Initiate with a token

View as Markdown
Start an execution with a **stored token** instead of credentials: you send the token, the platform recovers the access it stands for, and the engine logs in with it. You never held the password, and this endpoint does not return it. Everything else behaves like [Initiate with parameters](api:POST/executions/init/v1/parametrized) — same `202`, same `execution_id`, same way of following it and reading its results. <Note> **New to tokenization?** [Credential Tokenization](/guides/credential-tokenization) is the explanation — what a token is, which half each side holds, why neither of us can open the credentials alone, and how long it lives. Read it before you build against this endpoint. **And this is never the first run.** A token exists only because an earlier [parametrized execution](api:POST/executions/init/v1/parametrized) asked for `base_configurations.tokenized_access`, came back with a `ticket`, and that ticket was exchanged — once — at [Exchange a Ticket](api:PUT/executions/t10n). No token yet? That is where to start. The same per-application capability that allowed that run is what allows this one. </Note> <Warning> **`customer_interaction_available` matters most on this call.** As covered in [Initiate with parameters](api:POST/executions/init/v1/parametrized), it decides whether the source may contact your customer — and a token is usually a scheduled refresh nobody is watching. Left at `false`, no SMS or push is ever sent: the run ends with `CUSTOMER_INTERVENTION_REQUIRED` instead of waking somebody up. </Warning> ## The token decides who and where Three things are **not yours to choose here** — they were fixed when the token was minted, and sending them changes nothing: <CardGroup cols={2}> <Card title="customer_id" icon="fa-solid fa-user"> Comes from the token, exactly as you sent it on the first run. </Card> <Card title="engine_reference" icon="fa-solid fa-plug"> Comes from the token. One token, one source, for life. </Card> </CardGroup> <CardGroup cols={1}> <Card title="The credentials" icon="fa-solid fa-key"> Recovered from storage. There is no `parameters` field on this request at all. </Card> </CardGroup> What you can still choose is `features` — **from the set the token was scoped to**, never beyond it. Asking for fewer is normal; asking for one outside the original scope is refused. If you need a wider scope, run a parametrized execution with the features you want and mint a new token from it: broadening what stored credentials may reach should require the credentials again. `base_configurations`, `external_execution_id` and `hooks_extra_data` work exactly as they do on the parametrized request — with one field missing from the block: **`tokenized_access` is not part of a tokenized request.** This run is already tokenized, and a token cannot ask for a ticket. Sending it anyway is ignored rather than refused, so an integration that shares one payload builder between both calls keeps working. ## What the answers mean | Status | Meaning | | :--- | :--- | | `202` | Accepted and queued, with the `execution_id` to follow. | | `403` | **Two refusals, told apart by `detail`.** `t10n_not_found` is the vague one on purpose — no such token, or the wrong key — because guessing tokens must teach nobody anything. `app_t10_disabled` (or `app_t10_forbidden`) is the other: your application is not enabled to tokenize, checked before the body is read and nothing to do with this token. | | `423` | **The token is locked**, so nothing was launched. `T10N_LOGIN_LOCK` means the source rejected the stored credentials and only your customer can fix it; `T10N_SYSTEM_LOCK` is ours and usually passes. | | `400` | Refused before creating anything — `T10N_REJECTED` for a revoked or broken token, `T10N_EXCEPTION` when the stored credentials could not be read. Both need a new token, not a retry. | | `409` | An execution is already running on this token. The body names it; follow that one. | | `503` | The engine is not available. Not your request — retry later, or check the catalogue. | <Warning> **A locked token means a person has to act, and retrying makes it worse.** Institutions count failed logins, and enough of them locks the account for your customer, not just for you. Read [Token Status](api:GET/executions/t10n/{token_id}) before a batch, and drop the tokens that are not `T10N_OK` or `T10N_KO` from the run. </Warning> <Note> **Server to server only.** This call is authorised with your application secret: it belongs in your backend, never in a browser, a mobile app or anything your customer can read. A leaked secret launches executions on your account. </Note>

Authentication

X-APP-SECRETstring
Application Secret

Request

This endpoint expects an object.
tokenobjectRequired

The pair that stands in for a customer’s credentials: an identifier and a key.

It is what Exchange a Ticket handed you — once — in return for the ticket a first execution issued, and what you send back to run that access again without holding the password.

The two halves are not interchangeable. The id says WHICH stored credentials; the key is what makes them readable, together with a secret that never leaves our runtime. Send both, and keep the key as you keep a password: nothing here will ever show it to you again. The Credential Tokenization guide explains the shared-custody model behind that.

