Skip to content

Update access and the link

PATCH/api/v1/content/{id}

Access
API key
Permission
content:write

Update title, access, password, one-time opening, expiry, view limit or download UI

Example request

curl -X PATCH "https://lac.pics/api/v1/content/Xq3u9RkT0bLmA7cV2pWz1eFy" \
  -H "Authorization: Bearer lac_api_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "visibility": "unlisted",
  "password": "correct-horse-7",
  "ttl": "week"
}'

Parameters

Path

  • idstringrequired

    The file or note id.

Request body

application/jsonrequired

  • tagsarray of string

    NFKC, trim, collapse spaces and lowercase; deduplicated after normalization. Raw controls are invalid. Omission preserves tags on update; an empty array clears them.

    up to 10 items · unique

  • titlestring

    Title, up to 180 characters.

    up to 180 characters

  • visibilitystring

    private is owner-only. unlisted is accessible by link. public also appears in the authenticated feed and profile. public cannot be combined with oneTime (400 ONE_TIME_NOT_PUBLIC). Omitted on creation: use the account default (private or unlisted). Omitted on update: retain current access.

    values: "private" "unlisted" "public"

  • ttlstring

    Relative to this request; forever clears expiry. Access stops at expiry; encrypted objects are removed asynchronously through a persistent retry queue.

    values: "forever" "day" "week" "month"

  • passwordstringrequest only

    8–128 characters. Empty string removes the password; omission retains it on update. Stored as Argon2id, never returned. Changing it revokes previous viewer access. Other accounts see protected content in the feed, favorites, profiles and albums only as a locked card (id, type, author, lock flags): title, tags, file name, size, dimensions, dates and previews stay hidden.

    up to 128 characters · pattern ^(?:[\s\S]{8,128})?$

  • oneTimeboolean

    Only the first guest browser to explicitly open the share page receives access, for at most 10 minutes (including video Range requests). Owner previews and GET/HEAD do not consume the link. Omission retains the setting on update. Cannot be combined with visibility public: the resulting state is checked on creation and update (400 ONE_TIME_NOT_PUBLIC). Other accounts never see one-time content in the feed, profiles or albums.

    default false

  • allowDownloadboolean

    Disables the explicit download action; not DRM

  • expiresAtstring · date-time

    Link control (Pro, plan feature link_expiry): the exact end of the file and its link, 5 minutes to 10 years ahead (400 LINK_EXPIRY_INVALID), instead of a ttl preset — sending both is 400 VALIDATION_FAILED. Like ttl, the file is removed at that time.

    up to 40 characters

  • viewLimitintegeror null

    Link control (Pro, plan feature view_limit): counted views after which the link answers like an expired one. A limit at or below the views so far ends the link at once; raising or removing it (null, allowed on any plan) opens it again. Existing limits keep working after a plan ends.

    1–1,000,000

