Webhooks
Receive signed HTTPS notifications when broker connections, orders, positions, balances, and related data change.
Finatic can POST JSON events to an HTTPS endpoint you control whenever subscribed broker data changes. Delivery is handled by FinaticBackground (Supabase Realtime → outbound HTTPS), not the public Finatic API.
Tip: Configure webhooks in the Finatic web app under team settings → Webhooks. There is no Finatic SDK method for registering endpoints today; treat the endpoint URL and signing secret like production credentials.
What you configure
- HTTPS URL — Finatic only delivers to URLs that start with
https://. - Secret — Used to compute
X-Finatic-Signature. You can rotate it from team settings. - Modes —
live,paper, and where applicablesandbox. - Event types — One subscription row per
(endpoint, mode, event_type).
Event types
The catalog below matches the event strings Finatic uses in subscriptions and headers. The Finatic web UI event picker may lag the full server list; subscribe to anything your integration needs even if it is not shown in the dashboard yet.
Connection
connection.addedconnection.updatedconnection.removed
Orders
account.orders.addedaccount.orders.updatedaccount.orders.removed
Positions
account.positions.addedaccount.positions.updatedaccount.positions.removed
Balances
account.balances.addedaccount.balances.updatedaccount.balances.removed
Transactions (when enabled for your data plane)
account.transactions.addedaccount.transactions.updatedaccount.transactions.removed
Request shape
Each POST body is a JSON object with (at minimum):
schema_version— envelope version (currently1).event_id— unique id for this delivery (also sent asX-Finatic-Event-Id).event_type— same string you subscribed to (alsoX-Finatic-Event).mode—live,paper, orsandbox.delivery—livefor real traffic,testfor dashboard test sends (X-Finatic-Deliverymirrors this).occurred_at— ISO timestamp.user_broker_connection_id— Finatic broker connection this event belongs to.company_id— team account that owns the connection.summary— short human-readable summary.resource— identifies the row that changed (schemais alwaysbroker_datain JSON, withtable,operation, and optionalid).data— typically includes trimmedold/newrow snapshots and may include extra metadata the worker attaches for large or bundled updates.
Headers
Finatic sends at least:
Content-Type: application/jsonUser-Agent: Finatic-Webhooks/3.0X-Finatic-EventX-Finatic-Event-IdX-Finatic-DeliveryX-Finatic-Signature: sha256=<hex>when a secret is configuredThe signature is HMAC-SHA256 over the exact UTF-8 JSON body Finatic posts. The JSON is serialized with sorted object keys at every nesting level (same rule as
JSON.stringifyafter recursive key sort, and Pythonjson.dumps(..., sort_keys=True)).Verifying signatures (Node.js)
1import { createHmac } from 'node:crypto'; 2 3function sortKeysDeep(value: unknown): unknown { 4if (value === null || typeof value !== 'object') return value; 5if (Array.isArray(value)) return value.map(sortKeysDeep); 6 7const entries = Object.entries(value as Record<string, unknown>) 8 .sort(([a], [b]) => (a < b ? -1 : a> b ? 1 : 0)) 9 .map(([key, nestedValue]) => [key, sortKeysDeep(nestedValue)] as const); 10 11 return Object.fromEntries(entries); 12 } 13 14 export async function POST(request: Request) { 15 const rawBody = await request.text(); 16 const signatureHeader = request.headers.get('x-finatic-signature') ?? ''; 17 const parsed = JSON.parse(rawBody) as unknown; 18 const bodyUtf8 = JSON.stringify(sortKeysDeep(parsed)); 19 20 const expected = `sha256=${createHmac( 21 'sha256', 22 process.env.FINATIC_WEBHOOK_SECRET!, 23 ) 24 .update(bodyUtf8, 'utf8') 25 .digest('hex')}`; 26 27 if (signatureHeader !== expected) { 28 return new Response('invalid signature', { status: 401 }); 29 } 30 31 // Acknowledge quickly; do heavy work asynchronously. 32 return new Response('ok', { status: 200 }); 33 } 34 ``` 35 36 Replace `FINATIC_WEBHOOK_SECRET` with the secret shown in team settings for that endpoint. 37 38 ## Retries and success criteria 39 40 The worker treats **any HTTP 2xx** response as success. On timeouts, transport errors, or non-2xx responses, 41 Finatic 42 retries with **exponential backoff** up to **`WEBHOOK_MAX_ATTEMPTS`** (default **4** attempts) and 43 **`WEBHOOK_HTTP_TIMEOUT_SECONDS`** per attempt (default **15** seconds). Operators tune these on FinaticBackground 44 via 45 environment variables. 46 47 ## Testing 48 49 - Use the **Send test** action in team settings to POST a synthetic payload with `delivery: "test"` and validate 50 signature handling end to end. 51 - Prefer **sandbox** connections and **`sandbox`** mode subscriptions while you iterate. 52 53 ## Next steps 54 55 1. **[MetaTrader](/docs/metatrader)** — Push-agent terminals and signed ingest. 56 2. **[Connecting Brokers](/docs/quick-start/connecting-brokers)** — Portal-first broker linking from your app. 57 3. **[API Reference](/docs/api-reference)** — SDK methods and response shapes.