The key can travel encrypted, like any other secret you send us: either value may be rsa::… or hybrid::…, or the whole object may be one encrypted string. How to encrypt it.

external_execution_idstringOptional1-64 characters

Your own reference for this run — a case number, a job id, whatever your system calls it. We store it, echo it back on every state and event, and offer it as {external_execution_id} in the URL of the webhooks we deliver. We never interpret it.

It has one effect: a second execution with the same reference, for the same customer and still running, is refused with 409. That is also what lets you run one engine twice at once — give each run a different reference.

base_configurationsobjectOptional

How the execution behaves, as opposed to what it retrieves. Every setting has a default, so the block is optional — but customer_interaction_available decides the shape of your integration and, with it, whether your customer’s phone rings. Choose it on every request.

featureslist of objectsOptional

What to retrieve. Every feature is a name — accounts_read, labor_check — and you may send it as the bare string, or as an object when you want to configure it: {"code": "accounts_read", "configurations": {…}}.

The features an engine offers, and the settings each one accepts, are in Show Engine Details. Ask for one it does not implement and it is ignored: no data, no error, and nothing in the results to say it was skipped — which is why the list is built from the catalogue. Ask only for what you will use: each feature is more time inside the source, and a slow one holds the whole execution.

hooks_extra_datamap from strings to stringsOptionalDefaults to {}

Your own context, carried into every webhook this execution delivers. Each key and value is appended to the delivery as a query parameter, so a handler reads it without opening the body.

A value may also be a template variable — {external_execution_id}, {event}, {status_reason}… — replaced with this execution’s own data at send time; anything else is sent verbatim. The full list, and the rest of the delivery contract, is in Webhooks.

Never put secrets here. Query strings end up in access logs and proxies; your endpoint’s authentication belongs in its header.

configurationsmap from strings to anyOptional

Engine-specific settings, and almost always empty. An engine takes what it needs through parameters and features; this is for the rare source that asks for something structural on top, and that engine declares exactly what in its own spec at Show Engine Details.

If you are wondering whether the engine you are integrating needs one: it does not. The handful that do are unmistakable about it.

Response

202 Accepted
Accepted, not finished. The execution is queued; what the source says comes later, in the state and in the events.

app_idstringformat: "object-id"

The application this execution was launched with — the one your secret belongs to. Worth keeping when your product uses more than one, a sandbox and a production app being the usual case: every record and every event we send carries it.

customer_idstring

The customer_id you supplied when the execution was initialised, returned as you sent it — so an answer can be routed to the right case with no lookup on your side.

auth_originenum

How the call that created the execution was authorised: an application secret for a server-to-server call, or a user session when it was launched from a console. An audit field — it says who started the run, not how it went.

engine_referencestringformat: "engine-reference"
The engine this execution runs, exactly as the catalogue publishes it. It is echoed on every event and every record, so a stored result says which source it came from with no lookup on your side.
status_reasonenum

