DocsManagement API
Management API
Configure an INFRO organization as code: projects, gateway keys, connections, routes, budgets and policies through one versioned, token-authenticated API.
INFRO is in private early access. Running these examples requires an early-access account, an active trial or subscription entitlement, and your own provider connection. Self-serve purchasing is not generally open. See Early access.
Built, not yet available. The management API is built and not deployed: /manage/v1 does not answer requests yet, and nothing on this page can be used today. These pages describe the contract it ships with.
The management API lets a program configure your organization: Terraform, a CI pipeline, the INFRO CLI or a script of your own. It lives at https://api.infro.io/manage/v1, takes a management token, and covers the configuration you set in the console today: projects, gateway keys, provider connections, routes, organization settings, member budgets, webhook endpoints, custom model rates, alert channels and rules, cost centers, commitments, guardrail policies and end-customer spend caps.
It does not serve inference. Model requests still go to /v1 with a gateway key, and a management token is refused there.
Same rules as the console
The management API does not re-implement anything. Each request is handed to the same handler the console uses, running as the person who created the token, with their role as it is now. Validation, plan limits, role checks and audit records are therefore the ones you already know from the console, and they cannot drift apart.
The consequence is that request bodies are the console's bodies, with the console's snake_case field names. A field the console form does not take, the API does not take either.
Resources
| Resource type (URL segment) | Scope family | What delete does |
|---|---|---|
projects | projects | Archives the project. ?purge=true deletes it, only if it has no gateway keys and no usage |
gateway_keys | keys | Revokes the key |
provider_connections | connections | Deletes the connection |
routes | routes | Deletes the route |
org_settings | settings | No delete: one object per organization, read and patched |
member_budgets | budgets | No delete: patch spend_limit to null to remove a limit |
webhook_endpoints | webhooks | Deletes the endpoint |
model_prices | prices | Deletes the custom rate |
notification_channels | notifications | Deletes the channel |
notification_rules | notifications | Deletes the rule |
cost_centers | cost_centers | Archives the cost center |
cost_center_rules | cost_centers | Deletes the rule |
commitments | commitments | Deletes the commitment |
guardrail_policies | guardrails | Removes the policy |
end_user_cap_rules | end_users | Deletes the rule and its per-end-customer overrides |
Every resource supports GET /<type> (a list, {"object": "list", "data": [...]}) and GET /<type>/{id}. Fields and operations for each are on Resources. Three read-only data sources need any scope: GET /organization (the organization, its plan and this token), GET /provider_kinds and GET /models.
Three more resource types configure the MCP gateway, all in the mcp scope family: mcp_servers (delete removes the server, its tools and its grants), mcp_key_grants (delete removes the grant) and mcp_server_tools (read and actions only; tools are created by discovery). They also need the Business plan's gateway to enable anything. See Resources.
Plans
| Plan | What a token can do |
|---|---|
| Developer | No management API. Every request returns 403 with code: "plan_feature". |
| Startup | Read every resource, and create, change and delete projects and gateway keys. |
| Team and above | Every read and every write. |
A write the plan does not include returns 403 with code: "plan_feature" and the message names the plan it needs.
Items, versions and managed_by
Every item carries id, object, version and managed_by, plus the resource's own fields. version is an integer that moves on every configuration change, whether made in the console or through the API. It does not move on runtime changes such as a connection's health or a key's last-used time, so a failover does not make your next plan report a change. Single-item reads and writes return the version as ETag: "<version>".
managed_by records which tool last wrote the resource through this API: terraform, cli or api, or null when it was never written here. It is set from the User-Agent header (terraform-provider-infro/<version> or infro-cli/<version>; anything else is api). It is a label for people reading the console, not a lock and not a security control.
Writing safely
PATCHandDELETErequireIf-Match: "<version>"with the version you last read. Without it the request is refused with400andcode: "if_match_required". If the resource has changed since, the request is refused with409, typeconflict,code: "version_conflict", and the current version in theETagheader. Read it again, decide, and retry.PATCHis a merge. A field you leave out is unchanged; a field set tonullis cleared.POSThonoursIdempotency-Key(up to 200 characters). A retry with the same key and the same body returns the first response with the headerIdempotent-Replayed: true, and creates nothing new. A secret that was in the first response isnullin the replay, withsecret_redacted: true: it was shown once. The same key with a different body is refused with400andcode: "idempotency_key_reuse".- Every write records
managed_byand onemanagement_api.requestentry in the audit log, naming the token and its creator, next to the entry the console handler writes.
curl -i https://api.infro.io/manage/v1/routes/rt_01J9Z6 \
-H "Authorization: Bearer $INFRO_MANAGEMENT_TOKEN"
# ETag: "4"
curl https://api.infro.io/manage/v1/routes/rt_01J9Z6 \
-X PATCH \
-H "Authorization: Bearer $INFRO_MANAGEMENT_TOKEN" \
-H 'If-Match: "4"' \
-H "Content-Type: application/json" \
-d '{"max_retries": 2}'Export
GET /export returns every resource the token can read in one document: {"object": "export", "organization_id", "exported_at", "resources": {"<type>": [...]}}. Families the token cannot read are left out. It never contains a credential: provider secrets and Slack URLs are write-only, and a gateway key's or webhook endpoint's secret is shown only when it is created.
OpenAPI document
The request bodies for every resource are published as an OpenAPI 3.1 document at https://api.infro.io/manage/v1/openapi.json. It needs no token.
Known limits
- The
If-Matchcheck and the write are two separate steps. A change that lands in the milliseconds between them is not detected; the next read shows it. - A guardrail policy has no row of its own. It uses the version of what it is attached to (the organization's settings, a project or a key), so an unrelated change to that project or key also moves the policy's version.
- Not managed through this API: SSO, SCIM, the admin credentials used for cost reconciliation, OpenTelemetry export settings, and members and invitations. Configure those in the console.
- Request bodies are the console's: a field the console form does not take, the API does not take either.
Next
- Management tokens: creating one, scopes and expiry.
- Resources: fields and operations for each resource type.
- Terraform and the CLI: the two tools built on this API.
- AI assistants (MCP): the same operations for Claude Code, Cursor, VS Code, Windsurf and Codex.