Documentation

Everything needed to evaluate Orchent, on one page. First request in under five minutes.

Quickstart

  1. Sign up at app-staging.orchent.app.
  2. Clone a template or build a flow.
  3. Create an API key — it is shown once; store it.
  4. Call the endpoint:
shell
curl https://app-staging.orchent.app/v1/flows/ticket-classifier/run \
  -H "Authorization: Bearer sk_live_a1b2…" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"ticket": "Charged twice for the same order."}}'

Authentication

Bearer keys, scoped to the flows they may run. A key is shown once at creation, stored hashed, and displayed by prefix afterwards. Revocation is immediate — the next request with a revoked key gets a 401.

header
Authorization: Bearer sk_live_a1b2…

# displayed after creation as:  sk_live_a1b2…  (prefix only)

POST /v1/flows/{name}/run

Runs a published flow and returns the result, the run id and usage. Inputs are validated against the flow's declared schema before execution.

PARAMETER TYPE REQUIRED DESCRIPTION
inputs object required The flow's declared inputs. A schema mismatch is a 400, not a run.
query string optional Retrieval query passed to retrieve nodes.
stream boolean optional true switches the response to server-sent events. Default false.
user string optional Attribute this run to one of your end users — it appears in run history and daily rollups.

Streaming

Set "stream": true on the same endpoint. The response becomes server-sent events — tokens and step events as they happen — terminated by data: [DONE].

shell · SSE
curl -N https://app-staging.orchent.app/v1/flows/ticket-classifier/run \
  -H "Authorization: Bearer sk_live_a1b2…" \
  -d '{"inputs": {"ticket": "…"}, "stream": true}'

data: {"type":"token","value":"bil"}
data: {"type":"token","value":"ling"}
data: {"type":"result","run_id":"run_01J8ZQ4K7M2",
      "usage":{"tokens":312,"duration_ms":1190}}
data: [DONE]

Listing flows

Returns every flow the key can run, each with its declared input schema — a client can discover what a flow expects without reading its definition.

GET /v1/flows
{
  "flows": [
    {
      "name": "ticket-classifier",
      "published": true,
      "input_schema": {
        "ticket": { "type": "string", "required": true }
      }
    }
  ]
}

Run history

Every run is kept with its inputs, output, status, duration and token counts.

endpoints
GET /v1/runs?flow=ticket-classifier   # newest first
GET /v1/runs/run_01J8ZQ4K7M2          # one run, in full

Usage

Daily rollups of runs and tokens — per key, per flow, per end user (the user parameter). Per-tenant rollups are the billing source: your invoice reads from this endpoint.

endpoints
GET /v1/usage/daily                   # runs + tokens per day
GET /v1/usage/daily?user=cust_8841    # per end user

Errors

Every error has the same shape:

{"error":{"code":"…","message":"…","request_id":"…"}}

STATUS CODE MEANING
401 unauthorized Missing or invalid key.
403 forbidden Key lacks scope for this flow.
404 not_found No such flow — or not yours.
400 invalid_request Inputs failed the declared schema.
402 quota_exceeded Plan run quota exhausted. Refused, never billed over.
429 rate_limited Over 60 req/min for this key. Retry after the header says so.
500 internal Unexpected failure; the request_id is your reference.

Include the request_id when writing to support — it points at the exact run.

Rate limits

60 requests / minute per key. Over the limit, the call is refused with 429 rate_limited and a Retry-After header. Rate-limited calls are not runs and never count against your quota.

API reference

Generated from the OpenAPI document the gateway itself publishes, so it describes the API that is actually deployed rather than one somebody remembered to update. Point a client generator at it:

curl -O https://app-staging.orchent.app/openapi.json
openapi-generator generate -i openapi.json -g python -o ./orchent-client

Base URL https://app-staging.orchent.app · openapi.json

Auth

Sign up, sign in, sign out. Sets the session cookie the account-management endpoints require.

post/v1/auth/loginpublic

Sign in

Sets orchent_session (httpOnly) and orchent_csrf. Send the value of the second as X-CSRF-Token on every mutating request.