The precise cause of the state. Every reason belongs to exactly one status_code family and its wording never changes, so it is safe to branch on — read status_code when the family is all you need, and see the lifecycle for what each one asks of you.

  • Reasons for ONGOING:
    • ACCEPTED: queued, nothing has started yet.
    • WAITING: picked up, the engine is warming up.
    • RUNNING: logged in and extracting.
    • ASYNC_WAIT: waiting on the source to produce something on its own schedule.
  • Reasons for ACTION_REQUIRED:
    • MFA_REQUIRED: the source asked for a strong-authentication factor.
    • INPUT_REQUIRED: the engine needs another field it could not know in advance.
  • Reasons for COMPLETED:
    • COMPLETED: every requested feature answered.
  • Reasons for PARTIAL:
    • PARTIAL: finished, with some features answered and others not.
  • Reasons for FAILED:
    • FAILED: finished, and nothing could be retrieved.
  • Reasons for ABORTED:
    • CLIENT_CANCELLED: you aborted it.
    • USER_CANCELLED: your customer abandoned it.
    • ACTION_TIMEOUT: nobody answered the challenge in time.
    • TIMEOUT: the run exceeded its execution_timeout.
    • CUSTOMER_INTERVENTION_REQUIRED: a person was needed and none was available.
    • SYSTEM_CANCELLED: the platform stopped it.
  • Reasons for AUTH_ERROR — the source refused the login, and retrying the same values will not help:
    • INCORRECT_CREDENTIALS: rejected. Ask your customer for them again.
    • INCORRECT_MFA: the challenge was answered wrongly.
    • BLOCKED_USER: the institution has blocked the access.
    • FRIEZED_CREDENTIALS: the access is temporarily frozen.
    • CHANGE_PASSWORD: the institution requires a password change first.
    • MANUAL_INTERVENTION: the person must do something in the source’s own channel.
    • INCOMPATIBLE_ACCESS: this access does not work through this engine’s channel.
    • DUPLICATED_SESSION: another session is already open for that user.
  • Reasons for UNHANDLED_AUTH_ERROR:
    • UNHANDLED_AUTH_ERROR: the login failed in a way we could not classify.
  • Reasons for CONFIGURATION_ERROR — the request itself, so retrying it unchanged fails the same way:
    • BAD_CONFIGURATIONS: a feature configuration the engine does not accept.
    • INCORRECT_PARAMETERS_FORMAT: the parameters did not match the engine’s form.
    • INCORRECT_RESUME_FORMAT: the resume body did not match the published form.
    • ENCRYPTION_ERROR: an encrypted value could not be opened.
    • T10N_FORBIDDEN: your application may not tokenize.
    • T10N_NOT_AVAILABLE: this engine does not support tokenization.
    • T10N_REJECTED: the token is revoked or broken.
    • T10N_EXCEPTION: the stored credentials could not be read.
    • BAD_PROXY_CONFIGURATION: ours, not yours — contact support.
  • Reasons for TEMPORARY_ERROR — nothing is wrong with your request, retry later:
    • OUT_OF_SERVICE: the source itself is unavailable.
    • ENGINE_UNAVAILABLE: the engine is not serving right now.
    • ALREADY_EXECUTING: another execution is already running for that access.
    • ENGINE_BANNED, AUTO_CAPTCHA_ERROR, PROXY_ERROR, NETWORK_ERROR, INTERNAL_ERROR: the run could not be set up. Ours, and transient.

AUTH_OK belongs to this vocabulary too, but it only ever appears in authentication_status: a login that succeeds leaves the execution ONGOING.

status_codeenumRead-only

The family a state belongs to, and the value to branch on: it is always present, and every status_reason belongs to exactly one of these. The precise cause lives in the reason — read it when the family is not specific enough to decide. Allowed values are:

  • ONGOING: The execution is ongoing
  • ACTION_REQUIRED: The execution is waiting for an input
  • COMPLETED: The execution has been completed
  • ABORTED: The execution has been aborted
  • CONFIGURATION_ERROR: The execution has been rejected due to a configuration error
  • PARTIAL: The execution has been completed with errors
  • TEMPORARY_ERROR: The execution cannot be processed due to a temporary error
  • AUTH_ERROR: The execution failed due to an authentication error
  • UNHANDLED_AUTH_ERROR: The execution failed during the login because of an unhandled error
  • FAILED: The execution has failed
execution_idstringOptionalformat: "object-id"

The handle to this execution, and the one value worth storing from this response: you poll it for the state, you match it against the webhooks we deliver, and every results endpoint is addressed by it.

Present only when the execution was created. A request refused before that — a collision, an invalid configuration — answers without it.

session_idstringOptionalformat: "object-id"

The session this execution belongs to. An execution launched on its own is its own session, so today the two values usually match — treat them as two independent identifiers anyway: an execution can be one step of a wider journey, and a run you are pointed at is not always the one you asked for.

Address results and state by execution_id. Like it, this is only present when an execution was created.

external_execution_idstringOptional

The reference you attached when the execution was started, if you sent one — echoed so your own identifier travels beside ours, on this response and on every event.

status_messagestringOptional

A human-readable note, when there is one to add. It is diagnostic and never a contract: do not parse it and do not show it to your end user as it comes — branch on status_reason and write your own copy.

session_tokenstringOptional

A short-lived token that authorises acting on this execution and nothing else: it cannot read a single extracted record, and it stops working when the execution ends.

Resolving a pause through this API needs none of it — collect the value and send it to the resume endpoint. The token is for the other option, which is coming: handing that moment to a minimal hosted interface instead of building the screens yourself. Not a flow — no journey, no consent step, no branding, just what a pause needs over the execution you already started. Until it ships there is nothing to present this token to, so you can safely ignore it.

The prefix says which kind of run issued it: st_test_ when the run is a rehearsal — a sandbox application, or a sandbox engine under a production one — and st_live_ otherwise.

Errors

400
Bad Request Error
403
Forbidden Error
404
Not Found Error
409
Conflict Error
422
Unprocessable Entity Error
423
Locked Error
503
Service Unavailable Error