API reference

Webhooks

Be told about breaches, passes and fills instead of polling for them, with signed and verifiable deliveries.

Register a URL and we will tell you when something happens instead of you asking. For a firm watching hundreds of accounts this is the difference between knowing about a breach in seconds and burning your whole read budget discovering that nothing happened.

Register an endpoint

POST/v1/webhooksPlannedscope · accounts:write
curl
curl -X POST https://api.propexecutor.com/v1/webhooks \
  -H "Authorization: Bearer $PFX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.apexprop.example/hooks/propexecutor",
    "events": ["account.breached", "account.passed"]
  }'

HTTPS only. An empty events array means everything, so an endpoint registered without thinking still receives rather than silently getting nothing. The response carries a secret — store it, it is shown once.

Events

EventFires when
account.breachedA rule was violated. Carries the rule, the reason and the equity state at the moment it fired.
account.passedThe account hit its profit target and satisfied every other objective.
account.flaggedA rule with a flag action fired — worth review, trading continues.
account.createdAn account was provisioned, whether from the API or the panel.
account.assignedAn account's trader changed. Previous sessions are already revoked.
account.archivedAn account was taken out of circulation.
position.openedA position filled, including one from a resting order triggering.
position.closedA position closed — manually, or on its stop or target.
order.rejectedA pre-order rule refused an order, with which rule and why.
credits.lowRemaining account credits fell below a threshold you set.

Payload

POST to your URL
{
  "id": "evt_9f2c1b7a4e",
  "type": "account.breached",
  "created_at": "2026-09-27T14:02:19Z",
  "organization_id": "11111111-…",
  "data": {
    "account": 10000042,
    "trader_id": "3d21…",
    "status": "breached",
    "reason": "daily drawdown 5.2% exceeded the 5% limit",
    "equity": 9480,
    "balance": 9480,
    "peak_equity": 10310.55
  }
}

Verifying a delivery

Every request carries a signature over the raw body and a timestamp:

Request headers
X-PropExecutor-Id: evt_9f2c1b7a4e
X-PropExecutor-Timestamp: 1790503647
X-PropExecutor-Signature: v1=5d41402abc4b2a76b9719d911017c592…
Node
import crypto from "node:crypto";

function verify(rawBody, headers, secret) {
  const ts = headers["x-propexecutor-timestamp"];
  const sig = headers["x-propexecutor-signature"];

  // Reject anything older than five minutes, so a captured delivery cannot be
  // replayed against you later.
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;

  const expected =
    "v1=" +
    crypto
      .createHmac("sha256", secret)
      .update(`${ts}.${rawBody}`)
      .digest("hex");

  // Constant-time, so a caller cannot time their way to a valid signature.
  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

Verify over the raw bytes

Compute the HMAC on the body exactly as received, before any JSON parsing or re-serialising. Parsing and re-encoding changes key order and whitespace, and the signature will never match.

Delivery rules

  • Answer 2xx quickly. Anything else, or a timeout, counts as a failure. Acknowledge first and do your work after — a slow handler looks identical to a broken one.
  • At least once, not exactly once. A retry can deliver an event you already processed. Deduplicate on id.
  • Retries back off and eventually stop, rather than hammering a dead host forever. An endpoint that keeps failing is marked and stops being delivered to.
  • Order is not guaranteed. Use created_at if sequence matters, and treat each event as a statement about a moment rather than a step in a sequence.
  • An event is a notification, never authority. The decision behind it is already durably written. If you need certainty, read the account back.

Debugging

GET/v1/webhooks/{id}/deliveriesPlannedscope · accounts:read
POST/v1/webhooks/{id}/testPlannedscope · accounts:write

Deliveries are kept with their response status and error, so you can see exactly what we sent and what came back. The test endpoint sends a signed event with the same shape as a real one — use it to check your signature verification before you rely on it.

Managing endpoints

GET/v1/webhooksPlannedscope · accounts:read
DELETE/v1/webhooks/{id}Plannedscope · accounts:write