10xDotIn Product Docs

Deploy Agentic Pages as an External Developer

A copy-paste deployment guide for external developers creating 10x-hosted agentic pages with page context, public-agent KB, streaming chat, and generated lead UI.

Deploy Agentic Pages as an External Developer

Use this guide when you are building an agentic page for a handle you manage, a client handle, or an automation that publishes 10x pages.

An Agentic Page deployment is not a separate JavaScript app or AWS deployment. You deploy handle-owned page content, safe widget configuration, and public-agent knowledge into 10x. The 10x page shell injects the platform widget and the anonymous visitor runtime when the handle is eligible.

What you deploy

LayerWho owns itWhat you configure
Public pageYour handletitle, description, template, content, teaser, accessMode, and publish state
Public-agent KBYour handlePublic documents tagged with containerTags: ["public-page-agent"]
Widget configurationYour handle or pageVariant, theme tokens, copy, starter chips, safe behavior flags, and authenticated rich slots
Visitor runtime10x platformAnonymous agentic-question, agentic-chat, widget asset, generation, retrieval, and lead submission

The normal deployment boundary is:

external developer publishes page and KB -> 10x shell injects widget -> visitor asks anonymous public routes

Do not ask visitors to provide JWTs or PATs. Tokens are setup credentials only.

Prerequisites

  • A 10x handle, for example acme.
  • Page publishing access on the handle.
  • Public-agent availability enabled for the handle by plan entitlement, environment switch, or operator allowlist.
  • A creator/operator JWT for full setup.
  • Optional PAT with pages.write for page-only automation.
  • Public knowledge documents that do not contain secrets, private paid content, customer PII, internal runbooks, signed URLs, or unpublished claims.

Endpoint map

Setup with JWT

Use JWT when you need the complete bootstrap, including public-agent KB documents.

JobMethod and pathAuthSuccess
Create pagePOST /v2/handles/{handle}/pagesJWT, CREATOR+201
Update pagePUT /v2/handles/{handle}/pages/{pageSlug}JWT, CREATOR+200
Publish pagePOST /v2/handles/{handle}/pages/{pageSlug}/publishJWT, CREATOR+200
Create KB documentPOST /v2/handles/{handle}/knowledge/documentsJWT, OPERATOR+201
Query KBPOST /v2/handles/{handle}/knowledge/queryJWT, handle access200

Page automation with PAT

Use PAT when an external integration or MCP workflow should manage page content without a browser session.

JobMethod and pathRequired PAT scopeSuccess
List pagesGET /v2/public/handles/{handle}/pagespages.read200
Create pagePOST /v2/public/handles/{handle}/pagespages.write201
Update pagePUT /v2/public/handles/{handle}/pages/{pageSlug}pages.write200
Publish pagePOST /v2/public/handles/{handle}/pages/{pageSlug}/publishpages.write200
Preview page contentGET /v2/public/handles/{handle}/pages/{pageSlug}/previewpages.read200
Delete pageDELETE /v2/public/handles/{handle}/pages/{pageSlug}pages.write200

PAT page routes do not create public-agent KB documents. For KB seeding, use the JWT knowledge route or an approved MCP/automation flow that has knowledge.write.

Visitor runtime

These routes are anonymous. They are called by the widget or by public validation scripts.

JobMethod and pathAuthSuccess
JSON answer smoke testPOST /v2/public/pages/{handle}/{pageSlug}/agentic-questionNone200 JSON
Streaming widget runtimePOST /v2/public/pages/{handle}/{pageSlug}/agentic-chatNone200 text/event-stream
Lead submissionPOST /v2/public/handles/{handle}/leadsNone200 or 201 style success payload

Configure your shell variables

export API_BASE="https://ai.10x.in"
export HANDLE="acme"
export PAGE_SLUG="launch-agent"
export PUBLIC_PAGE_URL="https://${HANDLE}.10x.in/${PAGE_SLUG}"
export JWT_TOKEN="<creator-or-operator-jwt>"

For JWT setup calls:

export AUTH_HEADER="Authorization: Bearer ${JWT_TOKEN}"
export PAGES_BASE="${API_BASE}/v2/handles/${HANDLE}/pages"

For PAT page automation:

export PAT_TOKEN="patv1_<tokenId>.<secret>"
export AUTH_HEADER="Authorization: Bearer ${PAT_TOKEN}"
export PAGES_BASE="${API_BASE}/v2/public/handles/${HANDLE}/pages"

