← Prize Shape
API
Tokens

Run Prize Shape from your own code

Both metered lanes are available over HTTP and each returns one JSON object. The division of labour: the page decides the medium before the size, checks the pool against the Prizes line, counts awards and units, drafts the eligibility paragraph and routes every exposure - all free, in prizekit.js. The run writes the structure or the brief section; the page then holds the reply to its own picks (prizereply.js).

Base URL and the response shape

Every endpoint lives under https://api.skillsafe.ai/v1/app-api, and every response has one shape:

{ "ok": true,  "data":  { ... } }
{ "ok": false, "error": { "code": "...", "message": "..." } }

The token is minted for this app (the guest call takes {"slug":"prize-shape"}), so no slug header is needed afterwards. Send it as Authorization: Bearer …. The run body is the input object, sent bare.

StatusCodeMeaning
400validation_errorThe body is not a JSON object, or a required key (task, event, awards, facts) is missing.
401unauthorizedNo token, or a stale one. Mint a guest token or sign in again.
402insufficient_creditsThe balance is under min_credits. Price with /estimate first.
403forbiddenA guest token tried to run: both lanes are metered and need a personal sign-in.
404not_foundUnknown job id.
429rate_limitedBack off and retry.
5xxserver_errorTransient. Retry with the same Idempotency-Key so a retry never double-bills.

The task field comes first

Two lanes - structure (the prize structure to validate) and brief (the prize section to publish; unavailable while a prize uses a removed medium). A missing or unknown task is answered as structure. Both lanes send the same four fields.

The input

FieldRequiredWhat
taskyesstructure or brief. If it is missing or neither, do structure and set "task": "structure".
eventyesthe event, its cadence and intent, the Prizes line and team cap, who holds the money and who reviews, who might win, the handover, leftover and roster rules, any continuing condition, and the publication and close dates.
awardsyesthe tracks as published, every award with its medium and value, and the page's draft eligibility-to-receive paragraph.
factsyesthe page's medium decision, pool, split, units, gates, payout rung, the exposure categories with their routes, the pass threshold, the signals to record and every finding tagged [fix], [check] or [info].
retry_notenooptional; if present, your previous reply was unusable - follow it.

The rules the model applies

House rules

The replies

