Webhooks

How to receive and act on Omnibus webhook events: setup, what each event means for your platform, who receives it, and recovering missed events.

Register one HTTPS endpoint and Monark posts an event for every Omnibus state change. This page covers how to handle them. Payloads for each event are in the API reference under Omnibus Webhooks, and signature verification code is on the Webhooks page in Getting Started.

Setup

  • Register: POST /primary/v1/webhook with your url and a token. Monark signs each delivery with the token
  • Update or pause: PUT /primary/v1/webhook replaces the whole configuration, so send url, token and isActive every time. Leaving out isActive deactivates the webhook, and events raised while it is inactive are not delivered
  • Handle repeats: use X-Webhook-Event-Id to skip events you have already processed. Treat each event as a signal: re-read the order or position with a GET before acting

Omnibus Events

EventSent whenWhat to do
OmnibusOrderCreatedAn order is createdStore Monark's id against your referenceId. If the order is PendingActions, prompt for the outstanding order actions
OmnibusOrderAcceptedAn order is accepted for execution. Status becomes PendingExecutionShow the order as accepted. It can still be cancelled or amended until Monark's cutoff, unless it is routed to the netting queue
OmnibusOrderRejectedAn order is rejected after submission, for example Settlement:TaRejected, or an Execution: code for a netting order before it is accepted. Orders rejected at submission come back in the 201 response insteadShow the statusReasonCode and message, and release any cash or shares you set aside
OmnibusOrderSentAn order is sent to the TA. Status becomes ExecutedShow the order as final: it can no longer be cancelled. Nothing more is filled until the TA confirms
OmnibusOrderSettledThe TA confirms the order and tax lots are created, or a netting order with unnettedOrderRoute: Cancel reaches its deadline part-filled (Execution:Expired). Not sent when an order fills completely in the netting queueRecord fills and refresh positions. For a sell, check remainingQuantity in case the fund gated the redemption
OmnibusOrderUpdatedAn amendment is appliedRefresh the order
OmnibusOrderUpdateRejectedAn amendment accepted as Pending is refusedShow the reasonCode. The order keeps its previous terms
OmnibusOrderCancelledAn order is cancelled, including a netting order with unnettedOrderRoute: Cancel that reaches its deadline with nothing filled (Execution:Expired)Mark it cancelled and release any cash or shares you set aside
OmnibusOrderCancelRejectedA cancellation accepted as Pending is refusedShow the reasonCode. The order continues
OmnibusOrderFailedSettlement fails for an operational reason, for example Settlement:ConfirmationTimeoutShow the order as failed and contact Monark Operations
OmnibusModelOrderCreated, Accepted, Rejected, Sent, Settled, Cancelled, CancelRejected, FailedThe same milestones for a model order as a wholeHandle as above for the block. Its client lines send no OmnibusOrder events, except when a netting model order reaches its deadline, so read each one with GET /primary/v1/omnibus/order/{id}
OmnibusOrderFundingInstructionAt Monark's cutoff, once per custodian, share class and election with buys. Lists your orders, their amounts net of any order fee, and wire instructions: MMM Securities' if the custodian is in the MMM Securities master omnibus, otherwise the TA'sMake sure the custodian wires the amount as instructed, by the wire deadline agreed with Monark. Reconcile orders[].amount to your buys
OmnibusCancelOrderFundingInstructionReserved. Not currently sent—
OmnibusDividendCreatedA distribution is allocated to a client's lot. One event per lotSum by accountId for each client's total, and refresh positions for DRIP elections
OmnibusOrderPartiallyFilled, OmnibusModelOrderPartiallyFilledRetired and never sent. Fills in the netting queue don't send an event of their own, and an order that fills completely there moves to Settled without oneRead fills, and the order's status, with GET /primary/v1/omnibus/order/{id} or GET /primary/v1/omnibus/model-order/{id}
FinancialInstitution, FinancialInstitutionUpdateA custodian is added or changedRefresh your list of custodians

A rejection or refusal returned directly in an API response does not also send a webhook. Handle it from the response.

Completing a model order is the exception. POST /primary/v1/omnibus/model-order/complete returns 202 with a status of Processing, and the outcome follows as OmnibusModelOrderCreated, or as OmnibusModelOrderRejected or OmnibusModelOrderFailed with a statusReasonCode. A draft model order that is cancelled, by you or overnight with DraftExpired, sends OmnibusModelOrderCancelled. Batches refused by investor-orders send nothing.

Delivery & Replay

Each delivery is an HTTPS POST with a JSON body of { "eventType": "...", "data": { ... } }. Fields are camelCase and enums are strings. The body has no timestamp of its own.

  • Headers: X-Webhook-Event-Id identifies the event, X-Webhook-Signature carries the signature and User-Agent is MonarkWebhookClient
  • Signature: Base64 of an HMAC-SHA256 of the raw UTF-8 request body, keyed with your token as UTF-8. Compute it over the body exactly as received, before parsing, and reject any delivery that doesn't match. See Webhooks for sample code
  • Retries: Monark picks up new events within about a minute. A delivery that times out after 30 seconds, returns 408 or a 5xx, or hits a network error is retried twice, after 1 and 5 seconds. It is then marked Failed and not sent again. Other responses are not retried
  • Order: events can arrive out of order, so rely on the record's current state from a GET
  • Event log: GET /primary/v1/webhook/{id}/events lists past events with their eventType, data, createdAt, deliveredAt and a deliveryStatus of Pending, Delivered or Failed. from and to are required; eventType and deliveryStatus filter further. Failed deliveries can't be resent, so check the log after any outage on your side and re-read the affected records

Did this page help you?