ONE blocks:list
← Receivers

blocks:list

blocks family

mcp

Discover the page blocks that exist — name, category, surface, description and variant list, filterable and paged

Effect
ask
Awaits an outcome — the call returns the response below.
Caller
public
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/blocks:list \
  -H "Authorization: Bearer $ONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"data": { "category": "marketing", "limit": 20 }}'

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.

  • category string optional Exact category filter: ai · app · auth · content · data · ecommerce · email · learning · marketing · social · wallet. Read `facets.categories` for the live list.
  • surface string optional Exact surface filter: section · container · atomic · app · social-preview — how much chrome the block may carry.
  • search string optional Case-insensitive substring over name + description + category.
  • limit number optional Rows per page. Default 50, max 200.
  • cursor string optional Opaque offset from a previous response's `nextCursor`. The order is by name, so a cursor is stable.

Response

What comes back from the call.

  • ok true
  • workspace string | null The attested caller's slug, or null when anonymous. Never echoed from the request.
  • blocks object[]
  • total number Rows matching the filters BEFORE paging — exact. Tenant rows are counted in it and sort first.
  • returned number Rows in this response.
  • registryTotal number Every block in the registry, ignoring filters.
  • tenantTotal number The caller's own declared blocks matching the filters. 0 for an anonymous caller — this axis is read off the attested slug, never a body field.
  • measuredAt string When the manifest this projects was generated.
  • nextCursor string Present ⟺ more rows match. Absent means you have them all.
  • truncated object Present ⟺ rows were cut. ABSENT IS NOT FALSE — an uncut answer carries no `truncated` key.
  • stale object Present ⟺ the manifest's own header count disagrees with its contents. Regenerate with `node .claude/scripts/blocks-manifest.mjs`.
  • facets object Every value the filters accept, read off the registry — never hand-listed.

Traffic

Every call to blocks: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 blocks: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

API route 2
  • one.ie/web/src/lib/receiver-index.generated.ts:55
  • one.ie/web/src/lib/resolvers/blocks.ts:273
→

Answered by

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

blocks family · 2 more

JSON Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "category": {
      "description": "Exact category filter: ai · app · auth · content · data · ecommerce · email · learning · marketing · social · wallet. Read `facets.categories` for the live list.",
      "type": "string"
    },
    "surface": {
      "description": "Exact surface filter: section · container · atomic · app · social-preview — how much chrome the block may carry.",
      "type": "string"
    },
    "search": {
      "description": "Case-insensitive substring over name + description + category.",
      "type": "string"
    },
    "limit": {
      "description": "Rows per page. Default 50, max 200.",
      "type": "number"
    },
    "cursor": {
      "description": "Opaque offset from a previous response's `nextCursor`. The order is by name, so a cursor is stable.",
      "type": "string"
    }
  }
}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean",
      "const": true
    },
    "workspace": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The attested caller's slug, or null when anonymous. Never echoed from the request."
    },
    "blocks": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "registry",
              "tenant"
            ],
            "description": "`registry` is ONE's first-party Puck registry; `tenant` is a composition THIS workspace declared with `blocks:declare`. A tenant key can never shadow a registry name — the declare door refuses one that does."
          },
          "category": {
            "type": "string"
          },
          "surface": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "chatFit": {
            "type": "string"
          },
          "pagesUsing": {
            "type": "number",
            "description": "How many stored pages hold an instance, at the manifest's `measuredAt`. A popularity signal, not a live count — always 0 for a tenant block."
          },
          "canonicalVariant": {
            "description": "The variant that renders when none is sent. Absent on a block that is not a collapsed family, and on a tenant block.",
            "type": "string"
          },
          "variants": {
            "description": "The variant values this family accepts. Absent on a non-family block.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "composedOf": {
            "description": "TENANT ONLY — the registry components this composition expands into, in render order.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name",
          "source",
          "category",
          "surface",
          "description",
          "icon",
          "chatFit",
          "pagesUsing"
        ]
      }
    },
    "total": {
      "type": "number",
      "description": "Rows matching the filters BEFORE paging — exact. Tenant rows are counted in it and sort first."
    },
    "returned": {
      "type": "number",
      "description": "Rows in this response."
    },
    "registryTotal": {
      "type": "number",
      "description": "Every block in the registry, ignoring filters."
    },
    "tenantTotal": {
      "type": "number",
      "description": "The caller's own declared blocks matching the filters. 0 for an anonymous caller — this axis is read off the attested slug, never a body field."
    },
    "measuredAt": {
      "type": "string",
      "description": "When the manifest this projects was generated."
    },
    "nextCursor": {
      "description": "Present ⟺ more rows match. Absent means you have them all.",
      "type": "string"
    },
    "truncated": {
      "description": "Present ⟺ rows were cut. ABSENT IS NOT FALSE — an uncut answer carries no `truncated` key.",
      "type": "object",
      "properties": {
        "rows": {
          "type": "number",
          "description": "How many matching rows are NOT in this response."
        },
        "limit": {
          "type": "number",
          "description": "The budget that bit."
        },
        "reason": {
          "type": "string",
          "const": "page"
        }
      },
      "required": [
        "rows",
        "limit",
        "reason"
      ]
    },
    "stale": {
      "description": "Present ⟺ the manifest's own header count disagrees with its contents. Regenerate with `node .claude/scripts/blocks-manifest.mjs`.",
      "type": "object",
      "properties": {
        "declared": {
          "type": "number"
        },
        "actual": {
          "type": "number"
        }
      },
      "required": [
        "declared",
        "actual"
      ]
    },
    "facets": {
      "type": "object",
      "properties": {
        "categories": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "surfaces": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "categories",
        "surfaces"
      ],
      "description": "Every value the filters accept, read off the registry — never hand-listed."
    }
  },
  "required": [
    "ok",
    "workspace",
    "blocks",
    "total",
    "returned",
    "registryTotal",
    "tenantTotal",
    "measuredAt",
    "facets"
  ]
}