{"openapi":"3.1.0","info":{"title":"Twigg customer API","description":"Customer API operations. Prose documentation: https://twigg.ai/docs. Machine-readable index: https://twigg.ai/llms.txt.","version":"v1"},"servers":[{"url":"https://api.twigg.ai"}],"paths":{"/":{"get":{"tags":["Discovery"],"summary":"Public links for a client starting with only the API base URL.","operationId":"discovery","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Discovery"}}}}},"security":[]}},"/api/v1/chats":{"get":{"tags":["customer-api","Chats"],"summary":"List chats","description":"List chats newest first. Use after_id or before_id to page; they are mutually exclusive. Unknown query parameters are ignored.","operationId":"listChats","parameters":[{"name":"namespace","in":"query","description":"Scope to a namespace **and everything beneath it**. `acme/proj-7`\nreturns that scope's chats plus `acme/proj-7/user-99`'s and deeper.\nAbsent lists the whole organisation.\n\nA namespace with no chats is not an error — there is no registry, so\n\"empty\" and \"never used\" are the same state and both return `[]`.","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}},{"name":"after_id","in":"query","description":"Page **older** than this id. Listings run newest-first, so \"after\" means\nfurther down the list, which is further back in time.","required":false,"schema":{"$ref":"#/components/schemas/ChatId"}},{"name":"before_id","in":"query","description":"Page **newer** than this id.","required":false,"schema":{"$ref":"#/components/schemas/ChatId"}},{"name":"limit","in":"query","description":"1–100. Out-of-range values are clamped.","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"List chats","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatPage"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]},"post":{"tags":["customer-api","Chats"],"summary":"Create a chat","description":"Create an empty chat in the authenticated organisation. All request fields are optional.","operationId":"createChat","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChatRequest"}}},"required":true},"responses":{"201":{"description":"Create a chat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCreated"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/chats/{chat_id}":{"get":{"tags":["customer-api","Chats"],"summary":"Get a chat","description":"Fetch a chat owned by the authenticated organisation. Missing chats and chats owned by another organisation both return 404.","operationId":"getChat","parameters":[{"name":"chat_id","in":"path","description":"Resource identifier","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Get a chat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSummary"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]},"delete":{"tags":["customer-api","Chats"],"summary":"Delete a chat","description":"Delete a chat and its ledger. Repeating the deletion returns 404.","operationId":"deleteChat","parameters":[{"name":"chat_id","in":"path","description":"Resource identifier","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Delete a chat"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/chats/{chat_id}/history":{"get":{"tags":["customer-api","Chats"],"summary":"Read chat history","description":"Read the newest page by default, with rows ordered oldest first. Use before_ordinal or after_ordinal, not both. Unknown query parameters return 422.","operationId":"getChatHistory","parameters":[{"name":"chat_id","in":"path","description":"Resource identifier","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"before_ordinal","in":"query","description":"Page **backwards** from here: the parts immediately older than this\nordinal. What a reader scrolling up sends, using the `first_ordinal` of\nthe page they already have.","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"after_ordinal","in":"query","description":"Page **forwards** from here: the parts immediately newer than this\nordinal. What a UI already open sends to pick up what has arrived since,\nusing `last_ordinal`.\n\nAn **ordinal**, not a part id, because ordinals are the ledger's only\ntotal order and a client paging already holds the one it saw last. They\nare never renumbered, so a cursor stays valid; deletes leave gaps, so a\ncursor is not an index and must not be incremented by hand.","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"limit","in":"query","description":"1–100, or 1–20 with `include=full`. Out-of-range values are clamped, not\nrejected.","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"include","in":"query","description":"How much of an attachment travels: `stubs` (the default), `none`, or\n`full`.","required":false,"schema":{"type":"string","description":"The `include` parameter's vocabulary.\n\nNamed for what the client gets rather than for what we do — `stubs` is the\ndescriptor, `full` adds the bytes — because the caller is choosing the size\nof their response, not a storage strategy.","enum":["stubs","none","full"]}}],"responses":{"200":{"description":"Read chat history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryPageResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/chats/{chat_id}/responses":{"post":{"tags":["customer-api","Responses"],"summary":"Submit a turn and stream the answer","description":"Submit a prompt or tool results, then stream the model response as server-sent events. Failures before the first byte use HTTP errors; later failures use the error event. Dropping the connection does not cancel the turn.","operationId":"createResponse","parameters":[{"name":"chat_id","in":"path","description":"Resource identifier","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateResponseRequest"}}},"required":true},"responses":{"200":{"description":"Submit a turn and stream the answer","content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/ResponseEvent"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/budgets":{"get":{"tags":["customer-api","Configuration"],"summary":"List active context budgets","operationId":"listActiveBudgets","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContextBudgetResponse"}}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]},"post":{"tags":["customer-api","Configuration"],"summary":"Publish context budgets","operationId":"publishBudgets","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishContextBudgetRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContextBudgetResponse"}}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/budgets/active":{"delete":{"tags":["customer-api","Configuration"],"summary":"Withdraw context budget","operationId":"withdrawBudget","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}},{"name":"model","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ModelId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivateResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/budgets/versions":{"get":{"tags":["customer-api","Configuration"],"summary":"List context budget versions","operationId":"listBudgetVersions","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}},{"name":"model","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ModelId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContextBudgetResponse"}}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/budgets/{id}/activate":{"post":{"tags":["customer-api","Configuration"],"summary":"restoreBudget","operationId":"restoreBudget","parameters":[{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/ContextBudgetPolicyId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextBudgetResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/defaults":{"get":{"tags":["customer-api","Configuration"],"summary":"Read default policies","operationId":"getConfigurationDefaults","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DefaultPoliciesResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/instructions":{"get":{"tags":["customer-api","Configuration"],"summary":"listInstructionVersions","operationId":"listInstructionVersions","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConfigVersionResponse"}}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]},"post":{"tags":["customer-api","Configuration"],"summary":"Publish system instructions","operationId":"publishInstructions","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishInstructionRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigVersionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/instructions/active":{"delete":{"tags":["customer-api","Configuration"],"summary":"withdrawInstructions","operationId":"withdrawInstructions","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivateResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/instructions/{id}":{"get":{"tags":["customer-api","Configuration"],"summary":"Read instruction version","operationId":"getInstructions","parameters":[{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/SystemInstructionId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstructionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/instructions/{id}/activate":{"post":{"tags":["customer-api","Configuration"],"summary":"restoreInstructions","operationId":"restoreInstructions","parameters":[{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/SystemInstructionId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigVersionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/namespaces":{"get":{"tags":["customer-api","Configuration"],"summary":"List namespaces used by chats or configuration","operationId":"listConfigurationNamespaces","responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Namespace"}}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/resolved":{"get":{"tags":["customer-api","Configuration"],"summary":"Resolve effective configuration","operationId":"resolveConfiguration","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolvedConfig"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/resolved-budget":{"get":{"tags":["customer-api","Configuration"],"summary":"Resolve effective context budget","operationId":"resolveContextBudget","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}},{"name":"model","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ModelId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolvedBudget"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/retention":{"get":{"tags":["customer-api","Configuration"],"summary":"listRetentionVersions","operationId":"listRetentionVersions","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RetentionPolicyResponse"}}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]},"post":{"tags":["customer-api","Configuration"],"summary":"Publish retention policy","operationId":"publishRetention","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishRetentionPolicyRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionPolicyResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/retention/active":{"delete":{"tags":["customer-api","Configuration"],"summary":"withdrawRetention","operationId":"withdrawRetention","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivateResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/retention/{id}/activate":{"post":{"tags":["customer-api","Configuration"],"summary":"restoreRetention","operationId":"restoreRetention","parameters":[{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/RetentionPolicyId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetentionPolicyResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/tools":{"get":{"tags":["customer-api","Configuration"],"summary":"listToolVersions","operationId":"listToolVersions","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConfigVersionResponse"}}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]},"post":{"tags":["customer-api","Configuration"],"summary":"Publish saved tools","operationId":"publishTools","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishToolsRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigVersionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/tools/active":{"delete":{"tags":["customer-api","Configuration"],"summary":"withdrawTools","operationId":"withdrawTools","parameters":[{"name":"namespace","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivateResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/tools/{id}":{"get":{"tags":["customer-api","Configuration"],"summary":"Read tool version","operationId":"getTools","parameters":[{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/ToolSchemaId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolSchemaResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/config/tools/{id}/activate":{"post":{"tags":["customer-api","Configuration"],"summary":"restoreTools","operationId":"restoreTools","parameters":[{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/ToolSchemaId"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigVersionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/models":{"get":{"tags":["customer-api","Catalogue"],"summary":"List available models","description":"Returns active models available for new requests, with the caller's prices.","operationId":"listModels","responses":{"200":{"description":"List available models","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogueModel"}}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/namespaces":{"get":{"tags":["customer-api","Catalogue"],"summary":"List namespaces in use","description":"Unpaged, deliberately. A namespace count is bounded by how a customer scopes\nrather than by how much they use the product, and a cursor on a list nobody\nwill page is API surface with no reader.","operationId":"listNamespaces","responses":{"200":{"description":"List namespaces in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NamespacePage"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/runs/{run_id}":{"get":{"tags":["customer-api","Runs"],"summary":"Inspect a run","description":"`404` for a run in another organisation, exactly as for one that does not\nexist. The scoping is in the query rather than a check after it, so there is\nno timing difference and no way to probe for someone else's run id.","operationId":"getRun","parameters":[{"name":"run_id","in":"path","description":"Resource identifier","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Inspect a run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunInspection"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/updates":{"get":{"tags":["public-info"],"summary":"List published updates","operationId":"listPublicUpdates","responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PublicPlatformUpdate"}}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{}]}},"/api/v1/usage":{"get":{"tags":["customer-api","Usage"],"summary":"Query organisation or namespace usage","operationId":"queryUsage","parameters":[{"name":"range","in":"query","required":true,"schema":{"type":"string","enum":["24h","7d","30d","90d"]}},{"name":"bin","in":"query","description":"Absent means \"do not bin\" — the window's totals, or one row per group.","required":false,"schema":{"$ref":"#/components/schemas/UsageBin"}},{"name":"group_by","in":"query","description":"Absent means \"do not split\" — the organisation as a whole.","required":false,"schema":{"$ref":"#/components/schemas/UsageDimension"}},{"name":"namespace","in":"query","description":"Absent is the whole organisation. Present reports the namespace **and its\nsubtree**, which is a different question from the namespace alone and the\none a customer with per-project paths is asking.","required":false,"schema":{"$ref":"#/components/schemas/Namespace"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageReport"}}}},"401":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[{"ApiKey":[]}]}},"/api/v1/version":{"get":{"tags":["Discovery"],"operationId":"get","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiVersion"}}}}},"security":[]}},"/v1/catalogue":{"get":{"tags":["public-catalogue","Catalogue"],"summary":"List public model prices","description":"No API key required. Anonymous requests use platform-default prices. A valid console session uses that organisation's markup; an invalid session is treated as anonymous.","operationId":"listCatalogue","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Catalogue"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/catalogue/models.md":{"get":{"tags":["public-catalogue","Catalogue"],"summary":"Read model prices as Markdown","description":"No API key required. Anonymous requests use platform-default prices. A valid console session uses that organisation's markup; an invalid session is treated as anonymous.","operationId":"getCatalogueMarkdown","responses":{"200":{"description":"","content":{"text/markdown":{"schema":{"type":"string"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/catalogue/{name}":{"get":{"tags":["public-catalogue","Catalogue"],"summary":"Get public model prices","description":"No API key required. Anonymous requests use platform-default prices. A valid console session uses that organisation's markup; an invalid session is treated as anonymous.","operationId":"getCatalogueModel","parameters":[{"name":"name","in":"path","description":"Public model name; may include slashes.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogueModelResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}},"components":{"schemas":{"ApiKeyId":{"type":"string","format":"uuid"},"ApiVersion":{"type":"object","required":["version","commit","api_version"],"properties":{"api_version":{"type":"string"},"commit":{"type":"string"},"version":{"type":"string"}}},"BalanceEntryType":{"type":"string","enum":["usage","compaction","topup","refund","adjustment","promotional_credit"]},"BilledRates":{"type":"object","description":"Per-million rates as the customer pays them.","required":["input","output","currency"],"properties":{"cache_read":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RatePerMillion","description":"Absent when the provider does not meter it."}]},"cache_write":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RatePerMillion"}]},"currency":{"type":"string"},"input":{"$ref":"#/components/schemas/RatePerMillion"},"output":{"$ref":"#/components/schemas/RatePerMillion"}}},"BilledTier":{"type":"object","description":"One pricing condition, in the customer's terms. Rates here are billed too.","required":["id","mode","metric","min"],"properties":{"cache_read":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RatePerMillion"}]},"cache_write":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RatePerMillion"}]},"id":{"type":"string"},"input":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RatePerMillion"}]},"max":{"type":["integer","null"],"format":"int64","minimum":0},"metric":{"type":"string"},"min":{"type":"integer","format":"int64","minimum":0},"mode":{"$ref":"#/components/schemas/TierMode"},"output":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RatePerMillion"}]}}},"BlockStart":{"oneOf":[{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["text"]}}},{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["reasoning"]}}},{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["refusal"]}}},{"type":"object","required":["tool_use_id","tool_name","kind"],"properties":{"kind":{"type":"string","enum":["tool_call"]},"tool_name":{"$ref":"#/components/schemas/ToolName"},"tool_use_id":{"$ref":"#/components/schemas/ToolUseId"}}}]},"BudgetFraction":{"type":"number","format":"float"},"BudgetSource":{"oneOf":[{"type":"object","description":"No level published one. There is no row, which is why this is a variant\nand not a null id.","required":["kind"],"properties":{"kind":{"type":"string","enum":["platform_default"]}}},{"type":"object","description":"A published policy won, whole.","required":["id","kind"],"properties":{"id":{"$ref":"#/components/schemas/ContextBudgetPolicyId"},"kind":{"type":"string","enum":["policy"]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The level it was published at. `None` is org-global."}]},"tagged_model":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ModelId","description":"`Some` when the level's tag for this model won over its untagged\npolicy; `None` when the level's untagged policy is what won."}]}}}],"description":"The configuration scope and model tag that supplied the resolved context budget."},"Catalogue":{"type":"object","description":"The whole catalogue plus the margin its prices include.","required":["models","markup_percent","organisation_specific"],"properties":{"markup_percent":{"$ref":"#/components/schemas/MarkupPercent","description":"The platform-default markup the listed prices already include. Zero\nmeans the prices are provider cost."},"models":{"type":"array","items":{"$ref":"#/components/schemas/CatalogueModel"}},"organisation_specific":{"type":"boolean","description":"Present when a signed-in caller's organisation has its own rate; the\nprices then reflect that rate rather than the default."}}},"CatalogueModel":{"type":"object","description":"One catalogue entry, in full. The list and the detail share it: a detail\npage is not a different fact, only a bigger frame around the same one.","required":["id","name","display_name","provider","provider_label","model_family","context_window","max_output_tokens","supports_reasoning","supports_tools","media","thinking","rates","tiers"],"properties":{"avg_time_to_first_token_ms":{"type":["number","null"],"format":"double","description":"Mean milliseconds from provider request to first nonempty output delta,\nover successful requests completed in the last 24 hours. Includes retry waits.\nNull when no timing samples exist. Refreshed every 15 minutes."},"context_window":{"type":"integer","format":"int32"},"display_name":{"type":"string"},"icon_url":{"type":["string","null"]},"id":{"$ref":"#/components/schemas/ModelId"},"max_output_tokens":{"type":"integer","format":"int32"},"max_reasoning_effort":{"type":["string","null"]},"max_tool_definitions":{"type":["integer","null"],"format":"int32"},"media":{"$ref":"#/components/schemas/MediaCapabilities"},"model_family":{"type":"string"},"name":{"type":"string","description":"The identifier to send as `model` on a run."},"provider":{"$ref":"#/components/schemas/Provider"},"provider_label":{"type":"string"},"rates":{"$ref":"#/components/schemas/BilledRates"},"supports_reasoning":{"type":"boolean"},"supports_tools":{"type":"boolean"},"thinking":{"type":"string"},"tiers":{"type":"array","items":{"$ref":"#/components/schemas/BilledTier"}},"uptime":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Uptime","description":"Observed provider request success rate over the past 24 hours, after retries,\nas a fraction from 0 to 1. Refreshed every 15 minutes. Null means no\neligible completed requests. Local validation failures, interrupted runs\nand unclassified historical failures are excluded; this is not time-based uptime."}]}}},"CatalogueModelResponse":{"allOf":[{"$ref":"#/components/schemas/CatalogueModel"},{"type":"object","required":["markup_percent"],"properties":{"markup_percent":{"$ref":"#/components/schemas/MarkupPercent"}}}]},"ChatCreated":{"type":"object","description":"The new chat, including its immutable namespace, labels, metadata and creation time.","required":["id","namespace","title","description","user_metadata","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"description":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatDescription"}]},"id":{"$ref":"#/components/schemas/ChatId"},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]},"title":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatTitle"}]},"user_metadata":{"$ref":"#/components/schemas/UserMetadata","description":"Echoed from the request, like the labels above — but for a different\nreason. This one *is* readable from the row; it is echoed so the\nresponse reflects what the customer sent rather than what `jsonb`\nnormalisation made of it, and so all three optional fields behave the\nsame way here."}}},"ChatDescription":{"type":"string","maxLength":200,"minLength":1},"ChatId":{"type":"string","format":"uuid"},"ChatPage":{"type":"object","description":"One page of chats.","required":["data","first_id","last_id","has_more"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ChatSummary"},"description":"Newest first, whichever direction was paged.\n\nNamed `data` rather than `chats` so one pagination helper works across\nevery list endpoint we add — the same reason the upstream APIs do it."},"first_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatId","description":"Id of the first item in `data`. Pass as `before_id` to page backwards.\n`null` when the page is empty."}]},"has_more":{"type":"boolean","description":"Whether more chats exist **in the direction being paged**."},"last_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatId","description":"Id of the last item in `data`. Pass as `after_id` for the next page."}]}}},"ChatPartId":{"type":"string","format":"uuid"},"ChatSummary":{"type":"object","description":"One chat in a listing.\n\nEverything optional here is optional in the customer's data, not in our\nresponse: `null` means they did not set it, and the field is always present\nso a client never has to distinguish \"absent\" from \"unset\".","required":["id","namespace","title","description","user_metadata","length","created_at","updated_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"description":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatDescription"}]},"id":{"$ref":"#/components/schemas/ChatId"},"length":{"type":"integer","format":"int64","description":"How many parts the chat's ledger holds.\n\nA count of rows, not of tokens, characters or messages — one assistant\nturn can be several parts (reasoning, then text, then a tool call), so\nthis is larger than the number of exchanges a customer would count by\neye. It is meant as an \"is there anything in here, and roughly how\nmuch\" signal, not as an addressing scheme: ordinals are never\nrenumbered and deletes leave gaps, so the last part's ordinal is not\n`length - 1`."},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]},"title":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatTitle"}]},"updated_at":{"type":"string","format":"date-time"},"user_metadata":{"$ref":"#/components/schemas/UserMetadata"}}},"ChatTitle":{"type":"string","maxLength":50,"minLength":1},"Compaction":{"type":"object","required":["blocks_generated","blocks_reused","in_progress_elsewhere"],"properties":{"blocks_generated":{"type":"integer","minimum":0},"blocks_reused":{"type":"integer","minimum":0},"in_progress_elsewhere":{"type":"integer","minimum":0}}},"ConfigMode":{"type":"string","enum":["append","replace"]},"ConfigVersionResponse":{"type":"object","description":"One published version, without its payload. The body of an instruction and\nthe definitions of a bundle are fetched per version, not listed — a history\nendpoint that returned every body would fetch and decrypt a blob per row.","required":["id","version","estimated_tokens","is_active","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"estimated_tokens":{"$ref":"#/components/schemas/TokenEstimate"},"id":{"type":"string"},"is_active":{"type":"boolean"},"mode":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ConfigMode","description":"How this version combines with the org-global one — `None` for the two\nsurfaces that do not combine at all (retention policies and context\nbudgets), where a mode would be a field the customer could set and\nnothing would read."}]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]},"version":{"type":"integer","format":"int32"}}},"ConfigWarning":{"oneOf":[{"type":"object","description":"A namespace tool replaced a global tool of the same name. The union is\nkeyed on name, so this is how an override is *meant* to work — but it is\nalso exactly what a typo in a tool name looks like from the outside.","required":["name","namespace","code"],"properties":{"code":{"type":"string","enum":["tool_shadowed"]},"name":{"$ref":"#/components/schemas/ToolName"},"namespace":{"$ref":"#/components/schemas/Namespace"}}},{"type":"object","description":"The namespace's instruction is in `replace` mode, so the org-global\ninstruction is not being sent at all.","required":["namespace","code"],"properties":{"code":{"type":"string","enum":["global_instruction_replaced"]},"namespace":{"$ref":"#/components/schemas/Namespace"}}},{"type":"object","description":"The namespace's tool bundle is in `replace` mode, so the global bundle\nis not being sent at all — including tools the customer may assume are\nalways present.","required":["namespace","dropped","code"],"properties":{"code":{"type":"string","enum":["global_tools_replaced"]},"dropped":{"type":"integer","minimum":0},"namespace":{"$ref":"#/components/schemas/Namespace"}}},{"type":"object","description":"A nearer level's retention policy displaced a farther level's. This is how\nthe override is *meant* to work: a policy is a complete decision table and\nis selected whole, so the farther one contributes nothing — not its rules\nand not its defaults. It still warns, because the result looks identical\neither way, and \"my org-wide rule stopped applying\" is otherwise\nundiagnosable.\n\nBoth levels are named because at depth neither is guessable from the\nother: \"a namespace policy won\" does not say which of four ancestors\nstopped applying.","required":["code"],"properties":{"code":{"type":"string","enum":["retention_policy_overridden"]},"displaced":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The nearest level whose policy is not being applied."}]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The level whose policy is in force. `None` is org-global."}]}}},{"type":"object","description":"The budget in force did not come from the plainest place: either an\nancestor level supplied it, or a model tag at the winning level displaced\nthat level's untagged policy — or both.\n\nTwo facts, one warning, because either alone misleads. \"The budget came\nfrom `acme`\" and \"the budget came from `acme`, tagged to this model\" send\nan admin to different rows, and the second is the only one that explains\nwhy a sibling model in the same namespace behaves differently.","required":["code"],"properties":{"code":{"type":"string","enum":["context_budget_resolved_at"]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The level that supplied it. `None` is the org-global scope."}]},"tagged_model":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ModelId","description":"`Some` when that level's tag for this model beat its untagged policy."}]}}},{"type":"object","description":"Oldest ledger parts were omitted because no complete context fitted.","required":["dropped","start_ordinal","end_ordinal","code"],"properties":{"code":{"type":"string","enum":["history_dropped"]},"dropped":{"type":"integer","format":"int64"},"end_ordinal":{"type":"integer","format":"int64"},"start_ordinal":{"type":"integer","format":"int64"}}}],"description":"Something legal but worth saying out loud."},"ContextBudget":{"type":"object","required":["version","headroom"],"properties":{"eager_compaction":{"$ref":"#/components/schemas/EagerCompaction"},"headroom":{"$ref":"#/components/schemas/BudgetFraction"},"history_mode":{"$ref":"#/components/schemas/HistoryMode"},"max_history_tokens":{"type":["integer","null"],"format":"int32","minimum":32000},"version":{"type":"integer","format":"int32","maximum":3,"minimum":3}},"additionalProperties":false},"ContextBudgetPolicyId":{"type":"string","format":"uuid"},"ContextBudgetResponse":{"allOf":[{"$ref":"#/components/schemas/ConfigVersionResponse"},{"type":"object","required":["budget"],"properties":{"budget":{"$ref":"#/components/schemas/ContextBudget"},"model_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ModelId","description":"`None` is the scope default, not an untagged leftover."}]}}}],"description":"One context-budget version with its document and the model it is tagged to."},"CreateChatRequest":{"type":"object","description":"Body for [`create`]. Every field is optional — the minimum viable request is\n`{}`, which opens a chat in the org's default scope with no labels.\n\nThe org is deliberately absent: it comes off the authenticated key, so a\ncaller cannot open a chat anywhere but their own organisation.","properties":{"description":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatDescription"}]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The scope this chat's configuration resolves against, and the prefix it\nwill be listed under. Immutable once set.\n\nNote this field does **not** coerce an empty string to \"no namespace\",\nwhere `title` and `description` below do. A namespace is load-bearing —\nit decides which system instructions and tools every future run on this\nchat receives — so a client whose interpolation produced `\"\"` should get\na 422 rather than a chat silently pinned to the org-global scope. The\nlabels are decorative, and an untouched form field is not worth a\nrejection."}]},"title":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ChatTitle"}]},"user_metadata":{"$ref":"#/components/schemas/UserMetadata","description":"Arbitrary customer JSON, capped at a kilobyte. Twigg never reads it —\nit is somewhere to hang a ticket reference or a UI flag so the customer\ndoes not have to keep a parallel table keyed by our ids.\n\nAbsent means an empty object, never `null`, so \"no tags\" is one stored\nvalue rather than two."}},"additionalProperties":false},"CreateResponseRequest":{"type":"object","description":"Submit a turn or retry the latest failed run. Responses always use server-sent events.","required":["model","input"],"properties":{"idempotency_key":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/IdempotencyKey","description":"Prevents a second run for the same key. Org-scoped and honoured for 24 hours.\nReusing a key returns HTTP 409 conflict naming the original run in the message;\nit does not replay the SSE stream. After a dropped connection, inspect that run\nwith GET /api/v1/runs/{run_id} and read chat history for persisted output.\nDo not generate a new key merely to retry an uncertain submission."}]},"input":{"type":"array","items":{"oneOf":[{"type":"object","description":"The customer's own turn.","required":["type"],"properties":{"media":{"type":"array","items":{"$ref":"#/components/schemas/SubmittedMedia"}},"text":{"type":"string"},"type":{"type":"string","enum":["prompt"]}}},{"type":"object","description":"The answer to a tool call the model made.","required":["tool_use_id","tool_name","type"],"properties":{"is_error":{"type":"boolean","description":"Anthropic's `tool_result.is_error`. Dropped when translating to a\nprovider with no equivalent."},"media":{"type":"array","items":{"$ref":"#/components/schemas/SubmittedMedia"},"description":"What the tool returned besides text — a screenshot, most often,\nwhich is the canonical case the media tier exists for."},"text":{"type":"string"},"tool_name":{"type":"string","description":"The tool's name, as it was called. Required because Google puts the\nfunction name on the response and nothing else on the row could\nsupply it without joining back to the call."},"tool_use_id":{"$ref":"#/components/schemas/ToolUseId"},"trust":{"$ref":"#/components/schemas/TrustLevel","description":"How far this content is trusted, driving the write-time hygiene\nlimits. Defaults to `customer_data`, the safe assumption."},"type":{"type":"string","enum":["tool_result"]}}}],"description":"One part the customer is submitting.\n\nOnly the two **user-role** kinds are representable. A customer cannot author\na `message`, a `reasoning` block or a `tool_call` — those come back from a\nmodel — so leaving them out makes the impossible submission unconstructible\nrather than merely rejected, and there is no branch anywhere below that has\nto check for one."},"maxItems":128,"minItems":0},"max_tokens":{"type":["integer","null"],"format":"int32","description":"Output ceiling. Only ever **lowered** — by the model's own ceiling, and\nby what the balance can pay for.","minimum":1},"model":{"type":"string","description":"The catalogue `name`, as `GET /api/v1/models` lists it — **not** the\nstring the provider spells it with.\n\nThe two are separate columns precisely so this one can stay stable: the\nwire name carries snapshot dates that vendors move under us, and a\ncustomer who pinned one would break the day an alias was re-pointed.\n\nOnly an **active** model resolves; a withdrawn one would open a turn\nnothing can continue."},"reasoning_effort":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ReasoningEffort","description":"How hard the model should think, where it can. Coerced with a warning\nrather than rejected when the model cannot honour it."}]},"retry_of":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RunId","description":"Retry the latest failed customer run on this chat without appending input.\nSend input: [] and a new idempotency key. Supply the model and any\nrequest-level tools again; the retry uses the current configuration."}]},"tools":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ToolDefinition"},"description":"Tools for this request alone, in the same shape a published bundle uses.\n\nThe **nearest** level there is, so one of these shadows a namespace or\norg-global tool of the same name. They are charged against the context\nbudget like any other tool, because the provider charges for them."},"user_metadata":{"$ref":"#/components/schemas/UserMetadata","description":"Arbitrary customer JSON, attached to every part this turn writes."}},"additionalProperties":false},"DeactivateResponse":{"type":"object","description":"Whether anything was actually withdrawn. The call is idempotent, so `false`\nmeans \"there was no override\", not a failure.","required":["was_active"],"properties":{"was_active":{"type":"boolean"}}},"DefaultPoliciesResponse":{"type":"object","description":"The policies in force for an org that has published nothing.\n\nBoth are the platform documents themselves, not a copy: the console seeds its\neditors from this so the form a customer first sees is the policy actually\nbeing applied to their chats. Editing the shipped documents moves both at\nonce, which is the point — a hard-coded copy in the client is a second\nstatement of the same fact, and the two only ever agree until someone edits\none of them.","required":["retention","budget"],"properties":{"budget":{"$ref":"#/components/schemas/ContextBudget"},"retention":{"$ref":"#/components/schemas/RetentionRules"}}},"Delta":{"oneOf":[{"type":"object","required":["text","kind"],"properties":{"kind":{"type":"string","enum":["text"]},"text":{"type":"string"}}},{"type":"object","required":["text","kind"],"properties":{"kind":{"type":"string","enum":["reasoning"]},"text":{"type":"string"}}},{"type":"object","required":["text","kind"],"properties":{"kind":{"type":"string","enum":["tool_input"]},"text":{"type":"string"}}},{"type":"object","required":["text","kind"],"properties":{"kind":{"type":"string","enum":["refusal"]},"text":{"type":"string"}}}]},"Discovery":{"type":"object","required":["service","versions","openapi","docs","llms_txt"],"properties":{"docs":{"type":"string"},"llms_txt":{"type":"string"},"openapi":{"type":"string"},"service":{"type":"string"},"versions":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}}}},"EagerCompaction":{"oneOf":[{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["off"]}}},{"type":"object","required":["at","mode"],"properties":{"at":{"$ref":"#/components/schemas/BudgetFraction"},"mode":{"type":"string","enum":["at_fill"]}}}]},"ErrorBody":{"type":"object","description":"The customer-visible error payload, shared by HTTP errors and SSE failures.","required":["code","message"],"properties":{"code":{"type":"string"},"details":{},"hint":{"type":["string","null"]},"message":{"type":"string"}}},"ErrorEnvelope":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}}},"HistoryBody":{"oneOf":[{"type":"object","description":"A user prompt.","required":["text","type"],"properties":{"text":{"type":"string"},"type":{"type":"string","enum":["prompt"]}}},{"type":"object","description":"A tool result. `tombstone_reason` is present only when Twigg closed a\npending call whose result never arrived; omit it when submitting results.","required":["tool_use_id","tool_name","text","is_error","trust","type"],"properties":{"is_error":{"type":"boolean"},"text":{"type":"string"},"tombstone_reason":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TombstoneReason"}]},"tool_name":{"type":"string"},"tool_use_id":{"$ref":"#/components/schemas/ToolUseId"},"trust":{"$ref":"#/components/schemas/TrustLevel"},"type":{"type":"string","enum":["tool_result"]}}},{"type":"object","description":"The model's own turn.","required":["text","type"],"properties":{"refusal":{"type":["string","null"]},"text":{"type":"string"},"type":{"type":"string","enum":["message"]}}},{"type":"object","description":"Reasoning text exposed by the provider. Text may be empty when the\nprovider hides its reasoning. Replay signatures are not returned.","required":["text","type"],"properties":{"text":{"type":"string"},"type":{"type":"string","enum":["reasoning"]}}},{"type":"object","description":"A tool call the model made, for the customer to execute.","required":["tool_use_id","tool_name","arguments","type"],"properties":{"arguments":{"type":"string","description":"JSON-encoded tool arguments. Parse this string to obtain the arguments object."},"tool_name":{"type":"string"},"tool_use_id":{"$ref":"#/components/schemas/ToolUseId"},"type":{"type":"string","enum":["tool_call"]}}}],"description":"History content: a user prompt, tool result, assistant message, reasoning or tool call."},"HistoryMedia":{"type":"object","description":"An attachment, as a customer reads it back.","required":["media_id","mime","byte_len"],"properties":{"byte_len":{"type":"integer","format":"int64","minimum":0},"data_base64":{"type":["string","null"],"description":"Standard base64, present only under `include=full`."},"filename":{"type":["string","null"]},"height":{"type":["integer","null"],"format":"int32","minimum":0},"media_id":{"$ref":"#/components/schemas/MediaId"},"mime":{"type":"string"},"page_count":{"type":["integer","null"],"format":"int32","minimum":0},"width":{"type":["integer","null"],"format":"int32","minimum":0}}},"HistoryMode":{"type":"string","enum":["summarize","drop_oldest"]},"HistoryPageResponse":{"type":"object","description":"One page of a chat's parts.","required":["data","first_ordinal","last_ordinal","has_more"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/HistoryPart"},"description":"**Oldest first**, whichever direction was paged — a transcript is read in\nthe order it happened, so a UI appending to the bottom never reverses a\npage."},"first_ordinal":{"type":["integer","null"],"format":"int64","description":"Ordinal of the first part in `data`. Pass as `before_ordinal` to page\nfurther back. `null` when the page is empty."},"has_more":{"type":"boolean","description":"Whether more parts exist **in the direction this page was paged** —\nolder, by default and when paging back; newer, when paging forward."},"last_ordinal":{"type":["integer","null"],"format":"int64","description":"Ordinal of the last part in `data`. Pass as `after_ordinal` to pick up\nwhat arrives after it. `null` when the page is empty."}}},"HistoryPart":{"type":"object","description":"A stored chat part with its ID, position, metadata and content. Prompt and tool-result content can be reused in a new submission; assistant-authored parts cannot be submitted.","required":["id","ordinal","created_at","role","part","user_metadata"],"properties":{"created_at":{"type":"string","format":"date-time"},"id":{"$ref":"#/components/schemas/ChatPartId"},"media":{"type":["array","null"],"items":{"$ref":"#/components/schemas/HistoryMedia"},"description":"Attachments, when the part has any and `include` asked for them.\n\nReturned on the history envelope, separately from `part`. To resubmit an\nattachment, request `include=full` and copy its MIME type, base64 bytes and\noptional filename into the submitted prompt or tool result's `media` list.\nGenerated IDs, sizes and dimensions are read-only history metadata."},"ordinal":{"type":"integer","format":"int64"},"part":{"$ref":"#/components/schemas/HistoryBody"},"role":{"type":"string","description":"`user` or `assistant`, derived from the kind — there is no stored role.\nPresent because a UI's first decision is which side of the transcript a\npart belongs on, and deriving it from five kind names is work every\nclient would otherwise repeat."},"user_metadata":{}}},"IdempotencyKey":{"type":"string","maxLength":128,"minLength":1},"InstructionResponse":{"allOf":[{"$ref":"#/components/schemas/ConfigVersionResponse"},{"type":"object","required":["body"],"properties":{"body":{"type":"string"}}}],"description":"An instruction version with its body — what the editor loads."},"MarkupPercent":{"type":"string"},"MediaCapabilities":{"type":"object","required":["configured","max_attachments_per_part","user","tool_result","assistant"],"properties":{"assistant":{"$ref":"#/components/schemas/MediaPolicy"},"configured":{"type":"boolean","description":"False means legacy adapter defaults, not verified model-level support."},"max_attachments_per_part":{"type":"integer","minimum":0},"tool_result":{"$ref":"#/components/schemas/MediaPolicy"},"user":{"$ref":"#/components/schemas/MediaPolicy"}}},"MediaCarrier":{"type":"string","enum":["user_message","assistant_message","tool_result"]},"MediaId":{"type":"string","format":"uuid"},"MediaPolicy":{"type":"object","required":["mime_types","max_bytes_per_attachment"],"properties":{"max_attachments_per_request":{"type":["integer","null"],"format":"int32","description":"Count across this carrier in the entire context, not per message.","minimum":0},"max_bytes_per_attachment":{"type":"integer","format":"int64","description":"Effective byte ceiling, including the platform inline attachment limit.","minimum":0},"mime_types":{"type":"array","items":{"$ref":"#/components/schemas/MimeType"}}}},"MediaRetentionRule":{"type":"object","description":"One media rule.","required":["mime","retain"],"properties":{"mime":{"$ref":"#/components/schemas/MimePattern"},"retain":{"$ref":"#/components/schemas/RecencyThreshold","description":"How recent a part must be for media of this type to be replayed."}},"additionalProperties":false},"MediaRules":{"type":"object","description":"The media section: which attachments are replayed.","properties":{"default":{"$ref":"#/components/schemas/RecencyThreshold","description":"Applied when no rule matches."},"rules":{"type":"array","items":{"$ref":"#/components/schemas/MediaRetentionRule"}}},"additionalProperties":false},"MimePattern":{"type":"string"},"MimeType":{"type":"string"},"ModelId":{"type":"string","format":"uuid"},"Money":{"type":"string","description":"A signed monetary amount in the stated currency. Negative amounts debit a balance; positive amounts credit it."},"Namespace":{"type":"string","maxLength":255,"minLength":1,"pattern":"^[a-z0-9_-]{1,64}(/[a-z0-9_-]{1,64})*$"},"NamespacePage":{"type":"object","description":"Every namespace in use, ascending.","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Namespace"},"description":"Named `data` like every other listing, so one client-side helper works\nacross the whole surface.\n\n**Chats with no namespace contribute nothing.** Absent is the org's\ndefault scope rather than a value, and returning it as one would invite a\nclient to send it back as a namespace — which is exactly the empty-string\nnamespace the create endpoint rejects."}}},"OrganisationId":{"type":"string","format":"uuid"},"PendingCall":{"type":"object","required":["tool_use_id","tool_name"],"properties":{"tool_name":{"type":"string"},"tool_use_id":{"$ref":"#/components/schemas/ToolUseId"}}},"Provider":{"type":"string","enum":["anthropic","openai","google","xai","fireworks","openrouter"]},"PublicPlatformUpdate":{"type":"object","description":"Published site feed: no account-specific read receipts or draft metadata.","required":["id","title","body","kind","important","published_at"],"properties":{"body":{"$ref":"#/components/schemas/UpdateBody"},"id":{"$ref":"#/components/schemas/UpdateId"},"important":{"type":"boolean"},"kind":{"$ref":"#/components/schemas/UpdateKind"},"published_at":{"type":"string","format":"date-time"},"title":{"$ref":"#/components/schemas/UpdateTitle"},"version":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/UpdateVersion"}]}}},"PublishContextBudgetRequest":{"type":"object","description":"Body for publishing a context budget.\n\n`model_ids` is the tag list: one document applied to each of those models,\none version row each. An **empty** list publishes the scope default instead —\nthe budget every model without a tag of its own uses. Publishing again for the same scope and model creates a new version and makes\nit active; the previous version remains available for restoration.","required":["budget"],"properties":{"budget":{"$ref":"#/components/schemas/ContextBudget"},"model_ids":{"type":"array","items":{"$ref":"#/components/schemas/ModelId"}},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]}},"additionalProperties":false},"PublishInstructionRequest":{"type":"object","description":"Body for publishing an instruction. `mode` is ignored on the global scope,\nwhere there is nothing to combine with.","required":["mode","body"],"properties":{"body":{"type":"string"},"mode":{"$ref":"#/components/schemas/ConfigMode"},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]}},"additionalProperties":false},"PublishRetentionPolicyRequest":{"type":"object","description":"Body for publishing a retention policy. `rules` is validated into\n[`RetentionRules`] at the boundary, so an unreachable rule, a truncation that\ncould never cut anything, or an unknown schema version is a 422 before the\nhandler runs.\n\nNo `mode`: a policy is a complete decision table and is selected whole, so\nthere is nothing to combine and nothing to configure about combining.","required":["rules"],"properties":{"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]},"rules":{"$ref":"#/components/schemas/RetentionRules"}},"additionalProperties":false},"PublishToolsRequest":{"type":"object","description":"Body for publishing a tool bundle. `definitions` is validated into a\n[`ToolBundle`] at the boundary, so a malformed bundle is a 422 before the\nhandler runs.","required":["mode","definitions"],"properties":{"definitions":{"type":"array","items":{"$ref":"#/components/schemas/ToolDefinition"}},"mode":{"$ref":"#/components/schemas/ConfigMode"},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]}},"additionalProperties":false},"RatePerMillion":{"type":"string","description":"Price in the stated currency per one million tokens."},"ReasoningEffort":{"type":"string","enum":["off","low","medium","high","x_high","max"]},"RecencyThreshold":{"type":"number","format":"float"},"ResolvedBudget":{"type":"object","description":"The budget half of a resolution.\n\nSeparate from [`ResolvedConfig`] because it is resolved at a different moment\nand over one axis more: config resolution answers \"what is configured for\nthis namespace\", which a customer can ask without naming a model, while a\nbudget is resolved over namespace *and* model and only means something once a\nrun has picked one.","required":["budget","source","warnings"],"properties":{"budget":{"$ref":"#/components/schemas/ContextBudget","description":"Always present: an org that has published nothing gets the platform\ndefault rather than no budget at all."},"model_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ModelId","description":"The model this was resolved for. `None` asks what an untagged model gets."}]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The scope this was resolved for — what was asked, not what answered.\n[`BudgetSource::Policy::namespace`] is the level that actually supplied\nit, and the two differ whenever a budget is inherited."}]},"source":{"$ref":"#/components/schemas/BudgetSource"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/ConfigWarning"}}}},"ResolvedConfig":{"type":"object","description":"The resolution result.","required":["tools","retention","estimated_tokens","versions","warnings"],"properties":{"estimated_tokens":{"$ref":"#/components/schemas/TokenEstimate","description":"Instruction plus bundle, as budgeted against. Summed from the frozen\nper-row estimates rather than recomputed, so it matches what the packer\nwill use."},"instructions":{"type":["string","null"],"description":"`None` when neither scope has an active instruction — distinct from an\nempty string, which would be an instruction that says nothing."},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The scope this was resolved for. `None` is org-global."}]},"retention":{"$ref":"#/components/schemas/RetentionRules","description":"What a replayed part looks like: which media comes back, how tool\npayloads are truncated, whether reasoning is replayed, what is anchored.\nAlways present — when no scope has published a policy this is the\nplatform default, because \"no configuration\" must not mean \"replay every\nimage forever\".\n\nIt contributes nothing to `estimated_tokens`: a policy is never sent to\na provider, it only decides what of the ledger is, and that cost is\ncounted per part."},"tools":{"type":"array","items":{"$ref":"#/components/schemas/ToolDefinition"}},"versions":{"$ref":"#/components/schemas/ResolvedConfigVersions"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/ConfigWarning"}}}},"ResolvedConfigVersions":{"type":"object","description":"Which version rows produced a resolution. Persisted on a run's manifest so\n\"what configuration did this request use\" keeps its answer after newer\nversions are published.","required":["instructions","tools"],"properties":{"instructions":{"type":"array","items":{"$ref":"#/components/schemas/SystemInstructionId"},"description":"Every instruction version that contributes, **root first** — the order\nthey are concatenated in.\n\nA list rather than a global/namespace pair. The pair could not express\nthe truth at any depth past one: a chain is arbitrarily deep, every level\non `append` contributes, and a `replace` truncates at whichever level\nissued it. Reporting two ids meant a middle level either vanished from\nthe answer or was misreported as the namespace's."},"retention_policy":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RetentionPolicyId","description":"One id, not a list: at most one level's retention policy is ever in\nforce, because a policy is selected whole rather than combined."}]},"tools":{"type":"array","items":{"$ref":"#/components/schemas/ToolSchemaId"},"description":"Every tool bundle version that contributes, root first. Same reasoning."}}},"ResponseEvent":{"oneOf":[{"type":"object","description":"Always first: identifiers and tool calls closed by this submission.","required":["data","event"],"properties":{"data":{"type":"object","description":"Always first: identifiers and tool calls closed by this submission.","required":["run_id","chat_id","closed_tool_calls"],"properties":{"chat_id":{"$ref":"#/components/schemas/ChatId"},"closed_tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/ToolUseId"}},"run_id":{"$ref":"#/components/schemas/RunId"}}},"event":{"type":"string","enum":["run"]}}},{"type":"object","description":"Configuration warnings; emitted second, and may repeat after compaction.","required":["data","event"],"properties":{"data":{"type":"object","description":"Configuration warnings; emitted second, and may repeat after compaction.","required":["warnings"],"properties":{"warnings":{"type":"array","items":{"$ref":"#/components/schemas/Warning_ConfigWarning"}}}},"event":{"type":"string","enum":["config_warnings"]}}},{"type":"object","description":"Model compatibility warnings before content starts.","required":["data","event"],"properties":{"data":{"type":"object","description":"Model compatibility warnings before content starts.","required":["warnings"],"properties":{"warnings":{"type":"array","items":{"$ref":"#/components/schemas/Warning_TranslationWarning"}}}},"event":{"type":"string","enum":["translation_warnings"]}}},{"type":"object","description":"Compaction work the request is waiting for.","required":["data","event"],"properties":{"data":{"type":"object","description":"Compaction work the request is waiting for.","required":["blocks","in_progress_elsewhere"],"properties":{"blocks":{"type":"integer","minimum":0},"in_progress_elsewhere":{"type":"integer","minimum":0}}},"event":{"type":"string","enum":["compacting"]}}},{"type":"object","required":["data","event"],"properties":{"data":{"$ref":"#/components/schemas/BlockStart"},"event":{"type":"string","enum":["block_start"]}}},{"type":"object","required":["data","event"],"properties":{"data":{"$ref":"#/components/schemas/Delta"},"event":{"type":"string","enum":["delta"]}}},{"type":"object","required":["data","event"],"properties":{"data":{"type":"object"},"event":{"type":"string","enum":["block_stop"]}}},{"type":"object","description":"Terminal success. Null cost means settlement is pending; inspect the run later.","required":["data","event"],"properties":{"data":{"type":"object","description":"Terminal success. Null cost means settlement is pending; inspect the run later.","required":["cost","cost_currency","stop_reason","usage","server_tools","model_served","provider_response_id","pending_tool_calls","compaction"],"properties":{"compaction":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Compaction"}]},"cost":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Money"}]},"cost_currency":{"type":"string"},"model_served":{"type":["string","null"],"description":"The model identifier reported by the upstream provider, when available.\nThis may differ from the catalogue name used in the request (for example,\ngpt-5-6-luna can return gpt-5.6-luna). Do not use this as a catalogue lookup key."},"pending_tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/PendingCall"}},"provider_response_id":{"type":["string","null"]},"server_tools":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ServerToolUsage"}]},"stop_reason":{"$ref":"#/components/schemas/StopReason"},"usage":{"$ref":"#/components/schemas/Usage"}}},"event":{"type":"string","enum":["done"]}}},{"type":"object","description":"Terminal failure after the stream has opened.","required":["data","event"],"properties":{"data":{"$ref":"#/components/schemas/ErrorBody","description":"Terminal failure after the stream has opened."},"event":{"type":"string","enum":["error"]}}}],"description":"Each variant is one SSE frame: `event: <event>` followed by `data: <JSON>`.\nThe wrapper documents the framing; only its `data` is sent as the JSON payload."},"RetentionPolicyId":{"type":"string","format":"uuid"},"RetentionPolicyResponse":{"allOf":[{"$ref":"#/components/schemas/ConfigVersionResponse"},{"type":"object","required":["rules"],"properties":{"rules":{"$ref":"#/components/schemas/RetentionRules"}}}],"description":"One retention-policy version with its rules.\n\nNo `estimated_tokens`: a policy is never sent to a provider, so unlike an\ninstruction or a bundle it has no token cost of its own. The version envelope\nis shared with the other surfaces, so the field is reported as zero rather\nthan given a separate response shape for one absent number."},"RetentionRules":{"type":"object","description":"The stored document. Private fields: holding one is proof it parsed.","required":["version"],"properties":{"anchor_parts":{"type":"integer","format":"int32","description":"How many parts at the head of the chat are pinned verbatim, never\ncompacted and never truncated. `0` disables it.\n\nCounted in **parts**, not tokens, because the value a customer wants to\nexpress is \"the task spec\", which is a part boundary they can see — not a\ntoken count they would have to estimate and re-tune whenever they edited\nthe spec.","minimum":0},"media":{"$ref":"#/components/schemas/MediaRules"},"reasoning":{"$ref":"#/components/schemas/RecencyThreshold","description":"How recent a part must be for its reasoning to be replayed. Defaults to\nthe same window as media: a reasoning block's replay token is worthless\nto a model of another family anyway, and old reasoning is the least\nload-bearing, most expensive thing in a long agentic history."},"text":{"$ref":"#/components/schemas/TextRules"},"tools":{"$ref":"#/components/schemas/ToolRules"},"verbatim_within":{"$ref":"#/components/schemas/RecencyThreshold","description":"How recent a payload must be to escape truncation entirely — tool results,\ntool arguments and prose alike.\n\nOne setting for the whole document, deliberately, and the direct\ndescendant of the old `truncate_within_frontier` flag. \"Don't cut the tool\noutput I just received\" is not a per-tool judgement, and giving each\nfamily its own would put three definitions of \"recent\" back in a document\nwhose entire point is that there is one.\n\nHoisted out of the tool section when prose truncation arrived: the\nalternative was a second identical field on [`TextRules`], which is how a\nshared metric quietly becomes two that drift."},"version":{"type":"integer","format":"int32","minimum":0}},"additionalProperties":false},"RunId":{"type":"string","format":"uuid"},"RunInspection":{"type":"object","required":["id","chat_id","namespace","origin","status","is_live","error","model","provider_request_id","usage","latency_ms","cost","settled_at","manifest","created_at","completed_at"],"properties":{"chat_id":{"$ref":"#/components/schemas/ChatId"},"completed_at":{"type":["string","null"],"format":"date-time"},"cost":{"type":["string","null"],"description":"What it was charged, once settled. `None` covers both \"still running\" and\n\"finished but not yet settled\" — a sweep may be seconds or hours behind,\nand the two are the same fact to a reader: no charge has landed yet."},"created_at":{"type":"string","format":"date-time"},"error":{"type":["string","null"],"description":"The failure, when there was one. Present on `failed` runs only."},"id":{"$ref":"#/components/schemas/RunId"},"is_live":{"type":"boolean","description":"Whether a running call has an unexpired durable ownership lease.\nFalse on expiry, before recovery necessarily closes the run. A paused\nworker is indistinguishable from a dead one and is fenced in either case."},"latency_ms":{"type":["integer","null"],"format":"int32"},"manifest":{"type":"object","description":"The context and configuration this call actually used. Opaque JSON on\npurpose: it is a record, not an API — the shape follows what the planner\nhappened to record, and freezing it into typed fields would make every\nplanner change a breaking change here."},"model":{"type":"string","description":"Our catalogue `name`, never the provider's wire string — the same\nidentifier the customer sent and `/api/v1/models` lists."},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The scope the run's configuration resolved against. `None` is org-global."}]},"origin":{"$ref":"#/components/schemas/RunOrigin","description":"Whether the customer asked for this call or we did. A `compaction` run is\none the customer never made and is still billed for, which is exactly why\nit is visible here rather than folded into inference."},"provider_request_id":{"type":["string","null"],"description":"The provider's own id for the call, for quoting at us in a support\nconversation. Already visible on the turn's terminal SSE event."},"settled_at":{"type":["string","null"],"format":"date-time"},"status":{"$ref":"#/components/schemas/RunStatus","description":"**The durable answer**, from the `runs` row and never from the cache."},"usage":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Usage","description":"`None` while in flight, or after interruption when usage was lost.\nMissing counts must never be presented as confirmed zero usage."}]}}},"RunOrigin":{"type":"string","enum":["customer","compaction"]},"RunStatus":{"type":"string","enum":["running","succeeded","failed","cancelled"]},"ServerToolUsage":{"type":"object","description":"Provider-executed operations. Counts are successful billable operations,\ntaken from terminal usage, not inferred from streamed attempts.","required":["document_search_calls"],"properties":{"document_search_calls":{"type":"integer","format":"int32","minimum":0},"provider_cost":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Money","description":"Total provider charge, including tokens, when document tools were used."}]}}},"StopReason":{"type":"string","enum":["end_turn","max_tokens","tool_use","stop_sequence","refusal"]},"SubmittedMedia":{"type":"object","description":"An inline attachment. Supply standard base64 bytes without a data-URI prefix and the matching MIME type. Model-specific format, byte and count limits apply.","required":["mime","data_base64"],"properties":{"data_base64":{"type":"string","description":"Standard base64, no data-URI prefix.\n\nNamed for its encoding because the field is what a customer has to get\nright, and `data` alone invites a raw string or a `data:` URL — both of\nwhich would decode to something, quietly, and be sealed as an image\nnothing can open."},"filename":{"type":["string","null"],"description":"Shown in a UI, and named in the stub that replaces this attachment once\nretention drops it — which is why it is worth carrying even though no\nprovider requires it."},"mime":{"type":"string","description":"Explicit MIME type, such as `image/png` or `application/pdf`. Validated\nagainst the selected model's configured media capabilities before the\nturn is persisted. Supported formats differ by model and carrier."}},"additionalProperties":false},"SubmittedPart":{"oneOf":[{"type":"object","description":"The customer's own turn.","required":["type"],"properties":{"media":{"type":"array","items":{"$ref":"#/components/schemas/SubmittedMedia"}},"text":{"type":"string"},"type":{"type":"string","enum":["prompt"]}}},{"type":"object","description":"The answer to a tool call the model made.","required":["tool_use_id","tool_name","type"],"properties":{"is_error":{"type":"boolean","description":"Anthropic's `tool_result.is_error`. Dropped when translating to a\nprovider with no equivalent."},"media":{"type":"array","items":{"$ref":"#/components/schemas/SubmittedMedia"},"description":"What the tool returned besides text — a screenshot, most often,\nwhich is the canonical case the media tier exists for."},"text":{"type":"string"},"tool_name":{"type":"string","description":"The tool's name, as it was called. Required because Google puts the\nfunction name on the response and nothing else on the row could\nsupply it without joining back to the call."},"tool_use_id":{"$ref":"#/components/schemas/ToolUseId"},"trust":{"$ref":"#/components/schemas/TrustLevel","description":"How far this content is trusted, driving the write-time hygiene\nlimits. Defaults to `customer_data`, the safe assumption."},"type":{"type":"string","enum":["tool_result"]}}}],"description":"One part the customer is submitting.\n\nOnly the two **user-role** kinds are representable. A customer cannot author\na `message`, a `reasoning` block or a `tool_call` — those come back from a\nmodel — so leaving them out makes the impossible submission unconstructible\nrather than merely rejected, and there is no branch anywhere below that has\nto check for one."},"SystemInstructionId":{"type":"string","format":"uuid"},"TextRules":{"type":"object","description":"Truncation policies for older user prompts and assistant messages. The current exchange and configured anchor remain protected.","properties":{"message":{"$ref":"#/components/schemas/Truncation","description":"Applied to an assistant `message`'s text.\n\nSeparate from `prompt` for the same reason a tool's arguments and result\nare separate: they are different sizes with different value. A customer\npasting logs wants their own input cut; a customer whose model writes long\nanswers wants the replies cut."},"prompt":{"$ref":"#/components/schemas/Truncation","description":"Applied to a `prompt` part's text."}},"additionalProperties":false},"TierMode":{"type":"string","enum":["cliff","graduated"]},"TokenEstimate":{"type":"integer","format":"int32","description":"A count of estimated tokens. Always non-negative; saturates rather than\noverflowing, because a budget calculation must never wrap into a small\nnumber and wave through a request that cannot fit."},"TombstoneReason":{"type":"string","enum":["abandoned","cancelled","expired"]},"ToolDefinition":{"type":"object","description":"A named tool with a description and JSON Schema parameters. Parameters must be a valid schema describing an object; external schema references are not supported.","required":["name","input_schema"],"properties":{"description":{"type":["string","null"]},"input_schema":{"type":"object"},"name":{"$ref":"#/components/schemas/ToolName"},"strict":{"type":["boolean","null"],"description":"Ask the provider to guarantee the tool call validates against the schema.\n\n`None` means the customer did not say, which is distinct from `false`:\nthe providers' own defaults differ, and translating an unstated\npreference into an explicit `false` would silently opt a customer out of\na guarantee they never declined. Dropped when targeting Google, which has\nno equivalent."}}},"ToolName":{"type":"string"},"ToolNamePattern":{"type":"string"},"ToolRetentionRule":{"allOf":[{"$ref":"#/components/schemas/ToolTreatment"},{"type":"object","required":["tool"],"properties":{"tool":{"$ref":"#/components/schemas/ToolNamePattern"}}}],"description":"One tool rule."},"ToolRules":{"type":"object","description":"The tool section: how tool payloads are cut down.","properties":{"default":{"$ref":"#/components/schemas/ToolTreatment","description":"Applied when no rule matches."},"errors":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Truncation","description":"Replaces the matched `result` treatment on a part flagged `is_error`.\n`None` means errors follow the ordinary rule.\n\nWorth its own knob because failures split the customer base cleanly: for\none, a stack trace is the most valuable thing in the history; for the\nnext, it is a retry loop's worth of noise."}]},"mark_truncations":{"type":"boolean","description":"Whether a cut payload carries a visible marker of what was elided.\n\nDefaults **on**, and deliberately not a per-rule choice: a model that\ncannot tell output was truncated will confidently invent the missing\nmiddle, and that failure is not a per-tool judgement call."},"rules":{"type":"array","items":{"$ref":"#/components/schemas/ToolRetentionRule"}}},"additionalProperties":false},"ToolSchemaId":{"type":"string","format":"uuid"},"ToolSchemaResponse":{"allOf":[{"$ref":"#/components/schemas/ConfigVersionResponse"},{"type":"object","required":["definitions"],"properties":{"definitions":{"type":"array","items":{"$ref":"#/components/schemas/ToolDefinition"}}}}],"description":"One tool-bundle version with its definitions — the single-version shape, the\nsibling of [`InstructionResponse`]. The history endpoint returns bare\n[`ConfigVersionResponse`]s, because definitions are sealed and listing them\nwould be a fetch and a decrypt per row."},"ToolTreatment":{"type":"object","description":"How one tool's two payloads are treated. Arguments and results are separate\nbecause they are separate parts with separate sizes — a `write_file` call's\narguments routinely dwarf its result, and a `search` call's result dwarfs its\narguments.","properties":{"arguments":{"$ref":"#/components/schemas/Truncation","description":"Applied to the `tool_call` arguments."},"result":{"$ref":"#/components/schemas/Truncation","description":"Applied to the `tool_result` payload."}},"additionalProperties":false},"ToolUseId":{"type":"string"},"Truncation":{"oneOf":[{"type":"object","description":"Replay it whole, however large.","required":["mode"],"properties":{"mode":{"type":"string","enum":["keep"]}}},{"type":"object","description":"Always cut to `to` tokens.","required":["to","mode"],"properties":{"keep":{"$ref":"#/components/schemas/TruncationShape"},"mode":{"type":"string","enum":["always"]},"to":{"$ref":"#/components/schemas/TokenEstimate"}}},{"type":"object","description":"Cut to `to` tokens, but only once the payload exceeds `over`. The common\nshape: small results replay verbatim, a runaway one is clipped.","required":["over","to","mode"],"properties":{"keep":{"$ref":"#/components/schemas/TruncationShape"},"mode":{"type":"string","enum":["over"]},"over":{"$ref":"#/components/schemas/TokenEstimate"},"to":{"$ref":"#/components/schemas/TokenEstimate"}}}],"description":"Keep content unchanged, always truncate to a token target, or truncate only when it exceeds a threshold. Choose the head, tail, or both ends to retain."},"TruncationShape":{"type":"string","enum":["head","tail","head_and_tail"]},"TrustLevel":{"type":"string","enum":["trusted","customer_data","untrusted"]},"UpdateBody":{"type":"string"},"UpdateId":{"type":"string","format":"uuid"},"UpdateKind":{"type":"string","enum":["release","notice","maintenance"]},"UpdateTitle":{"type":"string"},"UpdateVersion":{"type":"string"},"Uptime":{"type":"string","description":"A measured ratio from 0 to 1; multiply by 100 to display a percentage."},"Usage":{"type":"object","required":["input_tokens","output_tokens","cache_read_tokens","cache_write_tokens","reasoning_tokens"],"properties":{"cache_read_tokens":{"type":"integer","format":"int32","description":"Served from the provider's prompt cache, billed below base rate.","minimum":0},"cache_write_tokens":{"type":"integer","format":"int32","description":"Written to the provider's prompt cache, billed above base rate. The\nResponses API does not meter this and reports zero.","minimum":0},"input_tokens":{"type":"integer","format":"int32","description":"Billable input at the base rate. Excludes both cache figures.","minimum":0},"output_tokens":{"type":"integer","format":"int32","description":"Everything the model produced, reasoning included.","minimum":0},"reasoning_tokens":{"type":"integer","format":"int32","description":"The thinking share of [`Self::output_tokens`]. **A subset, not an\naddition** — reported for visibility, never summed into the total.","minimum":0}}},"UsageBin":{"type":"string","enum":["hour","day"]},"UsageDimension":{"type":"string","enum":["model","namespace","api_key","entry_type","organisation","run"]},"UsageGroup":{"oneOf":[{"type":"object","required":["dimension"],"properties":{"dimension":{"type":"string","enum":["model"]},"model_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ModelId","description":"Absent on a credit, which names no model."}]},"model_name":{"type":["string","null"]}}},{"type":"object","description":"`None` is the org-global scope — chats created without a namespace — not\nan unknown one.","required":["dimension"],"properties":{"dimension":{"type":"string","enum":["namespace"]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]}}},{"type":"object","description":"`None` covers events with no key: console-initiated work, and credits.","required":["dimension"],"properties":{"api_key_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ApiKeyId"}]},"dimension":{"type":"string","enum":["api_key"]}}},{"type":"object","description":"Usage grouped by organisation. Labels are null when unavailable.","required":["organisation_id","dimension"],"properties":{"dimension":{"type":"string","enum":["organisation"]},"name":{"type":["string","null"]},"organisation_id":{"$ref":"#/components/schemas/OrganisationId"},"slug":{"type":["string","null"]}}},{"type":"object","required":["entry_type","dimension"],"properties":{"dimension":{"type":"string","enum":["entry_type"]},"entry_type":{"$ref":"#/components/schemas/BalanceEntryType"}}},{"type":"object","required":["entry_type","dimension"],"properties":{"api_key_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ApiKeyId"}]},"dimension":{"type":"string","enum":["run"]},"entry_type":{"$ref":"#/components/schemas/BalanceEntryType"},"last_occurred_at":{"type":["string","null"],"format":"date-time","description":"When this run last recorded an event — what the list is ordered by,\nsince a run has no single instant of its own here."},"model_name":{"type":["string","null"]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]},"run_id":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RunId"}]}}}],"description":"Which slice a row is, and everything needed to label it.\n\nA tagged union rather than a `key: String`, because the labels are not\ninterchangeable: a model row needs the id *and* the human name, a namespace\nrow's key can legitimately be absent (the org-global scope), and a run row\ncarries the context you would drill from."},"UsageReport":{"type":"object","description":"A report: the rows, plus the shape of the question they answer.\n\nThe window is echoed because it is not what the caller literally asked for —\na range preset is resolved against the clock and rounded to the hour — and a\nchart that cannot state its own axis is a chart nobody can check.","required":["window","rows","cached"],"properties":{"bin":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/UsageBin"}]},"cached":{"type":"boolean","description":"Whether these rows came from the cache. Surfaced rather than hidden: the\nconsole tells the customer their usage lags by minutes, and this is the\nhonest version of that sentence."},"group_by":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/UsageDimension"}]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace"}]},"rows":{"type":"array","items":{"$ref":"#/components/schemas/UsageRow"}},"window":{"$ref":"#/components/schemas/UsageWindow"}}},"UsageRow":{"allOf":[{"$ref":"#/components/schemas/UsageTotals"},{"type":"object","properties":{"bucket":{"type":["string","null"],"format":"date-time"},"group":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/UsageGroup"}]}}}],"description":"One row of a report: an optional bucket, an optional group, and the measures.\n\nBoth are `Option` because the same row type serves all four query shapes, and\nwhich of them are populated is a property of the query rather than of the\nrow — the report echoes the query shape beside the rows so a reader never has\nto infer it."},"UsageTotals":{"type":"object","description":"The measures every row carries, whatever it is grouped by.\n\n`runs` counts **distinct run ids**, not events: a run that was compacted\nproduces two events naming it, and counting rows would report the busy runs\ntwice. Credits share the analytics source table but are excluded from this\nusage report.","required":["runs","input_tokens","output_tokens","cache_read_tokens","cache_write_tokens","reasoning_tokens","cost"],"properties":{"cache_read_tokens":{"type":"integer","format":"int64"},"cache_write_tokens":{"type":"integer","format":"int64"},"cost":{"$ref":"#/components/schemas/Money","description":"Model-call spend in the requested window. Credits share the source table\nbut are excluded from usage reports."},"input_tokens":{"type":"integer","format":"int64"},"output_tokens":{"type":"integer","format":"int64"},"reasoning_tokens":{"type":"integer","format":"int64","description":"A subset of `output_tokens`, never an addition — and priced at zero, so\nit explains a cost rather than adding to it."},"runs":{"type":"integer","format":"int64"}}},"UsageWindow":{"type":"object","description":"A validated `[from, to)` range over `occurred_at`.\n\nHalf-open, so consecutive windows tile without double-counting the instant\non the boundary — an event at exactly midnight belongs to one day, not two.","required":["from","to"],"properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"UserMetadata":{"type":"object","description":"Customer JSON object, at most 1024 bytes when serialized compactly. Defaults to an empty object."},"Warning_ConfigWarning":{"allOf":[{"oneOf":[{"type":"object","description":"A namespace tool replaced a global tool of the same name. The union is\nkeyed on name, so this is how an override is *meant* to work — but it is\nalso exactly what a typo in a tool name looks like from the outside.","required":["name","namespace","code"],"properties":{"code":{"type":"string","enum":["tool_shadowed"]},"name":{"$ref":"#/components/schemas/ToolName"},"namespace":{"$ref":"#/components/schemas/Namespace"}}},{"type":"object","description":"The namespace's instruction is in `replace` mode, so the org-global\ninstruction is not being sent at all.","required":["namespace","code"],"properties":{"code":{"type":"string","enum":["global_instruction_replaced"]},"namespace":{"$ref":"#/components/schemas/Namespace"}}},{"type":"object","description":"The namespace's tool bundle is in `replace` mode, so the global bundle\nis not being sent at all — including tools the customer may assume are\nalways present.","required":["namespace","dropped","code"],"properties":{"code":{"type":"string","enum":["global_tools_replaced"]},"dropped":{"type":"integer","minimum":0},"namespace":{"$ref":"#/components/schemas/Namespace"}}},{"type":"object","description":"A nearer level's retention policy displaced a farther level's. This is how\nthe override is *meant* to work: a policy is a complete decision table and\nis selected whole, so the farther one contributes nothing — not its rules\nand not its defaults. It still warns, because the result looks identical\neither way, and \"my org-wide rule stopped applying\" is otherwise\nundiagnosable.\n\nBoth levels are named because at depth neither is guessable from the\nother: \"a namespace policy won\" does not say which of four ancestors\nstopped applying.","required":["code"],"properties":{"code":{"type":"string","enum":["retention_policy_overridden"]},"displaced":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The nearest level whose policy is not being applied."}]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The level whose policy is in force. `None` is org-global."}]}}},{"type":"object","description":"The budget in force did not come from the plainest place: either an\nancestor level supplied it, or a model tag at the winning level displaced\nthat level's untagged policy — or both.\n\nTwo facts, one warning, because either alone misleads. \"The budget came\nfrom `acme`\" and \"the budget came from `acme`, tagged to this model\" send\nan admin to different rows, and the second is the only one that explains\nwhy a sibling model in the same namespace behaves differently.","required":["code"],"properties":{"code":{"type":"string","enum":["context_budget_resolved_at"]},"namespace":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Namespace","description":"The level that supplied it. `None` is the org-global scope."}]},"tagged_model":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ModelId","description":"`Some` when that level's tag for this model beat its untagged policy."}]}}},{"type":"object","description":"Oldest ledger parts were omitted because no complete context fitted.","required":["dropped","start_ordinal","end_ordinal","code"],"properties":{"code":{"type":"string","enum":["history_dropped"]},"dropped":{"type":"integer","format":"int64"},"end_ordinal":{"type":"integer","format":"int64"},"start_ordinal":{"type":"integer","format":"int64"}}}],"description":"Something legal but worth saying out loud."},{"type":"object","required":["message"],"properties":{"message":{"type":"string"}}}]},"Warning_TranslationWarning":{"allOf":[{"oneOf":[{"type":"object","description":"Historical attachments exceeded the target model's byte or request-count\nlimit and were replaced with text markers. Aggregated per (MIME, carrier).","required":["mime","carrier","count","code"],"properties":{"carrier":{"$ref":"#/components/schemas/MediaCarrier"},"code":{"type":"string","enum":["media_limit_exceeded"]},"count":{"type":"integer","minimum":0},"mime":{"$ref":"#/components/schemas/MimeType"}}},{"type":"object","description":"Media the target model cannot receive in this position was replaced with\na text marker. Aggregated per (MIME, carrier), separately from retention.","required":["mime","carrier","count","code"],"properties":{"carrier":{"$ref":"#/components/schemas/MediaCarrier"},"code":{"type":"string","enum":["media_unsupported"]},"count":{"type":"integer","minimum":0},"mime":{"$ref":"#/components/schemas/MimeType"}}},{"type":"object","description":"Reasoning was requested but the target model does not support it, so the\nrequest went without a thinking configuration.","required":["model","code"],"properties":{"code":{"type":"string","enum":["reasoning_not_supported"]},"model":{"type":"string"}}},{"type":"object","description":"Reasoning was switched **off** and the provider has no way to express\nthat, so thinking remained enabled.\n\nThe mirror of [`ReasoningNotSupported`](Self::ReasoningNotSupported), and\nthe reason it is a warning rather than something to swallow: the customer\ngets more than they asked for *and is billed for it*. The Responses API\nhas no \"off\" every vendor behind it accepts — the candidates are\nmodel-specific and rejected elsewhere — so omitting the block is the only\nuniversally legal shape, and omitting it means the default applies.\nSilence here would make an explicit `off` look honoured while it quietly\ncosts money on every turn.","required":["model","code"],"properties":{"code":{"type":"string","enum":["reasoning_cannot_be_disabled"]},"model":{"type":"string"}}},{"type":"object","description":"The requested effort tier is above what this model accepts and was\nlowered. The run still happened, at less depth than asked for.","required":["model","requested","applied","code"],"properties":{"applied":{"$ref":"#/components/schemas/ReasoningEffort"},"code":{"type":"string","enum":["reasoning_effort_clamped"]},"model":{"type":"string"},"requested":{"$ref":"#/components/schemas/ReasoningEffort"}}},{"type":"object","description":"A tool definition carried a field the target provider has no equivalent\nfor (Google has no `strict`; only Anthropic has document `title` /\n`context`). Dropped on translation.","required":["tool","field","code"],"properties":{"code":{"type":"string","enum":["tool_field_dropped"]},"field":{"type":"string"},"tool":{"$ref":"#/components/schemas/ToolName"}}},{"type":"object","description":"Replay artifacts authored by a different model family were stripped,\nbecause a signature from one family is meaningless — or a hard rejection —\nto another. Expected whenever a chat hot-swaps providers, and reported so\na customer comparing two runs of the same chat can see why the second one\nlost its reasoning continuity.","required":["count","code"],"properties":{"code":{"type":"string","enum":["foreign_artifacts_stripped"]},"count":{"type":"integer","minimum":0}}}]},{"type":"object","required":["message"],"properties":{"message":{"type":"string"}}}]}},"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer"}}}}