← Drench Room
API
Tokens

Drive Drench Room from your own code

Both metered steps - the drench plan and the job takeoff - are available over HTTP. A natural use is a paint-visualiser or renovation tool that already knows a room and a colour: your code sends the page's figures and shows the cited advice.

The split first: the page does the measuring; the model gives the judgement; the page checks it. The colour analysis, the tonal ladder, the areas, the cans, the hours and the flags come from drenchkit.js, which runs in node as well as in the browser. Its reconcile function then checks every cited id, that no colour outside the ladder slipped in, that the plan covers each surface in scope exactly once and its verdict matches its surfaces, that a takeoff buys every can and never less than the page computes, paints the ceiling before the walls, lands near the page's hours, and quotes no money when no price was entered.

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":"drench-room"}), 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 a required field 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 tasks 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, which routes the one system prompt to one of two contracts:

taskWhat it returnsVerdict field
planA title, a summary, a colour_read line; surfaces [{surface, step, sheen, why}] - one per surface in scope, step -2..2 or "off"; 1–3 light and risks lines; 2–3 styling tips; caveats.verdict: full, tonal, partial
takeoffA title, a summary; cans [{can_id, gallons, why}] - every can on the page; 4–8 supplies [{item, qty, why}]; ordered steps [{order, task, surface, hours, cite}]; a budget line; risks; tips; caveats.verdict: diy_weekend, diy_multi_day, hire_pro

A line is always {text, cite}: one or two plain sentences, and the ids they rest on - ladder steps T-2 T-1 T0 T+1 T+2, C-lrv C-family, room facts R-facing R-height R-size, light swatches L-day L-dusk L-lamp, areas A-walls A-ceiling A-trim A-doors A-builtins A-total, cans P0 P1…, hours H-prep H-primer H-ceiling H-walls H-trim H-doors H-builtins H-total, the paint cost M-total, and flags F-primer F-tall F-low F-north-deep F-no-daylight F-gloss-walls F-soft-trim F-vivid F-big F-walls-only F-long.

The declared input schema carries scalars only, so object-valued fields travel JSON-encoded as strings (DrenchKit.toWire does this). task, room, colour and facts are required.

Input fields

FieldTypeNotes
taskstringplan or takeoff.
roomstring (JSON){name, unit, length_ft, width_ft, height_ft, doors, windows, facing, current_walls, scope[], facts[]}.
colourstring (JSON){hex, label, family, value, lrv, oklch, ladder[], light[], facts[]} from DrenchKit.analyzeColour and lightStrip.
factsstring (JSON){areas[], assignment, cans[], primer, hours[], days, cost, flags[]} from DrenchKit.analyze.
planstring (JSON)takeoff only, optional: {verdict, summary, surfaces} from an earlier plan; apply it to the assignment first (DrenchKit.applyPlan).
notestringOptional; over 800 characters keeps the start and the end around a marker.
retry_notestringOnly on a reformat retry.

The reply

The job's output.output is a string holding one JSON object. Parse it with DrenchKit.parseReply, then normalize, then check it with reconcile(reply, {stats, plan}). applyPlan(assignment, reply) turns a plan into the surface assignment a takeoff then prices.

Worked examples

Replies produced against the app's prompt for the three sample rooms (lists shortened; the full replies ship in example-result.js). The page replays each of them free from its sample buttons. Inputs are shown with the ladder, areas and hours folded.

task: plan - Sage bedroom (sample room) (full)

Input:

{
 "task": "plan",
 "room": "{\"name\":\"Main bedroom\",\"unit\":\"ft\",\"length_ft\":13,\"width_ft\":12,\"height_ft\":8,\"doors\":1,\"windows\":2,\"facing\":\"east\",\"current_walls\":\"light\",\"scope\":[\"walls\",\"ceiling\",\"trim\",\"doors\"],\"facts\":[{\"id\":\"R-facing\",\"text\":\"east-facing windows\"},{\"id\":\"R-height\",\"text\":\"ceiling 8 ft\"},{\"id\":\"R-size\",\"text\":\"13 ft x 12 ft floor\"}]}",
 "colour": "{\"hex\":\"#8a9a7b\",\"label\":\"soft sage\",\"family\":\"muted green\",\"value\":\"mid\",\"lrv\":29.9,\"oklch\":{\"l\":0.665,\"c\":0.048,\"h\":129.9},\"ladder\":[{\"id\":\"T0\",\"step\":0,\"name\":\"base\",\"hex\":\"#8a9a7b\",\"lrv\":29.9},\"... T-2, T-1, T+1, T+2 in the same shape\"],\"light\":[{\"id\":\"L-day\",\"label\":\"Daylight, east-facing\",\"hex\":\"#889778\"},\"...\"],\"facts\":[{\"id\":\"C-lrv\",\"text\":\"approximate LRV 29.9 (mid)\"},{\"id\":\"C-family\",\"text\":\"muted green\"}]}",
 "facts": "{\"areas\":[{\"id\":\"A-walls\",\"text\":\"356 sq ft\",\"sqft\":356},\"...\"],\"assignment\":{\"walls\":{\"on\":true,\"step\":0,\"sheen\":\"matte\"},\"ceiling\":{\"on\":true,\"step\":0,\"sheen\":\"flat\"},\"trim\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"},\"doors\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"}},\"cans\":[{\"id\":\"P1\",\"sheen\":\"matte\",\"step\":\"T0\",\"surfaces\":[\"walls\"],\"area_sqft\":356,\"coats\":2,\"gallons\":2.03,\"buy\":\"2 gal + 1 qt matte, base\",\"buy_gallons\":2.25,\"litres\":8.5},\"...\"],\"primer\":false,\"hours\":[{\"id\":\"H-total\",\"label\":\"Total working hours\",\"h\":15.7}],\"days\":2,\"cost\":{\"id\":\"M-total\",\"total\":223,\"text\":\"about $223 of paint at $55 a gallon (quarts at 35% of a gallon, primer at 70%)\"},\"flags\":[]}",
 "note": "I want the full enveloped look - everything the same green, nothing white. I can paint one weekend."
}

