Webhooks

Atlaas can POST an event to your HTTPS endpoint whenever something happens on your terminals. Webhooks are on the Pro plan and above. Add and manage endpoints on the Webhooks page in the portal; the signing secret (whsec_...) is shown there. You can send a test event and see the recent deliveries for each endpoint from the same page.

Events

An endpoint with no event filter receives every event below.

EventWhen it fires
instance.stateA terminal changed state (deploying, running, stopped, error).
order.placeAn order was submitted to the broker.
order.modifyAn open order or position was modified.
order.closeA position was closed.
order.cancelA pending order was cancelled.
ea.connectedThe connector EA attached to a terminal.
ea.disconnectedThe connector EA dropped off a terminal.
deployment.completedAn expert advisor finished deploying.
deployment.failedAn expert advisor failed to deploy.

Request

Each delivery is a POST with a JSON body:

{
  "id": "cm1delivery0000example",
  "type": "order.place",
  "createdAt": "2026-10-01T09:30:00.000Z",
  "data": {
    "accountId": "cm1account0000example",
    "instanceId": "cm1instance000example",
    "level": "INFO",
    "message": "Order placed: BUY 0.10 EURUSD @ 1.0850 (ticket 123456)"
  }
}

data always carries accountId, instanceId (or null), level (INFO, WARN, ERROR, ...) and message. Event-specific fields are added alongside them, and fields are only ever added, never renamed.

Headers:

HeaderValue
X-Atlas-EventThe event type, e.g. order.place.
X-Atlas-DeliveryThe delivery id, the same as id in the body. Use it to dedupe retries.
X-Atlas-Signaturet=<unix seconds>,v1=<hex>, see below.

Verifying the signature

v1 is the hex HMAC-SHA256 of `${t}.${rawBody}` keyed with your endpoint's secret. Sign the raw request body exactly as received, before any JSON parsing, and reject old timestamps to stop replays.

import { createHmac, timingSafeEqual } from "node:crypto"

function verifyAtlasWebhook(secret, rawBody, header, toleranceSeconds = 300) {
    const t = /(?:^|,)t=(\d+)(?:,|$)/.exec(header)?.[1]
    const v1 = /(?:^|,)v1=([0-9a-f]+)(?:,|$)/.exec(header)?.[1]
    if (!t || !v1) return false
    if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSeconds) return false
    const expected = Buffer.from(createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"), "hex")
    const given = Buffer.from(v1, "hex")
    return expected.length === given.length && timingSafeEqual(expected, given)
}

Delivery and retries