Skip to main content
Connect to the Reinx MCP server with an organization key (reinx_org_live_…) and you get the management band instead of the agent spend band: tools for provisioning and configuring agents, projects, and teams. This is the “give one agent the orchestrator role” surface. An orchestrator can create a worker agent, set its budget, pause it, and read its activity — but can never spend its money. All management tool input and output fields use snake_case.

Configuration

Same URL as the agent band — the credential prefix selects the band.
The bands are disjoint. An organization key cannot see or call request_wallet_payment or any other spend tool. If you need one identity that both manages and spends, you need two credentials — that separation is the point.

Every call needs a purpose

All 21 tools — including search_docs and get_docs_page — require a purpose string of 3–500 characters explaining why the orchestrator is acting. Omitting it fails schema validation, so a client built without it fails on every call. It is recorded in the organization’s append-only audit ledger alongside the call outcome — write something an operator would find useful, and never put personal data in it. Note the ledger is append-only but not indefinitely readable: audit queries are clamped to the organization’s retention window (Free 7 days, Pro 30, Enterprise full history), so do not treat this trail as a permanently queryable record of your own activity.

What gates each call

The 19 resource-management tools must pass three checks, independently:
  1. Scope — does the key carry the required scope? Missing → 403 INSUFFICIENT_SCOPE (the response names the required_scope).
  2. Binding rung — may a key bound at this level call this route at all? No → 403 BINDING_NOT_ALLOWED.
  3. Target scope — the rung is fine, but is the object inside the key’s container? No → 403 OUT_OF_SCOPE, or 404 where the route hides the object’s existence entirely.
The last two are easy to conflate and need different fixes: BINDING_NOT_ALLOWED means the route is above your rung, OUT_OF_SCOPE means the object is outside your container.
Gate 3 fires only on per-target operations — get_*, set_*, pause_agent, archive_agent, anything naming one object. The list reads (list_agents, list_transactions, list_audit_events) behave differently: an out-of-binding project_id / team_id filter is intersected with the binding, so it returns a successful empty result, not 403 OUT_OF_SCOPE or 404. A bound key can never widen its view by passing a foreign filter — but it also never gets an error for trying, so do not wait for one. An empty list from a filtered read may simply mean the filter fell outside your binding.
search_docs and get_docs_page are exempt from all three. They need a valid org key and a purpose, but carry no scope requirement and no binding check — they only fetch public documentation, so there is no tenant resource to gate. A read-only key can call them.
See Authentication for the scope vocabulary and the binding matrix, and limits and boundaries for what no key can ever do.

Tools

Reads (8)

The last five require a write scope, not a read scope. They are write preconditions — a full-replacement write needs the current version first — so the write scope covers them. An agents:write key is self-sufficient for the agent read-modify-write loop.

Writes (11)

Docs (2)

An escape hatch for deeper recovery and how-it-works questions. Tool descriptions remain the primary contract — reach for these when a description isn’t enough. get_docs_page is pinned to docs.reinx.ai and refuses any other host with INVALID_PATH.

Parameters

These fields are in addition to the required purpose. All amounts are integer USD cents. Budget replacement rows use teams: [{ team_id, cap_cents }] or agents: [{ agent_id, allocated_cents }]. Include every editable child returned by the matching read. Each approval rule has id, type, enabled, and action (route_to_human or deny). Type-specific fields are threshold_cents for high_value; timezone, start_hour, end_hour, days, and optional start_minute/end_minute for off_hours; and lookback_days for new_recipient. Return the complete rules array with the read’s version.

Reading transaction rows

list_transactions returns next_cursor for pagination. Each row includes payment_type (wallet_transfer or card_purchase). A recorded outbound wallet payee appears as recipient: { address, chain_caip2 }; card rows, deposits, and treasury sweeps have recipient: null. Wallet rows have merchant_name: null. counterparty retains a deposit sender or treasury-sweep label. direction distinguishes credits from debits; payment_type identifies the rail family. recipient.chain_caip2 can be null on a history row whose destination network was not recorded. Do not infer it from the address. Other management reads also return snake_case fields, including budget_allocated, cap_cents, allocated_cents, approval_rules, and next_cursor. Values inside metadata or client configuration maps keep the format required by their consumers.

Creating: the idempotency contract

All three create tools — create_agent, create_project, create_team — require a caller-owned idempotency_key. create_agent additionally provisions external resources (a wallet, a policy) and returns a one-time API key, so a naive retry there could duplicate the agent or lose the key; the key prevents both. Project and team creates are simpler but take the same key for the same reason.
idempotency_key is required on every create — create_agent, create_project, and create_team. Each tool’s input schema enforces it, so on the MCP path omitting it fails argument validation before the call is made (not the REST 400 IDEMPOTENCY_KEY_REQUIRED — that is the direct-REST contract). Generate a stable, high-entropy value per logical resource and persist it before you call — you need it to recover.
On any ambiguous failure — timeout, network error, code-less 5xx, 409 REQUEST_IN_PROGRESS, 409 ORG_NOT_READY, or (agents only) 503 CREATE_RETRYABLE — retry with the SAME key and the SAME payload. It dedupes or resumes and returns the committed resource, never a second one. (Project and team creates dedupe the same way but never emit 503 CREATE_RETRYABLE — that is the agent-saga-only contention code.) Retries are not re-charged against your quota within the same UTC day — the attempt marker dedupes them whether or not the create completed. The one exception: resuming an incomplete create after 00:00 UTC consumes a unit from the new day, because the marker is day-scoped. Reusing a key with a different payload returns 409 IDEMPOTENCY_KEY_REUSE — that’s a bug in your code, not a transient condition.

