---
title: "List blobs"
method: GET
path: "/storage/v1/blobs"
tags: ["Storage"]
---

# List blobs

`GET /storage/v1/blobs`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/storage/v1/blobs`
- Auth: API key in header `apikey`

List blobs in the project. Requires the apikey header to carry a project service_key or project_admin JWT.

## Query parameters

- `prefix` string
- `limit` integer
- `cursor` string
- `sort` 'key:asc' | 'createdAt:asc' | 'createdAt:desc'
- `filter_uploaded_by` string
- `filter_tag` string
- `filter_format` string
- `filter_is_image` boolean
- `filter_min_width` integer
- `filter_max_width` integer
- `filter_min_height` integer
- `filter_max_height` integer

## Response `200`

{ blobs: [...], next_cursor }

- BlobListResponse
  - `blobs` BlobObject[], required
    - `key` string, required
    - `size_bytes` integer, required
    - `sha256` string, required
    - `content_type` string, nullable
    - `visibility` 'public' | 'private', required
    - `immutable_suffix` string, nullable
    - `etag` string
    - `url` string, uri, nullable
    - `immutable_url` string, uri, nullable
    - `cdn_url` string, uri, nullable
    - `cdn_immutable_url` string, uri, nullable
    - `created_at` string, date-time
    - `updated_at` string, date-time
    - `width_px` integer, nullable: v1.49 — display-oriented width in pixels (post-EXIF rotate). Null for non-images and pre-v1.49 uploads.
    - `height_px` integer, nullable: v1.49 — display-oriented height in pixels (post-EXIF rotate). Null for non-images and pre-v1.49 uploads.
    - `blurhash` string, nullable: v1.49 — ~30-byte LQIP placeholder. Decode client-side via the `blurhash` npm package.
    - `metadata` object, nullable: v1.50 — caller-provided per-key metadata. Flat object; values must be string/number/boolean/string[]. Serialized size ≤ 4 KB. Last-write-wins on re-upload; omitting `metadata` on a subsequent put clears any prior value. Null when no metadata was supplied.
    - `image_format` 'jpeg' | 'png' | 'webp' | 'avif' | 'tiff' | 'svg' | 'bmp' | 'heic' | 'null', nullable: v1.50 — bare image format detected from magic numbers (NOT from declared content_type). Null for non-images. Indexed for `filter_format=` queries.
    - `image_info` object, nullable: v1.50 — descriptive image-intrinsic fields: `has_alpha`, `color_space`, `animated`, `frame_count`, `bit_depth`, `orientation`. All optional; sharp only populates fields the source format carries. Null for non-images.
    - `image_exif` object, nullable: v1.50 — extracted EXIF tags with snake_case keys, filtered per `image_exif_policy`. Under `keep`: full EXIF object. Under `strip`: only the allowlist (camera_make / camera_model / lens_model / exposure_time / f_number / iso / focal_length / datetime_*). Null when no EXIF or all tags dropped under strip. ORIGINAL CAS bytes are never mutated — apps that need full EXIF can parse the served bytes themselves.
    - `image_exif_policy` 'keep' | 'strip' | 'null', nullable: v1.50 — which EXIF policy was applied at upload. Null for non-images or pre-v1.50 uploads.
    - `immutable` boolean: True when the key has a content-hashed immutable URL (`immutable_url`). The URL fields are built by the same rule as the AssetRef `assets.put` returns; public URL fields are null for private keys.
    - `variant_spec_version` string: Present for image sources with encoded variants: the variant generation the `variants` URLs belong to.
    - `display_url` string, uri, nullable: Present with `variant_spec_version`: a browser-renderable URL (the `display_jpeg` variant for HEIC sources, otherwise `url`).
    - `display_immutable_url` string, uri, nullable: Present with `variant_spec_version`: the immutable form of `display_url`.
    - `variants` object: Encoded image variants keyed by kind (`thumb`, `medium`, `large`, `display_jpeg`). Absent for non-images and images below the variant threshold.
    - `blurhash_data_url` string, nullable: Pre-decoded PNG data URL of the blurhash placeholder. Null when unset.
    - `asset_schema` 'v1.49' | 'v1.50' | 'v1.54' | 'null', nullable: Highest asset shape contract the row satisfies. Null when unset.
  - `next_cursor` string, nullable, required: Opaque cursor for the next page, under the same sort and filters; null on the last page.
  - `has_more` boolean, required: True when rows remain past this page; `next_cursor` is then set.
  - `reset` boolean, required: True when the request's `cursor` was unusable under its sort (issued for another sort, or malformed) and this response is the listing's first page instead. False otherwise.

## Other responses

- `400`: Invalid query parameter. Possible `code` values: INVALID_LIMIT, INVALID_SORT, INVALID_FILTER_KEY (lists supported keys in the message), INVALID_FILTER_VALUE.
- `403`: Requires service_role or project_admin key

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
