Mandates API

Unified mandate management for AP2 and ACP protocols.

Overview

Mandates are protocol-agnostic authorization tokens. The unified mandate service handles both AP2 cryptographic mandates and ACP checkout sessions through a single interface.

Create a Mandate

POST /mandates

Request Body

ParameterTypeRequiredDescription
typestringYesintent, cart, or payment
protocol_typestringYesap2 or acp
max_amountnumberYesMaximum authorized amount
currencystringNoCurrency code (default: USD)
constraintsobjectNoProtocol-specific constraints
expires_innumberNoTTL in seconds

Example

curl -X POST https://api.soft.house/mandates \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "intent",
    "protocol_type": "ap2",
    "max_amount": 1500,
    "currency": "USD",
    "expires_in": 3600
  }'

Response (201 Created)

{
  "data": {
    "id": "mnd_abc123",
    "type": "intent",
    "protocol_type": "ap2",
    "max_amount": 1500,
    "spent_amount": 0,
    "currency": "USD",
    "status": "active",
    "signature": "MEUCIQD...",
    "expires_at": "2026-01-20T11:30:00Z",
    "created_at": "2026-01-20T10:30:00Z"
  }
}

List Mandates

GET /mandates

Query Parameters

ParameterTypeDescription
typestringFilter by mandate type
protocol_typestringFilter by protocol
statusstringFilter by status
limitnumberItems per page
offsetnumberPagination offset

Get a Mandate

GET /mandates/:id

Revoke a Mandate

DELETE /mandates/:id

Revokes an active mandate. Returns 204 No Content.

Mandate Statuses

StatusDescription
activeCan be used for authorization
usedFully consumed
expiredPast expiration time
revokedManually cancelled

Protocol-Specific Fields

AP2 Mandates

AP2 mandates include cryptographic signature fields in protocol_metadata:

{
  "protocol_metadata": {
    "signature": "MEUCIQD...",
    "public_key": "MFkwEwYHKoZ...",
    "nonce": "abc123",
    "merchant_restrictions": ["merchant_a"]
  }
}

ACP Mandates

ACP mandates include Stripe session fields:

{
  "protocol_metadata": {
    "stripe_session_id": "cs_live_...",
    "payment_intent_id": "pi_...",
    "bearer_token_scope": {
      "merchant_id": "merchant_456",
      "max_amount": 10000
    }
  }
}