Drive Macro Desk from your own code
Everything the web page does is available over HTTP: send a description of the person with the diet facts you computed, and get the same coach's plan back — or send the check-in facts and get the adjustment note. The natural use is a coaching pipeline that regenerates a client's plan when their weight or training week changes, or a weekly job that reads three weigh-ins and writes the adjustment.
One thing to be clear about before the first call: the model never computes the diet. Maintenance
calories, the deficit, the macros, the meal template, the phase and the check-in arithmetic are computed by the caller
and sent as facts. The model's job is judgement over those facts — goal fit, pitfalls, noise against
signal, the prose. See computing the facts yourself; the engine the web page uses ships as a
plain script (/diet.js) you can load in node.
Base URL and the envelope
Every endpoint lives under https://api.skillsafe.ai/v1/app-api and every response uses the same envelope, so one helper covers the whole API:
{ "ok": true, "data": { ... } }
{ "ok": false, "error": { "code": "...", "message": "...", "status": 402, "details": { ... } } }
The token is minted for this app (the guest endpoint takes {"slug":"macro-desk"} in its body), so
no slug header is needed afterwards — send your token as Authorization: Bearer … on every call.
| Status | Code | Meaning |
|---|---|---|
| 400 | validation_error | The body is not a JSON object, or a declared required field (task, about, facts) 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: running is metered and needs a personal token. |
| 404 | not_found | Unknown job id. |
| 429 | rate_limited | Back off and retry. |
1. Get a token
A guest token is free and enough for /me and /estimate. Running a lane needs a personal token — sign in on the token page and copy it from there.
curl -s -X POST https://api.skillsafe.ai/v1/app-api/guest -H "Content-Type: application/json" -d '{"slug":"macro-desk"}'import json, urllib.request
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api/guest", data=json.dumps({"slug": "macro-desk"}).encode(), headers={"Content-Type": "application/json"})
print(json.load(urllib.request.urlopen(req))["data"]["token"])const r = await fetch("https://api.skillsafe.ai/v1/app-api/guest", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ slug: "macro-desk" }) });
const { data } = await r.json(); console.log(data.token);res, err := http.Post("https://api.skillsafe.ai/v1/app-api/guest", "application/json", strings.NewReader(`{"slug":"macro-desk"}`))
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/guest")).header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{\"slug\":\"macro-desk\"}")).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/guest")
res = Net::HTTP.post(uri, { slug: "macro-desk" }.to_json, "Content-Type" => "application/json")
puts JSON.parse(res.body)["data"]["token"]$ch = curl_init("https://api.skillsafe.ai/v1/app-api/guest");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_POSTFIELDS => '{"slug":"macro-desk"}']);
echo json_decode(curl_exec($ch), true)["data"]["token"];var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/guest", new StringContent("{\"slug\":\"macro-desk\"}", Encoding.UTF8, "application/json"));
Console.WriteLine(await res.Content.ReadAsStringAsync());2. A tiny client
One helper, one envelope. The samples below reuse it.
curl -s -X GET https://api.skillsafe.ai/v1/app-api/me \
-H "Authorization: Bearer $SKILLSAFE_TOKEN" \
-H "Content-Type: application/json"import json, urllib.request
TOKEN = "YOUR_TOKEN"
def call(method, path, body=None):
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api" + path, method=method, data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"})
with urllib.request.urlopen(req) as r: return json.load(r)
print(call("GET", "/me"))const TOKEN = "YOUR_TOKEN";
async function call(method, path, body) {
const r = await fetch("https://api.skillsafe.ai/v1/app-api" + path, { method, headers: { Authorization: "Bearer " + TOKEN, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
return r.json();
}
console.log(await call("GET", "/me"));req, _ := http.NewRequest("GET", "https://api.skillsafe.ai/v1/app-api/me", nil)
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/me"))
.header("Authorization", "Bearer " + token).header("Content-Type", "application/json")
.method("GET", HttpRequest.BodyPublishers.noBody()).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/me")
req = Net::HTTP::Get.new(uri, "Authorization" => "Bearer #{token}", "Content-Type" => "application/json")
puts Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }.body$ch = curl_init("https://api.skillsafe.ai/v1/app-api/me");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token", "Content-Type: application/json"]]);
echo curl_exec($ch);var req = new HttpRequestMessage(HttpMethod.Get, "https://api.skillsafe.ai/v1/app-api/me");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
Console.WriteLine(await (await http.SendAsync(req)).Content.ReadAsStringAsync());3. Check the session and the balance
GET /me returns subject_type (user or guest), subject_id and credits. A real user's first run should not 402: compare credits with the estimate's hold_credits before running.
curl -s -X GET https://api.skillsafe.ai/v1/app-api/me \
-H "Authorization: Bearer $SKILLSAFE_TOKEN" \
-H "Content-Type: application/json"import json, urllib.request
TOKEN = "YOUR_TOKEN"
def call(method, path, body=None):
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api" + path, method=method, data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"})
with urllib.request.urlopen(req) as r: return json.load(r)
print(call("GET", "/me"))const TOKEN = "YOUR_TOKEN";
async function call(method, path, body) {
const r = await fetch("https://api.skillsafe.ai/v1/app-api" + path, { method, headers: { Authorization: "Bearer " + TOKEN, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
return r.json();
}
console.log(await call("GET", "/me"));req, _ := http.NewRequest("GET", "https://api.skillsafe.ai/v1/app-api/me", nil)
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/me"))
.header("Authorization", "Bearer " + token).header("Content-Type", "application/json")
.method("GET", HttpRequest.BodyPublishers.noBody()).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/me")
req = Net::HTTP::Get.new(uri, "Authorization" => "Bearer #{token}", "Content-Type" => "application/json")
puts Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }.body$ch = curl_init("https://api.skillsafe.ai/v1/app-api/me");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token", "Content-Type: application/json"]]);
echo curl_exec($ch);var req = new HttpRequestMessage(HttpMethod.Get, "https://api.skillsafe.ai/v1/app-api/me");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
Console.WriteLine(await (await http.SendAsync(req)).Content.ReadAsStringAsync());4. Price the run — free
POST /estimate with the exact run body returns model (gpt-5.6-terra), model_alias (gpt-terra), markup_bps (1000), hold_credits (reserved, not the price) and min_credits. No job, no charge. The body must be a JSON object: the server does not validate the shape beyond that, so send exactly the fields below.
curl -s -X POST https://api.skillsafe.ai/v1/app-api/estimate \
-H "Authorization: Bearer $SKILLSAFE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}'import json, urllib.request
TOKEN = "YOUR_TOKEN"
def call(method, path, body=None):
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api" + path, method=method, data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"})
with urllib.request.urlopen(req) as r: return json.load(r)
print(call("POST", "/estimate", {"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}))const TOKEN = "YOUR_TOKEN";
async function call(method, path, body) {
const r = await fetch("https://api.skillsafe.ai/v1/app-api" + path, { method, headers: { Authorization: "Bearer " + TOKEN, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
return r.json();
}
console.log(await call("POST", "/estimate", {"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}));req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/estimate", strings.NewReader(`{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}`))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/estimate"))
.header("Authorization", "Bearer " + token).header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}
""")).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/estimate")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{token}", "Content-Type" => "application/json")
req.body = "{\"task\": \"plan\", \"about\": \"34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.\", \"draft\": \"\", \"facts\": \"<JSON string from Diet.plan(spec) - see below>\"}"
puts Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }.body$ch = curl_init("https://api.skillsafe.ai/v1/app-api/estimate");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}']);
echo curl_exec($ch);var req = new HttpRequestMessage(HttpMethod.Post, "https://api.skillsafe.ai/v1/app-api/estimate");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
req.Content = new StringContent(@"{""task"": ""plan"", ""about"": ""34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength."", ""draft"": """", ""facts"": ""<JSON string from Diet.plan(spec) - see below>""}", Encoding.UTF8, "application/json");
Console.WriteLine(await (await http.SendAsync(req)).Content.ReadAsStringAsync());The fields both lanes take
| Field | Type | Meaning |
|---|---|---|
task | string, required | plan or adjust. The lane. A missing or unknown value makes the model pick the closer lane and name it in lane. |
about | string, required | The person in their own words: training, food habits, diet history. Twenty characters or more. |
draft | string | Optional. The user's current plan or targets, to be checked claim by claim in draft_check. |
log | string | Adjust lane. What happened since the plan: adherence, sleep, hunger, cycle, travel, weigh-in conditions. |
facts | string, required | A JSON string (not an object): Diet.plan(spec) for the plan lane; {"checkin": Diet.adjust(spec), "plan": summary} for the adjust lane. |
Computing the facts yourself
Load /diet.js in node with a stub window and call the same functions the page calls. The plan spec:
global.window = {}; require("vm").runInThisContext(require("fs").readFileSync("diet.js", "utf8"));
const Diet = window.Diet;
const plan = Diet.plan({
sex: "female", weight: 155, unit: "lb", // or unit: "kg"
bodyfat_pct: 26, age: 34, height_cm: 168, // optional
goal: "fat_loss", // fat_loss | muscle_gain | maintenance
experience: "intermediate", // beginner | intermediate | advanced
week: ["hard","moderate","hard","moderate","hard","rest","rest"], // Mon..Sun: rest | light | moderate | hard
rate_pct: 0.65, weeks: 8, // % bodyweight per week, phase length
vegan: false, fat_g_per_lb: 0.39, // plant-based uplift; optional fat preference (floor 0.3)
meals: 5, wake: "06:30", train: "17:30", sleep: "23:00"
});
// plan.days.hard.calories, plan.weekly.average_calories, plan.phase.end_weight_lb, plan.meal_templates.training.rows ...
const checkin = Diet.adjust({ goal: "fat_loss", unit: "lb", weights: [155, 154.6, 154.4, 153.9],
target_rate_pct: 0.65, current_calories: 1890, weeks_planned: 8, start_weight: 155, fat_g_per_lb: 0.39 });
// checkin.observed_lb_per_week, checkin.kcal_per_day_change, checkin.new_calories, checkin.verdict ...
Send JSON.stringify(plan) as facts for the plan lane; for the adjust lane send JSON.stringify({ checkin, plan: summary }) where summary is the plan's targets (goal, weight, rate, weeks, calories by day type — see Recon.planSummary in /recon.js).
The plan request body, in full
Every field app.js sends, with facts abbreviated:
{
"task": "plan",
"about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.",
"draft": "",
"facts": "<JSON string from Diet.plan(spec) - see below>"
}
The adjust request body, in full
{
"task": "adjust",
"about": "(same as the plan)",
"draft": "",
"log": "Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.",
"facts": "<JSON string: {\"checkin\": Diet.adjust(spec), \"plan\": summary}>"
}
Worked example: the adjust lane
curl -s -X POST https://api.skillsafe.ai/v1/app-api/estimate \
-H "Authorization: Bearer $SKILLSAFE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"task": "adjust", "about": "(same as the plan)", "draft": "", "log": "Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.", "facts": "<JSON string: {\"checkin\": Diet.adjust(spec), \"plan\": summary}>"}'import json, urllib.request
TOKEN = "YOUR_TOKEN"
def call(method, path, body=None):
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api" + path, method=method, data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"})
with urllib.request.urlopen(req) as r: return json.load(r)
print(call("POST", "/estimate", {"task": "adjust", "about": "(same as the plan)", "draft": "", "log": "Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.", "facts": "<JSON string: {\"checkin\": Diet.adjust(spec), \"plan\": summary}>"}))const TOKEN = "YOUR_TOKEN";
async function call(method, path, body) {
const r = await fetch("https://api.skillsafe.ai/v1/app-api" + path, { method, headers: { Authorization: "Bearer " + TOKEN, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
return r.json();
}
console.log(await call("POST", "/estimate", {"task": "adjust", "about": "(same as the plan)", "draft": "", "log": "Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.", "facts": "<JSON string: {\"checkin\": Diet.adjust(spec), \"plan\": summary}>"}));req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/estimate", strings.NewReader(`{"task": "adjust", "about": "(same as the plan)", "draft": "", "log": "Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.", "facts": "<JSON string: {\"checkin\": Diet.adjust(spec), \"plan\": summary}>"}`))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/estimate"))
.header("Authorization", "Bearer " + token).header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{"task": "adjust", "about": "(same as the plan)", "draft": "", "log": "Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.", "facts": "<JSON string: {\"checkin\": Diet.adjust(spec), \"plan\": summary}>"}
""")).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/estimate")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{token}", "Content-Type" => "application/json")
req.body = "{\"task\": \"adjust\", \"about\": \"(same as the plan)\", \"draft\": \"\", \"log\": \"Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.\", \"facts\": \"<JSON string: {\\\"checkin\\\": Diet.adjust(spec), \\\"plan\\\": summary}>\"}"
puts Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }.body$ch = curl_init("https://api.skillsafe.ai/v1/app-api/estimate");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"task": "adjust", "about": "(same as the plan)", "draft": "", "log": "Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3.", "facts": "<JSON string: {\"checkin\": Diet.adjust(spec), \"plan\": summary}>"}']);
echo curl_exec($ch);var req = new HttpRequestMessage(HttpMethod.Post, "https://api.skillsafe.ai/v1/app-api/estimate");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
req.Content = new StringContent(@"{""task"": ""adjust"", ""about"": ""(same as the plan)"", ""draft"": """", ""log"": ""Hit the numbers on weekdays; two untracked restaurant dinners each weekend; travelled in week 3."", ""facts"": ""<JSON string: {\""checkin\"": Diet.adjust(spec), \""plan\"": summary}>""}", Encoding.UTF8, "application/json");
Console.WriteLine(await (await http.SendAsync(req)).Content.ReadAsStringAsync());5. Run it, then poll
POST /run returns {job_id}; GET /jobs/{job_id} until status is succeeded or failed. Send an Idempotency-Key header derived from the input and the lane so a retry never double-bills. The reply's output.output is the JSON text described in the contract below; charged_credits is the actual cost.
curl -s -X POST https://api.skillsafe.ai/v1/app-api/run \
-H "Authorization: Bearer $SKILLSAFE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}'import json, urllib.request
TOKEN = "YOUR_TOKEN"
def call(method, path, body=None):
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api" + path, method=method, data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"})
with urllib.request.urlopen(req) as r: return json.load(r)
print(call("POST", "/run", {"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}))const TOKEN = "YOUR_TOKEN";
async function call(method, path, body) {
const r = await fetch("https://api.skillsafe.ai/v1/app-api" + path, { method, headers: { Authorization: "Bearer " + TOKEN, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
return r.json();
}
console.log(await call("POST", "/run", {"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}));req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run", strings.NewReader(`{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}`))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/run"))
.header("Authorization", "Bearer " + token).header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}
""")).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/run")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{token}", "Content-Type" => "application/json")
req.body = "{\"task\": \"plan\", \"about\": \"34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.\", \"draft\": \"\", \"facts\": \"<JSON string from Diet.plan(spec) - see below>\"}"
puts Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }.body$ch = curl_init("https://api.skillsafe.ai/v1/app-api/run");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}']);
echo curl_exec($ch);var req = new HttpRequestMessage(HttpMethod.Post, "https://api.skillsafe.ai/v1/app-api/run");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
req.Content = new StringContent(@"{""task"": ""plan"", ""about"": ""34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength."", ""draft"": """", ""facts"": ""<JSON string from Diet.plan(spec) - see below>""}", Encoding.UTF8, "application/json");
Console.WriteLine(await (await http.SendAsync(req)).Content.ReadAsStringAsync());curl -s -X GET https://api.skillsafe.ai/v1/app-api/jobs/JOB_ID \
-H "Authorization: Bearer $SKILLSAFE_TOKEN" \
-H "Content-Type: application/json"import json, urllib.request
TOKEN = "YOUR_TOKEN"
def call(method, path, body=None):
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api" + path, method=method, data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"})
with urllib.request.urlopen(req) as r: return json.load(r)
print(call("GET", "/jobs/JOB_ID"))const TOKEN = "YOUR_TOKEN";
async function call(method, path, body) {
const r = await fetch("https://api.skillsafe.ai/v1/app-api" + path, { method, headers: { Authorization: "Bearer " + TOKEN, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
return r.json();
}
console.log(await call("GET", "/jobs/JOB_ID"));req, _ := http.NewRequest("GET", "https://api.skillsafe.ai/v1/app-api/jobs/JOB_ID", nil)
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/jobs/JOB_ID"))
.header("Authorization", "Bearer " + token).header("Content-Type", "application/json")
.method("GET", HttpRequest.BodyPublishers.noBody()).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/jobs/JOB_ID")
req = Net::HTTP::Get.new(uri, "Authorization" => "Bearer #{token}", "Content-Type" => "application/json")
puts Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }.body$ch = curl_init("https://api.skillsafe.ai/v1/app-api/jobs/JOB_ID");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token", "Content-Type: application/json"]]);
echo curl_exec($ch);var req = new HttpRequestMessage(HttpMethod.Get, "https://api.skillsafe.ai/v1/app-api/jobs/JOB_ID");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
Console.WriteLine(await (await http.SendAsync(req)).Content.ReadAsStringAsync());6. Or stream it
POST /run-stream is server-sent events: job, then tick heartbeats, then done with the full output. Browsers receive ticks rather than text deltas, so build progress on elapsed time and parse the output from done.
curl -N -s -X POST https://api.skillsafe.ai/v1/app-api/run-stream \
-H "Authorization: Bearer $SKILLSAFE_TOKEN" -H "Accept: text/event-stream" \
-H "Content-Type: application/json" -d '{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}'
# events: job (the job id), tick (heartbeat), done (the full output). Browsers receive ticks, not deltas.import json, urllib.request
TOKEN = "YOUR_TOKEN"
def call(method, path, body=None):
req = urllib.request.Request("https://api.skillsafe.ai/v1/app-api" + path, method=method, data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"})
with urllib.request.urlopen(req) as r: return json.load(r)
print(call("POST", "/run-stream", {"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}))const TOKEN = "YOUR_TOKEN";
async function call(method, path, body) {
const r = await fetch("https://api.skillsafe.ai/v1/app-api" + path, { method, headers: { Authorization: "Bearer " + TOKEN, "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
return r.json();
}
console.log(await call("POST", "/run-stream", {"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}));req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run-stream", strings.NewReader(`{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}`))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.skillsafe.ai/v1/app-api/run-stream"))
.header("Authorization", "Bearer " + token).header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("""
{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}
""")).build();
System.out.println(HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString()).body());require "net/http"; require "json"
uri = URI("https://api.skillsafe.ai/v1/app-api/run-stream")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{token}", "Content-Type" => "application/json")
req.body = "{\"task\": \"plan\", \"about\": \"34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.\", \"draft\": \"\", \"facts\": \"<JSON string from Diet.plan(spec) - see below>\"}"
puts Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }.body$ch = curl_init("https://api.skillsafe.ai/v1/app-api/run-stream");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"task": "plan", "about": "34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength.", "draft": "", "facts": "<JSON string from Diet.plan(spec) - see below>"}']);
echo curl_exec($ch);var req = new HttpRequestMessage(HttpMethod.Post, "https://api.skillsafe.ai/v1/app-api/run-stream");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
req.Content = new StringContent(@"{""task"": ""plan"", ""about"": ""34-year-old woman, lifting four years, three hard sessions a week after work and two moderate days. Cook at home; do not track on weekends. Last cut ran 20 weeks and cost strength."", ""draft"": """", ""facts"": ""<JSON string from Diet.plan(spec) - see below>""}", Encoding.UTF8, "application/json");
Console.WriteLine(await (await http.SendAsync(req)).Content.ReadAsStringAsync());The output contract
One JSON object. Common keys on every reply: lane, title, headline, verdict, summary, notes_on_input[], risks[], next_steps[], draft_check[] {claim, status: agrees|disagrees|unverifiable, note}.
| Lane | Verdict | Body |
|---|---|---|
plan | ready · ready_with_changes · not_advisable | plan_text (paragraphs, every number from facts) · goal_fit {rating: good|questionable|wrong_phase, why} · priorities[] {level: calories|macros|timing|food_composition|supplements, note} · food_guidance[] · pitfalls[] {pitfall, applies: yes|no|unclear, note} (ten, each judged) |
adjust | hold · cut · add · end_phase · wait | adjustment_text · trend_reading · macro_change {macro: fat|carbs|none, direction: cut|add|none, why} · phase_status {status: continue|complete|stop_early, why} · adherence_flags[] |
The web page re-reads every number in plan_text / adjustment_text / trend_reading against the facts it sent (Recon.reconcile in /recon.js) and shows the disagreements; do the same in a pipeline before trusting a figure.
Derived from the agent skill @borisghidaglia/rp-diet, an index of The Renaissance Diet 2.0. Not medical advice.