Reply:

{
 "task": "plan",
 "verdict": "full",
 "title": "Full sage envelope for the main bedroom",
 "summary": "This plan carries soft sage (T0) across every surface in scope - walls, ceiling, trim and doors - for the fully enveloped, no-white look you asked for. At a mid LRV in the muted green family, the colour stays calm and grounded rather than heavy, and the east-facing light keeps it fresh through the day. With everything matching, sheen does the work of separating surfaces: matte walls and ceiling, satin trim and doors for durability.",
 "colour_read": {
  "text": "Soft sage sits at a mid LRV (about 29.9) in the muted green family, so it reads as calm and grounded rather than dark or vivid. With east-facing windows, this room gets soft morning light that should keep the colour fresh rather than muddy through the day.",
  "cite": [
   "C-lrv",
   "C-family",
   "R-facing"
  ]
 },
 "surfaces": [
  {
   "surface": "walls",
   "step": 0,
   "sheen": "matte",
   "why": "Base T0 on the walls delivers the full enveloped look you want - matte keeps the colour flat and rich with no sheen to break the effect."
  },
  {
   "surface": "ceiling",
   "step": 0,
   "sheen": "flat",
   "why": "Carrying T0 onto the ceiling continues the wrap overhead so nothing white interrupts the room, and flat hides minor surface texture."
  },
  "..."
 ],
 "light": [
  {
   "text": "In daytime, the east-facing light keeps the sage close to true - fresh, with a touch of coolness in the morning.",
   "cite": [
    "L-day",
    "R-facing"
   ]
  },
  {
   "text": "At dusk with lamps off, the colour sinks toward its deeper, more muted side.",
   "cite": [
    "L-dusk"
   ]
  },
  "..."
 ],
 "risks": [
  {
   "text": "With walls, ceiling, trim and doors all the same T0 green, there is no colour break to disguise an uneven line where wall meets ceiling or trim - that cut line needs to be painted carefully.",
   "cite": [
    "A-walls",
    "A-ceiling",
    "A-trim",
    "T0"
   ]
  },
  {
   "text": "A single enveloping hue also shows every wall flaw, like dents or patch marks, more than a contrasting trim would, since nothing else draws the eye.",
   "cite": [
    "A-walls",
    "T0"
   ]
  },
  "..."
 ],
 "styling": [
  "Lean on warm woods like oak or walnut so the room doesn't feel cool against the green.",
  "Brass or other warm-toned metal hardware and fixtures pair well with a muted green envelope.",
  "..."
 ],
 "caveats": [
  "Screen colours are approximate; test a real sample of this green on two walls in different light before committing.",
  "This plan assumes sound, crack-free walls and trim - condition wasn't assessed here."
 ]
}

task: takeoff - Sage bedroom (sample room) (diy_weekend)

Input:

{
 "task": "takeoff",
 "room": "{\"name\":\"Main bedroom\",\"unit\":\"ft\",\"length_ft\":13,\"width_ft\":12,\"height_ft\":8,\"doors\":1,\"windows\":2,\"facing\":\"east\",\"current_walls\":\"light\",\"scope\":[\"walls\",\"ceiling\",\"trim\",\"doors\"],\"facts\":[{\"id\":\"R-facing\",\"text\":\"east-facing windows\"},{\"id\":\"R-height\",\"text\":\"ceiling 8 ft\"},{\"id\":\"R-size\",\"text\":\"13 ft x 12 ft floor\"}]}",
 "colour": "{\"hex\":\"#8a9a7b\",\"label\":\"soft sage\",\"family\":\"muted green\",\"value\":\"mid\",\"lrv\":29.9,\"oklch\":{\"l\":0.665,\"c\":0.048,\"h\":129.9},\"ladder\":[{\"id\":\"T0\",\"step\":0,\"name\":\"base\",\"hex\":\"#8a9a7b\",\"lrv\":29.9},\"... T-2, T-1, T+1, T+2 in the same shape\"],\"light\":[{\"id\":\"L-day\",\"label\":\"Daylight, east-facing\",\"hex\":\"#889778\"},\"...\"],\"facts\":[{\"id\":\"C-lrv\",\"text\":\"approximate LRV 29.9 (mid)\"},{\"id\":\"C-family\",\"text\":\"muted green\"}]}",
 "facts": "{\"areas\":[{\"id\":\"A-walls\",\"text\":\"356 sq ft\",\"sqft\":356},\"...\"],\"assignment\":{\"walls\":{\"on\":true,\"step\":0,\"sheen\":\"matte\"},\"ceiling\":{\"on\":true,\"step\":0,\"sheen\":\"flat\"},\"trim\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"},\"doors\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"}},\"cans\":[{\"id\":\"P1\",\"sheen\":\"matte\",\"step\":\"T0\",\"surfaces\":[\"walls\"],\"area_sqft\":356,\"coats\":2,\"gallons\":2.03,\"buy\":\"2 gal + 1 qt matte, base\",\"buy_gallons\":2.25,\"litres\":8.5},\"...\"],\"primer\":false,\"hours\":[{\"id\":\"H-total\",\"label\":\"Total working hours\",\"h\":15.7}],\"days\":2,\"cost\":{\"id\":\"M-total\",\"total\":223,\"text\":\"about $223 of paint at $55 a gallon (quarts at 35% of a gallon, primer at 70%)\"},\"flags\":[]}",
 "plan": "{\"verdict\":\"full\",\"summary\":\"This plan carries soft sage (T0) across every surface in scope - walls, ceiling, trim and doors - for the fully enveloped, no-white look you asked for. At a mid LRV in the muted green family, the colour stays calm and grounded rather than heavy, and the east-facing light keeps it fresh through the day. With everything matching, sheen does the work of separating surfaces: matte walls and ceiling, satin trim and doors for durability.\",\"surfaces\":[{\"surface\":\"walls\",\"step\":0,\"sheen\":\"matte\",\"why\":\"Base T0 on the walls delivers the full enveloped look you want - matte keeps the colour flat and rich with no sheen to break the effect.\"},\"...\"]}",
 "note": "I want the full enveloped look - everything the same green, nothing white. I can paint one weekend."
}

