Gridex API documentation

Gridex Staff API

Documentation 2026-10-12.1. Staff response schema 2026-10-09.1. Manage staff accounts and customer service from your own backend.

You do not need to match the latest documentation revision exactly to use a supported API version. Documentation updates do not change the business response schema or require an integration upgrade. Earlier supported Staff response profiles remain available. Independent staff onboarding has its own schema, 2026-10-05.2.

Current OpenAPI · Immutable release · Release manifest

Integration readiness

The documented Staff API is available for integration development. Production use requires the deployed API and OPS database prerequisites plus the organization's active credential, explicit Staff scopes, identity provider, membership and any independent-login binding. Verify an authenticated read and write with the intended role and company, correct audit attribution and a retry of the same logical operation before go-live.

Configure staff login

Create an API credential with the specific staff scopes you need. In Settings → Customer login, add an OIDC provider or your backend public signing key with purpose Staff. Copy its issuer and audience exactly. Existing website and customer scopes do not grant staff access.

Your backend authenticates the person and maps their account to a Gridex user UUID. Keep the API credential and signing private key on your server. Derive the acting user from the authenticated account, never from a browser supplied UUID.

Sign each request

Send Authorization: Bearer <GRIDEX_API_KEY> and x-gridex-staff-assertion: <SIGNED_JWT> on every call. Supported algorithms are RS256, PS256 and ES256. The JWT requires the configured iss and aud, sub equal to the staff Gridex user UUID, integer iat and exp with a lifetime of at most 900 seconds, and a unique jti. Optional nbf controls the earliest valid time.

Clients registered for an independent staff identity additionally send token_use "staff_access", company_id, local_auth_issuer, local_auth_subject, staff_binding_id and staff_binding_version from onboarding; sub stays the central Gridex user UUID. A removed or revoked registration is rejected and never falls back to the central flow. See the independent staff onboarding guide in docs/staff-api/independent-onboarding.md.

Each assertion is accepted once. Generate a new assertion and jti for every attempt, including reads and retries. Gridex checks the current central account, active organization membership, current identity binding where required, and the person's role permissions and overrides for every request.

Your backend verifies the local Auth session before signing. Gridex also calls the registered local Auth getUser during identity resolution and invitation acceptance. A normal Staff request validates the signed proof and current central authority; it does not call local Auth getUser again for an already signed proof.

import { createPrivateKey, randomUUID, sign } from 'node:crypto'

function staffAssertion(authenticatedStaffGridexUserId) {
  const iat = Math.floor(Date.now() / 1000)
  const encode = value => Buffer.from(JSON.stringify(value)).toString('base64url')
  const header = encode({ alg: 'RS256', typ: 'JWT', kid: process.env.GRIDEX_STAFF_KEY_ID })
  const payload = encode({
    iss: process.env.GRIDEX_STAFF_ISSUER,
    aud: process.env.GRIDEX_STAFF_AUDIENCE,
    sub: authenticatedStaffGridexUserId,
    iat, exp: iat + 300, jti: randomUUID(),
  })
  const input = header + '.' + payload
  const signature = sign('RSA-SHA256', Buffer.from(input),
    createPrivateKey(process.env.GRIDEX_STAFF_PRIVATE_KEY_PEM))
  return input + '.' + signature.toString('base64url')
}

Scopes and permissions

The credential scope and the person's permission are both required.

ScopeOperationPermission
staff_users.readList staff and rolesusers.read
staff_users.writeInvite, change roles, disable and reactivateusers.write
staff_customers.readSearch and retrieve customerscustomers.read
staff_customers.writeChange contact detailsmasterdata.write
staff_customers.writeRequest identity changecustomers.write
staff_cases.readRead cases, events and attachmentscases.read
staff_cases.writeCreate, reply, note, phone, status, assign and uploadcases.write

Staff cannot grant a role exceeding their own permissions or disable themselves. The final active administrator cannot be disabled or demoted. Assignees must be active staff in the same organization.

Writes and retries

Every POST and PATCH requires Idempotency-Key. Reuse that key and unchanged body for a retry, with a fresh assertion and jti. Use a new key for a new logical operation. Contact updates require expectedUpdatedAt from the latest customer updated_at and at least one editable field. A version conflict requires reloading and reconciling state. Identity changes preserve customer approval and contract acceptance.

Customer and case paths use opaque references; staff account operations use Gridex user UUIDs. Identity numbers are masked in customer responses. Internal notes and phone logs require staff access. Writes are audited with the acting staff identity, API credential and staff_api channel.

Upload a raw PDF, PNG or JPEG body up to 4 MiB with x-file-name and optional x-attachment-visibility: internal or customer (default internal). Only released attachments can be downloaded; the stored hash is verified on download.

Replay, request IDs and storage project

Every Staff write response, including staff-user invite, role change, disable and enable, carries Idempotency-Replayed: true when a stored result is returned and false for a new execution. Current authentication and permission are checked before any replay.

Gridex issues one server request ID per call and returns the same value in request_id, the X-Request-ID header and the request log, on success and on error. An inbound X-Request-ID is kept only as a separate client correlation value.

The optional x-gridex-expected-project-ref header pins the storage project; a mismatch returns 412 storage_project_mismatch before any authentication or write. Responses carry X-Gridex-Project-Ref.

