Skip to content

Search Guest message

POST
/v1/object-types/hospitality.guest_message/search
curl --request POST \
--url https://api.aerandil.com/v1/object-types/hospitality.guest_message/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.

Typed shadow of a single inbound or outbound message. The full payload lives in the external messaging system (Twilio, WhatsApp Business, Mews Conversations, HiJiffy / Canary inbox, OTA Messaging API, voice-IVR transcript store); Aerandil holds the audit-grade decision-time fields plus an optional external_record_reference pointer to the full content. PCI-DSS 4.0 hard-validator-enforced: no Luhn-matching digit sequence may appear in redacted_excerpt. The content_hash is the tamper-evidence anchor.

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 channel channel_thread_id direction received_at author_kind author_principal redacted_excerpt content_hash word_count detected_language ingress_principal template_id purpose delivery_state delivery_address vendor_message_id delivery_attempted_at delivery_attempts delivery_error

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.guest_message
properties
required
object
author_kind
Who composed the message (guest / staff_human / staff_agent / system)
string
Allowed values: guest staff_human staff_agent system
author_principal
`principal.stable_id()` of the author when not the guest
string
channel
required
Communication channel
string
Allowed values: sms whatsapp email web_chat app_chat voice_ivr ota_inbox social_dm in_room_device other
channel_thread_id
External system thread identifier (Booking.com conversation_id, Twilio MessageSid, WhatsApp wamid, etc.)
string
content_hash
SHA-256 of the original message bytes (tamper-evidence)
string
conversation_ref
required
The conversation container
string format: uuid
delivery_address
The phone number or email address the message goes to, resolved when it was recorded
string
delivery_attempted_at
When the adapter last tried to send it
string format: date-time
delivery_attempts
How many times the adapter has tried to send it
integer
delivery_error
Why the last send failed, in words the desk can act on
string
delivery_state
Where the kernel's own send stands: queued, sending (claimed by the worker), sent, or failed
string
Allowed values: queued sending sent failed
detected_language
BCP-47 — may differ from `conversation.language` (mid-thread switches)
string
direction
required
Inbound (from guest) or outbound (to guest)
string
Allowed values: inbound outbound
id
required
Message id
string
ingress_principal
`principal.stable_id()` of the service or human that recorded the message
string
purpose
Why the house wrote: a reply, a service message, marketing, or a waitlist offer
string
Allowed values: reply service marketing waitlist_offer payment_request card_refused
received_at
required
When the message arrived (inbound) or was sent (outbound)
string format: date-time
redacted_excerpt
PII-stripped excerpt for the audit trail (default cap 280 chars)
string
redactions_applied
required
Per-message redaction kinds
Array<string>
Allowed values: pan cvv government_id health_disclosure child_safeguarding other_pii
template_id
WhatsApp Business template id (required outside the 24-hour service window)
string
vendor_message_id
The delivery vendor's id for the send (Twilio MessageSid, SMTP Message-ID)
string
waitlist_entry_ref
The waitlist entry whose offer this message carries; its claim token is minted when the message is sent
string format: uuid
word_count
Optional word count (triage-cost analytics)
integer
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.guest_message",
"properties": {
"author_kind": "guest",
"channel": "sms",
"delivery_state": "queued",
"direction": "inbound",
"purpose": "reply",
"redactions_applied": [
"pan"
]
},
"scope": {
"level": "tenant"
}
}
]
}

Validation error — unknown property or filter type mismatch.