Dataset chats
Chats are project training examples. A chat contains ordered system, user,
and assistant messages plus optional name, description, and tags.
CRUD and bulk endpoints
GET /api/v1/projects/{owner_slug}/{project_slug}/chats
POST /api/v1/projects/{owner_slug}/{project_slug}/chats
POST /api/v1/projects/{owner_slug}/{project_slug}/chats/bulk
GET /api/v1/projects/{owner_slug}/{project_slug}/chats/{chat_id}
PUT /api/v1/projects/{owner_slug}/{project_slug}/chats/{chat_id}
DELETE /api/v1/projects/{owner_slug}/{project_slug}/chats/{chat_id}
GET /api/v1/projects/{owner_slug}/{project_slug}/chats/categories
GET /api/v1/projects/{owner_slug}/{project_slug}/tags
Create one example:
{
"name": "returns-001",
"description": "Approved returns answer",
"tags": ["support"],
"messages": [
{"role": "user", "text": "Can I return this?"},
{"role": "assistant", "text": "Yes, within 30 days."}
]
}
List and detail responses include a computed message_count, durable
updated_at, and nullable source. Source is csv, api, editor, or
playground; old rows can be null. API-key writes are always classified by
the server and cannot spoof provenance.
Automatically saved text inferences from the OpenAI-compatible endpoint have
source=api and the inference and model:<model reference> tags. They follow
the owner's sampling setting and never capture another caller's shared/public
traffic. A manual Playground save uses source=playground. Historical missing
sources remain null; names and editable tags are not used to guess origin.
Browsing at scale
The list always uses bounded cursor pages, without a mode opt-in. Numbered
page and page_size parameters are not part of this contract:
GET .../chats?limit=25
GET .../chats?limit=25&cursor=<next_cursor>
GET .../chats?limit=25&before=<previous_cursor>
GET .../chats?limit=25&boundary=last
cursor, before, and boundary are mutually exclusive and opaque. Cursors
belong to this project. Responses include next_cursor, previous_cursor,
is_last_page, total_count, total_count_capped, and search_applied.
Counts are capped at 10,000 rather than scanning an arbitrarily large dataset.
Filters run before pagination. Search matches chat names and message text;
terms shorter than two characters are not applied and terms longer than 128
characters return 422. Use tags, source, and normalized categories
filters as published by the endpoint. GET .../chats/categories?q= returns at
most 50 visible category facets with counts.
Mutability and training
Editing or deleting a chat changes the current dataset, but never rewrites an already-created training job. Before it starts, every job freezes its selected input and train/evaluation membership. Use the job dataset endpoints when you need the exact historical input rather than the current chat.