Request body
FIELDTYPENOTES
emailstringrequired
passwordstringrequired
Responses
STATUSBODYWHEN
200Identity

Signed in.

401Error

Wrong email or password. The two are not distinguished.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/auth/logoutsession only

Sign out

Deletes the session server-side and clears the cookies. Sessions are server-side precisely so this can actually revoke one.

Responses
STATUSBODYWHEN
204

Signed out. Idempotent.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/auth/password/forgotpublic

Start a password reset

The response never varies with the answer. This endpoint is handed an address by an anonymous caller and must not become a way to ask whether somebody has an Orchent account, so the status and body are fixed constants on every path — including when there is no such account.

Request body
FIELDTYPENOTES
emailstringrequired
Responses
STATUSBODYWHEN
200EmailSent

Always this, whatever was or was not found.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/auth/password/resetpublic

Set a new password from a reset link

Spends the token, sets the password, and signs the account out everywhere — a reset exists because the account may already be in someone else's hands, and one that leaves their cookie working has not taken it back. It also confirms the address, since the link is only reachable from that inbox.

Request body
FIELDTYPENOTES
tokenstringrequired
passwordstringrequired
Responses
STATUSBODYWHEN
200EmailSent

Reset. The session cookies are cleared.

400Error

The link is no longer valid, or the new password does not meet the policy — checked first, so a rejected password does not burn the one-use link.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/auth/signuppublic

Create an account

Creates a tenant and its first user, and signs that user in — the response carries Set-Cookie: orchent_session and orchent_csrf. The new tenant starts on the Free plan.

Request body
FIELDTYPENOTES
emailstringrequired
passwordstringrequired
tenant_namestringrequired
Responses
STATUSBODYWHEN
201Identity

Account created and signed in.

400Error

Invalid email, a password that does not meet the policy, a blank tenant name, or an email that is already registered.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/auth/verifypublic

Confirm an email address

Spends the token from a confirmation link. Public on purpose: the token *is* the credential, and also requiring a session would break the ordinary case of opening the link on a phone you are not signed in on.

Request body
FIELDTYPENOTES
tokenstringrequired
Responses
STATUSBODYWHEN
200EmailVerified

Confirmed. Following an already-spent link twice is a no-op, not a second welcome.

400Error

The link is expired, already used, or not a link we issued.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/auth/verify/resendsession only

Send a fresh confirmation link

To the signed-in user's own address, taken from the session and not from the body — an endpoint that mails a link to whatever address it is handed is an open relay with extra steps.

Responses
STATUSBODYWHEN
200EmailSent

On its way, or already_verified, which is not an error.

401Error

Missing, malformed or unrecognised credentials.

404Error

Email is not configured on this deployment.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/mesession only

The signed-in user and their tenant

Also refreshes the orchent_csrf cookie, so a client can call this on boot to recover a token it does not have.

Responses
STATUSBODYWHEN
200Identity

The caller.

401Error

No valid session.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Flows

The catalogue you can run, and running one. This is the surface a customer backend actually uses.

get/v1/flowsAPI key or session

The flows you can run

Published and enabled flows only: the platform catalogue plus your own published flows, which shadow a platform flow of the same name for you and for nobody else. A flow that exists but is unpublished is absent here and 404s on run — indistinguishable from one that does not exist.

Responses
STATUSBODYWHEN
200CatalogueFlowList

The catalogue.

401Error

Bad credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/flows/{flow}/runAPI key or session

Run a flow

The endpoint everything else exists to support.

With "stream": false (the default) the response is JSON. With "stream": true it is text/event-stream: data: frames terminated by data: [DONE], and an error part-way through arrives as one more frame carrying the usual error envelope.

{flow} resolves tenant-first — your own published flow wins over a platform flow of the same name. Every run here is metered and counts against your quota.

Parameters
FIELDTYPENOTES
flow (path)stringrequired
Responses
STATUSBODYWHEN
200RunResult

The run finished.

401Error

