Skip to main content
This API authenticates with Client SDK keys (osk_ prefix). This is a separate endpoint from the REST API Chat (OpenAI-compatible).

Send Message

POST /v1/chat/{persona_id}
Sends a message to a persona. Omit thread_id to create a new thread, or include it to continue an existing conversation. Available models can be queried via GET /v1/models.

Request

New Thread (model required):
{
  "model": "shopping-assistant",
  "messages": [
    {
      "role": "user",
      "content": "What should I have for dinner tonight?"
    }
  ]
}
Continue Thread (model not needed):
{
  "thread_id": "thr_a1b2c3d4e5f6",
  "messages": [
    {
      "role": "user",
      "content": "Tell me the curry ingredients"
    }
  ]
}
FieldTypeRequiredDescription
modelstringRequired for new threadModel name (from GET /v1/models)
thread_idstringNoExisting thread ID (omit to create a new thread)
messagesarrayYesMessage array
messages[].rolestringYesuser
messages[].contentstringYesMessage content
The model specified when creating a new thread is fixed to that thread. Subsequent messages in the same thread do not need the model field.

Response

{
  "success": true,
  "data": {
    "thread_id": "thr_a1b2c3d4e5f6",
    "is_new_thread": true,
    "user_message": {
      "message_id": "msg_u1v2w3x4y5z6",
      "role": "user",
      "content": "What should I have for dinner tonight?",
      "created_at": "2026-04-16T10:00:00Z"
    },
    "assistant_message": {
      "message_id": "msg_a7b8c9d0e1f2",
      "role": "assistant",
      "blocks": [
        {
          "type": "text",
          "content": "How about a warm beef curry on a rainy day like this?"
        },
        {
          "type": "product_list",
          "title": "Spicy Beef Curry Ingredients",
          "badge": "AI Pick",
          "items": [
            { "id": "p_001", "name": "Premium Beef Sirloin (300g)", "section": "Meat Counter", "price": 24500 },
            { "id": "p_002", "name": "Organic Potato & Carrot Set", "section": "Fresh Produce", "price": 4800 }
          ],
          "actions": [
            { "id": "view_recipe", "label": "View details", "style": "primary" },
            { "id": "show_alternates", "label": "Other suggestions", "style": "secondary" }
          ]
        },
        {
          "type": "suggestion",
          "content": "Would you like a red wine recommendation to pair with the curry?",
          "actions": [
            { "id": "wine_yes", "label": "Recommend", "style": "primary" },
            { "id": "wine_no", "label": "No thanks", "style": "secondary" }
          ]
        }
      ],
      "created_at": "2026-04-16T10:00:01Z"
    }
  }
}

Block Types

Assistant responses are returned as a structured blocks array.
TypeDescriptionKey Fields
textText messagecontent
imageImageurl
product_listProduct listingtitle, items[], actions[]
suggestionAI recommendation/suggestioncontent, actions[]

Actions

The actions included in blocks provide information for handling user interactions on the client side.
FieldDescription
idAction identifier
labelButton text
styleprimary / secondary / text

Get Thread

GET /v1/chat/{persona_id}/threads/{thread_id}
Retrieves thread metadata (message bodies are not included).

Response

{
  "success": true,
  "data": {
    "thread_id": "thr_a1b2c3d4e5f6",
    "title": "Dinner Menu Recommendations",
    "status": "ACTIVE",
    "message_count": 4,
    "started_at": "2026-04-16T10:00:00Z",
    "last_active_at": "2026-04-16T10:30:00Z"
  }
}
StatusDescription
ACTIVEIn progress
CLOSEDEnded

Close Thread

POST /v1/chat/{persona_id}/threads/{thread_id}/close
Closes a thread. The persona status transitions from CHAT to READY.

Response

{
  "success": true,
  "data": {
    "thread_id": "thr_a1b2c3d4e5f6",
    "thread_status": "CLOSED",
    "persona_status": "READY",
    "closed_at": "2026-04-16T10:35:00Z"
  }
}
Requesting on an already-closed thread returns 409 Conflict:
{
  "success": false,
  "error": {
    "code": "ALREADY_CLOSED",
    "message": "thread is already closed"
  }
}

List Messages

GET /v1/chat/{persona_id}/threads/{thread_id}/messages
Retrieves the message list for a thread (oldest first). Supports cursor-based pagination.

Query Parameters

ParameterTypeDefaultDescription
limitinteger50Number of messages to return (max 100)
beforestring-Load messages before this message_id (reverse paging)

Response

{
  "success": true,
  "data": {
    "thread_id": "thr_a1b2c3d4e5f6",
    "messages": [
      {
        "message_id": "msg_u1v2w3x4y5z6",
        "role": "user",
        "content": "What should I have for dinner tonight?",
        "created_at": "2026-04-16T10:00:00Z"
      },
      {
        "message_id": "msg_a7b8c9d0e1f2",
        "role": "assistant",
        "blocks": [
          { "type": "text", "content": "How about beef curry?" }
        ],
        "created_at": "2026-04-16T10:00:01Z"
      }
    ],
    "has_more": false,
    "next_before": null
  }
}
When has_more is true, pass the next_before value as the before parameter to load the next page.

Full Flow Example

# 1. Create persona
PERSONA_ID=$(curl -s -X POST https://api.ones1ght.com/v1/persona \
  -H "Authorization: Bearer $SDK_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "John Doe", "locale": "en"}' | jq -r '.data.persona_id')

# 2. List available models
curl -s https://api.ones1ght.com/v1/models \
  -H "Authorization: Bearer $SDK_KEY"

# 3. Start chat (new thread created automatically, model required)
THREAD_ID=$(curl -s -X POST https://api.ones1ght.com/v1/chat/$PERSONA_ID \
  -H "Authorization: Bearer $SDK_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "shopping-assistant", "messages": [{"role": "user", "content": "What should I have for dinner?"}]}' | jq -r '.data.thread_id')

# 4. Continue conversation (model not needed, fixed to thread)
curl -X POST https://api.ones1ght.com/v1/chat/$PERSONA_ID \
  -H "Authorization: Bearer $SDK_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"thread_id\": \"$THREAD_ID\", \"messages\": [{\"role\": \"user\", \"content\": \"Tell me the curry ingredients\"}]}"

# 5. Retrieve message history
curl https://api.ones1ght.com/v1/chat/$PERSONA_ID/threads/$THREAD_ID/messages \
  -H "Authorization: Bearer $SDK_KEY"

# 6. Close thread
curl -X POST https://api.ones1ght.com/v1/chat/$PERSONA_ID/threads/$THREAD_ID/close \
  -H "Authorization: Bearer $SDK_KEY"