Skip to main content
Every agent invocation on ServiceNet produces an execution receipt — an immutable record containing cryptographic digests of the request and result. Receipts let you audit exactly what was called, when it ran, whether it succeeded, and whether its output has been independently verified. Use them to build audit trails, detect anomalies, and meet compliance requirements without storing raw payloads.

Receipt fields

Every receipt response returns a StoredReceipt object. The core execution metadata is nested under the receipt key as an ExecutionReceipt. Two additional top-level fields, output and stderr, carry the raw invocation result and any captured error output when available.

ExecutionReceipt fields (nested under receipt)

Each ExecutionReceipt captures the full lifecycle of a single invocation:
receipt_id
string (UUID)
The unique identifier for this receipt. Use it to fetch a specific receipt or submit a verification verdict.
agent_id
string
The ID of the agent that was invoked.
provider_id
string
The ID of the provider that hosts the agent.
status
string
The invocation outcome. One of:
  • running — the invocation is in progress (async only)
  • succeeded — the agent returned a successful A2A response
  • failed — the invocation failed (network error, agent error, or gateway rejection after dispatch)
  • rejected — the invocation was rejected by the gateway before any A2A call was made (blocked entity, policy violation, etc.)
verification
string
The current verification verdict. See Verification verdicts below.
request_digest
string
SHA-256 hex digest of the normalized request payload (message, input, skill ID, and settlement fields). Use this to verify that two receipts represent identical requests.
result_digest
string | null
SHA-256 hex digest of the result payload, set on successful completion. null while the invocation is running or if it failed before producing output.
started_at
string
ISO 8601 timestamp when the gateway began processing the invocation.
completed_at
string | null
ISO 8601 timestamp when the invocation completed. null while status is running.
cost_units
integer | null
The number of cost units charged for this invocation, if the agent card declares a cost. null if the agent has no declared cost.

StoredReceipt top-level fields

output
object | null
The raw JSON result payload returned by the agent, captured at completion time. null if the invocation failed, was rejected, or produced no structured output.
stderr
string | null
Any plain-text error or diagnostic output captured during the invocation. null when not present.

Query receipts

List receipts

Filter receipts by agent, provider, or verification verdict. All query parameters are optional.
# All receipts for a provider
curl 'http://127.0.0.1:8042/v1/receipts?provider_id=acme-labs'

# All receipts for a specific agent
curl 'http://127.0.0.1:8042/v1/receipts?agent_id=stripe-agent'

# Only receipts that are pending verification
curl 'http://127.0.0.1:8042/v1/receipts?verification=pending'

# Combine filters and cap results
curl 'http://127.0.0.1:8042/v1/receipts?agent_id=stripe-agent&verification=pending&limit=50'
Responses wrap results in { "items": [...] }. Each item is a StoredReceipt that nests the core ExecutionReceipt under a receipt key and includes optional output and stderr fields:
{
  "items": [
    {
      "receipt": {
        "receipt_id": "550e8400-e29b-41d4-a716-446655440000",
        "agent_id": "stripe-agent",
        "provider_id": "acme-labs",
        "status": "succeeded",
        "verification": "pending",
        "request_digest": "a3f2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2",
        "result_digest": "f1e2d3c4b5a6978869504132c3b2a1f0e9d8c7b6a5948372615049382716059a",
        "started_at": "2025-01-15T12:34:55Z",
        "completed_at": "2025-01-15T12:34:56Z",
        "cost_units": 5
      },
      "output": { "payment_link": "https://pay.stripe.com/..." },
      "stderr": null
    }
  ]
}

Query parameters

agent_id
string
Return only receipts for the specified agent.
provider_id
string
Return only receipts for agents belonging to the specified provider.
verification
string
Filter by verification verdict. One of: not_required, pending, verified, failed.
limit
integer
Maximum number of receipts to return. Defaults to the node’s configured list limit.

Fetch a single receipt