Missing, malformed or unrecognised credentials.

402Error

The plan's monthly run quota is spent.

404Error

No such flow, or it is not published.

429Error

Over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Runs

What has run, how long it took and what it returned.

get/v1/runssession only

List runs

Newest first, keyset-paginated: pass the next_cursor you were given back as cursor.

Parameters
FIELDTYPENOTES
limit (query)integeroptional
cursor (query)string | nulloptional
Responses
STATUSBODYWHEN
200RunList

A page of runs.

400Error

limit outside 1–100, or a malformed cursor.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/runs/{run_id}session only

One run, with its inputs and outputs

Parameters
FIELDTYPENOTES
run_id (path)stringrequired
Responses
STATUSBODYWHEN
200RunDetail

The run.

401Error

Missing, malformed or unrecognised credentials.

404Error

No such run for this tenant.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Usage

Daily rollups and the current month against the plan quota.

get/v1/usagesession only

Daily usage and the current quota

from and to are inclusive YYYY-MM-DD days. Omit both for everything on record. quota.runs_used is always the current calendar month, whatever range you asked for — it is what the 402 is measured against.

Responses
STATUSBODYWHEN
200Usage

Buckets, totals and quota.

400Error

A malformed day, or from after to.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Keys

Mint and revoke the `ock_live_…` keys your backend authenticates with.

get/v1/keyssession only

List API keys

Secrets are never included — only the displayable prefix.

Responses
STATUSBODYWHEN
200ApiKeyList

The tenant's keys, revoked ones included.

401Error

This endpoint requires a user session; an API key cannot mint or list keys.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/keyssession only

Mint an API key

The only response that ever contains the secret.

Request body
FIELDTYPENOTES
namestringrequired
Responses
STATUSBODYWHEN
201ApiKeyCreated

Created. Save key now.

400Error

Missing or over-long name.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

delete/v1/keys/{key_id}session only

Revoke an API key

Immediate and idempotent. A revoked key authenticates nothing.

Parameters
FIELDTYPENOTES
key_id (path)stringrequired
Responses
STATUSBODYWHEN
204

Revoked.

401Error

Missing, malformed or unrecognised credentials.

404Error

No such key for this tenant.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Secrets

The credentials your flows authenticate with. The mirror image of keys: a key is something Orchent issues and shows you once, a secret is something you supply and Orchent shows you **never**. Values are write-only — no endpoint on this API returns one. Reference a secret in a flow as `{{secret:NAME}}`; Orchent supplies the value as the request leaves and it is never written into the flow.

get/v1/secretsAPI key or session

List your secrets

Names and metadata. Never a value — there is no field for one and no endpoint that would return one.

Readable with an API key as well as a session, because tooling needs the names; writing is session-only (below).

Responses
STATUSBODYWHEN
200SecretList

Your secrets, without their values.

401Error

Bad credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/secretssession only

Store a secret

Session-only, like minting an API key: supplying a credential is a human action, and a leaked API key must not be able to swap the token a live flow authenticates with.

A name that already exists is a 400, not an overwrite — a silent overwrite turns a typo into a live flow quietly changing credential. Rotate with PUT instead.

Request body
FIELDTYPENOTES
namestringrequired
valuestringrequired
descriptionstringoptional
Responses
STATUSBODYWHEN
201Secret

Stored. The response carries metadata only.

400Error

Bad name, empty value, or the name is already taken.

401Error

This endpoint requires a user session.

402Error

Your plan's secret limit is reached.

404Error

This deployment has no secret storage configured.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

put/v1/secrets/{name}session only

Rotate a secret

Replaces the value and leaves the name alone, so every flow referencing it keeps working and picks up the new value on its next run.

Parameters
FIELDTYPENOTES
name (path)stringrequired
Request body
FIELDTYPENOTES
valuestringrequired
descriptionstring | nulloptional
Responses
STATUSBODYWHEN
200Secret

Rotated.

400Error

Empty or over-long value.

401Error

This endpoint requires a user session.

404Error

No such secret for this tenant, or storage is not configured.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

