REST API v1

How to call TMS File endpoints — method, path, samples, and copyable curl. Set BASE_URL to your service origin (for example http://localhost:3000).

Placeholder: $BASE_URL

  • GET/api/v1/health-checks

    Liveness check — confirms the TMS File service process is responding.

    Response

    Sample
    {
      "message": "TMS-FILE is running"
    }

    cURL

    curl
    curl -sS "$BASE_URL/api/v1/health-checks"
  • POST/api/v1/files/uploadmultipart/form-data

    Upload a single file: create metadata and write bytes using the organization's active storage binding.

    Request

    multipart/form-data fields listed below.

    Sample
    file                (binary, required)
    organization_id     (string, required)
    sub_system          (string, required)
    original_name       (string, optional — defaults to file name)
    mime_type           (string, optional)
    upload_temp         (boolean, optional — TEMP local-only file)

    Response

    Sample
    {
      "file_id": "01HZX…",
      "original_name": "sample.pdf",
      "mime_type": "application/pdf",
      "file_size": 12345,
      "ext": "pdf",
      "file_path": "1/oms/2026/09/26/…",
      "sync_status": "PENDING",
      "updated_at": "2026-09-26T10:00:00.000Z"
    }

    cURL

    curl
    curl -sS -X POST "$BASE_URL/api/v1/files/upload" \
      -F "file=@./sample.pdf" \
      -F "organization_id=1" \
      -F "sub_system=oms" \
      -F "original_name=sample.pdf" \
      -F "mime_type=application/pdf"
  • PUT/api/v1/files/uploadmultipart/form-data

    Lifecycle mutations on an existing file_id: promote TEMP → THUMBNAIL, promote to ready, or replace the binary blob.

    Request

    multipart/form-data. make_as_thumbnail and make_as_ready are mutually exclusive.

    Sample
    file_id             (string, required)
    make_as_thumbnail   (boolean — TEMP → THUMBNAIL; no binary)
    make_as_ready       (boolean — promote without or with binary)
    file                (binary — replace blob when status allows)
    original_name / mime_type  (optional with file)
    
    Flags make_as_thumbnail and make_as_ready are mutually exclusive.

    Response

    Sample
    {
      "file_id": "01HZX…",
      "sync_status": "NONE",
      "updated_at": "2026-09-26T10:05:00.000Z"
    }

    cURL

    curl
    curl -sS -X PUT "$BASE_URL/api/v1/files/upload" \
      -F "file_id=01HZX…" \
      -F "make_as_ready=true"
  • POST/api/v1/files/batchmultipart/form-data

    Batch upload (multipart items[]). All-or-nothing: insert DB rows in a transaction, then write files sequentially.

    Request

    Root fields plus indexed items[N].* parts.

    Sample
    organization_id     (string, required)
    sub_system          (string, required)
    items[N].file       (binary, required)
    items[N].original_name / mime_type  (optional)
    
    All-or-nothing: DB transaction then sequential disk writes.

    Response

    Sample
    [
      { "file_id": "…", "original_name": "a.pdf", "…": "…" },
      { "file_id": "…", "original_name": "b.png", "…": "…" }
    ]

    cURL

    curl
    curl -sS -X POST "$BASE_URL/api/v1/files/batch" \
      -F "organization_id=1" \
      -F "sub_system=oms" \
      -F "items[0].file=@./a.pdf" \
      -F "items[0].original_name=a.pdf" \
      -F "items[0].mime_type=application/pdf" \
      -F "items[1].file=@./b.png" \
      -F "items[1].original_name=b.png" \
      -F "items[1].mime_type=image/png"
  • GET/api/v1/files/{fileId}

    Read a file: LOCAL streams bytes; CLOUD redirects to a presigned URL. Use disposition=attachment to download.

    Request

    Path and optional query as below.

    Sample
    Path: fileId (ULID)
    Query: disposition=attachment (optional)

    Response

    Sample
    LOCAL  → 200 stream (file bytes)
    CLOUD  → 302 redirect to presigned URL

    cURL

    curl
    curl -sS -L -o out.bin "$BASE_URL/api/v1/files/{fileId}"
    # Download as attachment:
    curl -sS -L -o out.bin "$BASE_URL/api/v1/files/{fileId}?disposition=attachment"
  • GET/api/v1/files/{fileId}/{width}/{height}

    Square gallery variant: width must equal height and match the size whitelist. Streams WebP from variant cache or resizes on the fly.

    Request

    Path rules below. Non-square or non-whitelisted size → 400.

    Sample
    Path: fileId, width, height
    Rules: width === height; size in whitelist: 200, 250, 300, 400, 500, 700, 1000
    Outside whitelist or non-square → 400
    Always streamed via tms-file (no R2 redirect)

    Response

    Sample
    200 image/webp (cached or resized on the fly)
    Passthrough original when max edge ≤ requested size

    cURL

    curl
    curl -sS -o thumb.webp "$BASE_URL/api/v1/files/{fileId}/500/500"
  • DELETE/api/v1/files/{fileId}

    Soft purge: sets purge_status = SYSTEM_PURGE. A background job deletes storage bytes then removes the DB row.

    Request

    Path parameter only.

    Sample
    Path: fileId (ULID)

    Response

    Sample
    {
      "fileId": "01HZX…",
      "deleted": true,
      "storageLocation": "LOCAL",
      "purgePending": true
    }

    cURL

    curl
    curl -sS -X DELETE "$BASE_URL/api/v1/files/{fileId}"
  • GET/api/v1/storage-providers

    List active storage providers as { providerCode, providerName }.

    Response

    Sample
    [
      { "providerCode": "R2", "providerName": "Cloudflare R2" }
    ]

    cURL

    curl
    curl -sS "$BASE_URL/api/v1/storage-providers"
  • POST/api/v1/organization-storage-bindings/createapplication/json

    Create the organization's file storage binding (one active binding per organization).

    Request

    JSON body.

    Sample
    {
      "organizationId": 1,
      "organizationName": "Demo Org",
      "storageProvider": "R2",
      "syncEnabled": true
    }

    Response

    Sample
    {
      "id": 10,
      "organizationId": 1,
      "organizationName": "Demo Org",
      "isActive": true,
      "syncEnabled": true,
      "storageProvider": "R2",
      "effectiveFrom": "2026-09-26T10:00:00.000Z",
      "effectiveTo": null
    }

    cURL

    curl
    curl -sS -X POST "$BASE_URL/api/v1/organization-storage-bindings/create" \
      -H "Content-Type: application/json" \
      -d '{
        "organizationId": 1,
        "organizationName": "Demo Org",
        "storageProvider": "R2",
        "syncEnabled": true
      }'
  • PUT/api/v1/organization-storage-bindings/updateapplication/json

    Update the organization's active storage binding (including isActive to terminate or resume).

    Request

    JSON body.

    Sample
    {
      "organizationId": 1,
      "organizationName": "Demo Org",
      "storageProvider": "R2",
      "syncEnabled": true,
      "isActive": true
    }

    Response

    Sample
    {
      "id": 10,
      "organizationId": 1,
      "isActive": true,
      "syncEnabled": true,
      "storageProvider": "R2"
    }

    cURL

    curl
    curl -sS -X PUT "$BASE_URL/api/v1/organization-storage-bindings/update" \
      -H "Content-Type: application/json" \
      -d '{
        "organizationId": 1,
        "organizationName": "Demo Org",
        "storageProvider": "R2",
        "syncEnabled": true,
        "isActive": true
      }'