Skip to main content
An is the durable contract between a user and an agent — what the user wants, what the agent may do, and under which signed authorisations. This guide covers the Platform API surface: request and response shape, lifecycle actions, and how to expand related resources. On the wire, an Errand is created and driven through the IPA (Intelligent Purchase Authorisation) routes and lifecycle. For the concept and composition model, see Errands; for the state machine, see Errand lifecycle.
An Errand sits above its mandates. The Errand handles orchestration (finding, validating, approving); a with sr:us:pint:spend:execute authorises the on-chain transaction at execution time. See scopes.

Prerequisites

  • A verified user with a deployed Safe — see onboarding.
  • A signed Stamped Mandate that carries the scopes the Errand needs (at minimum sr:us:pint:perpetual:search; add sr:us:pint:spend:execute to authorise execution). See Stamped Mandates for the mint flow and scopes for the catalog.
  • A Platform API JWT — see authentication.

Create an Errand

On the wire, you create an Errand with POST /v0/user/ipa, which returns 202 Accepted once the pre-flight workflow is triggered. Pass Idempotency-Key to guard against duplicate submissions: if a previous request with the same key successfully produced an Errand, the retry returns that original Errand with 208 Already Reported. If the previous attempt did not produce an Errand (e.g. it failed before creation), the retry is processed as a new request.
curl -X POST https://api.sumvin.com/v0/user/ipa \
  -H "x-juno-jwt: <token>" \
  -H "x-juno-orgid: <your-org-id>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ipa-req-0001" \
  -d '{
    "raw_intent": "Find me a pair of Nike Air Max 90 in size 10, under $150",
    "intent_type": "product",
    "autonomy_level": "approve_before_purchase",
    "constraints": { "max_price": 150.00, "currency": "USD" },
    "originating_chat_id": "chat_xyz789",
    "pint_uri": "sr:us:pint:def456"
  }'

Request fields

FieldTypeRequiredDescription
raw_intentstringYesThe user’s request in natural language (1–2000 chars). Preserved verbatim for audit and re-parsing.
intent_typeenumNoproduct, service, or composite. Default: product.
autonomy_levelenumNosupervised, approve_before_purchase (default), auto_within_conditions, autonomous.
constraintsobjectNoSelection filters (what results are acceptable). See constraints.
conditionsarrayNoAuto-execution triggers. Only evaluated when autonomy_level = auto_within_conditions.
originating_chat_idstringNoExternal ID of the chat session this Errand came from — carried through for traceability.
originating_agent_task_idstringNoExternal ID of an existing agent task to attach this Errand to. Mutually exclusive with Idempotency-Key.
pint_uristringNoURI of a Stamped Mandate (PINT) to link to this Errand for spending-limit enforcement. Validated before pre-flight fires.
constraints answer what is acceptable (e.g. max_price = 200). conditions answer when an approved Errand may auto-execute (e.g. buy if price drops below 180). They are evaluated at different stages — don’t conflate them.

Response shape

{
  "intent": {
    "id": "ipa_1a2b3c4d",
    "intent_type": "product",
    "status": "qualifying",
    "autonomy_level": "approve_before_purchase",
    "raw_intent": "Find me a pair of Nike Air Max 90 in size 10, under $150",
    "constraints": { "max_price": 150.00, "currency": "USD" },
    "preflight_workflow_id": "wf_preflight_9a7d2f",
    "pint_uris": ["sr:us:pint:def456"],
    "created_at": 1740000000000
  },
  "_links": {
    "self": { "href": "/v0/user/ipa/ipa_1a2b3c4d" },
    "events": { "href": "/v0/user/ipa/ipa_1a2b3c4d/events" },
    "answers": { "href": "/v0/user/ipa/ipa_1a2b3c4d/answers", "method": "PUT" },
    "cancel": { "href": "/v0/user/ipa/ipa_1a2b3c4d", "method": "DELETE" }
  }
}

Key response fields

FieldDescription
idThe Errand’s external ID. Use as {ipa_id} in subsequent requests.
statusCurrent lifecycle state. See Errand lifecycle for the full state machine.
preflight_workflow_idExternal ID of the durable workflow validating the intent and Stamped Mandate scopes.
pint_urisStamped Mandates linked to the originating and, once present, executing agent tasks.
constraintsEchoed and parsed from the request.
conditionsParsed auto-execution triggers (when supplied).
_links links indicating which actions are valid for the current state.
The originating and executing agent tasks, candidates, manifests, and events are not returned by default — fetch them via expand.

Drive the lifecycle

The _links field on every Errand response tells you which actions are currently valid. For the full state diagram, see Errand lifecycle.

Submit clarification answers