Responses

  • 200SuccessContent
    • idstringrequired

      The file id.

    • titlestringrequired

      Title, up to 180 characters.

    • tagsarray of stringrequired

      NFKC, trim, collapse spaces and lowercase; deduplicated after normalization. Raw controls are invalid. Omission preserves tags on update; an empty array clears them.

      up to 10 items · unique

    • originalNamestring

      The original file name.

    • typestringrequired

      IMAGE, VIDEO, PASTE or FOLDER (a folder of code).

      values: "IMAGE" "VIDEO" "PASTE" "FOLDER"

    • mimestringrequired

      The MIME type of the stored file.

    • pasteFormatstringor null

      values: "plain" "markdown" "code"

    • pasteLanguagestringor null
    • folderFilesintegeror null

      A code folder (type FOLDER): files in its archive. Null for other kinds. The archive itself is the media: GET /api/media/{id} serves it (Range requests read one file by the ZIP central directory), ?download=1 as an attachment.

      at least 1

    • revisionintegerrequired

      Optimistic revision for editing saved paste text; distinct from share access version.

      at least 1

    • accessVersionintegerrequired

      Share access version: 1 for a new file, raised by every change of visibility, password or one-time. From 2 on, url carries it as ?v= so messengers build a fresh link card instead of the one they kept for the previous access.

      at least 1

    • sizeinteger · int64required

      Size in bytes.

    • visibilitystringrequired

      private is owner-only. unlisted is accessible by link. public also appears in the authenticated feed and profile. public cannot be combined with oneTime (400 ONE_TIME_NOT_PUBLIC). Omitted on creation: use the account default (private or unlisted). Omitted on update: retain current access.

      values: "private" "unlisted" "public"

    • allowDownloadbooleanrequired
    • passwordProtectedbooleanrequired
    • oneTimebooleanrequired
    • consumedAtstring · date-timeor null
    • readExpiresAtstring · date-timeor null
    • readMaxExpiresAtstring · date-timeor null
    • hasVideoTextboolean
    • videoTextRevisioninteger

      0–2,147,483,647

    • viewsintegerrequired

      Explicit guest opens, deduplicated during the viewer grant (normally 24 hours). Owner previews are excluded.

      at least 0

    • viewLimitintegeror null

      Link control (Pro, plan feature view_limit): after this many counted views the link answers like an expired one (404 SHARE_UNAVAILABLE) to everyone but the owner and viewers still holding the grant of their counted open. Media of a limited file is served only after an explicit open (POST /api/share/{id}/open), so direct media links and link cards cannot bypass the count. Null: no limit.

      1–1,000,000

    • viewLimitReachedAtstring · date-timeor null

      When the view limit was used up; null while views remain or without a limit.

    • mediaStatusstring

      New videos are processed asynchronously. Playback and previews require READY. The owner may explicitly download the original with ?download=1 while PROCESSING or FAILED; it is returned as an application/octet-stream attachment.

      values: "PROCESSING" "READY" "FAILED"

    • mediaErrorstringor null

      The reason when processing failed.

    • widthintegeror null

      Width in pixels.

    • heightintegeror null

      Height in pixels.

    • durationMsintegeror null

      Video duration in milliseconds.

    • videoCodecstringor null
    • hasAudioboolean
    • previewUrlstringor null

      Encrypted derived preview served with the same access checks as the source.

    • expiresAtstring · date-timeor null
    • createdAtstring · date-timerequired

      When it was created.

    • urlstring · urirequired

      The file page to share: {WEB_ORIGIN}/s/{id}, with ?v={accessVersion} once access changed (the page ignores the parameter; older links keep working).

    • mediaUrlstringrequired

      The address of the file itself.

    • moderationHoldstringor null

      Automatic check: review — hidden from everyone but the owner until a moderator decides; blocked — kept hidden by a moderator. Others get such a file exactly like a private one, so only the owner ever sees a non-null value.

      values: "review" "blocked"

    • favoriteboolean

      Present in list responses

    • ownedboolean

      Present in list responses

    • authorobject
      3 fields
      • idstring

        The author’s id.

      • usernamestring
      • namestring
  • 401Authentication required
  • 403SCOPE_REQUIRED, or PLAN_FEATURE_REQUIRED with params.feature (link_expiry, view_limit) when the plan in force lacks it.PLAN_FEATURE_REQUIRED
  • 404Content unavailable
  • 409Media processing, upload idempotency or paste revision conflict
  • 410Previously uploaded content was deleted or expired
  • 413Size or quota limit
  • 429Rate limit, or the account already uses all its upload slots
  • 503Upload or password verification capacity reached

Example response

200 · application/json
{
  "id": "Xq3u9RkT0bLmA7cV2pWz1eFy",
  "title": "capture",
  "tags": [
    "release"
  ],
  "originalName": "capture.png",
  "type": "IMAGE",
  "mime": "image/png",
  "pasteFormat": null,
  "pasteLanguage": null,
  "folderFiles": 1,
  "revision": 1,
  "accessVersion": 1,
  "size": 482133,
  "visibility": "unlisted",
  "allowDownload": true,
  "passwordProtected": false,
  "oneTime": false,
  "consumedAt": null,
  "readExpiresAt": null,
  "readMaxExpiresAt": null,
  "hasVideoText": false,
  "videoTextRevision": 0,
  "views": 3,
  "viewLimit": null,
  "viewLimitReachedAt": null,
  "mediaStatus": "READY",
  "mediaError": null,
  "width": 1920,
  "height": 1080,
  "durationMs": null,
  "videoCodec": null,
  "hasAudio": false,
  "previewUrl": null,
  "expiresAt": null,
  "createdAt": "2026-09-27T09:30:00.000Z",
  "url": "https://lac.pics/s/Xq3u9RkT0bLmA7cV2pWz1eFy",
  "mediaUrl": "/api/media/Xq3u9RkT0bLmA7cV2pWz1eFy",
  "moderationHold": null,
  "favorite": false,
  "owned": true,
  "author": {
    "id": "cmf8a1x2k0000q7lh3v9w2e4d",
    "username": "alex",
    "name": "Alex"
  }
}

Error codes

CodeStatusMessage
LINK_EXPIRY_INVALID400Pick a date and time at least 5 minutes and at most 10 years ahead.
ONE_TIME_NOT_PUBLIC400A one-time file cannot be published in the feed and profile. Choose link access or turn off the one-time link.
PLAN_FEATURE_REQUIRED403This is available in Pro.

Answers of any method with a key (an invalid or expired key, a missing permission, too many requests) are in Errors.

Update access and the link: PATCH /api/v1/content/{id} · lacuna API