Skip to content

Webhooks ​

Webhooks let you receive real-time updates when certain actions happen in your Samply account—like when an upload finishes or a comment is added. When one of your subscribed events occurs, Samply sends an HTTP POST request to the URL you provide with a JSON payload describing the event.

Create a webhook ​

This endpoint creates a webhook and returns a webhook object.

Request type POST

Endpoint /webhooks

Attributes ​

js
{
  label: string,
  url: string,
  events: string[],
}

label string

A name to help you identify the webhook.


url string

The endpoint URL where Samply will send event payloads. Must be an https:// URL on a publicly reachable host, using port 443 or 8443.


events string array

One or more event types to subscribe to. See available events below.

Destination requirements ​

Destinations must be reachable from the public internet. Samply rejects a webhook with a 400 when the URL:

  • uses any scheme other than https://
  • uses a port other than 443 or 8443
  • contains a username or password
  • points at a loopback, private, link-local or cloud metadata address, or at a host that resolves to one

Redirects are not followed, so the destination must accept the POST directly.

Delete a webhook ​

This endpoint deletes a webhook by id.

Request type DELETE

Endpoint /webhooks/:webhookid

Available events ​

Event typeDescription
player.createdA new player is created
player.updatedAn existing player is modified
project.createdA new project is created
project.updatedAn existing project is modified
comment.createdA new comment is posted
upload.startedA file begins uploading
upload.completedA file has finished uploading
upload.failedA file upload fails due to an error

Webhook object ​

All webhook actions return a webhook object with the following structure.

js
{
  id: string,
  label: string,
  events: string[],
  url: string,
  timeCreated: number,
  timeModified: number,
  secret: string, // Only returned on create
}

id string readonly

Webhook id.


label string readonly

Webhook label.


events string array readonly

Subscribed event types.


url string readonly

Destination URL.


timeCreated number readonly

Time created in millis since Unix epoch.


timeModified number readonly

Time modified in millis since Unix epoch.


secret string readonly

Signing secret used to verify deliveries. Only returned on creation, so store it securely.

Example payload ​

json
{
  "id": "a459f855-da9f-4dfc-9181-35da2badfdcc",
  "type": "comment.created",
  "object": "event",
  "projectid": "mSg4Nu5vAch9pkCEcgDP",
  "boxid": "cd01f0c1-f1b3-4bc9-95c3-e14e5b01fbe1",
  "boxName": "Mystery Machine",
  "commentid": "uDXE192QibaDfK51eTTN",
  "data": {
    "after": {
      "id": "uDXE192QibaDfK51eTTN",
      "object": "comment",
      "message": "<p>Scooby Doo Where Are You?</p>",
      "creator": {
        "displayName": "eschirtz",
        "email": null,
        "photoURL": null,
        "uid": "TlYYwlHzZohpleC8a2Vo1SYY1902"
      },
      "isReply": false,
      "timeCreated": 1750041281427,
      "timeModified": 1750041281427
    }
  },
  "timeCreated": 1750041281427,
  "uid": "zklUx8RcjHZTqqi4mWoQNoBMsU03"
}

Verifying webhooks ​

Samply signs every delivery using the Standard Webhooks format. Every new webhook has its own signing secret, starting with whsec_. It's returned when you create the webhook, and you can also find it in your Samply preferences.

Every delivery includes these headers:

HeaderDescription
webhook-idUnique id for the event. The same as id in the payload. Use it to ignore duplicates.
webhook-timestampWhen the delivery was sent, in seconds since the Unix epoch.
webhook-signaturev1, followed by a base64 HMAC-SHA256 signature.

The signature is computed over {webhook-id}.{webhook-timestamp}.{raw request body}, keyed with the base64-decoded part of your secret after whsec_. Always verify against the raw body exactly as received, before parsing it as JSON.

To protect against replays, reject deliveries whose timestamp is more than 5 minutes from your current time, and ignore any webhook-id you've already processed.

The easiest way to verify is with a Standard Webhooks library, such as standardwebhooks for Node.js:

js
import { Webhook } from "standardwebhooks";

const wh = new Webhook(process.env.SAMPLY_WEBHOOK_SECRET);

app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  try {
    // Throws if the signature doesn't match or the timestamp is too old
    const event = wh.verify(req.body.toString(), req.headers);
    // Handle the event...
    res.sendStatus(200);
  } catch (error) {
    res.sendStatus(400);
  }
});

Webhooks created prior to October 2026 don't have a secret by default, so their deliveries arrive unsigned. To add a secret, open the webhook in your preferences and choose Generate signing secret to start signing them.

Tips ​

  • Test your endpoint with a tool like Webhook.site before going live.
  • Use webhooks alongside tools like Zapier or Make to trigger automations.
  • You can delete or update webhooks at any time from your Samply preferences.

Need help? Contact support or check out our integration guides.