Skip to content

Webhooks

View as Markdown

Connect your MASV account to external web services to receive notifications via custom webhooks.

You can create custom webhooks for any Team you belong to, subject to the access policy.

MethodRoute
POST/teams/{team_id}/custom_webhooks
NameTypeRequiredDescription
X-API-KEYStringYesAPI key
Content-TypeStringYesMust be application/json
NameTypeRequiredDescription
activeBooleanYesIndicates if the webhook is active or not
body_extrasObjectNoA static list of keys and values to be appended to the body of all events. All values must be strings.
eventsString[]YesIndicates which events this webhook will receive (see supported events below)
headersObjectNoA static list of header keys and values to be included on every event that is sent
methodStringYesVerb used when event is sent — POST and PUT are currently supported
nameStringNoOptional internal reference to the webhook and its purpose
urlStringYesThe HTTP or HTTPS endpoint for events to be sent to
Terminal window
# Store your API key in an environment variable — never hardcode it.
# See /api/api-keys/ for key management best practices.
curl -d '{"active": true, "events": ["package.created", "package.finalized"], "method": "$METHOD", "name": "$NAME", "url": "$URL"}' \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/teams/$TEAM_ID/custom_webhooks

After a successful request, this endpoint returns 201 Created:

{
"active": true,
"body_extras": {
"key": "value",
"key2": "value2"
},
"events": ["package.created", "package.finalized"],
"id": "ACHSFSDI32343ASD",
"headers": {
"key": "value",
"key2": "value2"
},
"method": "POST",
"name": "Portal Uploads",
"url": "https://mywebhooks.endpoint"
}

You can update custom webhooks for any Team you belong to, subject to the access policy.

MethodRoute
PUT/custom_webhooks/{custom_webhook_id}
NameTypeRequiredDescription
X-API-KEYStringYesAPI key
Content-TypeStringYesMust be application/json

Same fields as the create webhook endpoint above.

Terminal window
curl -d '{"active": true, "events": ["package.created", "package.finalized"], "method": "$METHOD", "name": "$NAME", "url": "$URL"}' \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X PUT https://api.massive.app/v1/custom_webhooks/$CUSTOM_WEBHOOK_ID

After a successful request, this endpoint returns 200 OK with the updated webhook object.

MethodRoute
DELETE/custom_webhooks/{custom_webhook_id}
NameTypeRequiredDescription
X-API-KEYStringYesAPI key
Terminal window
curl -H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X DELETE https://api.massive.app/v1/custom_webhooks/$CUSTOM_WEBHOOK_ID

Returns 204 No Content. Any transfers in progress at the time of deletion will complete normally.

MethodRoute
GET/teams/{team_id}/custom_webhooks
NameTypeRequiredDescription
X-API-KEYStringYesAPI key
Terminal window
curl -H "X-API-KEY: $API_KEY" \
-X GET https://api.massive.app/v1/teams/$TEAM_ID/custom_webhooks

Returns 200 OK with an array of webhook objects. The connections property indicates the number of Portals attached to each webhook.

Custom webhooks can be attached to a Portal on either the Create or Update Portal methods via the custom_webhooks property. The complete list must be passed on every update — any omissions are removed unless the custom_webhooks property is excluded entirely.

MethodRoute
PUT/portals/{portal_id}
NameTypeRequiredDescription
X-API-KEYStringYesAPI key
Content-TypeStringYesMust be application/json
NameTypeRequiredDescription
custom_webhooksArrayNoList of webhook objects with id property
Terminal window
curl -d '{"name": "$NAME", "subdomain": "$PORTAL_SUBDOMAIN", "custom_webhooks": [{"id":"<ID1>"}, {"id":"<ID2>"}], "has_access_code": false, "active": true}' \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X PUT https://api.massive.app/v1/portals/$PORTAL_ID

Retrieve the list of Portals to see their attached custom webhooks.

MethodRoute
GET/teams/{team_id}/portals
Terminal window
curl -H "X-API-KEY: $API_KEY" \
-X GET https://api.massive.app/v1/teams/$TEAM_ID/portals

Webhook events are sent for successful actions in MASV. The payload follows a standard format with small variations based on the source object. Events are emitted from MASV to each connected webhook and are attempted up to 5 times with an incremental back-off between attempts.

{
"event_id": "SFUHDF35DSD88F",
"event_time": "2021-01-14T10:39:45.334Z",
"event_type": "package.created",
"body_extras": {
"key": "value"
},
"object": {
"type": "package",
"id": "JF4D076SA6FA1",
"name": "Sample Upload",
"portal_id": "01CYCWJC40RXPK3HNQVYKAX1K1",
"sender": "test@masv.io",
"size": 0,
"state": "new",
"total_files": 0,
"created_at": "2021-01-14T10:39:45.334Z",
"updated_at": "2021-01-14T10:39:45.334Z"
},
"custom_webhook_id": "ACHSFSDI32343ASD"
}
PropertyDescription
event_idUnique identifier for the webhook event
event_timeTimestamp for when the event was generated
event_typeSubject of the event (package.created or package.finalized)
body_extrasKey/value pairs supplied on the webhook
objectThe actual record (a package in this case)
object.portal_idPortal the package was uploaded to (omitted if not a Portal package)
custom_webhook_idIdentifier of the webhook this event was associated with
{
"event_id": "SFUHDF35DSD88F",
"event_time": "2021-01-14T16:39:56.350Z",
"event_type": "package.finalized",
"body_extras": {
"key": "value"
},
"object": {
"type": "package",
"id": "JF4D076SA6FA1",
"name": "Sample Upload",
"portal_id": "01CYCWJC40RXPK3HNQVYKAX1K1",
"sender": "test@masv.io",
"size": 33454545,
"state": "finalized",
"total_files": 30,
"created_at": "2021-01-14T10:39:45.334Z",
"updated_at": "2021-01-14T16:39:56.350Z"
},
"custom_webhook_id": "ACHSFSDI32343ASD"
}

The size and total_files fields are populated on the package.finalized event (they are 0 during package.created).

MASV webhooks do not currently include a cryptographic signature for payload verification. To secure your webhook endpoint:

  • Use HTTPS — All webhook URLs must use HTTPS with a valid TLS certificate.
  • Use the headers field — Include a shared secret as a custom header when creating the webhook. Validate this header on your receiving endpoint to confirm the request originated from MASV.
  • Restrict by IP — If your infrastructure supports it, allowlist MASV’s outbound IP ranges.
  • Validate the payload structure — Check that event_type, custom_webhook_id, and object.id are present and well-formed before processing.