structure

  1. summary - one sentence, at most 35 words: the medium, the pool against the line, and the first thing to settle.
  2. medium - used (every medium the tracks use, as the page names them, including any removed), deleted (the page's removed media, [] when none), why (one sentence: the reason for each deletion, or why the media fit).
  3. pool - rung (none, modest, sponsor or flagship, the page's pick - copy it even when a finding says it must change, and say so in the note), organizer and sponsor (the page's amounts as numbers), line (the Prizes line as a number, or null when not set), note (one sentence).
  4. split - shape (podium, winner, track or flat, the page's pick - copy it even when a finding deletes it, and name the fix in the note), awards (the page's award count), note (one sentence).
  5. units - count (the page's per-person units, 0 when none), leftover (the page's leftover rule, or "" when not decided), note (one sentence).
  6. eligibility - blanks (the page's count of bracketed blanks), note (one sentence: what still has to be decided, or that the paragraph is ready to hand to the brief).
  7. payout - rung (standard, administered or counsel, the page's pick), handover (who hands over, from the input, or a role), claim (one sentence: what a winner provides, described as a category, never a form name), finality (one sentence, or "" when there is no continuing condition), lapse (one sentence: what happens to an unclaimed award - your design where the input is silent, labelled).
  8. exposures - one object per live category in the page's order: category (the page's name), route (the page's route exactly, or "not routed").
  9. signals - 2 or 3 short strings, the page's signals to record, each with the revision it would trigger (your design).
  10. caveats - at most 4 short strings: every [fix] finding first, then the most important [check] findings while there is room. [] when there are none of either.
{
  "task": "structure",
  "summary": "one sentence",
  "medium": { "used": [ "Gear" ], "deleted": [], "why": "one sentence" },
  "pool": { "rung": "modest", "organizer": 600, "sponsor": 0, "line": 1000, "note": "one sentence" },
  "split": { "shape": "podium", "awards": 3, "note": "one sentence" },
  "units": { "count": 12, "leftover": "returned", "note": "one sentence" },
  "eligibility": { "blanks": 0, "note": "one sentence" },
  "payout": { "rung": "standard", "handover": "a name or a role", "claim": "one sentence", "finality": "", "lapse": "one sentence" },
  "exposures": [ { "category": "Contest-law classification", "route": "a name or a role" } ],
  "signals": [ "what to record and what it changes" ],
  "caveats": [ "a caveat" ]
}

The page holds it to its own picks: the media and removals, the pool rung with its amounts and the Prizes line, the split and award count, the units and leftover rule, the blank count, the payout rung and every live exposure with its route; no number may appear that the input does not hold, and no tax form may be named.

brief

  1. awards - one short string per award, in the page's order: the track and place exactly as the page names them, what the award is, and its value or units as the page states them (for credits, the expiry and region). An award whose sponsorship is not signed is still listed - say in the note that it must not be published until signed.
  2. eligibility - the page's eligibility-to-receive paragraph, lightly edited for flow only: keep every sentence's decision, and keep every bracketed blank exactly as bracketed.
  3. claim - a few sentences: how a winner claims (identity and status as a category, never a form name), who hands over, and what happens to an unclaimed award.
  4. conditions - one or two sentences on the continuing condition and when awards become final, or "" when there is none.
  5. note - one sentence, at most 30 words, for the organizers: what to settle before the section is published.
{
  "task": "brief",
  "awards": [ "Overall first - ..." ],
  "eligibility": "the paragraph",
  "claim": "a few sentences",
  "conditions": "",
  "note": "one sentence"
}

The page requires every award in order with credit expiries, the eligibility paragraph's decisions with its exact bracketed blanks, unsigned sponsor awards held back in the note, any continuing condition, and no tax form named.

Worked examples - every lane, every sample

These are the page's three free samples (fictional events, sponsors and people). Each input is exactly what the page sends; each reply is the saved reply the sample replays, shipped as the validating model wrote it; the last line is the page's own check. Every sample has both lanes.

Northgate Student Hack (gear and credits) - structure

Modest pool, sized to the Prizes line; Graduated podium, 6 awards; Administered payout; 6 of 6 written.

Input:

{
 "task": "structure",
 "event": "Event: Northgate Student Hack; a recurring event; the prize is meant to reward the winners after it; effort ceiling normal\nBudget: Prizes line $1,500; team-size cap 4\nMoney: runs under a fiscal host (the student union's finance office); counsel not named\nWho might win: a minor no; outside the organizer's country no; organizers, volunteers, mentors and judges may build, may not win; sponsor employees may compete, not win their own employer's prize\nHandover by the prize lead; awards follow the submitted roster; leftover units returned; continuing condition code and video stay public, final 2027-04-15\nDates: prize structure published 2027-02-01; submissions close 2027-03-07",
 "awards": "Tracks as published:\nOverall | overall | funded by organizer | Gear | per person | 3 places\nBest use of the Atlas Maps API | sponsor | funded by Atlas Maps (signed) | Credits and vouchers | per team | 1 place | expiry 2027-12-31, region worldwide\nBest hardware hack | sponsor | funded by Voltrane Parts (NOT signed) | Gear | per person | 1 place\nAudience choice | audience | funded by organizer | Recognition only | per team | 1 place\nAwards (6):\nOverall first: Gear, $100 per person x 4 = $400\nOverall second: Gear, $60 per person x 4 = $240\nOverall third: Gear, $30 per person x 4 = $120\nBest use of the Atlas Maps API first: Credits and vouchers, $500 per team\nBest hardware hack first: Gear, $80 per person x 4 = $320\nAudience choice first: Recognition only\nEligibility-to-receive paragraph, as the page drafted it (no blanks):\nPrizes are awarded to the team named in the submission. Organizers, volunteers, mentors and judges may build projects and demo them, and are not eligible to receive a prize. Employees of a prize sponsor may build and compete, and are not eligible to receive a prize funded by their own employer. Prizes are awarded per team member up to the team-size limit of 4; unclaimed units are returned. Credit prizes carry the expiry date and redemption region stated with each award, and may need an account you create. To receive a prize you will be asked to confirm your identity and any information we are required to collect; we will tell you exactly what that is when you claim. Your code and demo video must remain public to keep the prize; awards become final on 2027-04-15.",
 "facts": "Medium: Gear, Credits and vouchers, Recognition only; nothing deleted; informal handover deleted\nPool: modest - Modest pool, sized to the Prizes line; organizer-funded $760; sponsor-funded $820 (Best hardware hack not signed); Prizes line $1,500 (it bounds the organizer-funded part only; sponsor money sits outside it)\nSplit: podium - Graduated podium; 6 awards; overall shares 53/32/16 (one published podium ran 50/30/20)\nUnits: 16 per-person units against a team cap of 4; leftover returned\nGates (counsel or the fiscal host reviews before announcing): none live\nPayout: administered - Administered payout; handover by the prize lead\nExposure categories live, with routes (never answered here - no threshold, no form name, no amount): Contest-law classification -> the student union's finance office; Payer-side tax reporting and withholding -> the student union's finance office; Sponsor employees receiving their own sponsor's prize -> the funding sponsor's legal team; Organizers, volunteers, mentors and judges receiving anything -> published practice\nPass threshold (6 of 6): The medium written; The total pool with the budget line it fits inside written; The split with an award count written; The eligibility-to-receive text, no blanks written; The payout mechanic naming who hands over what written; Every live exposure category routed to someone written\nSignals to record: Awards actually handed over against awards announced (self-set); Winners who never claimed, and by when the lapse rule ran (self-set); Prize units left over against the team-size rule (self-set)\nFindings (3):\n[info] gear_lead (medium): Gear: many items get backordered - order early for stock risk, keep the receipts, and decide the fate of a leftover unit before the event.\n[check] unsigned (pool): Best hardware hack is funded by Voltrane Parts but the sponsorship is not signed - announcing it before the money lands leaves the organizer owning the gap personally.\n[info] gate (readiness): Pass threshold: 6 of 6 in writing before the brief is published (self-set)."
}

Reply:

{
 "task": "structure",
 "summary": "Gear, credits and vouchers, and recognition only fund a modest $760 organizer pool against the $1,500 Prizes line, plus $820 sponsor funds outside it; the unsigned Voltrane Parts sponsorship needs settling first.",
 "medium": {
  "used": [
   "Gear",
   "Credits and vouchers",
   "Recognition only"
  ],
  "deleted": [],
  "why": "Gear and credits need no payment rail, and recognition only fits an event meant to reward its winners rather than draw attention, so none of the three media needed removing."
 },
 "pool": {
  "rung": "modest",
  "organizer": 760,
  "sponsor": 820,
  "line": 1500,
  "note": "The organizer-funded $760 sits inside the $1,500 Prizes line while the $820 sponsor total, which includes the unsigned Voltrane Parts track, sits outside it."
 },
 "split": {
  "shape": "podium",
  "awards": 6,
  "note": "The 6 awards split 53/32/16 across the overall podium's 3 places, plus one award each for Best use of the Atlas Maps API, Best hardware hack and Audience choice."
 },
 "units": {
  "count": 16,
  "leftover": "returned",
  "note": "The 16 per-person units run against the team-size cap of 4, follow the submitted roster, and any leftover unit is returned."
 },
 "eligibility": {
  "blanks": 0,
  "note": "With no gates live and no bracketed blanks left, the eligibility-to-receive paragraph is ready to hand to the brief."
 },
 "payout": {
  "rung": "administered",
  "handover": "the prize lead",
  "claim": "A winner confirms their identity and any other information the organizers are required to collect before the award is handed over.",
  "finality": "Code and the demo video must stay public for the award to remain earned, becoming final on 2027-04-15.",
  "lapse": "Our design: an award not claimed within a reasonable window lapses and is returned, matching the leftover-unit rule."
 },
 "exposures": [
  {
   "category": "Contest-law classification",
   "route": "the student union's finance office"
  },
  {
   "category": "Payer-side tax reporting and withholding",
   "route": "the student union's finance office"
  },
  {
   "category": "Sponsor employees receiving their own sponsor's prize",
   "route": "the funding sponsor's legal team"
  },
  {
   "category": "Organizers, volunteers, mentors and judges receiving anything",
   "route": "published practice"
  }
 ],
 "signals": [
  "Awards actually handed over against awards announced - a gap would trigger a payout-process review.",
  "Winners who never claimed, and by when the lapse rule ran - repeat lapses would trigger a revision of the claim window.",
  "Prize units left over against the team-size rule - a pattern would trigger a revision of the per-person unit count."
 ],
 "caveats": [
  "Best hardware hack's Voltrane Parts sponsorship is unsigned - do not announce it before the money lands."
 ]
}

The page's check: kept - nothing to flag

Northgate Student Hack (gear and credits) - brief

Modest pool, sized to the Prizes line; Graduated podium, 6 awards; Administered payout; 6 of 6 written.

Input:

{
 "task": "brief",
 "event": "Event: Northgate Student Hack; a recurring event; the prize is meant to reward the winners after it; effort ceiling normal\nBudget: Prizes line $1,500; team-size cap 4\nMoney: runs under a fiscal host (the student union's finance office); counsel not named\nWho might win: a minor no; outside the organizer's country no; organizers, volunteers, mentors and judges may build, may not win; sponsor employees may compete, not win their own employer's prize\nHandover by the prize lead; awards follow the submitted roster; leftover units returned; continuing condition code and video stay public, final 2027-04-15\nDates: prize structure published 2027-02-01; submissions close 2027-03-07",
 "awards": "Tracks as published:\nOverall | overall | funded by organizer | Gear | per person | 3 places\nBest use of the Atlas Maps API | sponsor | funded by Atlas Maps (signed) | Credits and vouchers | per team | 1 place | expiry 2027-12-31, region worldwide\nBest hardware hack | sponsor | funded by Voltrane Parts (NOT signed) | Gear | per person | 1 place\nAudience choice | audience | funded by organizer | Recognition only | per team | 1 place\nAwards (6):\nOverall first: Gear, $100 per person x 4 = $400\nOverall second: Gear, $60 per person x 4 = $240\nOverall third: Gear, $30 per person x 4 = $120\nBest use of the Atlas Maps API first: Credits and vouchers, $500 per team\nBest hardware hack first: Gear, $80 per person x 4 = $320\nAudience choice first: Recognition only\nEligibility-to-receive paragraph, as the page drafted it (no blanks):\nPrizes are awarded to the team named in the submission. Organizers, volunteers, mentors and judges may build projects and demo them, and are not eligible to receive a prize. Employees of a prize sponsor may build and compete, and are not eligible to receive a prize funded by their own employer. Prizes are awarded per team member up to the team-size limit of 4; unclaimed units are returned. Credit prizes carry the expiry date and redemption region stated with each award, and may need an account you create. To receive a prize you will be asked to confirm your identity and any information we are required to collect; we will tell you exactly what that is when you claim. Your code and demo video must remain public to keep the prize; awards become final on 2027-04-15.",
 "facts": "Medium: Gear, Credits and vouchers, Recognition only; nothing deleted; informal handover deleted\nPool: modest - Modest pool, sized to the Prizes line; organizer-funded $760; sponsor-funded $820 (Best hardware hack not signed); Prizes line $1,500 (it bounds the organizer-funded part only; sponsor money sits outside it)\nSplit: podium - Graduated podium; 6 awards; overall shares 53/32/16 (one published podium ran 50/30/20)\nUnits: 16 per-person units against a team cap of 4; leftover returned\nGates (counsel or the fiscal host reviews before announcing): none live\nPayout: administered - Administered payout; handover by the prize lead\nExposure categories live, with routes (never answered here - no threshold, no form name, no amount): Contest-law classification -> the student union's finance office; Payer-side tax reporting and withholding -> the student union's finance office; Sponsor employees receiving their own sponsor's prize -> the funding sponsor's legal team; Organizers, volunteers, mentors and judges receiving anything -> published practice\nPass threshold (6 of 6): The medium written; The total pool with the budget line it fits inside written; The split with an award count written; The eligibility-to-receive text, no blanks written; The payout mechanic naming who hands over what written; Every live exposure category routed to someone written\nSignals to record: Awards actually handed over against awards announced (self-set); Winners who never claimed, and by when the lapse rule ran (self-set); Prize units left over against the team-size rule (self-set)\nFindings (3):\n[info] gear_lead (medium): Gear: many items get backordered - order early for stock risk, keep the receipts, and decide the fate of a leftover unit before the event.\n[check] unsigned (pool): Best hardware hack is funded by Voltrane Parts but the sponsorship is not signed - announcing it before the money lands leaves the organizer owning the gap personally.\n[info] gate (readiness): Pass threshold: 6 of 6 in writing before the brief is published (self-set)."
}

Reply:

{
 "task": "brief",
 "awards": [
  "Overall first - Gear, $100 per person x 4 = $400.",
  "Overall second - Gear, $60 per person x 4 = $240.",
  "Overall third - Gear, $30 per person x 4 = $120.",
  "Best use of the Atlas Maps API first - Credits and vouchers, $500 per team, expiry 2027-12-31, region worldwide.",
  "Best hardware hack first - Gear, $80 per person x 4 = $320.",
  "Audience choice first - Recognition only."
 ],
 "eligibility": "Prizes are awarded to the team named in the submission. Organizers, volunteers, mentors and judges may build projects and demo them, and are not eligible to receive a prize. Employees of a prize sponsor may build and compete, and are not eligible to receive a prize funded by their own employer. Prizes are awarded per team member up to the team-size limit of 4; unclaimed units are returned. Credit prizes carry the expiry date and redemption region stated with each award, and may need an account you create. To receive a prize you will be asked to confirm your identity and any information we are required to collect; we will tell you exactly what that is when you claim. Your code and demo video must remain public to keep the prize; awards become final on 2027-04-15.",
 "claim": "A winner claims a prize by confirming their identity and any other information the organizers are required to collect, and the prize lead hands over the award once that is confirmed. Any unit a team does not use is returned under the team-size cap of 4, and an award that is never claimed lapses and is returned on the same basis (our design).",
 "conditions": "Winners must keep their code and demo video public to keep the prize, with awards becoming final on 2027-04-15.",
 "note": "Settle the Best hardware hack sponsorship with Voltrane Parts before publishing; it is listed here but must not go out until the funding is signed."
}

The page's check: kept - nothing to flag

Open Climate Hack (online, cash) - structure

Flagship pool; Graduated podium, 5 awards; Counsel-reviewed payout; 4 of 6 written.

Input:

{
 "task": "structure",
 "event": "Event: Open Climate Hack (online); a one-off edition; the prize is meant to buy attention before the event; effort ceiling normal\nBudget: Prizes line $10,000; team-size cap 5\nMoney: the team has its own legal entity; counsel outside counsel, to be engaged\nWho might win: a minor maybe; outside the organizer's country yes; organizers, volunteers, mentors and judges may build, may not win; sponsor employees not decided\nHandover by the operations lead; awards follow the submitted roster; leftover units not decided; continuing condition none\nDates: prize structure published 2027-04-10; submissions close 2027-05-02",
 "awards": "Tracks as published:\nGrand prize | overall | funded by organizer | Cash | per team | 3 places\nBest use of Nimbus Cloud | sponsor | funded by Nimbus Cloud (signed) | Cash | per team | 1 place\nSeed pitch slot | sponsor | funded by Quayfern Ventures (signed) | Opportunity | per team | 1 place | written commitment NO\nAwards (5):\nGrand prize first: Cash, $5,000 per team\nGrand prize second: Cash, $2,500 per team\nGrand prize third: Cash, $1,000 per team\nBest use of Nimbus Cloud first: Cash, $2,000 per team\nSeed pitch slot first: Opportunity, access rather than money\nEligibility-to-receive paragraph, as the page drafted it (2 blanks still bracketed):\nPrizes are awarded to the team named in the submission. Organizers, volunteers, mentors and judges may build projects and demo them, and are not eligible to receive a prize. [Sponsor employees may / may not receive a prize funded by their own employer.] A winner under the age of majority in [place] will be asked to have a parent or guardian receive the prize on their behalf. Where a prize cannot be delivered to a winner's location, we will agree an alternative of comparable value with that winner. To receive a prize you will be asked to confirm your identity and any information we are required to collect; we will tell you exactly what that is when you claim.",
 "facts": "Medium: Cash, Opportunity; deleted: Cash (a winner could be a minor, a winner could be outside the organizer's country); Opportunity (no written commitment); informal handover deleted\nPool: flagship - Flagship pool; organizer-funded $8,500; sponsor-funded $2,000; Prizes line $10,000 (it bounds the organizer-funded part only; sponsor money sits outside it)\nSplit: podium - Graduated podium; 5 awards; overall shares 59/29/12 (one published podium ran 50/30/20)\nUnits: no per-person units\nGates (counsel or the fiscal host reviews before announcing): a winner could be a minor; a winner could be outside the organizer's country; a sponsor's own employee could win that sponsor's prize\nPayout: counsel - Counsel-reviewed payout; handover by the operations lead\nExposure categories live, with routes (never answered here - no threshold, no form name, no amount): Contest-law classification -> outside counsel, to be engaged; Payer-side tax reporting and withholding -> outside counsel, to be engaged; Cross-border payment -> outside counsel, to be engaged; Minors receiving an award -> outside counsel, to be engaged; Sponsor employees receiving their own sponsor's prize -> the funding sponsor's legal team; Organizers, volunteers, mentors and judges receiving anything -> published practice\nPass threshold (4 of 6): The medium MISSING; The total pool with the budget line it fits inside written; The split with an award count written; The eligibility-to-receive text, no blanks MISSING; The payout mechanic naming who hands over what written; Every live exposure category routed to someone written\nSignals to record: Awards actually handed over against awards announced (self-set); Winners who never claimed, and by when the lapse rule ran (self-set); Any eligibility question raised on the day with no published answer (self-set)\nFindings (7):\n[fix] cash_deleted (medium): Grand prize is a cash prize, but a winner could be a minor and a winner could be outside the organizer's country - cash is deleted: the machinery to pay it correctly does not exist yet. Pick gear, credits or recognition, or route it to counsel before anything is announced.\n[fix] cash_deleted (medium): Best use of Nimbus Cloud is a cash prize, but a winner could be a minor and a winner could be outside the organizer's country - cash is deleted: the machinery to pay it correctly does not exist yet. Pick gear, credits or recognition, or route it to counsel before anything is announced.\n[fix] opportunity_unwritten (medium): Seed pitch slot offers an opportunity with no written commitment from Quayfern Ventures - an opportunity the organizer cannot deliver is the one prize that fails publicly. Deleted until the commitment is in writing.\n[info] flagship (pool): Flagship pool: \"a bigger pool draws more submissions\" is an assumption, not a measurement - one platform's guidance says a modest, well-distributed pool performs as well. Large enough that a losing team might ask who decided? Route the payout to counsel.\n[check] blanks (eligibility): The eligibility paragraph still has 2 bracketed blanks - publishing it with a bracket in it is worse than publishing nothing.\n[check] gates (eligibility): Live gates - a winner could be a minor; a winner could be outside the organizer's country; a sponsor's own employee could win that sponsor's prize. Each carries a legal obligation, not a menu choice: counsel or the fiscal host reviews the payout before the prize is announced.\n[check] gate (readiness): Pass threshold: 4 of 6 in writing before the brief is published - missing: The medium, The eligibility-to-receive text, no blanks (self-set)."
}

Reply:

{
 "task": "structure",
 "summary": "Cash and the opportunity are deleted, the flagship pool is $8,500 organizer plus $2,000 sponsor against the $10,000 Prizes line, and the first thing to settle is a new medium for the cash awards.",
 "medium": {
  "used": [
   "Cash",
   "Opportunity"
  ],
  "deleted": [
   "Cash",
   "Opportunity"
  ],
  "why": "Cash is deleted because a winner could be a minor and a winner could be outside the organizer's country, and Opportunity is deleted because Quayfern Ventures has given no written commitment."
 },
 "pool": {
  "rung": "flagship",
  "organizer": 8500,
  "sponsor": 2000,
  "line": 10000,
  "note": "Flagship is the page's pick though the assumption that a bigger pool draws more submissions is unmeasured, and the $10,000 Prizes line bounds only the $8,500 organizer-funded part while the $2,000 sponsor-funded part sits outside it."
 },
 "split": {
  "shape": "podium",
  "awards": 5,
  "note": "The page runs a graduated podium across 5 awards with overall shares of 59/29/12, compared with one published podium that ran 50/30/20."
 },
 "units": {
  "count": 0,
  "leftover": "",
  "note": "No non-cash prize currently carries per-person units, and the page has not yet decided a leftover-unit rule."
 },
 "eligibility": {
  "blanks": 2,
  "note": "The sponsor-employee eligibility choice and the minor's jurisdiction still need to be filled in before the two bracketed blanks can be published."
 },
 "payout": {
  "rung": "counsel",
  "handover": "the operations lead",
  "claim": "A winner confirms their identity and supplies whatever reporting information is required, as they will be told when they claim.",
  "finality": "",
  "lapse": "Design: with no lapse rule set by the page, an unclaimed award should stay with the operations lead until the organizers decide how it lapses."
 },
 "exposures": [
  {
   "category": "Contest-law classification",
   "route": "outside counsel, to be engaged"
  },
  {
   "category": "Payer-side tax reporting and withholding",
   "route": "outside counsel, to be engaged"
  },
  {
   "category": "Cross-border payment",
   "route": "outside counsel, to be engaged"
  },
  {
   "category": "Minors receiving an award",
   "route": "outside counsel, to be engaged"
  },
  {
   "category": "Sponsor employees receiving their own sponsor's prize",
   "route": "the funding sponsor's legal team"
  },
  {
   "category": "Organizers, volunteers, mentors and judges receiving anything",
   "route": "published practice"
  }
 ],
 "signals": [
  "Awards actually handed over against awards announced - a gap would trigger a review of the payout mechanic.",
  "Winners who never claimed, and by when the lapse rule ran - repeated non-claims would trigger writing an explicit lapse rule.",
  "Any eligibility question raised on the day with no published answer - would trigger filling the bracketed blanks before the next publication."
 ],
 "caveats": [
  "Grand prize is a cash prize but deleted since a winner could be a minor and a winner could be outside the organizer's country; pick gear, credits or recognition, or route it to counsel.",
  "Best use of Nimbus Cloud is a cash prize but deleted for the same minor and cross-border reasons; pick gear, credits or recognition, or route it to counsel.",
  "Seed pitch slot offers an opportunity with no written commitment from Quayfern Ventures and is deleted until the commitment is in writing.",
  "Pass threshold is 4 of 6 before publishing - missing: the medium, and the eligibility-to-receive text with no blanks."
 ]
}

The page's check: kept - nothing to flag

Riverside Civic Hack Day (no entity) - structure

Modest pool, sized to the Prizes line; Winner take most, 3 awards; Standard-form payout; 1 of 6 written.

Input:

{
 "task": "structure",
 "event": "Event: Riverside Civic Hack Day; a recurring event; the prize is meant to reward the winners after it; effort ceiling low\nBudget: Prizes line NOT SET; team-size cap 4\nMoney: no legal entity and no fiscal host; counsel not named\nWho might win: a minor no; outside the organizer's country no; organizers, volunteers, mentors and judges may build and win; sponsor employees may not compete\nHandover by not named; awards follow the people present; leftover units not decided; continuing condition none\nDates: prize structure published 2027-05-20; submissions close 2027-05-18",
 "awards": "Tracks as published:\nCommunity award | overall | funded by organizer | Recognition only | per team | 1 place\nOpen data track | sponsor | funded by City Library (signed) | Opportunity | per team | 1 place | written commitment yes\nOrganizers' pick | overall | funded by organizer | Gear | per team | 1 place\nAwards (3):\nCommunity award first: Recognition only\nOpen data track first: Opportunity, access rather than money\nOrganizers' pick first: Gear, $60 per team\nEligibility-to-receive paragraph, as the page drafted it (1 blank still bracketed):\nPrizes are awarded to the team members present at the closing ceremony. [Organizers, volunteers, mentors and judges: decide whether they may receive a prize.] Employees of a prize sponsor may not compete for or receive any prize. To receive a prize you will be asked to confirm your identity and any information we are required to collect; we will tell you exactly what that is when you claim.",
 "facts": "Medium: Gear, Opportunity, Recognition only; deleted: Cash (there is no legal entity and no fiscal host); informal handover available for goods to an adult at the venue\nPool: modest - Modest pool, sized to the Prizes line; organizer-funded $60; sponsor-funded $0; Prizes line not set\nSplit: winner - Winner take most; 3 awards\nUnits: no per-person units\nGates (counsel or the fiscal host reviews before announcing): none live\nPayout: standard - Standard-form payout; handover by not named\nExposure categories live, with routes (never answered here - no threshold, no form name, no amount): Contest-law classification -> NOT ROUTED; Payer-side tax reporting and withholding -> NOT ROUTED; Organizers, volunteers, mentors and judges receiving anything -> published practice\nPass threshold (1 of 6): The medium written; The total pool with the budget line it fits inside MISSING; The split with an award count MISSING; The eligibility-to-receive text, no blanks MISSING; The payout mechanic naming who hands over what MISSING; Every live exposure category routed to someone MISSING\nSignals to record: Awards actually handed over against awards announced (self-set); Winners who never claimed, and by when the lapse rule ran (self-set); Any eligibility question raised on the day with no published answer (self-set)\nFindings (12):\n[info] opportunity_open (medium): Open data track is an opportunity: its legal treatment is unsettled - an award working as a job or investment introduction may touch employment or securities rules. An open question to route.\n[info] gear_lead (medium): Gear: many items get backordered - order early for stock risk, keep the receipts, and decide the fate of a leftover unit before the event.\n[fix] no_line (pool): The organizer funds $60 of prizes, but the budget's Prizes line is not set - say so rather than sizing against nothing.\n[fix] winner_deleted (split): Winner take most with a sponsor-funded track - deleted: that sponsor bought a named award and this shape has nowhere to put it. Use a graduated podium beside the sponsor tracks.\n[check] two_overall (split): 2 overall awards - one ranked podium, with every other award a track or a separate layer.\n[fix] staff_win (eligibility): People working the event allowed to receive prizes - published practice keeps organizers, volunteers, mentors and judges out of the receiving pool whatever they may build.\n[check] blanks (eligibility): The eligibility paragraph still has 1 bracketed blank - publishing it with a bracket in it is worse than publishing nothing.\n[check] unrouted (exposure): No one named to route contest-law classification, payer-side tax reporting and withholding to - name the counsel or fiscal host who answers it; never answer it on the page.\n[check] no_entity (payout): No legal entity and no fiscal host: nobody can sign a payout. A fiscal sponsor is the standard route; recognition is the one medium that needs neither.\n[check] no_handover (payout): Name who hands over or transfers each award - \"the sponsor is handling it\" is not a payout plan.\n[fix] publish_late (publication): The prize structure is published 2027-05-20, not before submissions close (2027-05-18) - a prize announced after teams chose what to build has already failed at motivating anything.\n[check] gate (readiness): Pass threshold: 1 of 6 in writing before the brief is published - missing: The total pool with the budget line it fits inside, The split with an award count, The eligibility-to-receive text, no blanks, The payout mechanic naming who hands over what, Every live exposure category routed to someone (self-set)."
}

Reply:

{
 "task": "structure",
 "summary": "Gear, Opportunity and Recognition only fund a modest $60 organizer pool against a Prizes line that is not yet set, which is the first thing to settle.",
 "medium": {
  "used": [
   "Gear",
   "Opportunity",
   "Recognition only"
  ],
  "deleted": [
   "Cash"
  ],
  "why": "Cash is deleted because there is no legal entity and no fiscal host to run a cash payout."
 },
 "pool": {
  "rung": "modest",
  "organizer": 60,
  "sponsor": 0,
  "line": null,
  "note": "The organizer funds $60 of prizes but the Prizes line itself is not set, so the pool cannot yet be sized against it."
 },
 "split": {
  "shape": "winner",
  "awards": 3,
  "note": "Winner take most is deleted now that City Library funds a sponsor track, so the fix is a graduated podium beside the sponsor track."
 },
 "units": {
  "count": 0,
  "leftover": "",
  "note": "No medium here carries per-person units, so the leftover rule stays undecided."
 },
 "eligibility": {
  "blanks": 1,
  "note": "One bracketed blank - whether organizers, volunteers, mentors and judges may receive a prize - still has to be decided before publication."
 },
 "payout": {
  "rung": "standard",
  "handover": "not named",
  "claim": "A winner confirms their identity and any other information the event is required to collect.",
  "finality": "",
  "lapse": "An unclaimed award should revert to the organizer until a published lapse rule says otherwise (our design)."
 },
 "exposures": [
  {
   "category": "Contest-law classification",
   "route": "not routed"
  },
  {
   "category": "Payer-side tax reporting and withholding",
   "route": "not routed"
  },
  {
   "category": "Organizers, volunteers, mentors and judges receiving anything",
   "route": "published practice"
  }
 ],
 "signals": [
  "Awards actually handed over against awards announced - a gap triggers a review of the payout mechanic.",
  "Winners who never claimed, and by when the lapse rule ran - repeated misses trigger writing a lapse rule.",
  "Any eligibility question raised on the day with no published answer - triggers a rewrite of the eligibility paragraph."
 ],
 "caveats": [
  "The organizer funds $60 of prizes, but the Prizes line is not set.",
  "Winner take most is deleted because a sponsor funds a track; use a graduated podium instead.",
  "Organizers, volunteers, mentors and judges must stay out of the receiving pool, per published practice.",
  "The prize structure publishes 2027-05-20, after submissions close 2027-05-18."
 ]
}

The page's check: kept - nothing to flag

Riverside Civic Hack Day (no entity) - brief

Modest pool, sized to the Prizes line; Winner take most, 3 awards; Standard-form payout; 1 of 6 written.

Input:

{
 "task": "brief",
 "event": "Event: Riverside Civic Hack Day; a recurring event; the prize is meant to reward the winners after it; effort ceiling low\nBudget: Prizes line NOT SET; team-size cap 4\nMoney: no legal entity and no fiscal host; counsel not named\nWho might win: a minor no; outside the organizer's country no; organizers, volunteers, mentors and judges may build and win; sponsor employees may not compete\nHandover by not named; awards follow the people present; leftover units not decided; continuing condition none\nDates: prize structure published 2027-05-20; submissions close 2027-05-18",
 "awards": "Tracks as published:\nCommunity award | overall | funded by organizer | Recognition only | per team | 1 place\nOpen data track | sponsor | funded by City Library (signed) | Opportunity | per team | 1 place | written commitment yes\nOrganizers' pick | overall | funded by organizer | Gear | per team | 1 place\nAwards (3):\nCommunity award first: Recognition only\nOpen data track first: Opportunity, access rather than money\nOrganizers' pick first: Gear, $60 per team\nEligibility-to-receive paragraph, as the page drafted it (1 blank still bracketed):\nPrizes are awarded to the team members present at the closing ceremony. [Organizers, volunteers, mentors and judges: decide whether they may receive a prize.] Employees of a prize sponsor may not compete for or receive any prize. To receive a prize you will be asked to confirm your identity and any information we are required to collect; we will tell you exactly what that is when you claim.",
 "facts": "Medium: Gear, Opportunity, Recognition only; deleted: Cash (there is no legal entity and no fiscal host); informal handover available for goods to an adult at the venue\nPool: modest - Modest pool, sized to the Prizes line; organizer-funded $60; sponsor-funded $0; Prizes line not set\nSplit: winner - Winner take most; 3 awards\nUnits: no per-person units\nGates (counsel or the fiscal host reviews before announcing): none live\nPayout: standard - Standard-form payout; handover by not named\nExposure categories live, with routes (never answered here - no threshold, no form name, no amount): Contest-law classification -> NOT ROUTED; Payer-side tax reporting and withholding -> NOT ROUTED; Organizers, volunteers, mentors and judges receiving anything -> published practice\nPass threshold (1 of 6): The medium written; The total pool with the budget line it fits inside MISSING; The split with an award count MISSING; The eligibility-to-receive text, no blanks MISSING; The payout mechanic naming who hands over what MISSING; Every live exposure category routed to someone MISSING\nSignals to record: Awards actually handed over against awards announced (self-set); Winners who never claimed, and by when the lapse rule ran (self-set); Any eligibility question raised on the day with no published answer (self-set)\nFindings (12):\n[info] opportunity_open (medium): Open data track is an opportunity: its legal treatment is unsettled - an award working as a job or investment introduction may touch employment or securities rules. An open question to route.\n[info] gear_lead (medium): Gear: many items get backordered - order early for stock risk, keep the receipts, and decide the fate of a leftover unit before the event.\n[fix] no_line (pool): The organizer funds $60 of prizes, but the budget's Prizes line is not set - say so rather than sizing against nothing.\n[fix] winner_deleted (split): Winner take most with a sponsor-funded track - deleted: that sponsor bought a named award and this shape has nowhere to put it. Use a graduated podium beside the sponsor tracks.\n[check] two_overall (split): 2 overall awards - one ranked podium, with every other award a track or a separate layer.\n[fix] staff_win (eligibility): People working the event allowed to receive prizes - published practice keeps organizers, volunteers, mentors and judges out of the receiving pool whatever they may build.\n[check] blanks (eligibility): The eligibility paragraph still has 1 bracketed blank - publishing it with a bracket in it is worse than publishing nothing.\n[check] unrouted (exposure): No one named to route contest-law classification, payer-side tax reporting and withholding to - name the counsel or fiscal host who answers it; never answer it on the page.\n[check] no_entity (payout): No legal entity and no fiscal host: nobody can sign a payout. A fiscal sponsor is the standard route; recognition is the one medium that needs neither.\n[check] no_handover (payout): Name who hands over or transfers each award - \"the sponsor is handling it\" is not a payout plan.\n[fix] publish_late (publication): The prize structure is published 2027-05-20, not before submissions close (2027-05-18) - a prize announced after teams chose what to build has already failed at motivating anything.\n[check] gate (readiness): Pass threshold: 1 of 6 in writing before the brief is published - missing: The total pool with the budget line it fits inside, The split with an award count, The eligibility-to-receive text, no blanks, The payout mechanic naming who hands over what, Every live exposure category routed to someone (self-set)."
}

Reply:

{
 "task": "brief",
 "awards": [
  "Community award first - Recognition only, funded by the organizer.",
  "Open data track first - Opportunity, access rather than money, funded by City Library under a signed written commitment.",
  "Organizers' pick first - Gear, $60 per team, funded by the organizer."
 ],
 "eligibility": "Prizes are awarded to the team members present at the closing ceremony. [Organizers, volunteers, mentors and judges: decide whether they may receive a prize.] Employees of a prize sponsor may not compete for or receive any prize. To receive a prize you will be asked to confirm your identity and any information we are required to collect; we will tell you exactly what that is when you claim.",
 "claim": "A winner claims a prize by confirming their identity and any other information the event is required to collect. Who hands over each award has not yet been named. The input does not say what happens to an unclaimed award; as a design choice, an unclaimed award should revert to the organizer until a lapse rule is published.",
 "conditions": "",
 "note": "Settle the Prizes line, the split shape, the bracketed eligibility blank, and who hands over each award, then publish before the 2027-05-18 close, not after."
}

The page's check: kept - nothing to flag

The awards CSV for the first sample

track,place,medium,funder,per,unit_value,units,value
Overall,first,gear,organizer,person,100,4,400
Overall,second,gear,organizer,person,60,4,240
Overall,third,gear,organizer,person,30,4,120
Best use of the Atlas Maps API,first,credits,Atlas Maps,team,500,1,500
Best hardware hack,first,gear,Voltrane Parts,person,80,4,320
Audience choice,first,recognition,organizer,team,0,1,0

Build the input yourself

Load the engine in node (global.window = global; require("./prizekit.js"); require("./prizereply.js")), then:

const K = PrizeKit, R = PrizeReply;
const f = K.form({ name: "My Hack", prizesLine: "1500", teamCap: "4", entity: "host", hostName: "our fiscal host", handover: "the prize lead",
  leftover: "returned", publishDate: "2027-02-01", closeDate: "2027-03-07", tracks: fs.readFileSync("tracks.csv", "utf8") });
// f.media, f.deleted, f.pool, f.baseline, f.sponsorPool, f.split, f.awardCount, f.awards, f.units
// f.paragraph (eligibility to receive), f.blanks, f.gates, f.payout, f.exposures (key, route), f.gate, f.findings
K.awardsCSV(f)                                 // track, place, medium, funder, per, unit_value, units, value
const b = K.buildInput(f, "structure");        // or "brief"
const wire = K.toWire(b.input);                // POST this to /estimate and /run
// then: const reply = R.normalize(R.parseReply(job.output.output), "structure");
// R.check(reply, b)                           // {status: kept or flagged, notes}

Get a token for the steps below from /tokens.html.

Step 1 — a tiny client helper

One function that sends JSON and unwraps the response. Paste a personal token from /tokens.html, or leave it empty and mint a guest token in step 2.

BASE="https://api.skillsafe.ai/v1/app-api"
TOKEN="paste-your-token-here"   # from https://prize-shape.skillsafe.ai/tokens.html
api() { # api METHOD PATH [JSON-BODY]
  curl -s -X "$1" "$BASE$2" -H "Content-Type: application/json" \
    ${TOKEN:+-H "Authorization: Bearer $TOKEN"} ${3:+--data "$3"}
}

Step 2 — a token

A guest token is enough for /me and /estimate. A run is metered, so it needs a personal token: sign in on /tokens.html and copy it from there.

# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN=$(curl -s -X POST "$BASE/guest" -H "Content-Type: application/json" -d '{"slug":"prize-shape"}' | jq -r '.data.token')

Step 3 — GET /me

Who the token is (subject_type: user or guest) and the credit balance.

api GET /me | jq '.data | {subject_type, credits}' 

Step 4 — POST /estimate

Free. The body is the run input itself, the bare object (never wrapped in {"input": ...}). hold_credits is a reservation, not the price; min_credits is what the balance must cover; model_alias reads gpt-terra.

# input.json: the run input object - {"task": "structure", "event": "Event: ...; a recurring event ...", "awards": "Tracks as published: ...", "facts": "Medium: Gear, Credits and vouchers ..."}
# - see the input table
api POST /estimate "$(cat input.json)" | jq '.data | {hold_credits, min_credits, model, model_alias, markup_bps, warnings}' 

Step 5 — POST /run, then poll the job

Send an Idempotency-Key built from the lane and the input: a retry with the same key never bills twice. The page uses prize-shape:<task>:<inputHash>:a<attempt> - the lane is part of the key - and its one automatic reformat retry is a new attempt number, named in the page as one extra run. A structure carries summary, medium, pool, split, units, eligibility, payout, exposures, signals and caveats; a brief section carries awards, eligibility, claim, conditions and note. The code below prints the headline parts of either (list items are plain strings).

KEY="prize-shape:structure:$(shasum -a 256 input.json | cut -c1-16):a1"
JOB=$(curl -s -X POST "$BASE/run" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $KEY" --data @input.json | jq -r '.data.job_id')
while :; do
  J=$(api GET "/jobs/$JOB"); S=$(echo "$J" | jq -r '.data.status')
  case "$S" in succeeded|failed|cancelled) break;; esac; sleep 2
done
echo "$J" | jq -r '.data.output.output' > reply.json   # one JSON object, the reply contract
echo "$J" | jq '.data | {charged_credits, truncated}'
jq -r '.summary // .format, .note // .eligibility, ((.signals // .caveats)[] | "\(.signal // .caveat): \(.text // .text)")' reply.json
jq -r '.claim // .note // empty' reply.json   # how to claim (brief)

Step 6 — POST /run-stream

The same run as Server-Sent Events, with the same input.json. Browsers receive progress ticks rather than text deltas; the final done event carries the reply.

# Server-Sent Events: tick/delta events while the job runs, then a final event with the job
curl -N -s -X POST "$BASE/run-stream" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: prize-shape:structure:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json