Ingram Cloud

Documentation

API at a glance

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> and IC-Api-Version: 2026-05-01 on every request (Auth & tokens). The version header pins the request/response vocabulary; 2026-05-01 is the only live version today.
  • Errors: the OpenAI-standard envelope, always — so the openai SDK 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-Key header on creates; replays return the original response instead of duplicating. This covers streaming run creation too: a retried key returns a run.duplicate pointer rather than starting a second run. Resources with a natural key also upsert on it: re-POST /v1/smiths with an existing live external_id returns that smith (200) rather than erroring.
  • Pagination: list endpoints take limit + cursor and return { data, next_cursor, has_more }, newest first. The cursor is opaque — pass the previous page's next_cursor straight back; never parse it. Pull the next page while has_more is true. The run and event feeds add their own filters (since, status, external_id_prefix, …) on top of the same cursor.
  • Filtering: GET /v1/smiths filters by exact external_id, customer_id, or agent_id, and segments by external_id_prefix (matches one namespace, e.g. anon:). GET /v1/runs takes the same external_id_prefix to pull one segment's conversation history (plus smith_id and status).
  • Ids: prefixed and sortable: smt_ (smith), agt_ (agent), run_, thr_, apr_, evt_, cus_, trc_. A run and its trace share a suffix (run_Xtrc_X). Thread ids are yours if you pass them, minted with thr_ 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

ResourceEndpoints
SmithsPOST/GET /v1/smiths · GET/PATCH/DELETE /v1/smiths/{sid}
Config revisionsGET /v1/smiths/{sid}/revisions · POST …/revisions/{n}/restore
AgentsPOST/GET /v1/agents · GET/PATCH/DELETE /v1/agents/{aid} · POST/GET …/versions · POST …/rollout · POST …/attach · POST /v1/agents/import
RunsPOST/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-compatiblePOST /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.
FilesGET /v1/files/{fid} · GET …/files/{fid}/content (metadata + bytes for a file inlined into a conversation; scope files:read)
MemoryGET /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
CatalogGET /v1/catalog · GET /v1/catalog/{slug} (curated MCP integration presets)
ApprovalsGET /v1/approvals[?status=] · GET /v1/approvals/{id}
ConnectionsGET/POST /v1/smiths/{sid}/connections · PATCH/DELETE …/{cid} · POST …/{cid}/refresh · POST …/connections/authorize (start OAuth) · GET /v1/oauth/callback/{provider} (browser redirect)
DeploymentsGET/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)
SchedulesGET/POST /v1/smiths/{sid}/schedules · PATCH/DELETE …/{schid} · POST …/{schid}/run_now
Events & webhooksGET /v1/events · GET/POST /v1/tenant/webhooks · PATCH/DELETE …/{wid} · POST …/{wid}/test
Usage & costGET /v1/tenant/usage · GET /v1/usage?group_by= · POST/GET /v1/usage/events
BudgetsPOST/GET /v1/budgets · GET/PATCH/DELETE /v1/budgets/{bid} · GET …/{bid}/status
CustomersPOST/GET /v1/customers · GET/PATCH/DELETE /v1/customers/{cid}
TokensPOST/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 keysGET /v1/tenant/model_keys · PUT/DELETE …/model_keys/{provider} · GET /v1/tenant/models
Providers (OAuth)GET /v1/tenant/providers · PUT/DELETE …/providers/{provider}
TracesGET /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.