Skip to main content

API and automation

What this page is — every way to drive Orbit Papers without the screens: the public REST API, outbound webhooks, event-driven document generation, and the assistant tools.

What it is for — so other systems can create, move and react to Papers documents without anyone opening the screens.

The problem it solves — the documents most worth automating — one per order, one per won deal — otherwise cost a person every time, and your other systems learn about a signature days late.

Route: /api/v1/ext/papers/… · Credentials: an API key from Developers → API keys (Manage Api Keys) carrying the scopes below


1. What it is​

MechanismDirectionUse it for
REST APIYour system → PapersCreate and submit documents, approve, share, run AI, read reports
WebhooksPapers → your systemReact when a document is finalized, signed, revoked…
Generation triggersOrbit event → PapersA won deal or submitted form creates a document with no code
Assistant / MCP toolsA person or agent → PapersThe same operations in conversation
Embedded viewsPapers UI inside another siteWhen a person must act, not a system

Every route obeys the same rules as the screens. A type requiring approval cannot be finalized through the API, and a key cannot see documents outside its organisation and project.


2. Why you would use it​

  • The repetitive documents write themselves. An offer letter per accepted candidate or a contract per won deal needs no one to open Papers.
  • Your systems learn the moment something is signed. paper.fully_executed can start billing within seconds, instead of when someone remembers to tell finance.
  • Least privilege by design. Narrow scopes mean an integration that files documents cannot approve them.
  • Safe retries. POSTs accept an Idempotency-Key, so a network retry cannot create two contracts.

3. Step by step — REST​

  1. Developers → API keys: create a key, choose the scopes, and bind it to a project if the integration should see only one.
  2. Send Authorization: Bearer with the key on every call.
  3. On POSTs, send an Idempotency-Key header with a unique value per logical operation.
  4. Read the RateLimit-* response headers and back off on HTTP 429.

The organisation, and the project for a project-bound key, always come from the key, never from the request. An org-wide key may pass project_id when creating; a project-bound key gets project_scope_mismatch if it names another project.


4. Field reference​

Scopes​

ScopeAllows
papers:document:readTypes, documents, comments, pending decisions, zones (read)
papers:document:writeCreate and submit documents, share links, generate from an event, replace zones
papers:workflow:actApprove, reject or return on behalf of a named approver
papers:obligation:readObligations, per document or across the key's scope
papers:ai:runSummarize and risk analysis — credits billed to the organisation
papers:report:readProject-shared saved reports and their data

Routes (prefix /api/v1/ext/papers)​

Method and pathScopeBody fields
GET /typesdocument:read—
POST /documentsdocument:writetype_code, title, data_values, source_ref, project_id
GET /documents/{id}document:read—
GET /documents/{id}/commentsdocument:read—
GET /documents/{id}/obligations, GET /obligationsobligation:read—
POST /documents/{id}/submitdocument:writecomment
GET /approvals/pendingdocument:read— routed and unrouted decisions
PATCH /documents/{id}/workflow/statusworkflow:actaction, comments, approver_email, lifecycle_action
POST /documents/{id}/share-linkdocument:writeexpires_days, passcode, allow_download
POST /generatedocument:writeevent_type, payload
POST /ai/summarize, POST /ai/risksai:rundocument_id or raw_text, project_id, perspective, custom_focus, force
GET / PUT /types/{id}/zonesdocument:read / writeZone list — see zonal extraction
GET /reports, /reports/{id}, /reports/{id}/datareport:read— shared reports only

Errors​

Errors carry a type and a code:

HTTPCodeMeaning
400missing_fields, invalid_body, validation_failedBad input — the message says which field
400invalid_transition / invalid_actionNot allowed from the document's state
400missing_approver_emailWorkflow actions must name the approver
403project_scope_mismatchThe key cannot act in that project
403not_an_approver / approver_not_foundThe named person is not an approver on the current step, or does not exist
403key_missing_actorThe key has no user to act as
409invalid_lifecycleThe type's lifecycle cannot run this move
429—Rate limit: 60/min per key by default, 600/min per organisation (set by the platform operator)
502ai_execution_failed, approval_action_failedA downstream step failed — safe to retry with the same idempotency key

Webhook events (Orbit Papers)​

