PDP Schema
The Product Discovery Protocol (PDP) is a YAML specification that defines everything about your product's demo: screens, UI elements, demo flows, agent personality, knowledge base, and configuration.
Schema Sections
pdp_version — Schema version (currently "1.0")
product — Product metadata (name, URL, industry, personas)
agent — AI agent personality, tone, and LLM configuration
demo_accounts — Test accounts for live product navigation
screens — Product pages and their interactive elements
example_values — Realistic data for form fills and searches
flows — Step-by-step demo walkthroughs
knowledge — FAQs, competitive positioning, pricing
config — Lead capture, branding, domains, timeouts
product
namestringrequiredProduct name
versionstringProduct version
base_urlstring (URL)requiredDemo environment URL
descriptionstringrequiredProduct description
industrystringrequiredIndustry category (e.g., "CRM / Sales")
target_personasstring[]requiredTarget user roles
agent
namestringrequiredAgent display name
personalitystringrequiredSystem prompt personality description
tone'friendly' | 'professional' | 'technical' | 'casual'requiredCommunication style
voiceobjectTTS config: { provider, voice_id }
llmobjectrequiredLLM configuration
agent.llm
providerstringrequired"anthropic"
modelstringrequiredModel ID (e.g., "claude-sonnet-4-20250514")
temperaturenumberrequired0.0 – 1.0
max_tokensnumberrequiredMax response tokens
demo_accounts
Array of test accounts used for live product navigation.
idstringrequiredUnique account identifier
rolestringrequiredUser role name
credentials.login_urlstring (URL)requiredLogin page URL
credentials.login_method'form' | 'api' | 'sso'requiredAuthentication method
credentials.fieldsobjectrequiredCSS selector → encrypted value pairs
credentials.submit_selectorstringSubmit button CSS selector
permissions_summarystringDescription of account permissions
is_defaultbooleanDefault account for new sessions
pool_sizenumberNumber of concurrent sessions supported
reset_strategy'api' | 'db_snapshot' | 'soft_delete' | 'none'How to reset account state between sessions
screens
Array of product pages and their interactive elements.
idstringrequiredUnique screen identifier
routestringrequiredURL path (e.g., "/dashboard")
titlestringrequiredHuman-readable screen name
purposestringrequiredWhat this screen is for
wait_for_selectorstringCSS selector to wait for before screen is "ready"
elementsarrayrequiredInteractive elements on this screen
tagsstring[]Categorization tags
related_screensstring[]IDs of related screens
screens[].elements[]
idstringrequiredUnique element identifier
typestringrequiredbutton | input | select | table | chart | tab | link | modal | section | textarea | checkbox | radio | toggle
selectorstringrequiredCSS selector or data-testid
labelstringrequiredHuman-readable label
descriptionstringWhat this element does
example_values
Provides realistic data for demo form fills and searches. Values can be referenced in flows using template syntax: {{entities.deals[0].name}}
example_values:
entities:
customers:
- name: "Horizon Technologies"
email: "sarah@horizontech.com"
deals:
- name: "Enterprise License"
value: "$48,000"
form_fills:
new_deal:
"[name='dealName']": "{{entities.deals[0].name}}"
search_queries:
- "Horizon Technologies"flows
Array of step-by-step demo walkthroughs.
idstringrequiredUnique flow identifier
titlestringrequiredFlow name
descriptionstringrequiredWhat this flow demonstrates
trigger_phrasesstring[]requiredNatural language phrases that activate this flow
rolestringrequireddemo_account ID to use
personastringTarget persona for this flow
estimated_duration_secondsnumberExpected duration
stepsarrayrequiredOrdered list of demo steps
flows[].steps[]
screen_idstringrequiredTarget screen ID
actionstringrequirednavigate | click | fill | select | highlight | wait | scroll
element_idstringTarget element ID (for click, fill, select, highlight)
valuestringValue to fill or select
narrationstringrequiredWhat the agent says during this step
wait_msnumberDelay after this step (milliseconds)
knowledge
product_faqsarrayrequiredArray of { question, answer, category? }
competitive_positioningobjectCompetitor comparisons with differentiators and weaknesses
pricing_infoobject{ can_disclose, plans: [{ name, price, features }] }
docs_urlstringExternal documentation URL
custom_instructionsstringAdditional agent instructions
config
lead_capture.enabledbooleanrequiredEnable lead capture
lead_capture.fieldsstring[]requiredFields: email, company, name, phone
lead_capture.triggerstringrequired"after_N_steps" (e.g., "after_3_steps") or "never"
ctaobjectCall-to-action: { text, url }
branding.primary_colorstringrequiredHex color (e.g., "#6366f1")
branding.widget_positionstringrequired"bottom-right" or "bottom-left"
branding.agent_namestringOverride agent display name in widget
branding.logo_urlstringCustom logo URL
idle_nudge_secondsnumberSeconds before idle nudge
session_timeout_secondsnumberSession timeout in seconds
allowed_domainsstring[]requiredDomains where the widget can run
gdpr_modebooleanEnable GDPR-compliant mode
Full Example
A complete PDP for an example CRM product:
pdp_version: "1.0"
product:
name: "AcmeCRM"
version: "2.1.0"
base_url: "https://demo.acmecrm.com"
description: "Modern CRM for small and medium businesses"
industry: "CRM / Sales"
target_personas:
- "Sales Manager"
- "Account Executive"
agent:
name: "Alex"
personality: "You are Alex, a friendly and knowledgeable product expert for AcmeCRM."
tone: "friendly"
llm:
provider: "anthropic"
model: "claude-sonnet-4-20250514"
temperature: 0.5
max_tokens: 1200
demo_accounts:
- id: "sales_manager"
role: "Sales Manager"
credentials:
login_url: "https://demo.acmecrm.com/login"
login_method: "form"
fields:
"[name='email']": "enc:dGVzdEBhY21lLmNvbQ=="
"[name='password']": "enc:cGFzc3dvcmQxMjM="
submit_selector: "button[type='submit']"
permissions_summary: "Full access to contacts, deals, and reports"
is_default: true
pool_size: 3
reset_strategy: "none"
screens:
- id: "dashboard"
route: "/dashboard"
title: "Dashboard"
purpose: "Main dashboard showing sales pipeline overview and key metrics"
wait_for_selector: ".dashboard-loaded"
elements:
- id: "pipeline_chart"
type: "chart"
selector: "[data-testid='pipeline-chart']"
label: "Sales Pipeline Chart"
description: "Visual representation of the deal pipeline by stage"
- id: "add_deal_btn"
type: "button"
selector: "[data-testid='add-deal']"
label: "Add Deal"
description: "Opens the new deal creation form"
tags: ["overview", "pipeline"]
- id: "contacts"
route: "/contacts"
title: "Contacts"
purpose: "Contact list with search, filters, and bulk actions"
elements:
- id: "search_input"
type: "input"
selector: "[data-testid='contact-search']"
label: "Search Contacts"
- id: "add_contact_btn"
type: "button"
selector: "[data-testid='add-contact']"
label: "Add Contact"
- id: "deal_form"
route: "/deals/new"
title: "New Deal"
purpose: "Form to create a new sales deal"
elements:
- id: "deal_name"
type: "input"
selector: "[name='dealName']"
label: "Deal Name"
- id: "deal_value"
type: "input"
selector: "[name='dealValue']"
label: "Deal Value"
- id: "deal_stage"
type: "select"
selector: "[name='stage']"
label: "Pipeline Stage"
- id: "save_deal_btn"
type: "button"
selector: "button[type='submit']"
label: "Save Deal"
example_values:
entities:
customers:
- name: "Horizon Technologies"
email: "sarah@horizontech.com"
phone: "(415) 555-0142"
deals:
- name: "Horizon Technologies - Enterprise License"
value: "$48,000"
stage: "Proposal"
form_fills:
new_deal:
"[name='dealName']": "{{entities.deals[0].name}}"
"[name='dealValue']": "{{entities.deals[0].value}}"
search_queries:
- "Horizon Technologies"
flows:
- id: "create_deal"
title: "Create a New Deal"
description: "Walk through creating a new sales deal from start to finish"
trigger_phrases:
- "show me how to create a deal"
- "I want to add a new deal"
- "create a deal"
role: "sales_manager"
persona: "Sales Manager"
estimated_duration_seconds: 120
steps:
- screen_id: "dashboard"
action: "navigate"
narration: "Let me take you to the dashboard first."
- screen_id: "dashboard"
action: "highlight"
element_id: "pipeline_chart"
narration: "Here's your sales pipeline with deals by stage."
wait_ms: 2000
- screen_id: "dashboard"
action: "click"
element_id: "add_deal_btn"
narration: "Let's create a new deal."
- screen_id: "deal_form"
action: "fill"
element_id: "deal_name"
value: "{{entities.deals[0].name}}"
narration: "I'll enter the deal name."
- screen_id: "deal_form"
action: "fill"
element_id: "deal_value"
value: "{{entities.deals[0].value}}"
narration: "And the deal value - $48,000."
- screen_id: "deal_form"
action: "select"
element_id: "deal_stage"
value: "Proposal"
narration: "Setting the stage to Proposal."
- screen_id: "deal_form"
action: "click"
element_id: "save_deal_btn"
narration: "Done! The deal is now in your pipeline."
knowledge:
product_faqs:
- question: "How many contacts can I store?"
answer: "Unlimited on paid plans, up to 1,000 on free."
category: "limits"
- question: "Does AcmeCRM integrate with email?"
answer: "Yes — Gmail, Outlook, and any IMAP provider with two-way sync."
category: "integrations"
- question: "Is there a mobile app?"
answer: "Yes, native iOS and Android apps with offline access."
category: "features"
competitive_positioning:
Salesforce:
differentiators:
- "10x faster setup - no admin needed"
- "70% lower cost for teams under 50"
pricing_info:
can_disclose: true
plans:
- name: "Starter"
price: "Free"
features: ["Up to 1,000 contacts", "Basic pipeline"]
- name: "Professional"
price: "$29/user/month"
features: ["Unlimited contacts", "Email integration", "Reports"]
- name: "Enterprise"
price: "$79/user/month"
features: ["Everything in Professional", "Custom fields", "API access", "SSO"]
config:
lead_capture:
enabled: true
fields: ["email", "company"]
trigger: "after_3_steps"
cta:
text: "Start Free Trial"
url: "https://acmecrm.com/signup"
branding:
primary_color: "#6366f1"
widget_position: "bottom-right"
idle_nudge_seconds: 8
session_timeout_seconds: 1800
allowed_domains:
- "acmecrm.com"
- "localhost"
gdpr_mode: false