Reply:

{
 "task": "takeoff",
 "verdict": "diy_weekend",
 "title": "Full Sage Takeoff: One Weekend, Four Surfaces",
 "summary": "This takeoff turns the full-envelope soft sage (T0) plan into a buying list and schedule for the walls, ceiling, trim and doors. At about 15.7 working hours over 2 days with no primer coat needed, it's a comfortable DIY weekend project.",
 "cans": [
  {
   "can_id": "P1",
   "gallons": 2.25,
   "why": "Covers two coats on all 356 sq ft of wall in T0 matte; the extra quart avoids running short mid-coat."
  },
  {
   "can_id": "P2",
   "gallons": 1,
   "why": "One gallon of T0 flat covers the two coats needed on the 156 sq ft ceiling with a little left over."
  },
  "..."
 ],
 "supplies": [
  {
   "item": "9-inch roller frame with 3/8-inch nap covers",
   "qty": "2 frames, 4 naps",
   "why": "keeps the ceiling flat and wall matte finishes even across two coats each"
  },
  {
   "item": "angled sash brush, 2 to 2.5 inch",
   "qty": "1",
   "why": "cuts in corners and edges, and brushes the trim and doors in satin"
  },
  "..."
 ],
 "steps": [
  {
   "order": 1,
   "task": "Fill nail holes and dings, sand smooth, tape off trim and the ceiling line, and cover the floor and furniture.",
   "surface": "prep",
   "hours": 4.1,
   "cite": [
    "H-prep"
   ]
  },
  {
   "order": 2,
   "task": "Cut in and roll two coats of T0 flat on the ceiling, letting the first coat dry before recoating.",
   "surface": "ceiling",
   "hours": 2.6,
   "cite": [
    "H-ceiling"
   ]
  },
  "..."
 ],
 "budget": {
  "text": "About $223 for all the paint, figured at $55 a gallon with quarts priced at 35% of a gallon.",
  "cite": [
   "M-total"
  ]
 },
 "risks": [
  {
   "text": "Walls, ceiling and trim are all the same T0 green, so the cut line where wall meets ceiling is the only visual break in the room - keep it straight, since there's no contrasting trim colour to hide a wobble.",
   "cite": [
    "T0",
    "A-walls",
    "A-ceiling"
   ]
  },
  {
   "text": "Two coats across three different sheens (matte walls, flat ceiling, satin trim and doors) means several drying windows - plan recoat gaps so the 15.7 hours of work isn't rushed into one sitting.",
   "cite": [
    "H-total",
    "H-walls",
    "H-ceiling",
    "H-trim",
    "H-doors"
   ]
  },
  "..."
 ],
 "tips": [
  "Paint the ceiling first, then walls, then trim and doors last so any drips land on surfaces you haven't finished yet.",
  "Keep a wet edge on the walls and work in sections to avoid lap marks in this solid colour.",
  "..."
 ],
 "caveats": [
  "The quoted hours assume steady, uninterrupted work; add time if you're newer to painting or taking breaks between coats.",
  "Gallon amounts match the listed coats - buy a little extra if your walls or trim are more textured or porous than assumed."
 ]
}

task: plan - Navy study (sample room) (tonal)

Input:

