Skip to content

AI Agent Integration

AI Agent Integration Guide

This guide shows how an AI coding agent (Claude, GPT, Devin, etc.) can use the GhostMind platform API to build applications on top of ChatGPT and Savio TTS.

Quick Start for Agents

1. Discover Capabilities

Always start by reading the capability manifest:

Terminal window
curl https://ghostmind.optdmsa.com/v1/capabilities \
-H "Authorization: Bearer $GHOSTMIND_API_KEY"

This tells you what features are available, which providers are connected, and what endpoints exist.

Critical rules for capability checking:

  • Call /v1/capabilities first — before any other endpoint.
  • Do NOT assume enabled: true for any feature. Check the actual value.
  • Distinguish supported (platform-level) from enabled (effective for your workspace). A feature can be supported: true but enabled: false if no account is connected or the upstream account lacks authorization.
  • When enabled: false, check the reason field for a machine-readable explanation (e.g. no_connected_account, upstream_not_authorized).
  • Query /v1/models to discover available model IDs.
  • Do NOT invent endpoints. Only use endpoints listed in the capabilities manifest or the OpenAPI spec.

2. Check Connected Accounts

Terminal window
curl https://ghostmind.optdmsa.com/v1/connections \
-H "Authorization: Bearer $GHOSTMIND_API_KEY"

Verify that a chatgpt account with status: "active" exists before attempting chat completions.

3. Read the OpenAPI Spec

