Payment API Overview

The Audit1 Payment API lets you collect insurance premiums from insured employers through multiple payment channels -- all from a single set of API credentials.

Who is this for?

Partners, carriers, and platforms (like billing systems) that want to programmatically collect premiums, down payments, and installments on behalf of their insureds.


Payment Methods #

Method How It Works Best For
Payment Links Generate a secure Stripe checkout URL. Send to the insured via email. Down payments, late payments, one-time charges
Subscriptions Auto-charge on a recurring monthly schedule via Stripe. Monthly installments
Direct Debits Pull funds directly from a linked bank account via ACH. PayGo collections, recurring premiums
Bank Linking Embed Plaid bank account verification in your UI. Connecting insured bank accounts securely

How It Works #

1. Authenticate with your API key (must have "payments" or "all" scope)
2. Create a payment (link, subscription, or direct debit)
3. Insured pays (clicks link, or bank debited automatically)
4. Receive webhook notification when payment completes
5. View commissions earned

Flow #

flowchart LR platform["Your Platform"] api["Audit1 Payment API
Scoped API key"] links["Payment Links
Stripe checkout"] subs["Subscriptions
Stripe recurring"] debits["Direct Debits
ACH transfers"] bank["Bank Linking
Plaid verification"] platform --> api api --> links api --> subs api --> debits api --> bank classDef primary fill:#4f39f6,color:#ffffff,stroke:#4f39f6,stroke-width:2px; class api primary

Base URL #

https://payments.audit1.com/api/v1

Note: This is the production URL (pending DNS provisioning). During development, use the Cloud Run service URL directly.

Both sandbox and production use the same URL. Your API key prefix determines the environment: - audit1_test_cli_* / audit1_test_sec_* = sandbox - audit1_live_cli_* / audit1_live_sec_* = production


Authentication #

Send your Client ID and Client Secret as headers with every request.

X-Client-ID: audit1_test_cli_a1b2c3d4...
X-Client-Secret: audit1_test_sec_f6e5d4c3...
Content-Type: application/json

Your API key must have payment scope (scope: "payments" or scope: "all"). The auth middleware explicitly filters for these scopes -- keys with only payroll scope are rejected with 401 Unauthorized.

Scope Enforcement #

API keys are validated in two layers:

  1. Auth middleware -- Verifies client_id + client_secret (bcrypt), checks the key has payments or all scope, and validates environment prefix matches key record.
  2. Tenant scope middleware -- Loads the Payment_api_clients record for the authenticated owner. This record defines allowed_carrier_ids and allowed_employer_ids. Requests for entities outside your scope return 403 Forbidden. Empty arrays = access to all (typically for platform-level integrations).

Optional HMAC Signature #

For additional security, include an HMAC-SHA256 signature with each request:

X-Signature: <hmac_sha256_hex>
X-Timestamp: <epoch_milliseconds>

Signature payload: ${timestamp}.${method}.${path}.${body}

Requests with timestamps older than 5 minutes are rejected (replay protection).

See Authentication for full details on key management, environments, and HMAC signing.


Response Format #

All responses use a consistent envelope:

{
  "ok": true,
  "data": { ... },
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 123,
    "total_pages": 3
  }
}

Errors:

{
  "ok": false,
  "error": "Bad Request",
  "message": "Required fields: employer_id, carrier_id, policy_id"
}

Rate Limiting #

Default
Limit 100 requests/minute per API key
Headers X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After
Exceeded 429 Too Many Requests with Retry-After seconds

Custom rate limits can be configured per partner via the Payment_api_clients.rate_limit field.


curl -X POST https://payments.audit1.com/api/v1/payment-links \
  -H "X-Client-ID: audit1_test_cli_your_id_here" \
  -H "X-Client-Secret: audit1_test_sec_your_secret_here" \
  -H "Content-Type: application/json" \
  -d '{
    "employer_id": "681xyz789abc123456789012",
    "carrier_id": "680abc456def789012345678",
    "policy_id": "682def789ghi012345678901",
    "premium_cents": 145000,
    "fee_cents": 5000,
    "payment_type": "ONE_TIME",
    "payment_context": "down_payment",
    "customer": {
      "name": "ACME Corp",
      "email": "billing@acme.com"
    }
  }'

Response (201 Created)

{
  "ok": true,
  "data": {
    "_id": "683abc123def456789012345",
    "stripe_payment_link_id": "plink_1abc2def3ghi...",
    "stripe_url": "https://checkout.stripe.com/c/pay/cs_a1b2c3...",
    "status": "created",
    "billing_entity_type": "employer",
    "total_cents": 150000,
    "link_amount_cents": 150000,
    "installment_plan": null
  }
}

Send the stripe_url to your insured. When they pay, you receive a payment.completed webhook.


Webhook Events #

The following events are dispatched to registered webhook endpoints:

Event Description
payment.completed Payment received successfully
payment.failed Payment attempt failed
payment.refunded Payment refunded (full or partial)
subscription.created New subscription activated
subscription.cancelled Subscription cancelled
installment.paid Installment payment received
installment.failed Installment payment failed

Next Steps #

Guide What you'll learn
1 Payment Links & Subscriptions Create, list, cancel, and refund payments
2 Direct Debits Initiate automated bank debits and batch collections
3 Bank Accounts & Linking Link bank accounts and manage debit credentials
4 Payment Webhooks Receive real-time payment event notifications