Reconfiguring: the version loop

Every reconfiguring write carries a version token, and the loop is always the same:
  1. Read the current state (get_*). Budget and approval-rule reads include version; get_agent_budget_policy returns agent.updated_at, which you send as version.
  2. Modify it.
  3. Write it back with that same version.
If anything else changed it in between you get a 409 — re-read and retry, never blind-write. The code differs by tool, so branch on all three:
The two write shapes differ on omitted fields. This is the easiest thing to get wrong.
  • update_agent_budget_policy is a PARTIAL patch. A field you omit is left unchanged. To clear a spend ceiling you must send it explicitly as null — omitting it silently keeps the old limit in force.
  • set_project_budget / set_team_budget are STRUCTURED full replacements. cap_cents, the complete child array (teams for a project, agents for a team), and version are all required. You cannot omit a child to leave it alone — a missing one is rejected 422. Clearing a cap is cap_cents: null, never omission.
  • set_project_approval_rules / set_team_approval_rules replace the whole rules array. Leaving an entry out of the array deletes that rule. There is no per-field merge.
Omission is therefore never a clearing strategy: on the agent patch it means “leave alone”, and on the project/team setters it is either a validation failure or a deletion. Use explicit null on the agent patch and on cap_cents. On the agent patch, null also means different things per field: on per_transaction_limit_cents and daily_spend_limit_cents, null = no limit; on hourly_velocity_limit and daily_velocity_limit, null = fall back to the platform default, which is not unlimited.

Archiving: why your key usually cannot

Archiving is terminal, so a machine may archive only a zombie of its own making. Every one of these must hold:
  • The agent was created by this key’s lineage (a rotated key still qualifies).
  • Its bundled key’s re-delivery window has closed.
  • The credential never authenticated, and the agent has no activity.
  • The wallet balance is zero.
  • No human has ever minted or revoked a key for it. Any human key management permanently disqualifies the machine path — the agent is no longer a machine orphan, so it is a human’s to archive even if everything else passes.
If any of these fails to hold, archiving returns a terminal 403 MACHINE_ARCHIVE_DENIED — not retryable, ask a human to archive from the dashboard. Two cases are not this terminal 403, though: while the key window is still open or the non-delivery proof hasn’t been stamped, the route returns a recoverable 409 (KEY_STILL_DELIVERABLE / KEY_DELIVERY_UNPROVEN) instead — recover the key or stamp the proof rather than escalating (next section).
The server cannot prove the key was never delivered — only that it can no longer be re-delivered, and was never used. An expired re-delivery window says nothing about whether your original create response reached you; a key you received and simply never used looks identical to the gate. You hold the missing evidence. Before archiving, confirm from your own records that no credential was ever stored for this create. Archiving on the gate’s say-alone can destroy an agent whose key you are actually holding.
Two 409s are recoverable and mean specific things:
  • 409 KEY_STILL_DELIVERABLE — the new agent’s key window (~30 min) is still open. Do not archive. Replay create_agent with the same idempotency_key to recover the key and keep the agent.
  • 409 KEY_DELIVERY_UNPROVEN — replay create_agent (it returns api_key: null and key_delivery: "expired", which attempts to stamp the non-delivery proof), then re-issue archive_agent. The stamp is best-effort — a transient DB failure can drop it and leave the archive returning KEY_DELIVERY_UNPROVEN again, so retry replay + re-archive a few times with backoff (the stamp is idempotent, and each replay re-attempts it) — but a persistent recurrence means the stamp itself is failing (a durable fault), so escalate to a human rather than looping. (Same-key replays within the day are not re-charged against your create quota — the quota dedupes them internally; they only consume request rate-limit capacity — so the cost of a bounded retry is rate limit, not quota.) Only do this after confirming from your own records that the original create response was genuinely lost.
Also retryable: 409 BALANCE_UNVERIFIABLE (retry later), and a 200 carrying a non-empty wallets_failed array (re-issue until it comes back empty).

Limits

  • Management writes: 20/min per key, 40/min per organization — on top of the general per-organization ceiling. Reads use the general buckets only.
  • Creation quota: agents, projects, and teams share one counter, 100/day by default, resetting 00:00 UTC. Exhaustion is 429 CREATE_QUOTA_EXHAUSTED and will not clear by waiting out a rate-limit window. Same-UTC-day retries are not re-charged; resuming an incomplete create after 00:00 UTC charges the new day.

Audit

Management calls that reach a handler are written to the organization’s audit trail as mcp.tool_invoked, attributed to the key (name, prefix, last 6) — never to a human user, and never carrying the key’s secret. The project/team recorded is taken from the key’s binding, not from anything the caller supplies. Denials are audited too, so a scope or binding failure is visible to the humans who own the organization.
The audit write is best-effort: it is fire-and-forget, so a database outage can drop a row while the management call still succeeds. That keeps an outage from breaking your integration, but it means the trail is an operational log rather than a guaranteed compliance record — do not rely on it as your own system of record.