Skip to main content

Recording Custom Service Usage by API

When you sell your own custom service to your clients through a SaaS plan (for example "Resume Scans"), every client sub-account on the plan gets its own allowance of it. If the work behind that service runs in your own app, your app tells each time a client used it, with your own API key:

  • Record usage takes units off one client sub-account's allowance of the service.
  • Reverse usage gives back a usage event you recorded earlier, for example when the work is undone or failed.

Only the client sub-account you name is billed. Your own account and your other sub-accounts are not touched.

Before You Start​

  • An API key of your own account. Create one at app.votel.ai/settings/api-keys and send it in the X-API-Key header. The key needs edit access to Sub-Accounts (an owner's key has it).
  • The sub-account's id. It is the tenant_id of each sub-account GET /api/sub_account lists.
  • The service identifier. Every custom service has a slug, such as custom_c8a4a91e_resume_scans_dc7002b9ee8b. It is the service_slug of the service in GET /api/sub_account/{sub_account_id}/service-meters.
  • The service is on the sub-account's plan, so the sub-account has an allowance of it, and the sub-account is active.

Record Usage​

POST https://app.votel.ai/api/sub_account/{sub_account_id}/service-meters/{service_slug}/usage
FieldRequiredWhat it is
event_idYesYour own unique id for this piece of usage: your order, job or analysis id, up to 200 characters. Sending the same id again never charges again.
unitsNoHow many units this event used, from 1 to 10,000. Default 1.
descriptionNoA short note shown on the sub-account's billing activity.
curl -X POST "https://app.votel.ai/api/sub_account/01a60203-2cde-4ebe-95e0-7d87e8ba43d8/service-meters/custom_c8a4a91e_resume_scans_dc7002b9ee8b/usage" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"event_id": "analysis-58213", "units": 1}'
{
"event_id": "analysis-58213",
"sub_account_id": "01a60203-2cde-4ebe-95e0-7d87e8ba43d8",
"service_slug": "custom_c8a4a91e_resume_scans_dc7002b9ee8b",
"status": "recorded",
"replayed": false,
"units": 1,
"free_units": 1,
"paid_units": 0,
"amount_charged": 0.0,
"units_reversed": 0,
"amount_refunded": 0.0,
"included_units": 1000,
"included_units_remaining": 999,
"total_usage": 1
}

How the Units Are Counted​

  1. The included allowance first. Each unit comes off the allowance your plan gives the sub-account (included_units) until none is left (included_units_remaining).
  2. Then overage, if the service allows it. When the service is set to bill overage on the sub-account, each extra unit is charged to the sub-account's wallet at the service's price for that sub-account. The answer shows those units in paid_units and the money in amount_charged.
  3. Refused when it does not. When the service denies overage and the allowance is used up, or the sub-account's wallet cannot pay, nothing is recorded and the call is refused (see Errors). You can send the same event_id again once the problem is solved.

An unlimited allowance answers null for included_units and included_units_remaining.

Retries Never Charge Twice​

The event_id is what makes a retry safe. If your request times out, send it again with the same event_id:

  • If the first request already recorded the event, nothing more is charged. The answer is the first recording, with "replayed": true.
  • If the first request was refused, nothing was recorded, so the retry is charged normally.
  • If the first request is still running, the retry is refused with 409 and nothing is charged. Wait a few seconds and send it again.

An event_id belongs to one sub-account and one service. Use a new id for every new piece of usage.

Reverse Usage​

POST https://app.votel.ai/api/sub_account/{sub_account_id}/service-meters/{service_slug}/usage/reverse

Send the event_id the usage was recorded with:

curl -X POST "https://app.votel.ai/api/sub_account/01a60203-2cde-4ebe-95e0-7d87e8ba43d8/service-meters/custom_c8a4a91e_resume_scans_dc7002b9ee8b/usage/reverse" \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"event_id": "analysis-58213"}'

A reversal gives back everything the event still holds:

  • Units that came from the included allowance go back to it.
  • Overage the event paid is refunded to the sub-account's wallet, at the price it paid.

The answer has the same fields, with "status": "reversed", the units given back in units_reversed and the money in amount_refunded. Reversing the same event again changes nothing and answers "replayed": true.

There is no partial reversal. To correct a count, reverse the event and record the right count under a new event_id.

Errors​

StatusWhenWhat to do
402The sub-account's wallet cannot pay the overage.The sub-account adds funds, then send the same event_id again.
403The account is not one of your sub-accounts, the service is not a custom service your account created, the service is used up and denies overage, or the service is off for the sub-account.Check the ids. To allow more usage, change the service's limit for the sub-account.
404The sub-account was not found, it has no allowance of the service, or (on a reversal) no usage was recorded with that event_id.Check the ids and that the sub-account's plan includes the service.
409The same event_id is being recorded right now, or the sub-account is not active.Wait a few seconds and retry, or reactivate the sub-account.
422event_id is missing or blank, or units is out of range.Fix the request.
503The usage could not be recorded right now. Nothing was charged.Retry in a minute with the same event_id.