← Receivers

pages:build-site

pages family

Write a five-page business site — home, about, services, contact, faq — as DRAFTS from the business's own facts. Drops every proof block the facts cannot back (stats, logos, testimonials, pricing, team, badges, quotes, timelines, sample galleries), rewrites the rest with one model call per page, and cuts any sentence that invents a number, a name or a placeholder. Saves the facts as the workspace's business-facts. Idempotent by read-back: a template already built is reported created:false and left alone. Publishing is pages:publish-pack's job.

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
variable
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/pages:build-site \
  -H "Authorization: Bearer $ONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"data": { "slug": <string>, "facts": <object> }}'

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.

  • slug string required which workspace. NOT an authority claim — the caller is authorized by the attested ctx through the same callerControlsWorkspace walk every pages:* receiver uses. Absent = the caller's own workspace.
  • facts object required the candidate facts (lib/site-builder/facts.ts BusinessFactsCandidate) — the ONLY source the copy may state; an absent field is absent, never a guess
  • description string optional the visitor's own sentence about the business — extra context for the copy, and a source the number guard accepts

Response

What comes back from the call.

  • ok boolean all five pages exist (created now or already there)
  • error string
  • pages object[] one row per template, in reading order — passes straight into pages:publish-pack's `pages`
  • facts string[] the business-facts keys now saved for the workspace; empty when the facts column is not migrated
  • factsToAdd string[] labels of public facts the pages name that nobody has given — the lines they hide until the owner adds them
  • steps object[] facts, then page:<template> — a page whose copy fell back to the facts-only page says `copy_fallback:<why>`

Traffic

Every call to pages:build-site, 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 pages:build-site, 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:239
  • one.ie/web/src/lib/resolvers/site-build.ts:571
Workflow 1
  • one.ie/web/src/lib/workflow-templates.ts:324
→
JSON Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "slug": {
      "type": "string",
      "description": "which workspace. NOT an authority claim — the caller is authorized by the attested ctx through the same callerControlsWorkspace walk every pages:* receiver uses. Absent = the caller's own workspace."
    },
    "facts": {
      "type": "object",
      "properties": {
        "businessName": {
          "type": "string",
          "description": "the business's name — the one required fact; absent, the call is refused as \"missing facts\""
        },
        "whatYouSell": {
          "description": "a 2-5 word noun phrase — \"Emergency plumbing\"",
          "type": "string"
        },
        "summary": {
          "description": "two or three plain sentences on what the business does, in its own words",
          "type": "string"
        },
        "tagline": {
          "type": "string"
        },
        "founderName": {
          "description": "named on a page only when given",
          "type": "string"
        },
        "foundedYear": {
          "description": "a year the business stated; never inferred",
          "type": "number"
        },
        "phone": {
          "type": "string"
        },
        "email": {
          "type": "string"
        },
        "postalAddress": {
          "description": "withheld = no map and no Visit card, never a guessed address",
          "type": "string"
        },
        "openingHours": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "services": {
          "description": "what the business offers, as short names",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "currency": {
          "description": "ISO 4217, when the business states one",
          "type": "string"
        }
      },
      "required": [
        "businessName"
      ],
      "description": "the candidate facts (lib/site-builder/facts.ts BusinessFactsCandidate) — the ONLY source the copy may state; an absent field is absent, never a guess"
    },
    "description": {
      "description": "the visitor's own sentence about the business — extra context for the copy, and a source the number guard accepts",
      "type": "string"
    }
  },
  "required": [
    "slug",
    "facts"
  ]
}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean",
      "description": "all five pages exist (created now or already there)"
    },
    "error": {
      "type": "string"
    },
    "pages": {
      "description": "one row per template, in reading order — passes straight into pages:publish-pack's `pages`",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "template": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "created": {
            "type": "boolean"
          }
        },
        "required": [
          "template",
          "slug",
          "title",
          "created"
        ]
      }
    },
    "facts": {
      "description": "the business-facts keys now saved for the workspace; empty when the facts column is not migrated",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "factsToAdd": {
      "description": "labels of public facts the pages name that nobody has given — the lines they hide until the owner adds them",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "steps": {
      "description": "facts, then page:<template> — a page whose copy fell back to the facts-only page says `copy_fallback:<why>`",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "step": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          }
        },
        "required": [
          "step",
          "ok"
        ]
      }
    }
  },
  "required": [
    "ok"
  ]
}