Open this in Magpie

A webhook sends a JSON message to an address you choose when something happens to the issues or projects of Personal or the selected team. Team admins manage webhooks.

Create a webhook

Open Webhooks in the Issues section of the sidebar and choose Create webhook. Enter a name, the endpoint address and the events to send, then choose Save webhook. The address must use HTTPS and its host must resolve to a public address. Redirects are not followed.

After saving, the page shows the webhook's signing secret once. Choose Copy secret and store it where your endpoint can read it; Magpie shows only its last four characters after that.

Event Sent when
issue.created An issue is created, including by a public form, the API or an import
issue.updated An issue, its labels, links, attachments, comments or triage state change, or it is restored from Trash
issue.completed An issue moves into a status in the Completed category
issue.deleted An issue is moved to Trash
comment.created Someone comments on an issue
project.created A project is created
project.completed A project's status is set to Completed

Manage webhooks

The Webhooks page lists each webhook with its address, its events, whether it is enabled, the end of its signing secret and when it last delivered. Beside each one:

  • Pause stops sending, and Enable starts again.
  • Rotate secret makes a new signing secret and shows it once. The old secret stops working at once.
  • Remove removes the webhook.

Choose a webhook's name to change its name, address, events or Enabled setting. Pausing or removing a webhook, or changing its address or events, cancels the deliveries still waiting to be sent to it.

What Magpie sends

Each delivery is an HTTPS POST with a JSON body:

{
  "id": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
  "type": "issue.updated",
  "created_at": "2026-10-15T09:30:00+00:00",
  "data": {
    "issue": {
      "uuid": "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b",
      "identifier": "WEB-14",
      "title": "Checkout button does nothing",
      "description_markdown": "Steps to reproduce...",
      "status": "in_progress",
      "priority": "high",
      "assignee_user_id": 42,
      "due_date": "2026-10-20",
      "project": { "uuid": "a7f3c2d1-0b6e-4c8a-9e21-5d4b3c2a1f00", "name": "Website" },
      "created_at": "2026-10-01 08:00:00",
      "updated_at": "2026-10-15 09:30:00"
    },
    "team": { "id": 7, "name": "Acme" },
    "actor": { "id": 42, "name": "Sam Lee" }
  }
}

status is the status's key, not its display name. An issue.created event also has source: internal, api, public_form or import. An issue.deleted event has deleted_at, and a comment.created event has a comment with its uuid, body_markdown and created_at. Project events have a project with its uuid, name, identifier_prefix, description_markdown, status, start_date and target_date in place of issue.

Each request has these headers:

  • X-Magpie-Event: the event type.
  • X-Magpie-Id: the event ID, the same as id in the body.
  • X-Magpie-Timestamp: when this attempt was signed, in Unix seconds.
  • X-Magpie-Signature: t=<timestamp>,v1=<hex digest>.

Verify a delivery

Before you use a delivery, compute an HMAC-SHA256 of the timestamp, a full stop and the raw request body, using the signing secret as the key, and compare it with the v1 value. Reject a request whose timestamp is older than you allow. In PHP:

parse_str(str_replace(',', '&', $_SERVER['HTTP_X_MAGPIE_SIGNATURE']), $sig);
$expected = hash_hmac('sha256', $sig['t'] . '.' . $rawBody, $secret);
$valid = hash_equals($expected, $sig['v1']) && abs(time() - (int) $sig['t']) < 300;

Retries

Events are queued when the change is made and sent by a background job. A response with a 2xx status counts as delivered. After a failure, Magpie tries again with increasing delays, up to 5 attempts in all, and then stops. A retry keeps the same event ID, so the same event can arrive more than once; store the IDs you have handled and skip repeats.

For help with webhooks, Contact support.

Ask Magpie support

Send Magpie staff a question about anything this article does not answer.