Webhooks
How to receive and act on private markets webhook events: setup, what each event means for your platform, and recovering missed events.
Integrating through Apex AscendOS?The product guidance on this page applies to you. The endpoints, fields and statuses are Monark's; use the AscendOS equivalents listed in Building on Apex AscendOS.
Register one HTTPS endpoint and Monark posts an event for every state change that matters to your platform. This page covers what to do with each one. The payload of each event is documented in Webhook Event Types, and signature verification code is on the Webhooks page in Getting Started.
Setup
- Register:
POST /primary/v1/webhookwith yoururland atoken. Monark signs each delivery with the token. - Update or pause:
PUT /primary/v1/webhookreplaces the whole configuration, so sendurl,tokenandisActiveevery time. Leaving outisActivedeactivates the webhook, and events raised while it is inactive are not delivered. - Handle repeats: use
X-Webhook-Event-Idto skip events you have already processed. Treat each event as a signal and re-read the record with aGETbefore acting on it.
Events
| Event | Sent when | What to do |
|---|---|---|
SubscriptionStatus | An investor's transaction changes status, at every transition in the lifecycle | Re-read the transaction. On Processing, mark the commitment binding and stop offering to edit or withdraw. On Complete, release your cash lock and show the position. On Rejected or Failed, release the reserved cash and tell the investor why |
PreIPOCompanySPV | An SPV changes stage | Re-read the SPV. Treat it as investable only when monarkStage is PRIMARY_FUNDRAISE and isApproved is true. On PRE_CLOSE_REVIEW or later, stop accepting new subscriptions |
PreIPOCompanySPVUpdate | An SPV's terms change | Refresh pricing, fees, allocation and deadline anywhere they are cached or displayed |
PreIPOCompanySPVDocumentUpdate | An SPV's document set changes | Refresh the documents on the offering page. A new subscription agreement preview or PPM must be the one the investor attests to |
PreIPOCompanySPVSubscriptionActionDefinitionUpdate | The set of actions an SPV requires changes | Re-read the actions for any open transaction on that SPV. An investor part-way through may now owe a new acknowledgement |
ProspectiveOfferingAccessGained | Your financial institution is granted access to a prospective offering | Show it as an upcoming offering and open it for indications of interest |
ProspectiveOfferingAccessLost | That access is withdrawn | Remove it from the marketplace and stop accepting indications of interest against it |
IndicationOfInterestClosed | A prospective offering stops collecting interest | Close the form. Where the offering became a real SPV, point interested investors at it |
PendingSubscriptionReminder | A transaction has been sitting in Pending with actions outstanding | Prompt the investor to finish. This is the event behind an abandoned-order nudge |
CorporateAction | A corporate action affecting an active SPV is created or updated | Surface it as a notification or banner. Where it settles cash or shares, expect that to be handled directly with your custodian |
FinancialInstitution, FinancialInstitutionUpdate | A financial institution is added or changed | Refresh your list and its financialInstitutionIds |
The following event types exist but are not currently sent: PreIPOCompany, PreIPOCompanyInvestment, Investor, Document, InvestorSubscriptionAction. Do not build against them.
A refusal returned directly in an API response does not also raise a webhook. Handle it from the response.
The Two Status Vocabularies
Important: The
SubscriptionStatuswebhook reports the v1 subscription status, not the v2 transaction status. The two enums differ, and one value is renamed between them.
GET /primary/v2/transaction returns | The SubscriptionStatus webhook sends |
|---|---|
Pending | Pending |
Processing | Processing |
Settled | Settled |
Complete | Complete |
Canceled | Rejected |
Failed | Failed |
Initiated | not represented |
PendingCancellation | not represented |
A platform that switches on Canceled when handling webhooks will never match a cancellation, because the webhook calls it Rejected. Handle both vocabularies, or normalise at your webhook boundary and work in one of them internally.
Delivery and Replay
Each delivery is an HTTPS POST with a JSON body of { "eventType": "...", "data": { ... } }. Fields are camelCase and enums are strings. The body carries no timestamp of its own.
- Headers:
X-Webhook-Event-Ididentifies the event,X-Webhook-Signaturecarries the signature, andUser-AgentisMonarkWebhookClient. - Signature: Base64 of an HMAC-SHA256 of the raw UTF-8 request body, keyed with your
tokenas UTF-8. Compute it over the body exactly as received, before parsing, and reject any delivery that does not 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
408or a5xx, or hits a network error is retried twice, after 1 and 5 seconds. It is then marked failed and not sent again. Any other non-2xxresponse is marked failed immediately and is not retried. - Return quickly. Return a
2xxas soon as you have stored the event, and process it afterwards. The 30-second timeout is measured against your response, not your processing. - Order: events can arrive out of order, so rely on the record's current state from a
GETrather than on the sequence of deliveries. - Event log:
GET /primary/v1/webhook/{id}/eventslists past events with theireventType,data,createdAt,deliveredAtand adeliveryStatusofPending,DeliveredorFailed. Failed deliveries cannot be resent, so check the log after any outage on your side and re-read the affected records.
Next Steps
- The payload of every event: Webhook Event Types
- What each refusal means and what the investor should do: Errors & Reason Codes
Updated about 17 hours ago