Skip to content

Search Rail instruction

POST
/v1/object-types/hospitality.rail_instruction/search
curl --request POST \
--url https://api.aerandil.com/v1/object-types/hospitality.rail_instruction/search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "branch": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "cursor": "example", "filters": [ { "property": "id", "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.

One thing the card rail is to do at the processor once it can be reached again — OPERA’s offline settlement queue. Written by the rail (queue_rail_instruction) when the processor was unreachable (a transport failure, a 5xx, a 429) during a deferrable verb: a hold captured at check-out (capture), a hold released (void), a refund (refund), a departed stay’s late charges (charge_off_session), the desk’s Top up now for an in-house stay (top_up, continuing the stay’s open top-up attempt). Never a check-in’s authorisation — that hold is placed because the desk needs the answer now. attempt_id is written before the processor is asked again and every processor idempotency key for the instruction derives from it, so a retry is the same request and a capture that reached the processor once is never taken twice. The rail’s drain claims it (sending), asks the processor, and records the outcome through the same ledger verbs the online path uses: done; refused with the processor’s words, never retried; or queued again with an exponential backoff (not_before) until the cap or the key’s window, then abandoned for the GM. A processor that replayed a saved failure under the key has spent that attempt: what it did is read back, and when nothing moved the instruction is queued again under a new attempt_id. The desk may take a queued one back (cancel_rail_instruction → cancelled), never one the drain is sending. The night audit drains whatever is queued, and its close lists what is still open.

Media typeapplication/json
object
branch

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.

string format: uuid
cursor

Opaque cursor from a prior response’s next_cursor. Pass back verbatim; do not introspect.

string
filters

Conjunctive list of predicates. Empty or omitted matches every row in scope, capped by limit.

Array
One of:
object
property
required
Allowed value: id
type
required
Allowed value: eq
value
required
string
limit

Page size. Server defaults to 50, silently clamps at 500 (AIP-158 §3).

integer
>= 1 <= 500
order

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).

string
default: asc
Allowed values: asc desc
property_id

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.

string format: uuid
scope
One of: discriminator: level
object
level
required
string
Allowed value: tenant
Allowed values: tenant
sort_by

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).

string
default: created_at
Allowed values: created_at updated_at id kind state payment_id stay_id property_id attempt_id void_reason refund_reason queued_by attempts not_before queued_at last_attempt_at finished_at queued_because processor_words outcome_detail result_payment_id

Search results, ordered by (sort_by, id) in the requested order (ascending by default).

Media typeapplication/json
object
data
required
Array<object>
object
created_at
required
string format: date-time
id
required
string format: uuid
object_type
required
Allowed value: hospitality.rail_instruction
properties
required
object
amount
required
Rail instruction amount

What it moves: the capture to take, the hold to release, the refund to give, the collection asked for

object
amount
required
string format: decimal
currency
required
string format: iso-4217
attempt_id
required
The persisted attempt every processor idempotency key for the instruction derives from — a refund's is the key its online attempt was sent under, a collection's the stay's open collection attempt
string
attempts
required
How many times the drain has asked the processor
integer
finished_at
When it was done, refused, abandoned or cancelled
string format: date-time
id
required
Rail instruction id
string
kind
required
capture, void, refund, charge_off_session or top_up
string
Allowed values: capture void refund charge_off_session top_up
last_attempt_at
When the drain last asked the processor
string format: date-time
not_before
required
When the drain may ask again — the backoff after an unreachable rail
string format: date-time
outcome_detail
What the instruction came to, in the rail's words
string
payment_id
The payment a capture, release or refund acts on (its object id) — the rail_instruction_for_payment edge's target
string
processor_words
The processor's last words: its refusal, or the kind of failure that kept it from being reached — processor handles left out
string
property_id
required
The house the instruction is for (its object id)
string
queued_at
required
When the rail wrote the instruction down
string format: date-time
queued_because
What kind of failure the rail met when the instruction was written (`server_error (503)`, `timeout`, …) — a kind, never the request path, which names the processor's handle
string
queued_by
Who asked for it: the principal the queued request carried (its JSON), under whose name the drain records the ledger's leg — the online attempt's, not the rail's (F4, 2026-10-19)
string
refund_reason
Why a queued refund gives money back
string
Allowed values: duplicate fraudulent requested_by_customer reservation_cancelled deposit_return service_recovery overcharge_correction no_show_policy_exception package_component_refund membership_cancellation chargeback_prevention other
result_payment_id
The payment row the outcome recorded, when it made one (a refund's leg)
string
reverse_transfer
Whether a queued refund pulls the hotel's transfer back — the online attempt's form, kept so the drained retry under the same key is the same request (F4, 2026-10-19)
boolean
state
required
queued, sending, done, refused, abandoned or cancelled
string
Allowed values: queued sending done refused abandoned cancelled
stay_id
The stay a collection or a top-up is for (its object id) — the rail_instruction_for_stay edge's target
string
void_reason
Why a queued release releases the hold (the void's reason)
string
Allowed values: duplicate fraudulent requested_by_customer abandoned review_declined authorisation_expired reservation_cancelled guest_disputed_pre_arrival released_at_departure
provenance

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
pins
object
key
additional properties
object
pinned_at
string format: date-time
pinned_by
object
reason
required
string
properties
object
key
additional properties
object
external_id
string
recorded_at
required
string format: date-time
source
required
string
source_updated_at
string format: date-time
stream
string
scope
required
One of: discriminator: level
object
level
required
string
Allowed value: tenant
Allowed values: tenant
tenant_id
required
string format: uuid
updated_at
required
string format: date-time
version
required
integer
>= 1
has_more
required
boolean
next_cursor

Cursor for the next page; omitted when the result set is exhausted.

string
Example
{
"data": [
{
"object_type": "hospitality.rail_instruction",
"properties": {
"kind": "capture",
"refund_reason": "duplicate",
"state": "queued",
"void_reason": "duplicate"
},
"scope": {
"level": "tenant"
}
}
]
}

Validation error — unknown property or filter type mismatch.