{
 "task": "plan",
 "room": "{\"name\":\"Box-room study\",\"unit\":\"ft\",\"length_ft\":10,\"width_ft\":9,\"height_ft\":8,\"doors\":1,\"windows\":1,\"facing\":\"north\",\"current_walls\":\"light\",\"scope\":[\"walls\",\"ceiling\",\"trim\",\"doors\",\"builtins\"],\"facts\":[{\"id\":\"R-facing\",\"text\":\"north-facing windows\"},{\"id\":\"R-height\",\"text\":\"ceiling 8 ft\"},{\"id\":\"R-size\",\"text\":\"10 ft x 9 ft floor\"}]}",
 "colour": "{\"hex\":\"#2e3a55\",\"label\":\"ink navy\",\"family\":\"muted blue\",\"value\":\"very deep\",\"lrv\":4.3,\"oklch\":{\"l\":0.35,\"c\":0.05,\"h\":265.5},\"ladder\":[{\"id\":\"T0\",\"step\":0,\"name\":\"base\",\"hex\":\"#2e3a55\",\"lrv\":4.3},\"... T-2, T-1, T+1, T+2 in the same shape\"],\"light\":[{\"id\":\"L-day\",\"label\":\"Daylight, north-facing\",\"hex\":\"#283451\"},\"...\"],\"facts\":[{\"id\":\"C-lrv\",\"text\":\"approximate LRV 4.3 (very deep)\"},{\"id\":\"C-family\",\"text\":\"muted blue\"}]}",
 "facts": "{\"areas\":[{\"id\":\"A-walls\",\"text\":\"272 sq ft\",\"sqft\":272},\"...\"],\"assignment\":{\"walls\":{\"on\":true,\"step\":0,\"sheen\":\"matte\"},\"ceiling\":{\"on\":true,\"step\":0,\"sheen\":\"flat\"},\"trim\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"},\"doors\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"},\"builtins\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"}},\"cans\":[{\"id\":\"P1\",\"sheen\":\"matte\",\"step\":\"T0\",\"surfaces\":[\"walls\"],\"area_sqft\":272,\"coats\":2,\"gallons\":1.55,\"buy\":\"2 gal matte, base\",\"buy_gallons\":2,\"litres\":7.6},\"...\"],\"primer\":true,\"hours\":[{\"id\":\"H-total\",\"label\":\"Total working hours\",\"h\":15.8}],\"days\":2,\"cost\":{\"id\":\"M-total\",\"total\":333,\"text\":\"about $333 of paint at $68 a gallon (quarts at 35% of a gallon, primer at 70%)\"},\"flags\":[{\"id\":\"F-primer\",\"text\":\"The colour is very deep and the walls are light now - a tinted primer coat first saves a third coat.\"},{\"id\":\"F-north-deep\",\"text\":\"A very deep colour in a north-facing room reads darker and cooler than the chip all day.\"}]}",
 "note": "Small and dark already. I want it cosy like a library, not a cave. Shelves along one wall. Evenings only, a couple of hours at a time."
}

Reply:

{
 "task": "plan",
 "verdict": "tonal",
 "title": "A cosy, library-deep navy for the box-room study",
 "summary": "Keep ink navy as the one colour running through the room, but tune it so it reads as a library, not a cave: the walls lift one step to T+1 and the ceiling two steps to T+2 so the north light doesn't flatten them, while trim, doors and the shelving wall deepen to T-1 for crisp, bookish contrast. Every surface in scope stays in the navy family - nothing goes bright white - so the small room still reads as one confident, warm-lit colour story.",
 "colour_read": {
  "text": "Ink navy is a muted, very deep blue - approximate LRV 4.3 - that behaves more like an ink-black than a true blue in most light. In a north-facing room like this one, a colour this deep tends to read even cooler and flatter than the chip all day, which is the main thing this plan works around.",
  "cite": [
   "C-lrv",
   "C-family",
   "R-facing",
   "F-north-deep"
  ]
 },
 "surfaces": [
  {
   "surface": "walls",
   "step": 1,
   "sheen": "matte",
   "why": "One step up to T+1 keeps the moody, library-navy feel the note asks for while giving the north light enough reflectance that the room doesn't read as a cave; matte hides the inevitable wall imperfections a deep colour shows up."
  },
  {
   "surface": "ceiling",
   "step": 2,
   "sheen": "flat",
   "why": "The ceiling is the surface you look at least directly, so it can carry the biggest lift - T+2 bounces more light back down into a room with no south or west sun, raising the sense of height without touching the walls' depth."
  },
  "..."
 ],
 "light": [
  {
   "text": "Through the day, north light (L-day) pulls the base navy even cooler and a touch darker than the chip - expect a steady, muted blue rather than anything vivid.",
   "cite": [
    "L-day",
    "R-facing"
   ]
  },
  {
   "text": "At dusk with no lamps on (L-dusk), the room goes nearly black-navy; that's the point it will feel darkest, right before the lights go on.",
   "cite": [
    "L-dusk"
   ]
  },
  "..."
 ],
 "risks": [
  {
   "text": "A very deep navy in a north-facing room can flatten into a cave without help - that's the reason the walls move up to T+1 and the ceiling to T+2 instead of staying at the base shade.",
   "cite": [
    "F-north-deep",
    "T+1",
    "T+2"
   ]
  },
  {
   "text": "Trim, doors and built-ins step down to T-1 while the walls step up, so the line where they meet needs a careful, taped cut - a wavering hand there will read as a mistake instead of intentional contrast.",
   "cite": [
    "T-1",
    "T+1",
    "A-trim"
   ]
  },
  "..."
 ],
 "styling": [
  "Lean on warm metals - brass or aged brass - for hardware, shelf brackets and a picture light on the built-ins; warm metal against a cool navy is a classic library pairing.",
  "Keep bulbs warm, around 2700K, on the shelves and overhead, since lamp light is what this room will mostly be seen in.",
  "..."
 ],
 "caveats": [
  "This hex and ladder are read from a screen colour - tape up real samples of T0, T+1 and T-1 on two walls and check them in daylight, at dusk and under lamp light before buying anything.",
  "The condition and current finish of the walls, trim and built-ins aren't known from here - rough patches or an existing glossy coat change the prep, which the takeoff should cover."
 ]
}

