Coding agents
What to hand a coding agent so its first draft compiles, and how to scope the token it runs with.
Give it the docs
Every page in these docs has a raw Markdown twin. There is nothing to scrape and no docs MCP server to install:
/llms.txt— the index, generated from the same manifest this console renders. Base URL, version header, auth, the OpenAPI URL, then every page linked to its Markdown./docs/<slug>.md— any page as plain Markdown. Requesting/docs/<slug>withAccept: text/markdownreturns the same bytes./openapi.json— emitted from the live routes. Exact paths, request and response shapes, and every errorcodeenumerated on theErrorschema. When prose and spec disagree, the spec is right.
curl https://cloud.ingram.tech/llms.txt
curl https://cloud.ingram.tech/docs/runs.md
curl https://api.cloud.ingram.tech/openapi.json
Point the agent at /llms.txt first, then the two or three pages it names.
Paste this into your agent's instructions
Drop it in AGENTS.md, CLAUDE.md, .cursorrules, or whatever your harness
reads:
## Ingram Cloud
This project integrates Ingram Cloud (hosted AI agents over one REST API).
- Docs index: https://cloud.ingram.tech/llms.txt — any page is also raw
Markdown at https://cloud.ingram.tech/docs/<slug>.md. Read the relevant
pages before writing integration code.
- OpenAPI (source of truth): https://api.cloud.ingram.tech/openapi.json
- Base URL: https://api.cloud.ingram.tech — every endpoint under /v1.
- Every request sends `Authorization: Bearer $IC_TOKEN` and
`IC-Api-Version: 2026-05-01`.
- An **agent** (`agt_`) is the reusable design; a **smith** (`smt_`) is one
end-user's running clone. Never mix the two words.
- Chat goes over the OpenAI-compatible surface (`POST /v1/chat/completions`,
or the `openai` SDK with `baseURL` set to the /v1 base). Management calls go
through `@ingram-cloud/sdk`. Don't hand-roll fetch wrappers.
- $IC_TOKEN is a tenant-admin token: server-side only, never in client code,
never committed.
Give it the typed SDK
Install @ingram-cloud/sdk:
import { IngramCloud } from "@ingram-cloud/sdk/client";
const ic = new IngramCloud({ token: process.env.INGRAM_CLOUD_TOKEN! });
const smith = await ic.smiths.create({ external_id: "user-42" });
Method inputs are inferred from the same Zod schemas the API validates requests
with, so an invented field is a type error in the agent's editor rather than a
422 at runtime. Run tsc as the agent's inner loop.
The OpenAI-compatible surface needs no new client at all:
against an existing openai integration, only the baseURL changes. That is
what standards-first design buys here — the model's existing
knowledge of the wire is correct.
Give it a scratch project
A project is a tenant, and a tenant-admin token is bound to its project inside the JWT, so a token minted in a scratch project is cryptographically incapable of reading production. Deleting the project ends the experiment.
With an organization key:
# Authorization: organization key (server-side / IaC only)
curl https://api.cloud.ingram.tech/v1/organization/projects \
-H "Authorization: Bearer $IC_ORG_TOKEN" \
-H "IC-Api-Version: 2026-05-01" -H "Content-Type: application/json" \
-d '{ "name": "acme-agent-scratch" }'
# → 201 { "id": "proj_…", … }
# Authorization: organization key (server-side / IaC only)
curl https://api.cloud.ingram.tech/v1/organization/projects/proj_…/tokens \
-H "Authorization: Bearer $IC_ORG_TOKEN" \
-H "IC-Api-Version: 2026-05-01" -H "Content-Type: application/json" \
-d '{ "name": "coding agent scratch" }'
# → 201 { "token": "tha_live_…", "scopes": ["tenant:*"] }
Hand the agent that tha_live_…, not the org key: the org key mints tokens for
every project you own. DELETE /v1/organization/projects/{pid} deletes the
project.
Two more things to set:
- A cost budget with
action: "block"on the scratch project, so a retry loop stops at the budget rather than spending your balance. - Short
ttl_secondson the token.DELETE /v1/tenant/tokens/{id}revokes it immediately if it leaks.
Other credentials are already scoped: a
smith token the agent mints for browser code can
only touch that one smith, and 403 tenant_token_required blocks a smith token
from reading or changing configuration.
Let it read what happened
GET /v1/runs— every run, filterable bysmith_id,agent_id,status. A failed run carries why it failed.GET /v1/events— the append-only feed of run lifecycle, tool calls, approvals and budget thresholds. A tool that never ran and a tool that ran and threw produce different events.- The run's trace —
GET /v1/runs/{rid}/trace, the timed span tree: which model call, which tool, how long, what it cost. X-Request-Idon every response, and a stablecodeon every error.
A read-only token (*:read scopes only) covers all of it, so the debugging loop
needs no write access.
Ingram Cloud inside the coding agent
Deploy an agent as an mcp deployment and any
MCP client that speaks remote servers (Claude Code, Claude, ChatGPT) can call it
as a tool, with OAuth discovery handling credentials.
claude mcp add --transport http acme \
https://api.cloud.ingram.tech/v1/deployments/dep_…/mcp
Each caller talks to their own smith, so the isolation you built for end-users holds for your team.
Working the loop
- Pin
IC-Api-Version: 2026-05-01on every request. Requests without it get the latest version. - Let the agent execute a real curl against the scratch project rather than only writing code.
- On a disagreement about a field name, point it at
/openapi.json. - Watch for agent/smith confusion. Wrong-noun code compiles and looks correct; the instruction block above exists to prevent it.
Next: Quickstart for the three-curl path, or the TypeScript SDK for the typed one.