Skip to main content
A search usually ends within the 20 seconds that POST /v1/hotel_ai_search waits. When it does not, the call answers 202 and the search goes on as a task that you read or stream until it ends. Pick one of three ways to get the result.

Wait in the call

Without a Prefer header the call waits up to 20 seconds.
  • 200 when the turn ended in that time. status is completed, input_required, failed or canceled. Nothing more to read.
  • 202 when the search is still running. status is working, and the response carries:
Prefer: wait=N sets the wait to N seconds, from 0 to 20. A larger value is applied as 20, and Preference-Applied says so (wait=30 is answered with Preference-Applied: wait=20). An unreadable Prefer value is ignored and the default wait applies.

Read the task

The task read answers 200 with the same body as POST. Read it every Retry-After seconds while status is working, and stop at any other status. While the search runs, the task carries the early reply: message says what is being searched, and criteria holds it.
A turn that has not ended 90 seconds after it started ends as failed with error.code deadline_exceeded. Send the message again.

Stream the events

Send Accept: text/event-stream on POST to receive the turn as Server-Sent Events on the same connection.
A search that ends with hotels sends six events:
Every event carries task_id and context_id. id is the event’s sequence number in the task. The stream ends after the event that ends the turn. Comment lines (: keep-alive) arrive every 15 seconds and carry no event; most SSE clients skip them.

Resume a stream

A stream also closes after 45 seconds without an event that ends the turn, or when the connection drops. Reconnect to the task’s events with the id of the last event you received:
The stream resumes with the next event (id: 3 here), with no gap and no repeat. Without Last-Event-ID, or with a value that is not a number, the stream starts from the first event of the task. For a task that has already ended, the stream sends the remaining events and closes. GET .../events always answers with a stream, whatever the Accept header. When POST with Accept: text/event-stream is refused (400, 404, 410, 422, or an authentication error), the answer is the JSON error, with no stream.
  • A task that is working or input_required is canceled: 200 with status: "canceled". It writes no further result.
  • A task that has already ended answers 409 CONFLICT, for example The task has already ended (canceled).
You do not need to cancel before sending a correction. A new message in the conversation replaces a search that is still running; see Conversations.

Retry a message safely

Send an Idempotency-Key header (1 to 200 characters) with each message when your client may send it twice, for example after a timeout or a 502, 503 or 504.
  • A retry with the same key does not send a second message. It answers the first message again: its stored answer once that turn is over, or the same wait as a new message while it runs.
  • Keys belong to your account, not to a conversation: every API key of the account shares them. The body of a retry is not compared with the first one, so a retry with a different text still gets the first answer. Use a new key for each new message.