task: takeoff - Navy study (sample room) (diy_multi_day)

Input:

{
 "task": "takeoff",
 "room": "{\"name\":\"Box-room study\",\"unit\":\"ft\",\"length_ft\":10,\"width_ft\":9,\"height_ft\":8,\"doors\":1,\"windows\":1,\"facing\":\"north\",\"current_walls\":\"light\",\"scope\":[\"walls\",\"ceiling\",\"trim\",\"doors\",\"builtins\"],\"facts\":[{\"id\":\"R-facing\",\"text\":\"north-facing windows\"},{\"id\":\"R-height\",\"text\":\"ceiling 8 ft\"},{\"id\":\"R-size\",\"text\":\"10 ft x 9 ft floor\"}]}",
 "colour": "{\"hex\":\"#2e3a55\",\"label\":\"ink navy\",\"family\":\"muted blue\",\"value\":\"very deep\",\"lrv\":4.3,\"oklch\":{\"l\":0.35,\"c\":0.05,\"h\":265.5},\"ladder\":[{\"id\":\"T0\",\"step\":0,\"name\":\"base\",\"hex\":\"#2e3a55\",\"lrv\":4.3},\"... T-2, T-1, T+1, T+2 in the same shape\"],\"light\":[{\"id\":\"L-day\",\"label\":\"Daylight, north-facing\",\"hex\":\"#283451\"},\"...\"],\"facts\":[{\"id\":\"C-lrv\",\"text\":\"approximate LRV 4.3 (very deep)\"},{\"id\":\"C-family\",\"text\":\"muted blue\"}]}",
 "facts": "{\"areas\":[{\"id\":\"A-walls\",\"text\":\"272 sq ft\",\"sqft\":272},\"...\"],\"assignment\":{\"walls\":{\"on\":true,\"step\":1,\"sheen\":\"matte\"},\"ceiling\":{\"on\":true,\"step\":2,\"sheen\":\"flat\"},\"trim\":{\"on\":true,\"step\":-1,\"sheen\":\"satin\"},\"doors\":{\"on\":true,\"step\":-1,\"sheen\":\"satin\"},\"builtins\":{\"on\":true,\"step\":-1,\"sheen\":\"satin\"}},\"cans\":[{\"id\":\"P1\",\"sheen\":\"matte\",\"step\":\"T+1\",\"surfaces\":[\"walls\"],\"area_sqft\":272,\"coats\":2,\"gallons\":1.55,\"buy\":\"2 gal matte, one lighter\",\"buy_gallons\":2,\"litres\":7.6},\"...\"],\"primer\":true,\"hours\":[{\"id\":\"H-total\",\"label\":\"Total working hours\",\"h\":15.8}],\"days\":2,\"cost\":{\"id\":\"M-total\",\"total\":333,\"text\":\"about $333 of paint at $68 a gallon (quarts at 35% of a gallon, primer at 70%)\"},\"flags\":[{\"id\":\"F-primer\",\"text\":\"The colour is very deep and the walls are light now - a tinted primer coat first saves a third coat.\"},{\"id\":\"F-north-deep\",\"text\":\"A very deep colour in a north-facing room reads darker and cooler than the chip all day.\"}]}",
 "plan": "{\"verdict\":\"tonal\",\"summary\":\"Keep ink navy as the one colour running through the room, but tune it so it reads as a library, not a cave: the walls lift one step to T+1 and the ceiling two steps to T+2 so the north light doesn't flatten them, while trim, doors and the shelving wall deepen to T-1 for crisp, bookish contrast. Every surface in scope stays in the navy family - nothing goes bright white - so the small room still reads as one confident, warm-lit colour story.\",\"surfaces\":[{\"surface\":\"walls\",\"step\":1,\"sheen\":\"matte\",\"why\":\"One step up to T+1 keeps the moody, library-navy feel the note asks for while giving the north light enough reflectance that the room doesn't read as a cave; matte hides the inevitable wall imperfections a deep colour shows up.\"},\"...\"]}",
 "note": "Small and dark already. I want it cosy like a library, not a cave. Shelves along one wall. Evenings only, a couple of hours at a time."
}

Reply:

