← How Deep It Goes
API

Drive How Deep It Goes from your own code

The one metered task, chart-depth, is available over HTTP. It takes a topic someone loves (a hobby, food, craft or pastime) and 3 to 12 things they know about it, each with an optional depth guess, and returns every item placed on a five-band iceberg (Tip, Waterline, Shallows, Deep, Abyss) with a reason, a caption per band, a question for each empty band, notes where it parts ways with a guess, and a diver rank.

The division of labour first: the model places; the page adds up. The page flags first-person items (they always sink to the Abyss), computes the rank with fixed rules from the model's tiers, and re-checks the reply. The model never fact-checks the items.

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": "..." } }

The token is minted for this app (the guest call takes {"slug":"how-deep-it-goes"}), 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 field (task, topic, items, 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: the chart is 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, the input and the ranks

Every run sends task: chart-depth (the one task is chart-depth); a missing or different one is still answered as chart-depth. All fields are strings.

FieldRequiredWhat it holds
taskyesAlways chart-depth.
topicyesThe thing the person loves, up to 60 characters.
itemsyesOne numbered line per item (3 to 12): N. item text | your guess: Tip|Waterline|Shallows|Deep|Abyss|not sure | about you: yes|no. Item text is up to 90 characters.
factsyesThe page's lines: the item count, which items are about you, how many carry a guess, and the rank the guesses alone give.
retry_notenoOnly on the page's one reformat retry.

Tiers score Tip 1, Waterline 2, Shallows 3, Deep 4, Abyss 5; items that can't be placed are left out. First match wins: fewer than 3 placed is too-murky; a sum of at least 4 per item is abyss-dweller; at least 3 per item free-diver; at least 2 per item snorkeller; otherwise tip-spotter. The depth is the average cut (not rounded) to one decimal. Items written in the first person (I, my, we, our) are always Abyss.

The reply

{"task": "chart-depth", "headline": "...", "items": [{"n": 1, "tier": "shallows", "why": "..."}], "captions": {"tip": "...", "waterline": "...", "shallows": "...", "deep": "...", "abyss": "..."}, "verdict": "free-diver", "depth_score": "3.5", "dive_prompts": [{"tier": "tip", "question": "..."}], "guess_notes": [{"n": 5, "note": "..."}], "closing": "..."}
FieldWhat it holds
headlineAt most 20 words on how the items spread across the bands.
items[]One per input line, same numbers: tier (one of the five, or unplaceable) and why (at most 25 words, who would know it).
captionsOne line per band, in the topic's own words.
verdict, depth_scoreThe rank id and the average, by the rule above.
dive_prompts[]One question for every empty band (none when too murky).
guess_notes[]One note per item whose guess is two or more bands from its placement.
closingOne sentence naming the rank.

The page then checks the reply (DepthKit.check) - every item present, first-person items in the Abyss, the rank and depth re-added from the tiers, a question for each empty band, a note for each big guess gap, and time words, contact-like details or truth verdicts in the prose - and shows its own rank where they differ.

Worked examples - all five ranks

These are the 5 free samples on the page: the exact input the page sends and the reply that replays for free. Together they cover all five ranks.

Coffee, near the surface - rank: Tip spotter

Input:

{
 "task": "chart-depth",
 "topic": "Coffee",
 "items": "1. coffee is made from roasted beans | your guess: Tip | about you: no\n2. coffee has caffeine in it | your guess: Tip | about you: no\n3. coffee can be served hot or iced | your guess: not sure | about you: no\n4. a latte has milk in it | your guess: Waterline | about you: no\n5. decaf has less caffeine | your guess: Tip | about you: no\n6. an espresso is a small, strong shot | your guess: Abyss | about you: no",
 "facts": "items: 6\nabout-you items (first person, so they belong in the Abyss): none\nitems you guessed: 5 of 6\nyour guesses (about-you items counted as Abyss) give a depth of 2.0 (Snorkeller)"
}

Reply:

{
 "task": "chart-depth",
 "headline": "Your coffee knowledge sits mostly at the surface, with a couple of items edging toward the waterline.",
 "items": [
  {
   "n": 1,
   "tier": "tip",
   "why": "Even people who don't follow coffee at all usually know it's made from roasted beans."
  },
  {
   "n": 2,
   "tier": "tip",
   "why": "Even someone who never drinks coffee has usually heard that it has caffeine in it."
  },
  {
   "n": 3,
   "tier": "tip",
   "why": "Most people, even those who don't follow coffee, know it can be served hot or iced."
  },
  {
   "n": 4,
   "tier": "waterline",
   "why": "Anyone who has tried or watched someone order a latte would know it has milk in it."
  },
  {
   "n": 5,
   "tier": "tip",
   "why": "Even people who don't follow coffee at all usually know decaf has less caffeine."
  },
  {
   "n": 6,
   "tier": "waterline",
   "why": "Anyone who has tried or watched coffee being ordered would know an espresso is a small, strong shot."
  }
 ],
 "captions": {
  "tip": "People who don't pay any attention to coffee would still know this.",
  "waterline": "Anyone who has had some firsthand experience with coffee would know this.",
  "shallows": "People who follow coffee as a hobby would know this level of detail.",
  "deep": "Only serious coffee fans with lots of specialized knowledge would know this.",
  "abyss": "Only you or the people closest to you would know this about coffee."
 },
 "verdict": "tip-spotter",
 "depth_score": "1.3",
 "dive_prompts": [
  {
   "tier": "shallows",
   "question": "Is there a coffee habit or preference you've settled into that casual drinkers wouldn't share?"
  },
  {
   "tier": "deep",
   "question": "Is there something about coffee that only people who've followed it closely would know?"
  },
  {
   "tier": "abyss",
   "question": "Is there a coffee detail that's true only for you or the people closest to you?"
  }
 ],
 "guess_notes": [
  {
   "n": 6,
   "note": "I placed this one at Waterline rather than Abyss — it fits with coffee knowledge most people pick up from trying or watching a few orders."
  }
 ],
 "closing": "This puts you at Tip spotter, dipping just below the surface of what most people know about coffee."
}

Cheese, a bit below - rank: Snorkeller

Input:

{
 "task": "chart-depth",
 "topic": "Cheese",
 "items": "1. cheddar is a hard cheese | your guess: Tip | about you: no\n2. blue cheese has veins of mould | your guess: not sure | about you: no\n3. brie has a soft white rind | your guess: Waterline | about you: no\n4. a parmesan rind can flavour a pot of soup | your guess: Shallows | about you: no\n5. the crunchy crystals in long-aged cheese | your guess: not sure | about you: no\n6. washed-rind cheeses smell much stronger than they taste | your guess: Tip | about you: no",
 "facts": "items: 6\nabout-you items (first person, so they belong in the Abyss): none\nitems you guessed: 4 of 6\nyour guesses (about-you items counted as Abyss) give a depth of 1.7 (Tip spotter)"
}

Reply:

{
 "task": "chart-depth",
 "headline": "Your cheese knowledge stretches from common basics to one deep insight, settling mostly in the middle tiers.",
 "items": [
  {
   "n": 1,
   "tier": "tip",
   "why": "Even people who ignore cheese entirely have heard that cheddar is a hard cheese."
  },
  {
   "n": 2,
   "tier": "tip",
   "why": "Almost anyone, even without interest in cheese, knows blue cheese has veins of mould."
  },
  {
   "n": 3,
   "tier": "waterline",
   "why": "Anyone who has tried brie once or twice would notice its soft white rind."
  },
  {
   "n": 4,
   "tier": "shallows",
   "why": "Regular cheese followers know a parmesan rind can flavour a pot of soup."
  },
  {
   "n": 5,
   "tier": "deep",
   "why": "Only long-time devoted followers notice the crunchy crystals in long-aged cheese."
  },
  {
   "n": 6,
   "tier": "shallows",
   "why": "Regular followers who explore varieties know washed-rind cheeses smell much stronger than they taste."
  }
 ],
 "captions": {
  "tip": "Casual eaters who've never thought twice about cheese still know these.",
  "waterline": "Anyone who has sampled a few cheeses picks this much up.",
  "shallows": "Hobbyist cheese fans who dig a little deeper land here.",
  "deep": "Devoted, long-time cheese followers hold onto details like these.",
  "abyss": "Here sits cheese knowledge that's entirely personal to you and your own circle."
 },
 "verdict": "snorkeller",
 "depth_score": "2.3",
 "dive_prompts": [
  {
   "tier": "abyss",
   "question": "Is there a cheese tradition, memory, or quirky habit that belongs just to you or your closest circle?"
  }
 ],
 "guess_notes": [
  {
   "n": 6,
   "note": "You guessed Tip, but this one feels closer to Shallows, since it takes a bit of regular cheese curiosity to notice."
  }
 ],
 "closing": "Your cheese curiosity places you as a Snorkeller, dipping confidently below the surface without diving all the way down."
}

Knitting, well under - rank: Free diver

Input:

{
 "task": "chart-depth",
 "topic": "Knitting",
 "items": "1. knit and purl are the two basic stitches | your guess: Tip | about you: no\n2. knitting a gauge swatch before a big project | your guess: not sure | about you: no\n3. blocking a finished piece to even out the stitches | your guess: Shallows | about you: no\n4. Kitchener stitch to close the toe of a sock | your guess: not sure | about you: no\n5. steeking means cutting your knitting on purpose | your guess: Tip | about you: no\n6. my first scarf got wider with every row | your guess: Abyss | about you: yes",
 "facts": "items: 6\nabout-you items (first person, so they belong in the Abyss): 6\nitems you guessed: 4 of 6\nyour guesses (about-you items counted as Abyss) give a depth of 2.5 (Snorkeller)"
}

Reply:

{
 "task": "chart-depth",
 "headline": "Your knitting knowledge runs from everyday basics up through advanced techniques, plus one memory that's entirely your own.",
 "items": [
  {
   "n": 1,
   "tier": "tip",
   "why": "Even people who don't knit at all have usually heard that knit and purl are the two basic stitches."
  },
  {
   "n": 2,
   "tier": "shallows",
   "why": "Regular, hobbyist knitters are the ones who know to knit a gauge swatch before a big project."
  },
  {
   "n": 3,
   "tier": "shallows",
   "why": "Regular hobbyist knitters are the ones who know to block a finished piece to even out the stitches."
  },
  {
   "n": 4,
   "tier": "deep",
   "why": "Only long-time, devoted knitters usually know Kitchener stitch, used to close the toe of a sock."
  },
  {
   "n": 5,
   "tier": "deep",
   "why": "Only long-time, devoted knitters usually know that steeking means cutting your knitting on purpose."
  },
  {
   "n": 6,
   "tier": "abyss",
   "why": "Only you would know, first-hand, that your first scarf got wider with every row."
  }
 ],
 "captions": {
  "tip": "People who don't knit at all still usually know this much about knitting.",
  "waterline": "Anyone who's tried knitting once or twice would recognize this level.",
  "shallows": "Regular, everyday knitters comfortably know their way around here.",
  "deep": "Only long-time, devoted knitters usually reach this level of knitting knowledge.",
  "abyss": "Knitting knowledge here belongs only to you and maybe those close to you."
 },
 "verdict": "free-diver",
 "depth_score": "3.3",
 "dive_prompts": [
  {
   "tier": "waterline",
   "question": "What's something you noticed or learned the very first few times you tried knitting?"
  }
 ],
 "guess_notes": [
  {
   "n": 5,
   "note": "You guessed Tip for steeking, but it's landed in Deep instead — cutting your knitting on purpose is something mostly long-time, devoted knitters know about."
  }
 ],
 "closing": "With a mix of basics, deeper techniques, and a personal memory, you're sitting right in Free diver territory."
}

Cryptic crosswords, all the way down - rank: Abyss dweller

Input:

{
 "task": "chart-depth",
 "topic": "Cryptic crosswords",
 "items": "1. words like broken or mixed can signal an anagram | your guess: Deep | about you: no\n2. hidden-word clues tuck the answer inside the clue | your guess: not sure | about you: no\n3. setters sign their puzzles with pen names | your guess: Shallows | about you: no\n4. my nan always solved in pen | your guess: Abyss | about you: yes\n5. the clue my brother and I still argue about | your guess: not sure | about you: yes\n6. our family rule: no looking up answers before lunch | your guess: Abyss | about you: yes",
 "facts": "items: 6\nabout-you items (first person, so they belong in the Abyss): 4, 5, 6\nitems you guessed: 4 of 6\nyour guesses (about-you items counted as Abyss) give a depth of 4.4 (Abyss dweller)"
}

Reply:

{
 "task": "chart-depth",
 "headline": "Your cryptic crossword knowledge ranges from everyday solving tricks to deeply personal family memories in the Abyss.",
 "items": [
  {
   "n": 1,
   "tier": "shallows",
   "why": "Regular cryptic crossword solvers pick up that words like broken or mixed can signal an anagram."
  },
  {
   "n": 2,
   "tier": "shallows",
   "why": "Regular solvers come to know that hidden-word clues tuck the answer inside the clue."
  },
  {
   "n": 3,
   "tier": "shallows",
   "why": "Regular solvers notice that setters sign their puzzles with pen names."
  },
  {
   "n": 4,
   "tier": "abyss",
   "why": "Only you and your nan would know that your nan always solved in pen."
  },
  {
   "n": 5,
   "tier": "abyss",
   "why": "Only you and your brother would know the clue you still argue about."
  },
  {
   "n": 6,
   "tier": "abyss",
   "why": "This is your own family's rule, so only your family would know no looking up answers before lunch."
  }
 ],
 "captions": {
  "tip": "People who've merely heard of cryptic crosswords without ever attempting one.",
  "waterline": "Anyone who has had a go at a cryptic crossword a few times.",
  "shallows": "Regular solvers who've picked up the common tricks and conventions of cryptic crosswords.",
  "deep": "Long-time devotees who track the finer points of cryptic crossword habits.",
  "abyss": "Only you and the people closest to you know these personal crossword moments."
 },
 "verdict": "abyss-dweller",
 "depth_score": "4.0",
 "dive_prompts": [
  {
   "tier": "tip",
   "question": "Is there something about cryptic crosswords that almost anyone would recognise, even without trying one?"
  },
  {
   "tier": "waterline",
   "question": "What did you notice the first couple of times you tried a cryptic crossword?"
  },
  {
   "tier": "deep",
   "question": "What's something only the most devoted cryptic crossword fans tend to know?"
  }
 ],
 "guess_notes": [],
 "closing": "You're an Abyss dweller, holding personal cryptic crossword memories that only you and your circle know."
}

Too vague to chart - rank: Too murky to chart

Input:

{
 "task": "chart-depth",
 "topic": "Old films",
 "items": "1. that thing | your guess: Deep | about you: no\n2. the other one | your guess: not sure | about you: no\n3. you know which | your guess: Abyss | about you: no\n4. stuff | your guess: not sure | about you: no",
 "facts": "items: 4\nabout-you items (first person, so they belong in the Abyss): none\nitems you guessed: 2 of 4"
}

Reply:

{
 "task": "chart-depth",
 "headline": "None of these items say enough about old films to place them, so there's nothing to chart yet.",
 "items": [
  {
   "n": 1,
   "tier": "unplaceable",
   "why": "\"That thing\" doesn't say what it is, so it can't be placed on the chart."
  },
  {
   "n": 2,
   "tier": "unplaceable",
   "why": "\"The other one\" doesn't say what it is, so it can't be placed either."
  },
  {
   "n": 3,
   "tier": "unplaceable",
   "why": "\"You know which\" doesn't say what it is, so it can't be placed."
  },
  {
   "n": 4,
   "tier": "unplaceable",
   "why": "\"Stuff\" doesn't say what it is, so it can't be placed on the chart."
  }
 ],
 "captions": {
  "tip": "Everyone who's merely aware old films exist would know this.",
  "waterline": "Someone who's watched a few old films once or twice would know this.",
  "shallows": "People who watch old films fairly often would recognize this.",
  "deep": "Only devoted old films enthusiasts who follow closely would know this.",
  "abyss": "Only you or your closest circle would know something this personal."
 },
 "verdict": "too-murky",
 "depth_score": "",
 "dive_prompts": [],
 "guess_notes": [],
 "closing": "This is Too murky to chart — naming what each item actually is would help place them."
}

Build the input yourself

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

const K = DepthKit;
const form = K.form({ topic: "Tea", items: [
  { text: "green tea and black tea come from the same plant", guess: "shallows" },
  { text: "my gran warmed the pot first", guess: "abyss" },
  { text: "tea bags", guess: "tip" }] });
const built = K.buildInput(form);       // built.facts: about-you items and the rank your guesses give
const wire = K.toWire(built.input);     // POST this to /estimate and /run
// then: const reply = K.normalize(K.parseReply(job.output.output));
// K.outcome(reply, built.facts)        // the page's own rank and depth from the reply's tiers
// K.check(reply, built).notes          // the page's re-check of the reply
// K.md(built, reply, K.title(form))    // the iceberg as Markdown

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://how-deep-it-goes.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":"how-deep-it-goes"}' | 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": "chart-depth", "topic": "Knitting", "items": "1. knit and purl are the two basic stitches | your guess: Tip | about you: no\n...", "facts": "not given", ...}
# - see the field 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 how-deep-it-goes:<task>:<inputHash>:a<attempt> (the one task is chart-depth), 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="how-deep-it-goes:chart-depth:$(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: how-deep-it-goes:chart-depth:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json