Event types
The envelope
{ id, type, apiVersion, createdAt, workspaceId, actor, data }. id is the event id (evt_…), also sent as webhook-id. apiVersion is the payload version the endpoint was created with (2026-09-01).
actor says who caused the event: user (someone in the app), api_key (with its id), staff or system (scans, jobs, domain checks). An integration that writes back through the API can skip events its own key caused, which prevents loops.
New event types and new fields can appear at any time: ignore what you don't know. A change that would break a parser ships as a new apiVersion that existing endpoints opt into.
Events
Payloads
One example of every event, as it is delivered.
code.created
{ "id": "evt_018f3k2m9q4x7c1v", "type": "code.created", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "api_key", "userId": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "apiKeyId": "key_4f2a9c1e7b3d5a60" }, "data": { "code": { "id": "qr_8841ce2mxk", "workspaceId": "ws_8f21ac4e9d0b7c11", "name": "Van fleet – unit 14", "type": "url", "dynamic": true, "status": "active", "slug": "Xq7mK2p", "domainId": null, "shortUrl": "https://dotwick.co/Xq7mK2p", "content": { "type": "url", "url": "https://example.com/fleet/van-014" }, "design": { "pattern": "rounded", "eyes": { "frame": "circle", "ball": "circle" }, "colors": { "fg": "#18181B", "bg": "#FFFFFF" } }, "rules": { "routes": [], "expiresAt": null, "scanLimit": null, "inactiveUrl": null, "passwordProtected": false }, "folderId": "fld_8k2m4q7x", "templateId": null, "createdBy": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "createdAt": "2026-09-10T09:41:08.000Z", "updatedAt": "2026-09-10T09:41:08.000Z", "scans": 0 } }}code.updated
{ "id": "evt_028f3k2m9q4x7c1v", "type": "code.updated", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "user", "userId": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "apiKeyId": null }, "data": { "code": { "id": "qr_8841ce2mxk", "workspaceId": "ws_8f21ac4e9d0b7c11", "name": "Van fleet – unit 14", "type": "url", "dynamic": true, "status": "active", "slug": "Xq7mK2p", "domainId": null, "shortUrl": "https://dotwick.co/Xq7mK2p", "content": { "type": "url", "url": "https://example.com/fleet/van-014-spring" }, "design": { "pattern": "rounded", "eyes": { "frame": "circle", "ball": "circle" }, "colors": { "fg": "#18181B", "bg": "#FFFFFF" } }, "rules": { "routes": [], "expiresAt": null, "scanLimit": null, "inactiveUrl": null, "passwordProtected": false }, "folderId": "fld_8k2m4q7x", "templateId": null, "createdBy": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "createdAt": "2026-09-10T09:41:08.000Z", "updatedAt": "2026-09-12T14:03:51.000Z", "scans": 0 }, "changed": [ "content" ], "previousDestination": "https://example.com/fleet/van-014" }}code.status_changed
{ "id": "evt_038f3k2m9q4x7c1v", "type": "code.status_changed", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "user", "userId": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "apiKeyId": null }, "data": { "code": { "id": "qr_8841ce2mxk", "workspaceId": "ws_8f21ac4e9d0b7c11", "name": "Van fleet – unit 14", "type": "url", "dynamic": true, "status": "paused", "slug": "Xq7mK2p", "domainId": null, "shortUrl": "https://dotwick.co/Xq7mK2p", "content": { "type": "url", "url": "https://example.com/fleet/van-014" }, "design": { "pattern": "rounded", "eyes": { "frame": "circle", "ball": "circle" }, "colors": { "fg": "#18181B", "bg": "#FFFFFF" } }, "rules": { "routes": [], "expiresAt": null, "scanLimit": null, "inactiveUrl": null, "passwordProtected": false }, "folderId": "fld_8k2m4q7x", "templateId": null, "createdBy": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "createdAt": "2026-09-10T09:41:08.000Z", "updatedAt": "2026-09-12T14:03:51.000Z", "scans": 0 }, "from": "active", "to": "paused", "reason": "user" }}code.deleted
{ "id": "evt_048f3k2m9q4x7c1v", "type": "code.deleted", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "api_key", "userId": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "apiKeyId": "key_4f2a9c1e7b3d5a60" }, "data": { "codeId": "qr_8841ce2mxk", "name": "Van fleet – unit 14", "slug": "Xq7mK2p", "deletedAt": "2026-09-12T14:03:51.000Z" }}scan.created
{ "id": "evt_058f3k2m9q4x7c1v", "type": "scan.created", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "system", "userId": null, "apiKeyId": null }, "data": { "ts": "2026-09-12T14:03:51.000Z", "codeId": "qr_8841ce2mxk", "codeName": "Van fleet – unit 14", "country": "US", "city": "Portland", "device": "mobile", "os": "iOS 18", "browser": "Safari 18", "source": "qr", "isBot": false }}bulk.completed
{ "id": "evt_068f3k2m9q4x7c1v", "type": "bulk.completed", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "system", "userId": null, "apiKeyId": null }, "data": { "bulkImportId": "blk_9f24ab7c3e1d5f80", "status": "partially_succeeded", "total": 50, "created": 47, "failed": 1, "invalid": 2, "canceled": 0, "folderId": "fld_8k2m4q7x", "exportId": "exp_2m7x4k9q1c8v3b6n" }}export.completed
{ "id": "evt_078f3k2m9q4x7c1v", "type": "export.completed", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "system", "userId": null, "apiKeyId": null }, "data": { "exportId": "exp_2m7x4k9q1c8v3b6n", "status": "succeeded", "counts": { "total": 47, "succeeded": 47, "failed": 0 }, "formats": [ "svg", "pdf" ], "expiresAt": "2026-09-19T14:03:51.000Z", "bulkImportId": "blk_9f24ab7c3e1d5f80" }}domain.status_changed
{ "id": "evt_088f3k2m9q4x7c1v", "type": "domain.status_changed", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "system", "userId": null, "apiKeyId": null }, "data": { "domainId": "dom_5q8w2e7r4t1y9u3i", "hostname": "qr.example.com", "from": "ssl_issuing", "to": "active" }}form.submitted
{ "id": "evt_098f3k2m9q4x7c1v", "type": "form.submitted", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "system", "userId": null, "apiKeyId": null }, "data": { "codeName": "Open house – RSVP", "submission": { "id": "fsb_6h3j8k1l4z7x2c5v", "codeId": "qr_8841ce2mxk", "submittedAt": "2026-09-12T14:03:51.000Z", "data": { "name": "Sam Okafor", "email": "sam@example.com", "guests": "2" }, "country": "US" } }}gs1.recall_changed
{ "id": "evt_108f3k2m9q4x7c1v", "type": "gs1.recall_changed", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "user", "userId": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "apiKeyId": null }, "data": { "codeId": "qr_8841ce2mxk", "gtin14": "09506000134352", "qualifier": { "id": "gsq_4v8n2k7m1x5c9b3q", "codeId": "qr_8841ce2mxk", "key": "10:LOT-42", "level": "batch", "cpv": null, "batch": "LOT-42", "serial": null, "links": [], "defaultLinkType": null, "state": "recalled", "recall": { "title": "Do not use batch LOT-42", "body": "Northwind withdrew this batch after a supplier issue. Return the jar for a full refund.", "date": "2026-09-12", "contact": "recalls@example.com" }, "expiry": "271231", "printed": 5000, "note": null, "stateChangedAt": "2026-09-12T14:03:51.000Z", "createdAt": "2026-09-10T09:41:08.000Z", "updatedAt": "2026-09-12T14:03:51.000Z" }, "from": "clear", "to": "recalled" }}alert.fired
{ "id": "evt_128f3k2m9q4x7c1v", "type": "alert.fired", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "system", "userId": null, "apiKeyId": null }, "data": { "ruleId": "alr_3d9k2m7q4x8c1v5n", "ruleName": "Spring menu: 50 scans in 10 minutes", "kind": "threshold", "scope": { "kind": "folder", "codeId": null, "folderId": "fld_8k2m4q7x" }, "codeId": null, "codeName": null, "scans": 50, "windowStart": "2026-09-12T13:53:51.000Z", "windowEnd": "2026-09-12T14:03:51.000Z", "firedAt": "2026-09-12T14:03:51.000Z" }}webhook.test
{ "id": "evt_118f3k2m9q4x7c1v", "type": "webhook.test", "apiVersion": "2026-09-01", "createdAt": "2026-09-12T14:03:51.000Z", "workspaceId": "ws_8f21ac4e9d0b7c11", "actor": { "kind": "user", "userId": "u8Hk2LmN0pQ4rS6tV8wX0yZ2aB4cD6eF", "apiKeyId": null }, "data": { "endpointId": "whe_3k8m2q9x7c4v1b6n", "message": "Test event from Dotwick" }}bulk.completed fields
One event per finished run, whatever its size — not one code.created per code. It carries counts only: fetch the codes from the run.
data.bulkImportIdstringID of the run (blk_…).data.status"succeeded" | "partially_succeeded" | "failed" | "canceled"How the run ended.data.totalnumberItems in the request (rows of a file).data.creatednumberCodes created.data.failednumberValid items whose code failed to create at run time — retryable.data.invalidnumberItems skipped before the run started, for bad or missing data.data.cancelednumberItems left unprocessed because the run was cancelled.data.folderIdstring | nullFolder the codes were filed under, or null for the workspace root.data.exportIdstring | nullID of the ZIP export when the run asked for one — otherwise null.