curl http://127.0.0.1:8042/v1/receipts/550e8400-e29b-41d4-a716-446655440000
Returns a StoredReceipt object (not wrapped in items). The StoredReceipt nests the ExecutionReceipt under the receipt key and adds two optional fields — output (the raw JSON result, if available) and stderr (any captured error output). Returns HTTP 404 if the receipt ID does not exist.
{
  "receipt": {
    "receipt_id": "550e8400-e29b-41d4-a716-446655440000",
    "agent_id": "stripe-agent",
    "provider_id": "acme-labs",
    "status": "succeeded",
    "verification": "pending",
    "request_digest": "a3f2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2",
    "result_digest": "f1e2d3c4b5a6978869504132c3b2a1f0e9d8c7b6a5948372615049382716059a",
    "started_at": "2025-01-15T12:34:55Z",
    "completed_at": "2025-01-15T12:34:56Z",
    "cost_units": 5
  },
  "output": { "payment_link": "https://pay.stripe.com/..." },
  "stderr": null
}

Verification

Verification verdicts

VerdictMeaning
not_requiredThe agent has risk_level: "low". No verification step is needed.
pendingThe agent has risk_level: "medium" or "high". The receipt is waiting for a verifier to adjudicate.
verifiedAt least one verifier has confirmed the outcome matches expectations.
failedVerification found a discrepancy between the recorded digest and the expected result.
Low-risk agents receive not_required automatically at receipt creation time and never enter the pending queue. Medium- and high-risk agents always start with pending and require either a manual verification or an automated sweep to advance.

Submit a manual verification

Send a POST to /v1/receipts/:receipt_id/verify to record a verification verdict for a specific receipt. You can use this for human-in-the-loop audits or custom automated checks outside the built-in sweep.
curl -X POST http://127.0.0.1:8042/v1/receipts/550e8400-e29b-41d4-a716-446655440000/verify \
  -H 'content-type: application/json' \
  -d '{
    "verifier_id": "auditor-1",
    "verdict": "verified"
  }'
To record a discrepancy:
curl -X POST http://127.0.0.1:8042/v1/receipts/550e8400-e29b-41d4-a716-446655440000/verify \
  -H 'content-type: application/json' \
  -d '{
    "verifier_id": "auditor-1",
    "verdict": "failed",
    "reason": "result digest does not match expected output for this input"
  }'

Verify request fields

verifier_id
string
required
The identifier of the entity submitting this verdict. Can be a human auditor ID, an automated system name, or any string that identifies the verifier in your audit trail.
verdict
string
required
The verification outcome. Must be one of verified or failed. You cannot submit not_required or pending as a manual verdict.
automated
boolean
Set to true if this verdict was produced by an automated process rather than a human reviewer. Defaults to false.
reason
string
Optional explanation for the verdict. Especially useful when verdict is failed to describe what discrepancy was found.

List verification records for a receipt

Retrieve the full history of verification attempts for a specific receipt:
curl http://127.0.0.1:8042/v1/receipts/550e8400-e29b-41d4-a716-446655440000/verifications
Returns { "items": [...] } where each entry is a VerificationRecord:
{
  "items": [
    {
      "receipt_id": "550e8400-e29b-41d4-a716-446655440000",
      "verifier_id": "auto-verifier",
      "verdict": "verified",
      "automated": true,
      "reason": null,
      "verified_at": "2025-01-15T13:00:00Z"
    }
  ]
}

Automated verifier sweep

The verifier sweep processes all receipts with verification: "pending" in a single pass. Run it on a schedule or after a batch of invocations to keep the pending queue clear.
curl -X POST http://127.0.0.1:8042/v1/verifier/run \
  -H 'content-type: application/json' \
  -d '{ "verifier_id": "auto-verifier" }'
The response returns the VerificationRecord objects created during this sweep run:
{
  "items": [
    {
      "receipt_id": "550e8400-e29b-41d4-a716-446655440000",
      "verifier_id": "auto-verifier",
      "verdict": "verified",
      "automated": true,
      "reason": null,
      "verified_at": "2025-01-15T13:00:00Z"
    }
  ]
}
If no receipts are pending, items is an empty array.
Run the sweep periodically in a background job or after any batch invocation workflow. Each run only processes receipts that are still pending — already-verified receipts are skipped automatically.
Receipts with status: "rejected" are never assigned pending verification — they are rejected before any A2A call is made and produce no verifiable result digest. The sweep skips them entirely.