Skip to content

Publish, connect and receive leads

Publish reviewed pages, connect a domain, and send form responses to your tools.

Publish a single checked page

Publishing makes content public. Use it when the user has asked to publish the reviewed version. The server requires a terminal source version (ready or historical needs_review), exact source and asset integrity, publication authority and hosting capacity. quality.pass describes visual quality and does not block publication. Failed or cancelled jobs without a final result cannot be published.

page_publish · MCP / client input

{
  "params": {
    "id": "11111111-1111-4111-8111-111111111111"
  },
  "body": {
    "expectedContentHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  }
}

hosting_get · MCP / client input

{
  "params": {
    "pageId": "44444444-4444-4444-8444-444444444444"
  }
}

page_unpublish binds the currently published generation id. It stops serving while preserving source history and the inbox. API callers can request autoPublish:true when starting a page or site task if they have pages:publish scope. Studio requests automatic publication of final versions. Otherwise use the explicit publication command.

Publish all site pages together

  1. Read site_release_options with the intended homepageGenerationId. It returns the approved binding and compatible checked versions for every page. An empty versions array means that page has no final version compatible with the current site scope.
  2. Review one version for every required route. Call site_release_create with the exact binding and pages [{pageId,generationId,contentHash}], plus a new key. Never derive brandHash yourself.
  3. Read the saved manifest with site_release_get. site_release_download returns its immutable ZIP, exact local assets and font licenses. Packaging is free of generation and does not publish.
  4. Read site_publication_get, then site_publish with expectedVersion and the reviewed releaseId. The complete route tree changes together.
  5. For rollback, choose an existing compatible immutable release and publish it against the current publication version. For unpublish, use releaseId:null. A 409 requires rereading and reviewing current state.

site_release_options · MCP / client input

{
  "params": {
    "id": "11111111-1111-4111-8111-111111111111"
  },
  "query": {
    "homepageGenerationId": "22222222-2222-4222-8222-222222222222"
  }
}

site_publish · MCP / client input

{
  "params": {
    "id": "11111111-1111-4111-8111-111111111111"
  },
  "body": {
    "expectedVersion": 0,
    "releaseId": "22222222-2222-4222-8222-222222222222"
  },
  "idempotencyKey": "example-site-publish-001"
}

List releases with site_releases and carry nextCursor into before. A selected or built blog revision becomes public only when included in the published release.

Connect a supported hostname

When domain_connect is listed, attach the exact requested subdomain to the homepage pageId. Follow the returned DNS instructions at your DNS provider, then use domain_check until ownership/certificate status is ready. Waveform does not change your DNS records or imply that an unpublished page is live. Domain operations require domains:manage and available plan capacity. An API key or OAuth credential can authorize them.

domain_connect · MCP / client input

{
  "params": {
    "pageId": "44444444-4444-4444-8444-444444444444"
  },
  "body": {
    "hostname": "pages.example.com"
  }
}

domain_connect is not advertised as keyed/idempotent. On an uncertain response, read hosting_get and reconcile the existing hostname before retrying. domain_disconnect removes that hostname; it does not erase the page or release.

Connect and test a form

When form operations are listed, read forms_list first. Create an inbox-only standalone form, or bind nativeFormId and nativeSourceHash to the exact source and field names reviewed on the generated page. A standalone form does not connect an existing generated form automatically. A webhook URL/secret belongs in the private form configuration, never in page JavaScript.

form_create · MCP / client input

{
  "params": {
    "pageId": "44444444-4444-4444-8444-444444444444"
  },
  "body": {
    "name": "Repair inquiry",
    "fields": [
      {
        "name": "email",
        "label": "Email",
        "type": "email",
        "required": true
      }
    ],
    "webhook": null
  }
}

Save the returned form id. For a standalone embed, read hosting_get and construct its public URL as formOrigin + /_forms/ + pageId + / + form.id; use it as an iframe src with a useful title on your separately hosted website. Waveform-generated source does not admit iframes; use the native connection on Waveform hosting. Do not attach a Bearer header or key to this public URL. It accepts responses only while the page is published and hosting is serving. For a native connection, copy the existing form id or data-node-id attribute into nativeFormId, use the terminal quality.contentHash as nativeSourceHash, and match every supported field name/type/constraint from that source. A form with neither attribute can use waveform:auto:N, where N is its zero-based position in the exact source document’s form collection; any collision with an explicit id or data-node-id is rejected. A complete radio group is represented by one select field with the same name and all distinct radio values as options. Disabled, mixed or ambiguous controls cannot be connected. Waveform hosting supplies the submission runtime when it serves that exact published source; a downloaded ZIP does not include this managed connection. Downloads can use the hosted standalone embed instead.

form_update uses expectedRevision. form_copy binds a new native source hash and exact fields. These are not automatically retried after uncertainty; reconcile through forms_list. Public receipt and external delivery are distinct. A true delivery test sends data to the configured destination and needs explicit authorization.

form_test · MCP / client input

{
  "params": {
    "pageId": "44444444-4444-4444-8444-444444444444",
    "formId": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "deliverToDestination": false
  },
  "idempotencyKey": "example-form-test-001"
}

leads_list · MCP / client input

{
  "params": {
    "pageId": "44444444-4444-4444-8444-444444444444",
    "formId": "22222222-2222-4222-8222-222222222222"
  }
}

Page through leads with the last lead id as before. Inspect delivery state/history; delivered records the destination acknowledgement, not every downstream automation. lead_retry explicitly retries the saved delivery. Accepted leads and immutable releases survive unpublishing. Hosting grace and capacity are reported by hosting_get; do not infer continued serving from a saved publication alone.