← Receivers

media:list

media family

chatmcp

Every image and video a workspace owns, as typed rows — ONE R2 scan of `{workspace}/` filtered to the seven prefixes the reader will actually serve (media, chat, ads, products, pages, brand, courses), so generated chat images and ad creative are visible, not just hand-uploads. Carries `scanned` (how much of the page was not media), `truncated` (the budget that bit) and `nextCursor`. Each row's `url` is the one door that reads bytes.

Effect
ask
Awaits an outcome — the call returns the response below.
Caller
member
The class of authority the caller must already hold, decided from the attested context with no round trip.
Cost
free
What one call costs, so you can budget before acting.
Reversible
yes
The effect can be undone by a later call.
Idempotent
yes
Safe to retry as-is.

Send it with your agent

One click hands your coding agent a prompt that registers the substrate, reads this contract, and makes the call. Launch opens the app; the others copy the prompt.

Claude Code
Codex
Cursor
Gemini CLI
Claude Desktop
ChatGPT
curl -X POST https://one.ie/api/ask/media:list \
  -H "Authorization: Bearer $ONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"data": { "workspace": "one" }}'

The key is never in a link. npx -y @oneie/cli login writes it to ~/.config/oneie/key on your machine.

Request

Validated before dispatch — an invalid payload is refused with the fix, never half-applied.

  • workspace string optional Group slug. Omit for your own. Honoured only if you may read it.
  • kind image | video optional Omit for both. Filters the rows on this page; it does not change what is scanned.
  • prefix media | chat | ads | … optional Only assets under this top-level namespace. media = hand-uploads and library generations; chat = images/videos an agent made in a conversation; ads = creative; products/pages/courses/brand = assets filed beside the thing they illustrate.
  • limit number optional R2 objects to SCAN on this page BEFORE prefix/kind filtering — not a row count. Default 500, max 1000 (R2's own ceiling). A workspace whose bucket is mostly non-media can return few rows from a full scan; that is what `scanned` reports.
  • cursor string optional The nextCursor from the previous page.

Response

What comes back from the call.

  • ok boolean
  • workspace string The workspace actually read — always the one you asked for, because a request you may not read is refused rather than downgraded.
  • items object[]
  • total number Media rows in THIS answer, after the kind/prefix filter. NOT a pre-paging count — an R2 scan cannot know one without walking every page. A FLOOR whenever `truncated` is present: say 'at least N'.
  • scanned number Objects R2 listed on this page BEFORE filtering. `scanned` far above `total` means most of the page was not media — follow the cursor rather than concluding the workspace is empty.
  • byPrefix object What each namespace contributed to THIS page — never a workspace total.
  • prefixes string[] Every prefix this door will ever return, so a caller can offer the filter without hardcoding the list.
  • truncated object ABSENT IS NOT FALSE — a complete answer carries no such key. Present = R2 reported more objects under this workspace, `total` is a floor, and you must say so before planning on it.
  • nextCursor string Present iff `truncated` is. Follow it or you have not seen the bucket.
  • error string

Traffic

Every call to media:list, counted where it is dispatched — over HTTP or in-process alike. Aggregate only — no actor, no payload, no workspace.

Counting…

Wiring

Every place in the open source that names media:list, and the file that answers it. Read from the tree at build time — a receiver is reached by NAME through one door, so there is no import edge to follow and a grep is the honest shape of the question. Structure, not volume — the count is in Traffic above.

Called from

CLI 1
  • packages/cli/src/media.ts:188
SDK 3
  • packages/sdk/src/client.ts:927
  • packages/sdk/src/index.ts:53
  • packages/sdk/src/media.ts:3

Answered by

media:list one.ie/web/src/lib/resolvers/media.ts:190 Dispatched through POST /api/ask/media:list, after the envelope validates the payload.

media family · 2 more

JSON Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "workspace": {
      "description": "Group slug. Omit for your own. Honoured only if you may read it.",
      "type": "string"
    },
    "kind": {
      "description": "Omit for both. Filters the rows on this page; it does not change what is scanned.",
      "type": "string",
      "enum": [
        "image",
        "video"
      ]
    },
    "prefix": {
      "description": "Only assets under this top-level namespace. media = hand-uploads and library generations; chat = images/videos an agent made in a conversation; ads = creative; products/pages/courses/brand = assets filed beside the thing they illustrate.",
      "type": "string",
      "enum": [
        "media",
        "chat",
        "ads",
        "products",
        "pages",
        "brand",
        "courses"
      ]
    },
    "limit": {
      "description": "R2 objects to SCAN on this page BEFORE prefix/kind filtering — not a row count. Default 500, max 1000 (R2's own ceiling). A workspace whose bucket is mostly non-media can return few rows from a full scan; that is what `scanned` reports.",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    },
    "cursor": {
      "description": "The nextCursor from the previous page.",
      "type": "string"
    }
  }
}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "workspace": {
      "description": "The workspace actually read — always the one you asked for, because a request you may not read is refused rather than downgraded.",
      "type": "string"
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "The R2 object key, `{workspace}/{prefix}/…` — the handle every other media receiver takes."
          },
          "url": {
            "type": "string",
            "description": "`/api/product-image/{workspace}/{path}` — THE reader. Range-forwarding, prefix-allowlisted, refuses SVG by stored contentType."
          },
          "kind": {
            "type": "string",
            "enum": [
              "image",
              "video"
            ]
          },
          "prefix": {
            "type": "string",
            "description": "Top-level namespace, no trailing slash."
          },
          "contentType": {
            "type": "string"
          },
          "size": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Bytes, or null when R2 did not report it."
          },
          "uploaded": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "ISO time, or null."
          }
        },
        "required": [
          "key",
          "url",
          "kind",
          "prefix",
          "contentType",
          "size",
          "uploaded"
        ]
      }
    },
    "total": {
      "description": "Media rows in THIS answer, after the kind/prefix filter. NOT a pre-paging count — an R2 scan cannot know one without walking every page. A FLOOR whenever `truncated` is present: say 'at least N'.",
      "type": "number"
    },
    "scanned": {
      "description": "Objects R2 listed on this page BEFORE filtering. `scanned` far above `total` means most of the page was not media — follow the cursor rather than concluding the workspace is empty.",
      "type": "number"
    },
    "byPrefix": {
      "description": "What each namespace contributed to THIS page — never a workspace total.",
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "number"
      }
    },
    "prefixes": {
      "description": "Every prefix this door will ever return, so a caller can offer the filter without hardcoding the list.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "truncated": {
      "description": "ABSENT IS NOT FALSE — a complete answer carries no such key. Present = R2 reported more objects under this workspace, `total` is a floor, and you must say so before planning on it.",
      "type": "object",
      "properties": {
        "rows": {
          "type": "number"
        },
        "scanned": {
          "type": "number"
        },
        "limit": {
          "description": "The scan budget that bit.",
          "type": "number"
        },
        "reason": {
          "type": "string"
        }
      }
    },
    "nextCursor": {
      "description": "Present iff `truncated` is. Follow it or you have not seen the bucket.",
      "type": "string"
    },
    "error": {
      "type": "string"
    }
  },
  "required": [
    "ok"
  ]
}