Skip to main content

Overview

A Page is a fully hosted search UI served at https://mxp.co/p/{slug}. Each Page combines one or more retriever-backed tabs, an optional hero section, a featured gallery, stats bar, custom theme, and SEO metadata — all managed via a single API resource. When you publish a retriever with POST /v1/retrievers/{id}/publish, a companion Page is automatically created at /p/{public_name}. You can then customize it further or create entirely new Pages from scratch.

Auto-created on publish

Publishing a retriever auto-creates a Page at /p/{public_name}. No extra step needed.

Globally unique slugs

Page slugs are unique across all organizations. Once claimed, mxp.co/p/{slug} is yours.

No-auth public access

End-users browse mxp.co/p/{slug} without any API key. Your branding, your data.

Multi-tab search

Each tab routes to a different retriever — image search, text search, video — all in one URL.

Rendering modes

Pages support three rendering modes, evaluated in priority order:
PriorityModeWhen to use
1custom_htmlFull control — embed raw HTML/CSS/JS in a sandboxed iframe
2sections[] (template: "generic")Slot-based composition with typed blocks
3Named presetsLegacy templates ("brand-compliance", etc.)
Set template: "generic" and pass an ordered sections array. Each section has a type and a props dict:
{
  "slug": "product-search",
  "template": "generic",
  "meta": { "title": "Product Search" },
  "sections": [
    { "type": "hero",             "props": { "headline": "Find anything", "background_type": "gradient" } },
    { "type": "stats-bar",        "props": {} },
    { "type": "search-tabs",      "props": {} },
    { "type": "featured-gallery", "props": {} },
    { "type": "markdown-content", "props": { "content": "## About\nPowered by Mixpeek." } }
  ],
  "tabs": [{ ... }]
}
Available section types:
TypeDescription
heroFull-width headline with optional background image/video/gradient
stats-barHorizontal row of label+value stat pills
featured-galleryAuto-executing gallery on page load
search-tabsTab nav + search form + results grid
results-gridGrid of result cards (standalone, without tabs)
results-listList layout results
markdown-contentRendered markdown text block
iframe-embedSandboxed iframe escape hatch (props.url)

Custom HTML pages

For full control, set custom_html to a raw HTML string. It renders in a sandboxed iframe at full viewport size. The iframe can call mxp.co/p/{slug}/search directly:
<script>
async function search(query) {
  const res = await fetch('/p/my-page/search', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ tab_id: 'main', inputs: { query }, settings: {} })
  });
  return res.json();
}
</script>

Creating a Page

1

Create the Page

from mixpeek import Mixpeek

client = Mixpeek(api_key="your-api-key", namespace_id="ns_...")

page = client.pages.create(
    slug="product-search",
    template="generic",
    meta={
        "title": "Product Search",
        "description": "Semantic search across our catalog",
        "logo_url": "https://example.com/logo.png",
    },
    sections=[
        {"type": "hero", "props": {"headline": "Find anything", "background_type": "gradient"}},
        {"type": "stats-bar", "props": {}},
        {"type": "search-tabs", "props": {}},
    ],
    tabs=[
        {
            "tab_id": "text",
            "label": "Search",
            "retriever_id": "ret_abc123",
            "display_config": {
                "title": "Product Search",
                "template": "document-search",
                "theme": {"primary_color": "#FC5185"},
            },
        }
    ],
)
print(f"Page live at: https://mxp.co/p/{page.slug}")
2

Visit your Page

Your page is live immediately at https://mxp.co/p/product-search. No deployment needed.
3

Customize further

Use PATCH /v1/pages/{page_id} to update any field. All fields are optional in the patch request.

Tab routing

Each tab in tabs[] routes searches to a retriever. You can use either:
  • retriever_id — an internal retriever in your organization (org-scoped)
  • public_name — a marketplace catalog entry (proxied to the public API, no org context needed)
{
  "tabs": [
    {
      "tab_id": "images",
      "label": "Images",
      "retriever_id": "ret_private123",
      "display_config": { "title": "Image Search", "template": "portrait-gallery", "theme": {} }
    },
    {
      "tab_id": "videos",
      "label": "Videos",
      "public_name": "superbowl-video-search",
      "display_config": { "title": "Video Search", "template": "video-search", "theme": {} }
    }
  ]
}

