Skip to content
API console (try a request with your own key)Get early access

Credits

Every sheet costs 4 credits. A job reserves them for all its sheets when it is submitted, spends each sheet’s once it has been read, and refunds a sheet that could not be read - or the whole job, when its file could not be split. A job’s own credits say where it stands: perSheet, reserved, spent, refunded, and held (reserved and not yet spent or refunded).

GET /v1/account answers the balance first as sheetsRemaining: how many more drawing sheets the workspace can read now, the number a person reads (GitHub #57: sheets for people, credits for the ledger; added 2026-10-14). The credit fields stay as they were. GET /v1/account and GET /v1/workspace both answer the workspace’s balance as credits:

Property What it is
available What a new submission can reserve now: unexpired credits only.
held Reserved for jobs still being read.
spent Spent on sheets, all time.
perSheet What one sheet costs.
sheetsAvailable How many sheets available pays for: the same number as sheetsRemaining.
nextExpiry { "credits", "expiresAt" }: the soonest any available credits stop counting, and how many stop then. null when none will.

Credits can expire: a free trial’s at the trial’s end, a plan’s or a pack’s at the end of its period. They are spent soonest-expiring first, so the credits about to expire are the ones used. A submission needing more than available is refused whole with 402 not_enough_credits, and its problem says how many it needs, how many are available and where to get more (upgradeUrl: the dashboard’s Billing and credits page, which shows the workspace’s credits and sells plans and credit packs). Both endpoints state the plan as plan:

Property What it is
name starter, pro, business or scale while the workspace is on that plan (added 2026-10-14); else trial, trialEnded or none. More values may be added: treat one you do not know as a plan.
trialEndsAt When the free trial ends or ended; null when there was none.
renewsAt When the plan renews and its next month’s credits arrive; null when it is set to end, or there is no plan.
endsAt When a cancelled plan ends, at the end of the month paid for; null otherwise.
paymentFailed true while the plan’s last payment failed and Stripe is retrying it: reading continues meanwhile, and the workspace’s owner updates the card on the Billing and credits page. null when there is no plan.

GET /v1/account also states the limits this key works within as limits:

Property What it is
requestsPerMinute This key’s rate limit (Rate limits).
maximumFileSizeMegabytes The largest file a submission takes, in MB.
maximumSheetsPerFile The most sheets one file may hold.
maximumPageMegapixels The most pixels one page may hold, in millions.
retentionDays How many days after a job finishes its drawing is kept: the uploaded file, the page images and every value’s box (How long the drawing is kept).
Terminal window
curl -sS https://api.speccapture.com/v1/account \
-H "Authorization: Bearer $SPECCAPTURE_API_KEY"

Paste into a terminal with SPECCAPTURE_API_KEY set. Needs curl; scripts also use bash and jq.

GET /v1/credits/history lists every change to the workspace’s credits, newest first and a page at a time (Lists and paging): any key may read it, as any key reads the balance. Each entry has a type:

type What happened availableChange heldChange
grant Credits given: grantKind says where from - trial, plan (a plan’s month), pack, or addedBySpecCapture - with expiresAt and what of it is still unspent and counting (remaining) + 0
reservation A job’s sheets reserved when it was accepted - +
spend One sheet read: its share of the hold spent 0 -
refund A sheet that could not be read, or a whole job whose file could not be split + -
expiry A grant’s expiresAt passed with credits unspent: they stopped counting. It carries its grant’s entryId and grantKind - 0
takenBack The payment that bought a plan’s month or a pack was refunded or lost to a dispute, and its credits were taken back - never more than were still unspent (GitHub #160; docs/billing.md, “Refunds and disputes”). grantKind says which kind of grant - 0

Every entry has its entryId, the credits it moved (always more than 0), occurredAt, and its effect on the balance, so the whole history adds up: the availableChanges sum to credits.available, the heldChanges to credits.held, and the spends’ credits to credits.spent. A reservation, spend or refund names its job (jobId, fileName - null once the job was deleted - and sheetNumber for one sheet). type narrows the history to one kind of entry, and createdAfter / createdBefore to when they happened.