Challenges
Server-issued payment requirements
Your server issues a challenge to describe the payment required for a resource. Send challenges in the WWW-Authenticate header using the Payment authentication scheme.
Structure
WWW-Authenticate: Payment id="qB3wErTyU7iOpAsD9fGhJk",
realm="mpp.dev",
method="tempo",
intent="charge",
expires="2025-01-15T12:05:00Z",
opaque="eyJyb3V0ZSI6Ii92MS9zZWFyY2gifQ",
request="eyJhbW91bnQiOiIxMDAwIiwiY3VycmVuY3kiOiJ1c2QifQ"Required parameters
| Parameter | Description |
|---|---|
id | Unique challenge identifier, cryptographically bound to challenge parameters |
realm | Protection space identifier (typically the API domain) |
method | Payment method identifier (such as tempo or stripe) |
intent | Payment intent type (such as charge or session) |
request | Base64url-encoded JCS JSON with payment details |
Optional parameters
| Parameter | Description |
|---|---|
expires | ISO 8601 timestamp when the challenge expires |
description | Human-readable description of what's being paid for |
opaque | Base64url-encoded JCS JSON for server-defined correlation data |
request and opaque encoding
In HTTP headers, both request and opaque use base64url-encoded JCS JSON strings. Parse them after header processing to recover the structured values.
request object
The request parameter contains method-specific payment details encoded as base64url JCS JSON:
{
"amount": "1000",
"currency": "usd",
"recipient": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
}Servers can also attach correlation data in opaque:
{
"route": "/v1/search"
}Clients must echo opaque back unchanged when they submit a Credential.
Common fields across payment methods:
| Field | Description |
|---|---|
amount | Payment amount in base units (for example, cents for USD) |
currency | Currency code (usd) or token address (0x20c0...) |
recipient | Payment destination in method-native format |
Multiple challenges
Servers can offer multiple payment options in a single response:
HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment id="abc", method="tempo", ...
WWW-Authenticate: Payment id="def", method="stripe", ...Clients select one based on their capabilities and submit a single credential.
Challenge binding
Typical binding includes:
realm,method,intentrequestexpiresdigestopaque
For HMAC-bound IDs, the canonical input sequence is realm | method | intent | request | expires | digest | opaque. When expires, digest, or opaque is absent, use an empty string for that slot.
Use an HMAC-bound challenge ID to prevent clients from reusing a challenge ID with modified payment terms.