Drive Do Not Dig Here from your own code
The one metered task, carve, is available over HTTP. It takes what is sealed, where it is, when it was sealed, why nobody should open it, what the finder should do instead, a tone, how long the marker must work, your own draft warning and the page's drift scan of that draft. It returns a four-layer far-future warning (a top line, a warning, what, where, when and why, and the full record), 2 to 4 pictograms from a fixed set, every phrase in the draft that will not survive with a plain swap, a verdict on the draft, a line for a five-year-old in the house today and how a far-future finder might misread the top line.
The division of labour first: the page owns the drift scan, the weathering slider and the verdict rule; the model owns the reading of the draft and the wording of the marker; the page re-checks the reply.
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":"do-not-dig-here"}), so no slug header is needed afterwards. Send it as Authorization: Bearer …. The run body is the input object, sent bare.
| Status | Code | Meaning |
|---|---|---|
| 400 | validation_error | The body is not a JSON object, or a required field (task, thing, where, sealed, danger, wish, tone, horizon, draft, drift_scan) is missing. |
| 401 | unauthorized | No token, or a stale one. Mint a guest token or sign in again. |
| 402 | insufficient_credits | The balance is under min_credits. Price with /estimate first. |
| 403 | forbidden | A guest token tried to run: a carving is metered and needs a personal token. |
| 404 | not_found | Unknown job id. |
| 429 | rate_limited | Back off and retry. |
| 5xx | server_error | Transient. Retry with the same Idempotency-Key so a retry never double-bills. |
The task field and the verdicts
Every run sends task: carve (the one task is carve); a missing or different one is still answered as carve. The verdict on the draft is a rule, checked in order: fresh if the draft is (no draft); recarve if the draft never names the thing or never says where it is; recarve if 3 or more phrases will not survive; patch for 1 or 2; durable for none. The model reports the two draft checks and the drift list it counted, so the page can recompute the verdict and warn if it differs.
Input fields (every value is a string)
| Field | Required | What it holds |
|---|---|---|
task | yes | Always carve. |
thing | yes | What is sealed (at most 80 characters), or (not given). |
where | yes | Where it is (at most 80), or (not given). |
sealed | yes | <Month> <year>, <year> or not given. |
danger / wish | yes | Why nobody should open it (at most 300) and what to do instead (at most 140), or (not given). |
tone | yes | deadpan, solemn or frantic. |
horizon | yes | 1 year, 100 years, 1,000 years or 10,000 years. |
draft | yes | Your own warning (at most 600), or (no draft). |
drift_scan | yes | One line per flagged phrase, <n> | <phrase> | <name|date|slang|shout|in-joke>, or (none), or (no draft). |
clip_note | no | What the page shortened, if anything. |
retry_note | no | Only on the automatic reformat retry. |
The reply
One JSON object, in output.output of the finished job:
{"task": "carve", "title": "...", "draft_names_thing": true, "draft_says_where": true,
"drift": [{"phrase": "...", "kind": "name | date | slang | shout | in-joke | brand", "swap": "..."}],
"verdict": "fresh | durable | patch | recarve", "verdict_reason": "...",
"level1": "...", "level2": "...", "level3": {"what": "...", "where": "...", "when": "...", "why": "..."}, "level4": "...",
"pictograms": [{"id": "face | hand | lid | rays | nose | knot | door | walk | eye | suns | fire | spike", "why": "..."}],
"kid_line": "...", "misreading": "..."}
| Field | What it holds |
|---|---|
draft_names_thing / draft_says_where | Whether the draft itself names what is sealed and says where it is (both false with no draft). |
drift | Every phrase from the page's scan, in order, plus any other phrase that depends on outside knowledge, each with a plain swap of at most 12 words. |
verdict / verdict_reason | The rule above, and one sentence of facts behind it. |
level1 to level4 | The top line (at most 8 words, no numbers), the warning (at most 25), four facts of at most 14 words each, the full record (40 to 110 words) in the chosen tone. |
pictograms | 2 to 4 ids from the fixed set, always including face; suns only for 1,000 years or more. |
kid_line / misreading | A line for a five-year-old today (at most 15 words) and a deadpan misreading of the top line and pictograms (at most 35). |
title | A playful name of at most 8 words. |
The page then checks the reply against the form (MarkKit.check): the verdict against the rule, every scanned phrase answered in the drift, every drift phrase really in the draft, the word limits, the sealed year in the 'when' line and no date that was never given, 2 to 4 pictograms from the set, no name from the draft on the marker, no exclamation marks, no he or she, no "years ago" and no internal field name in the prose.
Worked examples, one per verdict
These are the four free samples on the page: the exact input and a stand-in model's reply, unedited. Together they cover recarve, durable, patch and fresh.
The tub at the back - recarve
Input:
{
"task": "carve",
"thing": "A takeaway tub of curry",
"where": "The bottom shelf of the fridge, behind the pickle jar",
"sealed": "August 2026",
"danger": "The lid bulges and the smell clears the kitchen when anyone lifts it.",
"wish": "Carry it to the outside bin without opening it.",
"tone": "deadpan",
"horizon": "10,000 years",
"draft": "DO NOT open Dave's curry from August!! Trust me. Ask Priya if unsure lol",
"drift_scan": "1 | DO NOT | shout\n2 | Dave's | name\n3 | August | date\n4 | !! | shout\n5 | Trust me | in-joke\n6 | Priya | name\n7 | lol | slang"
}
Reply:
{
"task": "carve",
"title": "The Curry That Must Never Be Opened",
"draft_names_thing": true,
"draft_says_where": false,
"drift": [
{
"phrase": "DO NOT",
"kind": "shout",
"swap": "do not open, in plain letters"
},
{
"phrase": "Dave's",
"kind": "name",
"swap": "someone who lived here"
},
{
"phrase": "August",
"kind": "date",
"swap": "2026"
},
{
"phrase": "!!",
"kind": "shout",
"swap": "a plain full stop"
},
{
"phrase": "Trust me",
"kind": "in-joke",
"swap": "leave it out"
},
{
"phrase": "Priya",
"kind": "name",
"swap": "someone else"
},
{
"phrase": "lol",
"kind": "slang",
"swap": "leave it out"
}
],
"verdict": "recarve",
"verdict_reason": "The draft never says where the tub is kept, so it cannot stand alone as the marker.",
"level1": "People sealed this. It is not good.",
"level2": "If this is opened, the lid bulges and the smell clears the kitchen. Keep it closed and do not open it.",
"level3": {
"what": "A takeaway tub of curry, sealed shut.",
"where": "Bottom shelf of a cold box for food, a fridge, behind a pickle jar.",
"when": "Sealed in August 2026.",
"why": "The lid bulges and the smell clears the kitchen if lifted."
},
"level4": "A takeaway tub of curry was sealed here by the people who lived here. It sits on the bottom shelf of a cold box for food, a fridge, behind a pickle jar. It was sealed in August 2026. The lid bulges and the smell clears the kitchen when anyone lifts it. Do not open it. Carry it to the outside bin without opening it.",
"pictograms": [
{
"id": "face",
"why": "Something here is clearly wrong, shown by the bulging lid."
},
{
"id": "lid",
"why": "The tub must stay closed to keep the bad smell inside."
},
{
"id": "nose",
"why": "Opening it lets a strong smell fill the whole kitchen."
},
{
"id": "suns",
"why": "This warning must keep working for a very long stretch of time."
}
],
"kid_line": "Please do not open the tub in the fridge. Just leave it there.",
"misreading": "A finder might think something bad and smelly was sealed because people dreaded it and wanted it kept shut for a very long time."
}
The cable drawer - durable
Input:
{
"task": "carve",
"thing": "A drawer of tangled charger cables",
"where": "The kitchen drawer under the toaster",
"sealed": "2019",
"danger": "Pull one cable and the whole knot comes out with it, and it takes an hour to put back.",
"wish": "Close it again and leave the knot alone.",
"tone": "solemn",
"horizon": "1,000 years",
"draft": "Knotted cables in this kitchen drawer under the toaster. Pull one and all of them come out. Keep it shut.",
"drift_scan": "(none)"
}
Reply:
{
"task": "carve",
"title": "The Cable Knot That Must Not Be Freed",
"draft_names_thing": true,
"draft_says_where": true,
"drift": [],
"verdict": "durable",
"verdict_reason": "No phrase in the draft depends on a name, date, slang, shout, or shared memory, so nothing needs to be recarved.",
"level1": "People sealed this, and it is not good.",
"level2": "Pulling a cable drags the whole tangle out, and it is slow to undo. Leave it closed.",
"level3": {
"what": "A drawer of tangled charger cables.",
"where": "The kitchen drawer under the toaster.",
"when": "Sealed in 2019.",
"why": "Pulling a cable drags the whole tangle out, and it is slow to fix."
},
"level4": "Here is a drawer of tangled charger cables, kept in the kitchen drawer under the toaster. It was sealed in 2019. Do not open it. Pulling a cable draws the whole tangle out with it, and setting it right again takes a long time. Close the drawer again, and leave the knot alone: this is what was asked. Nothing more about this is written. Let it remain closed and undisturbed.",
"pictograms": [
{
"id": "face",
"why": "Opening the drawer causes a tangle that takes a long time to undo."
},
{
"id": "knot",
"why": "The cables inside are tangled, and pulling any of them drags the rest loose."
},
{
"id": "lid",
"why": "Closing the drawer again and leaving it alone is what should happen."
},
{
"id": "suns",
"why": "This marker must stay clear and true for a very long time."
}
],
"kid_line": "Please leave this drawer shut and do not pull on any cables.",
"misreading": "Reading only that people sealed something bad, saw a tangled knot, a shut lid, and endless suns, a finder might conclude a dangerous beast was imprisoned for all time."
}
The chilli jar - patch
Input:
{
"task": "carve",
"thing": "A jar of pickled chillies",
"where": "The top shelf of the pantry",
"sealed": "2024",
"danger": "Far too hot to eat. Everyone who tried one cried.",
"wish": "(not given)",
"tone": "frantic",
"horizon": "100 years",
"draft": "Pickled chillies on this top shelf. Too hot to eat. Opened once in 2024 and everyone cried. Keep the lid on.",
"drift_scan": "1 | 2024 | date"
}
Reply:
{
"task": "carve",
"title": "The Chilli Jar That Must Stay Shut",
"draft_names_thing": true,
"draft_says_where": true,
"drift": [
{
"phrase": "2024",
"kind": "date",
"swap": "the year it was sealed"
}
],
"verdict": "patch",
"verdict_reason": "One phrase, the year, will not survive; everything else in the draft can stay.",
"level1": "People sealed something here. It is not good.",
"level2": "It is far too hot to eat and will make you cry if you try it. Keep it closed.",
"level3": {
"what": "A jar of pickled chillies.",
"where": "The top shelf of the pantry.",
"when": "Sealed in 2024.",
"why": "Far too hot to eat. Everyone who tried one cried."
},
"level4": "Do not open this. Do not open it. A jar of pickled chillies sits on the top shelf of the pantry. It was sealed in 2024. It is far too hot to eat. Everyone who tried one cried. Leave it closed. Do not open it. Leave it closed. It must stay closed. Leave it closed.",
"pictograms": [
{
"id": "face",
"why": "Something sealed here is bad and far too hot to eat."
},
{
"id": "lid",
"why": "The jar was sealed and should stay closed."
},
{
"id": "fire",
"why": "The chillies inside are far too hot to eat."
},
{
"id": "hand",
"why": "Tasting it made everyone who tried it cry."
}
],
"kid_line": "It is too hot. Please do not open it. Leave it closed.",
"misreading": "A future finder might think people sealed something here because it is a dreaded, burning, untouchable thing that must stay shut and is simply not good."
}
The attic box - fresh
Input:
{
"task": "carve",
"thing": "A box of my teenage diaries",
"where": "The attic, behind the water tank",
"sealed": "2009",
"danger": "Deeply embarrassing poems about a band I loved.",
"wish": "Leave it closed. If you must move it, do not read it.",
"tone": "solemn",
"horizon": "10,000 years",
"draft": "(no draft)",
"drift_scan": "(no draft)"
}
Reply:
{
"task": "carve",
"title": "The Diaries That Must Never Reopen",
"draft_names_thing": false,
"draft_says_where": false,
"drift": [],
"verdict": "fresh",
"verdict_reason": "There was no draft to check, so this marker is carved straight from the facts given.",
"level1": "People sealed this. It is not good.",
"level2": "Inside are poems that would deeply embarrass the person who sealed it. Keep this closed.",
"level3": {
"what": "A box of teenage diaries.",
"where": "The attic, behind the water tank.",
"when": "Sealed in 2009.",
"why": "Poems that deeply embarrass the person who sealed it."
},
"level4": "Here, behind the water tank in the attic, lies a box of teenage diaries, sealed in 2009. Inside are poems that would deeply embarrass the person who sealed it, written about a band once loved. The person who sealed it asked that this remain closed, and that if it must ever be moved, no one read what is inside. That is all that is known and all that is asked. Let it stay as it was sealed.",
"pictograms": [
{
"id": "face",
"why": "This box holds something that would deeply embarrass the person who sealed it."
},
{
"id": "lid",
"why": "The wish is for this box to stay closed."
},
{
"id": "eye",
"why": "The person who sealed it asked that no one read what is inside."
},
{
"id": "suns",
"why": "This marker needs to make sense for a very long time."
}
],
"kid_line": "Leave the box alone. Do not open it or look inside.",
"misreading": "Seeing only that people sealed something bad, a dreading face, a shut lid, a closed eye and endless suns, a finder might guess this seals away a monster for all eternity."
}
Build the input yourself
Load the script in node (global.window = global; require("./markkit.js")), then:
const K = MarkKit;
const form = K.form({ thing: "A jar of pickled chillies", where: "The top shelf of the pantry", year: "2024",
danger: "Far too hot to eat.", tone: "frantic", horizon: "100", draft: "Too hot. Opened once in 2024. Keep the lid on." });
K.scan(form.draft); // [{n: 1, phrase: "2024", kind: "date", start: 23}]
const built = K.buildInput(form);
built.provisional; // {verdict: "", why: "1 phrase flagged so far; ..."}
const wire = K.toWire(built.input); // POST this to /estimate and /run
// then: const reply = K.normalize(K.parseReply(job.output.output));
// K.check(reply, built).notes // the page's re-check of the carving
// K.md(built, reply) // the marker 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://do-not-dig-here.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"}
}
import json, urllib.request
BASE = "https://api.skillsafe.ai/v1/app-api"
TOKEN = "paste-your-token-here" # from https://do-not-dig-here.skillsafe.ai/tokens.html
def api(method, path, body=None, headers=None):
req = urllib.request.Request(BASE + path, method=method,
data=None if body is None else json.dumps(body).encode(),
headers={"Content-Type": "application/json", **({"Authorization": "Bearer " + TOKEN} if TOKEN else {}), **(headers or {})})
with urllib.request.urlopen(req) as r:
env = json.load(r)
if env.get("error"):
raise RuntimeError(env["error"])
return env["data"]
// do-not-dig-here.mjs -- Node 18+ (global fetch)
const BASE = "https://api.skillsafe.ai/v1/app-api";
let TOKEN = "paste-your-token-here"; // from https://do-not-dig-here.skillsafe.ai/tokens.html
async function api(method, path, body, headers = {}) {
const r = await fetch(BASE + path, { method, headers: { "Content-Type": "application/json",
...(TOKEN ? { Authorization: "Bearer " + TOKEN } : {}), ...headers },
body: body === undefined ? undefined : JSON.stringify(body) });
const env = await r.json();
if (env.error) throw new Error(env.error.code + ": " + env.error.message);
return env.data;
}
package main
import ("bytes"; "encoding/json"; "fmt"; "net/http")
const base = "https://api.skillsafe.ai/v1/app-api"
var token = "paste-your-token-here" // from https://do-not-dig-here.skillsafe.ai/tokens.html
func api(method, path string, body any, headers map[string]string) (map[string]any, error) {
var buf bytes.Buffer
if body != nil { json.NewEncoder(&buf).Encode(body) }
req, _ := http.NewRequest(method, base+path, &buf)
req.Header.Set("Content-Type", "application/json")
if token != "" { req.Header.Set("Authorization", "Bearer "+token) }
for k, v := range headers { req.Header.Set(k, v) }
res, err := http.DefaultClient.Do(req)
if err != nil { return nil, err }
defer res.Body.Close()
var env struct { Data map[string]any; Error map[string]any }
json.NewDecoder(res.Body).Decode(&env)
if env.Error != nil { return nil, fmt.Errorf("%v", env.Error) }
return env.Data, nil
}
// DoNotDigHere.java -- Java 17+, with com.fasterxml.jackson.core:jackson-databind
import com.fasterxml.jackson.databind.*;
import java.net.URI; import java.net.http.*; import java.util.*;
public class DoNotDigHere {
static final String BASE = "https://api.skillsafe.ai/v1/app-api";
static String token = "paste-your-token-here"; // from https://do-not-dig-here.skillsafe.ai/tokens.html
static final ObjectMapper M = new ObjectMapper();
static final HttpClient C = HttpClient.newHttpClient();
static JsonNode api(String method, String path, Object body, Map<String, String> headers) throws Exception {
var b = HttpRequest.newBuilder(URI.create(BASE + path)).header("Content-Type", "application/json");
if (!token.isEmpty()) b.header("Authorization", "Bearer " + token);
if (headers != null) headers.forEach(b::header);
b.method(method, body == null ? HttpRequest.BodyPublishers.noBody() : HttpRequest.BodyPublishers.ofString(M.writeValueAsString(body)));
JsonNode env = M.readTree(C.send(b.build(), HttpResponse.BodyHandlers.ofString()).body());
if (env.hasNonNull("error")) throw new RuntimeException(env.get("error").toString());
return env.get("data");
}
}
require "json"
require "net/http"
BASE = "https://api.skillsafe.ai/v1/app-api"
TOKEN = "paste-your-token-here" # from https://do-not-dig-here.skillsafe.ai/tokens.html
def api(method, path, body = nil, headers = {})
uri = URI(BASE + path)
req = Net::HTTPGenericRequest.new(method, !body.nil?, true, uri.request_uri,
{ "Content-Type" => "application/json" }.merge(TOKEN.empty? ? {} : { "Authorization" => "Bearer #{TOKEN}" }).merge(headers))
req.body = JSON.generate(body) unless body.nil?
env = JSON.parse(Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }.body)
raise env["error"].to_s if env["error"]
env["data"]
end
<?php
const BASE = "https://api.skillsafe.ai/v1/app-api";
$TOKEN = "paste-your-token-here"; // from https://do-not-dig-here.skillsafe.ai/tokens.html
function api(string $method, string $path, $body = null, array $headers = []) {
global $TOKEN;
$h = ["Content-Type: application/json"];
if ($TOKEN) $h[] = "Authorization: Bearer $TOKEN";
foreach ($headers as $k => $v) $h[] = "$k: $v";
$ch = curl_init(BASE . $path);
curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => $h, CURLOPT_RETURNTRANSFER => true]);
if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
$env = json_decode(curl_exec($ch), true);
if (!empty($env["error"])) throw new Exception(json_encode($env["error"]));
return $env["data"];
}
// Program.cs -- .NET 6+ console app
using System.Net.Http.Json; using System.Text.Json; using System.Text.Json.Nodes;
static class Api {
public const string Base = "https://api.skillsafe.ai/v1/app-api";
public static string Token = "paste-your-token-here"; // from https://do-not-dig-here.skillsafe.ai/tokens.html
static readonly HttpClient C = new();
public static async Task<JsonNode?> Call(string method, string path, object? body = null, Dictionary<string, string>? headers = null) {
var req = new HttpRequestMessage(new HttpMethod(method), Base + path);
if (Token != "") req.Headers.Add("Authorization", "Bearer " + Token);
if (headers != null) foreach (var h in headers) req.Headers.Add(h.Key, h.Value);
if (body != null) req.Content = JsonContent.Create(body);
var env = JsonNode.Parse(await (await C.SendAsync(req)).Content.ReadAsStringAsync())!;
if (env["error"] is JsonNode e && e.GetValueKind() != JsonValueKind.Null) throw new Exception(e.ToJsonString());
return env["data"];
}
}
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":"do-not-dig-here"}' | jq -r '.data.token')
# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN = ""
TOKEN = api("POST", "/guest", {"slug": "do-not-dig-here"})["token"]
// a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN = "";
TOKEN = (await api("POST", "/guest", { slug: "do-not-dig-here" })).token;
// inside main: a guest token (enough for /me and /estimate); a run needs your personal token
token = ""
g, err := api("POST", "/guest", map[string]string{"slug": "do-not-dig-here"}, nil)
if err != nil { panic(err) }
token = g["token"].(string)
// inside main: a guest token (enough for /me and /estimate); a run needs your personal token
token = "";
token = api("POST", "/guest", Map.of("slug", "do-not-dig-here"), null).get("token").asText();
# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN.replace("")
TOKEN.replace(api("POST", "/guest", { slug: "do-not-dig-here" })["token"])
// a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
$TOKEN = "";
$TOKEN = api("POST", "/guest", ["slug" => "do-not-dig-here"])["token"];
// a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
Api.Token = "";
Api.Token = (await Api.Call("POST", "/guest", new { slug = "do-not-dig-here" }))!["token"]!.GetValue<string>();
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}'
me = api("GET", "/me")
print(me["subject_type"], me.get("credits"))
const me = await api("GET", "/me");
console.log(me.subject_type, me.credits);
me, _ := api("GET", "/me", nil, nil)
fmt.Println(me["subject_type"], me["credits"])
JsonNode me = api("GET", "/me", null, null);
System.out.println(me.get("subject_type") + " " + me.get("credits"));
me = api("GET", "/me")
puts [me["subject_type"], me["credits"]].inspect
$me = api("GET", "/me");
echo $me["subject_type"], " ", $me["credits"] ?? "", "\n";
var me = await Api.Call("GET", "/me");
Console.WriteLine($"{me!["subject_type"]} {me["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": "carve", "thing": "A jar of pickled chillies", "where": "The top shelf of the pantry", "sealed": "2024", "danger": "Far too hot to eat.", "wish": "(not given)", "tone": "frantic", "horizon": "100 years", "draft": "(no draft)", "drift_scan": "(no draft)"}
api POST /estimate "$(cat input.json)" | jq '.data | {hold_credits, min_credits, model, model_alias, markup_bps, warnings}'
inp = json.load(open("input.json")) # {"task": "carve", "thing": "A jar of pickled chillies", "where": "The top shelf of the pantry", "sealed": "2024", "danger": "Far too hot to eat.", "wish": "(not given)", "tone": "frantic", "horizon": "100 years", "draft": "(no draft)", "drift_scan": "(no draft)"}
est = api("POST", "/estimate", inp)
print(est["hold_credits"], est["min_credits"], est["model"], est.get("warnings"))
import { readFileSync } from "node:fs";
const input = JSON.parse(readFileSync("input.json", "utf8")); // {task: "carve", thing, where, sealed, danger, wish, tone, horizon, draft, drift_scan, ...} (see the field table)
const est = await api("POST", "/estimate", input);
console.log(est.hold_credits, est.min_credits, est.model, est.warnings);
raw, _ := os.ReadFile("input.json") // add "os" to the imports
var input map[string]any
json.Unmarshal(raw, &input)
est, _ := api("POST", "/estimate", input, nil)
fmt.Println(est["hold_credits"], est["min_credits"], est["model"])
Map<String, Object> input = M.readValue(new java.io.File("input.json"), Map.class);
JsonNode est = api("POST", "/estimate", input, null);
System.out.println(est.get("hold_credits") + " " + est.get("min_credits") + " " + est.get("model"));
input = JSON.parse(File.read("input.json"))
est = api("POST", "/estimate", input)
puts [est["hold_credits"], est["min_credits"], est["model"]].inspect
$input = json_decode(file_get_contents("input.json"), true);
$est = api("POST", "/estimate", $input);
echo $est["hold_credits"], " ", $est["min_credits"], " ", $est["model"], "\n";
var input = JsonNode.Parse(File.ReadAllText("input.json"))!;
var est = await Api.Call("POST", "/estimate", input);
Console.WriteLine($"{est!["hold_credits"]} {est["min_credits"]} {est["model"]}");
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 do-not-dig-here:<task>:<inputHash>:a<attempt> (the one task is carve), 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="do-not-dig-here:carve:$(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}'
import hashlib, time
key = "do-not-dig-here:" + inp["task"] + ":" + hashlib.sha256(json.dumps(inp).encode()).hexdigest()[:16] + ":a1"
job = api("POST", "/run", inp, {"Idempotency-Key": key})
while True:
j = api("GET", "/jobs/" + job["job_id"])
if j["status"] in ("succeeded", "failed", "cancelled"):
break
time.sleep(2)
reply = json.loads(j["output"]["output"]) # the reply as one JSON object
print(j["charged_credits"], j.get("truncated"), reply.get("title"))
import { createHash } from "node:crypto";
const key = `do-not-dig-here:${input.task}:${createHash("sha256").update(JSON.stringify(input)).digest("hex").slice(0, 16)}:a1`;
const job = await api("POST", "/run", input, { "Idempotency-Key": key });
let j;
do { await new Promise((r) => setTimeout(r, 2000)); j = await api("GET", "/jobs/" + job.job_id); }
while (!["succeeded", "failed", "cancelled"].includes(j.status));
const reply = JSON.parse(j.output.output);
console.log(j.charged_credits, j.truncated, reply.title);
sum := sha256.Sum256(raw) // add "crypto/sha256", "encoding/hex", "time" to the imports
key := "do-not-dig-here:" + input["task"].(string) + ":" + hex.EncodeToString(sum[:8]) + ":a1"
job, _ := api("POST", "/run", input, map[string]string{"Idempotency-Key": key})
var j map[string]any
for {
time.Sleep(2 * time.Second)
j, _ = api("GET", "/jobs/"+job["job_id"].(string), nil, nil)
if s := j["status"]; s == "succeeded" || s == "failed" || s == "cancelled" { break }
}
fmt.Println(j["charged_credits"], j["truncated"], j["output"].(map[string]any)["output"])
var digest = java.security.MessageDigest.getInstance("SHA-256").digest(M.writeValueAsBytes(input));
String key = "do-not-dig-here:" + input.get("task") + ":" + HexFormat.of().formatHex(digest, 0, 8) + ":a1";
JsonNode job = api("POST", "/run", input, Map.of("Idempotency-Key", key)), j;
do { Thread.sleep(2000); j = api("GET", "/jobs/" + job.get("job_id").asText(), null, null); }
while (!Set.of("succeeded", "failed", "cancelled").contains(j.get("status").asText()));
JsonNode reply = M.readTree(j.get("output").get("output").asText());
System.out.println(j.get("charged_credits") + " " + reply);
require "digest"
key = "do-not-dig-here:#{input["task"]}:#{Digest::SHA256.hexdigest(JSON.generate(input))[0, 16]}:a1"
job = api("POST", "/run", input, { "Idempotency-Key" => key })
j = nil
loop do
sleep 2
j = api("GET", "/jobs/#{job["job_id"]}")
break if %w[succeeded failed cancelled].include?(j["status"])
end
reply = JSON.parse(j["output"]["output"])
puts [j["charged_credits"], j["truncated"], reply["title"]].inspect
$key = "do-not-dig-here:" . $input["task"] . ":" . substr(hash("sha256", json_encode($input)), 0, 16) . ":a1";
$job = api("POST", "/run", $input, ["Idempotency-Key" => $key]);
do { sleep(2); $j = api("GET", "/jobs/" . $job["job_id"]); }
while (!in_array($j["status"], ["succeeded", "failed", "cancelled"]));
$reply = json_decode($j["output"]["output"], true);
echo $j["charged_credits"], " ", $reply["title"], "\n";
var digest = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(input.ToJsonString()));
var key = $"do-not-dig-here:{input["task"]}:{Convert.ToHexString(digest, 0, 8).ToLowerInvariant()}:a1";
var job = await Api.Call("POST", "/run", input, new() { ["Idempotency-Key"] = key });
JsonNode j;
do { await Task.Delay(2000); j = (await Api.Call("GET", "/jobs/" + job!["job_id"]))!; }
while (!new[] { "succeeded", "failed", "cancelled" }.Contains(j["status"]!.GetValue<string>()));
var reply = JsonNode.Parse(j["output"]!["output"]!.GetValue<string>());
Console.WriteLine($"{j["charged_credits"]} {reply}");
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: do-not-dig-here:carve:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json
rev = json.load(open("input.json")) # the same run input as input.json: {"task": "carve", "thing": "A jar of pickled chillies", "where": "The top shelf of the pantry", "sealed": "2024", "danger": "Far too hot to eat.", "wish": "(not given)", "tone": "frantic", "horizon": "100 years", "draft": "(no draft)", "drift_scan": "(no draft)"}
req = urllib.request.Request(BASE + "/run-stream", method="POST", data=json.dumps(rev).encode(),
headers={"Content-Type": "application/json", "Authorization": "Bearer " + TOKEN,
"Idempotency-Key": "do-not-dig-here:carve:" + hashlib.sha256(json.dumps(rev).encode()).hexdigest()[:16] + ":a1"})
with urllib.request.urlopen(req) as r:
for line in r:
line = line.decode().strip()
if line.startswith("data:"):
print(line[5:].strip()[:200])
const rev = JSON.parse(readFileSync("input.json", "utf8"));
const r = await fetch(BASE + "/run-stream", { method: "POST", body: JSON.stringify(rev), headers: {
"Content-Type": "application/json", Authorization: "Bearer " + TOKEN,
"Idempotency-Key": `do-not-dig-here:carve:${createHash("sha256").update(JSON.stringify(rev)).digest("hex").slice(0, 16)}:a1` } });
const dec = new TextDecoder();
for await (const chunk of r.body) for (const line of dec.decode(chunk).split("\n"))
if (line.startsWith("data:")) console.log(line.slice(5).trim().slice(0, 200));
rraw, _ := os.ReadFile("input.json") // add "bufio", "strings" to the imports
rs := sha256.Sum256(rraw)
req, _ := http.NewRequest("POST", base+"/run-stream", bytes.NewReader(rraw))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Idempotency-Key", "do-not-dig-here:carve:"+hex.EncodeToString(rs[:8])+":a1")
res, _ := http.DefaultClient.Do(req)
sc := bufio.NewScanner(res.Body)
for sc.Scan() { if l := sc.Text(); strings.HasPrefix(l, "data:") { fmt.Println(l[5:]) } }
String rev = java.nio.file.Files.readString(java.nio.file.Path.of("input.json"));
var rd = java.security.MessageDigest.getInstance("SHA-256").digest(rev.getBytes());
var sreq = HttpRequest.newBuilder(URI.create(BASE + "/run-stream")).header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token).header("Idempotency-Key", "do-not-dig-here:carve:" + HexFormat.of().formatHex(rd, 0, 8) + ":a1")
.POST(HttpRequest.BodyPublishers.ofString(rev)).build();
C.send(sreq, HttpResponse.BodyHandlers.ofLines()).body().filter(l -> l.startsWith("data:")).forEach(System.out::println);
rev = File.read("input.json")
uri = URI(BASE + "/run-stream")
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json", "Authorization" => "Bearer #{TOKEN}",
"Idempotency-Key" => "do-not-dig-here:carve:#{Digest::SHA256.hexdigest(rev)[0, 16]}:a1")
req.body = rev
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |h|
h.request(req) { |res| res.read_body { |chunk| chunk.each_line { |l| puts l if l.start_with?("data:") } } }
end
$rev = file_get_contents("input.json");
$ch = curl_init(BASE . "/run-stream");
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $rev, CURLOPT_HTTPHEADER => [
"Content-Type: application/json", "Authorization: Bearer $TOKEN",
"Idempotency-Key: do-not-dig-here:carve:" . substr(hash("sha256", $rev), 0, 16) . ":a1"],
CURLOPT_WRITEFUNCTION => function ($ch, $chunk) { foreach (explode("\n", $chunk) as $l) if (str_starts_with($l, "data:")) echo $l, "\n"; return strlen($chunk); }]);
curl_exec($ch);
var rev = File.ReadAllText("input.json");
var rd = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(rev));
var sreq = new HttpRequestMessage(HttpMethod.Post, Api.Base + "/run-stream") { Content = new StringContent(rev, System.Text.Encoding.UTF8, "application/json") };
sreq.Headers.Add("Authorization", "Bearer " + Api.Token);
sreq.Headers.Add("Idempotency-Key", $"do-not-dig-here:carve:{Convert.ToHexString(rd, 0, 8).ToLowerInvariant()}:a1");
using var http = new HttpClient();
using var res = await http.SendAsync(sreq, HttpCompletionOption.ResponseHeadersRead);
using var rdr = new StreamReader(await res.Content.ReadAsStreamAsync());
for (string? l; (l = await rdr.ReadLineAsync()) != null;) if (l.StartsWith("data:")) Console.WriteLine(l);