delete/v1/secrets/{name}session only

Delete a secret

Not blocked by a flow still referencing it. Deleting a credential is usually a response to it being compromised, and "first edit four flows" is the wrong answer to that — those flows fail on their next run, naming the missing secret.

Parameters
FIELDTYPENOTES
name (path)stringrequired
Responses
STATUSBODYWHEN
204

Deleted.

401Error

This endpoint requires a user session.

404Error

No such secret for this tenant.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Billing

Plans, subscription state, checkout and the customer portal.

post/v1/billing/checkoutsession only

Start a checkout

Returns a provider-hosted URL to redirect the browser to. Orchent never sees a card.

The plan changes on the webhook, never on the redirect — the success URL is a browser navigation anyone can type, so it grants nothing.

Request body

No fields.

Responses
STATUSBODYWHEN
200CheckoutSession

Redirect the browser to checkout_url.

400Error

That plan cannot be bought self-serve.

401Error

Missing, malformed or unrecognised credentials.

404Error

Billing is not configured on this deployment.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/billing/portalsession only

Open the customer portal

Provider-hosted management: payment method, invoices, cancellation.

Responses
STATUSBODYWHEN
200PortalSession

Redirect the browser to portal_url.

401Error

Missing, malformed or unrecognised credentials.

404Error

Billing is not configured, or this tenant has no billing account yet — start a checkout first.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/billing/subscriptionsession only

This tenant's subscription

Responses
STATUSBODYWHEN
200Subscription

Subscription state. Answers even with billing switched off, reporting the real plan.

401Error

No valid session.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/billing/webhookpublic

Payment provider callback

Not for customers to call. Documented because it is a public route and an undocumented public route is worse.

Unauthenticated in the session sense and CSRF-exempt by construction: no principal is resolved, so there is no ambient credential for a cross-site form to ride on. The Stripe-Signature HMAC over the raw body *is* the authentication, and it is verified before the body is parsed. Always 200 once verified — an event we chose not to act on is not a delivery failure, and a non-2xx would make the provider retry for three days.

Responses
STATUSBODYWHEN
200WebhookAck

Received.

400Error

Signature missing, stale or forged.

404Error

No webhook secret configured, so nothing can be verified.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/planspublic

The plan catalogue

Public — the pricing page is readable before anyone signs in. The quota each plan grants is code; the *price* is read live from the payment provider, so it cannot drift from what a customer is actually charged.

Responses
STATUSBODYWHEN
200PlanList

Every plan. billing_enabled is false when this deployment has no payment provider configured.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Authoring

Write your own flows in the Orchent DSL: create, validate, test-run, publish. A published flow is runnable at `POST /v1/flows/{name}/run` like any other.

get/v1/authoring/flowsAPI key or session

Your flows

Every status, without definition. Never an engine handle.

Responses
STATUSBODYWHEN
200FlowList

Your flows.

401Error

Bad credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/authoring/flowsAPI key or session

Create a flow

Validates the definition, compiles it and creates it in the engine.

Request body
FIELDTYPENOTES
namestringrequired
descriptionstringoptional
definitionobjectrequired
input_schemaobject | nulloptional
publishbooleanoptional
Responses
STATUSBODYWHEN
201Flow

Created.

400Error

The name is not URL-safe, the definition was rejected (see error.problems), or the plan's flow limit is reached.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/authoring/flows/validateAPI key or session

Validate a definition

Entirely local: creates nothing, runs nothing, bills nothing. errors and warnings are objects with a path into the definition you sent.

Request body
FIELDTYPENOTES
definitionobjectrequired
Responses
STATUSBODYWHEN
200ValidationResult

The verdict. A rejected definition is still a 200 here — the request succeeded.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/authoring/flows/{flow_id}API key or session

One flow, with its definition

Parameters
FIELDTYPENOTES
flow_id (path)stringrequired
Responses
STATUSBODYWHEN
200Flow

The flow.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not yours, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

patch/v1/authoring/flows/{flow_id}API key or session

Update a flow

