What my team is entitled to
The same resolved grant as GET /v1/customers/{id}/entitlements, read by the customer’s own browser — so a front end can gate a screen without a server key in the page and without a backend of its own.
The customer is the one this request is acting inside: X-Customer-Id, or the contact’s oldest membership when the header is absent. Never a customer named in a parameter — the header identifies and the membership behind it authorizes, so an id somebody pastes in matches no membership and answers 404. Two tabs on two teams therefore stay correct, because there is no stored cursor for one to move under the other.
It needs a verified session. An anonymous session may ask and answers 404, which is true rather than a refusal: it belongs to no customer.
Authorizations
A contact session token, uk_ct_…. Belongs to one of the developer's own users, and reads only that user's data.
Headers
The customer this call is acting inside — the same arrangement as X-Organization-Id, one plane down. Switching customers is navigation, not a mutation: nothing is stored, you send a different header, and the membership JOIN behind it decides what you may do there. An id you are not a member of matches no row and answers 404. Absent, the contact's oldest membership answers.
Response
The resolved grant.
What one of your customers may do, resolved: their subscription's plan, with the overrides you promised them applied on top. This is the answer your own gate should read — the merge is done here so you never reimplement it from the pieces.
Every feature in the environment's catalogue is present, including the ones the plan does not carry, so a client can render an offer rather than an absence. A feature the plan carries and an override withholds is present and "enabled": false.
The key of the plan behind this answer. none means the customer is on no plan — never subscribed, or the only subscription is cancelled — which is a complete answer and not an error. unknown never appears in a 200: an answer nobody could resolve is a 503, not a plan.
"pro"
Always true in a 200 here. The field exists because it is false on GET /v1/organization/entitlements, where an unresolved read still has a truthful body to send — see that operation.
Keyed by your feature key, the string your own code gates on.