← Assessed Too High
Assessed Too High API
Tokens

Drive Assessed Too High from your own code

Both metered lanes are available over HTTP: the case check (a property tax assessment weighed against nearby sales and neighbours' assessments, with an appeal / fix-the-record / borderline / let-it-stand verdict, grounds, which comparables to lead with, the value to ask for, evidence and rebuttals) and the appeal letter (the written appeal plus a two-minute statement for the review board, or a records request when the evidence says let it stand). A natural use is a homeowners' association or a neighbourhood group checking many notices at once: your code sends each notice, the comparables and the page's figures, and gets back a structured case or a ready-to-file letter.

The division of labour first: the page does the arithmetic; the model judges and writes; the page re-checks every figure and address the model gives. The assessor's market value, the similarity ranking, the size adjustment (half a sale's price per sq ft per sq ft of difference - a rule of thumb, not an appraisal), the median of the sales, the neighbours' rate per sq ft, the size-error test, the value to ask for, the yearly saving, the flags and the page's verdict come from assesskit.js, which runs in node as well as in the browser. Its check function holds each reply to the user's own entries: every dollar figure must match one of the page's, every comparable must be on the list, the value asked for must sit below the assessor's and appear in the letter. Not legal, tax or appraisal advice.

Get a token on the token page (step 2 below also shows how to mint a guest token in code).

Base URL and the envelope

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

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

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

StatusCodeMeaning
400validation_errorThe body is not a JSON object, or task / notice 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 token.
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

Every run sends task: case or hearing. Both share the assessment fields; the letter lane adds its own. The model follows only the named task's contract.

TaskVerdictsReply fields
caseappeal (the evidence supports a lower value), fix_record (the record is wrong about the home), borderline (thin evidence or a small gap - ask for an informal review), let_stand (the evidence does not support a lower value)title, verdict, summary, grounds [{ground: market_value|equity|record_error, strength: strong|fair|weak, why}], comps [{comp, use: lead|support|drop, why}], ask_value (number or null), ask_why, evidence (strings), rebuttals [{they_say, you_say}], missing (strings)
hearingrequest_reduction, request_correction, informal_review, no_appeal (a records request instead of an appeal)title, verdict, summary, subject, letter (plain text), statement (spoken, under two minutes), requested_value (number or null), exhibits [{label, what}], questions [{q, a}], reminders (strings)

The declared input schema carries scalars only, so object-valued fields travel JSON-encoded as strings (AssessKit.toWire does this). The schema requires task and notice.

Input fields

FieldLaneTypeNotes
taskbothstringcase or hearing.
today, owner, placebothstringYYYY-MM-DD; the owner's name and the address as typed (may be empty).
noticebothstring (JSON){assessed_value, assessment_level_percent, level_entered, assessor_market_value, prior_year_value, change_from_prior_percent, tax_rate_percent, tax_rate_source, appeal_deadline, days_left}; empty string = not given.
homebothstring (JSON){record_sqft, measured_sqft, sqft_used, beds, baths, year_built, owner_estimate}.
compsbothstring (JSON)[{label, kind: sale | neighbour assessment, sale_price, sale_date, months_ago | assessed_value, sqft, beds, baths, year_built, price_per_sqft, adjusted_value, similarity, strength, used, left_out?}].
page_figuresbothstring (JSON){indicated_value, indicated_low, indicated_high, comps_used, gap, gap_percent, neighbour_median_per_sqft, subject_assessed_per_sqft, equity_indicated_assessed, equity_gap_percent, target_value, estimated_yearly_saving, figures_are_estimates}; gaps are the assessor minus the evidence.
page_flags, page_verdictbothstring (JSON), string[{level, text}] with level fix / warn / info; appeal, fix_record, borderline or let_stand.
notesbothstringThe owner's own words; past 1,500 characters the middle is cut with a marker.
boardhearingstringWho the letter is addressed to (may be empty).
case_noteshearingstringOne point a line - VERDICT:, ASK:, GROUND, LEAD:, SUPPORT:, DROP:, EVIDENCE:, REBUT: - from the case reply (AssessKit.caseToText), or empty.
retry_notebothstringOnly on a reformat retry.

The reply

The job's output.output is a string holding one JSON object. Parse it with AssessKit.parseReply, then normalize(reply, task), then check(reply, state, task), which returns {notes}: the page's notes (info, warn) shown under "Checked by the page".

Worked examples

Replies produced against the app's prompt for the sample homes (made up; lists shortened, letters folded; the full replies ship in example-result.js). Together they cover every verdict of both lanes. The page replays each of them free from its sample buttons.

task: case - bungalow - appeal

Input:

{
 "task": "case",
 "today": "2026-10-20",
 "owner": "Dana Fenwhistle",
 "place": "18 Linden Ave",
 "notice": "{\"assessed_value\":438000,\"assessment_level_percent\":100,\"level_entered\":true,\"assessor_market_value\":438000,\"prior_year_value\":371000,\"change_from_prior_percent\":18.1,\"tax_rate_percent\":1.9,\"tax_rate_source\":\"entered rate\",\"appeal_deadline\":\"2026-11-14\",\"days_left\":25}",
 "home": "{\"record_sqft\":1420,\"measured_sqft\":\"\",\"sqft_used\":1420,\"beds\":3,\"baths\":1.5,\"year_built\":1948,\"owner_estimate\":395000}",
 "comps": "[{\"label\":\"22 Linden Ave\",\"kind\":\"sale\",\"sale_price\":389000,\"sale_date\":\"2026-05\",\"months_ago\":5,\"sqft\":1380,\"beds\":3,\"baths\":1.5,\"year_built\":1951,\"price_per_sqft\":282,\"adjusted_value\":394600,\"similarity\":95,\"strength\":\"strong\",\"used\":true},{\"label\":\"9 Orchard St\",\"kind\":\"sale\",\"sale_price\":402500,\"sale_date\":\"2026-07\",\"months_ago\":3,\"sqft\":1460,\"beds\":3,\"baths\":2,\"year_built\":1946,\"price_per_sqft\":276,\"adjusted_value\":397000,\"similarity\":93,\"strength\":\"strong\",\"used\":true},\"... 3 more\"]",
 "page_figures": "{\"indicated_value\":395800,\"indicated_low\":384700,\"indicated_high\":402600,\"comps_used\":4,\"gap\":42200,\"gap_percent\":9.6,\"neighbour_median_per_sqft\":\"\",\"subject_assessed_per_sqft\":308,\"equity_indicated_assessed\":\"\",\"equity_gap_percent\":\"\",\"target_value\":396000,\"estimated_yearly_saving\":798,\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"info\",\"text\":\"25 days left to file (deadline 2026-11-14).\"},{\"level\":\"info\",\"text\":\"The assessment rose 18.1% from last year ($371,000 to $438,000).\"},\"... 4 more\"]",
 "page_verdict": "appeal",
 "notes": "The kitchen and the one full bath are original (1970s). The roof is 22 years old. Nothing has been added to th ... (145 characters)"
}

