API Reference

Complete reference documentation for the AutopayOS REST API.

Base URLs

EnvironmentURL
Productionhttps://api.autopayos.com
Sandboxhttps://sandbox-api.autopayos.com

Authentication

All API requests require authentication using an API key in the Authorization header:

Bash
curl https://api.autopayos.com/ap2/agents \
  -H "Authorization: Bearer ak_live_your_api_key"
Key TypePrefixEnvironment
Liveak_live_Production
Testak_test_Sandbox

Intents

Create Intent

Request permission for an agent to make a purchase.

POST /ap2/intents

Request body:

JSON
{
  "agentDid": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
  "principalDid": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH",
  "request": {
    "maxAmount": 100.00,
    "currency": "USD",
    "vendorHints": {
      "domain": "amazon.com",
      "mcc": "5411"
    }
  },
  "idempotencyKey": "unique-key-123"
}
FieldTypeRequiredDescription
agentDidstringYesDID of the requesting agent
principalDidstringYesDID of the authorizing user
request.maxAmountnumberYesMaximum purchase amount
request.currencystringYesISO 4217 currency code
request.vendorHints.domainstringNoMerchant domain
request.vendorHints.mccstringNoMerchant Category Code
idempotencyKeystringNoPrevent duplicate requests

Response (approved):

JSON
{
  "allowed": true,
  "intentVc": {
    "@context": ["https://www.w3.org/2018/credentials/v1"],
    "type": ["VerifiableCredential", "IntentMandate"],
    "issuer": "did:key:z6MkAutoPayOS...",
    "credentialSubject": {
      "mandateId": "intent_abc123xyz",
      "agentDid": "did:key:z6Mk...",
      "maxAmount": 100.00,
      "currency": "USD"
    },
    "proof": { "type": "Ed25519Signature2020", "jws": "..." }
  },
  "attestation": {
    "policyId": "pol_xyz",
    "policyVersion": 3,
    "policyHash": "sha256:..."
  },
  "hpRequired": false
}

Response (denied):

JSON
{
  "allowed": false,
  "reasonCodes": ["AMOUNT_OVER_CAP", "MERCHANT_NOT_ALLOWED"],
  "details": {
    "AMOUNT_OVER_CAP": { "requested": 500, "cap": 100 }
  }
}

List Intents

GET /ap2/intents

Query parameters:

ParameterTypeDescription
statusstringFilter by status (ACTIVE, USED, EXPIRED)
agentDidstringFilter by agent
limitnumberResults per page (default: 50)
cursorstringPagination cursor

Response:

JSON
{
  "data": [
    {
      "mandateId": "intent_abc123",
      "status": "ACTIVE",
      "agentDid": "did:key:z6Mk...",
      "maxAmount": 100.00,
      "currency": "USD",
      "createdAt": "2025-12-17T10:00:00Z",
      "expiresAt": "2025-12-17T11:00:00Z"
    }
  ],
  "hasMore": false,
  "cursor": null
}

Get Intent

GET /ap2/intents/:mandateId

Response:

JSON
{
  "mandateId": "intent_abc123",
  "status": "ACTIVE",
  "agentDid": "did:key:z6Mk...",
  "principalDid": "did:key:z6Mp...",
  "maxAmount": 100.00,
  "currency": "USD",
  "merchantDomain": "amazon.com",
  "intentVc": { ... },
  "attestation": { ... },
  "createdAt": "2025-12-17T10:00:00Z",
  "expiresAt": "2025-12-17T11:00:00Z"
}

Carts

Validate Cart

Verify a cart against an intent and policy.

POST /ap2/carts/validate

Request body:

JSON
{
  "intentVc": {
    "type": ["VerifiableCredential", "IntentMandate"],
    "credentialSubject": {
      "mandateId": "intent_abc123",
      "maxAmount": 100.00,
      "currency": "USD"
    },
    "proof": { ... }
  },
  "cartVc": {
    "type": ["VerifiableCredential", "CartMandate"],
    "credentialSubject": {
      "merchant": "amazon.com",
      "items": [
        { "name": "USB-C Cable", "price": 12.99, "quantity": 2 }
      ],
      "total": 25.98,
      "currency": "USD"
    },
    "proof": { ... }
  },
  "hpProof": { ... }
}
FieldTypeRequiredDescription
intentVcobjectYesIntent Verifiable Credential
cartVcobjectYesCart Verifiable Credential
hpProofobjectNoHuman Presence proof
idempotencyKeystringNoPrevent duplicate validations

Response (approved):

JSON
{
  "allowed": true,
  "approvalToken": "apt_xyz789abc...",
  "approvalTokenExpiresAt": "2025-12-17T10:05:00Z",
  "railDecision": {
    "rail": "STRIPE",
    "reason": "Optimal for merchant capabilities",
    "merchantConnected": true
  },
  "cartHash": "sha256:abc123..."
}

Response (rejected):

