API at a glance
Conventions and the endpoint map. The machine-readable OpenAPI spec is the field-by-field reference; these docs teach the flows.
Conventions
- Base URL
https://api.cloud.ingram.tech: everything under/v1. - Headers:
Authorization: Bearer <token>andIC-Api-Version: 2026-05-01on every request (Auth & tokens). The version header pins the request/response vocabulary;2026-05-01is the only live version today. - Errors: the OpenAI-standard envelope, always — so the
openaiSDK and any OpenAI-compatible client parse our failures unchanged:
{ "error": { "message": "…", "type": "invalid_request_error",
"param": null, "code": "model_key_missing" } }
Match on code (our stable slug); type is the OpenAI category
(invalid_request_error, authentication_error, permission_error,
rate_limit_error, api_error). The request id is the X-Request-Id
response header — log it; show message to humans.
- Idempotency: send an
Idempotency-Keyheader on creates; replays return the original response instead of duplicating. This covers streaming run creation too: a retried key returns arun.duplicatepointer rather than starting a second run. Resources with a natural key also upsert on it: re-POST /v1/smithswith an existing liveexternal_idreturns that smith (200) rather than erroring. - Pagination: list endpoints take
limit+cursorand return{ data, next_cursor, has_more }, newest first. Thecursoris opaque — pass the previous page'snext_cursorstraight back; never parse it. Pull the next page whilehas_moreis true. The run and event feeds add their own filters (since,status,external_id_prefix, …) on top of the same cursor. - Filtering:
GET /v1/smithsfilters by exactexternal_id,customer_id, oragent_id, and segments byexternal_id_prefix(matches one namespace, e.g.anon:).GET /v1/runstakes the sameexternal_id_prefixto pull one segment's conversation history (plussmith_idandstatus). - Ids: prefixed and sortable:
smt_(smith),agt_(agent),run_,thr_,apr_,evt_,cus_,trc_. A run and its trace share a suffix (run_X↔trc_X). Thread ids are yours if you pass them, minted withthr_if you don't. - Limits: no published rate limits yet (fair use); synchronous runs hold the connection for the whole turn, so prefer streaming for long ones.
Endpoint map
| Resource | Endpoints |
|---|---|
| Smiths | POST/GET /v1/smiths · GET/PATCH/DELETE /v1/smiths/{sid} |
| Config revisions | GET /v1/smiths/{sid}/revisions · POST …/revisions/{n}/restore |
| Agents | POST/GET /v1/agents · GET/PATCH/DELETE /v1/agents/{aid} · POST/GET …/versions · POST …/rollout · POST …/attach · POST /v1/agents/import |
| Runs | POST/GET /v1/smiths/{sid}/runs · GET …/runs/{rid} · GET …/runs/{rid}/events (SSE) · POST …/runs/{rid}/submit · POST …/runs/{rid}/replay · GET /v1/runs |
| OpenAI-compatible | POST /v1/chat/completions · POST /v1/responses (stream + non-stream; smith token = the smith, the user field = its external_id, or IC-Smith-Id header). Honors the standard request fields: model (inference LLM override), system/instructions (appended per turn), tools (client-side function-call loop) with tool_choice (auto/none/required/a named function), and multimodal image and file parts — see openai-compat. |
| Files | GET /v1/files/{fid} · GET …/files/{fid}/content (metadata + bytes for a file inlined into a conversation; scope files:read) |
| Memory | GET /v1/smiths/{sid}/blocks · PATCH …/blocks/{label} · GET/POST …/memories · POST …/memories/search · PATCH/DELETE …/memories/{mid} |
| Tools (MCP) | GET /v1/tenant/mcp · GET/PUT/DELETE /v1/tenant/mcp/{name} · POST …/mcp/{name}/refresh · GET /v1/tenant/hosted_tools |
| Catalog | GET /v1/catalog · GET /v1/catalog/{slug} (curated MCP integration presets) |
| Approvals | GET /v1/approvals[?status=] · GET /v1/approvals/{id} |
| Connections | GET/POST /v1/smiths/{sid}/connections · PATCH/DELETE …/{cid} · POST …/{cid}/refresh · POST …/connections/authorize (start OAuth) · GET /v1/oauth/callback/{provider} (browser redirect) |
| Deployments | GET/POST /v1/deployments · GET/PATCH/DELETE /v1/deployments/{depid} (target: a smith or an agent catch-all) · GET/PUT/DELETE /v1/tenant/telegram · GET/PUT/DELETE /v1/tenant/slack · GET /v1/slack/oauth/{tenant} (browser redirect) · GET/PUT/DELETE /v1/tenant/whatsapp · GET /v1/whatsapp/webhook/{tenant} (Meta verify + inbound) · GET/PUT/DELETE /v1/tenant/email · GET/POST/DELETE /v1/tenant/email/suppressions · GET/PUT/DELETE /v1/tenant/linkedin (Pages messaging — pending partner approval) |
| Schedules | GET/POST /v1/smiths/{sid}/schedules · PATCH/DELETE …/{schid} · POST …/{schid}/run_now |
| Events & webhooks | GET /v1/events · GET/POST /v1/tenant/webhooks · PATCH/DELETE …/{wid} · POST …/{wid}/test |
| Usage & cost | GET /v1/tenant/usage · GET /v1/usage?group_by= · POST/GET /v1/usage/events |
| Budgets | POST/GET /v1/budgets · GET/PATCH/DELETE /v1/budgets/{bid} · GET …/{bid}/status |
| Customers | POST/GET /v1/customers · GET/PATCH/DELETE /v1/customers/{cid} |
| Tokens | POST/GET /v1/tenant/tokens · DELETE …/tokens/{tid} |
| Projects (org key) | POST/GET /v1/organization/projects · GET/DELETE …/projects/{pid} · POST …/projects/{pid}/tokens (mint a project tenant:* token) |
| Credits (org key) | GET /v1/organization/billing/balance · GET …/billing/ledger · GET …/billing/usage (per-project draw this month) · POST …/billing/setup (add a card, unlock €10 free) · POST …/billing/checkout (Stripe top-up; optional mode "live"/"test", test is staff-only) · GET/PUT …/billing/autoreload · POST …/billing/reload (charge saved card) · GET …/billing/portal (Stripe billing portal) |
| Model keys | GET /v1/tenant/model_keys · PUT/DELETE …/model_keys/{provider} · GET /v1/tenant/models |
| Providers (OAuth) | GET /v1/tenant/providers · PUT/DELETE …/providers/{provider} |
| Traces | GET /v1/traces[?smith_id=] · GET /v1/traces/{tid} · POST /v1/traces:ingest |
Early-access surfaces
One resource appears in scopes and usage breakdowns but is early access and
not yet documented here: trace ingestion (POST /v1/traces:ingest: push
your own spans from an external runtime, optionally tagged with an app_id
that group_by=app then attributes usage by). Ask us before building on it.
Using the OpenAPI spec
GET https://cloud.ingram.tech/docs/openapi.json: feed it to your codegen
or API client of choice. The spec is generated from the live API, so it's
always in sync with the deployment.