Reply:

{
 "task": "case",
 "title": "Assessed 9.6% over what the sales say",
 "verdict": "appeal",
 "summary": "The four nearby sales used point to an estimated value near $395,800 — about $42,200 (9.6%) below the assessor's market value of $438,000 for 18 Linden Ave. That supports asking for a lower value, led by 22 Linden Ave, 9 Orchard St and 31 Linden Ave. File before the appeal deadline of November 14, 2026 (25 days left), bringing the notice and these sales. This is general information, not an appraisal or legal advice, so check the county's own rules and forms first.",
 "grounds": [
  {
   "ground": "market_value",
   "strength": "strong",
   "why": "Four comparable sales, adjusted to this home's size, point to about $395,800 — $42,200 (9.6%) below the assessor's market value of $438,000."
  }
 ],
 "comps": [
  {
   "comp": "22 Linden Ave",
   "use": "lead",
   "why": "Sold for $389,000 in 2026-05 and adjusted to $394,600 for this home's size, with a similarity score of 95."
  },
  {
   "comp": "9 Orchard St",
   "use": "lead",
   "why": "Sold for $402,500 in 2026-07 and adjusted to $397,000, with a similarity score of 93."
  },
  {
   "comp": "140 Mill Rd",
   "use": "support",
   "why": "Sold for $375,000 in 2026-03 and adjusted to $384,700, though it has 2 beds and 1 bath against this home's 3 beds and 1.5 baths."
  },
  "..."
 ],
 "ask_value": 396000,
 "ask_why": "This is the page's estimated value to ask for, in line with what the sales show (about $395,800, range $384,700 to $402,600) and well below the assessor's $438,000 market value.",
 "evidence": [
  "The assessment notice showing the assessed value of $438,000.",
  "The sale records for 22 Linden Ave, 9 Orchard St and 31 Linden Ave.",
  "The property record card for 18 Linden Ave.",
  "..."
 ],
 "rebuttals": [
  {
   "they_say": "The assessment is consistent with last year's value, which rose 18.1% to $438,000.",
   "you_say": "The four comparable sales, not last year's figure, show the market value is closer to $395,800 — about $42,200 (9.6%) lower."
  },
  "..."
 ],
 "missing": [
  "No neighbours' assessed values were entered, so there's no way to check uneven assessment against nearby homes.",
  "No measured square footage was given to check the record's 1,420 sq ft against an actual measurement.",
  "..."
 ]
}

task: case - ranch - fix the record

Input:

{
 "task": "case",
 "today": "2026-10-20",
 "owner": "Luis Marrowby",
 "place": "406 Fenwick Rd",
 "notice": "{\"assessed_value\":296400,\"assessment_level_percent\":50,\"level_entered\":true,\"assessor_market_value\":592800,\"prior_year_value\":281000,\"change_from_prior_percent\":5.5,\"tax_rate_percent\":4.2,\"tax_rate_source\":\"mills (per $1,000)\",\"appeal_deadline\":\"2026-12-01\",\"days_left\":42}",
 "home": "{\"record_sqft\":2150,\"measured_sqft\":1860,\"sqft_used\":1860,\"beds\":3,\"baths\":2,\"year_built\":1972,\"owner_estimate\":\"\"}",
 "comps": "[{\"label\":\"412 Fenwick Rd\",\"kind\":\"sale\",\"sale_price\":571000,\"sale_date\":\"2026-04\",\"months_ago\":6,\"sqft\":1880,\"beds\":3,\"baths\":2,\"year_built\":1970,\"price_per_sqft\":304,\"adjusted_value\":568000,\"similarity\":98,\"strength\":\"strong\",\"used\":true},{\"label\":\"38 Abbot Ct\",\"kind\":\"sale\",\"sale_price\":559000,\"sale_date\":\"2026-06\",\"months_ago\":4,\"sqft\":1820,\"beds\":3,\"baths\":2,\"year_built\":1974,\"price_per_sqft\":307,\"adjusted_value\":565100,\"similarity\":96,\"strength\":\"strong\",\"used\":true},\"... 3 more\"]",
 "page_figures": "{\"indicated_value\":568000,\"indicated_low\":565100,\"indicated_high\":584300,\"comps_used\":3,\"gap\":24800,\"gap_percent\":4.2,\"neighbour_median_per_sqft\":149,\"subject_assessed_per_sqft\":159,\"equity_indicated_assessed\":277100,\"equity_gap_percent\":6.5,\"target_value\":568000,\"estimated_yearly_saving\":521,\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"info\",\"text\":\"42 days left to file (deadline 2026-12-01).\"},{\"level\":\"fix\",\"text\":\"The record lists 2,150 sq ft; you measured 1,860 (13.5% less). A factual error is usually the simplest thing to get corrected.\"},\"... 4 more\"]",
 "page_verdict": "fix_record",
 "notes": "We measured the outside walls ourselves with a laser measure: 1,860 sq ft of finished living space. The listin ... (212 characters)"
}

Reply:

{
 "task": "case",
 "title": "Record overstates size by 13.5%",
 "verdict": "fix_record",
 "summary": "The property record lists 2,150 sq ft for this home, but a laser measurement found 1,860 sq ft - a 13.5% difference that is usually the simplest thing to get corrected. The sales also point to about $568,000, 4.2% under the assessor's market value of $592,800, and at the neighbours' rate of $149 per sq ft the home would be assessed at about $277,100, 6.5% lower than it is now. The first step should be asking the assessor to correct the recorded square footage, since that alone changes the market value the assessment is based on. Rules and forms for a correction vary by county, so check the local requirements and file before the December 1, 2026 deadline, 42 days away.",
 "grounds": [
  {
   "ground": "record_error",
   "strength": "strong",
   "why": "The record lists 2,150 sq ft; a laser measurement found 1,860 sq ft, a 13.5% difference - large enough on its own to change the assessor's market value once corrected."
  },
  {
   "ground": "market_value",
   "strength": "strong",
   "why": "Three strong, recent sales put what the sales say at about $568,000 (range $565,100 to $584,300), 4.2% under the assessor's market value of $592,800."
  },
  "..."
 ],
 "comps": [
  {
   "comp": "412 Fenwick Rd",
   "use": "lead",
   "why": "98% similar and sold 6 months ago for $571,000 ($304 per sq ft), adjusting to $568,000 for this home's size - the figure the sales point to."
  },
  {
   "comp": "38 Abbot Ct",
   "use": "lead",
   "why": "The most recent sale, 4 months ago, 96% similar at $307 per sq ft, adjusting to $565,100, the low end of the range."
  },
  {
   "comp": "17 Harlow Dr",
   "use": "support",
   "why": "Sold 8 months ago with 4 bedrooms against this home's 3, 80% similar, adjusting to $584,300 - the high end of the range."
  },
  "..."
 ],
 "ask_value": 568000,
 "ask_why": "This is what the sales say the home is worth once sized correctly, and it is already below the assessor's $592,800 market value.",
 "evidence": [
  "The assessment notice.",
  "The laser measurement showing 1,860 sq ft of finished living space, with notes on how it differs from the recorded 2,150 sq ft.",
  "Photos or a sketch of the enclosed back porch, showing it is unheated, in case the record is counting it as finished space.",
  "..."
 ],
 "rebuttals": [
  {
   "they_say": "The owner's measurement may not match the assessor's method.",
   "you_say": "The 1,860 sq ft figure comes from a laser measurement of the exterior walls, and the original purchase listing already showed 1,850 sq ft, close to that number."
  },
  "..."
 ],
 "missing": [
  "Whether the county requires an inspection or re-measurement to correct the recorded size.",
  "Whether 420 Fenwick Rd or 44 Abbot Ct have finished basements or additions not reflected in their per-square-foot figures.",
  "..."
 ]
}

task: case - townhouse - borderline

Input:

{
 "task": "case",
 "today": "2026-10-20",
 "owner": "Priya Calderwick",
 "place": "Unit 5, 12 Copper Row",
 "notice": "{\"assessed_value\":322000,\"assessment_level_percent\":100,\"level_entered\":true,\"assessor_market_value\":322000,\"prior_year_value\":298000,\"change_from_prior_percent\":8.1,\"tax_rate_percent\":2,\"tax_rate_source\":\"the tax bill divided by the assessed value\",\"appeal_deadline\":\"2026-10-30\",\"days_left\":10}",
 "home": "{\"record_sqft\":1240,\"measured_sqft\":\"\",\"sqft_used\":1240,\"beds\":2,\"baths\":2.5,\"year_built\":2004,\"owner_estimate\":300000}",
 "comps": "[{\"label\":\"Unit 2, 12 Copper Row\",\"kind\":\"sale\",\"sale_price\":305000,\"sale_date\":\"2026-06\",\"months_ago\":4,\"sqft\":1240,\"beds\":2,\"baths\":2.5,\"year_built\":2004,\"price_per_sqft\":246,\"adjusted_value\":305000,\"similarity\":100,\"strength\":\"strong\",\"used\":true},{\"label\":\"Unit 9, 12 Copper Row\",\"kind\":\"sale\",\"sale_price\":318000,\"sale_date\":\"2026-08\",\"months_ago\":2,\"sqft\":1260,\"beds\":2,\"baths\":2.5,\"year_built\":2004,\"price_per_sqft\":252,\"adjusted_value\":315500,\"similarity\":98,\"strength\":\"strong\",\"used\":true},\"... 1 more\"]",
 "page_figures": "{\"indicated_value\":312800,\"indicated_low\":305000,\"indicated_high\":315500,\"comps_used\":3,\"gap\":9200,\"gap_percent\":2.9,\"neighbour_median_per_sqft\":\"\",\"subject_assessed_per_sqft\":260,\"equity_indicated_assessed\":\"\",\"equity_gap_percent\":\"\",\"target_value\":313000,\"estimated_yearly_saving\":180,\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"warn\",\"text\":\"10 days left to file (deadline 2026-10-30) - file first, polish later.\"},{\"level\":\"info\",\"text\":\"The sales point to about $312,800 (range $305,000 to $315,500), 2.9% under the assessor's market value of $322,000.\"},\"... 1 more\"]",
 "page_verdict": "borderline",
 "notes": "Ours is an interior unit and backs onto the parking lot. Unit 9 is an end unit with a bigger patio."
}

Reply:

{
 "task": "case",
 "title": "Just 2.9% over three strong sales",
 "verdict": "borderline",
 "summary": "The evidence is borderline: three strong, recent sales - including two in the same building - point to about $312,800, only 2.9% ($9,200) below the assessor's market value of $322,000. That gap is real but small, which fits an informal review more than a full appeal. With only 10 days left before the October 30, 2026 deadline, file now and gather the comparable sales records afterward. This is general information, not tax or appraisal advice - check your county's own rules and process before filing.",
 "grounds": [
  {
   "ground": "market_value",
   "strength": "strong",
   "why": "Three strong recent sales - Unit 2, 12 Copper Row; Unit 9, 12 Copper Row; and 3 Tinsmith Way - adjust to about $312,800 (range $305,000 to $315,500), 2.9% below the assessor's market value of $322,000."
  }
 ],
 "comps": [
  {
   "comp": "Unit 2, 12 Copper Row",
   "use": "lead",
   "why": "Same building and same 1,240 sq ft as the home, sold for $305,000 in June 2026, a 100 similarity score with no size adjustment needed."
  },
  {
   "comp": "Unit 9, 12 Copper Row",
   "use": "lead",
   "why": "Same building, sold for $318,000 just 2 months ago; adjusted to $315,500 for its 1,260 sq ft, a 98 similarity score."
  },
  {
   "comp": "3 Tinsmith Way",
   "use": "support",
   "why": "Sold for $309,000 in April 2026 and adjusts to $312,800 for its 1,210 sq ft, a 94 similarity score."
  }
 ],
 "ask_value": 313000,
 "ask_why": "It matches the value to ask for that the three comparable sales support, the strongest evidence on hand.",
 "evidence": [
  "The assessment notice showing the $322,000 assessed value and the October 30, 2026 deadline.",
  "Sale documentation (closing statement or deed) for Unit 2, 12 Copper Row, Unit 9, 12 Copper Row and 3 Tinsmith Way.",
  "Photos showing the unit is an interior unit backing onto the parking lot, as the owner describes it.",
  "..."
 ],
 "rebuttals": [
  {
   "they_say": "The assessment only rose 8.1% from last year's $298,000.",
   "you_say": "Even so, the sales adjusted to this unit's size point to about $312,800, $9,200 below the new $322,000 figure."
  },
  "..."
 ],
 "missing": [
  "Any neighbours' assessed values per square foot, to check for uneven assessment.",
  "The owner's own measured square footage, to confirm the recorded 1,240 sq ft.",
  "..."
 ]
}

task: case - colonial - let it stand

Input:

{
 "task": "case",
 "today": "2026-10-20",
 "owner": "Sam Thistlecombe",
 "place": "5 Juniper Hill Rd",
 "notice": "{\"assessed_value\":520000,\"assessment_level_percent\":100,\"level_entered\":true,\"assessor_market_value\":520000,\"prior_year_value\":456000,\"change_from_prior_percent\":14,\"tax_rate_percent\":2.1,\"tax_rate_source\":\"entered rate\",\"appeal_deadline\":\"2026-11-30\",\"days_left\":41}",
 "home": "{\"record_sqft\":2240,\"measured_sqft\":\"\",\"sqft_used\":2240,\"beds\":4,\"baths\":2.5,\"year_built\":1994,\"owner_estimate\":480000}",
 "comps": "[{\"label\":\"11 Juniper Hill Rd\",\"kind\":\"sale\",\"sale_price\":548000,\"sale_date\":\"2026-05\",\"months_ago\":5,\"sqft\":2260,\"beds\":4,\"baths\":2.5,\"year_built\":1995,\"price_per_sqft\":242,\"adjusted_value\":545600,\"similarity\":98,\"strength\":\"strong\",\"used\":true},{\"label\":\"2 Larkspur Ct\",\"kind\":\"sale\",\"sale_price\":565000,\"sale_date\":\"2026-07\",\"months_ago\":3,\"sqft\":2310,\"beds\":4,\"baths\":2.5,\"year_built\":1997,\"price_per_sqft\":245,\"adjusted_value\":556400,\"similarity\":95,\"strength\":\"strong\",\"used\":true},\"... 2 more\"]",
 "page_figures": "{\"indicated_value\":551800,\"indicated_low\":545600,\"indicated_high\":567000,\"comps_used\":4,\"gap\":-31800,\"gap_percent\":-6.1,\"neighbour_median_per_sqft\":\"\",\"subject_assessed_per_sqft\":232,\"equity_indicated_assessed\":\"\",\"equity_gap_percent\":\"\",\"target_value\":\"\",\"estimated_yearly_saving\":\"\",\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"info\",\"text\":\"41 days left to file (deadline 2026-11-30).\"},{\"level\":\"info\",\"text\":\"The assessment rose 14% from last year ($456,000 to $520,000).\"},\"... 2 more\"]",
 "page_verdict": "let_stand",
 "notes": "The assessment jumped 14% and our taxes went up a lot. Neighbours are talking about appealing together."
}

Reply:

{
 "task": "case",
 "title": "Sales point above the assessment",
 "verdict": "let_stand",
 "summary": "The four sales used here point to about $551,800, at or above the assessor's market value of $520,000, so what's entered doesn't support a lower assessment - in some places pushing an appeal further could even end with a higher value. No neighbours' assessed values were entered, so uneven assessment can't be checked, and nothing here points to a factual error in the record. The 14% rise from last year is not, on its own, a ground for appeal. For now, the better step is to keep this year's sale records and check back next year. Rules, forms and deadlines vary by county, so check the local rules and the November 30, 2026 deadline before deciding whether to proceed.",
 "grounds": [
  {
   "ground": "market_value",
   "strength": "weak",
   "why": "The four sales used here adjust to about $551,800 at this home's size, above the assessor's market value of $520,000, so they don't show a lower value."
  }
 ],
 "comps": [
  {
   "comp": "11 Juniper Hill Rd",
   "use": "lead",
   "why": "Sold for $548,000 in 2026-05 at 2,260 sq ft ($242 per sq ft), adjusting to about $545,600 at this home's size - the closest match of the four."
  },
  {
   "comp": "2 Larkspur Ct",
   "use": "lead",
   "why": "Sold for $565,000 in 2026-07 at 2,310 sq ft ($245 per sq ft), adjusting to about $556,400 at this home's size."
  },
  {
   "comp": "27 Juniper Hill Rd",
   "use": "support",
   "why": "Sold for $541,000 in 2026-03 at 2,190 sq ft ($247 per sq ft), adjusting to about $547,200 at this home's size - the oldest of the four sales at seven months."
  },
  "..."
 ],
 "ask_value": null,
 "ask_why": "The sales point above the assessor's market value, so there's no lower figure to ask for this year.",
 "evidence": [
  "This year's sale records for 11 Juniper Hill Rd, 2 Larkspur Ct, 27 Juniper Hill Rd and 8 Larkspur Ct, to compare against next year's notice.",
  "Next year's assessment notice, to see whether the gap to these sales changes.",
  "Any neighbours' assessed values that come in, to check for uneven assessment.",
  "..."
 ],
 "rebuttals": [
  {
   "they_say": "The assessment went up 14% from last year, so it must be wrong.",
   "you_say": "The four sales used here still adjust to about $551,800, above the $520,000 assessor's market value, so the size of the increase doesn't show the value is too high."
  },
  "..."
 ],
 "missing": [
  "Neighbours' assessed values, to check whether this home is assessed higher per square foot than similar homes nearby.",
  "A measured square footage, to confirm the recorded 2,240 sq ft is correct."
 ]
}

task: hearing - bungalow - ask for a lower value

Input:

