Feature availability
The API follows the business's plan. What the panel shows a business, the API lets its keys reach — no more.
API access itself
Every call first checks that the business's plan includes
api_access. If it does not, every endpoint answers 403
feature_not_enabled with details[0].feature = "api_access".
Per-resource features
Some resources also need a feature of their own. Calling one without it answers the same 403, naming the feature. Nothing is changed, and other endpoints keep working.
Response · 403
{
"error": {
"type": "feature_not_enabled",
"message": "This resource needs the \"proposals\" feature, which this business's plan does not include.",
"details": [ { "feature": "proposals" } ]
},
"meta": { "request_id": "req_b7d4c316f1c2a9e0" }
}
Features by resource
Generated from the live route table.
| Feature | Resource | Endpoints |
|---|---|---|
Client Portalclient_portal |
Projects | GET /v1/projects/{id}/portalPOST /v1/projects/{id}/portal |
Client Updatesclient_updates |
Projects | GET /v1/projects/{id}/updatesPOST /v1/projects/{id}/updatesPOST /v1/projects/{id}/updates/{update_id}/send |
Discoverydiscover |
Discoveries | GET /v1/discoveriesPOST /v1/discoveriesGET /v1/discoveries/{id}PATCH /v1/discoveries/{id}DELETE /v1/discoveries/{id}POST /v1/discoveries/{id}/proposalPOST /v1/discoveries/{id}/extractPOST /v1/discoveries/{id}/researchPOST /v1/discoveries/{id}/questions |
Newsletternewsletter |
Newsletter | GET /v1/subscribersPOST /v1/subscribersDELETE /v1/subscribers/{id}GET /v1/campaignsPOST /v1/campaignsGET /v1/campaigns/{id}PATCH /v1/campaigns/{id}POST /v1/campaigns/{id}/send |
Proposalsproposals |
Proposals | GET /v1/proposalsPOST /v1/proposalsGET /v1/proposals/{id}PATCH /v1/proposals/{id}DELETE /v1/proposals/{id}POST /v1/proposals/{id}/sendPOST /v1/proposals/{id}/regenerate-linkPOST /v1/proposals/{id}/convertPOST /v1/proposals/{id}/deposit-invoiceGET /v1/proposals/{id}/pdf |
Stripe Paymentsstripe_payments |
Coupons | GET /v1/couponsPOST /v1/couponsGET /v1/coupons/{id}PATCH /v1/coupons/{id}DELETE /v1/coupons/{id}GET /v1/coupons/{id}/usage |
Stripe Paymentsstripe_payments |
Invoices | GET /v1/invoicesPOST /v1/invoicesGET /v1/invoices/{id}PATCH /v1/invoices/{id}DELETE /v1/invoices/{id}GET /v1/invoices/{id}/line-itemsPOST /v1/invoices/{id}/line-itemsPATCH /v1/invoices/{id}/line-items/{line_id}DELETE /v1/invoices/{id}/line-items/{line_id}POST /v1/invoices/{id}/issuePOST /v1/invoices/{id}/sendPOST /v1/invoices/{id}/voidGET /v1/invoices/{id}/paymentsPOST /v1/invoices/{id}/paymentsGET /v1/invoices/{id}/pdfGET /v1/invoices/{id}/pay-link |
Endpoints not listed need only api_access.
Checking in advance
There is no separate “what can I use” endpoint: call the resource and handle
feature_not_enabled. It is safe — a refused request does nothing — and it
stays correct when a plan changes.