Search Invoice
const url = 'https://api.aerandil.com/v1/object-types/hospitality.invoice/search';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"branch":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","cursor":"example","filters":[{"property":"number","type":"eq","value":"example"}],"limit":1,"order":"asc","property_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","scope":{"level":"tenant"},"sort_by":"created_at"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.aerandil.com/v1/object-types/hospitality.invoice/search \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "branch": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "cursor": "example", "filters": [ { "property": "number", "type": "eq", "value": "example" } ], "limit": 1, "order": "asc", "property_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "scope": { "level": "tenant" }, "sort_by": "created_at" }'Search for instances. Filters eq, contains, gte and lte AND-compose; or / not are additive follow-ups. Pages with an opaque cursor; the +1 fetch returns has_more without a second round-trip. Ordered by sort_by (default created_at) in order (default ascending), id breaking ties; rows with no value for a property key sort last.
The numbered, sealed document a folio becomes when it is issued — a tax invoice, or a credit note reversing one. Carries snapshots of the issuer, the recipient, every ledger line and the per-rate tax bands, so the document renders from itself and never changes after issue.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Optional open-branch id. Search composes that branch’s copy-on-first-write overlay instead of main, so a preview reads its own hypothetical writes. Omit to read main.
Opaque cursor from a prior response’s next_cursor. Pass back verbatim; do not introspect.
Conjunctive list of predicates. Empty or omitted matches every row in scope, capped by limit.
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
- object
object
object
Case-insensitive substring needle.
object
object
object
object
object
Case-insensitive substring needle.
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
object
Case-insensitive substring needle.
object
object
object
object
Case-insensitive substring needle.
object
object
object
object
Case-insensitive substring needle.
object
object
object
object
Case-insensitive substring needle.
object
object
object
object
Case-insensitive substring needle.
Page size. Server defaults to 50, silently clamps at 500 (AIP-158 §3).
Direction of sort_by: asc (oldest / smallest first) or desc. A cursor is bound to the sort_by and order it was minted under; another pair is refused (422).
The house a desk stands in: keeps this property’s rows (property- or venue-scoped there) and every row scoped to no property (tenant, brand, portfolio), and drops a sibling house’s — the meaning property_id has on the event tail.
object
object
object
object
object
What the page is ordered by: the row’s created_at or updated_at, or a property whose type orders — strings, enums and dates as text, ints, decimals and durations as numbers, datetimes as instants. Rows with no value sort last in either direction. A property the caller is not cleared to read is refused (403).
Responses
Section titled “Responses”Search results, ordered by (sort_by, id) in the requested order (ascending by default).
object
object
object
Zero on a settled stay; the transferred balance on a folio settled to a company’s A/R account.
object
Amount paid
object
SHA-256 over the canonical snapshot. With previous_hash this chains issued documents, which is what the modern fiscal regimes actually check — they put integrity on a chain over issued records rather than on the integer being dense.
Only set when amount_due is above zero — the company-billed case.
Gross total
object
The instant of issue. Also the renderer’s fixed timestamp, which is what makes a re-render byte-identical to the stored PDF.
The property’s business date of issue — an action parameter, never Utc::now(). This is the document’s date for tax purposes.
The property’s legal identity, as it printed.
object
object
object
invoice, or credit_note reversing one.
BCP 47 tag the document was rendered in.
The printed lines, snapshotted at issue.
object
object
object
object
Net total
object
The legal document number, e.g. STAN-2026-000123. Allocated from the property’s series inside the issuing transaction and never reissued.
The previous issued document’s content_hash — one chain per property, spanning invoices AND credit notes together, absent only for the property’s first. Deliberately NOT per series: Spain’s Orden HAC/1177/2024 art. 7(c) requires a system to produce “una unica cadena”, and art. 7(d) that the chain carry both the alta and the anulacion records; Basque TicketBAI chains to the previous issued invoice regardless of series. The number series stays per kind; the chain is one strand. Backwards here makes Veri-factu a rebuild rather than a configuration.
Who the document was addressed to, as it printed.
object
object
Unmarked twin of recipient.kind, so the board can filter company documents without reading the PII snapshot.
Which renderer produced the stored PDF. A later engine upgrade may change bytes, so a re-render under a different version is a copy, not the original.
The bare counter value number was rendered from. Kept so a gap in a series is detectable without parsing the formatted number.
The sequence this number came from — {property_id}:{kind}:{yyyy}. Series are annual and per document kind: France requires numbering that is chronological and continuous within a series, and a credit note sharing the invoice run cannot satisfy that.
Issued under the small-amount rule (UK £250, DE €250) without recipient details. Never true for a company recipient — the whole point of their document is input-tax recovery.
First day of the period supplied — the stay’s arrival. Printed as the Leistungszeitraum.
Last day of the period supplied — the stay’s departure, which is also the UK basic tax point for a completed stay.
Per-rate bands, derived from the charges’ own tax_application rows — the rule’s rate, not a recomputation.
object
object
object
Tax total
object
Per-property source attribution and pins. An entry under properties means the property’s current value came from that source (on the source’s own clock, source_updated_at); an entry under pins is a human override protecting the property from sourced writes.
object
object
object
object
object
object
object
object
object
object
object
Cursor for the next page; omitted when the result set is exhausted.
Example
{ "data": [ { "object_type": "hospitality.invoice", "properties": { "kind": "invoice", "recipient_kind": "person" }, "scope": { "level": "tenant" } } ]}Validation error — unknown property or filter type mismatch.