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/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 and re-read the record with a GET before acting on it.

Events

EventSent whenWhat to do
SubscriptionStatusAn investor's transaction changes status, at every transition in the lifecycleRe-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
PreIPOCompanySPVAn SPV changes stageRe-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
PreIPOCompanySPVUpdateAn SPV's terms changeRefresh pricing, fees, allocation and deadline anywhere they are cached or displayed
PreIPOCompanySPVDocumentUpdateAn SPV's document set changesRefresh the documents on the offering page. A new subscription agreement preview or PPM must be the one the investor attests to
PreIPOCompanySPVSubscriptionActionDefinitionUpdateThe set of actions an SPV requires changesRe-read the actions for any open transaction on that SPV. An investor part-way through may now owe a new acknowledgement
ProspectiveOfferingAccessGainedYour financial institution is granted access to a prospective offeringShow it as an upcoming offering and open it for indications of interest
ProspectiveOfferingAccessLostThat access is withdrawnRemove it from the marketplace and stop accepting indications of interest against it
IndicationOfInterestClosedA prospective offering stops collecting interestClose the form. Where the offering became a real SPV, point interested investors at it
PendingSubscriptionReminderA transaction has been sitting in Pending with actions outstandingPrompt the investor to finish. This is the event behind an abandoned-order nudge
CorporateActionA corporate action affecting an active SPV is created or updatedSurface it as a notification or banner. Where it settles cash or shares, expect that to be handled directly with your custodian
FinancialInstitution, FinancialInstitutionUpdateA financial institution is added or changedRefresh 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 SubscriptionStatus webhook 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 returnsThe SubscriptionStatus webhook sends
PendingPending
ProcessingProcessing
SettledSettled
CompleteComplete
CanceledRejected
FailedFailed
Initiatednot represented
PendingCancellationnot 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-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 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 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. Any other non-2xx response is marked failed immediately and is not retried.
  • Return quickly. Return a 2xx as 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 GET rather than on the sequence of deliveries.
  • 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. Failed deliveries cannot be resent, so check the log after any outage on your side and re-read the affected records.

Next Steps


Did this page help you?