Automate OTP submission
Build a service that receives an OTP request and submits the code without a human in the dashboard.
Automate OTP submission
Banks that enforce two-factor login normally need a person to type the one-time code. If your code arrives somewhere a machine can read it — an SMS gateway, an email inbox, an authenticator service — you can close that loop automatically. This guide builds a service that learns when a code is needed and submits it through the External API.
For the concepts behind this flow, see Assisted login and OTP.
Before you start
You will need:
- An account set to
login_mode: assisted. See Sessions. - A way to obtain the code programmatically (for example, a webhook from your SMS provider).
- A Reconbanker login, so you can create an API key.
Step 1: Create an API key
Create a key with the scopes your service needs. Use otp:write to submit codes and status:read if you intend to poll for status.
POST /me/api-keys
Content-Type: application/json
Authorization: Bearer <jwt>{
"name": "SMS relay",
"scopes": ["otp:write", "status:read"],
"account_ids": ["7e9a2b3c-4d5e-4f6a-9b8c-1d2e3f4a5b6c"]
}Store the returned key somewhere safe — it is shown only once. Set account_ids to the accounts this service may act on, or leave it null for all of them. See API keys for the full reference.
Step 2: Learn when a code is needed
Pick one of two patterns.
Option A — Push (notification webhook)
Subscribe the account to the assistance_required event so Reconbanker calls you the instant a code is requested. On the account's settings, set the notification endpoint and events (see Notification settings):
{
"notification_endpoint_url": "https://your-service.example/reconbanker/notify",
"notification_auth_type": "bearer",
"notification_auth_token": "<your-token>",
"notification_events": ["assistance_required"]
}Your endpoint then receives:
{
"account_id": "b9c224b3-3c2b-42bd-b23e-337ae0185690",
"type": "assistance_required",
"status": "assistance.requested",
"data": { "descriptor": { "length": 6, "type": "numeric" } },
"occurred_at": "2026-06-13T03:00:00.000Z"
}Option B — Poll (status endpoint)
If you would rather not expose an endpoint, poll the account status and act when pending_assistance appears:
GET /v1/accounts/:accountId/status
Authorization: Api-Key rbk_abcd1234_secret...{
"account_id": "b9c224b3-3c2b-42bd-b23e-337ae0185690",
"session_running": true,
"pending_assistance": {
"id": "req-1",
"type": "otp",
"descriptor": { "length": 6, "type": "numeric", "purpose": "login" },
"attempts": 0
}
}Step 3: Submit the code
Once your service has the code, submit it:
POST /v1/accounts/:accountId/otp
Content-Type: application/json
Authorization: Api-Key rbk_abcd1234_secret...{ "code": "123456" }A 202 Accepted ({ "submitted": true }) means Reconbanker took the code and forwarded it to the waiting login. It does not yet mean the bank accepted it. This endpoint is rate-limited, so submit once per code rather than retrying in a tight loop.
Testing locally
Run a tiny listener to see the notification webhook payload (Option A):
node -e "require('http').createServer((req,res)=>{let b='';req.on('data',c=>b+=c);req.on('end',()=>{console.log(req.method,req.url,b);res.end('ok')})}).listen(4000)"Point notification_endpoint_url at it (use a tunnel such as ngrok if Reconbanker runs elsewhere), then trigger an assisted login. You can exercise the /v1 endpoints directly with curl:
curl -sX POST https://reconbanker.your-domain.com/v1/accounts/$ACCOUNT_ID/otp \
-H "Authorization: Api-Key $RBK_KEY" \
-H "Content-Type: application/json" \
-d '{"code":"123456"}'What happens next
Reconbanker forwards the code and the login continues. To confirm success, watch the account status: when the code is accepted, pending_assistance clears back to null. A rejection surfaces as a login_failed event, which you can receive through the notification webhook. (The dashboard realtime stream additionally emits an assistance.fulfilled event, but that one is not delivered to the notification webhook.) If a login keeps failing, the account can be blocked until you intervene.