Stored credentials
Tokenization replaces a stored password with a token: an identifier and a key that mean “run that access, through this application, for that customer, for these features” — and nothing else, anywhere else. You keep the key half; the platform keeps the credentials, encrypted under something only your key can derive.
(The token’s first run can also happen in an experience INFONITE hosts — a Financial Rider session, where your customer signs in to their bank in our widget, which is what we call recurring access.)
Tokenization is enabled per application. If yours does not have it, asking for tokenized_access when you start an execution is refused with 403 and detail: insufficient_capabilities@login:tokenized_access — no ticket is ever issued, and no execution is created. The part before the @ is the stable code to branch on; what follows names the capability you are missing. A sandbox run is never refused for it: every application may rehearse anything.
Recurring access in production needs Tokenized access
Every application can tokenize in sandbox. In production, asking for tokenized_access without the Tokenized access capability is refused with 403 and insufficient_capabilities@login:tokenized_access — no ticket is issued and nothing is created.
And per engine. Not every engine can keep credentials: each one says so in tokenized_access, on List your engines and Show engine details. Banks, telcos and utilities — sources worth reading again — typically can. Asking an engine that cannot is refused before anything is created: 400 with T10N_NOT_AVAILABLE.
How you get a token
Ask for a ticket when you start an execution
Send base_configurations.tokenized_access: true to Initiate with parameters. The 202 comes back with a ticket — a single-use, short-lived string that exists only to be exchanged.
Exchange it, once
Exchange a ticket takes the execution_id and the ticket, and returns the real thing: a token_id and a token_key, plus the context the token is locked to.
Use it instead of credentials
Initiate with a token takes token where the other endpoint takes parameters. Everything else about the execution behaves identically.
Store both halves, and treat token_key like a password. It is the only copy — no screen, no endpoint and no support agent will read it back to you, because nothing on our side holds it. Lose it and the stored credentials can never be opened again, by anyone — until your customer connects the same account again, which renews the token with a new key. Why that is, and why it is deliberate.
What a token is allowed to do
The scope is fixed at the exchange, and no run can widen it.
Need a wider scope? Run a parametrized execution with the credentials and the features you want, and exchange its ticket: that renews the token with the new scope. That is deliberate: broadening what stored credentials may reach should require the credentials again.
Validity is 90 days from the exchange, and using the token does not extend it. When the date arrives, the stored credentials are deleted and the token stops existing.
Put the renewal in your calendar, not in your incident log. A quarterly re-run that never re-mints its tokens works perfectly for three months and then fails for everybody at once. Read date_expiration from Check a token, and renew the connection before it lapses — a new execution with the credentials, and its ticket exchanged: the same token_id, a new key and a new date.
One token per connection
A connection is your application, one engine, one customer_id of yours and one account at that source — the account is what locking_hash identifies. A connection has one token for life, and token_id is the field that never changes: it is the identifier to keep your customers’ connections by.
Exchanging a ticket for a connection you already hold a token for does not mint a second token, and does not revoke the one you have: it renews it. Same document, same token_id; what changes is the key, and with it what the token holds.
Keeping the list
Every exchange answer goes into your list by token_id: there is no other field to match on, nothing to deduplicate, and no need to compare locking_hash yourself. Managing your customers’ connections is the practical guide — what to keep per connection, the connect, reconnect and remove flows, what each row shows, and the upsert in code.
Renewing is not revoking. A renewal keeps the connection and changes its key; Revoke a token ends the connection — the credentials are deleted, and if your customer connects that account again later, it is a new connection with a new token_id.
Reading a token’s health
Check a token is the endpoint to call before a batch, and the one that explains a refusal.
A tokenized execution against a locked token answers 423 rather than starting, so a batch fails fast instead of hammering an institution with credentials it has already rejected.
A locked token means a person has to act — retrying makes it worse. Institutions count failed logins, and enough of them locks the account for your customer, not just for you.
Revoking
Revoke a token revokes it immediately and marks the stored credentials for deletion. Call it when a customer withdraws consent, closes their account with you, or asks you to stop — and after any suspicion that your half leaked.
Revoking does not touch executions already run with that token, nor the records they produced: those are removed with Delete an execution.
Your customer’s right to be forgotten is two calls, not a support ticket. Revoke the token, delete the executions. Both are immediate and neither needs us.
locking_hash, and recognising a returning login
Every execution that gets as far as authenticating publishes a locking_hash: a stable fingerprint of the fixed part of the credentials — the username, typically, or whatever the engine’s locking_fields declare. The same access always produces the same value, and the value reveals nothing.
It is what the platform uses to tell one account from another — the fourth part of a connection — without storing what the login is. You do not need to compare it yourself to recognise a returning login: the exchange already does, and answers with the token_id you have. It stays useful before any token exists — an execution’s locking_hash tells you which account it read.