Skip to content
LogoLogo

Credentials

Client-submitted payment proofs

A Credential is your response to a Challenge, proving that you paid or authorized the payment. Send credentials in the Authorization header.

Structure

Authorization: Payment eyJjaGFsbGVuZ2UiOnsiaWQiOiJxQjN3RXJUeVU3aU9wQXNEOWZHaEprIiwi...

The credential is a base64url-encoded JSON object:

{
  "challenge": {
    "expires": "2025-01-15T12:05:00Z",
    "id": "qB3wErTyU7iOpAsD9fGhJk",
    "intent": "charge",
    "method": "tempo",
    "opaque": "eyJyb3V0ZSI6Ii92MS9zZWFyY2gifQ",
    "realm": "mpp.dev",
    "request": "eyJhbW91bnQiOiIxMDAwIi4uLn0",
  },
  "payload": {
    "signature": "0xabc123...",
    "type": "transaction"
  },
  "source": "did:pkh:eip155:4217:0x1234567890abcdef..."
}

The echoed Challenge keeps the original HTTP wire values. In a Credential, challenge.request and challenge.opaque remain the same base64url-encoded JCS JSON strings from the WWW-Authenticate header.

Fields

FieldDescription
challengeThe Challenge being responded to
sourceIdentity of the payer (address, DID, account ID)
payloadMethod-specific payment proof

Single-use credentials

Each credential is valid for exactly one request. When processing a credential:

  1. Verify the challenge.id matches an outstanding challenge
  2. Verify the challenge has not expired
  3. Verify the payment or proof using method-specific procedures
  4. Reject any replayed credentials

Tempo charge payload types

Tempo charge currently uses three Credential payload shapes:

payload.typeWhen the client uses itWhat the server verifies
transactionNon-zero charge in pull modeSigned Tempo transaction before broadcast
hashNon-zero charge in push modeOn-chain receipt for the submitted transaction
proofZero-amount identity flowSigned proof message over the Challenge ID with no on-chain transfer

Example

Tempo charge payment

{
  "challenge": {
    "id": "zL4xCvBnM6kJhGfD8sAaWe",
    "intent": "charge",
    "method": "tempo",
    "opaque": "eyJyb3V0ZSI6Ii92MS9zZWFyY2gifQ",
    "realm": "mpp.dev",
    "request": "eyJhbW91bnQiOiI1MDAwIiwiY3VycmVuY3kiOiJ1c2QiLCJyZWNpcGllbnQiOiIweDc0MmQzNUNjNjYzNEMwNTMyOTI1YTNiODQ0QmM5ZTc1OTVmOGZFMDAifQ"
  },
  "payload": {
    "signature": "0x1b2c3d4e5f6a7b8c9d0e...",
    "type": "transaction"
  },
  "source": "did:pkh:eip155:4217:0x1234567890abcdef1234567890abcdef12345678"
}

The server verifies the signature authorizes a transfer matching the challenge parameters, then submits the payment on-chain.

For zero-amount Tempo Challenges, the payload becomes {"type":"proof","signature":"0x..."}. The server verifies the proof against the source identity instead of broadcasting a transfer.

Learn more