A new definition is re-validated and pushed to the engine. Editing a published flow does not change what callers get until you publish again.

Parameters
FIELDTYPENOTES
flow_id (path)stringrequired
Request body
FIELDTYPENOTES
namestring | nulloptional
descriptionstring | nulloptional
definitionobject | nulloptional
input_schemaobject | nulloptional
enabledboolean | nulloptional
Responses
STATUSBODYWHEN
200Flow

Updated.

400Error

The definition was rejected — see error.problems.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not yours, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

delete/v1/authoring/flows/{flow_id}API key or session

Delete a flow

Parameters
FIELDTYPENOTES
flow_id (path)stringrequired
Responses
STATUSBODYWHEN
204

Deleted.

400Error

It is published. Unpublish first.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not yours, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/authoring/flows/{flow_id}/publishAPI key or session

Publish a flow

Snapshots the definition and makes the flow runnable — and billable — at POST /v1/flows/{name}/run. Refused while the flow is disabled.

Parameters
FIELDTYPENOTES
flow_id (path)stringrequired
Responses
STATUSBODYWHEN
200Flow

Published.

400Error

The flow is disabled.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not yours, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/authoring/flows/{flow_id}/test-runAPI key or session

Test-run a draft

Never billed: no run row, no quota, and it works on drafts.

Parameters
FIELDTYPENOTES
flow_id (path)stringrequired
Request body
FIELDTYPENOTES
inputsobject | nulloptional
querystringoptional
streambooleanoptional
Responses
STATUSBODYWHEN
200TestRunResult

It ran.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not yours, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/authoring/flows/{flow_id}/unpublishAPI key or session

Unpublish a flow

Takes it out of the catalogue. Callers get a 404, as they would for a flow that never existed.

Parameters
FIELDTYPENOTES
flow_id (path)stringrequired
Responses
STATUSBODYWHEN
200Flow

Unpublished.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not yours, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Templates

The curated flow library, and cloning one into your account.

get/v1/templatesAPI key or session

The template library

Responses
STATUSBODYWHEN
200TemplateList

The curated library, read-only.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/templates/{template_id}API key or session

One template, with its definition

Parameters
FIELDTYPENOTES
template_id (path)stringrequired
Responses
STATUSBODYWHEN
200Template

The template.

401Error

Missing, malformed or unrecognised credentials.

404Error

No such template.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/templates/{template_id}/cloneAPI key or session

Clone a template into your account

Creates a private draft, independent of the template from then on. With no name, a name that is already taken is auto-suffixed rather than refused.

Parameters
FIELDTYPENOTES
template_id (path)stringrequired
Request body

No fields.

Responses
STATUSBODYWHEN
201Flow

Your new draft.

400Error

The name you asked for is taken or not URL-safe.

401Error

Missing, malformed or unrecognised credentials.

404Error

No such template.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Account

Data rights: take a copy of everything this account owns, or delete it. Session-only — exporting or deleting an entire account is not something a bearer key gets to do.

delete/v1/mesession only

Delete this account and everything under it

Irreversible, and there is no undo behind it, so it takes two independent confirmations: the organisation's name typed out (proves you know *which* account), and the account password re-entered (proves it is you).

In order: keys are revoked and flows unpublished so the account stops serving, the subscription is cancelled, compiled flows are deleted out of the engine, and then the tenant row goes — cascading to users, keys, sessions, runs, usage, billing events, authored flows and exports. Nothing is kept.

Request body
FIELDTYPENOTES
confirm_namestringoptional
passwordstringoptional
Responses
STATUSBODYWHEN
200DeletionReport

Deleted. The session cookies are cleared.

400Error

The name or the password did not confirm.

401Error

Missing, malformed or unrecognised credentials.

403Error

An API key cannot delete the account it belongs to.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/me/exportsession only

List exports

Exports expire 24 hours after they are ready.

Responses
STATUSBODYWHEN
200ExportList

This account's exports.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/me/exportsession only

Ask for a copy of everything this account owns