{
 "task": "takeoff",
 "verdict": "diy_multi_day",
 "title": "Ink Navy Library Takeoff - Box-room Study",
 "summary": "This keeps the tonal plan as-is: walls one step lighter, ceiling two steps lighter, and the trim, doors and shelving a step deeper for that bookish contrast. With a tinted primer pass plus two coats everywhere and your evenings-only schedule, plan on spreading it over a few short sessions rather than one weekend push.",
 "cans": [
  {
   "can_id": "P1",
   "gallons": 2,
   "why": "The walls need 1.55 gallons at T+1 matte; paint only comes in full gallons, so buy 2 and keep the rest for future touch-ups."
  },
  {
   "can_id": "P2",
   "gallons": 1,
   "why": "The ceiling needs 0.51 gallons at T+2 flat, which rounds up to the smallest full gallon can."
  },
  "..."
 ],
 "supplies": [
  {
   "item": "9-inch roller frames and covers",
   "qty": "2 sets",
   "why": "keeps the deep navy nap separate from the primer roller so colours don't mix"
  },
  {
   "item": "angled sash brush",
   "qty": "1",
   "why": "cuts in the ceiling line, window trim and the edges around the built-ins"
  },
  "..."
 ],
 "steps": [
  {
   "order": 1,
   "task": "Fill any holes or dings, sand smooth, tape off trim and windows, and cover the floor and shelving.",
   "surface": "prep",
   "hours": 3.1,
   "cite": [
    "H-prep"
   ]
  },
  {
   "order": 2,
   "task": "Roll and cut in the tinted primer coat across walls, ceiling, trim, doors and built-ins; let it dry fully before any colour goes on.",
   "surface": "primer",
   "hours": 2,
   "cite": [
    "H-primer",
    "P0"
   ]
  },
  "..."
 ],
 "budget": {
  "text": "About $333 of paint in total, at roughly $68 a gallon (quarts figured at 35% of a gallon, the primer at 70%).",
  "cite": [
   "M-total"
  ]
 },
 "risks": [
  {
   "text": "Skipping the tinted primer over these light walls would mean a third topcoat to fully block the old colour - the schedule above already builds that primer pass in.",
   "cite": [
    "F-primer",
    "P0"
   ]
  },
  {
   "text": "This room gets no direct sun, so the navy will look noticeably darker and cooler while you're painting in daylight than it does under evening lamps; keep a wet edge on the matte walls so lap marks don't show once it dries.",
   "cite": [
    "F-north-deep",
    "R-facing",
    "A-walls"
   ]
  },
  "..."
 ],
 "tips": [
  "Work top to bottom each evening - ceiling, then walls, then woodwork - so you're never left mid-surface when you have to stop.",
  "With only a couple of hours at a time, break at the end of a wall or a full coat rather than partway through one, and let each coat hit its recoat window before the next.",
  "..."
 ],
 "caveats": [
  "This assumes the walls only need light filling and sanding; existing gloss paint or bigger repairs would add prep time beyond H-prep."
 ]
}

task: plan - Clay living room (sample room) (partial)

Input:

{
 "task": "plan",
 "room": "{\"name\":\"Living room\",\"unit\":\"ft\",\"length_ft\":22,\"width_ft\":16,\"height_ft\":11,\"doors\":2,\"windows\":4,\"facing\":\"south\",\"current_walls\":\"mid\",\"scope\":[\"walls\",\"ceiling\",\"trim\",\"doors\"],\"facts\":[{\"id\":\"R-facing\",\"text\":\"south-facing windows\"},{\"id\":\"R-height\",\"text\":\"ceiling 11 ft\"},{\"id\":\"R-size\",\"text\":\"22 ft x 16 ft floor\"}]}",
 "colour": "{\"hex\":\"#b5643c\",\"label\":\"baked clay\",\"family\":\"terracotta\",\"value\":\"deep\",\"lrv\":19.3,\"oklch\":{\"l\":0.588,\"c\":0.118,\"h\":45.8},\"ladder\":[{\"id\":\"T0\",\"step\":0,\"name\":\"base\",\"hex\":\"#b5643c\",\"lrv\":19.3},\"... T-2, T-1, T+1, T+2 in the same shape\"],\"light\":[{\"id\":\"L-day\",\"label\":\"Daylight, south-facing\",\"hex\":\"#be673b\"},\"...\"],\"facts\":[{\"id\":\"C-lrv\",\"text\":\"approximate LRV 19.3 (deep)\"},{\"id\":\"C-family\",\"text\":\"terracotta\"}]}",
 "facts": "{\"areas\":[{\"id\":\"A-walls\",\"text\":\"747 sq ft\",\"sqft\":747},\"...\"],\"assignment\":{\"walls\":{\"on\":true,\"step\":0,\"sheen\":\"matte\"},\"ceiling\":{\"on\":true,\"step\":0,\"sheen\":\"flat\"},\"trim\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"},\"doors\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"}},\"cans\":[{\"id\":\"P1\",\"sheen\":\"matte\",\"step\":\"T0\",\"surfaces\":[\"walls\"],\"area_sqft\":747,\"coats\":2,\"gallons\":4.27,\"buy\":\"4 gal + 2 qt matte, base\",\"buy_gallons\":4.5,\"litres\":17},\"...\"],\"primer\":false,\"hours\":[{\"id\":\"H-total\",\"label\":\"Total working hours\",\"h\":35.2}],\"days\":5,\"cost\":{\"id\":\"M-total\",\"total\":483,\"text\":\"about $483 of paint at $60 a gallon (quarts at 35% of a gallon, primer at 70%)\"},\"flags\":[{\"id\":\"F-tall\",\"text\":\"Ceiling height 11 ft - plan on an extension pole and a tall ladder or a platform.\"},{\"id\":\"F-big\",\"text\":\"About 7.75 gallons of colour - a five-gallon pail of the main can is usually cheaper.\"},{\"id\":\"F-long\",\"text\":\"About 35.2 working hours - more than two full weekends for one painter.\"}]}",
 "note": "Tall room with a big bay of windows. I love the warm colour but want the ceiling to stay bright. I do not own a ladder taller than six feet."
}

Reply:

