The Delegation API
The Delegation exposes two APIs: the AI Gateway (OpenAI-compatible, routes to Claude / OpenAI / Gemini) and the Platform API (REST, manages projects, tasks, conversations, and files). Both share the same base domain.
Gateway base URL
https://gateway.malcolmstone.io
Platform base URL
https://delegation.malcolmstone.io
Auth scheme
Bearer token
Spec format
OpenAPI 3.0
base_url / baseURL — no other code changes needed.Authentication
Both APIs use Bearer tokens in the Authorization header, but they come from different sources:
| API | Token source | Prefix |
|---|---|---|
| AI Gateway | Developer dashboard → API Keys | gw- |
| Platform API | Session access_token (POST /api/auth, or the signed-in browser session) | eyJ… |
curl https://gateway.malcolmstone.io/v1/chat/completions \
-H "Authorization: Bearer gw-your-key" \
-H "Content-Type: application/json" \
-d '{"model":"us.anthropic.claude-sonnet-4-6","messages":[{"role":"user","content":"Hello"}]}'gw-. Never expose them client-side or commit them to source control. Revoke compromised keys immediately from the developer dashboard.SDKs & libraries
Because the Gateway is OpenAI-compatible, any OpenAI SDK works out of the box — just override the base URL and API key.
OpenAI SDK (Python & TypeScript)
The most common integration path. Works with streaming, tool calls, and all modalities.
# The gateway is drop-in compatible with the OpenAI API. # Just point base_url at the gateway. curl https://gateway.malcolmstone.io/v1/chat/completions \\n -H "Authorization: Bearer gw-your-key" ...
Vercel AI SDK
Use the @ai-sdk/openai provider pointed at the gateway. Supports streaming via streamText, structured output via generateObject, and React hooks.
# Use the openai provider pointed at the gateway # (install: npm i ai @ai-sdk/openai)
Other SDKs
Any library that accepts a base_url / baseURL override works: LangChain, LlamaIndex, Instructor, Marvin, Guidance, etc. The gateway passes through the OpenAI request schema unchanged.
Quickstart
Three steps to your first API call:
- Sign up for a developer account at delegation.malcolmstone.io/auth
- Go to Dashboard → API Keys and issue a key
- Send your first request:
curl https://gateway.malcolmstone.io/v1/chat/completions \
-H "Authorization: Bearer gw-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "us.anthropic.claude-sonnet-4-6",
"messages": [
{ "role": "system", "content": "You are a concise assistant." },
{ "role": "user", "content": "Explain the delegation pattern" }
],
"max_tokens": 256
}'{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "us.anthropic.claude-sonnet-4-6",
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "The delegation pattern ..." },
"finish_reason": "stop"
}],
"usage": { "prompt_tokens": 28, "completion_tokens": 142, "total_tokens": 170 }
}Chat completions
The primary endpoint. Accepts a conversation history and returns the next assistant message.
Context headers
Optional headers tag usage records so you can filter by session, project, or task in your dashboard.
| Header | Purpose |
|---|---|
| X-Session-ID | Groups multiple requests into one session |
| X-Conversation-ID | Groups requests into a conversation |
| X-Task-ID | Tags a request to a specific task |
| X-Project-ID | Tags a request to a project |
Function calling
Pass a tools array to let the model call functions you define. When the model decides to call a function, the response includes a tool_calls array — your code executes the function and sends the result back as a tool message.
curl https://gateway.malcolmstone.io/v1/chat/completions \
-H "Authorization: Bearer gw-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "us.anthropic.claude-sonnet-4-6",
"messages": [{"role":"user","content":"What is the weather in Paris?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type":"string","description":"City name"}
},
"required": ["city"]
}
}
}],
"tool_choice": "auto"
}'Multi-turn tool loop
Continue the conversation by appending the assistant's tool_calls message and your tool result, then sending the full history again:
// 1. Model response with tool call
{ "choices": [{ "message": {
"role": "assistant",
"tool_calls": [{ "id": "call_abc", "type": "function",
"function": { "name": "get_weather", "arguments": "{"city":"Paris"}" }}]
}}]}
// 2. Your follow-up request — append both messages
{ "messages": [
{ "role": "user", "content": "What is the weather in Paris?" },
{ "role": "assistant", "tool_calls": [{ "id": "call_abc", ... }] },
{ "role": "tool", "tool_call_id": "call_abc", "content": "18°C, partly cloudy" }
]}Vision & multimodal
Send images alongside text by using an array for the content field. Supported models: us.amazon.nova-pro-v1:0, us.anthropic.claude-sonnet-4-6, us.amazon.nova-lite-v1:0, and others.
curl https://gateway.malcolmstone.io/v1/chat/completions \
-H "Authorization: Bearer gw-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "us.amazon.nova-pro-v1:0",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "What is in this image?" },
{ "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }
]
}]
}'| Field | Type | Description |
|---|---|---|
typereq | string | text | image_url | image (base64). |
text | string | Text content (when type=text). |
image_url.url | string | Publicly accessible image URL. JPEG, PNG, GIF, WebP. |
image_url.detail | string | low | high | auto. Controls resolution and token cost. |
"url": "data:image/jpeg;base64,<b64>"Streaming
Add stream: true to receive tokens via Server-Sent Events as they are generated. Each line is data: {chunk}. The stream ends with data: [DONE].
curl https://gateway.malcolmstone.io/v1/chat/completions \
-H "Authorization: Bearer gw-your-key" \
-H "Content-Type: application/json" \
-d '{"model":"us.anthropic.claude-sonnet-4-6","stream":true,"messages":[{"role":"user","content":"Write a haiku"}]}'Chunk schema
// Each SSE chunk
data: {
"id": "chatcmpl-abc",
"object": "chat.completion.chunk",
"choices": [{
"index": 0,
"delta": { "role": "assistant", "content": "The " },
"finish_reason": null
}]
}
// Final chunk
data: { ..., "choices": [{ "delta": {}, "finish_reason": "stop" }] }
data: [DONE]Embeddings
Convert text into dense vector representations for semantic search, clustering, and retrieval-augmented generation.
curl https://gateway.malcolmstone.io/v1/embeddings \
-H "Authorization: Bearer gw-your-key" \
-H "Content-Type: application/json" \
-d '{"model":"amazon.titan-embed-text-v2:0","input":"The delegation pattern in AI"}'{
"object": "list",
"data": [{
"object": "embedding",
"index": 0,
"embedding": [0.0023064255, -0.009327292, ...]
}],
"model": "amazon.titan-embed-text-v2:0",
"usage": { "prompt_tokens": 8, "total_tokens": 8 }
}Image generation
curl https://gateway.malcolmstone.io/v1/images/generations \
-H "Authorization: Bearer gw-your-key" \
-H "Content-Type: application/json" \
-d '{"model":"stability.stable-image-core-v1:1","prompt":"A futuristic delegation of AI agents","size":"1024x1024"}'Audio
Text-to-speech and speech-to-text via Whisper.
Models
Use GET /v1/models to fetch the live list. Prices shown per 1 million tokens.
Text models
| Model ID | Input / 1M tok | Output / 1M tok |
|---|---|---|
| Claude Haiku 4.5 | $0.80 | $4.000 |
| Claude Sonnet 4.6 | $3.00 | $15.000 |
| Claude Opus 4.7 | $15.00 | $75.000 |
| Gemini 2.5 Flash | $0.50 | $3.000 |
| Gemini 2.5 Pro | $1.25 | $10.000 |
| Gemini 3.1 Flash Lite | $0.25 | $1.500 |
| Gemini 3.1 Pro | $2.00 | $12.000 |
Image models
| Model ID | Input / 1M tok | Output / 1M tok |
|---|---|---|
| Gemini 2.5 Flash Image | — | $0.039 |
| Gemini 3.1 Flash Image | — | $0.067 |
| Gemini 3 Pro Image | — | $0.134 |
Music models
| Model ID | Input / 1M tok | Output / 1M tok |
|---|---|---|
| Lyria 3 | — | $0.040 |
| Lyria 3 Pro | — | $0.080 |
Video models
| Model ID | Input / 1M tok | Output / 1M tok |
|---|---|---|
| Veo 3.1 Lite | — | $0.050 |
| Veo 3.1 Fast | — | $0.150 |
| Veo 3.1 | — | $0.400 |
Platform API
The Platform API manages your workspace: projects, tasks, conversations, files, and billing. All endpoints are authenticated with a session token sent as Authorization: Bearer <access_token>. Scripts and CLIs get one from POST /api/auth with { email, password } (refresh with PUT /api/auth, revoke with DELETE /api/auth); in the browser the signed-in session cookie is sent automatically.
403 Forbidden or 404 Not Found.# 1. Exchange your credentials for a session token
TOKEN=$(curl -s -X POST https://delegation.malcolmstone.io/api/auth \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"…"}' | jq -r .access_token)
# 2. Send it as a Bearer token
curl https://delegation.malcolmstone.io/api/projects \
-H "Authorization: Bearer $TOKEN"Projects
Projects are the top-level container for teams, tasks, conversations, and results.
Tasks
Tasks are units of work assigned to agents within a project.
Conversations
Each project has one conversation thread — a history of messages between the user and agents.
File storage
Upload, manage, and share files. Files can be public (CDN-hosted, permanent URL) or private (signed URL, time-limited access).
API keys
Issue and revoke gateway API keys programmatically or from the developer dashboard.
OpenAPI spec
The full OpenAPI 3.0 specification for both the Gateway API and Platform API is available as machine-readable JSON. Import it into Postman, Insomnia, Swagger UI, or any OpenAPI-compatible tool.
openapi.json
https://delegation.malcolmstone.io/api/openapi.json
Import into Postman
- Open Postman → Import
- Select "Link" and paste:
https://delegation.malcolmstone.io/api/openapi.json - Set the
Authorizationvariable to your gateway key or session token
Import into Insomnia
- Application menu → Import / Export → Import Data
- Choose "From URL" and paste the spec URL
Pricing
Developer accounts are fully à la carte — charged only for actual usage, no monthly minimums.
| Item | Price |
|---|---|
| Storage (public) | $0.05/GB |
| Storage (private) | $0.1/GB |
| Extra projects — 1 project | $0.2/ea |
| Extra projects — 10 projects | $0.1/ea |
| Extra projects — 100 projects | $0.04/ea |
| Extra agents — 10 agents | $0.1/ea |
Model costs per token are listed in the Models table above. All prices in USD.
Errors & rate limits
Both APIs use standard HTTP status codes and return errors as { "error": "message" } JSON.
| Status | Meaning | Action |
|---|---|---|
| 200 | Success | — |
| 204 | No content | — |
| 400 | Bad request | Check required fields and JSON structure |
| 401 | Unauthorized | Check your Bearer token — it may be missing or expired |
| 402 | Payment required | Top up your balance in the developer dashboard |
| 403 | Forbidden | You don't own this resource |
| 404 | Not found | The resource doesn't exist or isn't yours |
| 429 | Rate limit exceeded | Respect the Retry-After header and use exponential backoff |
| 500 | Internal server error | Transient — retry with backoff |
| 502 | Upstream error | The AI provider returned an unexpected response |
| 503 | Service unavailable | Try a different model or provider |
Rate limits
Each gateway key defaults to 60 requests / minute. Set a custom rate_limit when issuing a key (up to your plan maximum). Requests exceeding the limit return 429 with a Retry-After: N header.
min(2^attempt, 60) seconds between retries. Most transient errors resolve within 3 attempts.Idempotency
POST requests to the Platform API do not support idempotency keys. For safe retries, check whether the resource already exists via a GET before issuing a POST.
Changelog
2026-05-27
Current- Platform API: projects, tasks, conversations, results, teams, files
- GET /api/account — resolve and auto-provision the DB user record
- PATCH /api/account — self-service role switching (user ↔ developer)
- DELETE /api/account — self-service account soft-deletion
- Full OpenAPI 3.0 spec at /api/openapi.json
2026-05-23
- Stripe billing integration — subscriptions, invoices, top-ups
- Gateway usage tracking — per-request token and cost records
- Developer dashboard — API keys, usage charts, playground, quickstart
2026-05-18
- user_role enum — user | developer | admin
- File storage — public and private file uploads with CDN URLs
- Auth provider column — OAuth users provisioned on first login
2026-05-16
- Initial schema — projects, teams, tasks, conversations, results
- AI Gateway proxy — OpenAI-compatible routing to Claude, OpenAI, Gemini
Ready to build?
Sign up for a developer account and get your first API key in seconds.
Get started — it's free