Plans, tiers and usage
Every organization sits on one of three tiers. The tier decides which API calls are
allowed to produce, and it is the reason a call that worked in your colleague’s account
can return 402 in yours.
| Tier | How it is granted | What it can do |
|---|---|---|
FREE | Default for every new organization | Sign up, complete KYB, read everything it owns. Cannot produce |
STANDARD | Bought in the app by card | Create verification requests, issue credentials, mint API keys, mint identity-only organization codes |
PREMIUM_PLUS | Agreed with us and granted by hand | Standard, plus the Premium+ schemas, codes covering phone and address, direct vouchers and policies |
Entitlement is checked against one acting organization per request — not, as it once
was, against the best tier anywhere in your memberships. Name it with a
current-identity header carrying the organization’s ID; without the header, the
default is the organization you have belonged to longest. A header that is not a valid
organization ID, or names one you are not a member of, returns 403. If you belong to
several organizations, send the header — a call that used to succeed through a
better-tiered second organization now needs to name it.
What Free cannot do
Four endpoints refuse a Free organization with 402:
POST /verifications— create a verification requestPOST /credentials,POST /credentials/with-recipient,POST /credentials/importPOST /integrations/keys— mint an API key
{
"error": "This action needs a paid plan. Contact our team to upgrade.",
"code": "UPGRADE_REQUIRED",
"tier": "FREE"
}
Key off code, not the message text.
Minting an organization code also needs a paid plan, though it refuses with 403 organization is not on a plan that can issue codes rather than 402.
Everything else stays open: reading, listing, KYB, organization management, and — this is
deliberate — running verifications that already exist. POST /verifications/individuals is not gated, so a change of tier will never break a person
who is mid-flow. What a Free organization cannot do is create new verification requests or
new API keys.
Premium+ and assurance
Some schemas are marked as requiring Premium+ — the Socious Verified assurance schema carrying liveness, proof of address and mobile number verification is the one you are likely to meet. Creating or updating a verification against such a schema from a non-Premium+ organization returns:
{ "error": "`Socious Verified — Premium+` requires a Premium+ organization" }
with 403, not 402: this is not something a card fixes, it is a scope agreed with us.
Premium+ is custom-priced and granted by hand on purpose — there is no price to put behind a button, so there is no button.
Reading your usage
curl https://api.shinid.com/organizations/ORG_ID/usage \
-H "Authorization: Bearer SESSION_TOKEN"
{
"plan": "STANDARD",
"quota": 2000,
"period": { "start": "2026-04-01T00:00:00Z", "end": "2027-04-01T00:00:00Z" },
"period_kind": "term",
"usage": {
"verifications_completed": 42,
"credentials_issued": 7,
"verifications_completed_total": 613,
"credentials_issued_total": 88,
"verification_requests": 5,
"members": 3,
"verifications_via_code": 51,
"verifications_via_code_total": 60
},
"overage": { "count": 0, "included": 2000, "billable": false },
"history": [
{ "month": "2026-07", "verifications_completed": 120, "credentials_issued": 12,
"verifications_via_code": 130 }
]
}
Things to read carefully:
- The period is your contract term where one was agreed —
period_kind: "term", default twelve months — and the calendar month in UTC ("month") where none was. The allowance is contracted per term, so metering it monthly would misread a burst (a governance vote, an onboarding week) that the annual number comfortably covers. quotaisnullwhen no allowance was agreed. That means “not tracked here”, not “zero” and not “unlimited”.verifications_via_codecounts the runs your organization covered through its codes and vouchers. It is the counter your quota and overage are measured against, because it is the one with an authoritative organization-to-verification link behind it.verifications_completedis counted across your organization’s members, because a verification belongs to the user who created it. A person in two organizations counts toward both — which is exactly why it is not the billing counter.
verifications_completed counts individuals that reached VERIFIED. Failed and abandoned
runs are not counted.
Running out of quota
Exceeding the allowance never blocks a verification. At the cap the run is served and
the excess is counted in overage — count beyond included, with billable set —
and an invoice is raised from that number; nothing charges automatically. The one
exception is a runaway guard several multiples above the quota, which exists to stop an
unbounded leak, not to meter normal overage.
Billing state
GET /organizations/{id}/billing/subscription returns the Stripe subscription backing a
self-serve plan, or null where the tier was granted by hand — the normal case for
Premium+.
Standard is bought in the app: POST /organizations/{id}/billing/checkout opens a Stripe
Checkout session and returns its URL. It grants nothing on its own. The tier is applied by
the Stripe webhook, because the success redirect is under the browser’s control and so
proves no payment — worth knowing if you are watching for the upgrade to land, since it
arrives moments after the redirect rather than with it. Poll
GET /organizations/{id}/usage and read plan.
POST /organizations/{id}/billing/portal opens Stripe’s hosted portal to change a card,
download invoices or cancel. It returns 409 when the organization has never paid —
“you have no billing account” is a state, not a missing resource.