Use the JWT AUTH_HEADER for the KB steps unless your integration has a separate approved knowledge-write automation.

1. Create the page content

Use template: "html_render" and send an HTML fragment, not a full document. The 10x shell owns <html>, <head>, <body>, meta tags, default typography, the widget config script, and /assets/public-page-agent.js.

This example uses an inline chat mount. If you omit the mount, the widget falls back to a floating Ask launcher.

curl -sS -X POST "${PAGES_BASE}" \
  -H "${AUTH_HEADER}" \
  -H "Content-Type: application/json" \
  -d '{
    "pageSlug": "'"${PAGE_SLUG}"'",
    "title": "Launch Agent",
    "description": "Ask questions about launch support, onboarding, proof, pricing boundaries, and implementation handoff.",
    "template": "html_render",
    "accessMode": "PUBLIC",
    "status": "DRAFT",
    "content": "<main class=\"agentic-page\"><section><p>Implementation support</p><h1>Launch Agent</h1><p>Get onboarding checklists, launch templates, implementation support, proof points, and handoff guidance from a public assistant.</p><a href=\"#agent\">Ask the launch guide</a></section><section><h2>What this page can answer</h2><ul><li>What launch support includes.</li><li>What details are useful for follow-up.</li><li>Which claims are public and approved.</li></ul></section><section id=\"agent\"><h2>Ask the launch guide</h2><div id=\"tenx-public-page-agent-inline\" data-tenx-agent-variant=\"sales\" data-tenx-agent-launcher-label=\"Ask launch\" data-tenx-agent-default-open=\"true\"></div></section></main>"
  }'

Expected response:

{
  "page": {
    "handle": "acme",
    "pageSlug": "launch-agent",
    "title": "Launch Agent",
    "template": "html_render",
    "accessMode": "PUBLIC",
    "status": "DRAFT",
    "version": 1
  }
}

Common create errors:

StatusErrorFix
400invalid_payloadInclude title and non-empty content.
403insufficient_roleUse a creator/operator JWT or PAT with pages.write; paid pages require owner access.
403feature_lockedPages require the appropriate plan tier.
409page_existsUse PUT /pages/{pageSlug} to update instead.
409slug_conflictPick a page slug that is not already used by a short link.

2. Publish the page

curl -sS -X POST "${PAGES_BASE}/${PAGE_SLUG}/publish" \
  -H "${AUTH_HEADER}"

Expected response:

{
  "ok": true,
  "pageSlug": "launch-agent",
  "publishedAt": "2026-06-16T04:30:00.000Z"
}

After publish, the visitor URL is:

https://{handle}.10x.in/{pageSlug}

Custom domains use the same path shape:

https://pages.example.com/{pageSlug}

3. Add public-agent knowledge

Agentic Pages retrieve handle KB documents only when they carry the exact public-agent container tag.

["public-page-agent"]

Create small, single-purpose public documents. Use one document for offer facts, one for pricing boundaries, one for support/handoff policy, and one for refusal rules.

curl -sS -X POST "${API_BASE}/v2/handles/${HANDLE}/knowledge/documents" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Launch support policy",
    "topic": "agentic-pages",
    "source": "external-developer-deployment",
    "contentType": "text/plain",
    "containerTags": ["public-page-agent"],
    "content": "Launch support includes onboarding checklists, implementation templates, proof review, and a two-business-day handoff window. Do not quote private pricing. For blocked launches, ask the visitor to submit the generated follow-up form."
  }'

Expected response:

{
  "documentId": "kdoc_abc123",
  "title": "Launch support policy",
  "topic": "agentic-pages",
  "source": "external-developer-deployment",
  "contentType": "text/plain",
  "containerTags": ["public-page-agent"],
  "status": "INDEXED",
  "createdAt": "2026-06-16T04:30:00.000Z",
  "updatedAt": "2026-06-16T04:30:00.000Z"
}

Validate retrieval before sending traffic:

curl -sS -X POST "${API_BASE}/v2/handles/${HANDLE}/knowledge/query" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What launch support is included?",
    "limit": 4,
    "containerTags": ["public-page-agent"]
  }'

Expected response fields:

{
  "query": "What launch support is included?",
  "containerTags": ["public-page-agent"],
  "count": 1,
  "retrievalMode": "vector",
  "backend": "aurora_pgvector",
  "results": [
    {
      "title": "Launch support policy",
      "content": "Launch support includes onboarding checklists..."
    }
  ]
}

