Documentation ▸▾
API reference
Every endpoint, as the API describes itself. Each answer here is the one the API's own tests hold it to.
Himmel · 77 operations · https://api.gethimmel.com/v1
Checks
/v1/checkScope checkCheck a transaction, or an action about to be taken
Returns exactly one of four states - determined, undetermined_missing_facts, not_covered,
contested - with HTTP 200 for all four. Missing facts, an open recipient match and an
unconfirmed rule are answers, never errors.
transaction.status says what the check is: proposed for an action about to be taken, executed
for one taken. A key made for an agent says it, and leaving it out is refused (422 invalid-request,
required); from your account's own keys, and signed in, it is executed when left out.
The check_id is the receipt: store it against whatever you then do, and GET /v1/checks/{id}
reproduces this answer for the full retention window. The answer is stored before it is sent, so
the check is there the moment you read it; if the connection drops before you do, send the same
request again with the same Idempotency-Key and the stored answer comes back.
For an action a key made for an agent asks about, each person the answer names - a policy's
approver, a question's signer - is asked by Himmel, and requests beside the answer says so: whom,
when, and where each request stands (GET /v1/approvals/{id}). Ask about the same action again by
naming it in transaction.completes with status: proposed: its answer reads what was decided on
it, and nobody it names is asked again.
Himmel answers; the caller enforces. No endpoint blocks an action, and none takes one.
Parameters
Idempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
rule_setstringrequiredWhat to check against: a law set your account has switched on, or one of your own published policies. Either way every rule set of that domain that covers the transaction and that your account has on answers it: the law for the country it falls in, where your account has that law switched on, then your policies. With no law set among them, your policies are the whole answer, and it states no legal consequence.
rule_versionstring or nullThe version you expect to answer. The version in force on the transaction's date answers, always: named, it must be that one, and another is refused (
rule-version-not-in-force), naming the one in force.jurisdictionstring or nullWhere the transaction falls, as a code of two capital letters (
DE,FR,EU), when it may not be the rule set's own. It decides which country's law answers. A transaction outside the rule set's jurisdictions is answerednot_covered, and never counts toward that rule set's totals. Against a policy for several countries, or any, it is required wherever your account has law switched on for one of them.transactionTransactionIn10 fields
refstring or nullThe caller's opaque reference, at most 200 characters. Never PII.
channel"card" | "invoice" | "reimbursement" | "booking" | "agent"status"executed" | "proposed"executedis something that happened.proposedis an action the caller has not taken yet: checked identically, but out of history until the caller reports the outcome. Left out, it isexecuted- but a key made for an agent says which, and leaving it out is refused (required): nothing an agent sends is recorded as done because a field was left out.actorActorIn or null3 fields
kind"user" | "agent" | "system"idstring or nullThe agent's own identifier - or, for a person (
kind: user), their Himmel id: from your account's own keys a person of your account (unknown_user,left_the_account).on_behalf_ofstring or nullThe person the agent acts for, as your own systems identify them: an opaque id, never a name or an email address. They need no account here.
provenancemap of string or nullOpaque references the caller resolves in its own systems - a request reference, an approval it already holds - each name and reference at most 200 characters. Facts about where the instruction came from, never the agent's conclusion about what it means.
runstring or nullThe run of an agent this action is part of - the task a person dispatched it to do: a conversation, a ticket, a batch - as your own systems identify it: an opaque reference of at most 200 characters, never an email address or an IBAN. Every action of one run names the same, and the check log lists them together (
run=). A completion or a correction carries the action's.systemstring or nullThe system the action is taken in - the shop, the support desk, the ledger - by a short code your company picks:
support_desk,finance. Lowercase letters, digits,_and-, starting with a letter, at most 40 characters, and nevernone; anything else is refused (format). An action has one: named on its check, or where that named none by the first request after it that names one, it holds for every booking of the action, and another is refused (changed). No rule reads it: the check log finds by it (system=).executed_atstring or nullWhen an action sent as taken (
status: executed) was taken, a moment with its offset: it places the action in its day and gives it its own moment - an agent's runs, when it last acted. Any moment before the check, on the day the action is dated or a day either side, for time zones (not_its_dayotherwise), and at most a minute after the check is received, for clocks that differ (after_it_was_sent). Left out, the moment the check is received. Refused on an action asked about before it is taken (not_taken); a completion or a correction keeps its action's, so it is left out or sent the same (changed).completesstring or nullAn action already taken whose missing facts this check sends, by the
transaction_idits answers carry. The facts are that booking's with the ones sent added, and the complete booking stands in for it in every total; its answer replaces the one that stood. It is the same action:ref,channel,actor,provenance,jurisdiction,policiesand when it happened are the booking's, and may be left out. A fact the booking recorded a value for is left out or sent the same (changedotherwise); one left out or recorded as null may be given. Sent withstatus: proposed, an action still being asked about, asked about again: the booking that stands for it, its answer reading what was decided on the action.correctsstring or nullAn action already taken whose facts were sent wrong, by the
transaction_idits answers carry: this check's facts are that booking's with the ones sent in their place, and the corrected booking stands in for it in every total; its answer replaces the one that stood, and a decision made on that one is asked again. It is the same action -ref,channel,actor,jurisdiction,policiesand when it happened are the booking's (changedotherwise: an action that was another thing is taken back and sent again). One or the other ofcompletesandcorrects.
factsobjectThe facts the rule set takes, by name, as the catalogue lists them. An amount is
{"amount": <minor units>, "currency": "<ISO 4217>"}; one in another currency than the rule set's carriesequivalents, what your own systems record it as in the rule set's currency, which is what the rules read - without it, the answer asks for it. A key made for an agent never sends a person, nor the figure an approval was given for: Himmel holds them for the agent, and one sent with a value is refused (not_the_keys).policieslist of string or nullWhich of your published policies for the domain answer beside the law: left out, all of them;
[], none. A policy named asrule_setalways answers.explainboolean
Examples
determined: With every rule confirmed, the same booking is answered.
{
"rule_set": "de_gifts_entertainment",
"transaction": {
"channel": "agent",
"status": "executed"
},
"facts": {
"booking_date": "2023-03-14",
"account": "4630",
"recipient": "r1",
"amount_net": {
"amount": 2000,
"currency": "EUR"
},
"amount_gross": {
"amount": 2380,
"currency": "EUR"
}
}
}undetermined_missing_facts: Where nothing is recorded about the occasion, the answer is that we cannot tell — not that it is missing.
{
"rule_set": "de_gifts_entertainment",
"transaction": {
"channel": "agent",
"status": "executed"
},
"facts": {
"booking_date": "2023-03-14",
"account": "4650",
"participants": [
"r1",
"r2"
],
"participants_recorded": true,
"restaurant": true,
"invoice_attached": true,
"amount_net": {
"amount": 9500,
"currency": "EUR"
},
"amount_gross": {
"amount": 11305,
"currency": "EUR"
}
}
}not_covered: Until your rule owner confirms the rules, a check comes back saying so rather than answering.
{
"rule_set": "de_gifts_entertainment",
"transaction": {
"channel": "agent",
"status": "executed"
},
"facts": {
"booking_date": "2023-03-14",
"account": "4630",
"recipient": "r1",
"amount_net": {
"amount": 2000,
"currency": "EUR"
},
"amount_gross": {
"amount": 2380,
"currency": "EUR"
}
}
}contested: €250 a head is above the €100 you set for sign-off, so a named person confirms it was appropriate.
{
"rule_set": "de_gifts_entertainment",
"transaction": {
"channel": "agent",
"status": "executed"
},
"facts": {
"booking_date": "2023-03-14",
"account": "4650",
"participants": [
"r1",
"r2"
],
"participants_recorded": true,
"occasion_recorded": true,
"restaurant": true,
"invoice_attached": true,
"amount_net": {
"amount": 50000,
"currency": "EUR"
},
"amount_gross": {
"amount": 59500,
"currency": "EUR"
}
}
}Responses
200 One of the four states, always with HTTP 200.
One of 4, told apart by state.
effective_datestringrequiredThe date the rules were applied as of.
as_ofstringrequiredThe moment the history was read.
layersLayersrequired2 fields
lawLayerAnswer or nullThe law's answer. Left out where no law set is part of the answer - your policy's alone, for a country we hold no law for or one your account has not switched on.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or null5 fields
keystringrequiredvalueanyrequiredMoney as minor units and currency, or a number, a flag or a date.
rulestringrequiredbasisstring or nulllaw,policyorgoodwill.citationCitation or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
approveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
policieslist of LayerAnswer or nullYour policies for this domain, in the order they ran.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or null5 fields
keystringrequiredvalueanyrequiredMoney as minor units and currency, or a number, a flag or a date.
rulestringrequiredbasisstring or nulllaw,policyorgoodwill.citationCitation or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
approveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
engine_versionstringrequiredcheck_idstringrequiredThe receipt.
GET /v1/checks/{id}gives this answer back.transactionTransactionSummaryrequired9 fields
transaction_idstringrequiredstatus"executed" | "proposed"requiredproposedstays out of every total until you report that it executed.channel"card" | "invoice" | "reimbursement" | "booking" | "agent"requiredrefstring or nullYour own reference, as you sent it.
runstring or nullThe run of an agent the action is part of, as your systems identify it.
systemstring or nullThe system the action is taken in, by your company's code for it.
actorActor or null3 fields
kind"user" | "agent" | "system"requiredidstring or nullon_behalf_ofstring or nullThe person an agent acted for.
completesstring or nullThe booking whose missing facts this check sent, where it completed one: the same action, which this booking stands in for in every total.
correctsstring or nullThe booking whose facts sent wrong this check corrected, where it corrected one: the same action, as it should have been, which this booking stands in for in every total.
created_atstringrequiredrecipientRecipientSummary or null4 fields
resolutionstringrequiredresolved,unresolved,probable_matchormissing.recipient_idstring or nullreview_itemstring or nullThe open probable match, where there is one.
fy_totalMoney or nullThis recipient's total for the fiscal year, where the answer's first rule set totals money per recipient per fiscal year: the recipient's other bookings of the year that it counts, as known when the answer was given - this one not included, and later ones too where it counts the whole year. Left out where no such total was read;
history_usednames every total an answer read.2 fields
amountintegerrequiredcurrencystringrequired
history_usedlist of HistoryInput or null5 fields
rule_setstringrequiredinputstringrequiredThe rule set's name for this total, such as
recipient_fy_gifts.countintegerrequiredtransactionslist of HistoryTransactionrequired2 fields
transaction_idstringrequiredeffective_datestring or null
totalMoney | integer | string or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
citationslist of Citation or null4 fields
sourcestringrequiredThe source's key within the rule set, such as
estg.paragraphstring or nullclausestring or nulltext_refstring or nullThe passage in the rule set's own copy of the source,
sources/<file>#<anchor>.
confirmationslist of ConfirmationUsed or null3 fields
rulestringrequiredconfirmed_bystring or nullconfirmed_atstring or null
decisionslist of DecisionRead or nullEach question on this action a person decided, read as its answer: where the question's rule says what each answer leads to, a sign-off or an admin's override issues the action's answer again, and every answer to it after reads the decision while the rule asks the very same question. Left out where none was read.
8 fields
answerstringrequiredThe answer chosen, one of the question's candidates - or
approved, for an approval.questionstring or nullThe question's id. Null for an approval, which answers none.
rulestring or nullThe rule that raises the question, as it asks it. Null for an approval.
decided_bystring or nullWho decided: a person in your account, by id.
method"sign_off" | "override" | "approval" or nullA sign-off by the person the question names, an admin's override of it, or the approval of the person the action's answer named, asked by Himmel.
resolution_idstring or nullThe decision's record, on the answer it was made on.
leads_tostring or nullWhat the answer led to:
continue- on to the rules after the question, which gave the outcome - or the outcome it gives itself. Null for an approval, read from the first rule.approvalstring or nullThe fact the decision stood in for as its decider's approval - where the action recorded none, and the rule that gave the outcome read it - so one person who decides and approves is asked once. Null otherwise.
recheckslist of Recheck or nullThe earlier answers this booking changed, each issued again before this one was given. Left out when it changed none, and on a proposal, which changes nothing until it is reported as executed.
4 fields
new_check_idstring or nullsupersedesstring or nullbooking_datestring or nulloutcomestring or null
supersedes_check_idstring or nullThe earlier answer for the same transaction that this one replaces.
recheck_reasonstring or nullWhy it was issued again: a later transaction, an action taken back (
reversal) or corrected (correction), a link or split between recipients, a question raised about its recipient, the rules changing, a question on it decided (decision), or the action approved by the person its answer named (approval).tracelist of TraceStep or nullEvery rule reached, in order. Left out when the check asked
explain: false.6 fields
rulestringrequiredstagestringrequiredscope,outcomeorconsequence.matchedboolean or nullresolveinteger or nullWhich of the rule's branches applied.
missinglist of string or nullnotestring or null
sandboxtrue or nulltrueon an answer given in test. A live answer has no such field.superseded_bystring or nullThe newer answer for the same transaction, when there is one.
resolutionResolution or nullThe latest decision your people recorded on it: a sign-off, an override, an approval or a refusal.
6 fields
resolved_outcomestringrequiredOne of the question's answers, or of the outcomes its rule set declares - or for an approval Himmel asked for,
approvedorrefused.resolved_bystringrequiredmethod"sign_off" | "override" | "approval"requiredA sign-off by the person a question names, an admin's override, or the approval or refusal of the person Himmel asked (
POST /v1/approvals/{id}/approve).created_atstringrequiredWhen it was decided.
note_refstring or nullgiven_onstring or nullWhere the decision was carried over from an earlier answer that asked the very same question: the answer it was given on. Left out for a decision given on this answer.
resolutionslist of Resolution or nullEvery decision recorded on it - sign-offs, overrides, approvals and refusals - in the order recorded: an override leaves the sign-off before it on record. Left out where there is none.
6 fields
resolved_outcomestringrequiredOne of the question's answers, or of the outcomes its rule set declares - or for an approval Himmel asked for,
approvedorrefused.resolved_bystringrequiredmethod"sign_off" | "override" | "approval"requiredA sign-off by the person a question names, an admin's override, or the approval or refusal of the person Himmel asked (
POST /v1/approvals/{id}/approve).created_atstringrequiredWhen it was decided.
note_refstring or nullgiven_onstring or nullWhere the decision was carried over from an earlier answer that asked the very same question: the answer it was given on. Left out for a decision given on this answer.
factsobject or nullThe facts the booking was sent with, as stored: a recipient by the id it resolved to when it was sent, never a name, and everything else as sent - from a key made for an agent, a person and an approval's figure as Himmel holds them. The booking's, so every answer to it shows the same; the answer's own
recipientsays which identity that answer used. Read back beside the answer, never part of it.sent_bySender or nullWho sent the check: a key, or a person signed in - beside who acted, in
transaction.actor. Empty on an answer Himmel issued again, which nobody asked for (recheck_reasonsays why), and on one a person sent before this was kept. Read back beside the stored answer, never part of it; the answer a check returns when it is made does not carry it.4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
executionExecution or nullFor an action asked about before it was taken: what became of it, and who reported it. The answer itself still says
proposed, which is what was answered.7 fields
status"proposed" | "executed" | "abandoned" | "expired"requiredproposeduntil its caller reports;executed, orabandonedwhen reported not taken;expiredwhen nobody reported within 24 hours. An action taken back since readsexecuted, as its report said:reversalsays the rest.executed_atstring or nullWhen it was taken, as reported.
reasonstring or nullWhy it was not taken:
abandoned,refused_by_caller,failedorexpired.refstring or nullYour own reference for the action taken, as its report sent it - kept beside the action's own
transaction.ref, never over it. Empty where the report sent none.systemstring or nullThe system the action is taken in, as its check or its report named it. Empty where neither did.
reported_bySender or nullWho reported it. Empty until somebody does, and for one that expired.
4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
reported_atstring or null
reversalReversal or nullFor an action taken back after it was taken, on every answer to it: when, your reference for it, and who reported it. It counts toward nothing from then; the answer itself stays as it was given.
4 fields
reversed_atstringrequiredWhen it was taken back, as reported.
refstring or nullYour own reference for taking it back, where you sent one.
reported_bySender or nullWho reported it: a key, or a person.
4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
reported_atstring or null
requestslist of AskedOfAPerson or nullWhom Himmel asked about this action, as each request stands now - for an action a key made for an agent asked about, each person an answer to it names: a policy's approver, a question's signer. Beside the answer, never part of it. Left out where nobody was asked.
11 fields
idstringrequiredThe request,
apr_…:GET /v1/approvals/{id}.asked_ofstringrequiredThe person asked: a person in your account, by Himmel id.
asked_atstringrequiredWhen Himmel asked them.
asks"approval" | "question"requiredWhat they are asked: their
approvalof the action, which a policy of yours asks of them - or their answer to the answer'squestion, which a sign-off gives.status"waiting" | "approved" | "refused" | "decided" | "lapsed"requiredwaitingfor them, a week at most;approvedorrefusedby them;decidedby a sign-off or an admin's override;lapsed,reasonsaying why.waits_untilstringrequiredUntil when it waits for its person: a week after it was asked, the proposal held open until then. One still waiting then lapses,
no_answer, and a decision after it is409 nothing-to-decide.decided_bystring or nullWho decided it, by Himmel id: the person asked, or the admin who overruled.
resolution_idstring or nullThe decision that answered it, on the answer it was recorded on.
closed_atstring or nullWhen it stopped waiting.
reasonstring or nullWhy it lapsed: the action
executed,abandonedorexpired;no_answerin a week;no_longer_asked, an answer issued again naming them no more;refused, another person refusing the action.emailed_atstring or nullWhen Himmel emailed them, linking the request's page in the console: within a minute of the request, in your account's own environment. Null until then, and where it never goes - a request made in test in an account with a live side, one that stopped waiting first, a person with no address, or one whose mail server refused their address.
The facts, under these rule versions, as of this date, give this outcome.
A rule covers this, and needs facts it did not get. missing names them.
missinglist of MissingFactrequired7 fields
factstringrequiredtypestring or nullcurrencystring or nullFor an amount, the currency it is wanted in: the rule set's. Send it there, or - for an amount in another currency - beside it, as what your own systems record it as in this one (
equivalents).descriptionstring or nullneeded_bystring or nullThe rule that needed it.
review_itemstring or nullFor
recipient_identity: the probable match to answer first.ofHistoryTransaction or nullWhere the fact is another action's: a booking a total counts and cannot read, by its id and its date. Send the fact by completing that booking (
transaction.completes), not in this check.2 fields
transaction_idstringrequiredeffective_datestring or null
No confirmed rule covers this: your policy does not say, or a rule awaits confirmation.
reason"awaiting_confirmation" | "rule_flagged" | "policy_gap" | "no_rule_matched" | "no_rule_set_for_jurisdiction" | "rule_set_broken"requireddetailstring or nullunconfirmed_ruleslist of string or null
A rule covers this, and turns on a word it cannot apply mechanically. A named person decides.
questionQuestionrequired5 fields
idstringrequiredcandidateslist of stringrequiredreasonstringrequiredWhy this one cannot be settled by the rule.
rulestringrequiredwordingstring or nullThe rule's wording, as your rule owner confirmed it.
signerSigner or null1 field
useranyrequiredThe person who signs off, as your settings name them.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/checks/{check_id}/executionScope checks:writeWhat happened to a proposal
Report whether a proposed action was taken, on any answer to it - the one you kept from your first asking included, where you asked about it again. On executed: true the transaction joins history at that moment, and any earlier answer whose totals it moves is issued again with a check.rechecked alert. The action itself is answered again as it stands once taken: where a booking joined its totals, or rules or settings were confirmed, while it was asked about and it comes out otherwise, the new answer replaces the one given, and superseded_by names it; a change your rule owner has not confirmed yet never takes an answer away. On executed: false it is closed and never counts. A proposal with no report within 24 hours of its latest asking is closed as expired, unless a person Himmel asked about it holds it; a report after that is refused. Reporting the same outcome twice is answered the same way twice. ref is your own opaque reference for the action taken, kept beside the action's own transaction.ref and never over it: one that looks like an email address or an IBAN is refused with pii-in-facts. system is where the action was taken: the action's, or where it has none, named for it. A key made for an agent reports on its agent's own actions: on any other it gets 403 not-the-agents-action.
Parameters
check_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
executedbooleanrequiredrefstring or nullYour own reference for the action taken - a credit note's number - opaque and at most 200 characters: one that looks like an email address or an IBAN is refused (
pii-in-facts). Kept beside the action's owntransaction.ref, never over it, asexecution.ref; the check log finds the action by either.systemstring or nullThe system the action was taken in, as on the check (
transaction.system): where the action has one, the same or left out - another is refused (changed) - and where it has none, named for the whole action by the first report.executed_atstring or nullWhen the action was done, a moment with its offset: it places the action in its day. Between when it was asked about and this report, a minute either side for clocks that differ; else
invalid-request. Left out, the moment of the report.reason"abandoned" | "refused_by_caller" | "failed" or null
Responses
200 Successful response
check_idstringrequiredtransaction_idstringrequiredstatus"executed" | "abandoned" | "expired"requiredreasonstring or nullexecuted_atstring or nullrefstring or nullThe reference kept for the action taken, beside the action's own - on a repeat, the first report's. Empty where none was sent, and for an action not taken.
systemstring or nullThe system the action is recorded as taken in now; empty where none was named.
recheck_jobstring or nullThe job re-checking earlier answers this execution moves.
superseded_bystring or nullThe answer that replaced the one reported on, as
GET /v1/checks/{id}reads it: where the action, answered again as it stood once taken, came out otherwise - a booking joined its totals, or rules or settings were confirmed, while it was asked about. Empty where the answer stands as it was given.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/checks/{check_id}/reversalScope checks:writeAn action taken back
Report that an action taken was taken back afterwards - a credit given by mistake and clawed back, a refund whose payment failed. It counts toward nothing from then: every total it was in is worked out again without it, and each earlier answer that moves is issued again, with a check.rechecked alert where its state or outcome changed - those of actions that came while it stood included. Its own answers stay as they were given. Send it on any answer the action has: the check id you kept, or a later one. Take an action back this way, never by booking its negative, which counts as an action of its own. An action still being asked about is reported taken or not instead (/execution). Reporting it twice the same way is answered the same way twice. A key made for an agent takes back its agent's own actions: on any other it gets 403 not-the-agents-action.
Parameters
check_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
reversed_atstring or nullWhen it was taken back: a moment with its offset, or a day. Left out, the moment the report is received.
refstring or nullYour own reference for taking it back, opaque and at most 200 characters: one that looks like an email address or an IBAN is refused (
pii-in-facts).
Responses
200 Successful response
check_idstringrequiredtransaction_idstringrequiredThe booking taken back: the one that stood for the action.
status"reversed"requiredreversed_atstringrequiredrefstring or nullrecheck_jobstring or nullThe job issuing again the answers it counted in; empty on a repeat of the same report, which queues nothing.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/checks/{check_id}/resolutionScope checks:writeA sign-off, or an override
Record what your people decided. A sign-off decides a contested answer's question: only the person it names as signer gives one, choosing one of the question's candidates. An override is an admin overruling a determined answer, choosing one of the outcomes its rule set declares, or a contested one, choosing one of its question's answers. A decision is made on the answer that stands, for an action taken or still open. Where the question's rule says what each answer leads to, a decision on it issues the action's answer again in this request - the rules after the question answering too, the person who decided counting as approving it where the rules ask their approval next - and superseded_by names it; every answer the action is given after reads the decision while its rule asks the very same question. The answer decided on is never changed: the resolution is kept beside it. Supplying missing facts is a new check, not a resolution.
Needs a key with the scope checks:write. It records what a person decided, so a key made for an agent, which names nobody but itself, gets 403 cannot-decide.
Parameters
check_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
resolved_outcomestringrequiredmethod"sign_off" | "override"requiredresolved_bystring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you. Required from the account's own keys; a key made for an agent records no decision. For a contested check, the person its
signernames.note_refstring or nullYour own reference to the note behind the decision, opaque and at most 200 characters: one that looks like an email address or an IBAN is refused (
pii-in-facts).
Responses
200 Successful response
resolution_idstringrequiredcheck_idstringrequiredresolved_outcomestringrequiredmethod"sign_off" | "override"requiredsuperseded_bystring or nullThe answer the decision issued for the action, which replaces the one decided on: where the question's rule says what each answer leads to, the decision is read as its answer and the rules after it answer too. Null where the answer stands as it was - a question that says nothing of its answers, or a change still waiting for your rule owner, which issues it once confirmed.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/checks/{check_id}Scope checks:readOne stored answer, exactly as it was given
The answer as it was stored when it was given, for the whole retention period, with superseded_by when a later answer replaced it, and resolutions, every sign-off or override your people recorded, resolution the latest; facts, what the booking was sent with, a recipient by its id; sent_by, who sent the check - a key or a person signed in, beside who acted - and, for an action asked about before it was taken, execution: what became of it, and who reported it; for an action taken back, on every answer to it, reversal: when, and who reported it; and requests, whom Himmel asked about the action, as each request stands now.
Needs a key with the scope checks:read. From a key made for an agent it reads that agent's own alone: another agent's action is 403 not-the-agents-action, another agent's record 403 insufficient-scope.
Parameters
check_idpath · stringrequired
Responses
200 Successful response
One of 4, told apart by state.
effective_datestringrequiredThe date the rules were applied as of.
as_ofstringrequiredThe moment the history was read.
layersLayersrequired2 fields
lawLayerAnswer or nullThe law's answer. Left out where no law set is part of the answer - your policy's alone, for a country we hold no law for or one your account has not switched on.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or null5 fields
keystringrequiredvalueanyrequiredMoney as minor units and currency, or a number, a flag or a date.
rulestringrequiredbasisstring or nulllaw,policyorgoodwill.citationCitation or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
approveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
policieslist of LayerAnswer or nullYour policies for this domain, in the order they ran.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or null5 fields
keystringrequiredvalueanyrequiredMoney as minor units and currency, or a number, a flag or a date.
rulestringrequiredbasisstring or nulllaw,policyorgoodwill.citationCitation or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
approveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
engine_versionstringrequiredcheck_idstringrequiredThe receipt.
GET /v1/checks/{id}gives this answer back.transactionTransactionSummaryrequired9 fields
transaction_idstringrequiredstatus"executed" | "proposed"requiredproposedstays out of every total until you report that it executed.channel"card" | "invoice" | "reimbursement" | "booking" | "agent"requiredrefstring or nullYour own reference, as you sent it.
runstring or nullThe run of an agent the action is part of, as your systems identify it.
systemstring or nullThe system the action is taken in, by your company's code for it.
actorActor or null3 fields
kind"user" | "agent" | "system"requiredidstring or nullon_behalf_ofstring or nullThe person an agent acted for.
completesstring or nullThe booking whose missing facts this check sent, where it completed one: the same action, which this booking stands in for in every total.
correctsstring or nullThe booking whose facts sent wrong this check corrected, where it corrected one: the same action, as it should have been, which this booking stands in for in every total.
created_atstringrequiredrecipientRecipientSummary or null4 fields
resolutionstringrequiredresolved,unresolved,probable_matchormissing.recipient_idstring or nullreview_itemstring or nullThe open probable match, where there is one.
fy_totalMoney or nullThis recipient's total for the fiscal year, where the answer's first rule set totals money per recipient per fiscal year: the recipient's other bookings of the year that it counts, as known when the answer was given - this one not included, and later ones too where it counts the whole year. Left out where no such total was read;
history_usednames every total an answer read.2 fields
amountintegerrequiredcurrencystringrequired
history_usedlist of HistoryInput or null5 fields
rule_setstringrequiredinputstringrequiredThe rule set's name for this total, such as
recipient_fy_gifts.countintegerrequiredtransactionslist of HistoryTransactionrequired2 fields
transaction_idstringrequiredeffective_datestring or null
totalMoney | integer | string or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
citationslist of Citation or null4 fields
sourcestringrequiredThe source's key within the rule set, such as
estg.paragraphstring or nullclausestring or nulltext_refstring or nullThe passage in the rule set's own copy of the source,
sources/<file>#<anchor>.
confirmationslist of ConfirmationUsed or null3 fields
rulestringrequiredconfirmed_bystring or nullconfirmed_atstring or null
decisionslist of DecisionRead or nullEach question on this action a person decided, read as its answer: where the question's rule says what each answer leads to, a sign-off or an admin's override issues the action's answer again, and every answer to it after reads the decision while the rule asks the very same question. Left out where none was read.
8 fields
answerstringrequiredThe answer chosen, one of the question's candidates - or
approved, for an approval.questionstring or nullThe question's id. Null for an approval, which answers none.
rulestring or nullThe rule that raises the question, as it asks it. Null for an approval.
decided_bystring or nullWho decided: a person in your account, by id.
method"sign_off" | "override" | "approval" or nullA sign-off by the person the question names, an admin's override of it, or the approval of the person the action's answer named, asked by Himmel.
resolution_idstring or nullThe decision's record, on the answer it was made on.
leads_tostring or nullWhat the answer led to:
continue- on to the rules after the question, which gave the outcome - or the outcome it gives itself. Null for an approval, read from the first rule.approvalstring or nullThe fact the decision stood in for as its decider's approval - where the action recorded none, and the rule that gave the outcome read it - so one person who decides and approves is asked once. Null otherwise.
recheckslist of Recheck or nullThe earlier answers this booking changed, each issued again before this one was given. Left out when it changed none, and on a proposal, which changes nothing until it is reported as executed.
4 fields
new_check_idstring or nullsupersedesstring or nullbooking_datestring or nulloutcomestring or null
supersedes_check_idstring or nullThe earlier answer for the same transaction that this one replaces.
recheck_reasonstring or nullWhy it was issued again: a later transaction, an action taken back (
reversal) or corrected (correction), a link or split between recipients, a question raised about its recipient, the rules changing, a question on it decided (decision), or the action approved by the person its answer named (approval).tracelist of TraceStep or nullEvery rule reached, in order. Left out when the check asked
explain: false.6 fields
rulestringrequiredstagestringrequiredscope,outcomeorconsequence.matchedboolean or nullresolveinteger or nullWhich of the rule's branches applied.
missinglist of string or nullnotestring or null
sandboxtrue or nulltrueon an answer given in test. A live answer has no such field.superseded_bystring or nullThe newer answer for the same transaction, when there is one.
resolutionResolution or nullThe latest decision your people recorded on it: a sign-off, an override, an approval or a refusal.
6 fields
resolved_outcomestringrequiredOne of the question's answers, or of the outcomes its rule set declares - or for an approval Himmel asked for,
approvedorrefused.resolved_bystringrequiredmethod"sign_off" | "override" | "approval"requiredA sign-off by the person a question names, an admin's override, or the approval or refusal of the person Himmel asked (
POST /v1/approvals/{id}/approve).created_atstringrequiredWhen it was decided.
note_refstring or nullgiven_onstring or nullWhere the decision was carried over from an earlier answer that asked the very same question: the answer it was given on. Left out for a decision given on this answer.
resolutionslist of Resolution or nullEvery decision recorded on it - sign-offs, overrides, approvals and refusals - in the order recorded: an override leaves the sign-off before it on record. Left out where there is none.
6 fields
resolved_outcomestringrequiredOne of the question's answers, or of the outcomes its rule set declares - or for an approval Himmel asked for,
approvedorrefused.resolved_bystringrequiredmethod"sign_off" | "override" | "approval"requiredA sign-off by the person a question names, an admin's override, or the approval or refusal of the person Himmel asked (
POST /v1/approvals/{id}/approve).created_atstringrequiredWhen it was decided.
note_refstring or nullgiven_onstring or nullWhere the decision was carried over from an earlier answer that asked the very same question: the answer it was given on. Left out for a decision given on this answer.
factsobject or nullThe facts the booking was sent with, as stored: a recipient by the id it resolved to when it was sent, never a name, and everything else as sent - from a key made for an agent, a person and an approval's figure as Himmel holds them. The booking's, so every answer to it shows the same; the answer's own
recipientsays which identity that answer used. Read back beside the answer, never part of it.sent_bySender or nullWho sent the check: a key, or a person signed in - beside who acted, in
transaction.actor. Empty on an answer Himmel issued again, which nobody asked for (recheck_reasonsays why), and on one a person sent before this was kept. Read back beside the stored answer, never part of it; the answer a check returns when it is made does not carry it.4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
executionExecution or nullFor an action asked about before it was taken: what became of it, and who reported it. The answer itself still says
proposed, which is what was answered.7 fields
status"proposed" | "executed" | "abandoned" | "expired"requiredproposeduntil its caller reports;executed, orabandonedwhen reported not taken;expiredwhen nobody reported within 24 hours. An action taken back since readsexecuted, as its report said:reversalsays the rest.executed_atstring or nullWhen it was taken, as reported.
reasonstring or nullWhy it was not taken:
abandoned,refused_by_caller,failedorexpired.refstring or nullYour own reference for the action taken, as its report sent it - kept beside the action's own
transaction.ref, never over it. Empty where the report sent none.systemstring or nullThe system the action is taken in, as its check or its report named it. Empty where neither did.
reported_bySender or nullWho reported it. Empty until somebody does, and for one that expired.
4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
reported_atstring or null
reversalReversal or nullFor an action taken back after it was taken, on every answer to it: when, your reference for it, and who reported it. It counts toward nothing from then; the answer itself stays as it was given.
4 fields
reversed_atstringrequiredWhen it was taken back, as reported.
refstring or nullYour own reference for taking it back, where you sent one.
reported_bySender or nullWho reported it: a key, or a person.
4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
reported_atstring or null
requestslist of AskedOfAPerson or nullWhom Himmel asked about this action, as each request stands now - for an action a key made for an agent asked about, each person an answer to it names: a policy's approver, a question's signer. Beside the answer, never part of it. Left out where nobody was asked.
11 fields
idstringrequiredThe request,
apr_…:GET /v1/approvals/{id}.asked_ofstringrequiredThe person asked: a person in your account, by Himmel id.
asked_atstringrequiredWhen Himmel asked them.
asks"approval" | "question"requiredWhat they are asked: their
approvalof the action, which a policy of yours asks of them - or their answer to the answer'squestion, which a sign-off gives.status"waiting" | "approved" | "refused" | "decided" | "lapsed"requiredwaitingfor them, a week at most;approvedorrefusedby them;decidedby a sign-off or an admin's override;lapsed,reasonsaying why.waits_untilstringrequiredUntil when it waits for its person: a week after it was asked, the proposal held open until then. One still waiting then lapses,
no_answer, and a decision after it is409 nothing-to-decide.decided_bystring or nullWho decided it, by Himmel id: the person asked, or the admin who overruled.
resolution_idstring or nullThe decision that answered it, on the answer it was recorded on.
closed_atstring or nullWhen it stopped waiting.
reasonstring or nullWhy it lapsed: the action
executed,abandonedorexpired;no_answerin a week;no_longer_asked, an answer issued again naming them no more;refused, another person refusing the action.emailed_atstring or nullWhen Himmel emailed them, linking the request's page in the console: within a minute of the request, in your account's own environment. Null until then, and where it never goes - a request made in test in an account with a live side, one that stopped waiting first, a person with no address, or one whose mail server refused their address.
The facts, under these rule versions, as of this date, give this outcome.
A rule covers this, and needs facts it did not get. missing names them.
missinglist of MissingFactrequired7 fields
factstringrequiredtypestring or nullcurrencystring or nullFor an amount, the currency it is wanted in: the rule set's. Send it there, or - for an amount in another currency - beside it, as what your own systems record it as in this one (
equivalents).descriptionstring or nullneeded_bystring or nullThe rule that needed it.
review_itemstring or nullFor
recipient_identity: the probable match to answer first.ofHistoryTransaction or nullWhere the fact is another action's: a booking a total counts and cannot read, by its id and its date. Send the fact by completing that booking (
transaction.completes), not in this check.2 fields
transaction_idstringrequiredeffective_datestring or null
No confirmed rule covers this: your policy does not say, or a rule awaits confirmation.
reason"awaiting_confirmation" | "rule_flagged" | "policy_gap" | "no_rule_matched" | "no_rule_set_for_jurisdiction" | "rule_set_broken"requireddetailstring or nullunconfirmed_ruleslist of string or null
A rule covers this, and turns on a word it cannot apply mechanically. A named person decides.
questionQuestionrequired5 fields
idstringrequiredcandidateslist of stringrequiredreasonstringrequiredWhy this one cannot be settled by the rule.
rulestringrequiredwordingstring or nullThe rule's wording, as your rule owner confirmed it.
signerSigner or null1 field
useranyrequiredThe person who signs off, as your settings name them.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/checksScope checks:readThe check log
Your checks, newest first, fifty to a page. Continue with before set to the last page's next_before. Every answer ever given is here, including those a later answer replaced; current=true keeps only the answers that stand, one per booking. Each row says who acted and, in sent_by, who sent the check: a key, or a person signed in; that a later answer replaced it (superseded_by), what your people decided (resolution), and who approves or decides (a layer's approver, a contested answer's signer); and its transaction what is the action's rather than the answer's: who sent it, the latest decision on any of its answers, and the facts it was sent with. order=effective_date lists by the day each action happened, so an answer issued again never moves its row. Find an action by your own reference (ref), a booking's answers by its id (transaction), the actions of some days by the day they happened (effective_from, effective_to), a customer's by any of its records (recipient), who acted - one or several (actor), or every agent (actor_kind) - and for whom (on_behalf_of), an agent's run by its id (run), the actions taken in a system by its code (system), and the actions Himmel asked a person about by where each request stands (request) and whom it asked (asked_of); each row's transaction.requests says whom it asked. answer keeps the answers of a kind and against_rules=true the actions taken against your rules, as GET /v1/map counts them, each of its figures linking here. waiting=true keeps what waits on a person, which GET /v1/review counts in groups; reason finds why an answer is not covered and question the question it asks. state, outcome, policy_outcome and reason take several values, separated by commas. A group of the review queue links to the query here that lists its answers, and a checks.rerun alert to the answers it issued again.
Needs a key with the scope checks:read. From a key made for an agent it reads that agent's own alone: another agent's action is 403 not-the-agents-action, another agent's record 403 insufficient-scope.
Parameters
statequery · string or nullOne state, or several separated by commas.
rule_setquery · string or nullOnly the checks that named this rule set.
recipientquery · string or nullOnly the checks of this customer, by the id of any of its records: every record you answered to be the same, or a confirmed matching rule linked, counts as one, as a yearly total counts them. A record an open question only proposes does not.
actorquery · string or nullOnly what this person or agent did, by the id the check named - or any of several, separated by commas: the agents one person answers for, say.
actor_kindquery · string or nullOnly what this kind of actor did, as the check named it (
transaction.actor.kind):agent,userorsystem- or several, separated by commas.actor_kind=agentis what every agent did, which the map counts. Any other value is refused (enum).on_behalf_ofquery · string or nullOnly the actions done for this person, by the id the checks named as
actor.on_behalf_of, exactly: your own id for them, or a colleague's Himmel id.runquery · string or nullOnly the actions of this run of an agent, by the
transaction.runtheir checks named, exactly - withactor, one agent's run.systemquery · string or nullOnly the actions taken in this system, by the code their check or report named (
transaction.system) -nonefor those whose system nobody named - or several, separated by commas. A value that is no system's code is refused (format).transaction_statusquery · string or nullexecuted,proposed,abandoned,expiredorreversed(taken back): what became of the booking.requestquery · string or nullOnly the actions about which Himmel asked a person something whose request is now
waiting,approved,refused,decidedorlapsed- one, or several separated by commas. Withwaiting=true,request=waitingis the review queue's approvals.asked_ofquery · string or nullOnly the actions Himmel asked this person about, by their Himmel id - with
request, a request of theirs that now stands so:asked_of=usr_…&request=waitingis what waits on them.refquery · string or nullOnly the bookings sent with this
transaction.ref, your own reference, or reported taken with it (execution.ref), exactly.transactionquery · string or nullOnly the answers to this booking, by its
transaction_id- every one, those a later answer replaced included, unlesscurrent=true.effective_fromquery · string or nullOnly the actions that happened on this day or after, as each answer is dated (
effective_date): the day its facts give, or where they give none the day it was answered. A date,YYYY-MM-DD.effective_toquery · string or nullOnly the actions that happened on this day or before. A date,
YYYY-MM-DD.outcomequery · string or nullOne outcome, or several separated by commas.
policy_outcomequery · string or nullWhat a policy of yours answered - one outcome, or several separated by commas - whatever the answer as a whole says. Where our law answers too,
outcomeis the law's, so a gift your policy does not allow is found withpolicy_outcome=not_allowed.answerquery · string or nullOnly the answers of this kind - or of several, separated by commas - each read as the map counts it (
GET /v1/map): by its first policy's layer where a policy answered, and otherwise by the answer itself.allowed: determined, letting the action stand;approval:needs_approval;person: handed to a person, orcontested;refused:not_allowed;other: an outcome a policy declares in its own word;open: not covered, or a fact missing. Any other value is refused (enum).against_rulesquery · booleanOnly the actions taken against your rules, as
check.against_rulesis raised: reported taken, with an answer one of whose policies is determined with an outcome that does not let the action stand - any butallowedandnot_applicable.currentquery · booleanOnly the answers that stand: none given later replaced them.
waitingquery · booleanOnly the answers that stand and wait on a person at your company: a question nobody has decided, an answer your rules do not give yet, and facts missing from an action that was taken - or from any action, a "same customer?" question. Never an action that was not taken. What
GET /v1/reviewcounts.reasonquery · string or nullOnly the
not_coveredanswers not covered for this reason -policy_gap,awaiting_confirmation,rule_flagged,no_rule_matched,no_rule_set_for_jurisdictionorrule_set_broken- or several, separated by commas.questionquery · string or nullOnly the
contestedanswers that ask this question, by itsid.missingquery · string or nullOnly answers that name this fact as missing, e.g.
recipient.consequencequery · string or nullOnly answers that carry this consequence, e.g.
non_deductible_amount.recheckedquery · booleanOnly answers that replaced an earlier one: re-checks.
rerunquery · string or nullOnly the answers one re-run issued again, by the
rerun_iditschecks.rerunalert names: the answers a decision about the rules changed.fromquery · string or nullOnly the answers given at or after this moment, an ISO 8601 timestamp or a date - a date alone is its midnight, UTC. When the action happened is
effective_from.toquery · string or nullOnly the answers given before this moment, which is not included; as
from.limitquery · integerHow many to a page.
beforequery · string or nullThe last page's
next_before, to continue from.orderquery · "created_at" | "effective_date"created_at, the default: newest answer first.effective_date: by the day each action happened, newest first - within a day the one first asked about or booked last first - so an answer issued again never moves its row; withcurrent=true, one row per action.
Responses
200 Successful response
checkslist of CheckLogRowrequired20 fields
check_idstringrequiredcreated_atstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredrule_setstringrequiredeffective_datestringrequiredas_ofstringrequiredenv"live" | "test"requiredconsequenceslist of ConsequencerequiredEvery layer's consequences, law first.
5 fields
keystringrequiredvalueanyrequiredMoney as minor units and currency, or a number, a flag or a date.
rulestringrequiredbasisstring or nulllaw,policyorgoodwill.citationCitation or null4 fields
sourcestringrequiredThe source's key within the rule set, such as
estg.paragraphstring or nullclausestring or nulltext_refstring or nullThe passage in the rule set's own copy of the source,
sources/<file>#<anchor>.
layerslist of CheckLogLayerrequiredWhat each rule set made of it, law first. Where our law answers too,
outcomeis the law's, and what your policy said is here. Empty for an answer given before any rule ran.7 fields
kindstringrequiredlaworpolicy.rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullrulestring or nullThe rule whose branch gave this layer its outcome or its question. Empty where it waits on facts -
missingnames the rules that asked - or is not covered.approverstring or nullWho this layer's answer says must approve - where it
needs_approval, the person your settings name for it, by Himmel id. Empty where it names nobody.
transactionCheckLogTransactionrequired18 fields
transaction_idstringrequiredstatusstringrequiredexecuted,proposed,abandonedorexpired- orreversed, an action taken back after it was taken, which counts toward nothing.measureslist of MeasurerequiredWhat the action came to in another measure than money: each whole number a figure of its rule set marks as approved covers - a retention discount's percentage, where its policy marks
approved_percent: { type: int, approval: discount_percent }- read from the versions that answered it, in their order, each fact once. Empty where none marks one or the booking says none.2 fields
factstringrequiredThe fact, as the rule set declares it:
discount_percent.valueintegerrequiredWhat the action sent for it:
20.
actorCheckLogActorrequired3 fields
kindstring or nullidstring or nullon_behalf_ofstring or null
factsobjectrequiredThe facts the booking was sent with, as stored: a recipient by the id it resolved to, never a name, and everything else as sent - from a key made for an agent, a person and an approval's figure as Himmel holds them.
refstring or nullThe action's own reference, as its check sent it.
executed_refstring or nullYour own reference for the action taken, as its report sent it, beside the action's own:
ref=finds the action by either. Empty where its report sent none.recipient_idstring or nullbooking_datestring or nullamountBookedMoney or nullWhat the booking was for: the fact its rule set names as its amount (
amount_fact) - for our German gifts rule setamount_gross, what it was booked at, tax included - with the figures sent beside it (equivalents). Empty where the rule set names none or the booking says none.3 fields
amountintegerrequiredcurrencystringrequiredequivalentslist of Money or nullWhat the company's own systems record it as in other currencies, as sent beside it - a figure per currency, which a rule set in that currency reads. Never a rate we picked.
runstring or nullThe run of an agent the action was part of, where its check named one.
systemstring or nullThe system the action was taken in, by your company's code for it, as its check or a request after it named it: what
system=finds. Empty where nobody named one.sent_bySender or nullWho sent the action: the key or the person that sent its first answer - for an action whose facts a later check completed, whoever sent its first booking. The row's own
sent_byis the answer's, empty on an answer issued again.4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
completesstring or nullThe booking whose missing facts this booking's check sent, where it completed one: the same action, which this booking stands in for in every total.
correctsstring or nullThe booking whose facts sent wrong this booking's check corrected, where it corrected one: the same action, which this booking stands in for in every total.
reversed_atstring or nullWhen the action was taken back, where it was: its
statusis thenreversed.resolutionBookingResolution or nullThe latest decision - a sign-off, an override, an approval or a refusal - recorded on any answer to this action's bookings, and the answer it was recorded on - an earlier one where the answer was issued again since asking another question: a decision is carried over only where the same question is asked again.
7 fields
resolved_outcomestringrequiredOne of the question's answers, or of the outcomes its rule set declares - or for an approval Himmel asked for,
approvedorrefused.resolved_bystringrequiredmethod"sign_off" | "override" | "approval"requiredA sign-off by the person a question names, an admin's override, or the approval or refusal of the person Himmel asked (
POST /v1/approvals/{id}/approve).created_atstringrequiredWhen it was decided.
check_idstringrequiredThe answer it was recorded on.
note_refstring or nullgiven_onstring or nullWhere the decision was carried over from an earlier answer that asked the very same question: the answer it was given on. Left out for a decision given on this answer.
requestslist of AskedOfAPerson or nullWhom Himmel asked about this action, as each request stands now - for an action a key made for an agent asked about, each person an answer to it names: a policy's approver, a question's signer. Beside the answer, never part of it. Left out where nobody was asked.
11 fields
idstringrequiredThe request,
apr_…:GET /v1/approvals/{id}.asked_ofstringrequiredThe person asked: a person in your account, by Himmel id.
asked_atstringrequiredWhen Himmel asked them.
asks"approval" | "question"requiredWhat they are asked: their
approvalof the action, which a policy of yours asks of them - or their answer to the answer'squestion, which a sign-off gives.status"waiting" | "approved" | "refused" | "decided" | "lapsed"requiredwaitingfor them, a week at most;approvedorrefusedby them;decidedby a sign-off or an admin's override;lapsed,reasonsaying why.waits_untilstringrequiredUntil when it waits for its person: a week after it was asked, the proposal held open until then. One still waiting then lapses,
no_answer, and a decision after it is409 nothing-to-decide.decided_bystring or nullWho decided it, by Himmel id: the person asked, or the admin who overruled.
resolution_idstring or nullThe decision that answered it, on the answer it was recorded on.
closed_atstring or nullWhen it stopped waiting.
reasonstring or nullWhy it lapsed: the action
executed,abandonedorexpired;no_answerin a week;no_longer_asked, an answer issued again naming them no more;refused, another person refusing the action.emailed_atstring or nullWhen Himmel emailed them, linking the request's page in the console: within a minute of the request, in your account's own environment. Null until then, and where it never goes - a request made in test in an account with a live side, one that stopped waiting first, a person with no address, or one whose mail server refused their address.
outcomestring or nullmissinglist of MissingFact or nullWhat an
undetermined_missing_factsanswer asks for, as the answer names it.7 fields
factstringrequiredtypestring or nullcurrencystring or nullFor an amount, the currency it is wanted in: the rule set's. Send it there, or - for an amount in another currency - beside it, as what your own systems record it as in this one (
equivalents).descriptionstring or nullneeded_bystring or nullThe rule that needed it.
review_itemstring or nullFor
recipient_identity: the probable match to answer first.ofHistoryTransaction or nullWhere the fact is another action's: a booking a total counts and cannot read, by its id and its date. Send the fact by completing that booking (
transaction.completes), not in this check.2 fields
transaction_idstringrequiredeffective_datestring or null
reason"awaiting_confirmation" | "rule_flagged" | "policy_gap" | "no_rule_matched" | "no_rule_set_for_jurisdiction" | "rule_set_broken" or nullWhy a
not_coveredanswer is not covered.questionQuestion or nullThe question a
contestedanswer puts to a named person.5 fields
idstringrequiredcandidateslist of stringrequiredreasonstringrequiredWhy this one cannot be settled by the rule.
rulestringrequiredwordingstring or nullThe rule's wording, as your rule owner confirmed it.
signerSigner or nullWho decides a
contestedanswer's question: the person your settings name.1 field
useranyrequiredThe person who signs off, as your settings name them.
supersedes_check_idstring or nullThe earlier answer for the same booking that this one replaced.
superseded_bystring or nullThe newer answer for the same booking that replaced this one, where one did.
recheck_reasonstring or nullsent_bySender or nullWho sent the check: a key, or a person signed in - beside who acted, in
transaction.actor. Empty on an answer Himmel issued again, and on one a person sent before this was kept.4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
prefixstring or nullA key's prefix,
hk_live_7f3a: what your keys show, never the key itself.namestring or nullThe name the key was given, where it was given one.
resolutionResolution or nullThe latest decision your people recorded on this answer - a sign-off, an override, an approval or a refusal;
GET /v1/checks/{id}gives every one.6 fields
resolved_outcomestringrequiredOne of the question's answers, or of the outcomes its rule set declares - or for an approval Himmel asked for,
approvedorrefused.resolved_bystringrequiredmethod"sign_off" | "override" | "approval"requiredA sign-off by the person a question names, an admin's override, or the approval or refusal of the person Himmel asked (
POST /v1/approvals/{id}/approve).created_atstringrequiredWhen it was decided.
note_refstring or nullgiven_onstring or nullWhere the decision was carried over from an earlier answer that asked the very same question: the answer it was given on. Left out for a decision given on this answer.
next_beforestring or nullPass as
beforefor the next page; empty on the last one.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/reviewScope checks:readWhat waits on a person
What waits on somebody at your company, in groups: the approvals Himmel asked of a person about an agent's action, each question the rules leave to a person, the "same customer?" questions open, the answers your rules do not give yet by why, and the facts missing from actions taken, fact by fact. Each group says how many wait in it and links to the check log's query that lists them (waiting=true). An action never taken waits on nobody, and the facts of one still being asked about are its asker's to send. Nothing here decides anything: an approval is given or refused by the person asked, a question is decided with a resolution, "the same customer?" under Recipients, the rules by your rule owner confirming them, and missing facts come in a new check.
Needs a key with the scope checks:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Responses
200 Successful response
waitingintegerrequiredHow many answers wait on a person, each counted once, in whichever groups.
checksstringrequiredThe
GET /v1/checksquery that lists them:waiting=true.groupslist of ReviewGrouprequiredApprovals Himmel asked for, questions, "the same customer?", the rules, then facts; within a kind the largest first, but for the rules:
policy_gap,awaiting_confirmation,rule_flagged, then the rest. A group with nothing in it is not listed.9 fields
kind"approval" | "contested" | "match" | "not_covered" | "undetermined_missing_facts"requiredapproval: agents' actions whose answer names a person Himmel asked to approve, who has not answered yet.contested: a question the rules leave to a person.match: "the same customer?" questions.not_covered: answers your rules do not give yet, byreason.undetermined_missing_facts: a fact missing from actions taken.countintegerrequiredHow many wait in the group: the answers
checkslists, or formatchthe questions open, whichmatcheslists.checksstringrequiredThe
GET /v1/checksquery that lists the group's answers, exactly.questionQuestion or nullFor
contested: the question, as its newest answer asks it - the answers to choose from, and the rule that raises it in the words your rule owner confirmed.5 fields
idstringrequiredcandidateslist of stringrequiredreasonstringrequiredWhy this one cannot be settled by the rule.
rulestringrequiredwordingstring or nullThe rule's wording, as your rule owner confirmed it.
reason"awaiting_confirmation" | "rule_flagged" | "policy_gap" | "no_rule_matched" | "no_rule_set_for_jurisdiction" | "rule_set_broken" or nullFor
not_covered: why its answers are not covered.factstring or nullFor
undetermined_missing_facts: the fact.descriptionstring or nullFor
undetermined_missing_facts: the fact, as its rule set describes it.matchesstring or nullFor
match: where the open questions are listed,GET /v1/recipients/matches.answersinteger or nullFor
match: the answers waiting on one of its questions, whichcheckslists.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Confirmations
/v1/confirmationsScope rules:readWhat your account has to confirm
Every version of every rule set your account has on - our law where it is switched on for your account, your own policies, drafts included, and your matching rules - with how many of each version's rules wait for your rule owner (pending), how many they flagged, and waiting: how many answers that stand wait on a rule of the version, which confirming issues again. Law comes first, then policies, then matching rules, each oldest version first. A version's own page is GET /v1/confirmations/{rule_set}/{version}.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Responses
200 Successful response
rule_setslist of ConfirmationSetrequired5 fields
rule_setstringrequiredkindstringrequiredlaw,policyormatching.domainstringrequiredtitlestringrequiredversionslist of ConfirmationVersionrequired7 fields
versionstringrequiredstatusstringrequireddraft,publishedorsuperseded.effective_fromstringrequiredrulesintegerrequiredHow many rules the version has.
pendingintegerrequiredHow many nobody has confirmed or flagged yet.
flaggedintegerrequiredHow many your rule owner flagged. A flagged rule stays off.
waitingintegerrequiredHow many answers that stand wait on a rule of this version.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/confirmations/{rule_set}/{version}Scope rules:readOne page per rule set version: what to confirm, and what carried over
Nothing runs for your account until your rule owner confirms it. Per rule: its wording, each citation with the passage it points at, its worked examples as sentences, and its status - pending, confirmed on this page, flagged, or carried_over: confirmed on another version's page, where the rule reads exactly as it does here, so it runs without being confirmed again; its decision names that version. waiting counts the answers that stand and wait on a rule of this version, which confirming it issues again; each rule's waiting counts those that stopped at that rule, the first they could not pass. A rule set of the law is your account's to read and confirm once it is switched on for your account: before, this is rule-set-not-enabled.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Parameters
rule_setpath · stringrequiredversionpath · stringrequired
Responses
200 Successful response
rule_setstringrequiredversionstringrequiredstatusstringrequiredeffective_fromstringrequiredpendingintegerrequiredHow many rules still wait for your rule owner.
waitingintegerrequiredHow many answers that stand wait on a rule of this version. Confirming what is pending checks them again.
ruleslist of PageRulerequired10 fields
rulestringrequiredstagestringrequiredtitlestringrequiredwordingstringrequiredrule_hashstringrequiredA confirmation binds to this hash; a changed rule is confirmed again.
status"pending" | "confirmed" | "flagged" | "carried_over"requiredpending: nobody has confirmed or flagged it.confirmedon this page.flagged: it stays off.carried_over: confirmed on another version's page, where it reads exactly as here, so it runs without being confirmed again.waitingintegerrequiredHow many answers that stand stopped at this rule: it is the first they could not pass, unconfirmed or flagged.
citationslist of PageCitationrequired8 fields
sourcestringrequiredparagraphstring or nullclausestring or nulltext_refstring or nullsource_titlestring or nullsource_kindstring or nullstatute,official_guidance,case,policy_document, ordefault: the documented defaults a matching rule set starts from.excerptstring or nullThe passage itself, as the rule set holds it.
anchors_availablelist of string or nullWhere the citation resolves to no passage: the anchors the source has.
exampleslist of WorkedExamplerequired3 fields
casestringrequiredexamplestringrequiredThe case as one sentence, for the owner to read.
sourceobject or nullWhat settles the case: its type and reference.
decisionDecision or null5 fields
action"confirmed" | "flagged"requiredatstringrequiredversionstringrequiredThe version on whose page this was decided. Where it is another version's, the rule reads there exactly as it does here, and the decision holds for both.
by_userstring or nullcommentstring or null
previous_versionstring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/confirmations/{rule_set}/{version}Scope confirmConfirm, or flag, per rule
Each confirmation binds to the rule's hash, so a rule that changes is confirmed again. A flagged rule stays off for your account - checks that reach it answer not_covered with rule_flagged - and the comment reaches whoever maintains it: us for a rule of the law, your policy's draft for one of yours. Every answer your decision may change is checked again, in the background and in live and test alike: answers that waited on these rules, answers that used a rule you flag, and answers given under an earlier version this one now governs. rerun_id names that re-run; its checks.rerun alert says what changed. A rule of your policy that was drafted from its document, flagged with a comment, is drafted again alone, in the background: drafting_again names the document it follows on, the job and the rules, and the rule comes back to this page to be confirmed as it then reads, every rule it did not touch keeping its confirmation. A rule set of the law is confirmed once it is switched on for your account: before, this is rule-set-not-enabled, and nothing is recorded.
Needs a key with the scope confirm. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
rule_setpath · stringrequiredversionpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
ruleslist of ConfirmationItemrequired3 fields
rulestringrequiredaction"confirm" | "flag"requiredcommentstring
by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
rule_setstringrequiredversionstringrequiredrecordedlist of Recordedrequired3 fields
rulestringrequiredaction"confirmed" | "flagged"requiredrule_hashstringrequired
pendinglist of stringrequiredRules of this version still waiting.
rerun_idstring or nullThe re-run that checks again, in the background, every answer this decision may change. Its
checks.rerunalert says what changed, andGET /v1/checks?rerun=lists them. Null for matching rules, which match recipients again instead.drafting_againDraftingAgain or nullThe rules of your policy flagged with a comment, drafted again alone from its document and what you said. Null where none is: a rule of the law or of the matching rules, a policy posted as files, a flag without a comment, or a deployment that drafts nothing.
3 fields
document_idstringrequiredThe document they were drafted from, which says
draftingand where while they are drafted again, then what came of each in its latest entry ofdrafts.job_idstringrequiredruleslist of stringrequired
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Rule sets
/v1/rulesReadable without a keyEvery rule set you can see
The public catalogue: each rule set's title, domain and versions with their effective dates and changelog. Without a key it lists the rule sets of the law; with one, your own policies and matching rules too.
Readable without a key, for the rule sets of the law; with one, it needs the scope rules:read, and your own rule sets are added - except for a key made for an agent, which reads it as anybody does: what its agent is held to is GET /v1/agents/{agent_id}/rules.
Responses
200 Successful response
rule_setslist of RuleSetListItemrequired5 fields
rule_setstringrequiredkindstringrequiredlaw,policyormatching.domainstringrequiredtitlestringrequiredversionslist of RuleSetVersionSummaryrequired9 fields
versionstringrequiredstatusstringrequireddraft,publishedorsuperseded.effective_fromstringrequiredeffective_basisstringrequiredWhat the date is compared with: the transaction's own, or its year's start.
effective_date_factstringrequiredjurisdictionslist of stringrequiredchecksumstringrequiredchangelogstring or nullsuperseded_bystring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/rules/{rule_set}Readable without a keyOne rule set and its versions
Readable without a key for a rule set of the law.
Readable without a key, for the rule sets of the law; with one, it needs the scope rules:read, and your own rule sets are added - except for a key made for an agent, which reads it as anybody does: what its agent is held to is GET /v1/agents/{agent_id}/rules.
Parameters
rule_setpath · stringrequired
Responses
200 Successful response
rule_setstringrequiredkindstringrequireddomainstringrequiredtitlestringrequiredjurisdictionslist of stringrequiredversionslist of RuleSetVersionSummaryrequired9 fields
versionstringrequiredstatusstringrequireddraft,publishedorsuperseded.effective_fromstringrequiredeffective_basisstringrequiredWhat the date is compared with: the transaction's own, or its year's start.
effective_date_factstringrequiredjurisdictionslist of stringrequiredchecksumstringrequiredchangelogstring or nullsuperseded_bystring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/rules/{rule_set}/{version}Readable without a keyOne version: its facts, and its rules
The facts the version takes - name, type, whether required, what it means - so you can build a form or a validator against it; your settings it reads; the currency its limits are in, which an amount in another currency is read in at the figure you send beside it; its outcomes; and what it deliberately does not check. Readable without a key. With a key for an account that has the rule set enabled, each rule's wording and citations too.
Readable without a key, for the rule sets of the law; with one, it needs the scope rules:read, and your own rule sets are added - except for a key made for an agent, which reads it as anybody does: what its agent is held to is GET /v1/agents/{agent_id}/rules.
Parameters
rule_setpath · stringrequiredversionpath · stringrequired
Responses
200 Successful response
versionstringrequiredstatusstringrequireddraft,publishedorsuperseded.effective_fromstringrequiredeffective_basisstringrequiredWhat the date is compared with: the transaction's own, or its year's start.
effective_date_factstringrequiredjurisdictionslist of stringrequiredchecksumstringrequiredrule_setstringrequiredkindstringrequireddomainstringrequiredtitlestringrequiredfactsmap of FactSpecrequiredEvery fact the version takes, by name.
tenant_factsmap of TenantFactSpecrequiredoutcomeslist of stringrequirednot_checkedlist of NotCheckedrequired2 fields
topicstringrequiredreasonstringrequired
changelogstring or nullsuperseded_bystring or nullcurrencystring or nullThe currency its limits are in, as an ISO 4217 code: every amount its rules read is read in it, an amount in another currency at the figure sent beside it (
equivalents) - never at a rate we pick. Null where its rules read no amount, and for a version stored before rule sets said one.ruleslist of CatalogueRule or nullRules and their wording: only for an account with the rule set enabled.
7 fields
rulestringrequiredstagestringrequiredtitlestringrequiredwordingstringrequiredThe plain-language sentence your rule owner confirms.
rule_hashstringrequiredcitationslist of Citationrequired4 fields
sourcestringrequiredThe source's key within the rule set, such as
estg.paragraphstring or nullclausestring or nulltext_refstring or nullThe passage in the rule set's own copy of the source,
sources/<file>#<anchor>.
statusstring or null
rules_visibleboolean or nullfalsewhen the rules are left out because no key was sent.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/rules/{rule_set}/{version}/diffReadable without a keyWhat changed, in the words the owner confirms in
Per rule: changed, added, removed or unchanged, with the wording before and after. Then the worked examples that come out differently: each is run under both versions, not compared as text. Only changed and added rules need confirming again, and a rule changed says what moved in it beyond its own words (moved): a clause it cites, its examples, what it reads.
Readable without a key, for the rule sets of the law; with one, it needs the scope rules:read, and your own rule sets are added - except for a key made for an agent, which reads it as anybody does: what its agent is held to is GET /v1/agents/{agent_id}/rules.
Parameters
rule_setpath · stringrequiredversionpath · stringrequiredfromquery · stringrequired
Responses
200 Successful response
fromVersionRefrequired2 fields
rule_setstringrequiredversionstringrequired
toVersionRefrequired2 fields
rule_setstringrequiredversionstringrequired
summaryDiffSummaryrequired4 fields
changedintegerrequiredaddedintegerrequiredremovedintegerrequiredunchangedintegerrequired
ruleslist of RuleChangerequired8 fields
rulestringrequiredstatus"changed" | "added" | "removed" | "unchanged"requiredtitlestringrequiredwording_beforestring or nullwording_afterstring or nullrule_hash_beforestring or nullrule_hash_afterstring or nullmovedMoved or nullFor a rule
changed, what moved in it beyond its words; null for any other.6 fields
titlebooleanrequiredWhether its title changed.
wordingbooleanrequiredWhether its words changed:
wording_beforeandwording_after.clauseslist of ClauseMovedrequired4 fields
sourcestringrequiredclausestringrequiredIts clause or paragraph, as the rule cites it.
beforestring or nullIts text before: null where the rule did not cite it, or it had none.
afterstring or nullIts text now: null where the rule cites it no longer, or it has none.
exampleslist of ExampleMovedrequired7 fields
casestringrequiredfactslist of FactMovedrequiredThe facts of it that moved.
answerbooleanrequiredWhether the answer it expects moved.
historybooleanrequiredWhether the earlier actions it counts moved.
otherbooleanrequiredWhether anything else of it moved: who acts, the settings or decisions it assumes, its source.
beforestring or nullIts sentence before: null for an example the rule did not have.
afterstring or nullIts sentence now: null for one it has no longer.
logicbooleanrequiredWhether its conditions, what each branch decides, what it requires or its place among the rules changed.
readslist of ReadMovedrequired3 fields
kind"fact" | "setting" | "derived" | "total" | "table"requirednamestringrequiredchangedlist of stringrequiredWhat of it changed:
neworgone; for a fact or a setting itstype,values,pattern,currency,signedorapproval(whether it records an approval); for a total itssum,where,group_by,windowordays; for a derived value itsexpression; for a table itsrows.
examples_changedlist of ExampleChangerequired5 fields
casestringrequiredexamplestringrequiredbeforeExampleResultrequired3 fields
statestringrequiredoutcomestring or nullconsequenceslist of KeyValue or null2 fields
keystringrequiredvalueany
afterExampleResultrequired3 fields
statestringrequiredoutcomestring or nullconsequenceslist of KeyValue or null2 fields
keystringrequiredvalueany
rulestring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Recipients
/v1/recipientsScope checks:readRecipient identities
Each recipient record, newest first, with the identity it counts as once confirmed links are followed. A person signed in to the console as an admin or ops is also shown each record's name, and can search by it with q. A key is shown ids and never a name, so q is refused for it (names-withheld). ids asks for given records - the ones a list of checks names, say - where the listing alone is the newest.
Needs a key with the scope checks:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Parameters
qquery · string or nullidsquery · string or nullOnly these records, by id, separated by commas: up to 200.
limitquery · integer
Responses
200 Successful response
recipientslist of RecipientRecordrequired8 fields
recipient_idstringrequiredkindstringrequiredcreated_fromstringrequiredcreated_atstringrequiredcanonical_idstringrequiredThe identity this record counts as, after confirmed links.
labelstring or nullThe recipient's name as recorded, or its organisation or email address where no name was, read through the pseudonymiser. Shown only to a person signed in to the console as an admin or ops, and left out for a key, whatever its scopes. Null when only a number was recorded, or when the name is no longer kept (
name_expired).name_expiredboolean or nullTrue where a name was recorded and is no longer kept: a customer's names are kept through the end of the fiscal year after the one they were last met in. Their record and numbers stay, and the same spelling sent again finds them and brings the name back. Left out otherwise.
numbersmap of string or nullThe numbers your systems sent the record with, as sent -
customer_number,supplier_number,vendor_number,creditor_number, each kind once - and{}where none was: what the console shows a customer by where no name was sent. Shown to a person signed in to the console, whatever their role, and left out for a key.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/recipients/matchesScope checks:readProbable matches waiting for somebody to answer
Two recipient records a confirmed matching rule thinks may be one person. Totals follow recipients, not spellings, and a probable match is never merged without a person saying so: answer each with POST /v1/recipients/matches/{id}. Both records' names are shown to a person signed in to the console as an admin or ops; a key is shown their ids.
Needs a key with the scope checks:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Parameters
statusquery · stringlimitquery · integer
Responses
200 Successful response
matcheslist of ProbableMatchrequired6 fields
review_itemstringrequiredstatus"open" | "same" | "different"requiredrulestringrequiredThe confirmed matching rule that proposed it.
created_atstringrequiredaMatchSiderequired3 fields
recipient_idstringrequiredlabelstring or nullThe recipient's name as recorded, or its organisation or email address where no name was, read through the pseudonymiser. Shown only to a person signed in to the console as an admin or ops, and left out for a key, whatever its scopes. Null when only a number was recorded, or when the name is no longer kept (
name_expired).name_expiredboolean or nullTrue where a name was recorded and is no longer kept: a customer's names are kept through the end of the fiscal year after the one they were last met in. Their record and numbers stay, and the same spelling sent again finds them and brings the name back. Left out otherwise.
bMatchSiderequired3 fields
recipient_idstringrequiredlabelstring or nullThe recipient's name as recorded, or its organisation or email address where no name was, read through the pseudonymiser. Shown only to a person signed in to the console as an admin or ops, and left out for a key, whatever its scopes. Null when only a number was recorded, or when the name is no longer kept (
name_expired).name_expiredboolean or nullTrue where a name was recorded and is no longer kept: a customer's names are kept through the end of the fiscal year after the one they were last met in. Their record and numbers stay, and the same spelling sent again finds them and brings the name back. Left out otherwise.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/recipients/matches/{match_id}Scope recipients:writeSame, or different. Never automatic.
same links the two records into one identity and different keeps them apart for good. Either way the answers whose totals depend on it are issued again, in a job - the booking that raised the question among them, answered from then on like any other: with the other record after same, on its own after different.
Parameters
match_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
decision"same" | "different"requireddecided_bystring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
review_itemstringrequireddecision"same" | "different"requiredrecipientslist of stringrequiredrecheck_jobstring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/recipients/{recipient_id}/splitScope recipients:writeUndo a link, and re-check what it moved
Undoes this record's links to others. The links stay on record, marked undone, and the answers they moved are issued again.
Parameters
recipient_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
decision"same" | "different"requireddecided_bystring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
recipient_idstringrequiredundonelist of stringrequiredThe links undone. They stay on record, marked undone.
recheck_jobstring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Settings
/v1/tenant-factsScope rules:readThe settings your checks are answered with
What your rules read about your company - who approves, who signs off, your financial year's start, a limit of your own - each as it applies today (in_force), with every version (history), and settings: each one a rule set of your account reads, with the rule sets that read it and what each says it is for, for an amount the currencies they read it in, and unset where nothing is in force today, so a check reaching a rule that reads it asks for it. Himmel reads your financial year's start itself. Every check records the settings it read.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Responses
200 Successful response
in_forceobjectrequiredEach setting as it applies today.
historylist of TenantFactVersionrequiredEvery version of every setting, by key, newest first - a day's the latest saved first, so the first dated on or before a day is the one in force that day.
5 fields
keystringrequiredvalid_fromstringrequiredvalueanyconfirmed_bystring or nullconfirmed_atstring or null
settingslist of SettingrequiredEach setting a rule set of your account reads, or Himmel does, by key, with what reads it - and any other set, which nothing reads. Its values are in
in_forceandhistory.7 fields
keystringrequiredread_bylist of SettingReaderrequiredWhat reads it, each in its own words: your policies first, then your matching rules, then the law you have switched on, then Himmel. Empty for a setting stored that nothing reads any more, which cannot be changed.
5 fields
kind"law" | "policy" | "matching" | "himmel"requiredA law set switched on for your account, one of your policies or your matching rules - or
himmel: Himmel itself, which reads your financial year's start and which actions taken against the rules are emailed at once.titlestringrequiredversionslist of stringrequiredThe rule set's versions that declare the setting, drafts included, oldest first.
descriptionstringrequiredWhat this reader says the setting is for, as its newest version declares it.
rule_setstring or nullThe rule set's key; null for Himmel.
unsetbooleanrequiredNo value is in force today, or it is none: a check reaching a rule that reads it asks for it.
typestring or nullThe type a value must have, as what reads it declares it (docs: rule sets) - a person by their Himmel id is
user. Null for a setting nothing reads.patternstring or nullFor a code - a
string, or anaccountthat declares one: a regular expression the whole value must match. A value that does not is refused withinvalid-fact.valueslist of string or nullAn
enum's values.currencieslist of string or nullFor an amount: the currencies the rule sets that read it read it in, as their versions say. A value is in one of them, with what it comes to in each other beside it (
equivalents, as a check's amount carries them) - otherwisePUTrefuses it.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/tenant-facts/{key}Scope confirmA new version of one setting
Writes a new version from valid_from (today when left out). Nothing is overwritten, and an answer keeps the settings it read as its record. Dated back, a change reaches answers already given: those dated from valid_from on that read the setting are issued again by a re-run (rerun_id), with one checks.rerun alert once it is done - a financial year's start corrected to 1 April reaches the credits of the year it moves. The setting is checked first: something in your account reads it - a key nothing reads, a typo say, is invalid-fact with read_by_nothing, and the problem's settings lists what your rules do read - and its value holds no email address or IBAN (pii-in-facts) and has the type everything that reads it declares (invalid-fact). A signer or an approver is a person in your account, by their Himmel id, never a name (unknown_user when nobody here has it). An amount is in the currency each rule set that reads it reads it in, or carries what it comes to in that one beside it (equivalents) - otherwise invalid-fact, currency. The rules whose actions taken against them you hear of at once (emailed_at_once) are rules of your own policies, by id - otherwise invalid-fact, unknown_rule.
Needs a key with the scope confirm. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
keypath · stringrequired
Request body · application/json
valueanyrequiredvalid_fromstring or nullconfirmed_bystring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
keystringrequiredvalid_fromstringrequiredrerun_idstringrequiredThe re-run this change queued: the answers dated from
valid_fromon that read the setting are issued again where it changes them, with onechecks.rerunalert. A change from today on reaches none given before.valueany
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/meScope rules:readWho is calling, for which account, and what it may do
The account your key belongs to - with the country it is established in, the currency its books are kept in, how many years its checks are kept and, for an account opened by signing up, the terms its person accepted - whether this request acts in live or in test, the scopes the key carries, and for a key made for an agent, the agent it acts as. The console reads the same answer for the person signed in to it, whose role decides their scopes.
Responses
200 Successful response
accountAccountrequired9 fields
idstringrequiredslugstringrequirednamestringrequiredtest_onlybooleanrequiredtruefor an account that holds test data only: the sandbox. Every other has live and test.retention_yearsintegerrequiredHow many years its checks are kept: the period its country's law sets for its records, stated when the account was opened.
GET /v1/checks/{id}reproduces an answer for it.countrystring or nullWhere the company is established, as an ISO 3166-1 code:
US,AE,DE.currencystring or nullThe currency its books are kept in, as an ISO 4217 code: a playbook drafted for it states its limits in this one where its document names none. Never taken from the country: a company may keep its books in another.
termsTermsAccepted or nullThe terms of Himmel's the account's person accepted - opening it by signing up, or, for an account a builder opened, joining it as its owner - the latest, where its admins have accepted several. Null for an account opened with us, whose terms are in its contract, and for one a builder opened until its owner joins.
3 fields
versionstringrequiredThe version accepted, as
GET /v1/termsgives it.accepted_bystringrequiredThe Himmel id of the person who accepted them.
accepted_atstringrequired
opened_byOpenedBy or nullThe account that opened yours, for one a builder opened: its agents act for you, and it registers them and makes their keys here - never more. Null for an account opened with us or by signing up.
4 fields
idstringrequiredIts account's id: what
buildersays on its agents and keys.namestringrequiredIts company's name.
cut_off_atstring or nullWhen your account cut it off, for good: it acts in your account no more - its agents act on, until you switch them off. Null while it may act.
cut_off_bystring or nullThe Himmel id of the person who cut it off.
env"live" | "test"requiredWhere this request acts: a key's own environment, or for a person the account's own unless the request sent
Himmel-Env: test.callerIdentityrequired4 fields
kind"api_key" | "person"requiredidstringrequiredThe key's id, or the person's user id.
role"tenant_admin" | "tenant_engineer" | "tenant_ops" | "author" or nullA person's role, which decides their scopes. Null for a key.
actorActor or nullFor a key made for an agent: the agent it acts as, which every check it sends records whatever the request says. Null for your account's own keys, which name who acts in each request, and for a person.
3 fields
kind"user" | "agent" | "system"requiredidstring or nullon_behalf_ofstring or nullThe person an agent acted for.
scopeslist of stringrequiredWhat this caller may do: one scope per kind of call.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Alerts
/v1/alertsScope checks:readWhat has changed since you last looked
Newest first. check.rechecked means an answer you were given has been issued again - payload.was and payload.now say what moved - and a caller that acted on the earlier answer learns it here. check.against_rules means an action reported as taken was not allowed by your own rules as taken - not_allowed, needs_approval, hand_to_a_person - one alert an action. check.rule_set_broken means an action that happened could not be checked, its rules unable to run on its facts: it is kept, counts in every total, and is answered not_covered until a version that can answer it is confirmed. check.handed_over means an agent asked about an action your rules hand to the person they name, who is told: one alert for each action and person. The others: a new version published, a probable match to answer, and confirmations still pending once a version is in force. Poll it; webhooks come later.
Needs a key with the scope checks:read. From a key made for an agent it reads that agent's own alone: another agent's action is 403 not-the-agents-action, another agent's record 403 insufficient-scope.
Parameters
typequery · string or nullstatusquery · string or nulllimitquery · integer
Responses
200 Successful response
alertslist of Alertrequired9 fields
alert_idstringrequiredtypestringrequiredrule_set.version.published,check.rechecked,checks.rerun,recipient.probable_match,confirmation.overdue,check.against_rules,check.rule_set_brokenorcheck.handed_over.payloadobjectrequiredWhat changed: for
rule_set.version.published, therule_set, itsversionand the day it applies from (effective_from), the rules stillpending, andby_user, the person of yours who published it, null for our law; forcheck.rechecked,wasandnow, andby_user, the person whose approval or decision issued it again, null for any other cause; forchecks.rerun, itscause, how many answers it checked again (reissued) and changed (changed), how many of them are actions taken that now stand against your rules (against_rules), andchecks, the query that lists them; forconfirmation.overdue, therule_setandversion, the rules stillpending, and how many answers wait on them (waiting); forcheck.against_rules, an action taken that your own rules did not allow as taken - thecheck_idof the answer that stands,transaction_id,effective_date, who acted (actor), thecause, whether it is emailed at once or in the day's summary (emailed), andagainst: each policy that said so, itsrule_set,rule_version, theruleand itstitle, theoutcome, and theapproverit named, where it named one; forcheck.rule_set_broken, an action that happened whose rules could not run on its facts, kept and answerednot_covered- thecheck_id,transaction_id, therule_setits check named,effective_dateand the answer'sdetail; forcheck.handed_over, an action an agent asked about that your rules hand to the person they name - thecheck_idthat handed it over,transaction_id,action(its first booking),handed_to,effective_date, the agent (actor), and the policy that said so:rule_set,rule_version, therule, itstitleand theoutcome.status"open" | "acknowledged"requiredcreated_atstringrequiredacknowledged_bystring or nullacknowledged_atstring or nullemailed_atstring or nullemailed_tointeger or nullHow many people it was emailed to: your admins, and for
check.against_rulesthe approvers it names as well - never the person whose own act it reports (by_user): 0 where they are your only admin; forcheck.handed_overthe person it hands the action to alone. A person whose mail server refused their address is not counted, and the others are emailed all the same.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/alerts/{alert_id}/acknowledgeScope checks:writeMark an alert as seen
An alert has one status, shared by every caller of its environment, and is emailed to your admins whatever it is. acknowledged_by names who saw it: yourself, signed in; from one of the account's own keys, a person in the account, or nobody. A key made for an agent names nobody but itself, and naming anybody is 422 invalid-request (not_the_keys).
Parameters
alert_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
acknowledged_bystring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
alert_idstringrequiredstatus"acknowledged"required
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Policies
/v1/policiesScope rules:readThis account's policies and their versions
Each policy with every version: its status, and the rules still waiting for your rule owner.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Responses
200 Successful response
policieslist of PolicyListItemrequired4 fields
rule_setstringrequiredtitlestringrequireddomainstringrequiredversionslist of PolicyVersionSummaryrequired10 fields
policy_idstringrequiredrule_setstringrequiredversionstringrequiredstatusstringrequiredeffective_fromstringrequiredrulesintegerrequiredpending_confirmationlist of stringrequiredflaggedlist of stringrequiredsuperseded_bystring or nullfilled_fromFilledFrom or nullThe template that filled this version and the figures it was filled with; null for one posted as files or drafted from a document.
3 fields
templatestringrequiredThe template's name, as
GET /v1/templateslists it.versionstringrequiredThe template's own version when it filled this one.
valuesobjectrequiredEach blank's figure, by its name: money as
{amount, currency}, the rest whole numbers.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policiesScope policies:writePost a policy as a draft version: its files, or a template filled with your figures
A policy is a rule set of your own, laid out like any other: ruleset.yaml and the files under rules/, tests/ and sources/. It is stored as a draft however it lints, and checks says what would stop it being published. It sits on our law set for its domain and country where we hold one; where we hold none it stands alone, and says what is allowed, what needs whose approval and what a named person decides - no consequence, and nothing read from the law. Or from a template (GET /v1/templates): template and values in place of files, every blank your figure, in your account's currency, and every choice your option. Its document, rules and worked examples say your figures, and it is posted as a draft your rule owner confirms rule by rule - as a new policy's 1.0.0, or the next version of the one you have; a draft of it already there is 409 and is filled again with PUT. filled_from says what filled it. Idempotent on Idempotency-Key.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
Idempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
filesmap of string or nullEach file's path within the rule set, and its text - the same layout as any rule set version. Posted as a draft;
status: draftinruleset.yaml. Leave it out to fill a template instead.templatestring or nullOne of our templates, by its name (
GET /v1/templates): filled withvalues, it is your policy's document, rules and worked examples, posted as a draft for your rule owner to confirm. In place offiles.valuesobject or nullEvery blank of the template and your figure for it, by the blank's name: money as an integer
amountin minor units with your account'scurrency, days, percent and counts as whole numbers - and every choice and thevalueof the option you pick, by the choice's name. Each is required: the template proposes no figure and no choice.by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
policy_idstringrequiredrule_setstringrequiredversionstringrequiredstatusstringrequiredeffective_fromstringrequiredrulesintegerrequiredpending_confirmationlist of stringrequiredflaggedlist of stringrequiredfilled_fromFilledFrom or nullrequiredThe template that filled this version and the figures it was filled with; null for one posted as files or drafted from a document.
3 fields
templatestringrequiredThe template's name, as
GET /v1/templateslists it.versionstringrequiredThe template's own version when it filled this one.
valuesobjectrequiredEach blank's figure, by its name: money as
{amount, currency}, the rest whole numbers.
titlestringrequireddomainstringrequiredjurisdictionslist of stringrequiredsits_onlist of stringrequiredThe law versions it is layered over,
rule_set@version. Empty for a policy that stands alone: one for a domain and country we hold no law for, which states outcomes only.filesmap of stringrequiredchecksPublishChecksrequiredEverything publishing would run, run now.
6 fields
publishablebooleanrequiredblockinglist of PublishFindingrequired11 fields
checkstringrequiredlint,consequence,coverage,casesorfloor.codestring or nullrulestring or nullcasestring or nullmessagestring or nullfailureslist of string or nulllawstring or nulllaw_rulestring or nullpolicy_rulestring or nullowedanypaidany
warningslist of PublishFindingrequired11 fields
checkstringrequiredlint,consequence,coverage,casesorfloor.codestring or nullrulestring or nullcasestring or nullmessagestring or nullfailureslist of string or nulllawstring or nulllaw_rulestring or nullpolicy_rulestring or nullowedanypaidany
casesCaseCountsrequired2 fields
passedintegerrequiredfailedintegerrequired
coveragemap of integerrequiredHow many cases reach each rule.
floorFloorSummaryrequired2 fields
lawsintegerrequiredpayments_comparedintegerrequired
drafted_fromDraftedFrom or nullrequiredThe document this version was last drafted from; null for one posted as files.
5 fields
document_idstringrequiredfilenamestringrequiredtitlestringrequiredcreated_atstringrequiredWhen the document was uploaded.
drafted_atstringrequiredWhen the drafting that wrote this version began.
review_itemslist of ReviewItemrequiredWhat its latest drafting raised - examples the two drafts decide differently, holes the third pass found, cases that fail, examples a rule could not answer once altered - and each flag of a rule that stands flagged.
5 fields
review_itemstringrequiredkindstringrequiredstatusstringrequiredpayloadobjectrequiredcreated_atstring or null
superseded_bystring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/templatesScope rules:readThe templates a policy can be filled from
Each of our templates: what it is for, its blanks - each with its measure, the clauses that say it and the least and most it takes - the order its words put them in, its choices - a part you pick between its words, each with its options - the settings its rules read, and its document with each blank and choice shown by its name. Every figure is a blank and every choice yours: a template proposes none. Fill one with POST /v1/policies, template and values in place of files.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Responses
200 Successful response
templateslist of Templaterequired12 fields
templatestringrequiredIts name: what
POST /v1/policiestakes astemplate.versionstringrequiredtitlestringrequiredsummarystringrequiredlanguagestringrequiredThe language its document, rules and examples are written in.
policystringrequiredThe policy a filling is posted as:
policy.<your slug>.<policy>.domainstringrequiredblankslist of TemplateBlankrequiredEvery figure it needs, each yours to fill: it proposes none.
6 fields
namestringrequiredThe blank's name, as
valuesgives its figure.kind"money" | "days" | "percent" | "count"requiredIts measure: money, an integer
amountin your account's currency's minor units with thatcurrency; days, whole percent or a count of things, a whole number.clauseslist of stringrequiredThe clauses of the template's document that say it.
saysstringrequiredWhat the figure is, in words.
minimumintegerrequiredThe least it takes - for money, in minor units.
maximumintegerrequiredThe most it takes - for money, in minor units.
orderlist of TemplateOrderrequiredThe order its words put figures in: a filling out of it is refused, naming the clauses, never mended.
5 fields
lowerstringrequiredupperstringrequiredstrictbooleanrequiredWhether
uppermust be abovelower, not only at least it.clauseslist of stringrequiredsaysstringrequired
choiceslist of TemplateChoicerequiredEach part of the playbook you pick between its words - for
online_shop_support, what becomes of the AI assistant's refund above its own limit (clause 2.7) - each yours to pick: it proposes none.4 fields
namestringrequiredThe choice's name, as
valuesgives the option picked.clauseslist of stringrequiredThe clauses of the template's document it decides.
saysstringrequiredWhat it decides, in words.
optionslist of TemplateOptionrequiredWhat it may be: one of them, yours to pick.
2 fields
valuestringrequiredWhat
valuesgives the choice, picking this one.saysstringrequiredWhat it does, in words.
settingslist of TemplateSettingrequiredThe settings its rules read - people and a date, which your rule owner names.
3 fields
namestringrequiredtypestringrequiredsaysstringrequired
documentstringrequiredIts document, each blank and each choice shown by its name in brackets:
[refund_days].
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/documentsScope rules:readThis account's uploaded policy documents
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Responses
200 Successful response
documentslist of PolicyDocumentListItemrequiredNewest first.
7 fields
document_idstringrequiredrule_setstringrequireddomainstringrequiredtitlestringrequiredfilenamestringrequiredstatusstringrequiredcreated_atstringrequired
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/documentsScope policies:writeUpload a policy document: stored masked, never drafted yet
PDF, DOCX or Markdown. List every name in it to hide, one names field each. Those names, every name your account's documents hid before, every person of your account, every word that reads as a name - a given name followed by a capitalised word - and every email address, IBAN and phone number are replaced by placeholders before anything is stored; the file itself is not kept. Read the masked text that comes back: a single first name, or a name written otherwise, is still yours to find, and a word hidden as a name that is none is shown again with …/shown. Nothing is drafted until you ask.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
Idempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · multipart/form-data
filestringrequiredpolicystringrequiredThe name it drafts to: policy.<your slug>.<policy>
domainstringrequiredYour name for its set of books -
customer_support, say, or a law set's domain where it is to sit on one: short, lower case, parts joined by dotstitlestringnameslist of string or nullEvery name in the document to hide, once per form field, as written.
by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
document_idstringrequiredrule_setstringrequireddomainstringrequiredtitlestringrequiredfilenamestringrequiredmedia_typestringrequiredsha256stringrequiredThe file's hash. The file itself is not kept.
statusstringrequireduploaded,drafting,draftedorfailed.textstringrequiredThe masked text, one anchor per clause.
clauseslist of stringrequiredmaskedlist of MaskedItemrequired4 fields
placeholderstringrequiredWhat stands in the text, such as
[[NAME-1]].kindstringrequiredname,email,ibanorphone.why"listed" | "person" | "found" | "shape"requiredWhy it was hidden:
listed- on this upload, or on an earlier document of your account;person- a person of your account, by the name Himmel keeps for them;found- it reads as a name, a given name followed by a capitalised word, and you show it again where it is none;shape- an email address, an IBAN or a phone number.valuestring or nullFor a word hidden because it reads as a name, the word, so that you can tell whether it is one: on
GET, to a person signed in who is shown names (an admin or ops). Null otherwise - every other value, and to a key, is never returned.
draftslist of objectrequiredOne entry per draft run: each call's prompt,
prompt_hash,model_ref, outcome and tokens (usage) - the terms (terms), each draft (attempts, each saying where it departs from the terms), the examples asked for (examples) and the hunt for gaps (adversarial) - the version it wrote (policy_id), how many examples the two drafts decide differently (disagreements) and how many one could not run (not_compared), the probe (probe), what publishing would still ask once every rule is confirmed (once_confirmed), the seconds each step took (took), and the ids of the review items it raised (review_items). A run that could not go on saysoutcome: stopped, why in words (reason), what stopped it (error) and the calls it made (calls): the document isfailed, and can be drafted again.review_itemslist of ReviewItemrequired5 fields
review_itemstringrequiredkindstringrequiredstatusstringrequiredpayloadobjectrequiredcreated_atstring or null
created_atstringrequiredupdated_atstringrequiredprogressDraftingProgress or nullWhere its drafting is, while one is under way (
drafting); null otherwise.9 fields
step"queued" | "terms" | "drafts" | "examples" | "gaps" | "again" | "waiting"requiredqueued- asked for, no worker has taken it up yet;terms- the playbook's terms, what every rule and example will name;drafts- the two drafts, side by side;examples- the examples a rule is short of;gaps- the hunt for gaps;again- each rule its owner flagged with a comment, drafted again alone;waiting- to try again (retry_at,why).sincestringrequiredWhen this step began.
job_idstring or nullattemptinteger or nullWhich attempt this is, of
of.ofinteger or nullstarted_atstring or nullWhen this attempt began.
callsmap of CallProgressEach call of the step, by its prompt -
terms,draft_a,draft_b, ... - or, for a rule drafted again, by the rule's id.retry_atstring or nullWaiting: when the next attempt begins.
whystring or nullWaiting: why the last attempt brought no reply.
nextstring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/documents/{document_id}Scope rules:readOne document, masked, and its drafts
The masked text, its clauses, what was masked and why, and what drafting has made of it. No value masked is returned, but a word hidden because it reads as a name: to a person signed in who is shown names - an admin or ops - so that they can tell whether it is one.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Parameters
document_idpath · stringrequired
Responses
200 Successful response
document_idstringrequiredrule_setstringrequireddomainstringrequiredtitlestringrequiredfilenamestringrequiredmedia_typestringrequiredsha256stringrequiredThe file's hash. The file itself is not kept.
statusstringrequireduploaded,drafting,draftedorfailed.textstringrequiredThe masked text, one anchor per clause.
clauseslist of stringrequiredmaskedlist of MaskedItemrequired4 fields
placeholderstringrequiredWhat stands in the text, such as
[[NAME-1]].kindstringrequiredname,email,ibanorphone.why"listed" | "person" | "found" | "shape"requiredWhy it was hidden:
listed- on this upload, or on an earlier document of your account;person- a person of your account, by the name Himmel keeps for them;found- it reads as a name, a given name followed by a capitalised word, and you show it again where it is none;shape- an email address, an IBAN or a phone number.valuestring or nullFor a word hidden because it reads as a name, the word, so that you can tell whether it is one: on
GET, to a person signed in who is shown names (an admin or ops). Null otherwise - every other value, and to a key, is never returned.
draftslist of objectrequiredOne entry per draft run: each call's prompt,
prompt_hash,model_ref, outcome and tokens (usage) - the terms (terms), each draft (attempts, each saying where it departs from the terms), the examples asked for (examples) and the hunt for gaps (adversarial) - the version it wrote (policy_id), how many examples the two drafts decide differently (disagreements) and how many one could not run (not_compared), the probe (probe), what publishing would still ask once every rule is confirmed (once_confirmed), the seconds each step took (took), and the ids of the review items it raised (review_items). A run that could not go on saysoutcome: stopped, why in words (reason), what stopped it (error) and the calls it made (calls): the document isfailed, and can be drafted again.review_itemslist of ReviewItemrequired5 fields
review_itemstringrequiredkindstringrequiredstatusstringrequiredpayloadobjectrequiredcreated_atstring or null
created_atstringrequiredupdated_atstringrequiredprogressDraftingProgress or nullWhere its drafting is, while one is under way (
drafting); null otherwise.9 fields
step"queued" | "terms" | "drafts" | "examples" | "gaps" | "again" | "waiting"requiredqueued- asked for, no worker has taken it up yet;terms- the playbook's terms, what every rule and example will name;drafts- the two drafts, side by side;examples- the examples a rule is short of;gaps- the hunt for gaps;again- each rule its owner flagged with a comment, drafted again alone;waiting- to try again (retry_at,why).sincestringrequiredWhen this step began.
job_idstring or nullattemptinteger or nullWhich attempt this is, of
of.ofinteger or nullstarted_atstring or nullWhen this attempt began.
callsmap of CallProgressEach call of the step, by its prompt -
terms,draft_a,draft_b, ... - or, for a rule drafted again, by the rule's id.retry_atstring or nullWaiting: when the next attempt begins.
whystring or nullWaiting: why the last attempt brought no reply.
nextstring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/documents/{document_id}/draftScope policies:writeDraft rules from a document whose masked text you have read
An optional step: drafting uses a language model on the masked text, and takes minutes, so it runs as a job - the document says drafted or failed when it is done. Before it is queued the stored text is masked again, where nothing drafted from it cites it yet: against your account's people as they are now, the names your other documents hid, and what reads as a name - so a colleague who joined after the upload is hidden too. Two drafts are made independently and compared by what they answer; where they differ, and every hole a third pass finds, becomes a review item. A document is drafted over the law your account has switched on for its domain, or, with none, as your own rules standing alone - covering wherever you act, and dated by a fact of their own. Nothing drafted runs until your rule owner confirms it, and confirming a rule sets the examples drafted for it. A policy changes through its document: drafting a revised one gives the drafter the version it revises, and replaces the policy's draft in place where it has one, so a rule that reads as it did beside the same clause keeps its confirmation. A call that fails costs that call: each reply is kept as it comes back, a retry starts from the first call not done, and an error no retry mends - a key refused, an account out of credit - stops the drafting at once. A drafting that stops says why in its entry of drafts, and the document can be drafted again, reading the replies already back while it reads the same. One document of a policy is drafted at a time (409). Answers 503 in a deployment with no model configured; a policy can always be posted as files instead.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
document_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
202 The draft is queued.
document_idstringrequiredstatus"drafting"requiredjob_idstringrequired
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs. - 503An optional part of the service is not configured in this deployment, or a service it relies on did not answer:
typesays which.
/v1/policies/documents/{document_id}/namesScope policies:writeHide more names in a document not drafted yet
Each name is masked where it stands in the stored text, as the upload masks one: the name to the vault, a placeholder in its place, and the clauses read again. For a document not drafted - uploaded, or failed - so a name you find reading the masked text back is hidden before anything reaches a model; one drafted or being drafted is 409, since what was drafted from it cites its text as it was. Idempotent on Idempotency-Key.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
document_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
nameslist of stringrequiredEach name to hide, as the document writes it; another way of writing it is another entry.
by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
document_idstringrequiredrule_setstringrequireddomainstringrequiredtitlestringrequiredfilenamestringrequiredmedia_typestringrequiredsha256stringrequiredThe file's hash. The file itself is not kept.
statusstringrequireduploaded,drafting,draftedorfailed.textstringrequiredThe masked text, one anchor per clause.
clauseslist of stringrequiredmaskedlist of MaskedItemrequired4 fields
placeholderstringrequiredWhat stands in the text, such as
[[NAME-1]].kindstringrequiredname,email,ibanorphone.why"listed" | "person" | "found" | "shape"requiredWhy it was hidden:
listed- on this upload, or on an earlier document of your account;person- a person of your account, by the name Himmel keeps for them;found- it reads as a name, a given name followed by a capitalised word, and you show it again where it is none;shape- an email address, an IBAN or a phone number.valuestring or nullFor a word hidden because it reads as a name, the word, so that you can tell whether it is one: on
GET, to a person signed in who is shown names (an admin or ops). Null otherwise - every other value, and to a key, is never returned.
draftslist of objectrequiredOne entry per draft run: each call's prompt,
prompt_hash,model_ref, outcome and tokens (usage) - the terms (terms), each draft (attempts, each saying where it departs from the terms), the examples asked for (examples) and the hunt for gaps (adversarial) - the version it wrote (policy_id), how many examples the two drafts decide differently (disagreements) and how many one could not run (not_compared), the probe (probe), what publishing would still ask once every rule is confirmed (once_confirmed), the seconds each step took (took), and the ids of the review items it raised (review_items). A run that could not go on saysoutcome: stopped, why in words (reason), what stopped it (error) and the calls it made (calls): the document isfailed, and can be drafted again.review_itemslist of ReviewItemrequired5 fields
review_itemstringrequiredkindstringrequiredstatusstringrequiredpayloadobjectrequiredcreated_atstring or null
created_atstringrequiredupdated_atstringrequiredprogressDraftingProgress or nullWhere its drafting is, while one is under way (
drafting); null otherwise.9 fields
step"queued" | "terms" | "drafts" | "examples" | "gaps" | "again" | "waiting"requiredqueued- asked for, no worker has taken it up yet;terms- the playbook's terms, what every rule and example will name;drafts- the two drafts, side by side;examples- the examples a rule is short of;gaps- the hunt for gaps;again- each rule its owner flagged with a comment, drafted again alone;waiting- to try again (retry_at,why).sincestringrequiredWhen this step began.
job_idstring or nullattemptinteger or nullWhich attempt this is, of
of.ofinteger or nullstarted_atstring or nullWhen this attempt began.
callsmap of CallProgressEach call of the step, by its prompt -
terms,draft_a,draft_b, ... - or, for a rule drafted again, by the rule's id.retry_atstring or nullWaiting: when the next attempt begins.
whystring or nullWaiting: why the last attempt brought no reply.
nextstring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/documents/{document_id}/shownScope policies:writeShow again a word hidden as a name that is none
A word that reads as a name - a given name followed by a capitalised word - is hidden at upload without being listed (why: found), and GET shows it to an admin or ops. Where one is no name - a branch called after a city, a product - list its placeholder here: it is put back where it stands, as it was first written, the clauses are read again, and it is not hidden for reading as a name in this document again. A name you listed, a person of your account and an address or a number stay hidden (422 invalid-request, not_read_as_a_name). For a document not drafted, uploaded or failed; one drafting or drafted is 409, since what was drafted from it cites its text. Idempotent on Idempotency-Key.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
document_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
placeholderslist of stringrequiredEach word's placeholder, as the text writes it:
[[NAME-3]]. Only a word hidden because it reads as a name (why: found) is shown again.by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
document_idstringrequiredrule_setstringrequireddomainstringrequiredtitlestringrequiredfilenamestringrequiredmedia_typestringrequiredsha256stringrequiredThe file's hash. The file itself is not kept.
statusstringrequireduploaded,drafting,draftedorfailed.textstringrequiredThe masked text, one anchor per clause.
clauseslist of stringrequiredmaskedlist of MaskedItemrequired4 fields
placeholderstringrequiredWhat stands in the text, such as
[[NAME-1]].kindstringrequiredname,email,ibanorphone.why"listed" | "person" | "found" | "shape"requiredWhy it was hidden:
listed- on this upload, or on an earlier document of your account;person- a person of your account, by the name Himmel keeps for them;found- it reads as a name, a given name followed by a capitalised word, and you show it again where it is none;shape- an email address, an IBAN or a phone number.valuestring or nullFor a word hidden because it reads as a name, the word, so that you can tell whether it is one: on
GET, to a person signed in who is shown names (an admin or ops). Null otherwise - every other value, and to a key, is never returned.
draftslist of objectrequiredOne entry per draft run: each call's prompt,
prompt_hash,model_ref, outcome and tokens (usage) - the terms (terms), each draft (attempts, each saying where it departs from the terms), the examples asked for (examples) and the hunt for gaps (adversarial) - the version it wrote (policy_id), how many examples the two drafts decide differently (disagreements) and how many one could not run (not_compared), the probe (probe), what publishing would still ask once every rule is confirmed (once_confirmed), the seconds each step took (took), and the ids of the review items it raised (review_items). A run that could not go on saysoutcome: stopped, why in words (reason), what stopped it (error) and the calls it made (calls): the document isfailed, and can be drafted again.review_itemslist of ReviewItemrequired5 fields
review_itemstringrequiredkindstringrequiredstatusstringrequiredpayloadobjectrequiredcreated_atstring or null
created_atstringrequiredupdated_atstringrequiredprogressDraftingProgress or nullWhere its drafting is, while one is under way (
drafting); null otherwise.9 fields
step"queued" | "terms" | "drafts" | "examples" | "gaps" | "again" | "waiting"requiredqueued- asked for, no worker has taken it up yet;terms- the playbook's terms, what every rule and example will name;drafts- the two drafts, side by side;examples- the examples a rule is short of;gaps- the hunt for gaps;again- each rule its owner flagged with a comment, drafted again alone;waiting- to try again (retry_at,why).sincestringrequiredWhen this step began.
job_idstring or nullattemptinteger or nullWhich attempt this is, of
of.ofinteger or nullstarted_atstring or nullWhen this attempt began.
callsmap of CallProgressEach call of the step, by its prompt -
terms,draft_a,draft_b, ... - or, for a rule drafted again, by the rule's id.retry_atstring or nullWaiting: when the next attempt begins.
whystring or nullWaiting: why the last attempt brought no reply.
nextstring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/documents/{document_id}/withdrawScope policies:writeWithdraw a document never sent to drafting
The document is removed, and its text with it; the audit log keeps that it was withdrawn and by whom, never what it said. One sent to drafting is 409: what was drafted from it cites it. Idempotent on Idempotency-Key.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
document_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
document_idstringrequiredstatus"withdrawn"required
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/{policy_id}Scope rules:readOne version: its files, and what blocks publishing it
checks runs everything publishing would run, now: lint, the consequence check, the policy's own cases over the law (or on their own, for a policy that stands alone), ten cases and a worked example per rule, and the law floor.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Parameters
policy_idpath · stringrequired
Responses
200 Successful response
policy_idstringrequiredrule_setstringrequiredversionstringrequiredstatusstringrequiredeffective_fromstringrequiredrulesintegerrequiredpending_confirmationlist of stringrequiredflaggedlist of stringrequiredfilled_fromFilledFrom or nullrequiredThe template that filled this version and the figures it was filled with; null for one posted as files or drafted from a document.
3 fields
templatestringrequiredThe template's name, as
GET /v1/templateslists it.versionstringrequiredThe template's own version when it filled this one.
valuesobjectrequiredEach blank's figure, by its name: money as
{amount, currency}, the rest whole numbers.
titlestringrequireddomainstringrequiredjurisdictionslist of stringrequiredsits_onlist of stringrequiredThe law versions it is layered over,
rule_set@version. Empty for a policy that stands alone: one for a domain and country we hold no law for, which states outcomes only.filesmap of stringrequiredchecksPublishChecksrequiredEverything publishing would run, run now.
6 fields
publishablebooleanrequiredblockinglist of PublishFindingrequired11 fields
checkstringrequiredlint,consequence,coverage,casesorfloor.codestring or nullrulestring or nullcasestring or nullmessagestring or nullfailureslist of string or nulllawstring or nulllaw_rulestring or nullpolicy_rulestring or nullowedanypaidany
warningslist of PublishFindingrequired11 fields
checkstringrequiredlint,consequence,coverage,casesorfloor.codestring or nullrulestring or nullcasestring or nullmessagestring or nullfailureslist of string or nulllawstring or nulllaw_rulestring or nullpolicy_rulestring or nullowedanypaidany
casesCaseCountsrequired2 fields
passedintegerrequiredfailedintegerrequired
coveragemap of integerrequiredHow many cases reach each rule.
floorFloorSummaryrequired2 fields
lawsintegerrequiredpayments_comparedintegerrequired
drafted_fromDraftedFrom or nullrequiredThe document this version was last drafted from; null for one posted as files.
5 fields
document_idstringrequiredfilenamestringrequiredtitlestringrequiredcreated_atstringrequiredWhen the document was uploaded.
drafted_atstringrequiredWhen the drafting that wrote this version began.
review_itemslist of ReviewItemrequiredWhat its latest drafting raised - examples the two drafts decide differently, holes the third pass found, cases that fail, examples a rule could not answer once altered - and each flag of a rule that stands flagged.
5 fields
review_itemstringrequiredkindstringrequiredstatusstringrequiredpayloadobjectrequiredcreated_atstring or null
superseded_bystring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/{policy_id}Scope policies:writeNew files for a draft, or the draft filled again from its template
A draft changes until it is published; a published version never does. Confirmations of rules the edit did not touch are kept. template and values in place of files fill the draft again from a template - a figure changed, say - under its own version: the rules the change reaches wait for your rule owner again, the rest keep their confirmations.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
policy_idpath · stringrequired
Request body · application/json
filesmap of string or nullEach file's path within the rule set, and its text - the same layout as any rule set version. Posted as a draft;
status: draftinruleset.yaml. Leave it out to fill a template instead.templatestring or nullOne of our templates, by its name (
GET /v1/templates): filled withvalues, it is your policy's document, rules and worked examples, posted as a draft for your rule owner to confirm. In place offiles.valuesobject or nullEvery blank of the template and your figure for it, by the blank's name: money as an integer
amountin minor units with your account'scurrency, days, percent and counts as whole numbers - and every choice and thevalueof the option you pick, by the choice's name. Each is required: the template proposes no figure and no choice.by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
Responses
200 Successful response
policy_idstringrequiredrule_setstringrequiredversionstringrequiredstatusstringrequiredeffective_fromstringrequiredrulesintegerrequiredpending_confirmationlist of stringrequiredflaggedlist of stringrequiredfilled_fromFilledFrom or nullrequiredThe template that filled this version and the figures it was filled with; null for one posted as files or drafted from a document.
3 fields
templatestringrequiredThe template's name, as
GET /v1/templateslists it.versionstringrequiredThe template's own version when it filled this one.
valuesobjectrequiredEach blank's figure, by its name: money as
{amount, currency}, the rest whole numbers.
titlestringrequireddomainstringrequiredjurisdictionslist of stringrequiredsits_onlist of stringrequiredThe law versions it is layered over,
rule_set@version. Empty for a policy that stands alone: one for a domain and country we hold no law for, which states outcomes only.filesmap of stringrequiredchecksPublishChecksrequiredEverything publishing would run, run now.
6 fields
publishablebooleanrequiredblockinglist of PublishFindingrequired11 fields
checkstringrequiredlint,consequence,coverage,casesorfloor.codestring or nullrulestring or nullcasestring or nullmessagestring or nullfailureslist of string or nulllawstring or nulllaw_rulestring or nullpolicy_rulestring or nullowedanypaidany
warningslist of PublishFindingrequired11 fields
checkstringrequiredlint,consequence,coverage,casesorfloor.codestring or nullrulestring or nullcasestring or nullmessagestring or nullfailureslist of string or nulllawstring or nulllaw_rulestring or nullpolicy_rulestring or nullowedanypaidany
casesCaseCountsrequired2 fields
passedintegerrequiredfailedintegerrequired
coveragemap of integerrequiredHow many cases reach each rule.
floorFloorSummaryrequired2 fields
lawsintegerrequiredpayments_comparedintegerrequired
drafted_fromDraftedFrom or nullrequiredThe document this version was last drafted from; null for one posted as files.
5 fields
document_idstringrequiredfilenamestringrequiredtitlestringrequiredcreated_atstringrequiredWhen the document was uploaded.
drafted_atstringrequiredWhen the drafting that wrote this version began.
review_itemslist of ReviewItemrequiredWhat its latest drafting raised - examples the two drafts decide differently, holes the third pass found, cases that fail, examples a rule could not answer once altered - and each flag of a rule that stands flagged.
5 fields
review_itemstringrequiredkindstringrequiredstatusstringrequiredpayloadobjectrequiredcreated_atstring or null
superseded_bystring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/{policy_id}/publishScope policies:writePublish a draft, if nothing stands in the way
Refused with policy-blocked and every finding in blocking when the policy would set a consequence the law decides, when one of its own cases does not come out as it says, when a rule has fewer than ten cases or no worked example (a case naming it), when it would pay less than the law says is owed, or while a drafted example waits for your rule owner to confirm the rule it is an example for. Otherwise the version is published, its drafted examples written as confirmed by the owner, and the one before it superseded. Its rules run once your rule owner confirms them. It applies from effective_from, which a version replacing a published one must give (422), never before that one's date.
Needs a key with the scope policies:write. It changes what your account has decided, which live and test share, so it is done from live: in an account with a live side, a test key gets 403 live-only.
Parameters
policy_idpath · stringrequiredIdempotency-Keyheader · string or nullMakes a retry safe: the same key with the same request within 24 hours gets the first answer again, and nothing is done twice. The same key with a different request is
409 idempotency-conflict. Keys are per environment and per path.
Request body · application/json
by_userstring or nullWho did it, when your key acts for a person: their Himmel id, which the console's Developers page shows them, and Settings' People an admin. They must be in your account, with a role that could do this themselves, and the record keeps it as your key's claim. A key made for an agent names nobody but itself: leave it out. Signed in to the console, leave it out: it is you.
changelogstringWhat changed, and why, in a sentence or two.
effective_fromstring or nullThe date the version applies from: an action of that date or later is checked against it. Required for a version that replaces a published one, and never before that one's date; a first version left without one applies from its own date, its document's. A date in the past is allowed: the actions since then are checked again under it once its rules are confirmed, and every earlier answer stays on record.
Responses
200 Successful response
policy_idstringrequiredrule_setstringrequiredversionstringrequiredstatus"published"requiredeffective_fromstringrequiredwarningslist of PublishFindingrequired11 fields
checkstringrequiredlint,consequence,coverage,casesorfloor.codestring or nullrulestring or nullcasestring or nullmessagestring or nullfailureslist of string or nulllawstring or nulllaw_rulestring or nullpolicy_rulestring or nullowedanypaidany
supersedesstring or nulldiffDiffSummary or null4 fields
changedintegerrequiredaddedintegerrequiredremovedintegerrequiredunchangedintegerrequired
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 409The request conflicts with what is stored: see
detail. - 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/policies/{policy_id}/evaluateScope checkDry-run a version: the law, and the law with it
Send facts, or the id of a stored transaction, and see the law's answer beside the answer with this version layered over it - or, for a policy that stands alone, the policy's answer, with law_only null. A stored transaction is answered with the law its check was answered under, where it fell; a version for other countries than that one is not_covered there, and a transaction of another domain is refused. Nothing is stored, no recipient is created, and confirmations are not applied: it shows what the rules say. A retry is always safe, so it takes no Idempotency-Key.
Needs a key with the scope check. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Parameters
policy_idpath · stringrequired
Request body · application/json
factsobject or nullactorActorIn or nullWho acts, as a check's
transaction.actorsays it: left out, the caller, as a check would record it. A stored transaction says who acted itself, so not besidetransaction_id.3 fields
kind"user" | "agent" | "system"idstring or nullThe agent's own identifier - or, for a person (
kind: user), their Himmel id: from your account's own keys a person of your account (unknown_user,left_the_account).on_behalf_ofstring or nullThe person the agent acts for, as your own systems identify them: an opaque id, never a name or an email address. They need no account here.
transaction_idstring or null
Responses
200 Successful response
dry_runtruerequiredpolicy_idstringrequiredrule_setstringrequiredversionstringrequiredstatusstringrequiredconfirmationsstringrequiredlaw_onlyDeterminedAnswer | UndeterminedAnswer | NotCoveredAnswer | ContestedAnswer or nullrequiredThe law's answer alone; null for a policy that stands alone.
one of 4
One of 4, told apart by
state.effective_datestringrequiredThe date the rules were applied as of.
as_ofstringrequiredThe moment the history was read.
layersLayersrequired2 fields
lawLayerAnswer or nullThe law's answer. Left out where no law set is part of the answer - your policy's alone, for a country we hold no law for or one your account has not switched on.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or nullnot_checkedlist of NotChecked or nullapproveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
policieslist of LayerAnswer or nullYour policies for this domain, in the order they ran.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or nullnot_checkedlist of NotChecked or nullapproveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
engine_versionstringrequiredrecipientRecipientSummary or null4 fields
resolutionstringrequiredresolved,unresolved,probable_matchormissing.recipient_idstring or nullreview_itemstring or nullThe open probable match, where there is one.
fy_totalMoney or nullThis recipient's total for the fiscal year, where the answer's first rule set totals money per recipient per fiscal year: the recipient's other bookings of the year that it counts, as known when the answer was given - this one not included, and later ones too where it counts the whole year. Left out where no such total was read;
history_usednames every total an answer read.2 fields
amountintegerrequiredcurrencystringrequired
history_usedlist of HistoryInput or null5 fields
rule_setstringrequiredinputstringrequiredThe rule set's name for this total, such as
recipient_fy_gifts.countintegerrequiredtransactionslist of HistoryTransactionrequired2 fields
transaction_idstringrequiredeffective_datestring or null
totalMoney | integer | string or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
citationslist of Citation or null4 fields
sourcestringrequiredThe source's key within the rule set, such as
estg.paragraphstring or nullclausestring or nulltext_refstring or nullThe passage in the rule set's own copy of the source,
sources/<file>#<anchor>.
confirmationslist of ConfirmationUsed or null3 fields
rulestringrequiredconfirmed_bystring or nullconfirmed_atstring or null
decisionslist of DecisionRead or nullEach question on this action a person decided, read as its answer: where the question's rule says what each answer leads to, a sign-off or an admin's override issues the action's answer again, and every answer to it after reads the decision while the rule asks the very same question. Left out where none was read.
8 fields
answerstringrequiredThe answer chosen, one of the question's candidates - or
approved, for an approval.questionstring or nullThe question's id. Null for an approval, which answers none.
rulestring or nullThe rule that raises the question, as it asks it. Null for an approval.
decided_bystring or nullWho decided: a person in your account, by id.
method"sign_off" | "override" | "approval" or nullA sign-off by the person the question names, an admin's override of it, or the approval of the person the action's answer named, asked by Himmel.
resolution_idstring or nullThe decision's record, on the answer it was made on.
leads_tostring or nullWhat the answer led to:
continue- on to the rules after the question, which gave the outcome - or the outcome it gives itself. Null for an approval, read from the first rule.approvalstring or nullThe fact the decision stood in for as its decider's approval - where the action recorded none, and the rule that gave the outcome read it - so one person who decides and approves is asked once. Null otherwise.
recheckslist of Recheck or nullThe earlier answers this booking changed, each issued again before this one was given. Left out when it changed none, and on a proposal, which changes nothing until it is reported as executed.
4 fields
new_check_idstring or nullsupersedesstring or nullbooking_datestring or nulloutcomestring or null
supersedes_check_idstring or nullThe earlier answer for the same transaction that this one replaces.
recheck_reasonstring or nullWhy it was issued again: a later transaction, an action taken back (
reversal) or corrected (correction), a link or split between recipients, a question raised about its recipient, the rules changing, a question on it decided (decision), or the action approved by the person its answer named (approval).tracelist of TraceStep or nullEvery rule reached, in order. Left out when the check asked
explain: false.6 fields
rulestringrequiredstagestringrequiredscope,outcomeorconsequence.matchedboolean or nullresolveinteger or nullWhich of the rule's branches applied.
missinglist of string or nullnotestring or null
state: "determined"A dry run's determined answer: stored nowhere, so it has no id.
state: "undetermined_missing_facts"A dry run's answer that needs facts it did not get.
missinglist of MissingFactrequired7 fields
factstringrequiredtypestring or nullcurrencystring or nullFor an amount, the currency it is wanted in: the rule set's. Send it there, or - for an amount in another currency - beside it, as what your own systems record it as in this one (
equivalents).descriptionstring or nullneeded_bystring or nullThe rule that needed it.
review_itemstring or nullFor
recipient_identity: the probable match to answer first.ofHistoryTransaction or nullWhere the fact is another action's: a booking a total counts and cannot read, by its id and its date. Send the fact by completing that booking (
transaction.completes), not in this check.2 fields
transaction_idstringrequiredeffective_datestring or null
state: "not_covered"A dry run's answer that no rule covers.
reason"awaiting_confirmation" | "rule_flagged" | "policy_gap" | "no_rule_matched" | "no_rule_set_for_jurisdiction" | "rule_set_broken"requireddetailstring or nullunconfirmed_ruleslist of string or null
state: "contested"A dry run's answer that turns on a word a person decides.
questionQuestionrequired5 fields
idstringrequiredcandidateslist of stringrequiredreasonstringrequiredWhy this one cannot be settled by the rule.
rulestringrequiredwordingstring or nullThe rule's wording, as your rule owner confirmed it.
signerSigner or null1 field
useranyrequiredThe person who signs off, as your settings name them.
with_policyDeterminedAnswer | UndeterminedAnswer | NotCoveredAnswer | ContestedAnswerrequiredone of 4
One of 4, told apart by
state.effective_datestringrequiredThe date the rules were applied as of.
as_ofstringrequiredThe moment the history was read.
layersLayersrequired2 fields
lawLayerAnswer or nullThe law's answer. Left out where no law set is part of the answer - your policy's alone, for a country we hold no law for or one your account has not switched on.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or nullnot_checkedlist of NotChecked or nullapproveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
policieslist of LayerAnswer or nullYour policies for this domain, in the order they ran.
12 fields
rule_setstringrequiredrule_versionstringrequiredstate"determined" | "undetermined_missing_facts" | "not_covered" | "contested"requiredoutcomestring or nullbasisstring or nulllaw,policyorgoodwill.consequenceslist of Consequence or nullnot_checkedlist of NotChecked or nullapproveranyWho a policy says must approve, where it names one.
handed_toanyWhom a policy hands the action to, where its rule names one: a person in your account, by Himmel id. Where an agent asked about the action, Himmel tells them (
check.handed_over).tenant_facts_usedlist of string or nullYour settings this answer read.
reference_versionsmap of integer | string or nullWhich version of each reference table it read, such as dated VAT rates.
waiting_onstring or nullA policy rule that reads the law's answer waits for the law to settle:
law.
engine_versionstringrequiredrecipientRecipientSummary or null4 fields
resolutionstringrequiredresolved,unresolved,probable_matchormissing.recipient_idstring or nullreview_itemstring or nullThe open probable match, where there is one.
fy_totalMoney or nullThis recipient's total for the fiscal year, where the answer's first rule set totals money per recipient per fiscal year: the recipient's other bookings of the year that it counts, as known when the answer was given - this one not included, and later ones too where it counts the whole year. Left out where no such total was read;
history_usednames every total an answer read.2 fields
amountintegerrequiredcurrencystringrequired
history_usedlist of HistoryInput or null5 fields
rule_setstringrequiredinputstringrequiredThe rule set's name for this total, such as
recipient_fy_gifts.countintegerrequiredtransactionslist of HistoryTransactionrequired2 fields
transaction_idstringrequiredeffective_datestring or null
totalMoney | integer | string or null
not_checkedlist of NotChecked or null2 fields
topicstringrequiredreasonstringrequired
citationslist of Citation or null4 fields
sourcestringrequiredThe source's key within the rule set, such as
estg.paragraphstring or nullclausestring or nulltext_refstring or nullThe passage in the rule set's own copy of the source,
sources/<file>#<anchor>.
confirmationslist of ConfirmationUsed or null3 fields
rulestringrequiredconfirmed_bystring or nullconfirmed_atstring or null
decisionslist of DecisionRead or nullEach question on this action a person decided, read as its answer: where the question's rule says what each answer leads to, a sign-off or an admin's override issues the action's answer again, and every answer to it after reads the decision while the rule asks the very same question. Left out where none was read.
8 fields
answerstringrequiredThe answer chosen, one of the question's candidates - or
approved, for an approval.questionstring or nullThe question's id. Null for an approval, which answers none.
rulestring or nullThe rule that raises the question, as it asks it. Null for an approval.
decided_bystring or nullWho decided: a person in your account, by id.
method"sign_off" | "override" | "approval" or nullA sign-off by the person the question names, an admin's override of it, or the approval of the person the action's answer named, asked by Himmel.
resolution_idstring or nullThe decision's record, on the answer it was made on.
leads_tostring or nullWhat the answer led to:
continue- on to the rules after the question, which gave the outcome - or the outcome it gives itself. Null for an approval, read from the first rule.approvalstring or nullThe fact the decision stood in for as its decider's approval - where the action recorded none, and the rule that gave the outcome read it - so one person who decides and approves is asked once. Null otherwise.
recheckslist of Recheck or nullThe earlier answers this booking changed, each issued again before this one was given. Left out when it changed none, and on a proposal, which changes nothing until it is reported as executed.
4 fields
new_check_idstring or nullsupersedesstring or nullbooking_datestring or nulloutcomestring or null
supersedes_check_idstring or nullThe earlier answer for the same transaction that this one replaces.
recheck_reasonstring or nullWhy it was issued again: a later transaction, an action taken back (
reversal) or corrected (correction), a link or split between recipients, a question raised about its recipient, the rules changing, a question on it decided (decision), or the action approved by the person its answer named (approval).tracelist of TraceStep or nullEvery rule reached, in order. Left out when the check asked
explain: false.6 fields
rulestringrequiredstagestringrequiredscope,outcomeorconsequence.matchedboolean or nullresolveinteger or nullWhich of the rule's branches applied.
missinglist of string or nullnotestring or null
state: "determined"A dry run's determined answer: stored nowhere, so it has no id.
state: "undetermined_missing_facts"A dry run's answer that needs facts it did not get.
missinglist of MissingFactrequired7 fields
factstringrequiredtypestring or nullcurrencystring or nullFor an amount, the currency it is wanted in: the rule set's. Send it there, or - for an amount in another currency - beside it, as what your own systems record it as in this one (
equivalents).descriptionstring or nullneeded_bystring or nullThe rule that needed it.
review_itemstring or nullFor
recipient_identity: the probable match to answer first.ofHistoryTransaction or nullWhere the fact is another action's: a booking a total counts and cannot read, by its id and its date. Send the fact by completing that booking (
transaction.completes), not in this check.2 fields
transaction_idstringrequiredeffective_datestring or null
state: "not_covered"A dry run's answer that no rule covers.
reason"awaiting_confirmation" | "rule_flagged" | "policy_gap" | "no_rule_matched" | "no_rule_set_for_jurisdiction" | "rule_set_broken"requireddetailstring or nullunconfirmed_ruleslist of string or null
state: "contested"A dry run's answer that turns on a word a person decides.
questionQuestionrequired5 fields
idstringrequiredcandidateslist of stringrequiredreasonstringrequiredWhy this one cannot be settled by the rule.
rulestringrequiredwordingstring or nullThe rule's wording, as your rule owner confirmed it.
signerSigner or null1 field
useranyrequiredThe person who signs off, as your settings name them.
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 413The request's body is larger than the operation takes, refused before any of it is read (
body-too-large): a policy's files at most 5 MB, any other body 1 MB - and an uploaded file at most 20 MB (file-too-large). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Sandbox
/v1/sandbox/examples/{rule_set}Scope rules:readThe rule set's own test cases, as requests you can send
Each example is a sequence: send its requests in order, because an answer can depend on what was sent before it - a customer's third goodwill credit in 90 days is answered in the light of the first two. Each request says who acts where the case does, and one the case asks about before it is taken is a proposal: what then becomes of it is yours to report. A proposal is dated the day it is asked, so an example asked about is served dated today, every date in it moved with it - a refund five days after delivery stays five days after. Recipient ids, and the ids of who acts, carry recipient_suffix, new on every call, so examples sent twice do not add up. expect is the answer the case expects under needs_tenant_facts, and assumes says what else it takes for granted that no request carries - rules not yet confirmed or flagged, recipients linked, when things happened, nobody acting - so where your account differs, its answer does too; rules answer only once your rule owner has confirmed them. Each is served in your account's terms: a person it names through a setting is the person your account names there, an action taken dated before the version starts is moved into it with every date of the example, a key made for an agent is served its agent acting, and one of your account's own keys the one agent your account has switched on - what cannot be is said in assumes (people, before_the_version, agents), and an example served as your agent, where a total counts each agent's actions apart, says it adds to that agent's totals (agent_totals). source: api is one of ours rather than the rule set's: a booking in a country it does not cover, for a rule set that names its countries. A rule set is served to an account that has it on.
Needs a key with the scope rules:read. From a key made for an agent it reads that agent's own alone: another agent's action is 403 not-the-agents-action, another agent's record 403 insufficient-scope.
Parameters
rule_setpath · stringrequiredversionquery · string or nullstatequery · string or nullOnly examples that expect this state
Responses
200 Successful response
rule_setstringrequiredversionstringrequiredrecipient_suffixstringrequiredAppended to every recipient id in this response, and to every id of who acts, and new on every call, so examples sent twice do not add up into one recipient's yearly total, or one actor's day.
exampleslist of SandboxExamplerequired8 fields
idstringrequiredsource"case" | "api"requiredcase: one of the rule set's own test cases.api: one of ours - a booking in a country the rule set does not cover - which no rule of the set answers.examplestringrequiredexpectobjectrequiredThe answer the case expects.
needs_tenant_factsobjectrequiredThe settings that answer assumes. Your own may differ.
assumesExampleAssumesrequiredWhat else that answer takes for granted: empty where it is nothing.
12 fields
unconfirmedlist of string or nullRules it takes as not yet confirmed by your rule owner.
flaggedlist of string or nullRules it takes as flagged.
linkedlist of list of string or nullIts recipients it takes as one person, linked by your rule owner: each pair a record and the identity it counts as.
triggerobject or nullThe change it expects answers to be issued again from -
reason, and for a link or split itsrecipients- where no request of its own makes that change.as_ofstring or nullThe moment it is answered as of.
atmap of string or nullWhen it takes its transactions to have happened, by the case's own id for each -
casefor the one it asks about: a request sent now happened now.nobody_actsboolean or nullIt takes it that nobody is recorded as acting where it names nobody, and its rules read who acts. Sent signed in to the console, you are recorded instead.
decisionslist of object or nullThe questions it takes as decided on its action -
question,answer,by- which no request carries: the person the question names signs it off on the answer that asked it (POST /v1/checks/{id}/resolution), and the action is answered again.peoplelist of string or nullThe people it names - by the case's own ids - that your account has nobody apart for: a setting it names a person through that your account names nobody in, a person in no setting who is nobody of your account's, or two of its people your account names one person for. Every other person it names is served as the person your account names.
before_the_versionstring or nullThe first day of the version served, where its own action is taken before it and could not be moved into it - the version starting after today, say - so no version of it answers the action.
agentslist of string or nullThe agents it names acting - by the case's own ids - that it could not be served as an agent of yours: sent with one of your account's own keys, which names only an agent your account has registered, where your account has several switched on or none. Its requests name the case's agent with the fetch's suffix, which that key is refused for (
unknown_agent): send it with the key of the agent it is about.agent_totalsstring or nullThe agent of yours it is served as, where a total of its rule set counts each agent's actions apart: what it sends adds to that agent's own totals in the environment it is sent in, beside whatever the agent did there, so its answer may differ from what it expects.
sendlist of ExampleSteprequired3 fields
method"POST"requiredpathstringrequiredbodyobjectrequired
rulestring or null
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 404Nothing with that id or name exists for this account.
- 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
/v1/sandbox/policy-sampleScope rules:readA synthetic company policy, as a document and as the rules it should draft to
"Beispiel GmbH", invented and labelled so in its first line, written to hold the hard cases: a limit with a named approver, a per-recipient cap stricter than the law's, a vague word left to a named signer, a kind of entertainment it never mentions, and a clause that tries to say what is deductible, which publishing refuses. files can be posted to POST /v1/policies as they are.
Needs a key with the scope rules:read. What it reads is your whole account's, so a key made for an agent, which reads its own agent's alone, gets 403 insufficient-scope.
Responses
200 Successful response
synthetictruerequiredrule_setstringrequireddocumentstringrequiredThe sample policy as a document. Invented, and labelled so.
filesmap of stringrequiredThe rule set it drafts to, ready for
POST /v1/policies.noteslist of stringrequired
- 401No API key was sent, or it is not in use (
unauthorized). - 403The caller may not do this, and
typesays why: the key or role lacks the scope, the rule set is not enabled for this account, the person signed in belongs to no account, names were asked for by a caller that is not shown them, or a request acting in test tried to change the account's settings (live-only). - 422The request, or a fact in it, is not in the documented shape - a query parameter the operation does not take included, which is named (
unknown_parameter) rather than ignored - or itsHimmel-Envdoes not fit the caller. Missing facts are not errors. - 429More requests in a minute than the key's or the person's limit (
rate-limited) - or, opening an account, more accounts in a day than the deployment opens, withRetry-Aftersaying when to try again. - 500Something failed on our side.
X-Request-Ididentifies it in our logs.
Service
/healthzNo key neededWhether the service can answer
A database ping and a full check run by the engine on fixed facts: 200 and ok when both pass, 503 and degraded when either fails - a database that has not answered within two seconds is unreachable. Needs no key.
Responses
200 The service can answer.
status"ok" | "degraded"requiredengine_versionstringrequiredengine"ok" | "failing"requireddatabase"ok" | "unreachable"required
- 503Degraded: the database or the engine failed, said which.