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 #
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:
- Auth middleware -- Verifies
client_id+client_secret(bcrypt), checks the key haspaymentsorallscope, and validates environment prefix matches key record. - Tenant scope middleware -- Loads the
Payment_api_clientsrecord for the authenticated owner. This record definesallowed_carrier_idsandallowed_employer_ids. Requests for entities outside your scope return403 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.
Quick Example: Create a Down Payment Link #
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 |