POST
/v1/customers/{id}/conversationsConversations
Stateful, server-managed chat history scoped to one Customer. Each conversation holds a running message list (cap 5,000), an optional system prompt and default model, and a status. Note the path: conversations live under a customer, /v1/customers/{id}/conversations (the {id} accepts ext:<external_id> too).
Request
- HTTP
- POST
- URL
- /v1/customers/{id}/conversations
- Auth
- api_key
Try it
# create a conversation for a customer
curl https://api.fightclub.pro/v1/customers/cus_42/conversations \
-H "Authorization: Bearer $FC_API_KEY" -H "Content-Type: application/json" \
-d '{"title":"Support thread","default_model":"fc:openai/gpt-4o-mini"}'
# => { "id":"conv_...", "status":"active", "message_count":0, ... }
# append a turn (stateful — you don't resend history)
curl https://api.fightclub.pro/v1/customers/cus_42/conversations/conv_.../messages \
-H "Authorization: Bearer $FC_API_KEY" -H "Content-Type: application/json" \
-d '{"role":"user","content":"What is my refund window?"}'Example response
{
"id": "conv_9KmQ2",
"object": "conversation",
"customer_id": "cus_42",
"title": "Support thread",
"system_prompt": null,
"default_model": "fc:openai/gpt-4o-mini",
"metadata": {},
"status": "active",
"message_count": 0,
"created_at": "2026-06-24T12:00:00.000Z",
"updated_at": "2026-06-24T12:00:00.000Z"
}A representative 200 body. Ids and timestamps are illustrative.
Body parameters
| Name | Type | Default | Description |
|---|---|---|---|
| title | string | null | optional | Display title. |
| system_prompt | string | null | optional | System prompt applied to messages in this conversation. |
| default_model | string | null | optional | Default model ref for messages that do not specify one. |
| metadata | object | optional | Free-form JSON, up to 2 KB serialized. |
* required.
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 20 | Page size for the list endpoint (max 100). |
| after | string | optional | Cursor: the last conversation id from the previous page. |
| status | string | optional | Filter by status: active | locked | archived. |
| include_messages | boolean | optional | On GET one conversation: true to inline the messages array. |
Response fields
| Name | Type | Description |
|---|---|---|
| id | string | Conversation id (conv_*). |
| object | string | "conversation". |
| customer_id | string | The owning customer. |
| title | string | null | Title, or null. |
| system_prompt | string | null | System prompt, or null. |
| default_model | string | null | Default model, or null. |
| metadata | object | Your metadata. |
| status | string | active | locked | archived. locked = a message request is in flight. |
| message_count | integer | Messages in the conversation. |
| created_at | string | ISO 8601 timestamp. |
| updated_at | string | ISO 8601 timestamp. |
Errors
- 401
missing_tokenNo Authorization header was sent. - 401
invalid_auth_schemeThe scheme was neither Bearer nor Client. - 401
invalid_token_formatA Bearer token not prefixed ko_. - 401
invalid_tokenThe API key is unknown, revoked or expired. - 403
insufficient_scopeThe key is valid but lacks the required scope. - 400
malformed_jsonBody is not valid JSON. - 400
metadata_too_largemetadata exceeds 2 KB serialized. - 400
invalid_statusList filter status must be active, locked or archived. - 400
invalid_status_transitionPATCH status must be active or archived (you cannot set locked). - 409
conversation_lockedA message request holds the lock; retry after it finishes. - 404
not_foundNo such customer or conversation (also cross-tenant).
See the full error reference.
Related routes
| GET | /v1/customers/{id}/conversations | List a customer's conversations (cursor + status filter). |
| GET | /v1/customers/{id}/conversations/{conv_id} | Retrieve one. Add ?include_messages=true to inline messages. |
| PATCH | /v1/customers/{id}/conversations/{conv_id} | Update title, system_prompt, default_model, metadata or status (active|archived). |
| DELETE | /v1/customers/{id}/conversations/{conv_id} | Soft-delete (204 No Content). |
| POST | /v1/customers/{id}/conversations/{conv_id}/messages | Append a message + get the model reply (the stateful chat turn). |
| GET | /v1/customers/{id}/conversations/{conv_id}/messages | List the messages in a conversation. |
Notes
- ·Conversations are Ringside's server-side chat memory: you append a message and we keep the full history, unlike /v1/chat/completions where you resend the whole array each call.
- ·A conversation caps at 5,000 messages.
- ·While a message turn is running, the conversation status is locked and a second concurrent write returns 409 conversation_locked.
- ·created_at and updated_at are ISO 8601 strings.