Docs menu · HTTP API

HTTP API

Authentication, keys and scopes, idempotency, errors and limits, and every endpoint an integration uses.

Updated

Basics

  • Base URL: https://api.neltava.com. JSON in, JSON out.
  • Authenticate with x-api-key: sk_….
  • Money is integer minor units — amount_minor: 4900 is 49.00 USD — in the currency’s own exponent (JPY 0, KWD 3). Currencies are ISO-4217, uppercase.
  • POST /v1/decisions requires an idempotency-key header. Retrying with the same key and body returns the same decision (with idempotent-replay: true); the same key with a different body is a conflict.
  • Timestamps are ISO-8601 in UTC. The decision list paginates with limit and cursor → next_cursor.

Keys and scopes

Create keys in the console (Developers → API keys). A key is shown once and stored only as a hash.

KeyScopesFor
Agentauthorize, bound to one agentThe agent itself: ask for decisions, report its outcomes, read its authority.
Adminadmin review read authorizeYour backend: agents, authority, keys, webhooks.
Reviewerreview readA person or tool that allows, denies and labels.
Read-onlyreadDashboards, exports, the report.
Payment adapterconsumeYour payment service in Enforce: consume capabilities, report rail outcomes. More

Errors

Errors have one shape. Branch on code; the message is for people.

error
{
  "error": {
    "code": "insufficient_scope",
    "message": "this route requires the 'admin' scope",
    "request_id": "7d1c…"
  }
}
StatuscodeMeaning
400invalid_requestThe body or query failed validation; the message names the field.
401unauthenticatedMissing, unknown, revoked or expired key.
403insufficient_scopeThe key can't do this (e.g. an agent key calling an admin route).
403agent_mismatchAn agent key named a different agent.
403agent_not_activeThe agent is paused or revoked.
403self_review_forbiddenThe requester can't review their own request.
404not_foundNo such resource in this workspace.
409idempotency_conflictThe idempotency key was already used for a different request.
409agent_existsAn agent with that slug already exists.
409agent_limitThe plan's agent quota is reached.
409plan_requiredEnforce needs a paid plan.
409authority_changedThe authority changed since the decision; ask again.
409not_reviewableOnly a REVIEW decision can be reviewed.
409review_finalAn Enforce review is final.
409outcome_conflictThe outcome contradicts what was already reported.
422agent_requiredA workspace key must name the agent.
422currency_mismatchThe outcome's currency differs from the decision's.
429rate_limitedToo many requests; retry after the Retry-After header.
503auth_unavailableSign-in couldn't be verified right now; retry.

Capability refusals (capability_used, payee_mismatch…) are listed in Enforce at the payment point.

Rate limits

600 requests a minute per key. Over it, the API answers 429 rate_limited with Retry-After: 60. Repeated requests with unknown keys are limited per client. The SDK retries 429s; it never treats one as permission to spend.

Decisions

POST/v1/decisionsscope: authorize

Ask whether a spend may happen. Answers 201 with the decision (200 on an idempotent replay).
request
curl -X POST https://api.neltava.com/v1/decisions \
  -H "x-api-key: $NELTAVA_AGENT_KEY" \
  -H "idempotency-key: run-7-step-3" \
  -H "content-type: application/json" \
  -d '{
    "task": "Q4 pipeline: enterprise developer leads",
    "action": {
      "type": "purchase",
      "merchant": "Platform Weekly",
      "amount_minor": 9000,
      "currency": "USD",
      "description": "Sponsored slot reaching platform engineers at enterprise companies"
    }
  }'
Body
action.typepurchase, subscription, top_up… Required.
action.merchantWho would be paid. Required.
action.amount_minor, action.currencyRequired.
action.descriptionWhat, and why.
action.payee_id<rail>:<id>, e.g. domain:clearbit.com. A capability binds to it.
action.categoryA declared category — an untrusted claim.
taskThis run’s task, as the agent states it.
traceUp to 25 steps: { step, kind?, tool?, at? }.
limitable, min_amount_minorMay the amount be capped, and to no less than what.
agentOnly for workspace keys: the agent’s slug.
contextYour own data, up to 8 KB, kept with the decision.
201 response (abridged)
{
  "decision_id": "dec_7f3c…",
  "decision": "ALLOW",
  "effective_decision": "ALLOW",
  "reason_code": "WITHIN_AUTHORITY",
  "requested_amount_minor": 9000,
  "authorized_amount_minor": 9000,
  "currency": "USD",
  "mode": "SHADOW",
  "explanation": "Allowed: 90.00 USD at Platform Weekly is within growth-agent's authority."
}

