QRsome

API reference

The HTTP API behind QRsome. JSON in, JSON out. 14 endpoints.

Overview

QR codes for agents: styled static and dynamic QR codes from QRsome, for your own agent or a script (assistants use the MCP server with the same account). Dynamic codes do not expire: they redirect until you delete them. Authenticate with an API key from your account page: Authorization: Bearer sk_qr_…. Each code has stable image links (/f/<user>/<code id>.svg|png): they keep working, with the current look, until the code is deleted. New codes are drawn in your default saved look unless you name another (look) or "none"; a shape, color or logo you send wins. Never send images as base64 when a link works: give an https link to the logo.

Base URL

https://qrsome.com

Authentication

Send an API key in the Authorization header. Keys start with sk_qr_. Create and revoke keys in your account. A key is shown once.

Authorization: Bearer sk_qr_…

Endpoints

List your QR codes

GET/api/qr

Newest first.

Query parameters

  • limitinteger
  • cursorstring

    next_cursor from the previous page.

Example

curl 'https://qrsome.com/api/qr' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

200 A page of codes.

{
  "codes": [
    {
      "id": "string",
      "kind": "static",
      "label": "string",
      "encoded": "string",
      "destination": "string",
      "short_url": "string",
      "svg_url": "https://example.com",
      "png_url": "https://example.com",
      "look": null,
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z",
      "title": "string",
      "content_type": "url",
      "look_name": "string",
      "can_undo": true,
      "image_version": "string"
    }
  ],
  "next_cursor": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

Create a QR code

POST/api/qr

No limit on static codes (rate-limited to 60 per minute). Returns the code with its image URLs, or with ?format=svg|png the image itself (the code is still saved; its id is in X-QR-Id).

Query parameters

  • formatstring

Request body

  • datastring

    The exact text to encode. Give data or content, not both.

    At most 2953 characters.

  • contentobject

    A typed payload, formatted and escaped for you.

    • typestringrequired

      One of: "url", "text", "wifi", "vcard", "email", "sms", "phone", "geo", "whatsapp", "event", "social".

    • urlstring
    • textstring
    • ssidstring
    • passwordstring
    • encryptionstring

      One of: "WPA", "WEP", "nopass".

    • hiddenboolean
    • first_namestring
    • last_namestring
    • organizationstring
    • titlestring
    • phonestring
    • mobilestring
    • emailstring
    • streetstring
    • citystring
    • regionstring
    • postal_codestring
    • countrystring
    • notestring
    • tostring
    • subjectstring
    • bodystring
    • messagestring
    • latnumber
    • lngnumber
    • startstring

      event: 2026-11-05, 2026-11-05T19:30 or with Z / an offset.

    • endstring
    • locationstring
    • descriptionstring
    • networkstring

      One of: "instagram", "tiktok", "x", "facebook", "linkedin", "linkedin_company", "youtube", "threads", "github", "telegram".

    • handlestring

      social: the profile's handle, with or without @.

  • sizeinteger

    Width and height in pixels.

    Minimum 128. Maximum 2048.

  • margininteger

    Quiet zone in modules.

    Minimum 0. Maximum 8.

  • fgstring

    Foreground color. Must be darker than the background, contrast ratio at least 3:1.

  • bgstring | any

    Background color or transparent (checked as white).

  • gradientobject

    Linear gradient replacing fg; both stops must pass the contrast check.

    • fromstringrequired
    • tostringrequired
    • anglenumber

      Default: 0. Minimum 0. Maximum 360.

  • shapestring

    The code's shape: classic (square dots and corners), rounded, dots (round dots and corners) or elegant.

    One of: "classic", "rounded", "dots", "elegant".

  • logostring

    An https:// URL (fetched server-side: PNG, JPEG, SVG or WebP, up to 512 KB, 5 s timeout), brand for the default look's logo, none, or a data URL (data:image/png;base64,…) of a PNG, JPEG, SVG or WebP up to 200 KB. Forces error correction H; takes at most 22% of the width.

  • eccstring

    One of: "L", "M", "Q", "H".

  • labelstring

    At most 100 characters.

  • dynamicboolean

    Encode a short link whose destination can change later, with scan counts (links only: a url or social content, or data that is an http(s) URL).

  • lookstring

    A saved look by name, or none. Omitted: your default look, if any.

    At most 60 characters.

Example

curl -X POST 'https://qrsome.com/api/qr' \
  -H 'Authorization: Bearer sk_qr_…' \
  -H 'Content-Type: application/json' \
  -d '{"data":"string","content":{"type":"url","url":"string","text":"string","ssid":"string","password":"string","encryption":"WPA","hidden":true,"first_name":"string","last_name":"string","organization":"string","title":"string","phone":"string","mobile":"string","email":"string","street":"string","city":"string","region":"string","postal_code":"string","country":"string","note":"string","to":"string","subject":"string","body":"string","message":"string","lat":0,"lng":0,"start":"string","end":"string","location":"string","description":"string","network":"instagram","handle":"string"},"size":0,"margin":0,"fg":"string","bg":"string","gradient":{"from":"string","to":"string","angle":0},"shape":"classic","logo":"string","ecc":"L","label":"string","dynamic":true,"look":"string"}'

Responses

201 Created.

{
  "id": "string",
  "kind": "static",
  "label": "string",
  "encoded": "string",
  "destination": "string",
  "short_url": "string",
  "svg_url": "https://example.com",
  "png_url": "https://example.com",
  "look": null,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z",
  "title": "string",
  "content_type": "url",
  "look_name": "string",
  "can_undo": true,
  "image_version": "string"
}

400 Invalid input, too long, a bad logo, or colors that would not scan (`low_contrast`).

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

429 Rate limited.

{
  "error": "string",
  "message": "string"
}

Create a dynamic QR code (same as POST /api/qr with dynamic: true)

POST/api/qr/dynamic

Free includes 10 active dynamic codes. Generation is rate limited and subject to the account creation allowance. Returns the code with its short URL and image URLs.

Request body

  • urlstring (uri)required

    http(s) destination.

  • sizeinteger

    Width and height in pixels.

    Default: 512. Minimum 128. Maximum 2048.

  • margininteger

    Quiet zone in modules.

    Default: 2. Minimum 0. Maximum 8.

  • fgstring

    Foreground color. Must be darker than the background, contrast ratio at least 3:1.

    Default: "#000000".

  • bgstring | any

    Background color or transparent (checked as white).

    Default: "#ffffff".

  • gradientobject

    Linear gradient replacing fg; both stops must pass the contrast check.

    • fromstringrequired
    • tostringrequired
    • anglenumber

      Default: 0. Minimum 0. Maximum 360.

  • shapestring

    The code's shape: classic (square dots and corners), rounded, dots (round dots and corners) or elegant.

    One of: "classic", "rounded", "dots", "elegant".

  • logostring

    An https:// URL (fetched server-side: PNG, JPEG, SVG or WebP, up to 512 KB, 5 s timeout) or a data URL of a PNG, JPEG, SVG or WebP up to 200 KB. Forces error correction H; takes at most 22% of the width.

  • eccstring

    One of: "L", "M", "Q", "H". Default: "M".

  • labelstring

    At most 100 characters.

  • lookstring

    A saved look by name, or none. Omitted: your default look, if any.

    At most 60 characters.

Example

curl -X POST 'https://qrsome.com/api/qr/dynamic' \
  -H 'Authorization: Bearer sk_qr_…' \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","size":512,"margin":2,"fg":"#000000","bg":"#ffffff","gradient":{"from":"string","to":"string","angle":0},"shape":"classic","logo":"string","ecc":"M","label":"string","look":"string"}'

Responses

201 Created.

{
  "id": "string",
  "kind": "static",
  "label": "string",
  "encoded": "string",
  "destination": "string",
  "short_url": "string",
  "svg_url": "https://example.com",
  "png_url": "https://example.com",
  "look": null,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z",
  "title": "string",
  "content_type": "url",
  "look_name": "string",
  "can_undo": true,
  "image_version": "string"
}

400 Invalid input or URL refused.

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

429 Too many requests in a short time; wait before trying again.

{
  "error": "string",
  "message": "string"
}

Get one QR code

GET/api/qr/{id}

Path parameters

  • idstringrequired

Example

curl 'https://qrsome.com/api/qr/string' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

200 The code.

{
  "id": "string",
  "kind": "static",
  "label": "string",
  "encoded": "string",
  "destination": "string",
  "short_url": "string",
  "svg_url": "https://example.com",
  "png_url": "https://example.com",
  "look": null,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z",
  "title": "string",
  "content_type": "url",
  "look_name": "string",
  "can_undo": true,
  "image_version": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

404 Not found in your account.

{
  "error": "string",
  "message": "string"
}

Update a QR code

PATCH/api/qr/{id}

Label, destination (dynamic codes) and look. Only the fields you send change: every other look field keeps its current value. What the code encodes never changes, and its image links stay the same and serve the new image.

Path parameters

  • idstringrequired

Request body

  • labelstring

    A new name (empty removes it).

    At most 100 characters.

  • urlstring

    Dynamic codes: the new destination.

  • lookstring

    Redraw in a saved look (its whole look), or none for plain.

    At most 60 characters.

  • fgstring

    Foreground color. Must be darker than the background, contrast ratio at least 3:1.

  • bgstring | any

    Background color or transparent (checked as white).

  • gradientobject

    Linear gradient replacing fg; both stops must pass the contrast check.

    • fromstringrequired
    • tostringrequired
    • anglenumber

      Default: 0. Minimum 0. Maximum 360.

  • shapestring

    The code's shape: classic (square dots and corners), rounded, dots (round dots and corners) or elegant.

    One of: "classic", "rounded", "dots", "elegant".

  • logostring

    An https:// URL (fetched server-side: PNG, JPEG, SVG or WebP, up to 512 KB, 5 s timeout), brand for the default look's logo, none, or a data URL (data:image/png;base64,…) of a PNG, JPEG, SVG or WebP up to 200 KB. Forces error correction H; takes at most 22% of the width.

  • sizeinteger

    Width and height in pixels.

    Minimum 128. Maximum 2048.

  • margininteger

    Quiet zone in modules.

    Minimum 0. Maximum 8.

  • eccstring

    One of: "L", "M", "Q", "H".

Example

curl -X PATCH 'https://qrsome.com/api/qr/string' \
  -H 'Authorization: Bearer sk_qr_…' \
  -H 'Content-Type: application/json' \
  -d '{"label":"string","url":"string","look":"string","fg":"string","bg":"string","gradient":{"from":"string","to":"string","angle":0},"shape":"classic","logo":"string","size":0,"margin":0,"ecc":"L"}'

Responses

200 Updated.

{
  "id": "string",
  "kind": "static",
  "label": "string",
  "encoded": "string",
  "destination": "string",
  "short_url": "string",
  "svg_url": "https://example.com",
  "png_url": "https://example.com",
  "look": null,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z",
  "title": "string",
  "content_type": "url",
  "look_name": "string",
  "can_undo": true,
  "image_version": "string"
}

400 Invalid request, low contrast, logo refused, or a destination for a static code.

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

404 No such code.

{
  "error": "string",
  "message": "string"
}

Delete a QR code

DELETE/api/qr/{id}

Deletes the images and, for a dynamic code, its short link (printed copies stop working).

Path parameters

  • idstringrequired

Example

curl -X DELETE 'https://qrsome.com/api/qr/string' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

204 Deleted.

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

404 Not found in your account.

{
  "error": "string",
  "message": "string"
}

Scan stats of a dynamic code

GET/api/qr/{id}/stats

Path parameters

  • idstringrequired

Query parameters

  • daysinteger

Example

curl 'https://qrsome.com/api/qr/string/stats' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

200 Stats.

{
  "qr": {
    "id": "string",
    "kind": "static",
    "label": "string",
    "encoded": "string",
    "destination": "string",
    "short_url": "string",
    "svg_url": "https://example.com",
    "png_url": "https://example.com",
    "look": null,
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": "2026-01-01T00:00:00Z",
    "title": "string",
    "content_type": "url",
    "look_name": "string",
    "can_undo": true,
    "image_version": "string"
  },
  "stats": {
    "slug": "string",
    "total": 0,
    "by_day": [
      {
        "date": "string",
        "count": 0
      }
    ],
    "by_country": [
      {
        "country": "string",
        "count": 0
      }
    ],
    "by_referrer": [
      {
        "host": "string",
        "count": 0
      }
    ]
  }
}

400 A static code (`not_dynamic`) or bad `days`.

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

404 Not found in your account.

{
  "error": "string",
  "message": "string"
}

Update a QR code (same as PATCH /api/qr/{id})

POST/api/qr/{id}/style

Label, destination (dynamic codes) and look. Only the fields you send change: every other look field keeps its current value. What the code encodes never changes, and its image links stay the same and serve the new image.

Path parameters

  • idstringrequired

Request body

  • labelstring

    A new name (empty removes it).

    At most 100 characters.

  • urlstring

    Dynamic codes: the new destination.

  • lookstring

    Redraw in a saved look (its whole look), or none for plain.

    At most 60 characters.

  • fgstring

    Foreground color. Must be darker than the background, contrast ratio at least 3:1.

  • bgstring | any

    Background color or transparent (checked as white).

  • gradientobject

    Linear gradient replacing fg; both stops must pass the contrast check.

    • fromstringrequired
    • tostringrequired
    • anglenumber

      Default: 0. Minimum 0. Maximum 360.

  • shapestring

    The code's shape: classic (square dots and corners), rounded, dots (round dots and corners) or elegant.

    One of: "classic", "rounded", "dots", "elegant".

  • logostring

    An https:// URL (fetched server-side: PNG, JPEG, SVG or WebP, up to 512 KB, 5 s timeout), brand for the default look's logo, none, or a data URL (data:image/png;base64,…) of a PNG, JPEG, SVG or WebP up to 200 KB. Forces error correction H; takes at most 22% of the width.

  • sizeinteger

    Width and height in pixels.

    Minimum 128. Maximum 2048.

  • margininteger

    Quiet zone in modules.

    Minimum 0. Maximum 8.

  • eccstring

    One of: "L", "M", "Q", "H".

Example

curl -X POST 'https://qrsome.com/api/qr/string/style' \
  -H 'Authorization: Bearer sk_qr_…' \
  -H 'Content-Type: application/json' \
  -d '{"label":"string","url":"string","look":"string","fg":"string","bg":"string","gradient":{"from":"string","to":"string","angle":0},"shape":"classic","logo":"string","size":0,"margin":0,"ecc":"L"}'

Responses

200 Updated.

{
  "id": "string",
  "kind": "static",
  "label": "string",
  "encoded": "string",
  "destination": "string",
  "short_url": "string",
  "svg_url": "https://example.com",
  "png_url": "https://example.com",
  "look": null,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z",
  "title": "string",
  "content_type": "url",
  "look_name": "string",
  "can_undo": true,
  "image_version": "string"
}

400 Invalid request, low contrast, logo refused, or a destination for a static code.

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

404 No such code.

{
  "error": "string",
  "message": "string"
}

Create up to 200 QR codes in one look

POST/api/qr/batch

Each item has a label and data or content. Items that fail (bad content, the dynamic limit) are listed in failed; the rest are made. zip_url downloads every SVG and PNG and a CSV (label, content, links).

Request body

  • itemsarray of objectrequired

    At most 200 items.

    • labelstringrequired

      At most 100 characters.

    • datastring

      The exact text to encode. Give data or content, not both.

      At most 2953 characters.

    • contentany
  • dynamicboolean

    Encode a short link whose destination can change later, with scan counts (links only: a url or social content, or data that is an http(s) URL).

  • lookstring

    A saved look by name, or none. Omitted: your default look, if any.

    At most 60 characters.

  • fgstring

    Foreground color. Must be darker than the background, contrast ratio at least 3:1.

  • bgstring | any

    Background color or transparent (checked as white).

  • gradientobject

    Linear gradient replacing fg; both stops must pass the contrast check.

    • fromstringrequired
    • tostringrequired
    • anglenumber

      Default: 0. Minimum 0. Maximum 360.

  • shapestring

    The code's shape: classic (square dots and corners), rounded, dots (round dots and corners) or elegant.

    One of: "classic", "rounded", "dots", "elegant".

  • logostring

    An https:// URL (fetched server-side: PNG, JPEG, SVG or WebP, up to 512 KB, 5 s timeout), brand for the default look's logo, none, or a data URL (data:image/png;base64,…) of a PNG, JPEG, SVG or WebP up to 200 KB. Forces error correction H; takes at most 22% of the width.

  • sizeinteger

    Width and height in pixels.

    Minimum 128. Maximum 2048.

  • margininteger

    Quiet zone in modules.

    Minimum 0. Maximum 8.

  • eccstring

    One of: "L", "M", "Q", "H".

Example

curl -X POST 'https://qrsome.com/api/qr/batch' \
  -H 'Authorization: Bearer sk_qr_…' \
  -H 'Content-Type: application/json' \
  -d '{"items":[{"label":"string","data":"string","content":null}],"dynamic":true,"look":"string","fg":"string","bg":"string","gradient":{"from":"string","to":"string","angle":0},"shape":"classic","logo":"string","size":0,"margin":0,"ecc":"L"}'

Responses

201 The codes made and the ones that failed.

{
  "batch_id": "string",
  "codes": [
    {
      "id": "string",
      "kind": "static",
      "label": "string",
      "encoded": "string",
      "destination": "string",
      "short_url": "string",
      "svg_url": "https://example.com",
      "png_url": "https://example.com",
      "look": null,
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z",
      "title": "string",
      "content_type": "url",
      "look_name": "string",
      "can_undo": true,
      "image_version": "string"
    }
  ],
  "failed": [
    {
      "index": 0,
      "label": "string",
      "error": "string"
    }
  ],
  "zip_url": "https://example.com"
}

400 Invalid request.

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

429 Too many requests.

{
  "error": "string",
  "message": "string"
}

Search your QR codes

GET/api/qr/search

Fuzzy (typos and accents forgiven) over the label, the link and its site, the WiFi network, the contact's name, the event and the look's name. Without q: the filtered codes, newest first.

Query parameters

  • qstring
  • content_typestring
  • dynamicboolean
  • created_afterstring (date)
  • created_beforestring (date)
  • lookstring

    Only codes drawn in this saved look.

  • limitinteger

Example

curl 'https://qrsome.com/api/qr/search' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

200 Best match first.

{
  "codes": [
    {
      "id": "string",
      "kind": "static",
      "label": "string",
      "encoded": "string",
      "destination": "string",
      "short_url": "string",
      "svg_url": "https://example.com",
      "png_url": "https://example.com",
      "look": null,
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z",
      "title": "string",
      "content_type": "url",
      "look_name": "string",
      "can_undo": true,
      "image_version": "string"
    }
  ],
  "total": 0
}

400 Invalid filter.

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

List your saved looks

GET/api/looks

Example

curl 'https://qrsome.com/api/looks' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

200 Default first.

{
  "looks": [
    {
      "name": "string",
      "is_default": true,
      "fg": "string",
      "bg": "string",
      "gradient": {
        "from": "string",
        "to": "string",
        "angle": 0
      },
      "shape": "classic",
      "logo": true,
      "sample_svg_url": "https://example.com",
      "sample_png_url": "https://example.com",
      "updated_at": "2026-01-01T00:00:00Z"
    }
  ]
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

Save a look

PUT/api/looks

Creates the look, or updates the one with this name (case-insensitive): only the fields you send change. Colors are checked for contrast like a code. How many looks an account keeps depends on its plan (1 on Free); over it, 429 limit_reached.

Request body

  • namestringrequired

    The look's name; saving an existing name (case-insensitive) updates it.

    At most 60 characters.

  • logostring

    An https URL of a PNG, JPEG, SVG or WebP up to 512 KB (fetched once and kept), a data URL of one up to 200 KB, or none. Omitted: the look keeps its logo.

  • fgstring

    Foreground color, hex.

  • bgstring

    Background color, hex, or "transparent".

  • gradientobject
    • fromstringrequired
    • tostringrequired
    • anglenumber
  • shapestring

    The code's shape: classic (square dots and corners), rounded, dots (round dots and corners) or elegant.

    One of: "classic", "rounded", "dots", "elegant".

  • defaultboolean

    Make it the default look. The first look saved becomes the default.

  • from_codestring

    Copy this code's shape, color and logo; fields you send win.

Example

curl -X PUT 'https://qrsome.com/api/looks' \
  -H 'Authorization: Bearer sk_qr_…' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","logo":"string","fg":"string","bg":"string","gradient":{"from":"string","to":"string","angle":0},"shape":"classic","default":true,"from_code":"string"}'

Responses

200 Saved.

{
  "name": "string",
  "is_default": true,
  "fg": "string",
  "bg": "string",
  "gradient": {
    "from": "string",
    "to": "string",
    "angle": 0
  },
  "shape": "classic",
  "logo": true,
  "sample_svg_url": "https://example.com",
  "sample_png_url": "https://example.com",
  "updated_at": "2026-01-01T00:00:00Z"
}

400 Empty look, low contrast or logo refused.

{
  "error": "string",
  "message": "string"
}

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

409 Too many looks, or changed at the same time.

{
  "error": "string",
  "message": "string"
}

Delete a look

DELETE/api/looks

Codes drawn in it keep their look.

Query parameters

  • namestringrequired

Example

curl -X DELETE 'https://qrsome.com/api/looks?name=string' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

204 Deleted.

401 Missing or invalid API key.

{
  "error": "string",
  "message": "string"
}

404 No such look.

{
  "error": "string",
  "message": "string"
}

Restore the previous QR appearance

POST/api/qr/{id}/undo

Restores a code's previous appearance (shape, colors and logo), including changes made in chat. Up to 20 appearances are kept. Its content, label, dynamic destination and saved looks stay unchanged. Returns the code in the preview with its current downloads.

Path parameters

  • idstringrequired

Example

curl -X POST 'https://qrsome.com/api/qr/string/undo' \
  -H 'Authorization: Bearer sk_qr_…'

Responses

200 Restored QR code

{
  "id": "string",
  "kind": "static",
  "label": "string",
  "encoded": "string",
  "destination": "string",
  "short_url": "string",
  "svg_url": "https://example.com",
  "png_url": "https://example.com",
  "look": null,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z",
  "title": "string",
  "content_type": "url",
  "look_name": "string",
  "can_undo": true,
  "image_version": "string"
}

409 No earlier look, or concurrent change