POST /api/v1/calculate with amount, buyer_state and counterparty_id. role defaults to seller. Send role buyer for use tax. Same body as the keyed call. 10 calls a day per IP.
2
Get a free key
POST /api/v1/auth/signup with email, password, agent_name and agent_work_type. The web signup form fills agent_name and agent_work_type for you. Save the key. It is shown once.
3
Add the key
Send it as X-API-Key. You get the full response, your own nexus, transaction history and 1,500 calls a month. No card. Selling? Set your nexus states first with POST /api/v1/nexus. Until you do, seller calls skip sales tax and return tax_if_nexus, the amount you would owe.
What gets stored
Demo calls store nothing. Keyed calls are saved to your own account as transaction history. Use a throwaway counterparty_id while testing.
Step 1 — curl, no key
# No key, no signup. Paste this into a terminal.
curl -X POST https://www.agenttax.io/api/v1/calculate \
-H "Content-Type: application/json" \
-d '{"role":"buyer","amount":2500,"buyer_state":"TX",
"transaction_type":"api_access","counterparty_id":"seller_01"}'
Captured from the live API. Texas taxes 80% of data processing, so the tax is 6.25% of $2,000. taxable_base appears whenever a state taxes only part of the amount. The demo response also carries an upgrade block with the signup body. Add a key to get the audit trail, the jurisdiction breakdown and advisories.
Python SDK
pip install agenttax
Node SDK
npm install agenttax
Full example, with a key — Python
from agenttax import AgentTaxClient
client = AgentTaxClient(api_key="atx_live_YOUR_KEY")
# Use tax on a purchase (buyer side needs no nexus setup)
result = client.calculate(
role="buyer",
amount=2500,
buyer_state="TX",
transaction_type="api_access",
counterparty_id="seller_01",
)
print(result["total_tax"]) # 125.0 (TX taxes 80% of data processing at 6.25%)
print(result["confidence"]) # {"score": ..., "level": ...}
# Selling instead? Configure nexus first (POST /api/v1/nexus).
# A new account has none, so a seller call returns total_tax 0 until you do.
# Log a capital gains trade
trade = client.log_trade(
asset_symbol="COMPUTE_CREDIT",
trade_type="buy",
quantity=100,
price_per_unit=0.25,
)
With a key, one request returns the tax amount, the statute and a confidence score. The demo lane leaves out the use_tax detail, the audit trail and advisories. The free tier is 1,500 calls a month with no credit card. Upgrade anytime from your dashboard.
Authentication
Include your API key in every authenticated request.
Header format
X-API-Key: atx_live_YOUR_KEY_HERE
Also accepts Authorization: Bearer atx_live_... — Keys are SHA-256 hashed. Raw key shown once at creation.
Free
1,500/mo
Hard cutoff
Starter — $25/mo
10,000/mo
Hard cutoff
Growth — $99/mo
100,000/mo
Over limit: we contact you before billing
Pro — $199/mo
1,000,000/mo
Over limit: we contact you before billing
Keyless access (demo mode)
POST /api/v1/calculate works with no key and no payment. It is the only endpoint that does. The request body is the same, including the required counterparty_id.
Limits, per IP: 30 requests per minute and 10 per UTC day (resets at 00:00 UTC). Every request counts, including ones rejected with 400. Remaining calls are in the X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. Over either limit returns 429 RATE_LIMITED with a free-signup block and the x402 pay-per-call option.
What it returns:"mode": "demo", total_tax, combined_rate, applied_rate, classification_basis, a confidence score and level, nexus_configured_for_state, resolution and "intent": "estimate". When a $0.00 comes from a default rather than a determination it also carries exemption or tax_if_nexus with a note.
What it leaves out: the audit trail, the jurisdiction breakdown, advisories (for example the Chicago lease-tax advisory) and the sales_tax / use_tax detail. Do not treat a demo result as final without those. Seller-side demo calls use a shared demo nexus profile, not yours.
Nothing is saved to an account: demo calls do not appear in any transaction history or nexus tracking.
A key is required for the full response, your own nexus configuration, transaction history, volume above the demo limits (the free tier is 1,500 calls/month, no card), and every other authenticated endpoint. A key is free: POST /api/v1/auth/signup.
Typed resolution and estimates
Every /calculate response, keyed or keyless, carries resolution. It answers three questions on their own axes, so you can tell a confident figure from a guess.
One axis, from a Chicago seller call with no nexus set
"nexus": {
"status": "unknown",
"basis": "no_nexus_profile",
"detail": "No nexus is set for Illinois, but the Chicago city tax does not depend on it and is charged."
}
location: did a local rate answer, or only the state rate? Bases zip_local_rate, zip_not_in_db, zip_proxy, state_only, no_location.
nexus: does the figure rest on your own nexus answer? Bases configured, override, no_nexus_profile, not_applicable (buyer calls). Keyless seller calls read unknown here, because they run on a shared demo nexus profile.
taxability: did a researched rule answer? Bases category_rule, state_override, no_sales_tax, simplified_flag, fact_not_declared (the detail names the field to send), held_conservative, exemption_certificate (a certificate on file answered).
Each axis is { status, basis, detail }. status is resolved, partial or unknown. Branch on status and basis. detail is a sentence for people; never parse it. total_tax is never withheld. If you want "unknown means do not charge," branch on resolution.*.status yourself.
Quote before you charge: send "intent": "estimate" with your key. You get the same figures and the same resolution, and nothing is saved: no transaction row and no nexus revenue. An estimate still counts toward your monthly calls. Idempotency-Key is ignored on an estimate, so a paid retry is a new paid call.
Test Mode
Test mode (atx_test_ prefixed keys) is on the roadmap. Until then, test with demo calls or the free tier (1,500 calls/month, no credit card). Demo calls store nothing. Keyed calls are saved to your account as transaction history, so use a throwaway counterparty_id while you test.
Rate Limiting
Keyed /calculate calls are rate-limited per API key to 120 requests per 60 seconds. Going over returns 429 RATE_LIMITED with a Retry-After header. Using up the Free plan's 1,500 calls/month also returns 429 RATE_LIMITED, but with a "Monthly limit reached" error, an upgrade block and no Retry-After — retrying will not help until the month resets.
Response headers on /calculate
Headers
X-RateLimit-Limit: 120 # Requests allowed per 60-second window
X-RateLimit-Remaining: 117 # Requests left in the current window
X-RateLimit-Reset: 1714521600 # Unix time when the current window resets
# On burst 429 responses:
Retry-After: 2 # Seconds to wait before retrying
These headers describe the short burst window, not your monthly allowance. Monthly usage is on your dashboard. Recommended retry strategy for a burst 429: honor Retry-After, otherwise exponential backoff starting at 1 second, maximum 5 retries, jitter ±20%. Do not retry a 429 whose error says "Monthly limit reached".
Error Responses
All endpoints return errors in a consistent envelope. SDKs should branch on code (a frozen SCREAMING_SNAKE enum) rather than the human-readable error string.
Authenticated but lacks permission (cross-tenant, deactivated partner, etc.)
429
TIER_LIMIT_REACHED
Monthly optimization-report allowance for your plan used up (/optimize)
404
RESOURCE_NOT_FOUND
Entity / API key / partner / record / endpoint not found
405
METHOD_NOT_ALLOWED
Wrong HTTP method for the route
409
RESOURCE_CONFLICT
Unique-constraint violation, soft-deleted collision, optimistic-CAS lost race
409
IDEMPOTENCY_KEY_CONFLICT
Same Idempotency-Key reused with different request body
422
NEXUS_NOT_REACHED
Reserved, not currently returned. A seller call into a state with no nexus configured gets 200 with total_tax 0 and final_determination no_nexus
429
RATE_LIMITED
Burst or demo limiter tripped (see Retry-After), or the Free plan's monthly allowance is used up (no Retry-After)
500
INTERNAL
Unexpected server error — safe to retry with exponential backoff
503
DB_UNAVAILABLE
Postgres unreachable — transient; retry
Error Response Shape
{
"success": false,
"code": "INVALID_INPUT",
"error": "buyer_state is required for seller role calculations",
"request_id": "req_01HX..."
}
Tax Engine
Calculate sales tax, use tax, and 1099 obligations. Specify your role — seller gets collection obligations; buyer gets use tax exposure and seller remittance verification.
POST/api/v1/calculateAPI Key (or none: demo mode)
Calculate tax obligations. Sellers get sales tax with nexus/exemption checks. Buyers get use tax, seller remittance status, and 1099 tracking. Add buyer_zip for combined state+local rates.
POST/api/v1/calculateAPI Key
Buyer example — use tax, seller remittance verification, 1099 tracking.
GET/api/v1/transactionsAPI Key
List transaction history with tax calculations, newest first.
Gain/Loss Tracker
Track trades, manage cost basis lots (FIFO/LIFO/Specific ID), and calculate realized capital gains. Supports fractional quantities to 8 decimals — crypto, compute credits, data bundles, any tradeable AI agent asset.
POST/api/v1/tradesAPI Key
Log a buy or sell. Buys create cost basis lots. Sells match lots and compute realized gains with holding period classification.
POST/api/v1/tradesAPI Key
Sell — matches lots via FIFO and computes realized gains.
GET/api/v1/tradesAPI Key
List trades with per-asset summary stats.
Accounts & Keys
Create accounts, manage API keys, handle dashboard authentication.
POST/api/v1/auth/signup
Create a free account with agent registration. No credit card.
POST/api/v1/auth/login
Log in → session token for dashboard.
GET/api/v1/auth/meSession Token
Get the logged-in account: entity, agents, keys, this month's usage, recent transactions and trades.
GET/api/v1/keysAPI Key
List API keys (prefixes only).
POST/api/v1/keysAPI Key
Generate a new API key.
DELETE/api/v1/keysAPI Key
Revoke a key by prefix.
POST/api/v1/checkout
Stripe checkout to upgrade plan. Send either { product, tier } for one product or { tax_tier, gains_tier } for the bundle.
Configure the states you have nexus in. Sellers need this: without it, seller calculations return $0 sales tax.
GET/api/v1/nexusAPI Key
List the states you have nexus in.
Compliance
Nexus threshold monitoring, idempotency for agent retries, and 1099-DA draft exports.
POST/api/v1/calculateAPI Key
Nexus alerts — there is no separate alerts endpoint. Every keyed /calculate response carries a nexus_alerts array when your YTD revenue in any state is at 80% or more of its economic nexus threshold.
GET/api/v1/export/1099-daAPI Key
Generate a draft 1099-DA (Digital Asset Proceeds) export. Returns JSON matching IRS form fields — ready for tax software import or accountant handoff.
Idempotency Keys
AI agents frequently retry failed network calls. To prevent duplicate tax entries or double-counted trades, include an Idempotency-Key header on POST requests.
Usage
curl -X POST https://www.agenttax.io/api/v1/trades \
-H "Content-Type: application/json" \
-H "X-API-Key: atx_live_YOUR_KEY" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"asset_symbol":"ETH","trade_type":"buy","quantity":1,"price_per_unit":3000}'
# Retry with same key → returns cached response, no duplicate entry
# Response includes: X-Idempotency-Status: cached
Supported on
POST /calculate, /trades
Key TTL
24 hours
Cache header
X-Idempotency-Status
Reference Data
Public endpoints — no authentication required.
GET/api/v1/health
API status and database connectivity.
GET/api/v1/rates
Tax rates for all 50 states + DC. Filter by state.
GET/api/v1/rates/local
Combined state+local tax rate for a specific zip code. No auth required. Use buyer_zip in POST /api/v1/calculate to get this applied automatically.
POST/api/v1/verify
Submit state rates you researched; get back which ones match the engine's current-law rates.
GET/api/v1/blog
Blog articles with metadata. Filter with ?category= or fetch one post with ?slug=.