The public OpenAPI spec contains all /v1/* data plane routes with exact schemas (40 paths, 0 admin routes):

https://ghostmind.optdmsa.com/openapi-public.json

Use this to discover exact request/response schemas for all public endpoints.

Note: Routing headers (X-GhostMind-Conversation-Id, X-GhostMind-Project, etc.) are runtime hints and are NOT in the OpenAPI spec parameters. See the Routing Headers section below.

Common Workflows

Workflow 1: Simple Chat Completion

Terminal window
curl -X POST https://ghostmind.optdmsa.com/v1/chat/completions \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"messages": [{"role": "user", "content": "Hello!"}]
}'

The response is OpenAI-compatible. The X-GhostMind-Conversation-Id response header contains the conversation ID for continuations.

Workflow 2: Multi-turn Conversation

Terminal window
# First message — creates a conversation
RESPONSE=$(curl -s -D - -X POST https://ghostmind.optdmsa.com/v1/chat/completions \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"auto","messages":[{"role":"user","content":"What is 2+2?"}]}')
# Extract conversation ID from response header
CONV_ID=$(echo "$RESPONSE" | grep -i "x-ghostmind-conversation-id" | awk '{print $2}' | tr -d '\r')
# Continue the conversation
curl -X POST https://ghostmind.optdmsa.com/v1/chat/completions \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-H "X-GhostMind-Conversation-Id: $CONV_ID" \
-d '{"model":"auto","messages":[{"role":"user","content":"Now multiply that by 3."}]}'

Workflow 3: Project with Files

Terminal window
# 1. Create a project (returns an UPSTREAM project — note the slug AND id)
PROJECT=$(curl -s -X POST https://ghostmind.optdmsa.com/v1/projects \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Data Analysis","instructions":"You are a data analyst."}')
PROJECT_ID=$(echo $PROJECT | jq -r .id)
PROJECT_SLUG=$(echo $PROJECT | jq -r .slug) # e.g. "data-analysis"
# 2. Upload a file to the project
curl -X POST "https://ghostmind.optdmsa.com/v1/projects/$PROJECT_ID/files" \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-F "file=@data.csv"
# 3a. Chat in the project context — use the UPSTREAM project header + SLUG
curl -X POST https://ghostmind.optdmsa.com/v1/chat/completions \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-H "X-GhostMind-Upstream-Project: $PROJECT_SLUG" \
-d '{"model":"auto","messages":[{"role":"user","content":"Summarize the uploaded file."}]}'

Alternative — pin a conversation to the project (recommended for long-lived engines):

Terminal window
# Create a conversation bound to the project by UUID
CONV=$(curl -s -X POST https://ghostmind.optdmsa.com/v1/conversations \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"title\":\"Engine\",\"upstream_project_id\":\"$PROJECT_ID\"}")
CONV_ID=$(echo $CONV | jq -r .id)
# Every message continues on the same account+project — sticky binding
curl -X POST https://ghostmind.optdmsa.com/v1/chat/completions \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-H "X-GhostMind-Conversation-Id: $CONV_ID" \
-d '{"model":"auto","messages":[{"role":"user","content":"Summarize the uploaded file."}]}'

Common mistake: X-GhostMind-Project takes an internal GhostMind project slug — NOT the id/slug of a project created via POST /v1/projects. Passing an upstream slug there returns 422 wrong_project_header.

Workflow 4: Streaming Response

Terminal window
curl -N -X POST https://ghostmind.optdmsa.com/v1/chat/completions \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"stream": true,
"messages": [{"role": "user", "content": "Write a poem."}]
}'

The response is Server-Sent Events (SSE) — same format as OpenAI’s streaming API.

Workflow 5: Audio Transcription

Terminal window
curl -X POST https://ghostmind.optdmsa.com/v1/audio/transcriptions \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-F "file=@recording.mp3" \
-F "model=ghostmind-transcribe"

Workflow 6: Text-to-Speech (Async)

Terminal window
# 1. Discover available voices
curl https://ghostmind.optdmsa.com/v1/audio/providers/google_ai_studio_savio_tts/voices \
-H "Authorization: Bearer $GHOSTMIND_API_KEY"
# 2. Create a TTS job
JOB=$(curl -s -X POST https://ghostmind.optdmsa.com/v1/audio/generations \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"ghostmind-tts","input":"Hello world","voice":"yousef","response_format":"wav"}')
JOB_ID=$(echo $JOB | jq -r .id)
# 3. Poll for completion
curl "https://ghostmind.optdmsa.com/v1/audio/generations/$JOB_ID" \
-H "Authorization: Bearer $GHOSTMIND_API_KEY"
# 4. Download when ready
curl "https://ghostmind.optdmsa.com/v1/audio/generations/$JOB_ID/content" \
-H "Authorization: Bearer $GHOSTMIND_API_KEY" \
-o audio.wav

Error Handling

All errors use a canonical envelope:

{
"error": {
"code": "NO_HEALTHY_SESSION",
"message": "No healthy upstream session available.",
"type": "account_error",
"request_id": "req_abc123",
"retryable": true
}
}

Retry strategy: Retry errors where retryable: true with exponential backoff (1s, 2s, 4s, 8s, max 60s).

Request ID: Always include the request_id from the error in bug reports.

Streaming Errors

During streaming, provider/session errors are emitted as structured response.failed lifecycle events — not as assistant content text.

Critical rules:

  • Never interpret error text as assistant content
  • Stop reading the stream when you receive lifecycle_event.type == "response.failed"
  • Check error.retryable — retry if true, surface to user if false
  • The stream terminates with data: [DONE] after the error event

Streaming error codes:

  • ACCOUNT_REAUTH_REQUIRED (403, not retryable) — session expired
  • PROVIDER_RATE_LIMITED (429, retryable) — upstream rate-limited
  • PROVIDER_UNAVAILABLE (502/503, retryable) — upstream error
  • PROVIDER_TIMEOUT (504, retryable) — upstream timeout
  • INVALID_REQUEST (400, not retryable) — bad request parameters

See Streaming for the full SSE contract.

Key Headers

HeaderDirectionDescription
AuthorizationRequestBearer gmk_live_... API key
X-Request-IdBothCorrelation ID (echoed back if sent)
X-GhostMind-Conversation-IdBothConversation ID for continuations
X-GhostMind-Upstream-ProjectRequestUpstream project slug (from POST /v1/projects) for project-scoped chat
X-GhostMind-ProjectRequestInternal GhostMind project slug (admin-managed — not a /v1/projects entity)
X-GhostMind-Upstream-AccountRequestSpecific account label to use
X-GhostMind-Route-ProfileRequestRouting profile slug

OpenAI SDK Compatibility

The /v1/chat/completions endpoint is OpenAI-compatible for core chat functionality. You can use the OpenAI SDK directly:

from openai import OpenAI
client = OpenAI(
api_key="gmk_live_...",
base_url="https://ghostmind.optdmsa.com/v1",
)
response = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "Hello!"}],
)

Accepted but ignored parameters (for SDK compatibility — ChatGPT does not expose these controls):

  • temperature — accepted, no effect
  • top_p — accepted, no effect
  • max_tokens — accepted, no effect

Rejected parameters (return 400 UNSUPPORTED_PARAMETER):

  • tools — ChatGPT web backend does not expose tool/function calling
  • tool_choice — not supported
  • n > 1 — only one completion per request
  • logprobs — not supported

Do NOT assume full OpenAI API parity. GhostMind is a ChatGPT web gateway, not a direct OpenAI API proxy.

Next Steps