Workflow Webhooks
Use workflow webhooks for broker events that should reach Returning.AI quickly: registration, KYC, first deposit, account status changes, reward redemptions, and other lifecycle events.
Handshake first
The workflow API key belongs only on the handshake request. The main webhook request should use the short-lived x-session-token returned by the handshake. Do not put the workflow API key in browser code.
Flow
- 1. Broker backend receives an event. For example, a trader registers, completes KYC, makes a first deposit, or redeems a reward.
- 2. Broker backend calls the handshake URL. Send the workflow API key in
Authorizationorx-api-key. - 3. Returning.AI returns data.sessionToken. Treat it as short-lived. The current TTL is 300 seconds.
- 4. Broker backend calls the main webhook. Send the session token in
x-session-tokenwith the event payload.
async function sendRegistration(user) {
const handshake = await fetch(process.env.RAI_REGISTRATION_HANDSHAKE_URL, {
method: 'POST',
headers: {
Authorization: process.env.RAI_WORKFLOW_API_KEY,
'Content-Type': 'application/json',
},
})
if (!handshake.ok) {
throw new Error('Returning.AI webhook handshake failed')
}
const handshakeBody = await handshake.json()
const sessionToken = handshakeBody.data?.sessionToken
if (!sessionToken) {
throw new Error('Returning.AI handshake did not return data.sessionToken')
}
const response = await fetch(process.env.RAI_REGISTRATION_WEBHOOK_URL, {
method: 'POST',
headers: {
'x-session-token': sessionToken,
'Content-Type': 'application/json',
},
body: JSON.stringify({
eventType: 'user.registered',
customerId: user.customerId,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
occurredAt: new Date().toISOString(),
}),
})
if (!response.ok) {
throw new Error('Returning.AI registration webhook failed')
}
}Response shape
The handshake response nests the session token under data.sessionToken. Older examples that read a top-level sessionToken should be updated.
// Handshake response
{
"success": true,
"data": {
"sessionToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 300
}
}
// Main webhook response
{
"success": true,
"data": {
"received": true
}
}Payload guidance
- Use a stable broker identifier such as customerId as the primary mapping key.
- Include trading account logins separately when one customer can have multiple MT4 or MT5 accounts.
- Send occurredAt from the broker event time, not from retry time.
- Include idempotency keys for events that may retry.
- Do not send raw access keys, MT passwords, or private platform credentials.
Legacy direct API key mode
Some older workflows accepted the API key directly on the main webhook. Treat that as a legacy compatibility mode. New broker instructions should use the handshake/session-token flow unless Returning.AI explicitly disables token exchange for that workflow.