Webhooks
Register and manage the endpoint MultiSet delivers lifecycle events to, send test events, rotate the signing secret, and read the delivery log.
These endpoints manage the HTTPS URL that map, map set, and object lifecycle events are delivered to. See Webhooks for the event catalogue, the payload envelope, signature verification, and the retry policy.
Endpoints
Register a webhook endpoint
Registers the URL events are delivered to, and verifies it immediately by POSTing a signed endpoint.verify challenge that your service must echo back. See Verifying your endpoint.
The signing secret is returned once, in this response. It cannot be read back afterwards, only rotated.
Constraints:
The account must not already have an endpoint.
urlmust be HTTPS in production, and must not resolve to a private, loopback, or link-local address.Every entry in
eventsmust be a known event type or a valid wildcard.
Registers the URL lifecycle events are delivered to. One endpoint per account.
The endpoint is verified immediately: a signed endpoint.verify event is
POSTed to the URL, and your service must reply 200 and echo the
challenge value back in the response body. A bare 200 is not enough,
because a misconfigured proxy will return that for a URL that reaches nothing.
The signing secret is returned once, here, and cannot be read back afterwards. Store it before you close the response.
HTTPS in production. Private, loopback and link-local addresses are rejected, and the address is re-checked at delivery time.
https://acme.com/multiset-hooksEvent types to receive. Accepts exact names, an entity wildcard (map.*), a state wildcard (*.failed), or * for everything. New event types may appear under an existing wildcard, so your receiver must ignore types it does not recognise.
["map.*","object.active"]prod receiverEndpoint created. verified is false if the challenge failed.
Webhook endpoint createdShown once. Store it now, it cannot be retrieved again.
whsec_8f2b1c9d4e7a6b3f8c2d1e5a9b4c7d0etrueresponse did not echo the challengeInvalid URL, rejected address, or unknown event type
This account already has a webhook endpoint
POST /v1/webhook/endpoint HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 106
{
"url": "https://acme.com/multiset-hooks",
"events": [
"map.*",
"object.active"
],
"description": "prod receiver"
}{
"message": "Webhook endpoint created",
"endpoint": {
"_id": "60d5ec49f1b2c8b1f8e4e1a1",
"accountId": "text",
"url": "https://acme.com/multiset-hooks",
"description": "text",
"events": [
"map.*",
"object.active"
],
"status": "pending_verification",
"verifiedAt": "2026-01-01T00:00:00.000Z",
"consecutiveFailures": 0,
"lastSuccessAt": "2026-01-01T00:00:00.000Z",
"disabledAt": "2026-01-01T00:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
},
"secret": "whsec_8f2b1c9d4e7a6b3f8c2d1e5a9b4c7d0e",
"verified": true,
"verificationError": "response did not echo the challenge"
}Get the account's webhook endpoint
Returns the registered endpoint, including its status, consecutiveFailures, and lastSuccessAt, or null if none is registered. The signing secret is never returned.
Returns the registered endpoint, or null if none is registered. The signing secret is never returned.
The endpoint, or null if none is registered
GET /v1/webhook/endpoint HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
The endpoint, or null if none is registered
{
"endpoint": {
"_id": "60d5ec49f1b2c8b1f8e4e1a1",
"accountId": "text",
"url": "https://acme.com/multiset-hooks",
"description": "text",
"events": [
"map.*",
"object.active"
],
"status": "pending_verification",
"verifiedAt": "2026-01-01T00:00:00.000Z",
"consecutiveFailures": 0,
"lastSuccessAt": "2026-01-01T00:00:00.000Z",
"disabledAt": "2026-01-01T00:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
}Update a webhook endpoint
Change the URL, the subscribed events, the description, or set isActive to false to stop delivery without deleting the endpoint. Send at least one field.
Change the URL, the subscribed events, the description, or deactivate the endpoint. At least one field is required.
Changing url resets the endpoint to pending_verification, so no events
are delivered until verification succeeds again.
The endpoint's _id
Updated
Invalid URL or event type
Not found
PUT /v1/webhook/endpoint/{id} HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 69
{
"url": "text",
"events": [
"text"
],
"description": "text",
"isActive": true
}{
"message": "text",
"endpoint": {
"_id": "60d5ec49f1b2c8b1f8e4e1a1",
"accountId": "text",
"url": "https://acme.com/multiset-hooks",
"description": "text",
"events": [
"map.*",
"object.active"
],
"status": "pending_verification",
"verifiedAt": "2026-01-01T00:00:00.000Z",
"consecutiveFailures": 0,
"lastSuccessAt": "2026-01-01T00:00:00.000Z",
"disabledAt": "2026-01-01T00:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
}Delete a webhook endpoint
Removes the endpoint. Delivery stops immediately. The delivery log is kept, so you can still audit what was sent before the endpoint was removed.
Removes the endpoint. Delivery stops immediately and the delivery log is retained.
Deleted
No content
Not found
DELETE /v1/webhook/endpoint/{id} HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
No content
Re-run endpoint verification
Re-sends the signed challenge. Use it after fixing a receiver whose first verification failed, or to re-enable an endpoint that was auto-disabled after 20 consecutive delivery failures.
A successful verification sets the endpoint back to active and resets consecutiveFailures to zero, so this is the self-service route out of an auto-disable.
Re-sends the signed challenge. Use it after fixing an endpoint whose first verification failed, or to re-enable one that was auto-disabled after sustained delivery failures. A successful verification resets the failure count.
Verification result
response did not echo the challenge502Not found
POST /v1/webhook/endpoint/{id}/verify HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"verified": true,
"reason": "response did not echo the challenge",
"responseCode": 502
}Send a test event
Delivers a signed sample event synchronously and reports what your endpoint answered: the response code, how long it took, and the first 2KB of the response body. Pass type to choose which event shape to simulate, or omit it for map.active.
Test events carry livemode: false, are never retried, do not count towards consecutiveFailures, and are recorded in the delivery log with isTest: true.
Delivers a signed sample event synchronously and reports what your endpoint
answered. A test event is never retried, and carries livemode: false so
your handler can tell it from a real event. It is recorded in the delivery
log with isTest: true.
Which event shape to simulate. Defaults to map.active.
map.activeThe attempt result. Returns 200 even when delivery failed, because the API call itself succeeded. Check delivered.
trueevt_test_01JB8Z9K200342Endpoint is not verified
Not found
POST /v1/webhook/endpoint/{id}/test HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 21
{
"type": "map.active"
}{
"delivered": true,
"eventId": "evt_test_01JB8Z9K",
"responseCode": 200,
"responseTimeMs": 342,
"errorKind": "timeout",
"responseBody": "text"
}Rotate the signing secret
Returns a new secret once. The previous secret stops verifying immediately, so deploy the new one first, or accept a short window of signature failures. Failed deliveries in that window are retried, so nothing is lost if you rotate and redeploy promptly.
Returns a new signing secret once. The previous secret stops verifying immediately, so deploy the new one before rotating, or accept a short window of signature failures.
New secret
whsec_9c1d3f8a2b6e4d7c1a9f5b3e8d2c6a4fNot found
POST /v1/webhook/endpoint/{id}/rotate-secret HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"message": "text",
"secret": "whsec_9c1d3f8a2b6e4d7c1a9f5b3e8d2c6a4f"
}List webhook deliveries
Delivery history for the account. Filter by event type, delivery status, a date range, or resourceId to see every event raised for one map, map set, or object.
The event payload is omitted here to keep responses small. Fetch a single delivery to read it.
status
Meaning
queued
Accepted, first attempt not yet made
delivered
Your endpoint returned a 2xx
retrying
An attempt failed, another is scheduled at nextRetryAt
exhausted
All five attempts failed, it will not be tried again
cancelled
Not delivered, for example the endpoint was deleted mid-chain
Delivery history for the account, newest first. The event payload is omitted
here to keep the response small, fetch a single delivery to read it.
125Filter by event type
map.activeEverything that happened to one map, map set, or object
Paged deliveries
142125GET /v1/webhook/delivery HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
Paged deliveries
{
"total": 142,
"page": 1,
"limit": 25,
"deliveries": [
{
"eventId": "evt_1a0636bc890d38c1f72d2b9d122",
"type": "map.active",
"entity": "map",
"resourceId": "6710c22dee25fb59e9f3c67b",
"occurredAt": "2026-01-01T00:00:00.000Z",
"status": "queued",
"attempts": 1,
"responseCode": 200,
"responseTimeMs": 342,
"responseBody": "text",
"errorKind": "timeout",
"nextRetryAt": "2026-01-01T00:00:00.000Z",
"deliveredAt": "2026-01-01T00:00:00.000Z",
"isTest": true,
"history": [
{
"at": "2026-01-01T00:00:00.000Z",
"code": 503,
"errorKind": "text",
"ms": 1
}
],
"createdAt": "2026-01-01T00:00:00.000Z"
}
]
}Get one delivery
Returns the full record for one event, including the exact payload that was sent and one history entry per attempt with its response code, error kind, and timing.
Returns the full delivery record, with the data block that was sent to your endpoint.
The event id, also sent as the Multiset-Event-Id header
The delivery record
Not found
GET /v1/webhook/delivery/{eventId} HTTP/1.1
Host: api.multiset.ai
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"delivery": {
"eventId": "evt_1a0636bc890d38c1f72d2b9d122",
"type": "map.active",
"entity": "map",
"resourceId": "6710c22dee25fb59e9f3c67b",
"occurredAt": "2026-01-01T00:00:00.000Z",
"status": "queued",
"attempts": 1,
"responseCode": 200,
"responseTimeMs": 342,
"responseBody": "text",
"errorKind": "timeout",
"nextRetryAt": "2026-01-01T00:00:00.000Z",
"deliveredAt": "2026-01-01T00:00:00.000Z",
"isTest": true,
"history": [
{
"at": "2026-01-01T00:00:00.000Z",
"code": 503,
"errorKind": "text",
"ms": 1
}
],
"createdAt": "2026-01-01T00:00:00.000Z",
"payload": {}
}
}Error kinds
When a delivery fails, errorKind says how, which is usually enough to tell a configuration problem from an outage:
errorKind
Cause
timeout
No response within 10 seconds
dns
The hostname did not resolve
tls
Certificate or handshake failure
conn_refused
Nothing listening on the port
http_4xx
Your endpoint rejected the request, a signature check failing looks like this
http_5xx
Your endpoint errored
redirect_refused
The endpoint returned a redirect, which is never followed
network
Anything else at the transport layer
Last updated
Was this helpful?