202, not 200: the archive is built after this returns. Poll GET /v1/me/export/{export_id} for the download link.

Responses
STATUSBODYWHEN
202Export

Accepted; the archive is being built.

401Error

Missing, malformed or unrecognised credentials.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/me/export/{export_id}session only

Poll one export

Once status is ready the body carries a download_url.

Parameters
FIELDTYPENOTES
export_id (path)stringrequired
Responses
STATUSBODYWHEN
200Export

The export.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not this account's export, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

get/v1/me/export/{export_id}/downloadsession only

Download the archive

Gzipped JSON, orchent.export.v1. Two ways in and exactly two: the session cookie, or a token from POST .../link.

Parameters
FIELDTYPENOTES
export_id (path)stringrequired
token (query)string | nulloptional
Responses
STATUSBODYWHEN
200

The archive.

401Error

Missing, malformed or unrecognised credentials.

404Error

No such export, an expired one, or a token that does not match.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

post/v1/me/export/{export_id}/linksession only

Mint a fresh download link

Rotates the token, so the previous link stops working — which is what makes an accidentally-shared link revocable. The link carries a copy of an entire account, so it expires with the export rather than being a permanent capability.

Parameters
FIELDTYPENOTES
export_id (path)stringrequired
Responses
STATUSBODYWHEN
200Export

The export, with a new download_url.

400Error

The export is not ready.

401Error

Missing, malformed or unrecognised credentials.

404Error

Not this account's export, or not there.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Service

Liveness.

get/healthzpublic

Liveness

Responses
STATUSBODYWHEN
200Health

The gateway is up.

429Error

Rate limited: over 60 requests a minute for this key. See Retry-After.

500Error

Something failed inside Orchent. request_id identifies the occurrence.

Schemas

Every object the API returns or accepts.

ApiKey
FIELDTYPENOTES
idstringrequired
namestringrequired
prefixstringrequired

The displayable head of the key, e.g. ock_live_a1b2c3. The secret itself is never returned after creation.

created_atstring | nullrequired
last_used_atstring | nulloptional
revoked_atstring | nulloptional
ApiKeyCreated
FIELDTYPENOTES
idstringrequired
namestringrequired
keystringrequired

Shown once. Orchent stores only a SHA-256 hash, so this value cannot be recovered — save it now or revoke and mint another.

ApiKeyList
FIELDTYPENOTES
keysApiKey[]required
CatalogueFlow
FIELDTYPENOTES
namestringrequired

What you pass as {flow} when you run it.

modestringrequired

chat or workflow.

descriptionstring | nullrequired
input_schemaobject | nullrequired

The flow's declared inputs, or null when its author declared none. A declaration, not a validator — a run whose inputs contradict it is not rejected.

CatalogueFlowList
FIELDTYPENOTES
flowsCatalogueFlow[]required
CheckoutBody
FIELDTYPENOTES
planstringoptional
CheckoutSession
FIELDTYPENOTES
checkout_urlstringrequired
CloneBody
FIELDTYPENOTES
namestring | nulloptional
CreateFlowBody
FIELDTYPENOTES
namestringrequired
descriptionstringoptional
definitionobjectrequired
input_schemaobject | nulloptional
publishbooleanoptional
DeleteAccountBody

Two independent confirmations, both required. See data_rights.confirmation_problem for why neither alone is enough.

FIELDTYPENOTES
confirm_namestringoptional
passwordstringoptional
DeletionReport
FIELDTYPENOTES
tenant_idstringrequired
tenant_namestringoptional
deletedbooleanrequired

Whether the tenant row is gone.

rows_deletedobjectrequired

What was there, per table.

rows_remainingobjectrequired

What is still there, per table. Empty is the expected answer; anything in it is a cascade that did not fire.

keys_revokedintegeroptional
flows_unpublishedintegeroptional
sessions_endedintegeroptional
engine_flowsobjectoptional

Compiled flows removed from the engine.

subscriptionobject | nulloptional

What happened to the subscription, if there was one.

EmailSent
FIELDTYPENOTES
statusstringrequired

