Getting started
The most common problems hit during a first integration, drawn from real alpha bring-up. Search by symptom (the heading) or by the error code in the response.
"Backend OAuth not configured" / 503 from /admin/oauth/login#
Symptom — clicking "Sign in with ScaiKey" on the admin UI gives a generic error; backend logs show 503 admin OAuth not configured; missing: SCAISCRIBE_SCAIKEY_CLIENT_ID, ....
Cause — your ScaiScribe deployment hasn't finished its ScaiKey registration. The backend can't initiate the OAuth flow without a client_id + client_secret + session_secret.
Fix — your operator needs to register ScaiScribe with ScaiKey (one-time ceremony) and deploy the credentials. After they restart the backend, /v1/admin/config returns { "auth_configured": true } and the login button works.
401 UNAUTHENTICATED from every endpoint#
Symptom — every SDK call raises AuthError (or its language equivalent); the error envelope shows code: UNAUTHENTICATED.
Cause — either the token is missing/malformed, or ScaiScribe's auth backend doesn't trust the issuer.
Fix —
- Confirm the token is actually being sent: turn on the SDK's debug logging, or check the response's
request_idagainst the backend log line for that request. - Confirm you're getting the token from the right ScaiKey deployment. The token issuer (
issclaim) must match what ScaiScribe is configured to trust (SCAISCRIBE_SCAIKEY_BASE_URL). - If the token works against
/v1/health(which is public) but fails on/v1/documents, the token is reaching the backend fine but JWT verification is failing. Common cause: backend points at the wrong JWKS URL. The correct path for ScaiKey global apps is/api/v1/platform/.well-known/jwks.json— not/.well-known/jwks.json.
403 QUOTA_EXCEEDED#
Symptom — calls fail with QuotaError / QuotaException; envelope shows code: QUOTA_EXCEEDED and details.limit/details.current.
Cause — your tenant has hit its render or storage quota.
Fix — ask your operator to bump the quota for your tenant. In the meantime, finished documents you delete_document(doc_id) count against the quota until the lifecycle worker garbage-collects them; deleting old drafts can free up headroom immediately.
403 with no QUOTA_EXCEEDED — usually scope-related#
Symptom — ForbiddenError; envelope code varies (ROLE_INSUFFICIENT, TENANT_SCOPE_VIOLATION, etc.).
Cause — your token's scopes don't authorize the endpoint, or you're acting across tenant boundaries you don't have access to.
Fix —
- For admin endpoints (
/v1/admin/*), verify your user has the right role. For the alpha, onlysuperadmincan see global views;tenant_adminis scoped to one tenant. Check withclient.admin.me(). - For document endpoints, verify the document's
tenant_idmatches your token's tenant.
404 DOC_NOT_FOUND when you just created the document#
Symptom — create_document returns a doc_id, but the next call (get_document, add_element, etc.) returns 404.
Cause — almost always a typo or stringification bug in the integration code. Document IDs are opaque strings (doc_01ABC...); a missing character will silently 404.
Fix — log the doc_id you got back from create_document and the one you're passing in subsequent calls. If they're identical: confirm you're using the same ScaiScribe host on both calls. In multi-environment setups it's easy to point at dev for create and prod for read.
422 VALIDATION_FAILED on a PATCH#
Symptom — your add_element op returns 422; details shows a field path and a constraint.
Cause — the element payload doesn't match the spec for that element type. Common offenders:
add_elementwith noelementfield.- Heading
leveloutside 1–6. - Table missing
rows. - Image missing
asset_idANDurl.
Fix — check details.field in the envelope. Cross-reference with the Concepts → Spec format page or the JSON Schema. The SDKs help: the PatchOp model has typed shape that catches a lot at construct time.
Ingestion warning: INGEST_PANDOC_FOOTNOTE_DETECTED / INGEST_IMAGE_DROPPED / fidelity score < 1.0#
Symptom — ingest_document succeeds with fidelity_score < 1.0 and warnings calling out specific elements.
Cause — the source document used a feature ScaiScribe's ingest path doesn't fully model yet. When pandoc is installed on the worker host it runs alongside mammoth to surface higher-fidelity warnings (footnotes, math equations, citations, definition lists, line blocks); without pandoc only the mammoth-detected gaps are reported.
Fix — this isn't a bug, it's an honest report. The body element survives — usually as a paragraph carrying the visible text, with the structural metadata flagged in fidelity.warnings[]. For ScaiScribe-authored documents the JSON breadcrumb at scaiscribe/breadcrumbs.json in the .docx zip provides full round-trip equivalence; externally-authored docs degrade gracefully with documented warnings.
"Sync wrap timed out" / JobTimeoutError#
Symptom — finalize or ingest_document raises a timeout exception after the per-operation budget.
Cause — the underlying job is taking longer than the SDK's sync-wrap window (8–30s depending on operation).
Fix — pass sync=False. You'll get a JobEnvelope back immediately; poll get_job(job_id) until status becomes completed or failed. This is the right pattern for any job you know will exceed the default sync timeout.
1 2 3 4 | |
Where to look when stuck#
- Always include the
request_idwhen reporting issues. It's in every error envelope and on every access log line on the backend. /v1/healthis public — if it doesn't work, your network can't reach the backend at all./v1/admin/configis public — ifauth_configured: false, the backend isn't ready for ScaiKey auth.
For anything else, ping the platform team with the request_id of the failing call.