Intake questions
A manifest describes the questions a business enables. Agents collect answers without inventing the missing details.
A shared language for service pricing · 0.1-draft
An open standard so AI agents can quote services that don’t have a fixed price. Questions in → range + deposit out. A person confirms before it’s binding. Checkout stays on UCP or ACP.
Questions, pricing and human review, in a shared language.
Implement ↗Follow the JSON examples, then explore the reference bindings.
A common foundation
Agents can check out fixed-price goods. Tattoo, laser, wraps, and most consult work need questions and math first. UQP is that missing quote step.
Universal Quoting Protocol (UQP) separates what a business asks, how it prices and when a person decides.
A manifest describes the questions a business enables. Agents collect answers without inventing the missing details.
Business-owned factors produce an explainable range, deposit and session envelope.
Shared objects, trade-specific questions. Tattoo is the first pack; other packs remain planned.
For businesses
You set the rates, minimums and deposit rule. Agents never invent a number. Every quote is a range until you confirm it.
Your pricing model is explicit. Change a rate or disable a factor without rewriting the conversation.
Choose review before or after pricing. Uncertain requests wait for the person who can decide.
Keep payment outside the quoting core. An accepted quote can hand off to your checkout workflow.
See it in action
Six moments. One thread of structured data. Explore the Tattoo example, one step at a time.
QuoteManifest
The business tells an agent which questions are enabled and which pricing model to use.
Example data, not real prices.
See every field →{
"pack_id": "tattoo",
"pack_version": "0.1.0",
"enabled_questions": [
"description",
"placement",
"size",
"width",
"height",
"complexity",
"style",
"budget_min",
"budget_max",
"first_tattoo"
],
"pricing_model_ref": "urn:uqp:tattoo:pricing:example",
"artist_review_mode": "post_price",
"expiry_days": 7,
"currencies": [
"USD"
]
}QuoteRequest
The agent collects answers, preserving what the customer said. Consent travels separately from the answers.
Example data, not real prices.
See every field →{
"pack_id": "tattoo",
"pack_version": "0.1.0",
"answers": {
"description": "A small geometric mountain design with clean outlines.",
"size": "sm",
"placement": [
"Lower Arm"
],
"complexity": "simple",
"style": "blackgrey"
},
"consent": {
"share_for_pricing_research": false,
"anonymize": true,
"captured_at": "2026-11-05T12:00:00Z"
}
}PricingModel
Configured rates and enabled factors do the math. The model belongs to the business, not the agent.
Example data, not real prices.
See every field →{
"pack_id": "tattoo",
"pack_version": "0.1.0",
"provenance": "tattoo.co current constant, unvalidated",
"id": "tattoo-formula-a-example",
"artist_review_mode": "post_price",
"factors": [
{
"id": "size",
"enabled": true,
"provenance": "tattoo.co current constant, unvalidated",
"value": {
"dimensions": {
"xs": 1.5,
"sm": 3,
"md": 5,
"lg": 8,
"xl": 12,
"unsure": 5
},
"area_per_hour": 12,
"minimum_hours": 1,
"unknown_base_hours": 4
},
"mode": "no_estimate"
},
{
"id": "placement",
"enabled": true,
"provenance": "tattoo.co current constant, unvalidated",
"mode": "additive_0_5h",
"value": {
"additive_hours": 0.5,
"multiplier": 1.2,
"tricky": [
"Wrist",
"Hand",
"Neck",
"Foot",
"Lower Leg"
],
"match": {
"additive_0_5h": "substring",
"multiplier_1_2": "substring_ci"
}
}
},
{
"id": "complexity",
"enabled": true,
"provenance": "tattoo.co current constant, unvalidated",
"mode": "asked",
"value": {
"simple": 1,
"moderate": 1.15,
"detailed": 1.35,
"realism": 1.6
}
},
{
"id": "style",
"enabled": true,
"provenance": "tattoo.co current constant, unvalidated",
"mode": "asked",
"value": {
"blackgrey": 1,
"popcolor": 1.15,
"color": 1.3
}
},
{
"id": "tier",
"enabled": true,
"provenance": "tattoo.co current constant, unvalidated",
"mode": "fallback_standard"
},
{
"id": "deposit",
"enabled": true,
"provenance": "tattoo.co current constant, unvalidated",
"mode": "pct_of_low_30",
"value": {
"low_percentage": 0.3,
"total_percentage": 0.5,
"low_increment": 25,
"total_increment": 50,
"piece_increment": 25
}
}
],
"rates": {
"currency": "USD",
"pricing_mode": "hourly",
"tiers": {
"apprentice": 120,
"standard": 200,
"senior": 300
},
"range_band": {
"low": 0.85,
"high": 1.15
},
"piece_high_multiplier": 1.5,
"provenance": "tattoo.co current constant, unvalidated"
},
"minimums": {
"piece_deposit": 100,
"provenance": "tattoo.co current constant, unvalidated"
},
"rounding": {
"increment": 50,
"mode": "nearest"
},
"deposit_policy": {
"mode": "pct_of_low_30",
"percentage": 0.3
},
"expiry_days": 7,
"keyword_match": "substring"
}Quote
PAYLOAD_SUBMITTED returns a non-binding Estimate with a price, even while artist review is pending.
Example data, not real prices.
See every field →{
"review_status": "VALIDATED_PENDING_REVIEW",
"artist_review_mode": "post_price",
"price_range": {
"min": 150,
"max": 250,
"currency": "USD",
"basis": "hourly",
"method": "rule",
"provenance": {
"who": "PricingModel tattoo@0.1.0 (example rules, unvalidated)",
"when": "2026-11-05T12:00:00.000Z"
}
},
"assumptions": [
"tattoo.co current constant, unvalidated; supplied handoff attributed to f018b86, not independently revalidated.",
"Pricing uses unrounded hours; display logs both Formula A Math.round(t*10)/10 and Formula B toFixed(1).",
"Sessions are a provisional single block (zero for by_piece); session splitting and caps are not modeled.",
"Multiple placements trigger any-tricky once; area summing is not modeled.",
"Raw answers are preserved; anonymized=false because free text has not been deidentified."
]
}Quote
After artist review, QUOTED carries a binding Quote with range, deposit policies, sessions, confidence and valid_until. This synthetic review keeps the example pricing unchanged.
Example data, not real prices.
See every field →{
"pack_id": "tattoo",
"pack_version": "0.1.0",
"price_range": {
"min": 150,
"max": 250,
"currency": "USD",
"basis": "hourly",
"method": "rule",
"provenance": {
"who": "Example artist (synthetic review)",
"when": "2026-11-05T12:00:00Z"
}
},
"sessions": {
"count": 1,
"hours_per_session": 1
},
"deposit": {
"amount": 50,
"basis": "low",
"provenance": {
"who": "PricingModel tattoo@0.1.0 (example rules, unvalidated)",
"when": "2026-11-05T12:00:00.000Z"
},
"policies": [
"Example data, not real prices; provider must state final deposit policies before artist review."
],
"status": "unpaid",
"merchant_of_record": "provider"
},
"valid_until": "2026-11-12T12:00:00.000Z",
"review_status": "QUOTED"
}Quote → checkout
ACCEPTED requires explicit client approval of the amount and policies before external checkout handoff. The provider is merchant of record; UQP never holds funds.
Example data, not real prices.
See every field →{
"state": "ACCEPTED",
"handoff": "external checkout",
"deposit_paid": "processor confirmation only"
}Different roles. Shared context.
Inspect the objects and reference bindings before connecting a workflow.
Build from the spec →Keep control of the questions, rates and decisions that shape a quote.
Explore business controls →Collect structured answers and preserve the boundary between an estimate and a binding quote.
Read the transport notes →For developers
REST and MCP first, GraphQL next, A2A later. The core is transport-independent; bindings are still draft work.
Explore transports →Inspect the fields, validate the payloads and use the language you already work in.
Get the schemas →Design a handoff to UCP or ACP checkout. Integrations are not implemented in this draft.
Read the handoff boundary →Humans in the loop
When a request needs a person, it waits for one. The artist or owner confirms before a quote becomes binding.
Automation handles the repeatable work. People keep the judgment.
Explore the lifecycle →Industry packs
Intake, pricing factors and a reference evaluator for the first pack.
Powered by Tattoo.dev
Explore the Tattoo pack →An open invitation
Bring the questions your customers ask and the rules your shop actually uses. We’re co-designing packs with builders and owners — tattoo first.
Co-design a pack →Signup is open. Name, email, and industry (repo link and notes optional).