API

API reference

Every /api/v2 endpoint — agent configuration, databases, documents, turns, WhatsApp, boards, account, conversations, files and partners — with its OpenAPI 3.1 schema.

Updated 2026-10-01

Try it from here: in the viewer below, paste your agent's token (Agents → your agent → Generar token) into the agentToken auth field and run GET /api/v2/agents/{id}; calls go against the real API.

The full specification is at (OpenAPI 3.1). It is rendered below; you can import it into Postman or Bruno, or generate a client with openapi-generator.

Base: https://www.ghosty.studio. Every route requires Authorization: Bearer () and responds JSON with Cache-Control: no-store.

Map

ResourceRoutes
Agent configuration (gat_ token or session)GET/PATCH/DELETE /api/v2/agents/:id, PUT/DELETE/GET …/files/*, GET …/skills, GET/PUT …/skills/house, PUT/PATCH/DELETE …/skills/:slug, GET/PUT …/mcp, POST …/restart, GET …/templates, GET/POST/DELETE …/shares, GET/POST/DELETE …/teams, GET/PUT …/demo — see and
The agent as a fileGET …/export (YAML) and POST …/apply (plan and apply), with your session (not gat_); GET/POST …/bundle (Eve style) ·
Databases and photosGET …/dbs, PUT/DELETE …/dbs/:db, POST …/dbs/:db/query, GET …/dbs/:db/export, POST …/dbs/:db/import, POST …/dbs/:db/rehost, POST …/dbs/:db/photos · ,
DocumentsGET/POST …/documents, PUT/DELETE …/documents/:doc, GET/POST …/documents/:doc/versions, POST …/versions/:n/restore ·
Turns and diagnosticsPOST …/try, GET …/turns, GET …/turns/:turnId, GET …/doctor, GET/POST …/box · ,
WhatsAppGET/PUT …/whatsapp, POST …/whatsapp/link, POST …/whatsapp/history, GET/POST/DELETE …/wa, GET/POST …/wa/groups, POST …/wa/import, GET …/channels/links (who answered last; orphans=1) · , ,
Boards and cardsPOST …/board/archive, GET …/board/conversations, GET …/board/conversations/:ref, POST …/board/conversations/:ref/pause, POST …/board/conversations/:ref/reply, GET …/board/pending, GET/POST/DELETE /api/v2/workspaces/:slug/boards, POST …/boards/move-cards ·
AccountGET/DELETE /api/v2/me, GET /api/v2/me/usage, GET /api/v2/me/credentials, PUT/DELETE …/credentials/:provider · ,
Audit log and factoryGET /api/v2/audit · GET /api/v2/workspaces/:slug/factory/runs, GET/POST …/factory/runs/:runId · GET /api/v2/teams/handles · ,
AgentsGET /api/v2/me/agents · POST /api/v2/me/agents (create, scope agents:write; dryRun, workspace, like…) · GET …/agents/:agentId/schedule, GET …/agents/:agentId/tasks ·
ConversationsGET/POST …/agents/:agentId/conversations, GET/PATCH/DELETE …/conversations/:sessionId (?archivos=1 also returns its files), GET /api/v2/me/conversations?agentes=a,b (several agents' lists in one response)
TurnsPOST …/:sessionId/messages (202), GET …/:sessionId/events (SSE), POST …/:sessionId/cancel
Permissions and modelPOST …/:sessionId/permission, POST …/:sessionId/model
ScheduledGET/POST …/:sessionId/schedule, DELETE …/:sessionId/schedule/:id
SharingGET/POST/DELETE …/:sessionId/share
FilesGET/POST /api/v2/me/files, GET/DELETE /api/v2/me/files/:id, POST /api/v2/me/stt
ConnectorsGET /api/v2/me/connectors, POST …/:id/start, POST …/:id/credentials, DELETE …/:id
MemoriesGET/POST /api/v2/me/memories, PATCH/DELETE /api/v2/me/memories/:id
Long threadPOST /api/v2/me/agents/:agentId/conversations/:sessionId/continue
DevicesPOST/DELETE /api/v2/me/devices
Partners (gpk_/gps_ credential)/api/v2/partner, …/partner/credentials[/:id[/rotate]], …/partner/audit, GET …/partner/usage, …/partner/agent, …/partner/tenants[/:externalId], POST …/partner/turns ·

A complete turn

typescript
const base = "https://www.ghosty.studio/api/v2/me";const h = { Authorization: `Bearer ${token}`, "Content-Type": "application/json" };
// 1. open a conversationconst { id: sessionId } = await (await fetch(`${base}/agents/${agentId}/conversations`, { method: "POST", headers: h })).json();
// 2. subscribe to events BEFORE sending (the stream replays what was already emitted, so the order isn't critical)const es = new EventSource(`${base}/agents/${agentId}/conversations/${sessionId}/events`); // add the bearer with a polyfill that accepts headerses.addEventListener("chunk", (e) => process.stdout.write(JSON.parse(e.data).text));es.addEventListener("done", () => es.close());
// 3. send the message: responds 202 on acceptance, not on completionawait fetch(`${base}/agents/${agentId}/conversations/${sessionId}/messages`, {  method: "POST", headers: h,  body: JSON.stringify({ content: "Summarize this PDF in 5 lines", images: [{ name: "contract.pdf", mimeType: "application/pdf", data: base64 }] }),});

Attach something already in the account

Download everything: GET /api/v2/me/files?all=1 lists ALL the account's files (documents, conversations and what arrived through your agents' channels), 500 per page with nextCursor; each one has a group (documents | conversations | library). Each file downloads with GET /api/v2/me/files/:id (signed link). ghosty me files export uses it. A database downloads with GET /api/v2/agents/:id/dbs/:db/export (?format=sqlite, the default, or ?format=csv&table=T); only with the person's session, not with gat_.

GET /api/v2/me/files?q=contract (with q, even empty) returns your files: what you uploaded and what's in your personal conversations, never customer or test attachments. Each one has an id, a 15-min url for the thumbnail, and the next page in nextCursor. To send it to the agent you don't upload again: it goes by id.

typescript
await fetch(`${base}/agents/${agentId}/conversations/${sessionId}/messages`, {  method: "POST", headers: h,  body: JSON.stringify({ content: "Put this photo in the report", images: [{ fileId: "cmx…" }] }),});

The agent sees it as archivo:<id> and, in a later turn, fetches it again with its file_get tool (a fresh 15-min link). An id that isn't yours returns 404.

The browser's EventSource doesn't send headers; in Node use eventsource or fetch and read the body. Details of each event in .