{
 "task": "plan",
 "verdict": "partial",
 "title": "Baked clay drench, ceiling kept bright",
 "summary": "Walls, trim and doors all stay at the true baked-clay base (T0) so the room reads as one warm terracotta volume, while the ceiling is left out of the hue so it stays bright, exactly as you asked. With south light pouring through your bay of windows, expect the colour to glow by day and turn warmer and cosier once lamps take over.",
 "colour_read": {
  "text": "Baked clay is a deep, warm terracotta (approximate LRV 19.3) - rich and earthy rather than bright. Facing south, this living room gets strong direct daylight, which will keep a colour this deep from ever reading flat or muddy.",
  "cite": [
   "C-lrv",
   "C-family",
   "R-facing"
  ]
 },
 "surfaces": [
  {
   "surface": "walls",
   "step": 0,
   "sheen": "matte",
   "why": "Full-strength baked clay (T0) across all the walls gives the one-hue drench you love; matte keeps the deep colour soft rather than flashy under direct sun."
  },
  {
   "surface": "ceiling",
   "step": "off",
   "sheen": "",
   "why": "You asked for the ceiling to stay bright, so it's kept white/the existing colour rather than drenched - that bounces more daylight down into an 11-ft room instead of lowering it visually."
  },
  "..."
 ],
 "light": [
  {
   "text": "Direct south daylight through your bay of windows will push baked clay toward its warmest, most saturated look at midday - brighter and more orange than the swatch alone suggests.",
   "cite": [
    "L-day",
    "R-facing"
   ]
  },
  {
   "text": "As daylight fades the same colour reads noticeably darker and more brown-red; because the ceiling is kept bright, the room should still feel open rather than sinking into shadow at dusk.",
   "cite": [
    "L-dusk"
   ]
  },
  "..."
 ],
 "risks": [
  {
   "text": "At 11 ft, your walls run higher than a standard room, so cutting in near the ceiling line and coating the top courses needs a real extension pole or a tall ladder/platform - a 6-ft stepladder alone won't reach safely.",
   "cite": [
    "F-tall",
    "R-height"
   ]
  },
  {
   "text": "A deep, saturated colour over this much wall area (747 sq ft) shows roller lap marks more readily than a pale one, so each wall needs to be kept wet at the edges while you work across it.",
   "cite": [
    "F-tall",
    "A-walls"
   ]
  }
 ],
 "styling": [
  "Lean into warm metals - brass, bronze, aged gold - rather than cool chrome or nickel; they sit with baked clay's orange undertone instead of fighting it.",
  "Bring in lighter natural wood tones (oak, ash, rattan) on furniture or flooring so the room doesn't read as one unbroken block of colour.",
  "..."
 ],
 "caveats": [
  "This colour was analysed from a screen hex and the LRV is approximate - paint a sample of T0 on two different walls and view it in daylight, dusk and lamp light before committing the whole room.",
  "If this home was built before 1978, have any existing paint tested for lead before sanding trim or doors, and keep the room ventilated while you work, especially given the extra height you'll be working at."
 ]
}

task: takeoff - Clay living room (sample room) (hire_pro)

Input:

{
 "task": "takeoff",
 "room": "{\"name\":\"Living room\",\"unit\":\"ft\",\"length_ft\":22,\"width_ft\":16,\"height_ft\":11,\"doors\":2,\"windows\":4,\"facing\":\"south\",\"current_walls\":\"mid\",\"scope\":[\"walls\",\"ceiling\",\"trim\",\"doors\"],\"facts\":[{\"id\":\"R-facing\",\"text\":\"south-facing windows\"},{\"id\":\"R-height\",\"text\":\"ceiling 11 ft\"},{\"id\":\"R-size\",\"text\":\"22 ft x 16 ft floor\"}]}",
 "colour": "{\"hex\":\"#b5643c\",\"label\":\"baked clay\",\"family\":\"terracotta\",\"value\":\"deep\",\"lrv\":19.3,\"oklch\":{\"l\":0.588,\"c\":0.118,\"h\":45.8},\"ladder\":[{\"id\":\"T0\",\"step\":0,\"name\":\"base\",\"hex\":\"#b5643c\",\"lrv\":19.3},\"... T-2, T-1, T+1, T+2 in the same shape\"],\"light\":[{\"id\":\"L-day\",\"label\":\"Daylight, south-facing\",\"hex\":\"#be673b\"},\"...\"],\"facts\":[{\"id\":\"C-lrv\",\"text\":\"approximate LRV 19.3 (deep)\"},{\"id\":\"C-family\",\"text\":\"terracotta\"}]}",
 "facts": "{\"areas\":[{\"id\":\"A-walls\",\"text\":\"747 sq ft\",\"sqft\":747},\"...\"],\"assignment\":{\"walls\":{\"on\":true,\"step\":0,\"sheen\":\"matte\"},\"ceiling\":{\"on\":false,\"step\":0,\"sheen\":\"flat\"},\"trim\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"},\"doors\":{\"on\":true,\"step\":0,\"sheen\":\"satin\"}},\"cans\":[{\"id\":\"P1\",\"sheen\":\"matte\",\"step\":\"T0\",\"surfaces\":[\"walls\"],\"area_sqft\":747,\"coats\":2,\"gallons\":4.27,\"buy\":\"4 gal + 2 qt matte, base\",\"buy_gallons\":4.5,\"litres\":17},\"...\"],\"primer\":false,\"hours\":[{\"id\":\"H-total\",\"label\":\"Total working hours\",\"h\":25.9}],\"days\":4,\"cost\":{\"id\":\"M-total\",\"total\":342,\"text\":\"about $342 of paint at $60 a gallon (quarts at 35% of a gallon, primer at 70%)\"},\"flags\":[{\"id\":\"F-tall\",\"text\":\"Ceiling height 11 ft - plan on an extension pole and a tall ladder or a platform.\"},{\"id\":\"F-big\",\"text\":\"About 5.5 gallons of colour - a five-gallon pail of the main can is usually cheaper.\"}]}",
 "plan": "{\"verdict\":\"partial\",\"summary\":\"Walls, trim and doors all stay at the true baked-clay base (T0) so the room reads as one warm terracotta volume, while the ceiling is left out of the hue so it stays bright, exactly as you asked. With south light pouring through your bay of windows, expect the colour to glow by day and turn warmer and cosier once lamps take over.\",\"surfaces\":[{\"surface\":\"walls\",\"step\":0,\"sheen\":\"matte\",\"why\":\"Full-strength baked clay (T0) across all the walls gives the one-hue drench you love; matte keeps the deep colour soft rather than flashy under direct sun.\"},\"...\"]}",
 "note": "Tall room with a big bay of windows. I love the warm colour but want the ceiling to stay bright. I do not own a ladder taller than six feet."
}

