Base URL
https://platform.continualmi.com/v1Every path on this page is relative to that base.
Authentication
All endpoints require a bearer token created on the Keys page. Keys have the shape cmi_live_<public>.<secret>; only a hash of the secret is stored.
Authorization: Bearer cmi_live_<public>.<secret>Headers
| Header | Required | Applies to | Notes |
|---|---|---|---|
Authorization | yes | all | Bearer <api-key> |
Content-Type | yes (POST) | all | application/json |
Idempotency-Key | recommended | POST /entities/{id}/messages | Any string unique per message, up to 200 characters. A retry with the same key returns the reply already given instead of appending the message again. |
Accept | no | GET /entities/{id}/export | application/json (default) or application/x-continual-entity for the tar archive. |
Entities
A persistent being with server-side memory. Create it once, then send only new messages. Required scope for every entity endpoint: mgpt.responses:create. An entity is visible only to the account that created it; any key on that account can use it.
Create entity
/entities| Field | Type | Required | Notes |
|---|---|---|---|
model | string | yes | Model id, fixed for the entity's life. mgpt-1-27b. |
name | string | no | Up to 200 characters. Display only. |
instructions | string | no | The entity's standing system prompt. Always shown to the model, never rotated out. |
Returns 201 with the entity object plus entity_id.
curl https://platform.continualmi.com/v1/entities \
-H "Authorization: Bearer $CONTINUAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "mgpt-1-27b", "name": "Ada", "instructions": "You are Ada." }'List entities
/entitiesThe account's entities, most recently active first, up to 200. Returns { "object": "list", "data": [entity, …] }.
Retrieve entity
/entities/{id}The entity object, including the live window's token and block counts. Returns 404 for an id that does not belong to the account.
Send message
/entities/{id}/messagesAppends the message to the entity, rotates the window if it is over budget, generates the reply from the entity's window, and appends the reply. Writes to one entity are serialized: a second message while one is in flight returns 409.
| Field | Type | Required | Notes |
|---|---|---|---|
content | string | yes | The user message. |
stream | boolean | no | Default true. Set false for one buffered response. |
idempotency_key | string | no | Same as the Idempotency-Key header; the header wins if both are present. |
Streamed (default): text/event-stream of chat.completion.chunk objects in the standard streaming shape — a usage chunk precedes [DONE]. The response also carries an X-Entity-Id header.
Buffered (stream: false): a chat.completion object with an extra entity_id field.
curl -N https://platform.continualmi.com/v1/entities/$ENTITY/messages \
-H "Authorization: Bearer $CONTINUAL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: msg-0412" \
-d '{ "content": "Where did we leave off?" }'
data: {"id":"…","object":"chat.completion.chunk","model":"mgpt-1-27b","choices":[{"index":0,"delta":{"role":"assistant","content":"We were"},"finish_reason":null}]}
data: {"id":"…","object":"chat.completion.chunk","model":"mgpt-1-27b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"…","object":"chat.completion.chunk","model":"mgpt-1-27b","choices":[],"usage":{"prompt_tokens":812,"completion_tokens":61,"total_tokens":873}}
data: [DONE]usage.prompt_tokens reports what the model was shown, for transparency. You are billed for the message you sent and the reply, not for the window.
List messages
/entities/{id}/messagesThe transcript — every message ever, whether or not it is still in the window.
| Query parameter | Type | Required | Notes |
|---|---|---|---|
after | integer | no | Return messages with seq greater than this. Default 0. |
limit | integer 1–500 | no | Default 100. |
{
"object": "list",
"entity_id": "…",
"data": [
{ "seq": 1, "role": "user", "content": "…", "tokens": 18, "created_at": "2026-09-01T21:44:01Z" },
{ "seq": 2, "role": "assistant", "content": "…", "tokens": 41, "created_at": "2026-09-01T21:44:03Z" }
],
"has_more": false,
"next_after": 2
}Retrieve window
/entities/{id}/windowWhat the model is shown on the next turn, verbatim: the ordered alive blocks. A summary block's covers is the inclusive transcript range it replaced; a message block covers exactly its own seq.
{
"entity_id": "…",
"object": "entity.window",
"budget_tokens": 32000,
"tokens": 1418,
"blocks": [
{ "id": "…", "kind": "summary", "role": "system", "content": "…", "tokens": 210, "covers": [1, 38] },
{ "id": "…", "kind": "message", "role": "user", "content": "…", "tokens": 12, "covers": [39, 39] },
{ "id": "…", "kind": "message", "role": "assistant", "content": "…", "tokens": 61, "covers": [40, 40] }
]
}Export entity
/entities/{id}/exportContent-negotiated. With Accept: application/json (default) the response is the manifest plus the full transcript. With Accept: application/x-continual-entity it is a tar archive containing manifest.json, transcript.json and window.json. Model state joins the archive when native weights serve; the container does not change.
curl https://platform.continualmi.com/v1/entities/$ENTITY/export \
-H "Authorization: Bearer $CONTINUAL_API_KEY" \
-H "Accept: application/x-continual-entity" -o ada.tarDelete entity
/entities/{id}Hard-deletes transcript, window and state. Returns 202 { "id": "…", "object": "entity", "deleted": true }; removal completes within 24 hours across backups. Irreversible.
The entity object
{
"id": "551e9290-…",
"object": "entity",
"name": "Ada",
"instructions": "You are Ada.",
"model": "mgpt-1-27b",
"state": "none",
"read_only": false,
"transcript": { "messages": 40, "tokens": 6120, "cap_tokens": 1000000 },
"window": { "budget_tokens": 32000, "tokens": 1418, "blocks": 3 },
"created_at": "2026-09-01T21:44:00Z",
"updated_at": "2026-09-01T22:10:12Z"
}| Field | Type | Notes | |
|---|---|---|---|
state | string | none while the backbone is routed; names the attached model state once native weights serve. | |
read_only | boolean | true once the transcript reaches cap_tokens; messages then return 409. | |
transcript | object | Message count and estimated tokens across the whole history. | |
window | object | Budget and current size of the live window. tokens/blocks are present on retrieve, not on list. |
Errors
Errors return JSON with an error field and an HTTP status.
{ "error": "Unsupported model: example-model" }| Status | Meaning | Notes | |
|---|---|---|---|
400 | Validation error | Missing field, invalid messages, or unsupported model. | |
401 | Unauthorized | Missing or invalid bearer token. | |
402 | Insufficient balance | Body also carries balanceUsd, billedUsd, missingUsd. | |
403 | Forbidden | Key lacks the required scope. | |
404 | Not found | No such entity on this account. | |
409 | Conflict | Entity busy with another message, or read-only at the transcript cap. | |
5xx | Provider / platform failure | Safe to retry; a failed entity turn leaves no trace. |
Scopes
| Scope | Endpoints | ||
|---|---|---|---|
mgpt.responses:create | all /entities endpoints | The only scope keys carry today. |