Skip to main content

API Guide

The operator integrates with delta mandate via two HTTP APIs:

A third API runs in the opposite direction: the operator implements the Evidence Extraction API, which the Orchestrator calls during evaluation.

This page is the index for all three. CLI installation lives on the Install page; the Getting Started walkthrough shows the APIs in use end-to-end.

Orchestrator API

The Orchestrator is the write-side: operators register templates, submit signed intents, and forward agent proposals. It compiles templates server-side, drives evaluation, and produces proofs.

Each intent eventually reaches one of three terminal states:

  • success — template evaluation and proof creation both succeeded; the proof is available via the Verifier.
  • failure — the proposal did not satisfy the intent, or proof creation failed.
  • expired — no proposal arrived before the intent's TTL elapsed (default: 24 h).

The API is organized into 4 endpoint groups:

Intents

Submit and retrieve signed user intents, and propose solutions for them:

  • POST /intents — Submit a signed intent
  • GET /intents/{intent_id} — Get a stored intent by its ID
  • POST /intents/{intent_id}/proposal — Submit a proposal for a pending intent, triggering the delta mandate pipeline

Templates

Upload and delete compiled templates:

  • POST /templates — Compile, validate, and store a template from its source
  • POST /templates/validate — Compile and validate a template from its source without storing it
  • GET /templates/{template_id} — Get a human-readable pretty-printed representation of a stored template
  • DELETE /templates/{template_id} — Delete a stored template by its ID

Config

Read and update operator-facing runtime configuration:

  • GET /config — Get the runtime configuration
  • PUT /config — Set the runtime configuration

Events

Stream live orchestrator events to downstream clients:

  • GET /events — Server-Sent Events stream of orchestrator events. Each event's data is one JSON-encoded OrchestratorEvent

Verifier API

The Verifier is the read-side: operators query intent outcomes and fetch the resulting proofs. It ingests events from the Orchestrator and cryptographically validates each proof before exposing the result.

An intent's terminal status is returned together with outcome-specific data:

  • "success" — the proof was validated; the response includes the fulfilled intent and the satisfying proposal.
  • "failure" — the intent was not fulfilled; the response includes a reason string explaining why and the relevant proposal.
  • "expired" — no proposal arrived before the intent's TTL elapsed.

The API is organized into 2 endpoint groups:

Intents

Query the status of intents:

  • GET /intents/{intent_id} — Get the current status of an intent

Proofs

Fetch proof data:

  • GET /proofs/{intent_id} — Get the proof for an intent, if proving succeeded

Evidence Extraction API

Unlike the two APIs above, this one is implemented by the operator and called by the Orchestrator. When a proposal arrives, the Orchestrator sends its solution and metadata to the operator's extractor, which returns the extracted evidence attributes. The Orchestrator validates them against the template's evidence schema; attributes without enough evidence should be omitted from the response.

  • POST /extract — Fetches or resolves the proposed solution and extracts its evidence fields

Streaming events

The way to learn outcomes is the Orchestrator's event stream — consume it unless your environment really cannot hold a streaming connection, in which case polling the Verifier is the fallback. GET /events is a Server-Sent Events endpoint; each event's data is one JSON-encoded OrchestratorEvent:

mandate-orchestrator events stream

There are three event types, distinguished by the type field:

  • success — proof generation completed; carries the intent_id, the winning proposal, and the evidence used by the proof (a plain JSON object of field values).
  • failure — evidence extraction or proof generation failed; carries the intent_id, a human-readable reason, the proposal being processed, the evidence extracted before the failure (or null if extraction never produced any), and constraint_failures.
  • expired — the intent's TTL elapsed without a proposal; carries only the intent_id.

When a failure is caused by constraint violations, constraint_failures lists each violated constraint with its index (0-based position in the template), the pretty-printed expression, and a reason:

{
"type": "failure",
"intent_id": "550e8400-e29b-41d4-a716-446655440000",
"reason": "constraint[4] failed: evidence.price_cents <= intent.max_price_cents (constraint evaluated to False)",
"proposal": { "solution": "https://shop.example.com/products/pullover-xl", "metadata": { "merchant": "shop.example.com" } },
"evidence": { "category": "pullover", "price_cents": 5800, "size": "XL" },
"constraint_failures": [
{
"index": 4,
"pretty_expr": "evidence.price_cents <= intent.max_price_cents",
"reason": "constraint evaluated to False"
}
]
}

Two things to plan for when integrating:

  • The stream is shared. Events for all intents arrive on one stream — demultiplex by intent_id.
  • Missed events are not replayed. A subscriber only receives events emitted while it is connected. After a disconnect, reconcile any in-flight intents by querying the Verifier (mandate-verifier intents get), then resume listening.

The full event schema is in the Orchestrator API reference.

Besides SSE, both services expose a gRPC StreamEvents endpoint following the same success/failure/expired lifecycle, with slightly different payloads (the Orchestrator's gRPC success event carries the full proof; its failure event omits the evidence and constraint detail). The Verifier's stream emits validated outcomes. Useful for non-HTTP consumers and for operators wiring the Verifier to the Orchestrator; the protobuf definitions ship in the delta-mandate repo under crates/proto_types/proto/, and a dedicated gRPC guide is planned.

CLI configuration

The server URLs are provided by delta upon onboarding. Set them once and the CLIs pick them up:

export ORCHESTRATOR_URL=<orchestrator_url>
export VERIFIER_URL=<verifier_url>

delta provides the mandate-orchestrator and mandate-verifier CLIs for these APIs. The Getting Started walkthrough uses them end-to-end.

Errors

All endpoints return a JSON error body on non-2xx responses:

{ "message": "<short description>" }

Status codes used across both APIs:

  • 400 Bad Request — request validation failed: malformed payload, invalid signature, unknown template_id, template compilation error, or invalid evidence-extractor URL on PUT /config.
  • 404 Not Found — referenced intent, proposal, template, or proof does not exist.
  • 409 Conflict — the requested action conflicts with current state. Emitted by POST /intents/{intent_id}/proposal when the target intent already has a proposal (one proposal per intent), and by POST /intents when the intent already exists.
  • 500 Internal Server Error — internal error. Contact us if this should ever happen.

Per-endpoint error variants are documented in the OpenAPI specs.

OpenAPI specs

The OpenAPI specs document the full API surface: