Aventora Engagement Hub — Billing API
This guide is for platform partners who use Aventora Engagement Hub on behalf of end customers and bill those customers directly. You can assign a billing plan and add top-ups for existing Hub accounts through the REST API.
Everything in this document is server-to-server. Store API keys only on your backend.
Partners cannot create Hub billing accounts. Accounts are provisioned by Aventora when a customer workspace is set up (CRM + Hub auto-provision). Identify each customer by workspace admin email, resolve account_id once, then configure billing.
What you will receive from Aventora
Before integrating, confirm you have:
| Item | Description |
|---|---|
| Hub base URL | Your Engagement Hub API host (e.g. https://phone.aventora.ai). No trailing slash. |
| Partner billing key | Secret key with billing permissions (see Authentication). Not the per-tenant engagement key used for /start. |
| CRM provisioning secret | For creating customer workspaces via CRM provisioning (POST /auth/provision/workspace). |
You do not need a domain slug or account_id upfront. Use the workspace admin email from CRM (see Account resolution).
Authentication
Every request uses your partner key as a Bearer token:
Authorization: Bearer <partner_api_key>
Content-Type: application/json
Invalid or missing keys return 401 Unauthorized. Missing permissions return 403 Forbidden.
Required permissions
| Permission | Used for |
|---|---|
account_management | Look up account by email, read billing plan |
api_key_management | Set billing plan, quota top-ups |
billing_management | Credit top-ups (by account_id or email), read account by ID |
Keys with admin or * include all permissions. For full partner billing, request account_management, api_key_management, and billing_management (or a single key with admin / *).
Do not use tenant engagement keys (call_management only) for billing operations — they cannot change plans or top up balance.
Recommended workflow
Typical flow when you create CRM workspaces and bill customers:
Your platform CRM Engagement Hub
| | |
| POST /auth/provision/workspace |
| adminEmail = customer owner |
|--------------------------->| workspace created |
|<---------------------------| workspaceId, adminEmail |
| | |
| (wait ~1–2 min; CRM auto-provision creates Hub account) |
| |------------------------------->|
| |
| GET /accounts/email/{adminEmail} |
|------------------------------------------------------------>|
|<--------------------------- account_id --------------------|
| (store in your DB) |
| PUT /accounts/{account_id}/billing-plan |
| PATCH credits or allowance-quotas |
|------------------------------------------------------------>|
After billing is configured, use the Engagement Hub Start API with the tenant's engagement API key and domain_name.
Account resolution (by email)
Partners identify billing accounts by email — the workspace admin email passed to CRM when creating the customer (adminEmail on POST /auth/provision/workspace or POST /auth/provision/resolve).
When Hub auto-provision completes, the Hub accounts row uses that same email. You do not need a domain slug, CRM workspaceId, or CRM adminUserId for billing lookup.
Default billing for new partner workspaces: When CRM auto-provision creates the Hub account, the platform sets pay-as-you-go + credit, 100 welcome credits (configurable via PARTNER_CRM_INITIAL_CREDITS / DEFAULT_INITIAL_CREDITS on Hub), and platform default engagement rates. Partners can change the plan later via the Billing API.
Step 1 — Create workspace (CRM)
POST {CRM_API_URL}/auth/provision/workspace
Authorization: Bearer {CRM_PROVISIONING_SECRET}
Content-Type: application/json
{
"adminEmail": "owner@customer.com",
"adminFirstName": "Jane",
"adminLastName": "Owner",
"subdomain": "acme",
"displayName": "Acme Corp"
}
Save adminEmail — this is your billing lookup key. Wait until Hub wiring is ready (poll GET /auth/provision/workspaces until hubConnected: true, or wait ~1–2 minutes after create).
Step 2 — Resolve account_id (Hub)
Most billing endpoints require account_id (UUID). Resolve it once by email, then store it in your database (keyed by workspaceId or adminEmail).
GET /accounts/email/{email}
Look up the Hub billing account for the workspace admin email.
Auth: account_management (or admin / *)
URL: {HUB_BASE_URL}/accounts/email/{email}
Use the same email as CRM adminEmail (Hub matches case-insensitively).
Example request:
GET /accounts/email/owner@customer.com
Authorization: Bearer <partner_api_key>
Example response:
{
"account": {
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"email": "owner@customer.com",
"external_user_id": "42",
"domain_name": "acme",
"credits_balance": 100
},
"billing": {
"credits_balance": 100,
"is_suspended": false
}
}
Use account.account_id for plan updates and quota top-ups.
404 — Hub account not found yet. Auto-provision may still be running; retry after a short delay. Do not call POST /accounts/register.
Step 3 — Billing operations
| Operation | Endpoint | Needs account_id? |
|---|---|---|
| Read plan | GET /accounts/{account_id}/billing-plan | Yes |
| Set plan | PUT /accounts/{account_id}/billing-plan | Yes |
| Credit top-up | PATCH /accounts/{account_id}/credits | Yes |
| Quota top-up | PATCH /accounts/{account_id}/allowance-quotas | Yes |
| Credit top-up by email | POST /accounts/credits/add | No — email in body |
Credit top-ups without storing account_id
POST /accounts/credits/add accepts { "email": "owner@customer.com", "amount": 500 } with billing_management only. Useful for payment webhooks. The response includes account_id — store it for plan and quota calls. See Top-up by email.
Confirm a cached account_id
GET /accounts/{account_id} — Auth: billing_management
Identifiers partners should not use
| Identifier | Why not |
|---|---|
CRM adminUserId | CRM user UUID — not Hub external_user_id |
CRM workspaceId | No Hub lookup by workspace ID |
| Domain slug / subdomain alone | No partner Hub API by domain; use email |
GET /accounts/by-external-user/{id} | Domain-chatbot user ID only — not for typical partner integrations |
Account creation (not available to partners)
POST /accounts/register is platform provisioning only. Partner keys receive 403 Forbidden.
Billing plans
Each account has a payment plan and an accounting mode. Partners may set payg or subscription only.
| payment_plan | Meaning |
|---|---|
payg | Usage consumes balance or quotas; you top up as the customer pays you |
subscription | Periodic allowance (monthly or annual) with optional top-ups above the cap |
| accounting_mode | Meaning |
|---|---|
credit | Rate-based credit balance; each engagement deducts credits by type |
allowance | Unit quotas per category (one unit per SMS/call/email/bot response, etc.) |
Free and trial accounts
payment_plan: free is not available through the partner API. Trial and demo accounts are assigned by Aventora super admins only. Contact Aventora if a customer needs a free or trial plan.
Read billing plan
GET /accounts/{account_id}/billing-plan
Auth: account_management (or admin / *)
Example response:
{
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"payment_plan": "payg",
"accounting_mode": "credit",
"subscription_period": "monthly",
"credit": {
"balance": 250.0,
"grace": 10,
"subscription_limit": 0,
"subscription_used": 0,
"subscription_remaining": 0
},
"allowance_quotas": {
"engagement": { "limit": 0, "used": 0, "remaining": 0 },
"outbound_email": { "limit": 0, "used": 0, "remaining": 0 },
"inbound_call": { "limit": 0, "used": 0, "remaining": 0 },
"chatbot": { "limit": 0, "used": 0, "remaining": 0 }
},
"billing_plan": { }
}
Set billing plan
PUT /accounts/{account_id}/billing-plan
Auth: api_key_management
Allowed payment_plan values: payg, subscription only.
Body fields (all optional; send only what you are changing):
| Field | Type | Description |
|---|---|---|
payment_plan | string | payg or subscription |
accounting_mode | string | credit or allowance |
subscription_period | string | monthly or annual (subscription plans) |
subscription_credit_limit | number | Credit cap per period (subscription + credit) |
allowance_quotas | object | Quota limits per pool (subscription + allowance) |
reset_subscription_period | boolean | Reset period counters when changing plan |
Quota pool keys (under allowance_quotas.{pool}.limit):
| Pool | Covers |
|---|---|
engagement | Outbound SMS, phone, WhatsApp |
outbound_email | Outbound email sends |
inbound_call | Inbound phone engagements |
chatbot | Chatbot responses |
Example: pay-as-you-go with credits
{
"payment_plan": "payg",
"accounting_mode": "credit"
}
Example: subscription with monthly credit cap
{
"payment_plan": "subscription",
"accounting_mode": "credit",
"subscription_period": "monthly",
"subscription_credit_limit": 5000
}
Example: subscription with unit quotas
{
"payment_plan": "subscription",
"accounting_mode": "allowance",
"subscription_period": "monthly",
"allowance_quotas": {
"engagement": { "limit": 500 },
"outbound_email": { "limit": 200 },
"inbound_call": { "limit": 100 },
"chatbot": { "limit": 1000 }
}
}
Success response:
{
"success": true,
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"billing_plan": { }
}
Top-ups
Credit top-up — PATCH /accounts/{account_id}/credits
Use when accounting_mode is credit and plan is payg or subscription.
Auth: billing_management
Body:
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Credits to add (positive or negative adjustment) |
description | string | No | Reason shown in records, e.g. "Customer payment March 2026" |
Example:
{
"amount": 500,
"description": "Monthly credit purchase"
}
Example response:
{
"success": true,
"amount_added": 500,
"description": "Monthly credit purchase",
"account": {
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"credits_balance": 750
}
}
Quota top-up — PATCH /accounts/{account_id}/allowance-quotas
Use when accounting_mode is allowance.
Auth: api_key_management
Body:
| Field | Type | Required | Description |
|---|---|---|---|
quota_type | string | Yes | engagement, outbound_email, inbound_call, or chatbot |
amount | number | Yes | Units to add to the pool limit |
description | string | No | Optional note |
Example:
{
"quota_type": "engagement",
"amount": 100,
"description": "Extra SMS/call bundle"
}
Example response:
{
"success": true,
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"quota_type": "engagement",
"amount_added": 100,
"billing_plan": { }
}
Quota top-ups are rejected when accounting_mode is not allowance or when the plan is free.
Top-up by email — POST /accounts/credits/add
Add credits when you have the workspace admin email but not account_id (e.g. Stripe webhook, or before first lookup).
Auth: billing_management
Body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Workspace admin email (same as CRM adminEmail) |
amount | number | Yes | Positive credit amount |
description | string | No | e.g. "Stripe checkout" |
Example:
{
"email": "owner@customer.com",
"amount": 200,
"description": "Stripe checkout"
}
Example response:
{
"success": true,
"account_id": "550e8400-e29b-41d4-a716-446655440000",
"email": "owner@customer.com",
"credits_added": 200,
"new_balance": 450,
"description": "Stripe checkout"
}
The response includes account_id — store it for subsequent plan or quota calls. This endpoint does not replace email lookup for PUT /billing-plan or quota top-ups.
Error responses
| Status | Meaning | Typical cause |
|---|---|---|
| 400 | Bad request | Invalid plan/mode, missing required field, wrong accounting mode for top-up |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Insufficient permissions; payment_plan: free rejected for API keys; POST /accounts/register rejected for partner keys |
| 404 | Not found | Unknown account_id; email not found (Hub not provisioned yet — retry) |
| 402 | Payment required | Returned by Start API when customer balance is exhausted (not on billing endpoints) |
Example 403 (free plan):
{
"detail": "Setting a free billing plan requires super-admin authentication"
}
Example 403 (account register):
{
"detail": "Creating Hub billing accounts is restricted to platform provisioning. Partners may configure existing accounts (billing plan, top-ups) only."
}
Audit trail
Plan changes, subscription period renewals, and top-ups made through this API are recorded in the Hub billing ledger with change_source: api. Aventora super admins can review the full history (including super-admin UI changes and automatic period rollovers) in Domains → Manage → Pricing → Billing history. Partner keys cannot read the ledger; contact Aventora for accounting exports if needed.
End-customer experience
Your customers see balance and usage in Aventora Admin → Billing. See Engagement Hub Billing for the UI-oriented guide (no API details).
Related documentation
- CRM Laravel integration — create workspaces (
adminEmailis your billing key) - Engagement Hub Start API — start outreach after billing is configured
- Platform API Keys — how admin and tenant keys fit the platform
- API Security Model — authentication overview across services