Intent Spec Template — TOMO Partner Integration
This is the canonical template every TOMO intent specification follows. It is duplicated per-intent under docs/intents/<domain>.<intent>.md and filled in completely.
Authoring rule: Every field is REQUIRED. There is no "optional." If a partner cannot surface a field, that partner cannot list that intent on TOMO. TOMO Intelligence requires complete signal — incomplete listings are not a soft choice, they are a rejection condition.
This is harder for partners than industry-standard contracts. That is intentional. TOMO sets the bar; partners that meet it deliver users a maximum-information experience.
REQUIRED SECTIONS PER INTENT
Every <domain>.<intent>.md file MUST contain these 13 sections, in order, with full depth.
1. INTENT IDENTITY
2. NATURAL LANGUAGE COVERAGE — what user phrasings classify into this intent
3. INPUT — exact JSON shape TOMO sends to the provider
4. PROVIDER TOOLS — what the partner MUST implement
5. RESPONSE SHAPE — every field in every object the partner returns
6. CONTROLLED VOCABULARIES — fixed enums, no free text
7. TTBS DIMENSIONS — how TOMO ranks across providers source-blind
8. COMPLETION CONTRACT — what the partner POSTs when intent closes
9. WIDGET — which TOMO chat widget renders the result
10. CACHING POLICY — TTLs per call type
11. ERROR CODES — exhaustive list, no free-text errors
12. SANDBOX → PRODUCTION CHECKLIST — what reviewers verify
13. ANTI-FABRICATION RULES — forbidden fields, behaviors, signals
SECTION 1 — INTENT IDENTITY
INTENT NAMESPACE: <domain> // mobility | food | travel | etc.
INTENT NAME: <verb_object> // book_hotel | order_delivery | book_ride
FULL ID: <namespace>.<name> // travel.book_hotel
VERSION: v1.0.0
STATUS: draft | live | deprecated
LAST UPDATED: YYYY-MM-DD
TTBS WEIGHTS: time, taste, budget, safety // sum to 1.0; locked per domain
SECTION 2 — NATURAL LANGUAGE COVERAGE
Three lists with at least 8 entries each:
CLASSIFIES IN — user phrasings that route to this intent CLASSIFIES OUT — borderline NO — phrasings that look similar but go elsewhere MULTI-INTENT TRIGGERS — phrasings that fan out to this AND another intent
This section describes which requests belong to this intent.
SECTION 3 — INPUT (TOMO → PROVIDER)
Full JSON request body shape. Every field documented in a table:
| Field | Type | Constraint | Notes |
|---|
Field constraints use these markers:
REQUIRED— must be present + non-nullSTRICT ENUM— must match controlled vocabulary in §6ISO_DATE— ISO 8601 date (YYYY-MM-DD)ISO_DATETIME— ISO 8601 datetime with timezone offsetINR_INTEGER— whole rupees, no decimals, no formattingRFC_3066_LOCALE— e.g.en-INISO_3166_2— country code, alwaysINfor v1
Anti-fabrication preamble (every intent): "TOMO will never inject paid_placement signals, urgency text, or commission-influenced fields into this payload. Provider may not reject the request based on TOMO's commission rate."
SECTION 4 — PROVIDER TOOLS
For each tool the partner must implement, document:
TOOL NAME: <verb_object>
PURPOSE: one-sentence description
INPUT SHAPE: reference to §3 or sub-shape
OUTPUT SHAPE: reference to §5
SLA: p50, p95, p99 latencies
RATE LIMIT: requests TOMO will send per (user, partner)
IDEMPOTENCY: how the partner deduplicates retries
RETRY: what TOMO does on what error code
A typical commerce intent has 3-4 tools: search_*, get_*, create_*, optionally cancel_*.
SECTION 5 — RESPONSE SHAPE
The big one. Every field of every returned object. Format:
ObjectName:
field_name:
type: string | int | float | boolean | enum<...> | object | array<...>
constraint: REQUIRED | STRICT ENUM | URL | ISO_DATETIME | INR_INTEGER | etc.
semantics: one-sentence meaning
example: "Taj West End"
null_handling: REJECTED # always — no nulls allowed under strict-required regime
Authoring rule for §5: under strict-required, every field listed MUST be in every response. Partners that don't have the data must collect it, derive it, or contract a third-party data provider. There is no "skip this if you don't have it" path.
If a field is genuinely impossible for any partner (e.g., a hotel can't have a "trip distance" field — that's a ride property), the field doesn't appear in the spec at all.
Forbidden fields are listed at the end of §5 explicitly so partner reviewers can grep for them in test responses.
SECTION 6 — CONTROLLED VOCABULARIES
Every enum field gets a fixed list. Free text is forbidden where structure is possible.
Format:
field_path:
values:
value1: "human-readable description"
value2: "..."
resolution_order: how partners map their internal vocabulary to ours
Vocabulary changes require a spec version bump (v1.0.0 → v1.1.0) so partners get a heads-up.
SECTION 7 — TTBS DIMENSIONS
Four sub-sections. For each:
TIME:
signals_used: [field paths from §5]
weighting: how each signal contributes
user_band_handling: how user's "fast vs flexible" preference shifts ranking
TASTE:
signals_used: [...]
weighting: ...
user_band_handling: ...
BUDGET:
signals_used: [...]
weighting: ...
user_band_handling: ok / good / great spectrum
SAFETY:
signals_used: [...]
weighting: ...
user_band_handling: ...
Per-domain weights are locked in TOMO's internal domain agent registry. The intent spec restates them for clarity.
User can shift via DNA-weighting (silent personalization). Partners cannot influence weights through any spec field.
SECTION 8 — COMPLETION CONTRACT
The HMAC-signed POST partner sends to /api/v1/cpc/mcp_provider/{tomo_partner_id} when the intent closes (success or terminal failure).
Mandatory fields, signing scheme, replay window, retry behavior. Locked in TOMO's CPC webhook contract — see WEBHOOK_SIGNING.md.
SECTION 9 — WIDGET
The TOMO chat widget that renders this intent's results. Reference to:
- Source file:
src/widgets/types.ts - Type:
<WidgetName>Payload - Rendering rules: how Listing fields map to widget fields
Widget contracts are locked. Partners do not influence widget design.
SECTION 10 — CACHING POLICY
| Call | TTL | Rationale |
|---|
TTLs balance partner load vs data freshness. Pricing/availability calls cache short (30-60s). Static metadata (descriptions, photos) caches long (5-60min). Failure responses NEVER cache.
SECTION 11 — ERROR CODES
Exhaustive table. Free-text errors forbidden — every error must map to a code from this list.
| Code | HTTP Status | Meaning | TOMO retry behavior |
|---|
Universal codes (apply to every intent):
INVALID_REQUEST— payload malformedRATE_LIMITED— partner-side throttleINTERNAL_ERROR— partner-side failureINVALID_AUTH— bad credentialsSIGNATURE_INVALID— HMAC verification failed (CPC webhook only)
Intent-specific codes documented per intent.
SECTION 12 — SANDBOX → PRODUCTION CHECKLIST
Concrete, testable list. Reviewer (TOMO admin) ticks each before flipping status: live.
[ ] All required input fields validated
[ ] All response fields populated with real data (no test fixtures)
[ ] Controlled vocabularies respected (no free-text drift)
[ ] HMAC signing verified on test CPC webhook
[ ] Forbidden fields absent from all responses
[ ] SLA latency p95 met during 100-call sandbox test
[ ] Compliance docs uploaded and approved (intent-specific list)
[ ] Privacy policy URL live and accessible
[ ] Customer support contact verified (email + phone)
Intent-specific items append to this list.
SECTION 13 — ANTI-FABRICATION RULES
The hardest section. Rules that protect users from partner manipulation. Our team checks each rule by hand during review. (planned: an automatic check when your response arrives.)
RULE: No paid_placement_score, ad_bid, sponsored_rank, promotion_priority,
kickback_amount, referral_fee_kickback, _partner_revenue_share fields
anywhere in any response. Listings that carry these fields are rejected at review.
RULE: No artificial_urgency_text ("Only 1 left! Act fast!") unless backed
by a numeric inventory.rooms_left field with value <= 3. Partner
cannot fabricate scarcity.
RULE: review_score values must be unrounded floats from raw user reviews.
No "rounded up to 4.5 for marketing".
RULE: ... (intent-specific rules per spec)
VERSION HISTORY
Per-intent file maintains a changelog:
v1.0.0 — 2026-05-09 — Initial spec
v1.1.0 — YYYY-MM-DD — Added <field>; partners must update by YYYY-MM-DD
v2.0.0 — YYYY-MM-DD — Breaking change: <description>; partners must re-verify
HOW PARTNERS CONSUME THIS
- Read
_TEMPLATE.mdonce — understand the shape - Read the specific
<domain>.<intent>.mdfor each intent they want to serve - Implement the tools in §4 returning the shape in §5
- Test against TOMO sandbox (credentials set up with our team after your application is approved)
- POST signed CPC webhook from §8 on every closed intent
- Submit to TOMO admin for production review (§12)
- Our team tests your connection with you inside TOMO, then switches it on
Our team reviews every connection by hand before it goes live. The spec is the contract.
HOW TOMO CONSUMES THIS
TOMO reads the intent ID your tools declare, ranks results source-blind with the §7 weights, and shows them with the §9 widget as GREAT, GOOD and OK choices. Your §8 completion POST records the order and TOMO's fee. Our team uses the §12 checklist before your connection goes live.
This template is the contract for the contract. Every intent doc is graded against this template before it's added to the live catalog.