Auto-creation on retriever publish

When you publish a retriever, a companion Page is created automatically:
# Publish a retriever
curl -X POST https://api.mixpeek.com/v1/retrievers/ret_abc123/publish \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Namespace: $NAMESPACE_ID" \
  -d '{"public_name": "my-search", "display_config": {...}}'

# Page is now live at:
# https://mxp.co/p/my-search
The auto-created Page has a single tab that proxies searches through the retriever’s public_name. You can then customize it via PATCH /v1/pages/{page_id} — add sections, a hero, SEO config, or additional tabs.
If a Page with the same slug already exists, the auto-creation is skipped (idempotent).

Draft / Publish / Rollback

Pages support a draft workflow — edits via PATCH are saved as drafts and are not visible to end-users until you publish.

How it works

  1. Create a page → it’s live immediately (version 0).
  2. Edit the page via PATCH → changes are saved to the document but the public API continues to serve the last published snapshot.
  3. Publish with POST /v1/pages/{page_id}/publish → snapshots the current config, bumps the version, and makes the changes live.
  4. Rollback with POST /v1/pages/{page_id}/rollback → restores the previous published version (one level of undo).
For convenience, you can set "publish": true in a PATCH request to apply the update and publish in a single call.

Example: Edit → Preview → Publish

from mixpeek import Mixpeek

client = Mixpeek(api_key="your-api-key", namespace_id="ns_...")

# 1. Edit the page (draft — not live yet)
client.pages.update(
    page_id="pg_abc123",
    meta={"title": "New Title", "description": "Updated description"},
)

# 2. Preview at the API level (GET returns the draft)
draft = client.pages.get(page_id="pg_abc123")
print(f"Draft title: {draft.meta.title}")
print(f"Has unpublished changes: {draft.has_unpublished_changes}")

# 3. Publish when ready
published = client.pages.publish(page_id="pg_abc123")
print(f"Published version {published.version}")

Version tracking

Each publish increments the version counter. The response includes:
  • version — current published version number
  • has_unpublished_changestrue when the draft differs from the published snapshot
Rollback supports one level of undo only. After rolling back, you must publish again before you can roll back a second time.

/r/ redirects to /p/

Legacy marketplace URLs at mxp.co/r/{public_name} automatically redirect to mxp.co/p/{public_name} when a Page exists for that slug. If no Page exists, the original /r/ marketplace rendering is used as a fallback.

Public search API

End-users search through pages without any API key:
# Execute a search on the "evaluate" tab
curl -X POST https://api.mixpeek.com/v1/public/pages/product-search/search \
  -H "Content-Type: application/json" \
  -d '{
    "tab_id": "text",
    "inputs": { "query": "blue running shoes" },
    "settings": {}
  }'
For image inputs, pass a base64 data URI:
{
  "tab_id": "images",
  "inputs": { "query_image": "data:image/jpeg;base64,/9j/4AAQ..." },
  "settings": {}
}

Password protection

Pages can be gated with a password stored in your org secrets:
{
  "slug": "internal-dashboard",
  "password_secret_name": "my-page-password",
  ...
}
The public config endpoint returns "password_protected": true for these pages. Implement password verification in your frontend before calling the search endpoint.

Hero section

{
  "hero": {
    "headline": "Search our entire catalog",
    "subheadline": "Powered by multimodal AI",
    "background_type": "gradient",
    "background_color": "#1a1a2e",
    "text_color": "#ffffff",
    "logo_url": "https://example.com/logo.png",
    "height": "420px",
    "cta_label": "Try a demo",
    "cta_url": "https://example.com/demo"
  }
}
background_type can be "image", "video", "gradient", or "solid".

SEO configuration

{
  "seo": {
    "meta_title": "Product Search | Acme",
    "meta_description": "Find products with AI-powered semantic search",
    "og_image_url": "https://example.com/og.png",
    "og_type": "website",
    "twitter_card": "summary_large_image",
    "robots": "index, follow",
    "canonical_url": "https://mxp.co/p/product-search"
  }
}
When you publish a retriever, an OG image is auto-generated and populated in the companion Page’s SEO config.