JSON
{
  "allowed": false,
  "reasonCodes": ["CART_EXCEEDS_INTENT"],
  "details": {
    "CART_EXCEEDS_INTENT": {
      "cartTotal": 150.00,
      "intentMax": 100.00
    }
  }
}

Payments

Create Payment Mandate

Execute payment with approval token.

POST /ap2/payments/mandate

Request body:

JSON
{
  "approvalToken": "apt_xyz789abc...",
  "userAuthorization": "optional_signature"
}
FieldTypeRequiredDescription
approvalTokenstringYesToken from cart validation
userAuthorizationstringNoUser signature for high-value

Response:

JSON
{
  "pmVc": {
    "@context": ["https://www.w3.org/2018/credentials/v1"],
    "type": ["VerifiableCredential", "PaymentMandate"],
    "credentialSubject": {
      "mandateId": "pm_abc123",
      "intentId": "intent_abc123",
      "amount": 25.98,
      "currency": "USD",
      "merchant": "amazon.com",
      "rail": "STRIPE"
    },
    "proof": { ... }
  },
  "railResponse": {
    "rail": "STRIPE",
    "paymentIntentId": "pi_3abc123...",
    "status": "requires_capture"
  }
}

Policies

Get Current Policy

GET /ap2/policies/current

Response:

JSON
{
  "id": "pol_abc123",
  "version": 3,
  "name": "Default Policy",
  "rules": {
    "version": "2.0",
    "spend": {
      "amount_cap": 100.00,
      "currency": "USD",
      "categories": ["groceries", "electronics"]
    },
    "merchant": {
      "allow_list": ["amazon.com", "walmart.com"]
    },
    "risk": {
      "velocity_limit": {
        "max_transactions": 10,
        "time_window": "24h"
      }
    }
  },
  "hash": "sha256:def456...",
  "isActive": true,
  "createdAt": "2025-12-01T00:00:00Z"
}

Create Policy

POST /ap2/admin/policies

Request body:

JSON
{
  "name": "Shopping Agent Policy",
  "rules": {
    "version": "2.0",
    "spend": {
      "amount_cap": 200.00,
      "currency": "USD",
      "categories": ["groceries", "household", "electronics"]
    },
    "merchant": {
      "deny_list": ["casino.com"]
    },
    "context": {
      "presence": "optional",
      "presence_threshold": 100.00
    },
    "risk": {
      "velocity_limit": {
        "max_transactions": 20,
        "max_amount": 500.00,
        "time_window": "24h"
      }
    },
    "rails": {
      "allow": ["STRIPE"],
      "priorities": ["STRIPE"]
    }
  }
}

Response:

JSON
{
  "id": "pol_xyz789",
  "version": 1,
  "name": "Shopping Agent Policy",
  "hash": "sha256:abc123...",
  "createdAt": "2025-12-17T10:00:00Z"
}

Update Policy

PUT /ap2/admin/policies/:id

Simulate Policy

Test policy evaluation without creating an intent.

POST /ap2/admin/policies/:id/simulate

Request body:

JSON
{
  "request": {
    "amount": 150.00,
    "currency": "USD",
    "merchantDomain": "amazon.com"
  }
}

Response:

JSON
{
  "allowed": false,
  "reasonCodes": ["AMOUNT_OVER_CAP"],
  "evaluatedAt": "2025-12-17T10:00:00Z"
}

Agents

Register Agent

POST /ap2/agents

Request body:

JSON
{
  "name": "Shopping Assistant",
  "description": "AI-powered shopping agent",
  "capabilities": ["browse", "purchase", "compare"],
  "publicKey": "z6Mk..."
}

Response:

JSON
{
  "did": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
  "status": "ACTIVE",
  "displayName": "Shopping Assistant",
  "createdAt": "2025-12-17T10:00:00Z"
}

List Agents

GET /ap2/agents

Query parameters:

ParameterTypeDescription
statusstringACTIVE, REVOKED, SUSPENDED
limitnumberResults per page
cursorstringPagination cursor

Get Agent

GET /ap2/agents/:did

Revoke Agent

POST /ap2/admin/agents/:did/revoke

Request body:

JSON
{
  "reason": "Security concern"
}

Update Agent Velocity

PUT /ap2/admin/agents/:did/velocity

Request body:

JSON
{
  "maxTransactions": 20,
  "maxAmount": 1000.00,
  "timeWindow": "24h"
}

Evidence

Export Evidence

GET /ap2/evidence/export

Query parameters:

ParameterTypeDescription
lastnumberNumber of recent events
fromstringStart date (ISO 8601)
tostringEnd date (ISO 8601)
eventTypesstring[]Filter by event types
actorDidstringFilter by actor
formatstringjson or csv

Response:

JSON
{
  "events": [
    {
      "id": "evt_abc123",
      "seq": 1042,
      "eventType": "INTENT_ISSUED",
      "actorDid": "did:key:z6Mk...",
      "data": { ... },
      "hashPrev": "sha256:...",
      "hashCurr": "sha256:...",
      "createdAt": "2025-12-17T10:00:00Z"
    }
  ],
  "chainValid": true,
  "fromSeq": 1040,
  "toSeq": 1050
}