Deliberately coarse. Whether the provider accepted the message is not reported, because the customer cannot act on the difference and the honest next step either way is to look in their inbox. One of sent, already_verified, reset.

messagestringoptional

Text safe to show the customer.

EmailVerified
FIELDTYPENOTES
verifiedbooleanrequired
emailstringrequired
Error
FIELDTYPENOTES
errorobjectrequired
Export
FIELDTYPENOTES
idstringrequired
statusstringrequired

pending until the archive is built; expired after 24 hours. One of pending, ready, failed, expired.

requested_atstring | nullrequired
completed_atstring | nulloptional
expires_atstring | nulloptional
size_bytesinteger | nulloptional
countsobject | nulloptional

Rows per table in the archive — what you are about to download.

errorstringoptional

Present only on failed, and deliberately one fixed sentence.

download_urlstringoptional

Present once ready. From the poll endpoint it is the session-authenticated path; from POST .../link it carries a time-limited token instead.

ExportList
FIELDTYPENOTES
exportsExport[]required
Flow
FIELDTYPENOTES
idstringrequired
slugstringrequired

Identical to name. Served as an explicit alias so no client ever slugifies anything.

namestringrequired

Lowercase letters, digits and hyphens, 2–64 characters. URL-safe by construction, because it is what you call.

descriptionstring | nulloptional
modestringrequired
statusstringrequired

One of draft, published.

enabledbooleanrequired
runnablebooleanrequired

Published and enabled: whether POST /v1/flows/{name}/run will find it.

input_schemaobject | nulloptional
template_idstring | nulloptional
node_countintegerrequired
published_versioninteger | nulloptional
published_atstring | nulloptional
has_unpublished_changesbooleanoptional
created_atstring | nullrequired
updated_atstring | nullrequired
definitionobject | nulloptional

The Orchent DSL graph. Present everywhere except the listing.

FlowList
FIELDTYPENOTES
flowsFlow[]required
ForgotBody
FIELDTYPENOTES
emailstringrequired
Health
FIELDTYPENOTES
statusstringrequired
Identity
FIELDTYPENOTES
userUserrequired
tenantTenantrequired
KeyBody
FIELDTYPENOTES
namestringrequired
LoginBody
FIELDTYPENOTES
emailstringrequired
passwordstringrequired
Plan
FIELDTYPENOTES
idstringrequired
namestringrequired
taglinestringrequired
featuresstring[]required
runs_limitinteger | nullrequired

Runs a month. null means unmetered.

purchasablebooleanrequired

Whether POST /v1/billing/checkout will sell it. False for every plan when billing is not configured on this deployment.

pricePricerequired
PlanList
FIELDTYPENOTES
billing_enabledbooleanrequired
plansPlan[]required
PortalSession
FIELDTYPENOTES
portal_urlstringrequired
Price

Read live from the payment provider; null when there is nothing to read it from. The amount is never written down in Orchent.

FIELDTYPENOTES
amount_centsinteger | nulloptional
currencystringoptional
intervalstringoptional
Problem
FIELDTYPENOTES
codestringrequired

e.g. unknown_node_type, host_not_allowed.

messagestringrequired
pathstring | nulloptional

Where in the submitted definition, e.g. nodes[2].config.url.

nodestring | nulloptional
Quota
FIELDTYPENOTES
runs_limitinteger | nullrequired

null on an unmetered plan.

runs_usedintegerrequired

Runs so far this calendar month.

ResetBody
FIELDTYPENOTES
tokenstringrequired
passwordstringrequired
RunDetail
FIELDTYPENOTES
idstringrequired
flowstringrequired
statusstringrequired
duration_msinteger | nulloptional
tokensinteger | nulloptional
created_atstring | nullrequired
streamedbooleanrequired
inputsanyoptional
outputsanyoptional
errorstring | nulloptional
RunList
FIELDTYPENOTES
runsRunSummary[]required
next_cursorstring | nullrequired

Pass back as cursor for the next page. null on the last one.