Query parameters: existing parsing is kept by default. Send x-gridex-query-parsing: strict to require each parameter at most once and page, page_size and limit as plain decimal digits; violations return 422 invalid_field.

Endpoints

MethodPathScopeOperation
GET/api/v1/staff/usersstaff_users.readList staff accounts with their membership status.
POST/api/v1/staff/usersstaff_users.writeInvite staff to the organization within the acting staff role ceiling. Idempotency-Key is required.
PATCH/api/v1/staff/users/[id]staff_users.writeChange a staff role while preserving the final active administrator. Idempotency-Key is required.
POST/api/v1/staff/users/[id]/disablestaff_users.writeDisable staff while preventing self disable and loss of the final administrator. Idempotency-Key is required.
POST/api/v1/staff/users/[id]/enablestaff_users.writeReactivate a disabled staff membership. Idempotency-Key is required.
GET/api/v1/staff/rolesstaff_users.readList staff roles and whether the acting staff can assign each role.
GET/api/v1/staff/customersstaff_customers.readSearch and page customers belonging to the authenticated organization.
GET/api/v1/staff/customers/[ref]staff_customers.readRetrieve a customer with masked identity numbers and explicit public fields.
PATCH/api/v1/staff/customers/[ref]/contactstaff_customers.writeUpdate customer contact fields using an expected version. Idempotency-Key is required.
POST/api/v1/staff/customers/[ref]/identity-changestaff_customers.writeRequest a customer identity change with customer approval when required. Idempotency-Key is required.
GET/api/v1/staff/casesstaff_cases.readList customer cases available to staff in the authenticated organization.
POST/api/v1/staff/casesstaff_cases.writeCreate a customer support case as the acting staff. Idempotency-Key is required.
GET/api/v1/staff/cases/[reference]staff_cases.readRetrieve a customer case including staff visible events and attachments.
POST/api/v1/staff/cases/[reference]/messagesstaff_cases.writeReply to a customer through the existing support conversation. Idempotency-Key is required.
POST/api/v1/staff/cases/[reference]/notesstaff_cases.writeAdd an internal staff note to a customer case. Idempotency-Key is required.
POST/api/v1/staff/cases/[reference]/phone-interactionsstaff_cases.writeRecord a phone interaction and its customer verification evidence. Idempotency-Key is required.
PATCH/api/v1/staff/cases/[reference]/statusstaff_cases.writeChange the status of a customer case. Idempotency-Key is required.
PATCH/api/v1/staff/cases/[reference]/assigneestaff_cases.writeAssign a customer case to active staff in the same organization. Idempotency-Key is required.
GET/api/v1/staff/cases/[reference]/eventsstaff_cases.readList staff visible case events with a case bound continuation cursor.
GET/api/v1/staff/cases/[reference]/attachmentsstaff_cases.readList staff visible attachments of a customer case.
POST/api/v1/staff/cases/[reference]/attachmentsstaff_cases.writeUpload a staff attachment for content inspection before release. Idempotency-Key is required.
GET/api/v1/staff/cases/[reference]/attachments/[attachmentReference]/filestaff_cases.readDownload a released staff visible attachment with its hash verified.

Read complete case history

Case detail includes events_page and attachments_page. Follow next_cursor through GET /api/v1/staff/cases/{reference}/events or GET /api/v1/staff/cases/{reference}/attachments until has_more is false. Each list accepts limit from 1 to 100 (default 50) and cursor. Sign a fresh assertion for every page. Cursors are bound to the organization, customer and case.

Customer detail marks its initial contacts, addresses and sites with contacts_page, addresses_page and sites_page: limit is 100, returned is the included count, and has_more identifies additional records beyond the initial collection.

Errors

JSON errors contain error.code, error.message, error.retryable, error.field and error.blockers, plus request_id, correlation_id and contract_schema_version. Success and error responses carry X-Request-ID and X-Gridex-Contract-Version. X-Gridex-Documentation-Version identifies the associated documentation revision. When fetching OpenAPI itself, X-Gridex-Contract-Version identifies that document's revision.

HTTPReason or codeAction
400 / 422Invalid request or Idempotency-KeyCorrect fields or headers.
401staff_assertion_missing, staff_assertion_signature_invalid, staff_assertion_issuer_mismatch, staff_assertion_audience_mismatch, staff_assertion_expired, staff_assertion_replayedFix configuration or sign a fresh assertion.
403api_scope_missing, staff_provider_missing, staff_provider_invalid, staff_membership_inactive, staff_permission_denied, staff_role_ceiling_exceededCheck configured scopes, provider, active membership and permissions.
404Resource unavailable in this organizationUse a current reference from the same organization.
409version_conflict, staff_self_disable_forbidden, staff_last_admin_required, staff_invalid_user_state, staff_self_role_change_forbidden, idempotency conflictReload and reconcile the operation without bypassing safeguards.
410 / 423organization_closed, organization_inactive, organization_pausedResolve the organization lifecycle restriction before retrying.
413 / 415payload_too_large or attachment size/type rejectedReduce the JSON body or use PDF, PNG or JPEG within 4 MiB.
429Rate limit exceededObserve Retry-After and sign a fresh assertion for the retry.
412storage_project_mismatchUse the deployment serving the expected project; nothing was executed.
500 / 503Processing or service unavailableKeep the request ID; retry only when safe and retryable.