The full response also has reason_codes, policy_trace (every stage), purpose (the assessment), authority_version and authority_hash, reservation, and in Enforce a capability. What each field means.

GET/v1/decisionsscope: read (an agent key sees its own)

Filters: agent, decision, mode, reason, q (merchant), min_amount, max_amount, reviewed, labeled, from, to, order, limit (≤ 200), cursor.

GET/v1/decisions/:idscope: read

Reviews and labels

POST/v1/decisions/:id/reviewsscope: review

{ action: "ALLOW" | "DENY", reason_code, comment? } on a REVIEW decision. Reasons: reviews. A review is attributed to the key’s principal_id (e.g. user:…); whoever asked for the spend can’t review it.

POST/v1/decisions/:id/labelsscope: review

{ label: "PURPOSE_ALIGNED" | "PURPOSE_MISALIGNED" | "PURPOSE_UNCLEAR", comment? } on any decision.

Both are append-only. An Enforce review is final; a Shadow review or any label is corrected by sending a new one with supersedes set to the id it replaces.

Outcomes

POST/v1/decisions/:id/outcomesscope: authorize · consume · admin

What actually happened. type: SPEND_EXECUTED, SPEND_FAILED, SPEND_CANCELLED, REFUNDED, PARTIALLY_REFUNDED. source: CLIENT_REPORTED (default; the only one an agent key may send) or PAYMENT_RAIL (a payment adapter key, for payments it made).
report an outcome
curl -X POST https://api.neltava.com/v1/decisions/dec_7f3c…/outcomes \
  -H "x-api-key: $NELTAVA_AGENT_KEY" \
  -H "content-type: application/json" \
  -d '{
    "type": "SPEND_EXECUTED",
    "amount_minor": 9000,
    "currency": "USD",
    "external_reference": "ch_3Pq…",
    "occurred_at": "2026-09-27T14:03:00Z"
  }'

GET/v1/decisions/:id/outcomesscope: read

Agents and authority

POST/v1/agentsscope: admin

{ slug, name?, mode?, authority? }. New agents take the workspace mode (Shadow). Counts toward the plan’s agent quota.
create an agent with its authority
curl -X POST https://api.neltava.com/v1/agents \
  -H "x-api-key: $NELTAVA_ADMIN_KEY" \
  -H "content-type: application/json" \
  -d '{
    "slug": "growth-agent",
    "name": "Growth agent",
    "authority": {
      "purpose": {
        "objective": "Acquire qualified enterprise developer leads",
        "success_criteria": [
          "Leads are platform engineers at enterprise companies",
          "Cost per qualified lead under $120"
        ],
        "constraints": [
          "No consumer social campaigns",
          "Never buy contact lists"
        ],
        "context": "B2B developer-tools company, Q4 pipeline push"
      },
      "currency": "USD",
      "per_transaction_limit_minor": 50000,
      "review_threshold_minor": 25000,
      "monthly_budget_minor": 500000,
      "blocked_merchants": [
        "ListBroker"
      ]
    }
  }'

GET/v1/agentsscope: read

GET/v1/agents/:idscope: read

PATCH/v1/agents/:idscope: admin

{ name?, status?: "active" | "paused" | "revoked", mode?: "SHADOW" | "ENFORCE" }. Revoking is permanent.

POST/v1/agents/:id/authorityscope: admin

A new authority version (the full object — fields). Earlier versions stay on record.

GET/v1/agents/:id/authorityscope: read

POST/v1/agents/:id/authority/simulatescope: admin

Replays the agent’s recent real decisions against a draft authority. Nothing is saved.

Keys, reports, ledger

Keys

POST/v1/api-keysscope: admin

{ name, agent_id } for an agent key, or { name, scopes, principal_id? }. Add expires_in_seconds (60 to 31,536,000) for a key that stops working after that long — then it answers 401 “API key expired”; without it, the key never expires. Returns the key once, with its expires_at.

GET/v1/api-keysscope: admin

DELETE/v1/api-keys/:idscope: admin

Revokes the key.

Reports and workspace

GET/v1/reports/shadowscope: read

GET/v1/workspacescope: read

The plan, the trial and the quotas used.

Ledger and audit

GET/v1/ledger/verifyscope: read

Re-derives the workspace’s hash-chained history and reports any edit.

GET/v1/ledger/eventsscope: read

GET/v1/auditscope: read

Administrative events: agents, authority versions, keys, plan changes.

Webhooks

Webhooks have their own page.