Webhooks
Register HTTPS endpoints for real-time event notifications, HMAC-SHA256-signed over the raw body. Full event catalogue, per-event payloads, signature-verification code (Node & Python), at-least-once delivery semantics, and the delivery log.
Register HTTPS endpoints to receive real-time event notifications. MyStocks signs every delivery with
an HMAC-SHA256 signature over the raw request body using your webhook secret. Your endpoint must
respond HTTP 2xx within 8 seconds; heavy processing should be deferred to a background queue.
Failed deliveries are retried with exponential backoff — check the delivery log via
GET /webhooks/{id}/deliveries.
For mobile foreground UX, use GET /stream Server-Sent Events to receive the same partner events
with near-real-time delivery and resume via Last-Event-ID / ?since=. Webhooks and SSE carry order,
wallet, KYC, dividend, account, and market-status events; they do not provide tick-by-tick quotes
or Level-2 order book depth. Poll /market/quotes for fresh displayed prices, and use the
/users/{userId}/devices endpoints to manage your own APNs/FCM/Expo/Web Push fanout.
Register a webhook
POST /webhooks
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | HTTPS endpoint. Must respond 2xx within 8 s. |
| events | string[] | Yes | Array of event type strings to subscribe to. |
| secret | string | No | HMAC signing secret (min 16 chars). Generated automatically if omitted. |
curl -X POST "https://mystocks.africa/api/v1/partner/webhooks" \
-H "Authorization: Bearer pk_live_<key>" \
-H "Idempotency-Key: webhook_primary_001" \
-H "Content-Type: application/json" \
-d '{"url":"https://yourapp.com/webhooks/mystocks","events":["order.filled","order.rejected"],"secret":"my-signing-secret-min-16-chars"}'Event catalogue
| Event | Trigger |
|---|---|
order.pending | An order was submitted and is awaiting live fill. |
order.filled | An order was filled and executed. Shares/proceeds credited. |
order.rejected | An order was declined. Includes rejectionCode and rejectionReason. |
order.cancelled | An order was cancelled via DELETE /orders/{id}. |
order.replaced | A resting order was modified via PATCH /users/{id}/orders/{orderId} (same orderId). |
trade.settled | Alias for order.filled — use order.filled in new integrations. |
trade.rejected | Alias for order.rejected — use order.rejected in new integrations. |
deposit.confirmed | A sub-account deposit was recorded. |
withdraw.confirmed | A sub-account withdrawal was processed. |
wallet.credited | Master wallet received a top-up from MyStocks ops. |
kyc.updated | A sub-account KYC status changed. |
account.frozen | A sub-account was frozen (or unfrozen) by partner or MyStocks compliance. |
account.closed | A sub-account was soft-closed/offboarded via DELETE /users/{userId}. |
dividend.paid | A dividend was received and credited to a sub-account. |
corporateaction.declared | Generic corporate-action event for backwards compatibility. |
corporateaction.split | Stock split, reverse split, or bonus issue affecting holdings. |
corporateaction.suspension | Trading suspension or halt affecting a listed security. |
corporateaction.delisting | Delisting event for a listed security. |
corporateaction.rights_issue | Rights issue or similar subscription entitlement. |
corporateaction.symbol_changed | Ticker/symbol migration, rename, or exchange code change. |
quote.expired | A tradeable quote reached its 60-second TTL without being used. |
price.alert | A price alert you registered crossed its threshold. See Price alerts. |
market.status | An exchange changed phase (OPEN/CLOSED/HOLIDAY). |
incident.declared | A platform incident affecting your integration was opened. |
incident.resolved | A previously declared incident was closed. |
Price alerts
price.alert does not fire on its own — you subscribe to the thresholds you care about. Register one
with POST /price-alerts; threshold is in the instrument's local trading currency, the same
basis as a quote's price.
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | No | Required. Must exist and trade on the given exchange. |
| exchange | string | No | Required. Exchange code, e.g. NSE, NGX, JSE. |
| condition | string | No | Required. "above" or "below". |
| threshold | number | No | Required. Positive, in the local trading currency. |
| repeat | boolean | No | Default false. When false the alert fires once and disarms. When true it re-arms, but only after the price crosses back through the threshold — so a price hovering at the threshold cannot spam your endpoint. |
| clientAlertId | string | No | Optional. Your own reference, echoed back on the alert and in the webhook payload. |
Alerts are evaluated against the live price and only while the exchange is open, so a stale
closing price can never trigger one. Because quotes are polled on a ~15-minute cycle
(see Data freshness), an alert fires on the first poll after the
crossing — not at the instant of the tick. Do not use price.alert as an execution trigger; use a
resting LIMIT or STOP order, which is evaluated on the same cycle but actually places the trade.
List with GET /price-alerts, inspect one with GET /price-alerts/{alertId}, and remove one with
DELETE /price-alerts/{alertId}. You may hold up to 200 active alerts.
Delivery envelope
Every delivery wraps the event-specific payload in a standard three-field envelope. Sandbox deliveries
add isSandbox: true at the top level.
Event payloads
Signature verification
Every delivery includes an x-mystocks-signature header containing an HMAC-SHA256 hex digest of the
raw request body signed with your webhook secret. Always verify using a constant-time comparison.
Delivery semantics — at-least-once, not exactly-once. The same event can arrive more than once;
events are not guaranteed to arrive in order (a retried order.pending can land after
order.filled); and a delivery can fail all retries. The robust pattern: dedupe by eventId,
treat handlers as idempotent, and derive state from the event payload rather than arrival order.
Respond 2xx quickly and process asynchronously — you have 8 seconds before the attempt fails.
Manage & inspect
GET /webhooks · DELETE /webhooks/{id} · POST /webhooks/{id}/test · GET /webhooks/{id}/deliveries
List registered webhooks, delete one, fire a test event, or inspect delivery history.
POST /webhooks/{id}/test sends a test.event payload immediately and logs the delivery — useful for
verifying reachability and signature verification before going live. /deliveries returns each attempt
with HTTP status, response snippet, duration (ms), and the retry schedule if it failed. Retry schedule:
immediate → 5 s → 30 s → 5 min → 30 min → 2 h → 8 h → 24 h (8 attempts max).
Was this page useful?
Your signal helps us tighten partner onboarding docs.
Last updated on