If the query returns zero results, do not proceed to public validation. Fix the tag, content, or indexing state first.

4. Verify the page shell injects the widget

Fetch the public page and check for both the JSON config script and widget asset.

curl -sS "${PUBLIC_PAGE_URL}" | grep -E "tenx-public-page-agent-config|/assets/public-page-agent.js"

Expected markers:


If the markers are missing:

  • Confirm the page is PUBLISHED.
  • Confirm the handle is public-agent eligible.
  • Confirm the public page is rendered through the 10x page shell, not a copied static HTML file.
  • Confirm you are testing the handle host or the configured custom domain, not only the API host.

5. Smoke test the JSON answer route

Use agentic-question for simple API validation and non-widget integrations.

curl -sS -X POST "${API_BASE}/v2/public/pages/${HANDLE}/${PAGE_SLUG}/agentic-question" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "What launch support is included?"
  }'

Expected response shape:

{
  "answerMarkdown": "Launch support includes onboarding checklists, implementation templates, proof review, and a two-business-day handoff window.",
  "evidenceCards": [
    {
      "title": "Launch support policy",
      "snippet": "Launch support includes onboarding checklists...",
      "sourceType": "kb_doc",
      "sourceUrl": null
    }
  ],
  "ctaCards": [
    {
      "label": "Open page",
      "actionType": "link",
      "href": "https://acme.10x.in/launch-agent"
    }
  ],
  "followUps": [
    "What is included?",
    "How do I get started?",
    "What happens next?"
  ],
  "degraded": false,
  "retrievalMode": "page+related_pages+vector",
  "modelId": "anthropic.claude-haiku-4-5-20251001-v1:0"
}

Request errors:

StatusErrorFix
400invalid_jsonSend valid JSON.
400question_requiredSend a non-empty question.
400question_too_longKeep the latest visitor question at or below 500 characters.
404not_foundCheck handle eligibility, page publish state, handle status, and page slug. The response intentionally does not reveal which gate failed.

6. Smoke test the streaming widget route

Use agentic-chat for the embedded widget and generated UI.

curl -i -N -X POST "${API_BASE}/v2/public/pages/${HANDLE}/${PAGE_SLUG}/agentic-chat" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "parts": [
          { "type": "text", "text": "What support is included, and what should I share for follow-up?" }
        ]
      }
    ]
  }'

Expected headers:

HTTP/2 200
content-type: text/event-stream; charset=utf-8
cache-control: no-store
x-accel-buffering: no

Expected stream content includes text deltas plus a lead tool part:

tool-renderLeadQualificationSection

The generated lead UI has two containment layers:

LayerRendered bySafety rule
Native workspaceReact widgetRenders dynamicView, chips, evidence, and card UI.
Generated form HTMLSandboxed iframeOnly form HTML; no scripts, external assets, inline styles, images, or iframes.

The iframe uses:

<iframe sandbox="allow-forms allow-scripts"></iframe>

The parent widget submits generated leads with credentials: "omit" to:

POST /v2/public/handles/{handle}/leads

Streaming failure behavior:

StatusBodyMeaning
400messages_requiredBody must include a messages array.
400question_requiredThe latest user message did not contain text.
400question_too_longLatest user text is over 500 characters.
404not_foundHandle/page unavailable or not eligible.
200 SSEevent: error and {"error":"chat_unavailable"}Model streaming failed after configured fallback attempts.

7. Configure the widget safely

For normal 10x-rendered pages, the platform injects the widget. You only add an inline mount when you want the chat embedded in the page body.

<div id="tenx-public-page-agent-inline"></div>

Safe public embed overrides can be placed on that mount:

<div
  id="tenx-public-page-agent-inline"
  data-tenx-agent-variant="course"
  data-tenx-agent-accent-color="#0b6b3a"
  data-tenx-agent-launcher-label="Ask the guide"
  data-tenx-agent-default-open="true"></div>

Supported variants:

  • minimal
  • coach
  • sales
  • course
  • support

Authenticated owner configuration can also define richer copy, starter chips, behavior flags, and rich slots:

  • header
  • emptyState
  • leadIntro
  • success

