Skip to main content
A page is an ordered list of blocks. Each block carries a type, a config object whose shape is determined by type, and rendering hints (sort_order, spacing). This page documents the wire shape for every block type currently registered.
The dashboard editor is the authority for block authoring — v1 Pages is read-only. This page describes the read shape your client receives from GET /pages/{id}.

The block envelope

Every block has the same outer shape:
{
  "id": "11111111-1111-4111-8111-111111111111",
  "type": "heading",
  "config": { /* depends on type */ },
  "sort_order": 0,
  "spacing_top": 0,
  "spacing_bottom": 16
}
id
string (uuid)
required
Stable UUID for this block. Referenced from form submissions (each submitted field is keyed on its block id).
type
string
required
Block type. One of the values listed below. New types may be added without an OpenAPI version bump — treat unknown types as opaque.
config
object
required
Configuration for this block. Shape depends on type. The schema types this as unknown; see the per-type sections below for the exact shape.
sort_order
integer
required
Display order. The blocks[] array is already returned sorted by this field — use it for stable ordering across refetches.
spacing_top
integer
required
Top padding in pixels.
spacing_bottom
integer
required
Bottom padding in pixels.

Categories

CategoryTypes
Contentheading, text, image, video, divider, banner
Actionbutton, contact, file
Formform_text, form_textarea, form_email, form_phone, form_number, form_select, form_radio, form_switch, form_checkbox, form_rating, form_date, form_hidden, form_media, form_submit

Content blocks

heading

{
  "type": "heading",
  "config": {
    "text": "Welcome",
    "level": 2,
    "alignment": "center",
    "color": "#212b45"
  }
}
KeyTypeNotes
textstringHeading text. Required.
level1–6HTML heading level. Defaults to 1.
alignmentleft | center | rightDefaults to center.
colorstring (hex)Optional override. Inherits page text colour when omitted.

text

{
  "type": "text",
  "config": {
    "content": "Some rich text.",
    "alignment": "center",
    "color": "#444444"
  }
}
KeyTypeNotes
contentstringBody text. Required. Plain string (no rich-text markup).
alignmentleft | center | rightDefaults to center.
colorstring (hex)Optional override.

image

{
  "type": "image",
  "config": {
    "url": "https://files.awardee.dev/orgs/.../hero.jpg",
    "fileName": "hero.jpg",
    "linkUrl": "https://example.com"
  }
}
KeyTypeNotes
urlstringImage URL. Required. Always served from Awardee storage.
fileNamestringOriginal filename. Used as alt text on render.
linkUrlstringOptional click-through URL.

video

{
  "type": "video",
  "config": {
    "url": "https://www.youtube.com/watch?v=abc123",
    "provider": "youtube"
  }
}
KeyTypeNotes
urlstringVideo URL. Required.
providerupload | youtubeupload means a video file in Awardee storage; youtube is any YouTube watch URL. Defaults to upload.
fileNamestringOriginal filename for uploaded videos. Ignored for YouTube.

divider

{
  "type": "divider",
  "config": {
    "style": "line",
    "thickness": 1,
    "color": "#E2E7E8"
  }
}
KeyTypeNotes
styleline | dashed | spacespace renders an invisible spacer. Defaults to line.
thicknessintegerStroke thickness in px. Defaults to 1.
colorstring (hex)Stroke colour. Defaults to a neutral grey.
{
  "type": "banner",
  "config": {
    "title": "Important notice",
    "description": "Service will be unavailable Sunday 02:00–04:00 UTC.",
    "variant": "warning",
    "icon": { "prefix": "fas", "iconName": "triangle-exclamation" }
  }
}
KeyTypeNotes
titlestringBanner headline. Required.
descriptionstringOptional supporting copy.
variantinfo | success | warning | destructiveVisual tone. Defaults to info.
iconFaIconOptional. Overrides the variant’s default icon.

Action blocks

button

{
  "type": "button",
  "config": {
    "label": "Reserve a tasting",
    "icon": { "prefix": "fas", "iconName": "arrow-right" },
    "iconPosition": "end-gap",
    "destination": {
      "type": "url",
      "value": { "url": "https://example.com/book" }
    },
    "style": {
      "variant": "filled",
      "bgColor": "#212b45",
      "textColor": "#ffffff",
      "borderRadius": 24,
      "borderWidth": 1
    }
  }
}
KeyTypeNotes
labelstringButton label. Required.
iconFaIconOptional. Omit for a text-only button.
iconPositionstart | start-gap | end-gap | endWhere the icon sits relative to the label. Defaults to start.
destinationPageDestinationRequired. Where the button sends visitors.
styleobjectOptional visual overrides. See Button style.

contact

{
  "type": "contact",
  "config": {
    "name": "John Smith",
    "title": "Sales Manager",
    "company": "Awardee",
    "phone": "+61 412 345 678",
    "email": "[email protected]",
    "website": "https://example.com",
    "address": "1 Lygon St, Carlton VIC 3053",
    "avatarUrl": "https://files.awardee.dev/.../avatar.jpg"
  }
}
KeyTypeNotes
namestringRequired.
title, company, phone, email, website, address, avatarUrlstringAll optional.
Renders as a tap-to-save vCard on mobile.

file

{
  "type": "file",
  "config": {
    "url": "https://files.awardee.dev/.../specsheet.pdf",
    "fileName": "specsheet.pdf",
    "fileSizeBytes": 184320,
    "mimeType": "application/pdf",
    "label": "Download the spec sheet",
    "icon": { "prefix": "fas", "iconName": "file-pdf" },
    "color": "#212b45"
  }
}
KeyTypeNotes
urlstringFile URL. Required.
fileNamestringFilename. Required.
fileSizeBytesinteger | nullSize in bytes.
mimeTypestring | nullMIME type.
labelstringDisplay label. Defaults to filename.
iconFaIconOptional.
colorstring (hex)Accent colour for the file chip.

Form blocks

All form fields share a formBase schema and extend it with field-specific keys. The base:
KeyTypeNotes
labelstringVisible label. Empty string hides the label row.
placeholderstringOptional placeholder text.
requiredbooleanDefaults to false.
prefillParamstring | nullWhen set, auto-fills from the named URL query string param.
textColorstring (hex)Label/text colour.
The submitted value is keyed by block id in the submission’s data map — see Submissions.

form_text

{
  "type": "form_text",
  "config": {
    "label": "Your name",
    "required": true,
    "placeholder": "John Smith",
    "maxLength": 100
  }
}
Extra keys: maxLength (integer).

form_textarea

{
  "type": "form_textarea",
  "config": {
    "label": "Your message",
    "rows": 4,
    "placeholder": "Tell us a bit more…",
    "maxLength": 1000
  }
}
Extra keys: rows (integer, default 4), maxLength (integer).

form_email

{ "type": "form_email", "config": { "label": "Email", "required": true } }
Form-base only. The renderer enforces email validation.

form_phone

{ "type": "form_phone", "config": { "label": "Phone" } }
Form-base only. The renderer renders a phone-input widget.

form_number

{
  "type": "form_number",
  "config": {
    "label": "Quantity",
    "min": 1,
    "max": 100,
    "step": 1
  }
}
Extra keys: min, max, step (numbers).

form_select

{
  "type": "form_select",
  "config": {
    "label": "Choose one",
    "options": [
      { "label": "Option A", "value": "a" },
      { "label": "Option B", "value": "b" }
    ]
  }
}
Extra keys: options[] with { label, value, description? }. Always renders as a native-style dropdown — no variant.

form_radio

{
  "type": "form_radio",
  "config": {
    "label": "Pick one",
    "variant": "cards",
    "accentColor": "#212b45",
    "options": [
      { "label": "Option A", "value": "a", "description": "Best for X" },
      { "label": "Option B", "value": "b" }
    ]
  }
}
Extra keys: variant (list | cards, default cards), accentColor (hex), options[].

form_switch

Same shape as form_radio — multi-select toggle cards or list.

form_checkbox

Same shape as form_radio — multi-select with checkboxes.

form_rating

{
  "type": "form_rating",
  "config": {
    "label": "Rate this",
    "max": 5,
    "icon": "star",
    "color": "#212b45"
  }
}
KeyTypeNotes
maxinteger 1–6Number of icons. Default 5.
iconstar | emoji | heart | customBuilt-in icon set. custom uses customIcon.
customIconFaIconRequired when icon = "custom".
colorstring (hex)Selected-icon colour.

form_date

{
  "type": "form_date",
  "config": {
    "label": "When can you start?",
    "mode": "date",
    "minDate": "2026-01-01",
    "maxDate": "2026-12-31"
  }
}
KeyTypeNotes
modedate | datetime | timeDefault date.
minDate, maxDatestring (ISO 8601) | nullBounds.
relativeMax{ unit: "days" | "weeks" | "months", value: integer }Computed at render time; takes precedence over maxDate.

form_hidden

{
  "type": "form_hidden",
  "config": {
    "label": "Source",
    "value": "tabletop-qr"
  }
}
KeyTypeNotes
labelstringColumn label in the submissions table. Required.
valuestringStatic value attached to every submission.
Hidden fields are never visually rendered. Prefill-from-URL is handled by the visible field blocks; this is a pure constant.

form_media

{
  "type": "form_media",
  "config": {
    "label": "Upload",
    "title": "Upload your photo",
    "description": "JPEG, PNG, or HEIC. Up to 15 MB.",
    "icon": { "prefix": "fas", "iconName": "cloud-arrow-up" },
    "color": "#212b45",
    "allowed": { "media": true, "files": false, "any": false }
  }
}
KeyTypeNotes
titlestringTitle above the dropzone.
descriptionstringSupporting copy.
iconFaIconDropzone icon.
colorstring (hex)Accent for icon and border.
allowed{ media, files, any } (booleans)Which kinds of uploads. any wins if set.

form_submit

{
  "type": "form_submit",
  "config": {
    "label": "Submit",
    "iconPosition": "end-gap",
    "icon": { "prefix": "fas", "iconName": "paper-plane" },
    "loadingLabel": "Sending…",
    "style": {
      "variant": "filled",
      "bgColor": "#212b45",
      "textColor": "#ffffff",
      "borderRadius": 24
    },
    "redirectRules": [
      {
        "condition": {
          "blockId": "22222222-2222-4222-8222-222222222222",
          "operator": "eq",
          "value": "yes"
        },
        "destination": {
          "type": "url",
          "value": { "url": "https://example.com/yes" }
        }
      },
      {
        "condition": null,
        "destination": {
          "type": "url",
          "value": { "url": "https://example.com/thanks" }
        }
      }
    ]
  }
}
KeyTypeNotes
labelstringSubmit label. Default "Submit".
iconFaIconOptional.
iconPositionsame as buttonDefault start.
loadingLabelstringShown while the submission is in flight.
styleobjectSame shape as button.
redirectRulesarrayWhere to send the visitor after a successful submission.
Redirect rules are evaluated top-to-bottom, first match wins. The last rule should have condition: null (the fallback). Each rule:
{
  "condition": {
    "blockId": "form-block-uuid",
    "operator": "eq",
    "value": "yes"
  },
  "destination": { /* PageDestination */ }
}
Operators: eq, neq, gt, gte, lt, lte, in, not_in, contains.

Shared types

FaIcon

Font Awesome icon reference.
{ "prefix": "fas", "iconName": "arrow-right" }
  • prefix — FA style prefix (fas, far, fab, fad, etc.).
  • iconName — kebab-case icon name.

Button style

{
  "variant": "filled",
  "bgColor": "#212b45",
  "textColor": "#ffffff",
  "borderRadius": 24,
  "borderWidth": 1
}
  • variantfilled or outline.
  • bgColor, textColor — hex.
  • borderRadius — px.
  • borderWidth — px. Ignored when variant = "filled".

Page destination

The destination object used by button blocks (and form submit redirects). Discriminated on type:
Typevalue shape
url{ url }
page{ id, title, slug, publicSlug }
article{ id, title, slug, knowledgeBasePublicSlug, categoryPath }
chatbot{ id, name, slug, publicSlug }
knowledge_base{ id, name, slug, publicSlug }
file{ url, fileName, fileSizeBytes?, mimeType? }
email{ email, subject?, body? }
phone{ phone }
google_review{ placeId, businessName? }
{
  "type": "page",
  "value": {
    "id": "a1c2e4f6-8b0d-4e2a-9c1b-3d5e7f9a2c4e",
    "title": "Reservations",
    "slug": "reservations",
    "publicSlug": "reservations"
  }
}
The destination embeds enough of the target’s metadata (title, slug, etc.) so renderers can hyperlink without an extra lookup. The embedded values are a snapshot — refresh by re-reading the page if you need the latest.

Forward compatibility

New block types may be added without an OpenAPI version bump — they’re additive. Treat any unknown type as opaque and skip rendering rather than crashing. The config field is typed as unknown on the wire precisely so additions don’t break existing consumers.