Skip to content
Logo

Orgs

An org is the tenant. Customers, API keys, KYB submissions, quotes, and orders all hang off an org. A user can belong to one or more orgs. The common case is one. Multi-org users get a "Switch org" UI on the dashboard. Multi-org API callers mint a separate key per org.

Endpoints

Org

Members

Compliance email

The org's compliance contact address and its verification flow. Required when the org is created; these endpoints change it afterwards. See the compliance-email index for details.

KYB

The unified KYB profile + state. See the KYB index for the schema and per-endpoint pages.

Auth + scoping

Endpoints accept either an Api-Key: <key> header (org-scoped key, recommended for automation) or Authorization: Bearer <access-token> (dashboard session). Sending both at once returns 400 BothCredsProvided. See Auth for the full model.

The URLs encode the scope:

  • /orgs (plural): the caller's set of memberships. Listing + creation. With an API key, the listing enumerates the orgs the minting user belongs to.
  • /org (singular): the current org. Whichever org the credential is scoped to.
    • With an API key: the org the key was minted in. Permanent. Keys don't switch context.
    • With a dashboard session: see "Picking an org" below.

There's no /orgs/{id}/... form. You don't pass an explicit id in the path.

Picking an org (dashboard sessions)

A bearer token represents a user, not an org. The JWT claim is sub: <user_id>, with no embedded org id. Switching orgs does not require a new token. Pass the org id on the URL:

GET /v0/org?org=0a2a7e3c-...

If ?org= is omitted and you belong to exactly one org, the server picks it automatically. With more than one active membership the request is rejected (400, message "multiple org memberships: pass ?org=<id>"), so multi-org users must always pass ?org=.

If the supplied org id isn't one the caller belongs to, the response is 404 OrgNotFound. If the user has no active memberships at all, same code, message "no active org membership". See POST /orgs to bootstrap.

API keys do not accept ?org=. A key is bound to one org at mint time. The param is silently ignored. Mint a separate key per org instead.

Types

Org

FieldTypeNotes
idstring (UUID)Our id.
namestringDisplay name.
kyb_statusKybStatusCurrent KYB outcome. Rich state (link, missing fields, …) lives at GET /org/kyb/state.
compliance_emailstring, nullableCompliance contact address for the org, if set. May be awaiting verification. See compliance_email_verified.
compliance_email_verifiedbooleantrue once the org has proven control of compliance_email.
slack_channelstring, nullableSlack channel this org receives changelog updates in. null until one is set.
expired_quote_tolerance_bpsintegerDefault expired-quote tolerance, in basis points (0–500), for accepts that don't set their own. Starts at 1.
created_atstring (ISO-8601)
updated_atstring (ISO-8601)

OrgMembership

FieldTypeNotes
org_idstring (UUID)
user_idstring (UUID), nullablenull for pending invitations. The invitee doesn't have a Seismic user yet (or hasn't accepted). Becomes a real id once they sign up + accept.
invitation_idstring (UUID), nullableInverse of user_id: set on pending rows, null on active members. Drives DELETE /v0/org/invitations/{id}. Exactly one of (user_id, invitation_id) is non-null.
emailstringMember's email, denormalized for list views.
roleOrgRoleSee below.
created_atstring (ISO-8601)

OrgRole

A string enum: one of "owner", "admin", "member", "viewer". Every org must have at least one owner at all times. A demote or remove that would leave the org with zero owners returns 409 LastOwner.

ActionOwnerAdminMemberViewer
Read org, members, KYB, customers, orders✓✓✓✓
Mint / list / revoke API keys✓✓✓
Run quotes, accept quotes✓✓✓
Create end-user customers + accounts✓✓✓
Edit KYB profile, submit KYB, refresh state✓✓
Invite / remove members✓✓
Billing✓✓
Change roles (incl. promoting / demoting other owners)✓
Delete org✓

Admins can change roles between member ↔ viewer only. Anything that touches admin or owner is owner-only.

KybStatus

A string enum: one of "draft", "submitted", "under_review", "approved", "rejected", "terminally_rejected", "paused", "unknown".

ValueMeaning
draftKYB profile is editable and not yet submitted.
submittedProfile sent. Review hasn't begun yet.
under_reviewVerification is in progress.
approvedOrg is cleared for live activity.
rejectedVerification was rejected: correct the profile and submit again to re-verify. See rejection_reason on the KybState.
terminally_rejectedVerification was declined in a way that can't be corrected and resubmitted (e.g. a fraud or risk decision). The profile can still be edited and saved, but never resubmitted. Contact support.
pausedSeismic has placed a compliance hold on the org. It cannot transact, and resubmitting the profile does not lift the hold. Unlike terminally_rejected the hold is reversible: the status moves on once the hold is lifted.
unknownVerification backend returned a status we don't recognize. Contact support.

Rich state (link, missing fields, rejection reason, last sync) lives at GET /org/kyb/state.