Account Security
Three controls the account holder configures and the API then enforces on every attempt to move money out: cashout locks, transaction PIN and visibility of who else has access to the account.
They exist for the scenario where the integrator’s credential and token are correct — and it is the account holder’s session that was taken over. Nothing here is opt-out per request: what the holder configured applies even to the credential that configured it.
Every account starts with no lock and no PIN, and behaves exactly as it does today. The controls only apply once configured.
Cashout locks
account security locks are three independent limits:
Read
Write
PUT takes the whole desired document (scope security_locks.manage):
Tightening applies now; loosening waits 6 hours
This is the part that changes your flow, so it is worth reading closely: the decision is made field by field.
Someone who turns the block on and widens the window in the same call gets the block now and the window later. The response says exactly that:
The asymmetry is the whole design: whoever took over the account wants to turn off the block, widen the window, add their own IP — never to tighten. A symmetric grace period would protect the attacker and punish the holder who is reacting to fraud in progress.
Cancelling or bringing forward the loosening
Bringing it forward is the only path that shortens the grace period, which is why it costs the one thing whoever hijacked the session does not have: the PIN. Without this endpoint, the legitimate holder who wants their own cashout back would have to wait 6h with no alternative.
X-Acting-Ip
When the call comes from a server of yours on the account holder’s behalf (the internet banking case), the connection IP is your server’s, not the end user’s. cashoutSourceIps would be useless. Pass the user’s real IP in X-Acting-Ip — that is the one the lock evaluates.
The header is only accepted from integrator credentials. A delegated credential is used directly by its owner, so the connection IP is already the right one and X-Acting-Ip is ignored.
Errors
Transaction PIN
The PIN belongs to the operator (identified by the document in X-Acting-Document), not to the account. An account with three authorized people has three PINs; locking one does not affect the others.
It is only required when the caller’s credential is marked for it — in practice, the internet banking credential, where a single credential serves many account holders and the token alone cannot tell who is on the other side of the screen.
Register and change
Changing an existing PIN requires the current one in the same body (currentPin). Without that, whoever hijacked the session would simply change the PIN and the PIN would stop protecting anything.
The scope is pin.manage. The PIN never appears in a log or a response — it is stored as an argon2id hash and the clear value is discarded.
PIN rules
A rejected PIN returns 422 weak_pin with the reason named.
Use
On cashout routes (PIX out, TED, boleto, internal transfer), when the credential requires a PIN:
Missing either one returns 428 pin_required.
Lockout
A correct PIN resets the counter. To clear the 6-attempt case, whoever administers the account invalidates that operator’s PIN and they register a new one:
Verify before building the payment
This exists so the UI can confirm the PIN before the payment form. Without it, the user would only find out the PIN was wrong at the end of the flow — and each mistake would burn one of the 3 attempts. A wrong attempt here counts the same: the endpoint is not a free oracle.
Operator status
Documents come back masked. lockedUntil: null with requiresReset: true is the hard lock — the way out is resetting, not waiting.
Errors
Shared access
The same bank account can be reached by more than one tenant — the account holder hired two systems, or migrated from one to another and the old one still has access. The holder is entitled to see that:
Public metadata only: display name, state and since when. No credentials, volume, balance or configuration of the other tenants. status is the state of that tenant’s access to the account, not of the tenant itself — a suspended row shows up precisely so the holder can confirm a revocation took effect.
Read scope. Revoking access is a backoffice operation, not this route.
See also
- Cashout — the outgoing routes where locks and PIN apply
- Request Signing — the other half of the design: one credential per account
- Errors — full catalog