Account endpoints
Table of Contents
Register, balance, payment history, and free trial key endpoints. The account surface is API-only: no web portal, everything via HTTP. Base URL for all endpoints on this page: No auth, no body. Rate-limited per source IP. Request: empty body. Response (201 Created): The API key is returned exactly once and cannot be recovered. The funding address is a unique USDC address on Base, derived per account; incoming USDC transfers are credited to the account's balance (see billing). Errors: Bearer auth. Not billed. Request: no parameters. Response (200): Bearer auth. Not billed. Returns the onchain deposit history for the account: USDC transfers the watcher credited, most recent first. Per-call deductions are not itemized here; your current balance is on the balance endpoint. Request (query parameters): Response (200): An account is exactly: one key, one funding address, one balance. You can start without funding anything: a free trial key comes with a small starting credit and an expiry date. The barter is your email address, verified by a code. One trial key per email address and per IP address; disposable/temporary email domains are rejected. The verification code is what proves you own the mailbox - nothing is sent to the address beyond the verification mail. No auth. Rate-limited per source IP. Request: Response (200): A 6-digit code is mailed to the address. No auth. Submit the code from the mail. Request: Response (200): Smaller than the registration response on purpose: a trial holder needs the key, the grant and the expiry. No deposit address, chain or token is issued here because nothing is payable yet - top up with a registered key, or read this key's funding address from https://toll.nanotoll.dev.POST /api/v1/register
{
"api_key": "macs_00000000000000000000000000000000",
"funding_address": "0xeDfD6c7FB59c6B1dA3a3aABb30D6c96b868f0dA5",
"chain": "base",
"token": "USDC",
"credit_balance": 0.0
}429 RATE_LIMITED (too many registrations from one IP), 500 INTERNAL_ERROR.GET /api/v1/balance
{
"credit_balance": 12.50,
"funding_address": "0xeDfD6c7FB59c6B1dA3a3aABb30D6c96b868f0dA5",
"chain": "base",
"token": "USDC"
}GET /api/v1/payments
limit (optional): integer, how many records to return. Default 20, maximum 100.{
"payments": [
{
"tx_hash": "0x9e52adaf44e96394f2014201399406970299b164ba79d185e4986fede8bf5f86",
"log_index": 0,
"amount": 10.00,
"chain": "base",
"confirmations_seen": 15,
"status": "confirmed",
"created_at": "2026-10-20T14:00:00Z"
}
],
"count": 1
}status is "confirmed" or "reorged" (rare: a deposit that was orphaned from the chain).GET /api/v1/account reports key_status, derived on read: active, or expired for a free trial key past its expires_at. A paid or operator key has no expiry and is never retired - a credit_balance of 0 is an insufficient balance (HTTP 402), not a dead key. No key is ever deleted and no account is ever removed.Free trial key
POST /api/v1/trial
{
"email": "you@example.com"
}{
"message": "verification code sent",
"expires_in_minutes": 15
}POST /api/v1/trial/verify
{
"email": "you@example.com",
"code": "123456"
}{
"api_key": "macs_00000000000000000000000000000000",
"credit_balance": 0.25,
"key_type": "free",
"expires_at": "2026-11-19T00:00:00Z"
}GET /api/v1/account once you hold it. The trial key stops working at the expiry timestamp, and credit_balance shows the trial grant that was credited (the amount in this example is illustrative; the deployed grant applies).