Skip to main content
Diagram of Magica pushing webhook events to a customer server
Webhooks let your server receive HTTP POST notifications for asynchronous model and workflow runs. Public REST consumers should verify the signature, respond quickly, and process events idempotently.
Delivery is powered by Svix: automatic retries, HMAC-SHA256 signatures, and delivery logging included.

Configure a webhook

Pass a webhook object when starting a model run or workflow run.
curl -X POST https://api.magica.com/api/v1/runs \
  -H "Authorization: Bearer $MAGICA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflowId": "workflow-or-system-slug",
    "webhook": {
      "url": "https://your-app.com/webhooks/magica",
      "events": ["run.completed", "run.failed"],
      "metadata": { "orderId": "order_456" }
    }
  }'
For standalone model runs, include the same webhook object in POST /v1/nodes/{nodeType}/run.

Supported events

Model runs and workflow runs support different event sets.
EventModel runWorkflow runDescription
run.startedYesYesThe run started
run.completedYesYesThe run completed successfully
run.failedYesYesThe run failed
run.canceledNoYesThe workflow run was canceled
node.completedNoYesOne workflow node completed
node.failedNoYesOne workflow node failed
When you omit events, Magica sends every event supported by that run type.

Event payload

{
  "success": true,
  "type": "run.completed",
  "runId": "cuid_abc123",
  "workflowId": "cuid_def456",
  "data": { "status": "COMPLETED", "completedNodes": 5, "failedNodes": 0 },
  "metadata": { "orderId": "order_456" },
  "error": null,
  "createdAt": "2026-02-18T12:00:00.000Z"
}
FieldTypeDescription
successbooleantrue for success events, false for failures
typestringEvent type, such as run.completed
runIdstringExecution run ID
workflowIdstringWorkflow definition ID for workflow runs; node type for standalone model runs
dataobjectEvent-specific data
metadataobject | nullCustom metadata echoed back by the execution surface
errorstring | nullError message for failure events
createdAtstringISO 8601 timestamp

Event types

run.started

A run begins executing.

run.completed

All requested work finished successfully.

run.failed

One or more steps failed.

run.canceled

The run was canceled.

node.completed

A single node finished successfully.

node.failed

A single node failed.

Handler pattern

Always respond 200 OK immediately and process asynchronously. If your handler takes too long, Svix will retry and you may receive duplicate deliveries.
app.post("/webhooks/magica", (req, res) => {
  res.status(200).send("OK");

  const event = req.body;
  if (event.type === "run.completed") {
    enqueueResultProcessing(event.runId);
  }
  if (event.type === "run.failed") {
    logRunFailure(event.runId, event.error);
  }
});

Security

Every webhook is signed with HMAC-SHA256 via Svix. Verify signatures before trusting the payload:
import { Webhook } from "svix";

app.use("/webhooks/magica", express.raw({ type: "application/json" }));

const wh = new Webhook("whsec_your_signing_secret");

app.post("/webhooks/magica", (req, res) => {
  try {
    const payload = wh.verify(req.body, {
      "svix-id": req.headers["svix-id"],
      "svix-timestamp": req.headers["svix-timestamp"],
      "svix-signature": req.headers["svix-signature"],
    });
    res.status(200).send("OK");
    enqueueWebhook(payload);
  } catch (err) {
    res.status(400).send("Invalid signature");
  }
});