Skip to content
DocsDashboard

Artifacts (artifact)

A document to read: a plan, summary, draft, notes or instructions written in markdown. Display only: the page asks for no answer.

When to use it: You give the person a document to read: a plan, a summary, a draft, notes or instructions, written in markdown. It only displays information; the person does not answer.

When not to use it: Do not use it for a short reply you can write in chat, for numbers that belong in a chart or a table, or to ask the person something: use form or a picker.

Gather first:

  • The finished text. The page shows exactly what you send, so write it in full first.

Writing good content:

  • Put the takeaway in title and start the document with what matters most; the page title is already the main heading, so use ## for sections.
  • Prefer short sections, lists and small tables over long paragraphs: the person reads it on a phone.
  • Links must start with https:// or mailto:. There are no images and no HTML.
  • It is display-only: if the person should reply, ask in chat after you send the link.

Display-only: the page shows information and has no Submit button. It accepts no answer, so no result ever comes back.

Fields

Every page also has version (always 1), title, and optionally description, branding, cover (a header photo) and expiresAt; see Page fields. These are the fields of page (the page type and its data):

FieldDescription
markdownstring, required. The document, in markdown (GitHub-flavored), up to 20,000 characters: headings, paragraphs, lists, tables, code blocks, quotes, bold, emphasis and links. Only https:// and mailto: links work; any other link shows as its text. No images, and HTML shows as plain text. Limits: 1-20000 characters.

Why these are required: The document itself, in GitHub-flavored markdown (headings, lists, tables, code, quotes, bold, emphasis and links; only https and mailto links are followed; no images, and HTML shows as text). Display-only: no answer.

When optional fields are left out: Only markdown, up to 20,000 characters. Headings nest under the page title (the top level becomes a section heading); a link that is not https or mailto shows as its text. The link preview lists its section headings, or its first line of text.

Minimal example

Only the required fields:

{
  "version": 1,
  "title": "Packing list",
  "page": {
    "type": "artifact",
    "markdown": "- Passport\n- Charger\n- Rain jacket"
  }
}

Full example

{
  "version": 1,
  "title": "Your Lisbon weekend plan",
  "description": "Draft from our chat. Tell me in chat what to change.",
  "branding": {
    "name": "Wayfarer",
    "accentColor": "#1f5f8b"
  },
  "page": {
    "type": "artifact",
    "markdown": "## Friday\n\nLand at **10:40**, then take the metro (red line) to *Saldanha* and change to the yellow line for the hotel.\n\n1. Check in at Casa do Largo from 15:00\n2. Sunset at Miradouro da Senhora do Monte\n3. Dinner at 20:30 near Alfama\n\n## Saturday\n\n| Time | Plan | Cost |\n|---|---|---|\n| 09:30 | Tram 28 to Graça | €3 |\n| 11:00 | Tile museum | €8 |\n| 14:00 | Belém and pastéis | €12 |\n\n> Tram 28 fills up after 10:00. Board at Martim Moniz to get a seat.\n\n## Booking references\n\nHotel confirmation: `CDL-48213`. Full details on the [hotel site](https://example.com/casa-do-largo)."
  }
}

Send it

eve, AI SDK and MCP

With @pagesystems/eve, @pagesystems/ai-sdk or the MCP server, the model calls get_page_type_schema with "artifact" (the same JSON as GET /v1/page-types/artifact), then create_page with this input (no version or branding; branding comes from your dashboard):

{
  "title": "Your Lisbon weekend plan",
  "description": "Draft from our chat. Tell me in chat what to change.",
  "page": {
    "type": "artifact",
    "markdown": "## Friday\n\nLand at **10:40**, then take the metro (red line) to *Saldanha* and change to the yellow line for the hotel.\n\n1. Check in at Casa do Largo from 15:00\n2. Sunset at Miradouro da Senhora do Monte\n3. Dinner at 20:30 near Alfama\n\n## Saturday\n\n| Time | Plan | Cost |\n|---|---|---|\n| 09:30 | Tram 28 to Graça | €3 |\n| 11:00 | Tile museum | €8 |\n| 14:00 | Belém and pastéis | €12 |\n\n> Tram 28 fills up after 10:00. Board at Martim Moniz to get a seat.\n\n## Booking references\n\nHotel confirmation: `CDL-48213`. Full details on the [hotel site](https://example.com/casa-do-largo)."
  }
}

REST

curl https://pagesystems.ai/v1/pages \
  -H "Authorization: Bearer $PAGE_SYSTEMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"spec":{"version":1,"title":"Your Lisbon weekend plan","description":"Draft from our chat. Tell me in chat what to change.","branding":{"name":"Wayfarer","accentColor":"#1f5f8b"},"page":{"type":"artifact","markdown":"## Friday\n\nLand at **10:40**, then take the metro (red line) to *Saldanha* and change to the yellow line for the hotel.\n\n1. Check in at Casa do Largo from 15:00\n2. Sunset at Miradouro da Senhora do Monte\n3. Dinner at 20:30 near Alfama\n\n## Saturday\n\n| Time | Plan | Cost |\n|---|---|---|\n| 09:30 | Tram 28 to Graça | €3 |\n| 11:00 | Tile museum | €8 |\n| 14:00 | Belém and pastéis | €12 |\n\n> Tram 28 fills up after 10:00. Board at Martim Moniz to get a seat.\n\n## Booking references\n\nHotel confirmation: `CDL-48213`. Full details on the [hotel site](https://example.com/casa-do-largo)."}}}'

Validation errors

A spec that does not validate is refused with 400 invalid_spec. The message names each problem and its path, so a model can fix the spec and try again. For example:

Leaving out the required field markdown:

✖ Invalid input: expected string, received undefined
  → at page.markdown

Misspelling a field name (unknown keys are rejected):

✖ Unrecognized key: "colour"
  → at page