Documentation
Developer API
Org-scoped intelligence API for integrators — keys, quotas, portfolio reads/writes, and webhooks.
Authentication
Machine clients use org-owned API keys (not Supabase user JWTs). Create keys under Settings → Developer in the app (org owner/admin). The secret is shown once. Optionally set an expiry (for example 30 / 90 / 365 days, up to 730) at creation; expired keys are rejected like revoked ones.
- Header:
Authorization: Bearer billy_live_<prefix>_<secret> - Alias:
X-Api-Key: billy_live_… - Base path (stable forever):
/api/v1/ext
Scopes
read:portfolio— workspaces, tracked bills, diffs, summarieswrite:track— track / untrack billswrite:position— position × priorityread:events/read:watches/write:watches
New keys are read-only unless write scopes are requested at creation — choose “Read + write” in Settings → Developer, or pass scopes when creating the key via the API.
Quotas
Standard and enterprise plans include monthly API request limits (admin- provisioned). Burst limits also apply per key. Exceeding quota returns 429 with api_quota_exceeded or rate_limit_exceeded. Free plans do not include the developer API (403 api_not_enabled).
Resources
GET /api/v1/ext/workspacesGET|POST|DELETE …/workspaces/{id}/tracked-bills[/{bill_id}]PATCH …/tracked-bills/{bill_id}— position / priorityGET …/tracked-bills/{bill_id}/summaryand/diff(precomputed only)GET …/events— cursor paginationGET|POST|DELETE …/watches
Interactive OpenAPI: /docs on the API host (tag ext).
Outbound webhooks
Register HTTPS endpoints under Settings → Developer. Billy POSTs JSON when matching workspace events fan out:
- Kinds:
new_version,status_change,language_match,language_spread,summary_ready,vote_recorded,comment_deadline_soon, position/priority changes - Headers:
Billy-Signature(t=…,v1=…HMAC-SHA256 oft.body),Billy-Delivery-Id,Billy-Event - Retries with exponential backoff (up to 5 attempts)
- Compute expected = HMAC-SHA256(secret,
f"{t}.{raw_body}") - Compare to the
v1field; reject if timestamp is too old
Base URL
Production API host: https://api.billy.law. All developer routes live under /api/v1/ext on that host (same process as the product API today). The path and auth model are split-ready: a future billy-ext-api can run uvicorn proviso_api.ext_main:app and keep the same contract without client path changes.
MCP
The proviso-mcp package exposes the same contract over stdio for Cursor / Claude Desktop. Set BILLY_API_KEY and BILLY_API_BASE_URL=https://api.billy.law; tools map 1:1 to /api/v1/ext. Tracking and position tools need a key created with write scopes — read-only keys (the default) cover the read tools only.
Example
curl -H "Authorization: Bearer $BILLY_API_KEY" "https://api.billy.law/api/v1/ext/workspaces"