When the Errand is in qualifying or pending_clarification, the answers link is present and clarification_questions is populated.
curl -X PUT https://api.sumvin.com/v0/user/ipa/ipa_1a2b3c4d/answers \
  -H "x-juno-jwt: <token>" \
  -H "x-juno-orgid: <your-org-id>" \
  -H "Content-Type: application/json" \
  -d '{ "answers": { "preferred_color": "white", "new_or_used": "new only" } }'
Returns 200 OK with status: "qualifying" — the agent re-parses with the new context.

Approve or reject

In pending_approval, submit a decision. Approving conditionally adds conditions that must be met before the Errand auto-executes.
curl -X PUT https://api.sumvin.com/v0/user/ipa/ipa_1a2b3c4d/decision \
  -H "x-juno-jwt: <token>" \
  -H "x-juno-orgid: <your-org-id>" \
  -H "Content-Type: application/json" \
  -d '{ "decision": "approved" }'
Valid decision values: approved, rejected, conditional. A conditional decision also accepts conditions and monitor_until (epoch ms).

Cancel

Any non-terminal Errand can be cancelled. The pre-flight or executing workflow is halted and the Errand transitions to cancelled.
curl -X DELETE https://api.sumvin.com/v0/user/ipa/ipa_1a2b3c4d \
  -H "x-juno-jwt: <token>" \
  -H "x-juno-orgid: <your-org-id>"
Returns 200 OK, or 409 Conflict if the Errand is already terminal (completed, failed, expired, cancelled).

Read an Errand

curl https://api.sumvin.com/v0/user/ipa/ipa_1a2b3c4d \
  -H "x-juno-jwt: <token>" \
  -H "x-juno-orgid: <your-org-id>"

Expansions

Add expand query parameters to embed related resources in the same response. Without expand, these fields are null.
ExpansionField populatedShape
originating_agent_taskoriginating_agent_taskAgent task that created the Errand (e.g. the pre-flight task).
executing_agent_taskexecuting_agent_taskAgent task that carries the Errand into execution. Spawned during pre-flight, so it is available before approval is granted.
candidatescandidatesScored candidate results produced during searching and validating.
manifestsmanifestsPurchase manifests constructed once a candidate is selected.
eventseventsLifecycle event stream (same content as GET /v0/user/ipa/{ipa_id}/events).
curl "https://api.sumvin.com/v0/user/ipa/ipa_1a2b3c4d?expand=originating_agent_task&expand=executing_agent_task" \
  -H "x-juno-jwt: <token>" \
  -H "x-juno-orgid: <your-org-id>"

List Errands

curl "https://api.sumvin.com/v0/user/ipa?status=pending_approval&sort=-created_at&limit=20" \
  -H "x-juno-jwt: <token>" \
  -H "x-juno-orgid: <your-org-id>"
ParameterDescription
statusFilter by Errand status.
intent_typeproduct, service, composite.
sortcreated_at, updated_at, or status. Prefix - for descending.
offsetPage offset, ≥0. Default 0.
limitPage size, 1–100. Default 20.
expandRepeat per resource to expand — same options as the detail endpoint.
The response includes HAL next/prev links when more pages exist.

Event stream

GET /v0/user/ipa/{ipa_id}/events returns every state change, clarification exchange, approval decision, workflow transition, and cancellation recorded against the Errand. Fetch it directly, or embed it via expand=events on the detail endpoint.

Constraints

Structured requirements that define what results the agent may propose. Evaluated during parsing, search, validation, and manifest construction — not during execution monitoring.
FieldTypeDescription
max_pricenumberMaximum price per item.
max_totalnumberMaximum total spend.
currencystringCurrency code (e.g. USD).
deadlineintegerDeadline timestamp (epoch ms).
preferred_sellersarrayPreferred seller identifiers.
excluded_sellersarraySellers to exclude.
extraobjectAdditional key-value constraints.

Conditions

Auto-execution triggers evaluated once an Errand is approved with autonomy_level = auto_within_conditions. Each condition is typed by type (price_target, budget_cap, availability, time_window, flight_route, coverage_minimum, jurisdiction, group). See the Create Errand reference for the per-type schemas.

Idempotency and HAL

  • Idempotency-Key on POST /v0/user/ipa deduplicates retries when a prior request with the same key already produced an Errand — that original is returned with 208 Already Reported. Retries of a failed prior attempt are processed as new requests. Mutually exclusive with originating_agent_task_id in the body.
  • Every response carries _links — the presence of a link is the authoritative signal that the action is valid. See HAL, RFC 7807, idempotency, pagination.

Errors

All errors follow RFC 7807 Problem Details with stable error_code values (e.g. IPA-404-001, IPA-409-001).
StatusMeaning
401 UnauthorizedMissing or invalid JWT.
404 Not FoundErrand does not exist or does not belong to the authenticated user.
409 ConflictErrand is terminal and cannot be modified or cancelled.
422 Unprocessable EntityRequest body failed validation.