Skip to content

Traverse from Rail instruction

POST
/v1/object-types/hospitality.rail_instruction/objects/{id}/traverse
curl --request POST \
--url https://api.aerandil.com/v1/object-types/hospitality.rail_instruction/objects/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/traverse \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "as_of": "2026-04-15T12:00:00Z", "branch": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "cursor": "example", "direction": "out", "limit": 1, "link_type": "hospitality.link.rail_instruction_for_payment", "role": "example" }'

RPC-shaped traversal. Pick the edge by (link_type, direction) or by role — the registry resolves a role name (e.g. managed_by, direct_reports) to the underlying link side. link_type wins when both are present.

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.

id
required
string format: uuid

Object id (UUID v7, server-generated at create time).

Media typeapplication/json

Body for POST .../traverse. At least one of link_type or role MUST be supplied — the server returns 422 missing_traversal_target when both are absent. link_type wins when both are set.

object
as_of

RFC3339 temporal window: return neighbours whose edge was in effect at this instant ([effective_from, effective_to)) instead of now.

string format: date-time
branch

Traverse through an open branch’s overlay view instead of the canonical (main) plane. Does not compose with as_of (422).

string format: uuid
cursor
string
direction

Edge direction. Optional when the binding is asymmetric.

Allowed values: out in
limit
integer
>= 1 <= 500
link_type

API name of the link type to traverse. Narrowed to link types that bind the source. Wins over role.

Allowed values: hospitality.link.rail_instruction_for_payment hospitality.link.rail_instruction_for_stay
role

Link-side role name (e.g. managed_by, direct_reports). Mutually substitutable with link_type — the registry resolves the role to its underlying link and direction.

string

Neighbours along the resolved link.

Media typeapplication/json
object
data
required
Array<object>
object
created_at
required
string format: date-time
id
required
string format: uuid
object_type
required
string
properties
required
object
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
direction
required
Allowed values: out in
has_more
required
boolean
link_type
required
string
next_cursor
string
Example
{
"data": [
{
"scope": {
"level": "tenant"
}
}
],
"direction": "out"
}

No object with that id, or link type unknown.

Validation error — must supply link_type or role.