Tenancy and access
Collaterate is multi-tenant. A site is the unit of tenancy, and your partner record carries a set of granted site ids. Everything this API returns is filtered to that set.
Your grant
Section titled “Your grant”Grants are configured by Collaterate, per environment, and are not something you can inspect
indirectly or extend yourself. The authoritative view of your own grant is GET /v1/me:
{ "partnerId": "1", "partnerName": "Acme", "grantedSiteIds": [7, 8], "authMethod": "COGNITO_M2M", "scopes": ["partner-api/orders:read"]}grantedSiteIds is never empty for a working credential. A partner with no granted sites
cannot authenticate at all - see
when authentication fails.
Two distinct things control what you may do, and it is worth keeping them apart when debugging:
| Concept | Question it answers | Where you see it | Failure looks like |
|---|---|---|---|
| Grant | Which sites’ data? | grantedSiteIds |
404 on an order, or 400 invalid_site_id on a filter |
| Scope | Which operations? | scopes |
403 insufficient_scope |
How scoping is enforced
Section titled “How scoping is enforced”Site scoping is applied when the query is built, on every read, unconditionally. There is no code path in this API that can construct a query without it, and no parameter you can send that relaxes it. A row belonging to a site outside your grant is not filtered out of a response - it never leaves the database in the first place.
Two consequences follow, and both are visible to you:
Filtering by siteId narrows, it never widens. If you pass a siteId that is in your
grant, you get that site’s orders. If you pass one that is not, you get a 400 invalid_site_id. The parameter is never silently ignored, which would quietly widen the
result back to all of your sites and give you a different answer than the one you asked for,
and it never returns an empty page, which would be indistinguishable from a legitimate site
with no orders.
Some orders are excluded from every response. Orders that Collaterate does not mark as live - test and internal orders - are never returned to partners, regardless of grant. This is not configurable and there is no parameter to include them.
404, never 403
Section titled “404, never 403”GET /v1/orders/{orderNumber} returns the same 404 order_not_found for an order number
that was never issued and for an order that exists in a site you are not granted.
This is deliberate and permanent. Because a row outside your grant never comes back from the
database, the service genuinely cannot distinguish the two cases - and it must not try, since
confirming that an order exists somewhere you cannot see is itself a disclosure. Returning
403 here would let anyone holding any credential enumerate valid order numbers across the
whole platform.
When a change to your access takes effect
Section titled “When a change to your access takes effect”On your next request. Your partner record, your grants and your capabilities are looked up fresh on every call rather than being baked into your credential.
This has a practical consequence in both directions:
- A new site added to your grant is visible immediately. You do not need a new token, and a token you already hold picks up the new site on its next use.
- Access removed is gone immediately, for the same reason. There is no window in which an already-minted token keeps working against a site you no longer have.
The one exception is mutual TLS offboarding: removing a certificate from the truststore takes several minutes to propagate through the edge, though the partner record change itself is immediate and the credential stops resolving right away.
Site ids
Section titled “Site ids”Site ids are integers, stable, and assigned by Collaterate. You get yours from
GET /v1/me, and every order carries its own in the siteId field so you can attribute a
result from an unfiltered list.
There is no endpoint in v1 that lists sites beyond your own grant, and there is no way to discover whether a given site id exists. A site id you are not granted behaves identically to one that was never issued.
What is recorded
Section titled “What is recorded”Successful reads are audited. The record holds who called, which endpoint, which sites were in the grant at the time, how many rows were returned, and the request id. It does not hold order contents - copying the data into a second store would double the exposure surface and buy nothing.
Requests that returned an error are not audited as accesses, because they read nothing.
Not scoped
Section titled “Not scoped”GET /v1/ping has no authentication and therefore no tenancy. It reports whether the service
is reachable and nothing about you or your data. It is the one endpoint here that behaves
identically for everyone.