Reply:

{
 "task": "takeoff",
 "verdict": "hire_pro",
 "title": "Baked Clay Takeoff: Buy List Ready, Hire a Pro for the Height",
 "summary": "Walls, trim and doors all stay at the true baked-clay base (T0) while the ceiling is kept bright and out of the hue, just as planned. The full job runs about 25.9 hours and roughly $342 in paint - but at 11 ft with no ladder taller than 6 ft on hand, the ceiling-line cutting-in and upper trim work are better left to a pro.",
 "cans": [
  {
   "can_id": "P1",
   "gallons": 4.5,
   "why": "Buy 4 gal + 2 qt of the matte T0 base to cover the 4.27 gallons that two coats on 747 sq ft of walls need, with a little left over for touch-ups."
  },
  {
   "can_id": "P2",
   "gallons": 1,
   "why": "One gallon of satin T0 covers the 0.54 gallons that two coats on the trim and doors need combined."
  }
 ],
 "supplies": [
  {
   "item": "9-inch roller frames and 3/8-inch naps",
   "qty": "2 frames, 4 naps",
   "why": "Keep a separate roller and nap for the matte walls and the satin trim/doors so sheens don't mix."
  },
  {
   "item": "angled sash brush",
   "qty": "1, about 2.5 inches",
   "why": "For cutting in at the ceiling line and around door and trim edges."
  },
  "..."
 ],
 "steps": [
  {
   "order": 1,
   "task": "Fill nail holes, sand rough spots, tape off the ceiling line and door hardware, and lay drop cloths.",
   "surface": "prep",
   "hours": 6,
   "cite": [
    "H-prep"
   ]
  },
  {
   "order": 2,
   "task": "Roll two coats of matte T0 baked clay on the walls, letting the first coat dry before the second.",
   "surface": "walls",
   "hours": 11.1,
   "cite": [
    "H-walls",
    "P1"
   ]
  },
  "..."
 ],
 "budget": {
  "text": "About $342 total for paint, at roughly $60 a gallon across both cans.",
  "cite": [
   "M-total"
  ]
 },
 "risks": [
  {
   "text": "At 11 ft, cutting in where the bright ceiling meets the new T0 walls needs a tall ladder or platform - past the 6-ft ladder on hand, which is the main reason to bring in a pro for that line.",
   "cite": [
    "F-tall"
   ]
  },
  {
   "text": "Baked clay is a deep, saturated colour, so lap marks show easily if the wet edge isn't kept moving - work wall by wall rather than stopping partway through one.",
   "cite": [
    "C-lrv"
   ]
  },
  "..."
 ],
 "tips": [
  "Ask your paint store whether a 5-gallon pail of the matte T0 base works out cheaper than the 4 gal + 2 qt split, since the job needs close to that much.",
  "If you keep any of the prep work for yourself, do it before the pro arrives to save on labor hours.",
  "..."
 ],
 "caveats": [
  "If this home was built before 1978, test for lead paint before any sanding or scraping, especially on the trim and doors.",
  "This takeoff covers paint and material cost only - a pro's labor rate and schedule aren't estimated here."
 ]
}

Build the input yourself

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

const K = DrenchKit;
const room = { name: "Bedroom", unit: "ft", length: 13, width: 12, height: 8, doors: 1, windows: 2, facing: "east", current: "light", price: 55 };
let stats = K.analyze(room, "#8a9a7b", "soft sage", null);   // colour, ladder, areas, cans, hours, flags
const { input } = K.buildInput("plan", { stats, note: "" });
const wire = K.toWire(input);                                // POST this to /estimate and /run
// later: const plan = K.normalize(K.parseReply(job.output.output));
// K.reconcile(plan, { stats }) -> [{level, code, text}]
// stats = K.analyze(room, "#8a9a7b", "soft sage", K.applyPlan(stats.assign, plan));
// takeoff: K.buildInput("takeoff", { stats, plan })

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://drench-room.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":"drench-room"}' | 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": "plan", "room": "{...}", "colour": "{...}", "facts": "{...}"}
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 drench-room:<task>:<inputHash>:a<attempt>, 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="drench-room:plan:$(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: drench-room:plan:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json