---
title: "Create a caller-local deny receipt"
method: POST
path: "/v1/intel/refuse-receipt"
tags: ["Discovery & Ops"]
---

# Create a caller-local deny receipt

`POST /v1/intel/refuse-receipt`

## Request

- Base URL: `https://intel.twzrd.xyz`
- URL: `https://intel.twzrd.xyz/v1/intel/refuse-receipt`
- Auth: API key in header `X-Twzrd-Caller`

Notarize a caller's own local deny (e.g. spend_policy_denied). This is not a TWZRD wash verdict. Domain TWZRD:REFUSE_RECEIPT_V0; same Ed25519 v2 key as V6, different domain. Replay of the same natural key returns the same signed object for 90 days; after that a remint gets a new issued_at_unix and a new leaf. Requires X-Twzrd-Caller matching body.caller_id for the legacy format (202). Alternatively submit challenge_hash, issued_at_unix, resource, reason, payer_pubkey, signature for a free caller-signed declaration (200 logged, receipt_id, witness_signature). No caller header or payment required for this format. Ed25519 base58 signature over UTF-8 TWZRD:SIGNED_REFUSAL_V1 + LF + compact, sorted-key, ensure_ascii JSON of all five non-signature fields. issued_at_unix must be within 300s of server time. Optionally include quoted_price: this selects TWZRD:SIGNED_REFUSAL_V2 and signs all six non-signature fields, including the complete quote object. The witness receipt adds ingested_at_unix, the server ingestion time, bound into the witness leaf and distinct from the caller-signed issued_at_unix. Reasons and challenge provenance are caller claims. Invalid or stale signature returns 422 INVALID_REFUSAL_SIGNATURE.

## Headers

- `X-Twzrd-Caller` string, required

## Request body

- union: Legacy caller-local deny or caller-signed refusal declaration. No payment authorization.
  - object
    - `caller_id` string, required: Must match X-Twzrd-Caller.
    - `pay_to` string, required: Counterparty payTo.
    - `chain` 'solana' | 'base' | 'polygon', required
    - `rule_id` string, required
    - `policy_hash` string, required: 0x + 64 hex of their policy blob.
    - `denied_at_unix` integer, required
    - `challenge_hash` string: 0x-prefixed lowercase SHA-256 of exact decoded 402 challenge JSON bytes, before parsing.
    - `issued_at_unix` integer: UNIX seconds at which the caller formed the declaration; must be within 300s of server time.
    - `resource` string, uri
    - `reason` 'BUDGET_EXCEEDED' | 'UNTRUSTED_MERCHANT' | 'STALE_CORPUS' | 'UNSUPPORTED_CHAIN'
    - `payer_pubkey` string: Base58 Ed25519 declaration signer. No payer externality or payment claim.
    - `signature` string: Base58 Ed25519 signature over the domain-separated declaration.
    - `quoted_price` object: Caller-asserted offer, not independently authenticated seller pricing. Selects signed refusal V2.
      - `amount_atomic` string, required: Unsigned integer less than 2^128 in the asset's smallest units; not necessarily USDC micro-units.
      - `asset` string, required
      - `network` string, required
      - `pay_to` string, required
  - object
    - `caller_id` string: Must match X-Twzrd-Caller.
    - `pay_to` string: Counterparty payTo.
    - `chain` 'solana' | 'base' | 'polygon'
    - `rule_id` string
    - `policy_hash` string: 0x + 64 hex of their policy blob.
    - `denied_at_unix` integer
    - `challenge_hash` string, required: 0x-prefixed lowercase SHA-256 of exact decoded 402 challenge JSON bytes, before parsing.
    - `issued_at_unix` integer, required: UNIX seconds at which the caller formed the declaration; must be within 300s of server time.
    - `resource` string, uri, required
    - `reason` 'BUDGET_EXCEEDED' | 'UNTRUSTED_MERCHANT' | 'STALE_CORPUS' | 'UNSUPPORTED_CHAIN', required
    - `payer_pubkey` string, required: Base58 Ed25519 declaration signer. No payer externality or payment claim.
    - `signature` string, required: Base58 Ed25519 signature over the domain-separated declaration.
    - `quoted_price` object: Caller-asserted offer, not independently authenticated seller pricing. Selects signed refusal V2.
      - `amount_atomic` string, required: Unsigned integer less than 2^128 in the asset's smallest units; not necessarily USDC micro-units.
      - `asset` string, required
      - `network` string, required
      - `pay_to` string, required

## Response `200`

OK (JSON).

## Other responses

- `202`: Legacy caller-local deny receipt.
- `401`: Legacy mint missing/invalid X-Twzrd-Caller (error=caller_missing). Signed-refusal bodies without that header are not this response.
- `422`: INVALID_REFUSAL_SIGNATURE or INVALID_REFUSAL_PAYLOAD.
- `429`: Rate limited; retry after Retry-After.
- `503`: Signing or persistent storage unavailable; not logged.

## Changes

- **2026-09-23** `9178eb7516cf`: 1 breaking, 2 info
  - the `header` request parameter `X-Twzrd-Caller` became required
  - the endpoint scheme security `twzrdCaller` was added to the API
  - added the non-success response with the status `401`
- **2026-09-11** `f70b341db40e`: 18 info
  - added the new optional request property `challenge_hash`
  - added the new optional request property `issued_at_unix`
  - added the new optional request property `payer_pubkey`
  - added the new optional request property `quoted_price`
  - …14 more
- **2026-09-08** `d3cc5417434e`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/twzrd/apis/twzrd-agent-reputation-rails/changes/v1/intel/refuse-receipt/post.md)

---

[API](https://skmtc.dev/twzrd/apis/twzrd-agent-reputation-rails.md) - [All operations](https://skmtc.dev/twzrd/apis/twzrd-agent-reputation-rails/llms.txt) - [OpenAPI document](https://skmtc.dev/twzrd/apis/twzrd-agent-reputation-rails/revisions/beddd4662a76?raw)
