Outcome templates and keywords
Every deployer-created HIP-4 market fills a validator-voted template that fixes its wording, side names and typed keywords, one value per keyword.
A template takes the wording out of your hands. Validators vote it in, fixing the text, side names and typed keywords; you only fill the keywords. Its semanticRestriction states what its markets may mean, and a market that contradicts it is malformed and slashable.
Say you fill binaryPrice with perp BTC, priceDescription “the BTC mark”, seconds 60, threshold 100000 and time 20261101-1200. On chain the name is template:binaryPrice and the description perp:BTC|priceDescription:the BTC mark|seconds:60|threshold:100000|time:20261101-1200. It resolves Yes if the 60-second TWAP is above 100000 at 12:00 UTC on 1 November 2026.
Every template has one of 3 roles
Section titled “Every template has one of 3 roles”| Role | Deploys | Fixes |
|---|---|---|
| Standalone outcome | a single two-sided market | the side names, for example Over and Under |
| Question | a question, the container | the question’s text; sides are Yes and No |
| Question outcome | one outcome inside a question | declares a parent question template and only instantiates under it |
Names and descriptions contain typed {keyword} placeholders, for example "{underlying} above {target} at {expiry}"; an instance supplies exactly one value per keyword.
Where templates come from
Section titled “Where templates come from”Validators vote templates in with registerTemplate; {"type": "outcomeTemplates"} lists a network’s templates. Mainnet listed none until permissionless deployment launched; it now lists 28, and testnet 68.
Each entry carries id, role, name, description and keywords. role is {"standaloneOutcome": {"sideNames": [...]}}, "question" or {"questionOutcome": {"parent": <question template id>}}; keywords lists [keyword, type] pairs. The semanticRestriction sits at the end of description, after metadata= with a category and subCategory.
Versions are new ids with a numeric suffix (binaryPrice up to binaryPrice6); deployer tooling treats the highest as current. The same id can differ by network (5 keywords on one, 11 on the other) or exist on only one: mainnet has scalarPrice, testnet instead scalePrice (misspelt), scalePrice2 and scalarPrice3, same keywords.
Read outcomeTemplates on the target network every time, comparing keywords and semanticRestriction, not just the id: a new version can change what a market may mean.
The mainnet set
Section titled “The mainnet set”| Role | Templates |
|---|---|
| Standalone (13) | aiModelHeadToHead, awardEntryWins, binaryPrice, binaryPriceExternal, companyIpoConfirmed, companyIpoFirstDayMarketCap, priceTouch, scalarPrice, sportsContestWinner, sportsOverUnderMarket, sportsScalarMarket, sportsSpread, sportsTotal |
| Question (5) | awardWinner, policyRateDecision, policyRateLadder, sportsContestResult, sportsTournamentWinner, with 10 question outcome templates between them |
That is the live set.
Three price templates take a perp keyword of type hlPerp; binaryPriceExternal names an external feed instead:
| Template | Keywords | Semantics |
|---|---|---|
binaryPrice |
perp, priceDescription, seconds, threshold, time |
Yes if the seconds-second TWAP is above threshold at time; a delisted perp uses its delisting price |
priceTouch |
perp, priceDescription, seconds, target, time |
Yes once the seconds-second TWAP equals or crosses target after deployment and at or before time; can settle as soon as it touches |
scalarPrice |
high, low, perp, priceDescription, seconds, time |
sides Long and Short; Long pays (price - low) / (high - low) clamped to 0 and 1, Short the rest, on the seconds-second TWAP ending at time; semanticRestriction requires the price of a Hyperliquid perp |
binaryPriceExternal |
feed, instrument, priceDescription, seconds, shortName, threshold, time |
Yes if the seconds-second TWAP from feed is above threshold; 0.5 if no settlement price is publicly verifiable 24 hours after time; semanticRestriction requires an authoritative external feed |
Settlement fractions are part of each template’s semantics:
| Fraction | Templates |
|---|---|
| may settle at 0.5 (draw, void or an unestablished fact) | aiModelHeadToHead, awardEntryWins, binaryPriceExternal, companyIpoFirstDayMarketCap, sportsContestWinner, sportsOverUnderMarket, sportsScalarMarket, sportsSpread, sportsTotal |
| exact fractions expected | scalarPrice, sportsScalarMarket; on testnet scalePrice |
Keyword types and value rules
Section titled “Keyword types and value rules”| Hint | Value |
|---|---|
dateTime |
UTC YYYYMMDD-HHMM, for example "20260712-1830"; in the future, within the next year |
date |
UTC YYYYMMDD, meaning end of day; in the future, within the next year |
string |
free text |
shortString |
free text of at most 10 characters |
hlPerp |
the name of an existing perp, "ABC" or a HIP-3 "dex:ABC" |
uInt |
non-negative integer that fits in a u64, no sign or leading zeros |
uDecimal |
non-negative decimal, no sign, exponent, or leading or trailing zeros |
Every value is at most 100 characters, with no {, } or pipe; : is allowed so HIP-3 coin names fit. Deployer tooling reads “within the next year” as at most 366 days.
What lands on chain
Section titled “What lands on chain”| Field | Derived as |
|---|---|
| Name | template:<template id>, for example template:binaryPrice; the prefix is reserved for template deployments; at most 100 characters |
| Description | the keyword pairs sorted by keyword, joined as key:value with pipes; at most 2000 characters |
| Side names | standalone: template: plus the template’s side names, for example template:Long; question outcomes: Yes and No |
| Question fallback | named template fallback, description other, sides Yes and No |
Outcomes inside a question carry only their own keywords; the event time and any resolution deadline live on the parent. Protocol recurring markets use no template: they are named Recurring, with a description starting class:priceBinary (standalone) or class:priceBucket (a question, priceThresholds <lower>,<upper>, outcomes index:0 to index:2). They use underlying, targetPrice and expiry where binaryPrice uses perp, threshold and time (market shapes).
The numbers
Section titled “The numbers”| Limit | Value |
|---|---|
| Keyword value length | 100 characters |
shortString |
10 characters |
| Dated keywords | future, at most 366 days ahead |
| Display name after substitution | 70 characters (standalone, question); 25 (question outcome) |
| Standalone side name | 10 characters |
| On-chain name | 100 characters |
| On-chain description | 2000 characters |
| Question outcomes per question | 100 |
| Deployer fee scale | 0 to 10, decimal string |
| Templates | 28 mainnet (13 standalone, 5 question, 10 question outcome), 68 testnet |
Sending an instance
Section titled “Sending an instance”The example above, as sent:
{ "type": "outcomeDeploy", "venue": "ab", "operation": { "registerStandaloneOutcomeFromTemplate": { "id": "binaryPrice", "keywordToValue": [ ["perp", "BTC"], ["priceDescription", "the BTC mark"], ["seconds", "60"], ["threshold", "100000"], ["time", "20261101-1200"] ], "deployerFeeScale": "1" } }}A question with its outcomes, in display order (the protocol adds the fallback):
{ "type": "outcomeDeploy", "venue": "ab", "operation": { "registerQuestionFromTemplate": { "questionTemplateInstance": { "id": "abc", "keywordToValue": [["expiry", "20261101-1830"]], "deployerFeeScale": "1" }, "namedOutcomeTemplateInstances": [ { "id": "abc-outcome", "keywordToValue": [["choice", "A"]] }, { "id": "abc-outcome", "keywordToValue": [["choice", "B"]] } ] } }}Rules that fail silently or late:
keywordToValueis pairs sorted by keyword. Signed as a JSON object, it encodes differently and recovers a stranger’s address.deployerFeeScalesits on the standalone or question instance; question outcomes inherit it, including those added byregisterAndAssociateNamedOutcomeFromTemplate.- Grammar is checked on submission. A
uDecimal"95.000"signs fine and is rejected (it must be"95"), still using a daily slot. Validate locally. - A new outcome in a live question credits each holder of the fallback’s Yes with equal new Yes, so “other” keeps its meaning.
Reading a template correctly
Section titled “Reading a template correctly”- TWAP templates are not settled by one print: a single mark at
timeis the wrong input forbinaryPriceandscalarPrice. scheduledStartis kickoff, not a deadline. Sports templates also carryresolutionDeadline; price templates onlytime. Misreading it makes every sports market look overdue at kickoff.- Deployer-action examples are not live keywords. They use
underlying,targetandexpiry; livebinaryPriceusesperp,thresholdandtime,priceTouchusestarget. TheoutcomeTemplatesexample in the info docs does show the livebinaryPrice. Read names fromoutcomeTemplates, and never hard-code an id across networks.
Once listed, you owe a settlement (settling outcomes). For how templates look to traders, see market shapes.