RunResult
FIELDTYPENOTES
run_idstringrequired
answerstring | nulloptional
outputsanyoptional
tokensinteger | nulloptional
duration_msinteger | nulloptional
RunSummary
FIELDTYPENOTES
idstringrequired
flowstringrequired
statusstringrequired

succeeded or failed.

duration_msinteger | nulloptional
tokensinteger | nulloptional
created_atstring | nullrequired
Secret
FIELDTYPENOTES
namestringrequired

How a flow refers to it: {{secret:NAME}}. [A-Za-z][A-Za-z0-9_.-]{0,63}.

fingerprintstringrequired

A short keyed, one-way digest of the value — not a prefix of it and not reversible. It exists so you can tell whether a rotation landed, and whether this is the same value as the one in your CI, without the value ever crossing the wire.

descriptionstringrequired
key_versionintegeroptional

Which generation of the encryption key seals this value. Bookkeeping for key rotation; nothing a caller acts on.

created_atstring | nullrequired
updated_atstring | nullrequired
created_bystring | nulloptional
updated_bystring | nulloptional
last_used_atstring | nulloptional
SecretBody
FIELDTYPENOTES
namestringrequired
valuestringrequired
descriptionstringoptional
SecretList
FIELDTYPENOTES
secretsSecret[]required
limitinteger | nullrequired

How many your plan allows; null is unmetered.

enabledbooleanrequired

false on a deployment with no encryption key configured. Reads still answer; every write returns 404 with an explanation.

SecretValueBody

A rotation. The name is in the path; only the value changes.

FIELDTYPENOTES
valuestringrequired
descriptionstring | nulloptional
SignupBody
FIELDTYPENOTES
emailstringrequired
passwordstringrequired
tenant_namestringrequired
Subscription
FIELDTYPENOTES
planstringrequired
statusstring | nullrequired

The provider's status verbatim (active, trialing, past_due, unpaid, canceled, …), or null if there has never been one.

current_period_endstring | nulloptional
customer_idstring | nulloptional
billing_enabledbooleanrequired
manageablebooleanrequired

Whether POST /v1/billing/portal will work — it needs a billing account to point at.

needs_attentionbooleanrequired

True for the states a customer has to act on, so a client does not have to learn the provider's vocabulary.

Template
FIELDTYPENOTES
idstringrequired
namestringrequired
descriptionstring | nulloptional
categorystring | nulloptional
modestringrequired
input_schemaobject | nulloptional
versionintegerrequired
definitionobject | nulloptional

Present on the detail endpoint only.

TemplateList
FIELDTYPENOTES
templatesTemplate[]required
Tenant
FIELDTYPENOTES
idstringrequired
namestringrequired
planstringrequired

free, pro or unlimited.

TestRunBody
FIELDTYPENOTES
inputsobject | nulloptional
querystringoptional
streambooleanoptional
TestRunResult
FIELDTYPENOTES
flowstringrequired
answerstring | nulloptional
outputsanyoptional
tokensinteger | nulloptional
duration_msinteger | nulloptional
billedbooleanrequired

Always false. A test run creates no run row and spends no quota.

UpdateFlowBody
FIELDTYPENOTES
namestring | nulloptional
descriptionstring | nulloptional
definitionobject | nulloptional
input_schemaobject | nulloptional
enabledboolean | nulloptional
Usage
FIELDTYPENOTES
bucketsUsageBucket[]required
totalsobjectrequired
quotaQuotarequired
UsageBucket
FIELDTYPENOTES
datestringrequired
runsintegerrequired
tokensintegerrequired
User
FIELDTYPENOTES
idstringrequired
emailstringrequired
ValidateBody
FIELDTYPENOTES
definitionobjectrequired
ValidationResult
FIELDTYPENOTES
okbooleanrequired
errorsProblem[]required
warningsProblem[]required
VerifyBody
FIELDTYPENOTES
tokenstringrequired
WebhookAck
FIELDTYPENOTES
receivedbooleanrequired
outcomestringrequired

One of applied, duplicate, ignored, unattributed.