Skip to main content
POST https://api.humalike.com/v1/turn-taking/actions/respond
Submit your agent’s drafted reply after a speak decision. Turn-taking rewrites it into 1–5 short chat messages, scheduled a beat apart, and delivers them on the thread’s WebSocket as turn_taking.message events (with a turn_taking.typing indicator around them). The response tells you what was scheduled; the messages themselves arrive over the socket. See Receiving messages from the agent. Pass the turn_epoch from the submit_messages that returned speak. If a newer batch has arrived since, the draft is stale: nothing is scheduled, nothing is billed, and the response is superseded: true. This call is billable, unless it is superseded. See Billing.

Authorization

Authorization
string
required
Your bearer token: Bearer <token>. See Authentication.

Request body

thread_id
string
required
The thread to reply in.
content
string
required
The agent’s drafted reply, 1–4000 characters. This is the text that gets paced into chat messages.
turn_epoch
integer
required
The turn_epoch from the deciding submit_messages. Required: a reply whose epoch is behind the thread’s current turn is dropped as stale (an interruption).
system_prompt
string
Optional system-prompt text — the agent’s identity, character, and style — applied while rewriting the reply so it stays in the agent’s voice. Up to 8000 characters. Sent per request.
Request
{
  "thread_id": "b9c1e4f0-2a77-4f6e-9d2a-1f0c8e5b3a44",
  "content": "Yes — I can take a look. Can you share the export you tried and roughly when it failed?",
  "turn_epoch": 7
}

Response

scheduled
ScheduledMessage[]
The chat messages the reply was paced into, in delivery order. Each is also pushed over the WebSocket as a turn_taking.message event at its deliver_at. Empty when superseded is true.
superseded
boolean
true when the draft was stale because a newer batch arrived first. Nothing was scheduled and nothing was billed — draft again against the latest decision. false on a normal reply.
200 OK
{
  "scheduled": [
    {
      "id": "f2a0c6d1-8e3b-4a90-9c7e-2b1d4f6a0c11",
      "thread_id": "b9c1e4f0-2a77-4f6e-9d2a-1f0c8e5b3a44",
      "content": "Yes — I can take a look.",
      "position": 0,
      "deliver_at": "2026-06-16T12:00:01Z",
      "status": "scheduled"
    },
    {
      "id": "a7b3e9c2-1d44-4f08-bb6a-90c2e7d5f3a2",
      "thread_id": "b9c1e4f0-2a77-4f6e-9d2a-1f0c8e5b3a44",
      "content": "Can you share the export you tried and roughly when it failed?",
      "position": 1,
      "deliver_at": "2026-06-16T12:00:02Z",
      "status": "scheduled"
    }
  ],
  "superseded": false
}
A superseded reply schedules nothing:
200 OK (superseded)
{
  "scheduled": [],
  "superseded": true
}

Errors

StatusCodeWhen
401UNAUTHORIZEDThe bearer token is missing, invalid, or expired.
402PAYMENT_REQUIREDYour account can’t cover this request. You are not charged.
403forbiddenThe token is valid but not allowed here.
422VALIDATION_ERRORThe body is malformed, content is empty or too long, or turn_epoch is missing.
502UPSTREAM_ERRORA dependency the request relies on was unavailable. Retry with backoff.
A stale draft is not an error — it returns 200 with superseded: true. See Errors for the envelope shape.

Example

curl https://api.humalike.com/v1/turn-taking/actions/respond \
  -H "Authorization: Bearer $HUMALIKE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "thread_id": "b9c1e4f0-2a77-4f6e-9d2a-1f0c8e5b3a44",
    "content": "Yes — I can take a look. Can you share the export you tried and roughly when it failed?",
    "turn_epoch": 7
  }'

Next