Update a code
Change the destination
curl -X PATCH https://api.dotwick.com/v1/codes/qr_8841ce2mxk \ -H "Authorization: Bearer sk_live_…" \ -H "Content-Type: application/json" \ -d '{ "content": { "type": "url", "url": "https://example.com/fleet/van-014-spring" } }'{ "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}Partial updates
Send only the fields to change; the rest stay as they are. design and rules merge key by key into what is stored, arrays replace the stored array, and null clears a value.
A new slug keeps the old one working too, so links already printed never break. Every change is kept in the code's history (GET /v1/codes/{id}/versions) and sends a code.updated webhook.
Pause and resume
curl -X PATCH https://api.dotwick.com/v1/codes/qr_8841ce2mxk \ -H "Authorization: Bearer sk_live_…" \ -H "Content-Type: application/json" \ -d '{ "status": "paused" }'{ "id": "qr_8841ce2mxk", "status": "paused", "updatedAt": "2026-09-12T14:03:51.000Z"}Duplicate a code
POST /v1/codes/{id}/duplicate copies a code: its type, content, design, rules, password, tags, folder and domain come along. The copy gets its own short link, a name like Table 4 (copy), no scans and the status active. It counts against the plan like any new code and answers 201 with the new code, whose duplicatedFromId is the source.
Send name, folderId (null for the top level) or slug (Pro and above, dynamic codes) to set them on the copy. Business-card codes, GS1 codes and codes Dotwick disabled can't be duplicated. Send an Idempotency-Key so a retry never makes two copies.
curl -X POST https://api.dotwick.com/v1/codes/qr_8841ce2mxk/duplicate \ -H "Authorization: Bearer sk_live_…" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: van-014-copy-1" \ -d '{ "name": "Van fleet – unit 14 (spring)", "folderId": "fld_8k2m4q7x" }'{ "id": "qr_5d3b7e1f9a2c", "workspaceId": "ws_8f21ac4e9d0b7c11", "name": "Van fleet – unit 14 (spring)", "type": "url", "dynamic": true, "status": "active", "slug": "van14b", "domainId": null, "shortUrl": "https://dotwick.co/van14b", "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-12T14:03:51.000Z", "updatedAt": "2026-09-12T14:03:51.000Z", "scans": 0, "duplicatedFromId": "qr_8841ce2mxk"}Change many codes at once
PATCH /v1/codes/bulk does one action on up to 500 codes: pause, resume, archive, unarchive, addTags or removeTags (both with tagIds), move (with folderId, null for the top level) or delete. Not to be confused with POST /v1/codes/bulk, which creates codes.
Each code is handled on its own, with the same rules, events and webhooks as a single change. The answer is 200 even when some codes failed: results has one entry per code in request order, with ok and changed, or a reason and a message for a code that couldn't take the action, and counts adds them up. A code already in the state you asked for is ok with changed: false.
Repeating the request is safe, so it takes no Idempotency-Key. An unknown tag or folder fails the whole request with 404 not_found and writes nothing, and so does a move into a folder on a plan without folders (403 feature_not_in_plan).
- not_found: no such code, or it sits in a folder the key can't see.
- forbidden: the key's role may view the code but not change it.
- managed_code: the code belongs to a business card; pause, archive and delete go through the card.
- static_code and code_disabled: nothing to pause or resume.
- not_resumable: the code stopped because of its expiry date or scan limit; change that rule instead.
- too_many_tags: addTags would put more tags on the code than it can carry.
curl -X PATCH https://api.dotwick.com/v1/codes/bulk \ -H "Authorization: Bearer sk_live_…" \ -H "Content-Type: application/json" \ -d '{ "action": "pause", "codeIds": [ "qr_8841ce2mxk", "qr_2k8m4q7x1c9v" ] }'{ "action": "pause", "results": [ { "codeId": "qr_8841ce2mxk", "ok": true, "changed": true }, { "codeId": "qr_2k8m4q7x1c9v", "ok": false, "reason": "static_code", "message": "Static codes can't be paused: they work without our server." } ], "counts": { "ok": 1, "changed": 1, "failed": 1 }}