Appearance
Plan limits
In plain language: there is no cap on cards, and no cap on locations.
Status
Entitlement resolution, the admin grants and the kill switches described here are implemented and tested today. The API surface they gate ships with the Business API.
What the module includes
| Locations | Billed exactly as they always are — the add-on bundles none and changes none |
| Location count | Never capped, never blocked — there is no location limit and no "limit reached" error |
| Cards, card instances, holders | Uncapped |
| API keys | 10 per shop (API_KEY_MAX_PER_SHOP) — an abuse guard, raise it by asking |
| Webhooks | 50 per shop (WEBHOOK_MAX_PER_SHOP) |
| MCP keys | 5 per shop (MCP_KEY_MAX_PER_SHOP) |
The included-location count and every cap above are deployment settings shown with their defaults, not contractual figures. The price of an additional location comes from the pricing endpoint below, never from this page.
Current prices come from one place, so that a number in a document can never contradict the invoice:
bash
curl -s https://api.tesserapp.eu/api/v1/pricingExtra locations are billed, not blocked
Neither plan caps locations. There is no maximum, no "plan limit reached" error for locations, and there is deliberately never going to be one — the entitlement resolver returns "no maximum" as an explicit value so that the promise is asserted by a test rather than left to good intentions.
Locations past the included count are billed, not refused. That is the whole rule, and it is the one an integration needs to know.
Creating a location is not an API write today
The platform is pay-then-provision: a location is created server-side once the charge for it has succeeded, so it belongs to a payment flow with a payment instrument — which a server-to-server caller does not have. POST /locations is therefore not part of the API surface today, and the API can read, update, disable and enable locations but not create them.
Add locations in the dashboard. When the API route ships it will state the charge it incurred in its own response, so a CRM creating locations in a loop cannot discover the bill on the invoice — but the amount will come from the pricing service at the moment of the call, never from a number written in a document.
Cards are uncapped
There is no maximum number of cards, card instances or holders. "Unlimited cards" is not a marketing rounding — the platform has no cap to hit.
Webhooks
The widened webhook surface comes with API access; it does not need a second purchase. A shop can also be granted the webhook surface without the whole API, for the case where events are all it wants.
When access lapses
Two different things can happen, and neither destroys your credentials:
| What happened | What you get | What to do |
|---|---|---|
| The Business API add-on is no longer active for the shop, and no grant stands in for it | 401 business_api_required | Keys are suspended, not revoked — the suspension is stamped and cleared again on restore, so the same key resumes working. Nobody re-keys the CRM. |
| The subscription is suspended or cancelled (unpaid invoice) | 402 subscription_suspended on authentication, 422 in service checks | Settle it in the dashboard; the same key works immediately afterwards. Back off and alert a human — do not loop. |
Both are listed as recoverable in the error catalogue, and the reason is worth stating plainly: losing access must never cost the customer their integration wiring.
Trials and pilots
Access can be granted to a shop that is not on the integration plan — for a pilot, a migration or a proof of concept — and such a grant can carry an expiry. The dashboard warns before it lapses, precisely because a lapsing pilot would otherwise take a live integration down with it.
GET /me returns the shop's entitlements, whether each came from the plan or a grant, and when the earliest grant expires. If you build one health check into your integration, build it on that call.