{ "openapi": "3.1.0", "info": { "title": "Endgame Public API", "version": "1.0.0", "description": "Create and manage Endgame threads over HTTPS." }, "servers": [ { "url": "https://app.endgame.io" } ], "security": [ { "bearerAuth": [] } ], "paths": { "/api/v1/threads": { "post": { "operationId": "createThread", "summary": "Create a thread", "description": "Creates a new thread in the caller's organization. Requires a user-scoped API key; org-wide API keys and M2M applications receive `403 FORBIDDEN` during beta. The `prompt` is required -- it's persisted as the first user message and triggers the assistant's response to generate asynchronously. Poll `GET /api/v1/threads/{id}` until the derived `status.state` is `idle` (or `error`).", "tags": [ "Threads" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateThreadRequest" } } } }, "responses": { "200": { "description": "Thread created.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateThreadResponse" } } } }, "400": { "$ref": "#/components/responses/InvalidParams" }, "403": { "$ref": "#/components/responses/Forbidden" } } }, "get": { "operationId": "listThreads", "summary": "List threads", "description": "Lists threads visible to the caller, ordered by most recent activity first (`updatedAt` when present, otherwise `createdAt`). Personal keys see their own threads plus every org-published thread; the org-wide principal (shared by org-wide API keys and M2M applications) sees every org-published thread.", "tags": [ "Threads" ], "parameters": [ { "name": "limit", "in": "query", "required": false, "description": "Maximum number of threads to return (1-100, default 25).", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 } }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque cursor from a previous response's `nextCursor`. Omit for the first page.", "schema": { "type": "string" } }, { "name": "accountId", "in": "query", "required": false, "description": "Optional filter: only return threads associated with this account ID.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "A page of threads.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListThreadsResponse" } } } }, "400": { "$ref": "#/components/responses/InvalidParams" } } } }, "/api/v1/threads/{id}": { "get": { "operationId": "getThread", "summary": "Get a thread", "description": "Retrieves a thread, its messages, and its derived run status. Callers can only fetch threads they are permitted to read -- threads created by other users under a user-scoped key return `404 NOT_FOUND`.", "tags": [ "Threads" ], "parameters": [ { "$ref": "#/components/parameters/ThreadId" } ], "responses": { "200": { "description": "Thread, messages, and derived status.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetThreadResponse" } } } } } }, "patch": { "operationId": "updateThread", "summary": "Update a thread", "description": "Renames a thread. Only `title` is writable. Requires a user-scoped API key; org-wide API keys and M2M applications receive `403 FORBIDDEN` during beta. Users can only rename threads they created -- attempts to rename another user's thread also return `403 FORBIDDEN`, even when the thread is published.", "tags": [ "Threads" ], "parameters": [ { "$ref": "#/components/parameters/ThreadId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateThreadRequest" } } } }, "responses": { "200": { "description": "Updated thread.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateThreadResponse" } } } }, "400": { "$ref": "#/components/responses/InvalidParams" }, "403": { "$ref": "#/components/responses/Forbidden" } } }, "delete": { "operationId": "deleteThread", "summary": "Delete a thread", "description": "Soft-deletes a thread. The record is preserved server-side but will no longer appear in `GET /api/v1/threads` or be readable via `GET /api/v1/threads/{id}`. Requires a user-scoped API key; org-wide API keys and M2M applications receive `403 FORBIDDEN` during beta. Users can only delete threads they created.", "tags": [ "Threads" ], "parameters": [ { "$ref": "#/components/parameters/ThreadId" } ], "responses": { "200": { "description": "Deletion acknowledged.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeleteThreadResponse" } } } }, "403": { "$ref": "#/components/responses/Forbidden" } } } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "description": "One of: an Endgame API key prefixed `eak_` (created from Settings → API Keys with a Personal or Org-wide scope), or a WorkOS access token from an Endgame-provisioned M2M application (created from Settings → Applications and exchanged via the `client_credentials` grant)." } }, "parameters": { "ThreadId": { "name": "id", "in": "path", "required": true, "description": "Thread identifier.", "schema": { "type": "string" } } }, "schemas": { "Thread": { "type": "object", "description": "Public representation of a thread.", "required": [ "id", "title", "createdAt", "updatedAt", "accountId", "secondaryId", "published", "deleted", "threadUrl" ], "properties": { "id": { "type": "string", "description": "Stable thread identifier.", "readOnly": true, "example": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T" }, "title": { "type": "string", "description": "Human-readable title. Auto-generated from the first prompt when a thread is created without an explicit title.", "example": "What accounts does my team own?" }, "createdAt": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp of thread creation.", "readOnly": true, "example": "2026-04-22T14:32:10.000Z" }, "updatedAt": { "type": [ "string", "null" ], "format": "date-time", "description": "ISO 8601 timestamp of the last update. `null` if never updated.", "readOnly": true, "example": "2026-04-22T14:35:02.000Z" }, "accountId": { "type": [ "string", "null" ], "description": "Associated account ID, if any.", "example": "0018b00000abCdEfGhI" }, "secondaryId": { "type": [ "string", "null" ], "description": "Secondary linkage (e.g. opportunity, user). Settable on create only.", "example": null }, "published": { "type": "boolean", "description": "Whether the thread is published to the organization.", "readOnly": true, "example": false }, "deleted": { "type": "boolean", "description": "Whether the thread has been soft-deleted.", "readOnly": true, "example": false }, "threadUrl": { "type": [ "string", "null" ], "format": "uri", "description": "Deep link into the Endgame app for this thread.", "readOnly": true, "example": "https://app.endgame.io/threads/thr_01HZY6P8RB4K5C7X9E2N8MDQ4T" } }, "example": { "id": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T", "title": "What accounts does my team own?", "createdAt": "2026-04-22T14:32:10.000Z", "updatedAt": "2026-04-22T14:35:02.000Z", "accountId": "0018b00000abCdEfGhI", "secondaryId": null, "published": false, "deleted": false, "threadUrl": "https://app.endgame.io/threads/thr_01HZY6P8RB4K5C7X9E2N8MDQ4T" } }, "ThreadMessage": { "type": "object", "description": "A single message on a thread.", "required": [ "id", "threadId", "role", "content", "status", "createdAt", "completedAt", "steps", "sources", "attachments", "model" ], "properties": { "id": { "type": "string", "readOnly": true, "example": "msg_01HZY6P8RB4K5C7X9E2N8MDQ4U" }, "threadId": { "type": "string", "readOnly": true, "example": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T" }, "role": { "type": "string", "enum": [ "assistant", "user" ], "readOnly": true, "example": "assistant" }, "content": { "type": "string", "readOnly": true, "example": "Your team owns 42 accounts. The five largest by ARR are..." }, "status": { "type": [ "string", "null" ], "enum": [ "in_progress", "corroborating", "completed", "failed", "cancelled", null ], "description": "Lifecycle status of the message. Always `null` for `user` messages; non-null for assistant messages. `in_progress` and `corroborating` mean the assistant is still processing; `completed` is terminal success; `failed` means an error was hit; `cancelled` means the user or system aborted the message.", "readOnly": true, "example": "completed" }, "createdAt": { "type": "string", "format": "date-time", "readOnly": true, "example": "2026-04-22T14:32:11.000Z" }, "completedAt": { "type": [ "string", "null" ], "format": "date-time", "readOnly": true, "example": "2026-04-22T14:32:18.000Z" }, "steps": { "type": [ "array", "null" ], "description": "Reasoning steps emitted while the assistant was generating.", "items": { "type": "object", "required": [ "description" ], "properties": { "description": { "type": "string" } }, "additionalProperties": true }, "readOnly": true, "example": [ { "description": "Looking up accounts owned by your team" }, { "description": "Ranking by annualized revenue" } ] }, "sources": { "type": [ "array", "null" ], "description": "Source documents referenced by the assistant.", "items": { "type": "object", "additionalProperties": true }, "readOnly": true, "example": null }, "attachments": { "type": [ "array", "null" ], "description": "User-supplied attachments associated with the message.", "items": { "type": "object", "additionalProperties": true }, "readOnly": true, "example": null }, "model": { "type": [ "string", "null" ], "description": "Identifier of the model that produced the message, if applicable.", "readOnly": true, "example": "claude-opus-4-7" } } }, "ThreadStatus": { "type": "object", "description": "Derived run status based on the latest assistant message.", "required": [ "state", "activeMessageId", "latestUpdate", "stepCount" ], "properties": { "state": { "type": "string", "enum": [ "idle", "in_progress", "error" ], "description": "`idle` when no assistant work is pending (or no assistant messages exist yet), `in_progress` while the assistant is still generating, `error` if the most recent assistant message failed.", "example": "idle" }, "activeMessageId": { "type": [ "string", "null" ], "description": "ID of the assistant message currently being generated, if `state` is `in_progress`.", "example": null }, "latestUpdate": { "type": [ "string", "null" ], "description": "Description of the most recent reasoning step, or `\"Thinking\"` if the assistant hasn't emitted a step yet.", "example": null }, "stepCount": { "type": "integer", "minimum": 0, "description": "Number of reasoning steps emitted on the active assistant message.", "example": 0 } } }, "CreateThreadRequest": { "type": "object", "description": "Parameters for creating a thread. `prompt` is required; `title` auto-generates from it if omitted.", "required": [ "prompt" ], "properties": { "prompt": { "type": "string", "minLength": 1, "description": "First user message on the thread. Persisted immediately and triggers an assistant response that generates asynchronously.", "example": "What accounts does my team own?" }, "title": { "type": "string", "minLength": 1, "description": "Explicit title. If omitted, the title is auto-generated from the prompt.", "example": "Book of business review" }, "accountId": { "type": "string", "description": "Associate the thread with an account ID.", "example": "0018b00000abCdEfGhI" }, "secondaryId": { "type": "string", "description": "Secondary linkage (e.g. opportunity, user).", "example": "0068b00000abCdEfGhI" } }, "example": { "prompt": "What accounts does my team own?" } }, "CreateThreadResponse": { "type": "object", "required": [ "thread" ], "properties": { "thread": { "$ref": "#/components/schemas/Thread" }, "messageId": { "type": "string", "description": "ID of the user message persisted from `prompt`.", "example": "msg_01HZY6P8RB4K5C7X9E2N8MDQ4V" }, "responseMessageId": { "type": "string", "description": "ID of the in-flight assistant response message. Poll `GET /api/v1/threads/{id}` until this message's `status` is `completed` or `failed`.", "example": "msg_01HZY6P8RB4K5C7X9E2N8MDQ4W" } }, "example": { "thread": { "id": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T", "title": "What accounts does my team own?", "createdAt": "2026-04-22T14:32:10.000Z", "updatedAt": null, "accountId": null, "secondaryId": null, "published": false, "deleted": false, "threadUrl": null }, "messageId": "msg_01HZY6P8RB4K5C7X9E2N8MDQ4V", "responseMessageId": "msg_01HZY6P8RB4K5C7X9E2N8MDQ4W" } }, "ListThreadsResponse": { "type": "object", "required": [ "threads", "nextCursor", "truncated" ], "properties": { "threads": { "type": "array", "items": { "$ref": "#/components/schemas/Thread" } }, "nextCursor": { "type": [ "string", "null" ], "description": "Opaque cursor for the next page. `null` when there are no more pages.", "example": "MjAyNi0wNC0yMlQxNDozNTowMi4wMDBafHRocl8wMUhaWTZQOFJCNEs1QzdYOUUyTjhNRFE0VA==" }, "truncated": { "type": "boolean", "description": "`true` when the organization has more threads than the server-side pagination window can walk. Narrow the result with `accountId` to retrieve the threads this page can't surface.", "example": false } }, "example": { "threads": [ { "id": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T", "title": "What accounts does my team own?", "createdAt": "2026-04-22T14:32:10.000Z", "updatedAt": "2026-04-22T14:35:02.000Z", "accountId": null, "secondaryId": null, "published": false, "deleted": false, "threadUrl": "https://app.endgame.io/threads/thr_01HZY6P8RB4K5C7X9E2N8MDQ4T" } ], "nextCursor": null, "truncated": false } }, "GetThreadResponse": { "type": "object", "required": [ "thread", "messages", "status" ], "properties": { "thread": { "$ref": "#/components/schemas/Thread" }, "messages": { "type": "array", "items": { "$ref": "#/components/schemas/ThreadMessage" } }, "status": { "$ref": "#/components/schemas/ThreadStatus" } }, "example": { "thread": { "id": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T", "title": "What accounts does my team own?", "createdAt": "2026-04-22T14:32:10.000Z", "updatedAt": "2026-04-22T14:35:02.000Z", "accountId": null, "secondaryId": null, "published": false, "deleted": false, "threadUrl": "https://app.endgame.io/threads/thr_01HZY6P8RB4K5C7X9E2N8MDQ4T" }, "messages": [ { "id": "msg_01HZY6P8RB4K5C7X9E2N8MDQ4V", "threadId": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T", "role": "user", "content": "What accounts does my team own?", "status": null, "createdAt": "2026-04-22T14:32:10.000Z", "completedAt": null, "steps": null, "sources": null, "attachments": null, "model": null }, { "id": "msg_01HZY6P8RB4K5C7X9E2N8MDQ4W", "threadId": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T", "role": "assistant", "content": "Your team owns 42 accounts. The five largest by ARR are...", "status": "completed", "createdAt": "2026-04-22T14:32:11.000Z", "completedAt": "2026-04-22T14:32:18.000Z", "steps": [ { "description": "Looking up accounts owned by your team" }, { "description": "Ranking by annualized revenue" } ], "sources": null, "attachments": null, "model": "claude-opus-4-7" } ], "status": { "state": "idle", "activeMessageId": null, "latestUpdate": null, "stepCount": 2 } } }, "UpdateThreadRequest": { "type": "object", "description": "Only `title` is writable. Unknown fields are rejected with `INVALID_PARAMS`.", "additionalProperties": false, "required": [ "title" ], "properties": { "title": { "type": "string", "minLength": 1, "description": "New title. Must be at least one character.", "example": "Book of business review — Q2" } }, "example": { "title": "Book of business review — Q2" } }, "UpdateThreadResponse": { "type": "object", "required": [ "thread" ], "properties": { "thread": { "$ref": "#/components/schemas/Thread" } } }, "DeleteThreadResponse": { "type": "object", "required": [ "id", "deleted" ], "properties": { "id": { "type": "string", "example": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T" }, "deleted": { "type": "boolean", "enum": [ true ], "description": "Always `true` on a successful delete.", "example": true } }, "example": { "id": "thr_01HZY6P8RB4K5C7X9E2N8MDQ4T", "deleted": true } }, "Error": { "type": "object", "required": [ "error" ], "properties": { "error": { "type": "object", "required": [ "code", "message", "trace_id" ], "properties": { "code": { "type": "string", "enum": [ "INVALID_PARAMS", "UNAUTHORIZED", "FORBIDDEN", "NOT_FOUND", "RATE_LIMITED", "INTERNAL_ERROR" ], "description": "Stable machine-readable error code.", "example": "INVALID_PARAMS" }, "message": { "type": "string", "description": "Human-readable explanation.", "example": "prompt: String must contain at least 1 character(s)" }, "trace_id": { "type": "string", "description": "Unique identifier for the request. Include in support requests.", "example": "01HZY6P8RB4K5C7X9E2N8MDQ4T" } } } }, "example": { "error": { "code": "INVALID_PARAMS", "message": "prompt: String must contain at least 1 character(s)", "trace_id": "01HZY6P8RB4K5C7X9E2N8MDQ4T" } } } }, "responses": { "InvalidParams": { "description": "Request body or query parameters failed validation. See [Errors](/api-reference/endpoints#errors) for the full error envelope and code list.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "Forbidden": { "description": "Credential is valid but not permitted. Either the operation requires a user-scoped API key (org-wide credentials cannot mutate threads during beta), or the caller is user-scoped but did not create the thread. See [Errors](/api-reference/endpoints#errors) for the full error envelope.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }