API Reference

Complete reference for the CoverPay REST API. All endpoints accept and return JSON. Every response includes a request_id for tracing and support.

Base URLs

Sandboxhttps://sandbox.coverpayme.com/v1
Productionhttps://api.coverpayme.com/v1

Authentication

Authenticate every request with a Bearer token in the Authorization header. API keys are prefixed by environment:

  • cp_test_... for sandbox
  • cp_live_... for production

All requests must include Content-Type: application/json.

bash
curl https://api.coverpayme.com/v1/bnpl/offers \
  -H "Authorization: Bearer cp_live_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{"amount": 15000, "currency": "USD"}'

BNPL Offers

Query available BNPL offers for a given purchase amount. The smart router ranks providers by availability, APR, and approval likelihood.

POST/v1/bnpl/offers

Returns ranked BNPL offers from all available providers for the given amount.

Request body

FieldTypeRequiredDescription
amountintegerYesPurchase amount in cents (e.g. 15000 = $150.00)
currencystringYesISO 4217 currency code (currently only USD)
customerEmailstringNoPre-fill customer email for faster checkout

Example request

bash
curl -X POST https://api.coverpayme.com/v1/bnpl/offers \
  -H "Authorization: Bearer cp_test_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 15000,
    "currency": "USD",
    "customerEmail": "jane@example.com"
  }'

Example response

json
{
  "request_id": "req_8f3a1b2c4d5e",
  "offers": [
    {
      "provider": "klarna",
      "plan_type": "pay_in_4",
      "installments": 4,
      "per_installment": 3750,
      "total": 15000,
      "apr": 0,
      "currency": "USD",
      "min_amount": 3500,
      "max_amount": 150000,
      "score": 92.4
    },
    {
      "provider": "affirm",
      "plan_type": "monthly",
      "installments": 12,
      "per_installment": 1336,
      "total": 16032,
      "apr": 15.0,
      "currency": "USD",
      "min_amount": 5000,
      "max_amount": 1750000,
      "score": 87.1
    },
    {
      "provider": "afterpay",
      "plan_type": "pay_in_4",
      "installments": 4,
      "per_installment": 3750,
      "total": 15000,
      "apr": 0,
      "currency": "USD",
      "min_amount": 100,
      "max_amount": 200000,
      "score": 84.6
    },
    {
      "provider": "coverpay",
      "plan_type": "pay_in_4",
      "installments": 4,
      "per_installment": 3750,
      "total": 15000,
      "apr": 0,
      "currency": "USD",
      "min_amount": 1000,
      "max_amount": 50000,
      "score": 80.2
    }
  ]
}

Checkout Sessions

Create a checkout session to redirect the customer to a specific provider's payment flow.

POST/v1/bnpl/sessions

Creates a checkout session for the selected provider. Returns a redirect URL the customer should be sent to.

Request body

FieldTypeRequiredDescription
providerstringYesProvider slug: klarna, affirm, afterpay, paypal, sezzle, zip, coverpay
orderobjectYesOrder details (see below)
order.orderIdstringYesYour internal order ID
order.totalAmountintegerYesAmount in cents
successUrlstringYesURL to redirect after successful payment
cancelUrlstringYesURL to redirect if customer cancels

Example request

bash
curl -X POST https://api.coverpayme.com/v1/bnpl/sessions \
  -H "Authorization: Bearer cp_test_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "klarna",
    "order": {
      "orderId": "order_9f8e7d6c",
      "totalAmount": 15000
    },
    "successUrl": "https://mystore.com/checkout/success",
    "cancelUrl": "https://mystore.com/checkout/cancel"
  }'

Example response

json
{
  "request_id": "req_2c4d6e8f0a1b",
  "sessionId": "sess_kl_7a8b9c0d1e2f",
  "provider": "klarna",
  "redirectUrl": "https://pay.klarna.com/checkout/7a8b9c0d1e2f",
  "expiresAt": "2026-01-30T12:30:00Z"
}

Eligibility

Verify that a customer is eligible for BNPL before showing checkout options. The eligibility pipeline checks age, residency, KYC status, sanctions, and terms acceptance.

POST/v1/checkout/verify-eligibility

Runs the full eligibility pipeline and returns pass/fail for each check.

Request body

FieldTypeRequiredDescription
userIdstringYesCoverPay user ID
amountintegerYesRequested amount in cents