Rich slot HTML is sanitized and rendered inside the widget Shadow DOM. Rich slot CSS is also sanitized; selectors must start with .tenx-agent-slot, and only safe presentation properties such as color, background-color, border-color, border-radius, font-weight, line-height, margin, padding, and text-align are accepted.

Public embed overrides cannot provide rich HTML, arbitrary CSS, endpoint paths, model settings, sandbox flags, or prompt settings.

8. Optional PAT-only page deployment

Use this when a CI job or external service is responsible only for page content.

export PAT_TOKEN="patv1_<tokenId>.<secret>"
export AUTH_HEADER="Authorization: Bearer ${PAT_TOKEN}"
export PAGES_BASE="${API_BASE}/v2/public/handles/${HANDLE}/pages"

Create or update the page through the same payloads:

curl -sS -X PUT "${PAGES_BASE}/${PAGE_SLUG}" \
  -H "${AUTH_HEADER}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Launch Agent",
    "description": "Updated external deployment page.",
    "template": "html_render",
    "accessMode": "PUBLIC",
    "status": "DRAFT",
    "content": "<main><h1>Launch Agent</h1><p>Updated public launch support context.</p><div id=\"tenx-public-page-agent-inline\"></div></main>"
  }'

Publish with the PAT:

curl -sS -X POST "${PAGES_BASE}/${PAGE_SLUG}/publish" \
  -H "${AUTH_HEADER}"

Then switch back to JWT for public-agent KB creation:

export AUTH_HEADER="Authorization: Bearer ${JWT_TOKEN}"

PAT-only deployment is acceptable only when the required public-agent KB already exists or is managed by another approved process.

9. Validate end to end

Before sharing the URL, run every check in this table.

CheckCommand or observationExpected result
Page loadscurl -I "${PUBLIC_PAGE_URL}"200 or expected CDN success
Shell config existsgrep tenx-public-page-agent-configConfig script is present
Widget asset existsgrep /assets/public-page-agent.jsAsset script is present
KB retrieval worksPOST /knowledge/query with containerTagsAt least one relevant result
JSON answer worksPOST /agentic-question200, answerMarkdown, evidence
Streaming worksPOST /agentic-chat200 text/event-stream
Lead UI streamsInspect stream/UItool-renderLeadQualificationSection appears
Lead form is sandboxedBrowser dev toolsForm HTML is inside the sandboxed iframe
Secret refusal worksAsk for a private markerNo private marker appears
Length cap worksSend 501 chars400 question_too_long
Disabled handle safety worksTest a disabled fixture if availableNon-leaky 404
Paid-page safety worksTest paid fixture if applicableTeaser-safe answer only

Troubleshooting

SymptomLikely causeFix
POST /agentic-question returns 404 not_foundHandle is disabled, handle is inactive, page is unpublished, slug is wrong, or plan entitlement is missing.Check publish state and ask the operator to confirm public-agent eligibility.
Page loads but no widget markers appearShell did not inject public-agent config.Confirm the page is rendered by the 10x shell and the handle is eligible.
Widget appears but answers ignore KBMissing or wrong containerTags.Query /knowledge/query with containerTags: ["public-page-agent"] and fix documents until results appear.
Streaming route returns SSE chat_unavailablePrimary and fallback models failed or stream validation failed.Retry later, check public-page-agent model alarms/logs, and use agentic-question as a basic route smoke test.
Generated lead form is too genericKB steering is too broad.Add a short public-agent KB document describing exactly which fields and disclosure to use.
Browser lead submission failsOrigin or page host is not accepted, or the widget was copied outside the 10x shell.Test from the handle host/custom domain, not file:// or an unrelated domain.
PAT call works for pages but KB creation failsPAT page routes do not create KB documents.Use a creator/operator JWT or an approved knowledge-write automation for KB seeding.

Deployment checklist

  • Page content is an HTML fragment, not a full document.
  • Inline mount is present when the chat should be embedded.
  • Public-agent KB documents are public-safe and tagged with ["public-page-agent"].
  • Page is published and visible on the handle host or custom domain.
  • Anonymous agentic-question and agentic-chat routes pass validation.
  • Generated lead UI renders through the widget and iframe, not host-page HTML injection.
  • Visitor lead disclosure mentions that page, question, answer, evidence titles, and retrieval mode are included with the lead.
  • Paid pages use teaser-safe content only.
  • JWT/PAT credentials are kept server-side and never exposed to visitors.

Updated Jun 19, 2026