paper.created · paper.state_changed · paper.lifecycle_override · paper.finalized · paper.sent (signature request sent) · paper.signed · paper.fully_executed · paper.declined · paper.expired · paper.revoked · paper.superseded · paper.comment_added · paper.obligation_created · paper.obligation_completed · ai.risk.critical_detected (from the regulatory drift sweep)

Webhook delivery​

AspectBehaviour
Where configuredDevelopers → Webhooks: endpoint URL plus selected events
HeadersOrbit-Signature: t=<timestamp>,v1=<hmac>, Orbit-Event-Id, Orbit-Event-Type, User-Agent: Orbit-Webhooks/1.0
SignatureHMAC-SHA256 with the endpoint secret over the string <timestamp>.<raw body>
SuccessAny 2xx within 10 seconds
RetriesUp to 10 attempts, exponential backoff from 30 s, capped at 6 h
Disabled endpointPending deliveries are marked failed

Use Orbit-Event-Id to de-duplicate, because a retried delivery can arrive after your first successful handling timed out.


5. Generation triggers​

A trigger binds an event type to a document type. It has a title template, a source map from event payload to fields, and optional auto-submit and auto-finalize. When the event fires, every active trigger for it creates a document as a system actor. Each run leaves a papers.generation audit row, marked completed or failed.

EventTypical document
deal.wonThe customer agreement
form.submittedAn application or intake document — also runs intake form bridges
Any event another module enqueuesAnything with a matching trigger
POST /generate from your systemYour own events

A trigger on a type without a published version fails with "type has no published version". Configure triggers in generation triggers (Configure triggers/webhooks/auto-generation rules.).


6. Worked example​

Gatiro wants a customer agreement drafted whenever a deal is won in Pulse, and its billing system told when the agreement is signed.

  1. Trigger.
    • Event deal.won → type Customer agreement.
    • Title template: Agreement — deal name.
    • Source map: deal value → contract_value, account → customer_name.
    • Auto-submit on.
  2. Webhook. In Developers → Webhooks, an endpoint https://billing.gatiro.example/hooks/orbit subscribes to paper.fully_executed.
  3. Verification in the billing service:
const [t, v1] = req.get('Orbit-Signature').split(',').map(p => p.split('=')[1]);
const expected = crypto.createHmac('sha256', SECRET).update(`${t}.${rawBody}`).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) return res.sendStatus(401);
if (await seen(req.get('Orbit-Event-Id'))) return res.sendStatus(200);
  1. A deal is won at 10:02. By 10:02:05 Agreement — Harbor Health exists and has been submitted for approval.
  2. Approval via API. An internal tool approves on behalf of the CFO:
PATCH /api/v1/ext/papers/documents/9b1c…/workflow/status
Idempotency-Key: approve-9b1c-cfo
{"action": "APPROVE", "approver_email": "[email protected]", "comments": "Within pricing policy"}
  1. Nine days later the last signature lands. Billing receives paper.fully_executed, verifies the signature, and opens the first invoice.

7. The admin contract​

What must be configuredOtherwise
An API key with exactly the scopes needed403 on out-of-scope calls
The key bound to a user, for workflow actionskey_missing_actor
Approvers who are real approvers on the stepnot_an_approver
Published types for triggers and creationtype has no published version
A webhook secret stored by your serviceSignatures cannot be verified
AI credits, for papers:ai:runai_execution_failed

8. Downstream​

  • API-created documents behave exactly like UI-created ones: numbering, approvals, AI auto-runs, obligations.
  • Webhook deliveries and API calls appear in the Developers logs and analytics.
  • The assistant exposes create, submit, workflow act, share link, generate from event, summarize, risks, list types, list pending approvals, list and replace zones, and read obligations and comments — the same rules again.

9. Don't confuse this with…​

Embedded viewsA UI in someone else's page; the API has none
Capture inbox sourcesPush files in to be classified; the API creates structured documents
Inbound webhooks from payment gatewaysUnrelated to Papers events

10. Troubleshooting​

SymptomCause
403 insufficient scopeThe key lacks the route's scope (§4)
A document exists in Orbit but the API returns 404Outside the key's project; the API never reveals existence
Two documents from one retryNo Idempotency-Key on the POST
Webhooks never arriveEndpoint disabled, not subscribed to that event, or non-2xx responses exhausting 10 attempts
Signature check failsSigned over a re-serialised body instead of the raw bytes
Trigger never firedNo active trigger for that event and organisation, or the type is unpublished
Finalize refused through the APIThe type requires approval, just as in the UI