{
 "task": "hearing",
 "today": "2026-10-20",
 "owner": "Dana Fenwhistle",
 "place": "18 Linden Ave",
 "notice": "{\"assessed_value\":438000,\"assessment_level_percent\":100,\"level_entered\":true,\"assessor_market_value\":438000,\"prior_year_value\":371000,\"change_from_prior_percent\":18.1,\"tax_rate_percent\":1.9,\"tax_rate_source\":\"entered rate\",\"appeal_deadline\":\"2026-11-14\",\"days_left\":25}",
 "home": "{\"record_sqft\":1420,\"measured_sqft\":\"\",\"sqft_used\":1420,\"beds\":3,\"baths\":1.5,\"year_built\":1948,\"owner_estimate\":395000}",
 "comps": "[{\"label\":\"22 Linden Ave\",\"kind\":\"sale\",\"sale_price\":389000,\"sale_date\":\"2026-05\",\"months_ago\":5,\"sqft\":1380,\"beds\":3,\"baths\":1.5,\"year_built\":1951,\"price_per_sqft\":282,\"adjusted_value\":394600,\"similarity\":95,\"strength\":\"strong\",\"used\":true},{\"label\":\"9 Orchard St\",\"kind\":\"sale\",\"sale_price\":402500,\"sale_date\":\"2026-07\",\"months_ago\":3,\"sqft\":1460,\"beds\":3,\"baths\":2,\"year_built\":1946,\"price_per_sqft\":276,\"adjusted_value\":397000,\"similarity\":93,\"strength\":\"strong\",\"used\":true},\"... 3 more\"]",
 "page_figures": "{\"indicated_value\":395800,\"indicated_low\":384700,\"indicated_high\":402600,\"comps_used\":4,\"gap\":42200,\"gap_percent\":9.6,\"neighbour_median_per_sqft\":\"\",\"subject_assessed_per_sqft\":308,\"equity_indicated_assessed\":\"\",\"equity_gap_percent\":\"\",\"target_value\":396000,\"estimated_yearly_saving\":798,\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"info\",\"text\":\"25 days left to file (deadline 2026-11-14).\"},{\"level\":\"info\",\"text\":\"The assessment rose 18.1% from last year ($371,000 to $438,000).\"},\"... 4 more\"]",
 "page_verdict": "appeal",
 "notes": "The kitchen and the one full bath are original (1970s). The roof is 22 years old. Nothing has been added to th ... (145 characters)",
 "board": "Board of Assessment Review",
 "case_notes": "VERDICT: appeal\nASK: 396000 - This is the page's estimated value to ask for, in line with what the sales show  ... (2044 characters)"
}

Reply:

{
 "task": "hearing",
 "title": "Assessed 9.6% Above What Sales Show",
 "verdict": "request_reduction",
 "summary": "Four comparable sales near 18 Linden Ave point to a market value of about $395,800, roughly $42,200 (9.6%) below the assessor's $438,000 market value, so this letter and statement ask the Board to lower the assessment to $396,000. The three leading sales - 22 Linden Ave, 9 Orchard St and 31 Linden Ave - are close matches in size, age and location, and a fourth, 140 Mill Rd, supports the same range. These figures are the page's estimates, not an appraisal, and appeal rules, forms and deadlines vary by county, so check the local requirements before filing.",
 "subject": "Request to Reduce Assessment - 18 Linden Ave",
 "letter": "Dear Board of Assessment Review,\n\nI am writing to request a reduction in the property tax assessment for my home at 18 Linden Ave (Parcel [Parcel number]). The notice assesses the home at $438,000, an increase of 18.1% from last year's value of $371,000.\n\nThree recent sales close to my home point to a lower market value. 22 Linden Ave sold for $389,000 in 2026-05 and, adjusted to my home's size, comes to $394,600, with a similarity score of 95. 9 Orchard St sold for $402,500 in 2026-07, adjusted to $397,000, with a similarity score of 93. 31 Linden Ave, the most recent of the three, sold for $415,000 in 2026-08 and adjusted to $402,600, with a similarity score of 86. A fourth sale, 140 Mill Rd, sold for $375,000 in 2026-03 and adjusted to $384,700, though it has fewer bedrooms and bathrooms than my home. Together these sales point to about $395,800, with a range of $384,700 to $402,600 - about $42,200, or 9.6%, below the assessor's market value of $438,000.\n\n[... 6 more lines]",
 "statement": "My name is Dana Fenwhistle, and I'm the owner of the home at 18 Linden Ave. Tonight I'm asking the Board to lower the assessment to a market value of $396,000.\n\nThis year's notice set my home's market value at $438,000, up 18.1% from last year's $371,000. But recent sales nearby tell a different story. 22 Linden Ave, one of the closest matches to my home, sold for $389,000 in 2026-05 and adjusts to $394,600 for my home's size. 9 Orchard St sold for $402,500 in 2026-07, adjusting to $397,000. 31 Linden Ave, the most recent sale on my street, sold for $415,000 in 2026-08 and adjusts to $402,600. Together, these sales point to about $395,800 - roughly $42,200, or 9.6%, below the assessor's market value.\n\nThese three sales, all close matches to my home, point to a consistent range well under the assessor's figure. I'm asking the Board to set the assessment at $396,000, in line with what the sales show. Thank you for considering my request.",
 "requested_value": 396000,
 "exhibits": [
  {
   "label": "Exhibit A",
   "what": "The assessment notice, showing the assessed value of $438,000."
  },
  {
   "label": "Exhibit B",
   "what": "The sale records for 22 Linden Ave, 9 Orchard St and 31 Linden Ave."
  },
  {
   "label": "Exhibit C",
   "what": "The property record card for 18 Linden Ave."
  },
  "..."
 ],
 "questions": [
  {
   "q": "Why should the Board look at these sales instead of last year's assessed value?",
   "a": "The four comparable sales, not last year's figure, show the market value is closer to $395,800 - about $42,200 (9.6%) lower than the assessor's $438,000."
  },
  "..."
 ],
 "reminders": [
  "File the appeal by the deadline of 2026-11-14 (25 days from today).",
  "Keep copies of the notice, the sale records and the property record card for your own file.",
  "..."
 ]
}

task: hearing - ranch - ask for a correction

Input:

{
 "task": "hearing",
 "today": "2026-10-20",
 "owner": "Luis Marrowby",
 "place": "406 Fenwick Rd",
 "notice": "{\"assessed_value\":296400,\"assessment_level_percent\":50,\"level_entered\":true,\"assessor_market_value\":592800,\"prior_year_value\":281000,\"change_from_prior_percent\":5.5,\"tax_rate_percent\":4.2,\"tax_rate_source\":\"mills (per $1,000)\",\"appeal_deadline\":\"2026-12-01\",\"days_left\":42}",
 "home": "{\"record_sqft\":2150,\"measured_sqft\":1860,\"sqft_used\":1860,\"beds\":3,\"baths\":2,\"year_built\":1972,\"owner_estimate\":\"\"}",
 "comps": "[{\"label\":\"412 Fenwick Rd\",\"kind\":\"sale\",\"sale_price\":571000,\"sale_date\":\"2026-04\",\"months_ago\":6,\"sqft\":1880,\"beds\":3,\"baths\":2,\"year_built\":1970,\"price_per_sqft\":304,\"adjusted_value\":568000,\"similarity\":98,\"strength\":\"strong\",\"used\":true},{\"label\":\"38 Abbot Ct\",\"kind\":\"sale\",\"sale_price\":559000,\"sale_date\":\"2026-06\",\"months_ago\":4,\"sqft\":1820,\"beds\":3,\"baths\":2,\"year_built\":1974,\"price_per_sqft\":307,\"adjusted_value\":565100,\"similarity\":96,\"strength\":\"strong\",\"used\":true},\"... 3 more\"]",
 "page_figures": "{\"indicated_value\":568000,\"indicated_low\":565100,\"indicated_high\":584300,\"comps_used\":3,\"gap\":24800,\"gap_percent\":4.2,\"neighbour_median_per_sqft\":149,\"subject_assessed_per_sqft\":159,\"equity_indicated_assessed\":277100,\"equity_gap_percent\":6.5,\"target_value\":568000,\"estimated_yearly_saving\":521,\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"info\",\"text\":\"42 days left to file (deadline 2026-12-01).\"},{\"level\":\"fix\",\"text\":\"The record lists 2,150 sq ft; you measured 1,860 (13.5% less). A factual error is usually the simplest thing to get corrected.\"},\"... 4 more\"]",
 "page_verdict": "fix_record",
 "notes": "We measured the outside walls ourselves with a laser measure: 1,860 sq ft of finished living space. The listin ... (212 characters)",
 "board": "",
 "case_notes": "VERDICT: fix_record\nASK: 568000 - This is what the sales say the home is worth once sized correctly, and it is ... (2647 characters)"
}

Reply:

{
 "task": "hearing",
 "title": "Record overstates home by 13.5%",
 "verdict": "request_correction",
 "summary": "The property record lists 406 Fenwick Rd at 2,150 sq ft, but a laser measurement found 1,860 sq ft, a 13.5% difference, so this hearing asks the board to correct the record first. Once corrected, what the sales say - about $568,000, led by 412 Fenwick Rd and 38 Abbot Ct - and a nearby neighbour's lower per-square-foot assessment both support that market value, well under the assessor's $592,800. Check your county's specific rules and the December 1 deadline before filing.",
 "subject": "Request to correct recorded square footage at 406 Fenwick Rd",
 "letter": "Dear Board of Assessment Review,\n\nI am writing about the assessment for my home at 406 Fenwick Rd (Parcel number: [Parcel number]). The notice lists an assessed value of $296,400, which reflects an assessment level of 50% of market value, for a market value of $592,800.\n\nThe property record lists my home at 2,150 sq ft. I measured the home myself with a laser measure and found 1,860 sq ft of finished living space, a 13.5% difference. My original purchase listing also showed 1,850 sq ft, close to my own measurement. The record may be counting the enclosed back porch, which is unheated, as finished living space.\n\n[... 6 more lines]",
 "statement": "My name is Luis Marrowby, and I own the home at 406 Fenwick Rd. I'm asking the board to correct the record and set the market value at $568,000.\n\nThe property record lists my home at 2,150 sq ft, but I measured it myself with a laser measure and found 1,860 sq ft of finished living space, a 13.5% difference. My original purchase listing also showed 1,850 sq ft, close to that number. The record may be counting the enclosed back porch, which is unheated.\n\nOnce the size is corrected, the evidence points to a lower value. 412 Fenwick Rd, 98% similar to my home, sold six months ago for $571,000, which adjusts to $568,000 at my home's size. 38 Abbot Ct, 96% similar, sold four months ago and adjusts to $565,100. A neighbour at 44 Abbot Ct, 98% similar, is assessed at $150 per square foot, well below my home's $159.\n\n[... 1 more lines]",
 "requested_value": 568000,
 "exhibits": [
  {
   "label": "Exhibit A",
   "what": "The assessment notice, showing the assessed value, assessment level and assessor's market value."
  },
  {
   "label": "Exhibit B",
   "what": "The property record card, showing the recorded 2,150 sq ft."
  },
  {
   "label": "Exhibit C",
   "what": "The laser measurement showing 1,860 sq ft of finished living space."
  },
  "..."
 ],
 "questions": [
  {
   "q": "How was the 1,860 sq ft figure measured?",
   "a": "With a laser measure of the exterior walls; the original purchase listing also showed 1,850 sq ft, close to that figure."
  },
  "..."
 ],
 "reminders": [
  "File before the December 1, 2026 deadline - 42 days remain as of today.",
  "Keep copies of the notice, measurement, and sale records for your own records.",
  "..."
 ]
}

task: hearing - townhouse - informal review

Input:

{
 "task": "hearing",
 "today": "2026-10-20",
 "owner": "Priya Calderwick",
 "place": "Unit 5, 12 Copper Row",
 "notice": "{\"assessed_value\":322000,\"assessment_level_percent\":100,\"level_entered\":true,\"assessor_market_value\":322000,\"prior_year_value\":298000,\"change_from_prior_percent\":8.1,\"tax_rate_percent\":2,\"tax_rate_source\":\"the tax bill divided by the assessed value\",\"appeal_deadline\":\"2026-10-30\",\"days_left\":10}",
 "home": "{\"record_sqft\":1240,\"measured_sqft\":\"\",\"sqft_used\":1240,\"beds\":2,\"baths\":2.5,\"year_built\":2004,\"owner_estimate\":300000}",
 "comps": "[{\"label\":\"Unit 2, 12 Copper Row\",\"kind\":\"sale\",\"sale_price\":305000,\"sale_date\":\"2026-06\",\"months_ago\":4,\"sqft\":1240,\"beds\":2,\"baths\":2.5,\"year_built\":2004,\"price_per_sqft\":246,\"adjusted_value\":305000,\"similarity\":100,\"strength\":\"strong\",\"used\":true},{\"label\":\"Unit 9, 12 Copper Row\",\"kind\":\"sale\",\"sale_price\":318000,\"sale_date\":\"2026-08\",\"months_ago\":2,\"sqft\":1260,\"beds\":2,\"baths\":2.5,\"year_built\":2004,\"price_per_sqft\":252,\"adjusted_value\":315500,\"similarity\":98,\"strength\":\"strong\",\"used\":true},\"... 1 more\"]",
 "page_figures": "{\"indicated_value\":312800,\"indicated_low\":305000,\"indicated_high\":315500,\"comps_used\":3,\"gap\":9200,\"gap_percent\":2.9,\"neighbour_median_per_sqft\":\"\",\"subject_assessed_per_sqft\":260,\"equity_indicated_assessed\":\"\",\"equity_gap_percent\":\"\",\"target_value\":313000,\"estimated_yearly_saving\":180,\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"warn\",\"text\":\"10 days left to file (deadline 2026-10-30) - file first, polish later.\"},{\"level\":\"info\",\"text\":\"The sales point to about $312,800 (range $305,000 to $315,500), 2.9% under the assessor's market value of $322,000.\"},\"... 1 more\"]",
 "page_verdict": "borderline",
 "notes": "Ours is an interior unit and backs onto the parking lot. Unit 9 is an end unit with a bigger patio.",
 "board": "",
 "case_notes": "VERDICT: borderline\nASK: 313000 - It matches the value to ask for that the three comparable sales support, the ... (1887 characters)"
}

Reply:

{
 "task": "hearing",
 "title": "Assessed about 2.9% above comparable sales",
 "verdict": "informal_review",
 "summary": "Three comparable sales - Unit 2, 12 Copper Row; Unit 9, 12 Copper Row; and 3 Tinsmith Way - point to about $312,800 for this home, roughly 2.9% below the $322,000 assessed value, so this is set up as a request for an informal review rather than a full appeal. Unit 2 and Unit 9 are the strongest, most similar sales, with 3 Tinsmith Way supporting them. These figures are the page's estimates, not an appraisal, and the owner should check the county's own rules, forms and the October 30, 2026 deadline before filing.",
 "subject": "Informal Review Request - Unit 5, 12 Copper Row Assessment",
 "letter": "Dear Board of Assessment Review,\n\nI am writing to request an informal review of the assessment for my home at Unit 5, 12 Copper Row (Parcel number: [Parcel number]), currently assessed at $322,000, an increase of 8.1% over last year's $298,000.\n\nThree recent sales support a lower value. Unit 2, 12 Copper Row is the same 1,240 square feet as my home and sold for $305,000 in June 2026, needing no size adjustment. Unit 9, 12 Copper Row sold for $318,000 two months ago; adjusted to my home's size, that sale points to about $315,500. 3 Tinsmith Way sold for $309,000 in April 2026 and adjusts to about $312,800 for its size. Together these three sales point to a value of about $312,800, a range of $305,000 to $315,500, roughly $9,200 below the current assessed value.\n\n[... 6 more lines]",
 "statement": "My name is Priya Calderwick. I own Unit 5, 12 Copper Row, currently assessed at $322,000, and I'm asking the Board to set a market value of $313,000.\n\nThree recent sales support this number. Unit 2, 12 Copper Row is the same 1,240 square feet as my home and sold for $305,000 in June 2026 - no size adjustment needed. Unit 9, 12 Copper Row sold for $318,000 just two months ago; adjusted to my home's 1,240 square feet, that sale points to about $315,500. A third sale, 3 Tinsmith Way, sold for $309,000 in April 2026 and adjusts to about $312,800 for its size. Together, these sales point to a value of about $312,800, a range of $305,000 to $315,500 - roughly $9,200 below my current assessed value of $322,000.\n\nBased on this evidence, I'm asking the Board to set a market value of $313,000 for my home. Thank you.",
 "requested_value": 313000,
 "exhibits": [
  {
   "label": "Exhibit A",
   "what": "Sale record for Unit 2, 12 Copper Row (sold $305,000, June 2026)"
  },
  {
   "label": "Exhibit B",
   "what": "Sale record for Unit 9, 12 Copper Row (sold $318,000, August 2026)"
  },
  {
   "label": "Exhibit C",
   "what": "Sale record for 3 Tinsmith Way (sold $309,000, April 2026)"
  },
  "..."
 ],
 "questions": [
  {
   "q": "Why rely on sales from the same building?",
   "a": "Unit 2 and Unit 9 are in the same building as this home and match closely in size, beds and baths; Unit 2 is the exact 1,240 sq ft and needed no size adjustment."
  },
  "..."
 ],
 "reminders": [
  "File before the October 30, 2026 deadline - only 10 days remain.",
  "Keep copies of all sale records and the assessment notice for your own file.",
  "..."
 ]
}

task: hearing - colonial - no appeal

Input:

{
 "task": "hearing",
 "today": "2026-10-20",
 "owner": "Sam Thistlecombe",
 "place": "5 Juniper Hill Rd",
 "notice": "{\"assessed_value\":520000,\"assessment_level_percent\":100,\"level_entered\":true,\"assessor_market_value\":520000,\"prior_year_value\":456000,\"change_from_prior_percent\":14,\"tax_rate_percent\":2.1,\"tax_rate_source\":\"entered rate\",\"appeal_deadline\":\"2026-11-30\",\"days_left\":41}",
 "home": "{\"record_sqft\":2240,\"measured_sqft\":\"\",\"sqft_used\":2240,\"beds\":4,\"baths\":2.5,\"year_built\":1994,\"owner_estimate\":480000}",
 "comps": "[{\"label\":\"11 Juniper Hill Rd\",\"kind\":\"sale\",\"sale_price\":548000,\"sale_date\":\"2026-05\",\"months_ago\":5,\"sqft\":2260,\"beds\":4,\"baths\":2.5,\"year_built\":1995,\"price_per_sqft\":242,\"adjusted_value\":545600,\"similarity\":98,\"strength\":\"strong\",\"used\":true},{\"label\":\"2 Larkspur Ct\",\"kind\":\"sale\",\"sale_price\":565000,\"sale_date\":\"2026-07\",\"months_ago\":3,\"sqft\":2310,\"beds\":4,\"baths\":2.5,\"year_built\":1997,\"price_per_sqft\":245,\"adjusted_value\":556400,\"similarity\":95,\"strength\":\"strong\",\"used\":true},\"... 2 more\"]",
 "page_figures": "{\"indicated_value\":551800,\"indicated_low\":545600,\"indicated_high\":567000,\"comps_used\":4,\"gap\":-31800,\"gap_percent\":-6.1,\"neighbour_median_per_sqft\":\"\",\"subject_assessed_per_sqft\":232,\"equity_indicated_assessed\":\"\",\"equity_gap_percent\":\"\",\"target_value\":\"\",\"estimated_yearly_saving\":\"\",\"figures_are_estimates\":true}",
 "page_flags": "[{\"level\":\"info\",\"text\":\"41 days left to file (deadline 2026-11-30).\"},{\"level\":\"info\",\"text\":\"The assessment rose 14% from last year ($456,000 to $520,000).\"},\"... 2 more\"]",
 "page_verdict": "let_stand",
 "notes": "The assessment jumped 14% and our taxes went up a lot. Neighbours are talking about appealing together.",
 "board": "",
 "case_notes": "VERDICT: let_stand\nGROUND (weak) market value: The four sales used here adjust to about $551,800 at this home' ... (1976 characters)"
}

Reply:

{
 "task": "hearing",
 "title": "Sales point above the assessment",
 "verdict": "no_appeal",
 "summary": "The sales near 5 Juniper Hill Rd say about $551,800 at this home's size, ranging from $545,600 to $567,000, at or above the assessor's market value of $520,000, so there isn't a case for a lower value this year. No neighbours' assessed values were entered to check for uneven assessment, and the 14% rise from last year isn't itself a ground. Check your county's rules before deciding whether to request the property records below.",
 "subject": "Request for property records - 5 Juniper Hill Rd",
 "letter": "Dear Board of Assessment Review,\n\nI am writing about the property at 5 Juniper Hill Rd, [Parcel number], assessed at $520,000 for this year, up from $456,000 last year. Four recent nearby sales - 11 Juniper Hill Rd, 2 Larkspur Ct, 27 Juniper Hill Rd, and 8 Larkspur Ct - adjusted to this home's size, say about $551,800, ranging from $545,600 to $567,000, at or above the current assessment. Based on this, I am not asking to have the assessed value lowered at this time.\n\nI would like to request a copy of the property record card for 5 Juniper Hill Rd, [Parcel number], to confirm the recorded size, bedrooms, and bathrooms, and a list of the sales the assessor relied on in setting this year's value, so I can check them for myself. Having these on hand will let me compare them against the sales listed above and confirm the record is accurate.\n\n[... 4 more lines]",
 "statement": "This year, the recent sales near our home were compared against our assessment. Four of them - 11 Juniper Hill Rd, 2 Larkspur Ct, 27 Juniper Hill Rd, and 8 Larkspur Ct - adjust to about $545,600 to $567,000 for a home our size, which is at or above our assessed value of $520,000. Because of that, the sales don't support asking for a lower value this year, even though our assessment rose 14% from last year. If neighbours' assessed values come in showing we're assessed higher per square foot than similar homes nearby, that could change things next year.",
 "requested_value": null,
 "exhibits": [
  {
   "label": "Exhibit A",
   "what": "The property record card for 5 Juniper Hill Rd, [Parcel number], to confirm the recorded size, beds and baths."
  },
  {
   "label": "Exhibit B",
   "what": "The list of sales the assessor used in setting this year's assessed value, to compare against the four sales already reviewed."
  }
 ],
 "questions": [
  {
   "q": "Why isn't the 14% increase from last year, by itself, a reason to appeal?",
   "a": "The four sales used here still adjust to about $551,800 at this home's size, above the $520,000 assessor's market value, so the size of the increase doesn't show the value is too high."
  },
  "..."
 ],
 "reminders": [
  "Check your county's rules and any form needed to request the property record card and the sales the assessor used.",
  "If neighbours' assessed values come in, that could support a different look at this assessment next year.",
  "..."
 ]
}

Build the input yourself

Load the script in node (global.window = {}; require("./assesskit.js")), then:

const K = AssessKit;
const form = { assessed: "438,000", level: "100", tax_rate: "1.9", record_sqft: "1420", beds: "3", baths: "1.5", year_built: "1948",
  comps: "22 Linden Ave | $389,000 | 2026-05 | 1,380 sq ft | 3 bd | 1.5 ba | 1951\n9 Orchard St | $402,500 | 2026-07 | 1,460 sq ft | 3 bd | 2 ba | 1946" };
const st = K.state(form, "2026-10-20");             // assessor's value, ranked comps, what the sales say, flags, verdict
console.log(st.S.mv, st.I.value, st.target, st.saving, st.verdict);
const wire = K.toWire(K.buildInput(st, "case").input);   // POST this to /estimate and /run
// letter lane: set form.case_notes = K.caseToText(caseReply), recompute the state, then buildInput(st, "hearing")
// later: const reply = K.normalize(K.parseReply(job.output.output), "case");
// const { notes } = K.check(reply, st, "case");

Step 1 — a tiny client helper

One function that sends JSON and unwraps the envelope. 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://assessed-too-high.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":"assessed-too-high"}' | 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": "case", "today": "2026-10-20", "owner": "Dana Fenwhistle", "place": "18 Linden Ave (made-up)", "notice": "{...}", "home": "{...}", "comps": "[...]", "page_figures": "{...}", "page_flags": "[...]", "page_verdict": "appeal", "notes": "The kitchen and the one full bath are original ..."}
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 assessed-too-high:<task>:<inputHash>:a<attempt> (the examples below use the case lane), and its one reformat retry (with retry_note added) is attempt 2, a new key and a second run. The job's output.output is the reply text; truncated: true means the balance cut it short.

KEY="assessed-too-high:case:$(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}' 

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: assessed-too-high:case:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json