Search Evidence

GET /ap2/evidence/search

Query parameters:

ParameterTypeDescription
eventTypestringEvent type filter
actorDidstringActor DID filter
contextIdstringSession context ID
fromstringStart date
tostringEnd date

Get Evidence Bundle

GET /ap2/evidence/bundle/:transactionId

Response:

JSON
{
  "transactionId": "txn_abc123",
  "events": [
    { "eventType": "INTENT_ISSUED", "seq": 1042 },
    { "eventType": "CART_VALIDATED", "seq": 1043 },
    { "eventType": "PM_ISSUED", "seq": 1044 },
    { "eventType": "PAYMENT_AUTHORIZED", "seq": 1045 }
  ],
  "chainValid": true,
  "summary": {
    "agent": "did:key:z6Mk...",
    "merchant": "amazon.com",
    "amount": 38.85,
    "status": "CAPTURED"
  }
}

Verify Evidence Chain

GET /ap2/evidence/verify

Query parameters:

ParameterTypeDescription
fromSeqnumberStart sequence
toSeqnumberEnd sequence

Response:

JSON
{
  "valid": true,
  "fromSeq": 1000,
  "toSeq": 1100,
  "eventsVerified": 101
}

Human Presence

Begin Registration

POST /ap2/hp/webauthn/register/begin

Request body:

JSON
{
  "agentDid": "did:key:z6Mk...",
  "deviceName": "MacBook Pro"
}

Response:

JSON
{
  "publicKey": {
    "challenge": "base64...",
    "rp": { "name": "AutopayOS", "id": "autopayos.com" },
    "user": { "id": "...", "name": "[email protected]" },
    "pubKeyCredParams": [{ "type": "public-key", "alg": -7 }],
    "authenticatorSelection": { "userVerification": "required" }
  }
}

Complete Registration

POST /ap2/hp/webauthn/register/complete

Begin Authentication

POST /ap2/hp/webauthn/auth/begin

Complete Authentication

POST /ap2/hp/webauthn/auth/complete

Webhooks

Create Webhook

POST /ap2/admin/webhooks

Request body:

JSON
{
  "url": "https://your-server.com/webhooks/autopayos",
  "events": [
    "payment.authorized",
    "payment.captured",
    "payment.failed",
    "intent.denied"
  ],
  "secret": "whsec_your_secret"
}

List Webhooks

GET /ap2/admin/webhooks

Delete Webhook

DELETE /ap2/admin/webhooks/:id

Webhook Logs

GET /ap2/admin/webhooks/logs

Discovery

Agent Card

GET /.well-known/agent-card.json

Response:

JSON
{
  "@context": "https://schema.org/",
  "@type": "SoftwareApplication",
  "name": "AutopayOS Payment Agent",
  "capabilities": ["merchant", "payment-processor"],
  "protocols": ["ap2", "a2a"],
  "endpoints": {
    "a2a": "https://api.autopayos.com/a2a/gateway"
  }
}

Health Check

GET /healthz

Response:

JSON
{
  "status": "healthy",
  "timestamp": "2025-12-17T10:00:00Z"
}

Error Codes

HTTP CodeError CodeDescription
400BAD_REQUESTInvalid request parameters
401UNAUTHORIZEDInvalid or missing API key
403FORBIDDENInsufficient permissions
404NOT_FOUNDResource not found
409CONFLICTResource conflict
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORServer error

Policy Violation Codes

CodeDescription
AMOUNT_OVER_CAPAmount exceeds policy limit
CURRENCY_NOT_ALLOWEDCurrency not permitted
MERCHANT_NOT_ALLOWEDMerchant not on allowlist
MERCHANT_DENIEDMerchant on denylist
MCC_DENIEDMerchant category not allowed
VELOCITY_EXCEEDEDTransaction count exceeded
SPENDING_LIMIT_EXCEEDEDSpending amount exceeded
TIME_WINDOW_VIOLATEDOutside allowed time window
GEO_RESTRICTEDGeographic restriction
ANOMALY_DETECTEDUnusual pattern detected
CART_EXCEEDS_INTENTCart total over intent max
MERCHANT_MISMATCHCart merchant doesn't match intent
INTENT_EXPIREDIntent has expired
APPROVAL_TOKEN_EXPIREDApproval token has expired
AGENT_REVOKEDAgent has been revoked

Rate Limits

TierRequests/minuteBurst
Free60100
Pro300500
Enterprise10002000

Rate limit headers:

  • X-RateLimit-Limit: Maximum requests
  • X-RateLimit-Remaining: Remaining requests
  • X-RateLimit-Reset: Reset timestamp

Pagination

List endpoints use cursor-based pagination:

JSON
{
  "data": [...],
  "hasMore": true,
  "cursor": "eyJpZCI6MTAwfQ=="
}

Use the cursor in subsequent requests:

GET /ap2/intents?cursor=eyJpZCI6MTAwfQ==