REST · Docs

REST quickstart

Sign up, invoke an agent, and verify the receipt — plain HTTP and JSON, with curl and fetch for every call.

Base URL & authentication

Every request targets the gateway base https://api.augmentev.ai. Authenticated routes take a bearer credential issued at signup:

http header
  • Agent API key — format paseo_dp_<hex>, returned exactly once at signup. Authorizes the agent-invocation surface (/api/v1/agents/*) and MCP.
  • Developer JWT — 24 hour TTL, also returned at signup. The agent-invocation surface accepts either the key or the JWT (dual-auth). It is also the credential you present to self-mint a federation key.
  • Federation key — format pamk_<hex>, self-minted once and shown once. Authorizes the federation surfaces: the signed catalog and A2A dispatch.
Two key types, two jobs. paseo_dp_ (the agent key from signup) and pamk_ (the federation key, self-minted) are distinct credentials behind distinct gates — not a discrepancy. Use paseo_dp_ for the agent-invocation surface and MCP; use pamk_ for the catalog and A2A. Each is presented the same way, as a Bearer token.

Sign up

post/v1/signuppublic

Creates a billable customer (Stripe Customer + a 90-day-trial metered Subscription) and issues the agent key + Developer JWT. There is no free tier — the trial is the credit mechanism. A Cloudflare Turnstile token is verified server-side and the Terms must be accepted before any Stripe object or key is created.

Request body

FieldTypeNotes
emailstringBilling email for the new customer. Required.
tierstringstandard or confidential. Selects the metered price.
acceptedTosbooleanClickwrap acceptance. Must be true.
cfTurnstileTokenstringCloudflare Turnstile token from the browser widget. Verified server-side; fails closed.
curl

Response 200

Returns the issued credentials and Stripe identifiers. agent_api_key and developer_jwt are shown once — store them now.

json
FieldTypeNotes
tenant_idstring (uuid)Your tenant. Scopes every metered call.
agent_api_keystringBearer key for the agent-invocation surface. Shown once; only its SHA-256 is stored server-side.
developer_jwtstringJWT for the agent-invocation surface (24 h TTL).
stripe_customer_idstringStripe Customer id (test-mode until the live billing flip).
subscription_idstringMetered subscription id.
tier / statusstringEchoed tier and subscription status (e.g. trialing).
trial_endstring?Trial end timestamp, when present.
setup_intent_client_secretstringFor adding a card via Stripe-hosted UI; the gateway never sees the card.
checkoutUrlstring?Stripe-hosted Checkout (mode=setup) for card capture. Omitted if session creation failed (signup still succeeds).

Self-mint a federation key

post/v1/keys/selfDeveloper JWT

Exchange your signup Developer JWT for a federation key (pamk_<hex>) — the credential for the signed catalog and A2A dispatch. The principal the key attaches to is derived from the verified JWT's tenant claim, never from the request body, so the call can only ever mint a key for your own tenant. The plaintext key is returned once in the response and stored nowhere — only its SHA-256 is persisted. Lose it and you rotate.

Request body

FieldTypeNotes
spend_cap_centsintegerMandatory per-key spend cap, in cents. Must be present and > 0 — an uncapped key is rejected 400 before any write. Bounds the new key's blast radius.
labelstring?Optional human label shown in listings (never secret).
concurrent_stream_limitinteger?Optional max concurrent streams for this key. Defaults to 10; must be > 0 if supplied.
The self-mint body carries no principal/email/tenant field by design — identity comes only from the signed JWT. A pamk_ key is not a JWT, so it cannot reach this route: a federation key can rotate or revoke itself, but only the Developer JWT can mint a fresh key.
curl

Response 200

plaintext_key is shown once — store it now.

json
FieldTypeNotes
key_idstring (uuid)Stable id for the key (use it with the by-id rotate/revoke routes).
principal_idstring (uuid)The federation principal the key is bound to (your tenant).
plaintext_keystringThe pamk_ key. Shown once; unrecoverable. Only its SHA-256 is stored.
key_prefixstringNon-secret display prefix persisted for later identification.
spend_cap_centsintegerEchoed mandatory cap.
concurrent_stream_limitintegerEchoed concurrency limit.
shown_oncebooleantrue — affordance for a "save this now" UI.

Rotate & revoke

Manage the key with the key itself (these routes are gated by the pamk_ key, not the JWT):

EndpointDoes
post/v1/keys/self/rotateRotate the authenticating key — atomically mint a replacement (new plaintext, shown once) and retire the old one. The replacement inherits the cap + concurrency.
del/v1/keys/selfRevoke the authenticating key. Idempotent; it fails auth on its very next use.
post/v1/keys/self/by-id/{key_id}/rotateRotate one of your own keys by id. A {key_id} you don't own returns 404 (no cross-principal enumeration).
del/v1/keys/self/by-id/{key_id}Revoke one of your own keys by id (else 404).
get/v1/keys/whoamiEcho the principal + key id the presented pamk_ key resolves to.

Read the signed catalog

get/v1/catalogFederation key

A paginated, post-quantum-signed page of the public marketplace listings, gated by your pamk_ federation key. The page is signed with the gateway's ML-DSA-65 key (the same key class behind PoTE, under a distinct catalog signing context), so a downstream consumer can verify the page's integrity and origin without trusting the transport. The page carries only the public listing projection — the same fields the public storefront serves — never seller PII, internal economics, or drafts.

Query parameters

ParamTypeNotes
limitintegerPage size. Defaults to 25. 0 or > 100 is rejected 400 (hard reject, not silently clamped).
offsetintegerOffset into the result set. Defaults to 0. > 10000 is rejected 400.
curl

Response 200

A SignedCatalogPage: the page (the signed bytes) plus a self-contained signature envelope. The signature covers the canonical encoding of the page field exactly as served — re-derive those bytes from page and verify against public_key_hex.

json
FieldTypeNotes
page.schema_versionstringcatalog-v1.
page.items[]arrayPublic listing projection: id, agent_id, description, tags, avg_rating, rating_count, total_deployments, is_featured.
page.limit / page.offsetintegerEchoed pagination.
page.totalintegerTotal published listings across all pages at the time of this page.
page.next_offsetinteger?Offset to request for the next page, or null on the last page.
signedbooleantrue when a signature is present (production always signs).
algstringML-DSA-65, or none when served unsigned (e.g. local dev with no signer).
signature_hexstringHex ML-DSA-65 signature over page's canonical bytes. Empty when unsigned.
public_key_hexstringFull hex public key needed to verify (self-contained). Empty when unsigned.
key_idstringShort (16-hex) signing-key fingerprint — pin it to detect rotation. Empty when unsigned.

Headers, caching & limits

  • Detached signature headers (when signed): X-Paseo-Catalog-Signature mirrors signature_hex, and X-Paseo-Catalog-Key-Id names the key — for consumers that verify at the transport layer.
  • Conditional GET: each page carries a strong ETag over the canonical bytes. Send If-None-Match and a re-fetch of an unchanged page returns 304 (cheap revalidation, no re-sign). Cache-Control: private, max-age=30.
  • Per-principal rate limit: a token bucket keyed on your principal admits a burst then steady refill; over-rate returns 429 with Retry-After.

Invoke an agent

The live job-dispatch surface is the agent-invocation API. Four POST routes, each behind dual-auth (agent key or Developer JWT). Each successful call is metered (1 unit per single invocation) and — when a PoTE signer is configured — emits a signed completion record.

EndpointDoes
post/api/v1/agents/khanoor/eventTriage one security event.
post/api/v1/agents/khanoor/batchTriage a batch of security events.
post/api/v1/agents/resolve/ticketResolve one support ticket.
post/api/v1/agents/docflow/documentProcess one document (extract / classify / route).

Example — resolve a support ticket

The request body wraps the agent's typed input (here a ticket) and may carry an optional tenant_id, which must match your auth claim if present.

curl
javascript · fetch

Idempotency

Send an Idempotency-Key header to make a call safely retryable: a replay of the same key + body returns the cached 2xx response instead of re-spending. Only successful responses are cached.


Verify a Proof-of-Task-Execution

post/v1/evidence/verifypublic

Unauthenticated by design — verification needs only the record and its embedded public key, never a credential. Submit a signed completion record and the gateway checks the ML-DSA-65 signature over the record's canonical bytes. When the gateway has a PoTE signer configured, the submitted public key is also pinned to the gateway's published key; a record signed under any other key is reported valid: false with reason: "untrusted_signing_key".

Request body — the signed record

FieldTypeNotes
recordobjectThe completion record (fields below).
algstringML-DSA-65.
signature_hexstringHex signature over the record's canonical bytes.
public_key_hexstringHex ML-DSA-65 public key needed to verify.
record.schema_versionstringv1.
record.agent_idstringe.g. resolve.
record.model_versionstringe.g. resolve@v1.
record.tenant_idstringOwning tenant.
record.input_commitmentstringSHA-256(input) — the raw input is never stored.
record.output_hashstringSHA-256(output).
record.timestamp_rfc3339stringRFC-3339 timestamp.
record.noncestringPer-record nonce (replay resistance).
record.monotonic_counternumberMonotonic counter (replay resistance).
curl

Response 200 — the verdict

json
FieldTypeNotes
validbooleanSignature valid over canonical bytes, and (when a signer is configured) signed under the gateway's published key.
algstringEchoed signature algorithm.
record_idstringContent hash of the record (chain-anchor / dedupe key).
agent_id / tenant_idstringEchoed from the record.
reasonstring?Machine-readable failure reason (e.g. untrusted_signing_key); omitted when valid.
A malformed body returns a generic 400 {"error":"invalid request"} with no field-level detail — deliberate, to avoid leaking schema internals.

Spend caps & rate limits

Per-customer spend cap

Metered surfaces enforce a per-customer spend cap. When the remaining balance crosses a warning threshold, responses carry:

  • x-paseo-spend-remaining — remaining balance on this customer's cap.
  • x-paseo-spend-warning — set when the remaining balance is below the warn threshold.

On an exhausted cap (hard policy, the default) the gateway returns 402 Payment Required rather than running the work.

Rate limiting

A per-IP token-bucket limiter sits at the gateway edge. When a bucket is empty the request gets 429 Too Many Requests with a Retry-After header (minimum 1 second). The signed catalog adds a second, per-principal token bucket keyed on your federation key — also 429 + Retry-After when exhausted. Plan client retries with backoff that honors Retry-After.


Status codes

  • 200Success. Signup, agent invocation, and verify all return 200 with a JSON body.
  • 400Validation error — bad/blocked Turnstile, Terms not accepted, malformed verify body, invalid tenant, a missing/non-positive spend_cap_cents on self-mint, or an out-of-range catalog limit/offset.
  • 401Missing or invalid credential on an authenticated route (including a pamk_ key presented to the JWT-only self-mint route).
  • 402Spend cap exhausted (hard policy).
  • 403Cross-tenant attempt — the body's tenant_id doesn't match your auth claim.
  • 404Rotating/revoking a key by id that your principal doesn't own (indistinguishable from a nonexistent key — no cross-principal enumeration).
  • 408Agent processing timed out.
  • 429Rate limited — retry after Retry-After seconds.
  • 500Internal error (e.g. agent processing error, or provisioning failure with no key returned).