Example request

bash
curl -X POST https://api.coverpayme.com/v1/checkout/verify-eligibility \
  -H "Authorization: Bearer cp_test_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "usr_9a8b7c6d5e4f",
    "amount": 15000
  }'

Example response

json
{
  "request_id": "req_3d5f7a9b1c3e",
  "eligible": true,
  "failureReasons": [],
  "checks": {
    "age": { "passed": true },
    "residency": { "passed": true },
    "kyc": { "passed": true, "status": "approved" },
    "sanctions": { "passed": true },
    "terms": { "passed": true, "version": "2026-01-15" }
  }
}

Failure reasons

When eligible is false, the failureReasons array contains one or more of: UNDER_18DATE_OF_BIRTH_MISSINGNON_US_RESIDENTKYC_NOT_STARTEDKYC_PENDINGKYC_REJECTEDKYC_EXPIREDSANCTIONS_FLAGGEDTERMS_NOT_ACCEPTEDUSER_NOT_FOUND.

POST/v1/checkout/accept-terms

Records the customer's acceptance of CoverPay legal documents. Must be accepted before a checkout session can be created.

Request body

FieldTypeRequiredDescription
userIdstringYesCoverPay user ID
documentsstring[]YesArray of accepted document types: user_agreement, privacy_policy, regulatory, third_party

Example request

bash
curl -X POST https://api.coverpayme.com/v1/checkout/accept-terms \
  -H "Authorization: Bearer cp_test_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "usr_9a8b7c6d5e4f",
    "documents": [
      "user_agreement",
      "privacy_policy",
      "regulatory",
      "third_party"
    ]
  }'

Example response

json
{
  "request_id": "req_4e6g8i0k2m4o",
  "accepted": true,
  "version": "2026-01-15",
  "acceptedAt": "2026-01-29T14:22:31Z"
}
GET/v1/checkout/terms-status/:userId

Returns the current terms acceptance status for a user.

Path parameters

FieldTypeRequiredDescription
userIdstringYesCoverPay user ID

Example request

bash
curl https://api.coverpayme.com/v1/checkout/terms-status/usr_9a8b7c6d5e4f \
  -H "Authorization: Bearer cp_test_a1b2c3d4..."

Example response

json
{
  "request_id": "req_5f7h9j1l3n5p",
  "accepted": true,
  "version": "2026-01-15",
  "documents": [
    { "type": "user_agreement", "acceptedAt": "2026-01-29T14:22:31Z" },
    { "type": "privacy_policy", "acceptedAt": "2026-01-29T14:22:31Z" },
    { "type": "regulatory", "acceptedAt": "2026-01-29T14:22:31Z" },
    { "type": "third_party", "acceptedAt": "2026-01-29T14:22:31Z" }
  ]
}

Business

Manage your business account, settings, and API keys.

POST/v1/business/register

Register a new business account. Returns an access token and the created business object.

Request body

FieldTypeRequiredDescription
emailstringYesBusiness email address
passwordstringYesMinimum 8 characters
businessNamestringYesLegal business name
websitestringNoBusiness website URL

Example request

bash
curl -X POST https://api.coverpayme.com/v1/business/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "dev@mystore.com",
    "password": "secureP@ss123",
    "businessName": "My Store Inc.",
    "website": "https://mystore.com"
  }'

Example response

json
{
  "request_id": "req_6a7b8c9d0e1f",
  "accessToken": "eyJhbGciOiJIUzI1NiIs...",
  "business": {
    "id": "biz_3e4f5a6b7c8d",
    "name": "My Store Inc.",
    "email": "dev@mystore.com",
    "website": "https://mystore.com",
    "tier": "starter",
    "createdAt": "2026-01-29T15:00:00Z"
  }
}
POST/v1/business/login

Authenticate and receive an access token.

Request body

FieldTypeRequiredDescription
emailstringYesBusiness email address
passwordstringYesAccount password

Example response

json
{
  "request_id": "req_7b8c9d0e1f2a",
  "accessToken": "eyJhbGciOiJIUzI1NiIs...",
  "expiresIn": 86400
}
GET/v1/business/me

Returns the currently authenticated user and their associated business.

Example response

json
{
  "request_id": "req_8c9d0e1f2a3b",
  "user": {
    "id": "usr_1a2b3c4d5e6f",
    "email": "dev@mystore.com",
    "role": "owner"
  },
  "business": {
    "id": "biz_3e4f5a6b7c8d",
    "name": "My Store Inc.",
    "website": "https://mystore.com",
    "tier": "growth",
    "providers": ["klarna", "affirm", "afterpay"],
    "createdAt": "2026-01-15T10:00:00Z"
  }
}
PUT/v1/business/settings

Update business settings including enabled providers, branding, and routing preferences.

Request body

FieldTypeRequiredDescription
businessNamestringNoUpdated business name
websitestringNoBusiness website URL
providersstring[]NoEnabled provider slugs
brandColorstringNoHex color for checkout branding

Example response

json
{
  "request_id": "req_9d0e1f2a3b4c",
  "business": {
    "id": "biz_3e4f5a6b7c8d",
    "name": "My Store Inc.",
    "website": "https://mystore.com",
    "providers": ["klarna", "affirm", "afterpay", "coverpay"],
    "brandColor": "#f59e0b",
    "updatedAt": "2026-01-29T16:15:00Z"
  }
}
GET/v1/business/api-keys

List all API keys for the authenticated business. Secret keys are masked after creation.

Example response

json
{
  "request_id": "req_0e1f2a3b4c5d",
  "keys": [
    {
      "id": "key_1a2b3c4d",
      "name": "Production Key",
      "prefix": "cp_live_a1b2...",
      "environment": "production",
      "createdAt": "2026-01-20T10:00:00Z",
      "lastUsedAt": "2026-01-29T14:30:00Z"
    },
    {
      "id": "key_5e6f7a8b",
      "name": "Test Key",
      "prefix": "cp_test_x9y8...",
      "environment": "sandbox",
      "createdAt": "2026-01-15T09:00:00Z",
      "lastUsedAt": "2026-01-29T12:00:00Z"
    }
  ]
}
POST/v1/business/api-keys

Create a new API key. The full secret is returned only once in the response.

Request body

FieldTypeRequiredDescription
namestringYesA label for this key
environmentstringYessandbox or production

Example response

json
{
  "request_id": "req_1f2a3b4c5d6e",
  "key": {
    "id": "key_9c0d1e2f",
    "name": "Mobile App Key",
    "secret": "cp_live_sk_7g8h9i0j1k2l3m4n5o6p7q8r9s0t",
    "environment": "production",
    "createdAt": "2026-01-29T16:30:00Z"
  }
}

Important: The secret field is only returned at creation time. Store it securely -- you will not be able to retrieve it again.

DELETE/v1/business/api-keys/:keyId

Permanently revoke an API key. This action cannot be undone. Any requests using the revoked key will receive a 401 response.

Example response

json
{
  "request_id": "req_2a3b4c5d6e7f",
  "deleted": true,
  "keyId": "key_1a2b3c4d"
}

Webhooks

Manage webhook endpoints to receive real-time event notifications. See the Webhooks Guide for payload schemas, signature verification, and best practices.

GET/v1/business/webhooks

List all webhook endpoints configured for your business.

Example response

json
{
  "request_id": "req_3b4c5d6e7f8a",
  "endpoints": [
    {
      "id": "wh_1a2b3c4d",
      "url": "https://mystore.com/webhooks/coverpay",
      "events": ["checkout.completed", "payment.success", "payment.failed"],
      "enabled": true,
      "signingSecret": "whsec_a1b2...d4e5",
      "createdAt": "2026-01-20T10:00:00Z"
    }
  ]
}
POST/v1/business/webhooks

Create a new webhook endpoint. The URL must use HTTPS.

Request body

FieldTypeRequiredDescription
urlstringYesHTTPS endpoint URL
eventsstring[]YesEvent types to subscribe to

Example response

json
{
  "request_id": "req_4c5d6e7f8a9b",
  "endpoint": {
    "id": "wh_5e6f7a8b",
    "url": "https://mystore.com/webhooks/coverpay",
    "events": ["checkout.completed", "payment.success"],
    "enabled": true,
    "signingSecret": "whsec_9x8w7v6u5t4s3r2q1p0o",
    "createdAt": "2026-01-29T17:00:00Z"
  }
}
PUT/v1/business/webhooks/:id

Update an existing webhook endpoint. You can change the URL, subscribed events, or enabled state.

Request body

FieldTypeRequiredDescription
urlstringNoUpdated HTTPS endpoint URL
eventsstring[]NoUpdated event types
enabledbooleanNoEnable or disable the endpoint

Example response

json
{
  "request_id": "req_5d6e7f8a9b0c",
  "endpoint": {
    "id": "wh_5e6f7a8b",
    "url": "https://mystore.com/webhooks/v2/coverpay",
    "events": ["checkout.completed", "payment.success", "refund.completed"],
    "enabled": true,
    "updatedAt": "2026-01-29T17:30:00Z"
  }
}
DELETE/v1/business/webhooks/:id

Permanently delete a webhook endpoint. Pending deliveries will be cancelled.

Example response

json
{
  "request_id": "req_6e7f8a9b0c1d",
  "deleted": true,
  "endpointId": "wh_5e6f7a8b"
}
POST/v1/business/webhooks/:id/test

Send a test event to the webhook endpoint to verify it is reachable and correctly processing payloads.

Request body

FieldTypeRequiredDescription
eventTypestringNoEvent type to simulate (defaults to checkout.completed)

Example response

json
{
  "request_id": "req_7f8a9b0c1d2e",
  "delivered": true,
  "statusCode": 200,
  "responseTimeMs": 142,
  "eventType": "checkout.completed"
}
GET/v1/business/webhooks/:id/deliveries

List recent delivery attempts for a webhook endpoint, including status codes and response times.

Example response

json
{
  "request_id": "req_8a9b0c1d2e3f",
  "deliveries": [
    {
      "id": "dlv_a1b2c3d4",
      "eventType": "payment.success",
      "statusCode": 200,
      "responseTimeMs": 89,
      "success": true,
      "attempt": 1,
      "deliveredAt": "2026-01-29T16:45:12Z"
    },
    {
      "id": "dlv_e5f6a7b8",
      "eventType": "checkout.completed",
      "statusCode": 500,
      "responseTimeMs": 2340,
      "success": false,
      "attempt": 3,
      "deliveredAt": "2026-01-29T15:30:00Z",
      "nextRetryAt": "2026-01-29T17:30:00Z"
    }
  ]
}
GET/v1/business/webhooks/events

List all available webhook event types you can subscribe to.

Example response

json
{
  "request_id": "req_9b0c1d2e3f4a",
  "events": [
    { "type": "checkout.completed", "description": "Customer completed checkout" },
    { "type": "checkout.abandoned", "description": "Customer abandoned checkout session" },
    { "type": "payment.success", "description": "Payment was successfully processed" },
    { "type": "payment.failed", "description": "Payment processing failed" },
    { "type": "loan.created", "description": "BNPL loan was originated" },
    { "type": "loan.completed", "description": "All installments paid, loan closed" },
    { "type": "eligibility.failed", "description": "Customer failed eligibility check" },
    { "type": "refund.initiated", "description": "Refund was initiated" },
    { "type": "refund.completed", "description": "Refund was successfully processed" }
  ]
}

Errors

CoverPay uses conventional HTTP status codes. All error responses include a machine-readableerror code and a human-readable message.

Error response format

json
{
  "request_id": "req_0c1d2e3f4a5b",
  "error": "invalid_amount",
  "message": "Amount must be a positive integer in cents.",
  "retryAfter": null
}

Error codes

HTTP StatusError CodeDescription
400invalid_requestThe request body is malformed or missing required fields.
400invalid_amountAmount must be a positive integer in cents.
400invalid_providerThe specified provider is not supported or not enabled.
401unauthorizedMissing or invalid API key.
401token_expiredThe access token has expired. Re-authenticate.
403forbiddenThe API key does not have permission for this action.
404not_foundThe requested resource does not exist.
409duplicateA resource with this identifier already exists.
422eligibility_failedThe customer did not pass eligibility checks.
429rate_limitedToo many requests. Check the Retry-After header.
500internal_errorAn unexpected error occurred on our end.
502provider_errorThe upstream BNPL provider returned an error.
503service_unavailableCoverPay is temporarily unavailable. Try again shortly.

Rate Limits

Rate limits are applied per API key and vary by subscription tier. When rate limited, the response includes a Retry-After header with the number of seconds to wait.

TierRequests / minuteRequests / dayBurst
Starter6010,00020
Growth20050,00050
Scale600200,000100
EnterpriseCustomCustomCustom

Rate limit headers are included in every response: X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset.