BuildCalc API

Authentication

Bearer API keys, anti-abuse, and signup flows

API key format

API keys are 32-character base64url tokens prefixed bcapi_ (43 characters total). Pass via the Authorization header on every request:

Authorization: Bearer bcapi_<32-char-base64url-token>

Keys are hashed server-side with HMAC-SHA-256 + server pepper. The plaintext is shown only once at signup or key creation — store it in your secrets manager immediately. Lost keys cannot be recovered, only revoked + replaced.

Two signup flows

BuildCalc API supports both human and AI-agent signup. Both require a payment method on file (anti-abuse — see below).

Programmatic flow (AI agents)

POST /v1/account/signup
Content-Type: application/json

{
  "email": "[email protected]",
  "payment_method_id": "pm_..." Stripe PaymentMethod ID
}

No Turnstile required. Stripe's fraud-detection on the card-on-file is the anti-abuse layer — duplicate / fraudulent cards are rejected at customer creation time.

Browser flow (humans)

POST /v1/account/signup
Content-Type: application/json

{
  "email": "[email protected]",
  "turnstile_token": "0....",       Cloudflare Turnstile token
  "setup_intent_id": "seti_..." Stripe SetupIntent ID
}

Use Cloudflare Turnstile (free) + Stripe Elements to create the SetupIntent in the browser. Both layers required for the browser flow.

Why payment method on file from day 1

Even on the Free tier (1000 calls/mo, 10 RPM), every signup attaches a Stripe customer with a verified payment method. This blocks the bulk-signup-abuse vector without rate-limiting good-faith AI agents.

Upgrade triggers automatic Stripe billing — no second card-collection step.

Tiers + limits

TierMonthly quotaRPM limitBurstMonthly priceOverage
Free1,000 calls1020$0Hard cap (429s past quota)
Starter25,000 calls60120$49$0.04 / call past quota
Growth250,000 calls300600$249$0.02 / call past quota
EnterpriseCustom (default 10M)Custom (default 2,000)Custom$1,500+Negotiated

Pricing is set in Stripe; numbers above mirror the live Stripe products on the BuildCalc API account (TEST mode today; LIVE mode at LLC + banking formation completion).

Live tier + usage — see Usage stats below.

Idempotency

Mutating endpoints (signup, key rotation) accept an Idempotency-Key header per the IETF draft. Retry with the same key returns the cached response, making mid-network-drop retries safe.

POST /v1/account/signup
Idempotency-Key: 5f8a2c3e-...

Errors

All errors are RFC 7807 problem+json:

{
  "type": "https://docs.buildcalcapi.dev/errors/401",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Missing or invalid Authorization header. Use 'Bearer bcapi_...'.",
  "instance": "/v1/calc/concrete/yards",
  "request_id": "..."
}

Self-service billing

curl -X POST https://api.buildcalcapi.dev/v1/account/portal \
  -H "Authorization: Bearer bcapi_..." \
  -d '{"return_url": "https://example.com/dashboard"}'

Returns a Stripe Customer Portal session URL where the user can update card, view invoices, change plan, or cancel. No card data ever touches our servers.

Account management

All endpoints below take the calling key's Bearer token and act on the customer (identified by owner_email on the key). Use them from scripts, the mini-dashboard at /dashboard, or whatever client you wire up.

Usage stats

GET /v1/account/usage

curl https://api.buildcalcapi.dev/v1/account/usage \
  -H "Authorization: Bearer bcapi_..."
{
  "api_key_prefix": "bcapi_abcd",
  "tier_id": "starter",
  "period_start": "2026-05-01T00:00:00+00:00",
  "period_end": "2026-06-01T00:00:00+00:00",
  "requests_used": 4218,
  "requests_overage": 0
}

The current calendar month is the billing period. requests_overage counts calls past the tier's monthly quota — billed at the per-call overage rate on the next Stripe invoice.

List your API keys

GET /v1/account/api-keys

curl https://api.buildcalcapi.dev/v1/account/api-keys \
  -H "Authorization: Bearer bcapi_..."
{
  "keys": [
    {
      "id": "9b1c…",
      "key_prefix": "bcapi_abcd",
      "tier_id": "starter",
      "created_at": "2026-05-12T18:04:21.117892+00:00",
      "revoked_at": null,
      "last_used_at": "2026-05-18T16:01:09.482371+00:00"
    }
  ],
  "total": 1
}

Only metadata is returned — the plaintext token is never recoverable after signup or key creation. Sort order is most-recent-first.

Create another API key

POST /v1/account/api-keys

curl -X POST https://api.buildcalcapi.dev/v1/account/api-keys \
  -H "Authorization: Bearer bcapi_..." \
  -H "Idempotency-Key: $(uuidgen)"
{
  "api_key": "bcapi_<32-char-base64url>",
  "key_prefix": "bcapi_xyz1",
  "tier": "starter",
  "message": "Save your API key now. It cannot be retrieved later."
}

The new key inherits the calling customer's tier and Stripe subscription — usage on it counts against the same monthly quota. The plaintext is shown once; store it immediately. The endpoint is Idempotency-Key- aware (recommended) so retries don't create duplicate keys.

Revoke an API key

DELETE /v1/account/api-keys/{key_id}

curl -X DELETE \
  https://api.buildcalcapi.dev/v1/account/api-keys/9b1c0e6a-… \
  -H "Authorization: Bearer bcapi_..." \
  -H "Idempotency-Key: $(uuidgen)"
{ "status": "revoked", "key_id": "9b1c0e6a-…" }

Soft-revoke — sets revoked_at on the row, future requests return 401. Owner-only: revoking someone else's key returns 404. Replays via the same Idempotency-Key return the cached response. A key id can be found via GET /v1/account/api-keys above.

On this page