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.
  • Modeslive, paper, and where applicable sandbox.
  • 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.added
  • connection.updated
  • connection.removed

Orders

  • account.orders.added
  • account.orders.updated
  • account.orders.removed

Positions

  • account.positions.added
  • account.positions.updated
  • account.positions.removed

Balances

  • account.balances.added
  • account.balances.updated
  • account.balances.removed

Transactions (when enabled for your data plane)

  • account.transactions.added
  • account.transactions.updated
  • account.transactions.removed

Request shape

Each POST body is a JSON object with (at minimum):

  • schema_version — envelope version (currently 1).
  • event_id — unique id for this delivery (also sent as X-Finatic-Event-Id).
  • event_type — same string you subscribed to (also X-Finatic-Event).
  • modelive, paper, or sandbox.
  • deliverylive for real traffic, test for dashboard test sends (X-Finatic-Delivery mirrors 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 (schema is always broker_data in JSON, with table, operation, and optional id).
  • data — typically includes trimmed old / new row snapshots and may include extra metadata the worker attaches for large or bundled updates.

Headers

Finatic sends at least:

  • Content-Type: application/json

  • User-Agent: Finatic-Webhooks/3.0

  • X-Finatic-Event

  • X-Finatic-Event-Id

  • X-Finatic-Delivery

  • X-Finatic-Signature: sha256=<hex> when a secret is configured

    The 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.stringify after recursive key sort, and Python json.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.