Sign in

The OpenIntegrations API

One endpoint runs any action in the registry. If nobody has implemented it yet, an agent writes, tests and publishes the implementation on the fly — the first call takes a minute, the next ones hundreds of milliseconds.

Run an action

curl -X POST https://open-integrations.dev/api/run/github/get-repository \
  -H "X-Anthropic-Api-Key: $ANTHROPIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input": {"owner": "vercel", "repo": "next.js"}}'
  • Auth — an Anthropic (sk-ant-…) API key, or an interagentic identity (see below). The key is never stored, and it is not checked when you run an existing snippet: its hash simply identifies you.
  • Where the key goes — X-Anthropic-Api-Key: <key> (preferred). Authorization: Bearer <key> and X-LLM-Key: <key> keep working; when several are sent, the first of X-Anthropic-Api-Key, Authorization, X-LLM-Key wins.
  • Missing snippets are written with your key — when an action has no snippet yet, Claude writes it with your own Anthropic key, so Anthropic bills that one-time implementation to you. After that the snippet is free for everyone.
  • Body — { "input": { … } } matching the action's inputSchema. Sending the input object directly also works.
  • Credentials — provider credentials are managed by keychains.dev, so the code running on OpenIntegrations never gets access to sensitive keys. The first time auth to a provider is needed, the /api/run/:provider/:action call returns 403 CREDENTIALS_REQUIRED with an approval link. Use the link to complete the OAuth flow with the provider or enter your API keys, and the next call to /api/run/:provider/:action will work with no changes. Credentials are bound to the hash of your Anthropic API key, so all calls made with the same Anthropic key have access to the same provider accounts.
  • Version pinning — { "input": …, "versionId": "v_…" } runs an exact version.

Authenticate as an interagentic agent

Agents with an interagentic identity call the API as themselves, in Authorization:

  • an agent token: a JWT the agent signs with its own key, iss = interagentic://id.interagentic.dev/<namespace>, aud = this server's hostname (open-integrations.dev), five minutes at most, a fresh jti per request;
  • a human access token (typ: at+jwt) from the interagentic broker;
  • an iak_ API key.
# $AGENT_TOKEN: an agent token with aud=open-integrations.dev
curl -X POST https://open-integrations.dev/api/run/github/get-repository \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"input": {"owner": "vercel", "repo": "next.js"}}'
  • No Anthropic key needed to run an action that already works. To have a missing snippet written, add X-Anthropic-Api-Key (or X-LLM-Key): with an interagentic Authorization, the key is only read from those headers.
  • Provider credentials: bring your own keychains.dev token. Send X-Keychains-Auth: Bearer <agent token with aud=keychains.dev>; it is forwarded to keychains.dev for the run. Without it, an action that needs credentials answers 403 CREDENTIALS_REQUIRED with details.header = "X-Keychains-Auth". keychains.dev itself answers with an approval link when the provider is not connected yet.
  • One token per request. On requests that change state, a token's jti is remembered: using the same agent token twice is 401 INTERAGENTIC_TOKEN_REPLAYED.
  • Your runs, issues and pull requests are recorded as ia:<namespace> (ia:org_<id> when you act for an org, ia:user_<id> for a human).

Responses

{ "ok": true, "data": { … }, "meta": { "versionId": "v_…", "buildId": "build_…", "runId": "run_…", "latencyMs": 212, "runtime": "isolate" } }
{ "ok": false, "error": { "code": "ACTION_INPUT_INVALID", "message": "…", "details": [ … ] } }
CodeMeaning
LLM_KEY_REQUIRED401 — send a key
LLM_KEY_INVALID401 — the key is malformed, or Anthropic rejected it while writing a snippet
INTERAGENTIC_TOKEN_INVALID401 — the interagentic credential did not verify (the message says why: audience, expiry, signature, …)
INTERAGENTIC_TOKEN_REPLAYED401 — this agent token was already used; mint a fresh one per request
INTERAGENTIC_UNAVAILABLE503 — the interagentic broker could not be reached to verify the credential; retry
ACTION_INPUT_INVALID422 — input does not match the schema
ACTION_ERROR422 — the action threw; details.code names one of its possibleErrors
CREDENTIALS_REQUIRED403 — connect the provider at details.authorizationUrl; interagentic callers send X-Keychains-Auth (details.header)
GENERATING409 — someone else triggered the implementation; retry in a few seconds
GENERATE_FAILED502 — the agent could not implement it; open an issue or a pull request
RATE_LIMITED429 — 60 runs/min, 5 generations/day, 30 describes/min per caller

Describe what you want

Don't know the provider or the action? Describe it, and the call continues exactly as if you had called that action:

curl -L -X POST https://open-integrations.dev/api/describe \
  -H "X-Anthropic-Api-Key: $ANTHROPIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"description": "get the vercel/next.js repository on GitHub"}'
  • How — Claude reads the description on your own Anthropic key (it is required here, even for interagentic callers), searches the registry and picks one action that exists in it. The description is treated as data: it can only select a provider and action from the registry, never anything else.
  • Match — 307 Temporary Redirect to /api/run/<provider>/<action>, with X-Resolved-Provider and X-Resolved-Action headers. Follow it (curl -L; fetch does by default) and the same POST, with the same headers, runs that action, or has it written first, exactly like a direct call. Parameters the description states are filled in for you; an explicit input in the body wins: {"description": "…", "input": {"repo": "ai"}}.
  • Resolve only — POST /api/describe?resolveOnly=1 answers 200 { "ok": true, "data": { "provider", "action", "input", "reason" } } and runs nothing.
  • Limits — descriptions up to 2,000 characters; 30 describe calls per minute per caller.
CodeMeaning
NO_MATCHING_ACTION400 — nothing in the registry does that (or it is not an API action at all)
ACTION_NOT_POSSIBLE422 — the provider exists but cannot do that; details.provider names it
DESCRIBE_FAILED502 — the model call failed or was declined; rephrase and retry
DESCRIBE_RESOLUTION_EXPIRED410 — the redirect was followed more than an hour after the describe; describe again
LLM_KEY_REQUIRED / LLM_KEY_INVALID401 — send your Anthropic key / Anthropic rejected it

Read the registry

GET /api/providers?q=slack&category=crm&page=1
GET /api/providers/:slug
GET /api/providers/:slug/actions?stage=developed
GET /api/run/:provider/:action           # describe: name, stage, inputSchema

Contribute

Issues, comments and pull requests need a signed-in session (browser). Every pull request is compiled on coderun and run against the action's benchmark inputs before an admin merges it. Versions are content-addressed: /:provider/:action/versions/:hash.