Skip to content

Upload state

GET/api/v1/uploads/resumable/{id}

Access
API key
Permission
content:write

Read confirmed parts or recover a lost completion response

Example request

curl "https://lac.pics/api/v1/uploads/resumable/2f1b9c4e-8d3a-4b7e-9c61-0a5d2e8f7b13" \
  -H "Authorization: Bearer lac_api_YOUR_KEY"

Parameters

Path

  • idstring · uuidrequired

    The file or note id.

Headers

  • X-Lacuna-Accountstring

    Optional expected account ID; mismatch fails409 before reading state or buffering bytes.

Responses

  • 200Confirmed persisted state. No unconfirmed chunk bytes contribute to progress.ResumableUpload
    • idstring · uuidrequired

      The upload id.

    • statestringrequired

      The state: UPLOADING, COMPLETING, COMPLETED, CANCELLED or EXPIRED.

      values: "UPLOADING" "COMPLETING" "COMPLETED" "CANCELLED" "EXPIRED"

    • filenamestringrequired
    • sizeinteger · int64required

      Size in bytes.

      1–4,294,967,296

    • chunkSizeintegerrequired

      The part size: 2,097,152 bytes (2 MB).

      values: 2097152

    • chunkCountintegerrequired

      1–50

    • fingerprintstringrequired

      pattern ^[a-f0-9]{64}$

    • receivedarray of integerrequired

      Numbers of the confirmed parts.

      unique

    • receivedBytesinteger · int64required

      Confirmed bytes.

      0–4,294,967,296

    • expiresAtstring · date-timerequired
    • contentContentrequiredor null
      Content 40 fields
      • 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
  • 400Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 401Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 403Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 404Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 408Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 409Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 410Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 413Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 429Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 500Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.
  • 503Typed error. Reconcile uncertain results through status; retry completion with the same key and metadata.

Example response

200 · application/json
{
  "id": "Xq3u9RkT0bLmA7cV2pWz1eFy",
  "state": "COMPLETED",
  "filename": "recording.mp4",
  "size": 4194304,
  "chunkSize": 2097152,
  "chunkCount": 2,
  "fingerprint": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
  "received": [
    0,
    1
  ],
  "receivedBytes": 4194304,
  "expiresAt": "2026-09-28T09:30:00.000Z",
  "content": {
    "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

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

Upload state: GET /api/v1/uploads/resumable/{id} · lacuna API