Skip to navigation

Personal Access Token

Personal Access Token

A personal access token is the credential for automating your BeatAPI account. It carries your account’s permissions, so a script can read account data such as what each task or text request cost. Model, task and workflow requests still use an API key.

Personal access token or API key

Personal access tokenAPI key
Starts withnap_sk-
Use it forAccount automation, such as GET /v1/account/usage/recordsModel, task and workflow requests
How manyOne active token per accountAs many as you need
LimitsNone of its own: it has no separate model, IP or spending limitsOptional model, IP and spending limits per key
ExpiryNever expires; replace or revoke it to stop itOptional expiry per key

Create, replace or revoke it

  1. Sign in to the Dashboard and open Account security.
  2. Choose Create personal token and complete the verification step.
  3. Copy the token. The full token is shown only once; closing the window removes it from the page.
  4. Store it as a secret where your automation runs, for example in BEATAPI_PERSONAL_TOKEN.

Replace personal token issues a new token, and the previous one stops working immediately. Revoke personal token removes it, and tools that use it lose access at once. Both ask for verification. Keep the token on trusted servers: never put it in browser code, a mobile app or a shared repository.

Endpoints it can call

EndpointPurpose
GET /v1/account/usage/recordsList your billed requests, newest first
GET /v1/account/usage/records/{id}Read one record by task ID or request ID
GET /v1/usageAccount totals and breakdowns; see the Quick Guide

Send the token as Authorization: Bearer <token>. These endpoints need the usage:read permission, which the personal token includes. The two record endpoints refuse an API key with 403 forbidden; GET /v1/usage accepts either an API key or this token and returns the same summary. More account endpoints will accept this token over time.

Reconcile one task

Save data.id from the task-creation response, then look it up:

curl https://api.beatapi.io/v1/account/usage/records/task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ \
-H "Authorization: Bearer $BEATAPI_PERSONAL_TOKEN"
{
"data": {
"object": "usage_record",
"id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"type": "image",
"model": "seedream-5-pro",
"task_id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"request_id": "202610290330051234567893f9a1c2eXy7Kp2Qd",
"api_key": { "id": "1287", "title": "production", "key_prefix": "sk-Ab3d" },
"status": "succeeded",
"created_at": 1793244605,
"currency": "USD",
"credits_charged": 0.06,
"credits_refunded": 0,
"usage": { "images": 2 }
}
}

For a text request, use the request ID from the X-BeatAPI-Request-Id response header. When a text response body carries chatcmpl-<request ID> as its id, that value works as well. The request ID of a task’s creation call returns the same record as its task ID.

List usage records

curl -G https://api.beatapi.io/v1/account/usage/records \
-H "Authorization: Bearer $BEATAPI_PERSONAL_TOKEN" \
--data-urlencode "start=2026-10-01T00:00:00Z" \
--data-urlencode "end=2026-11-01T00:00:00Z" \
--data-urlencode "limit=100"
{
"data": {
"object": "list",
"data": [
{
"object": "usage_record",
"id": "20261029041512987654321b3f9a1c2eQm8Rt4Lw",
"type": "text",
"model": "deepseek-v4.1-flash",
"request_id": "20261029041512987654321b3f9a1c2eQm8Rt4Lw",
"api_key": { "id": "1287", "title": "production", "key_prefix": "sk-Ab3d" },
"status": "succeeded",
"created_at": 1793247312,
"currency": "USD",
"credits_charged": 0.002468,
"credits_refunded": 0,
"usage": { "input_tokens": 1200, "output_tokens": 350, "cached_tokens": 1024 }
}
],
"has_more": true,
"next_cursor": "eyJ0IjoxNzkzMjQ3MzEyLCJpIjo5ODc2NTQzMn0"
}
}
ParameterMeaning
startEarliest created_at to include. Unix seconds or RFC 3339, such as 2026-10-01T00:00:00Z
endExclusive upper bound, in the same formats
modelPublic model ID, such as seedream-5-pro
typeOne of text, image, video, workflow, data, realtime or other
api_key_idNumeric API key ID, as in api_key.id
limitRecords per page, from 1 to 100; the default is 20
cursorThe next_cursor of the previous page

While has_more is true, request the next page with cursor. An unknown parameter, a limit outside 1–100 or a timestamp in milliseconds is refused with 400 bad_request instead of being ignored.

The usage record

FieldMeaning
objectusage_record
idThe task ID for a task, otherwise the request ID
typetext, image, video, workflow, data, realtime or other
modelPublic model ID
task_idPresent for tasks
request_idRequest ID of the call that created the record, when known
api_keyid, title and key_prefix of the API key that paid; null for Dashboard playground use
statusqueued, processing, succeeded, failed, or refunded when the whole charge came back
created_atUnix seconds
currencyUSD
credits_chargedWhat you paid, in USD, after your discounts and any settlement; up to six decimal places
credits_refundedUSD returned to your balance
usageBillable quantities: input_tokens, output_tokens, cached_tokens and cache_write_tokens for text; images, seconds and resolution for media

A task’s amounts match usage.credits_charged and usage.credits_refunded from GET /v1/tasks/{task_id}. When a task settles above or below its reserved amount, the record shows the settled total. You can read only your own records: another account’s ID returns 404 not_found.

Errors

StatuscodeWhen
400bad_requestA query parameter is invalid
401unauthorizedThe token is missing, unknown or expired
403forbiddenAn API key was sent to a record endpoint, or the token lacks usage:read
404not_foundYour account has no record with that ID

Errors use the standard error object.