Contents

Basics

What every Unforged API shares: keys, versions, headers and errors.

API keys and permissions

Call https://api.unforged.sh with Authorization: Bearer <API key>. A key carries a set of permissions, chosen from your own when you create it, and each endpoint says which one it needs.

  • org:read See org, members, usage
  • org:members:manage Invite/remove members, assign roles
  • org:sso:manage Admin Portal links: SSO, directory sync, role mapping
  • org:keys:manage Create/revoke API keys (within own permissions)
  • org:billing:manage Checkout, billing portal, plan
  • org:settings:manage Retention, org-wide settings, the API version pin
  • org:audit:read Audit log
  • org:children:access Act in descendant orgs
  • org:children:manage Create/suspend child orgs
  • nib:checks:create Submit checks, sessions, live
  • nib:checks:read Read checks and results
  • nib:subjects:read Read subjects/references metadata and thumbnails
  • nib:references:write Enroll references, confirm-to-learn
  • nib:references:delete Delete references and subjects, unlearn
  • nib:settings:manage Policy, learning, templates, webhooks, bucket keys
  • folio:records:read See filed records, folders and metadata
  • folio:documents:read Open and download documents (a reason is recorded)
  • folio:documents:search Search record metadata and document text (audited)
  • folio:records:write File records, create folders, extend retention
  • folio:records:delete Request disposal and early deletion
  • folio:holds:manage Place and request release of legal holds
  • folio:holds:approve Approve hold releases and early deletion (second person)
  • folio:exports:create Create exports, custody and integrity reports
  • folio:audit:read Read the folio ledger
  • folio:settings:manage Retention classes, reason settings, protected folders, webhooks
  • sig:packages:read See packages, their signers and signed files
  • sig:packages:send Create, send, correct and void packages
  • sig:settings:manage Sig settings: Folio filing and Nib checks
  • loupe:checks:create Send documents to be checked for forgery
  • loupe:checks:read See document checks and their findings
  • loupe:checks:review Record the decision on a document check
  • loupe:settings:manage Loupe settings: webhooks

Roles and permissions

Versions

Current version2026-10-14

  • Send Unforged-Version: 2026-10-14 to choose a version per request. Without it your organisation’s pin applies.
  • Additive changes (new endpoints, optional parameters, response fields) never make a version. Ignore fields you don’t know.
  • Breaking changes ship only in a new dated version.
  • A version stays supported for 24 months after a newer one replaces it.
  • Deprecated versions answer with Deprecation, Sunset and Link headers.

Headers

  • Authorization
    Bearer <API key> on every route that needs a key.
  • Unforged-Version

    API version (YYYY-MM-DD) for this request; defaults to your pinned version.

  • Unforged-Org

    Act in a child organisation (its id). Needs org:children:access.

  • Idempotency-Key
    On a POST, the same key and body give back the first answer for 24 hours.

Errors

An error comes back as application/problem+json with a status, a sentence you can show, and a code that stays the same, so match on the code.

  • type required Type: string

    https://unforged.sh/problems/<code>

  • title required Type: string
  • status required Type: integer
  • detail required Type: string
  • code required Type: string

    A stable error code.

  • request_id optional Type: string
  • region optional Type: string

    On wrong_region, your home region.

  • api_host optional Type: string

    On wrong_region, that region's API host.

  • address optional Type: string

    On address_not_allowed, the address your request came from.

  • terms_version optional Type: string

    On learning_terms_required, the version to accept.

  • job_id optional Type: string

    On busy or timeout of a check that continues.

  • status_url optional Type: string
  • host optional Type: string

    On a failed URL fetch, the host.

  • reason optional Type: string

    On a failed URL fetch, why (e.g. http_status, timeout). On org_suspended, idle when the organisation was removed for inactivity (it can start again).

  • checks optional Type: object

    On not_ready.

  • errors optional Type: any[]

    On a synchronous check whose job failed.

Every code

  • access_suspended
  • address_not_allowed
  • awaiting_first_payment
  • billing_already_active
  • billing_required
  • busy
  • conflict
  • fetch_failed
  • idempotency_conflict
  • idempotency_in_progress
  • idempotency_key_required
  • idempotency_not_replayable
  • internal
  • invalid_request
  • invalid_signature
  • invalid_version
  • learning_terms_required
  • method_not_allowed
  • not_allowlisted
  • not_available_in_dev
  • not_found
  • not_implemented
  • not_ready
  • org_moving
  • org_suspended
  • permission_denied
  • quota_exceeded
  • rate_limited
  • reason_required
  • storage_provisioning
  • tenant_not_provisioned
  • timeout
  • too_large
  • unauthorized
  • unsupported_media
  • webhook_test_failed
  • wrong_region