Driving Next Move over HTTP
Base URL https://api.skillsafe.ai/v1/app-api. Every response is the same envelope: {"ok": true, "data": {...}} on success, {"ok": false, "error": {"code", "message", "status", "details"}} on failure.
The one field that decides everything: task
There are exactly two lanes and you never pick a technique yourself — that is the whole design. task: "plan" asks the model which of the app's known techniques this situation needs and in what order; task: "execute" works a confirmed plan through. A body with no task is answered by the closest lane, and the lane it chose is named in reading.
| task | required fields | returns |
|---|---|---|
plan | query | reading, steps[], declined[], unknown |
execute | query, plan[] | summary, results[], open[], caveats[] |
Declared input schema
The release declares these fields, so /estimate returns input_checked: true and names anything wrong in warnings. Treat a non-empty warnings as a stop.
| field | type | notes |
|---|---|---|
task | string | required — plan or execute |
query | string | required — the situation in the user's own words |
context | string | optional pasted material |
plan | array | execute only — the confirmed steps, in order |
prescan | object | the browser-side read of the query |
clipped | boolean | true when the query was cut to fit |
Send the fields at the top level. Wrapping them in {"input": {...}} returns 200 and charges normally while the model sees none of your fields — the app ships a client-side guard against exactly this.
The private reference lane ($refs)
The technique catalogue is not in this page and not in the app's JavaScript. It ships under private/ with access: "run", which nothing serves over HTTP. A run retrieves it with the reserved $refs key; the platform resolves it server-side, appends the matched records to the system prompt, and strips the key before the model sees the input. You receive only the completion.
The plan lane pulls the whole catalogue in one lookup using a sentinel token every record carries. The execute lane pulls one playbook per confirmed step by exact key. Both stay inside the platform ceiling of 8 lookups and 16 KB of injection per run — and because the records arrive after the hold is taken, a $refs run is surcharged by that cap, which is why you should always /estimate first.
Errors
| code | status | what it means |
|---|---|---|
unauthorized | 401 | No token, or a token that is not for this app. Mint a new one. |
forbidden | 403 | A guest called a signed-in-only lane. This app is private, so only the publisher holds a token at all. |
not_found | 404 | Unknown app slug, or an undeclared reference path. |
insufficient_credits | 402 | The wallet is below min_credits. /estimate before /run and this never fires. |
rate_limited | 429 | 30 requests/minute per IP, and 2,000 reference reads per app per UTC day. |
validation_error | 400 | The body was not a JSON object, or $model named a model this app does not accept. |
1. Get a token
Every /v1/app-api/* call takes an aut_* app-user token, not your account key. The tokens page mints, reveals and copies one without DevTools. This app is private, so only its publisher can hold a token at all — guests cannot be minted.
curl -s https://api.skillsafe.ai/v1/app-api/me -H "Authorization: Bearer YOUR_TOKEN"
import json, urllib.request
TOKEN = "YOUR_TOKEN" # or read it from your own secret store
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/me",
data=json.dumps({}).encode() if False else None,
headers={"Authorization": "Bearer " + TOKEN,
"Content-Type": "application/json"},
method="GET")
print(json.load(urllib.request.urlopen(req)))
const TOKEN = "YOUR_TOKEN";
const res = await fetch("https://api.skillsafe.ai/v1/app-api/me", {
method: "GET",
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
});
const { ok, data, error } = await res.json();
if (!ok) throw new Error(error.message);
console.log(data);
token := "YOUR_TOKEN" // or os.Getenv of your own variable name
body := []byte(`{}`)
req, _ := http.NewRequest("GET", "https://api.skillsafe.ai/v1/app-api/me", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
String token = "YOUR_TOKEN";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.skillsafe.ai/v1/app-api/me"))
.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json")
.GET()
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
require "net/http"; require "json"
token = "YOUR_TOKEN"
uri = URI("https://api.skillsafe.ai/v1/app-api/me")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{token}"
req["Content-Type"] = "application/json"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts JSON.parse(res.body)
<?php
$token = "YOUR_TOKEN";
$ch = curl_init("https://api.skillsafe.ai/v1/app-api/me");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token", "Content-Type: application/json"]);
$out = json_decode(curl_exec($ch), true);
var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var res = await http.GetAsync("https://api.skillsafe.ai/v1/app-api/me");
var json = await res.Content.ReadAsStringAsync();
2. Check who you are and what you can spend
subject_type is user or guest; credits is the wallet in credits, where 10,000 credits is $1.00.
curl -s https://api.skillsafe.ai/v1/app-api/me -H "Authorization: Bearer YOUR_TOKEN"
import json, urllib.request
TOKEN = "YOUR_TOKEN" # or read it from your own secret store
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/me",
data=json.dumps({}).encode() if False else None,
headers={"Authorization": "Bearer " + TOKEN,
"Content-Type": "application/json"},
method="GET")
print(json.load(urllib.request.urlopen(req)))
const TOKEN = "YOUR_TOKEN";
const res = await fetch("https://api.skillsafe.ai/v1/app-api/me", {
method: "GET",
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
});
const { ok, data, error } = await res.json();
if (!ok) throw new Error(error.message);
console.log(data);
token := "YOUR_TOKEN" // or os.Getenv of your own variable name
body := []byte(`{}`)
req, _ := http.NewRequest("GET", "https://api.skillsafe.ai/v1/app-api/me", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
String token = "YOUR_TOKEN";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.skillsafe.ai/v1/app-api/me"))
.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json")
.GET()
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
require "net/http"; require "json"
token = "YOUR_TOKEN"
uri = URI("https://api.skillsafe.ai/v1/app-api/me")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{token}"
req["Content-Type"] = "application/json"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts JSON.parse(res.body)
<?php
$token = "YOUR_TOKEN";
$ch = curl_init("https://api.skillsafe.ai/v1/app-api/me");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token", "Content-Type: application/json"]);
$out = json_decode(curl_exec($ch), true);
var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var res = await http.GetAsync("https://api.skillsafe.ai/v1/app-api/me");
var json = await res.Content.ReadAsStringAsync();
3. Price the run before you make it
/estimate is free, makes no job, and applies every gate /run applies before the hold. Assert model_alias is gpt-terra and read input_checked and warnings.
curl -s -X POST https://api.skillsafe.ai/v1/app-api/estimate \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"task": "plan",
"query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.",
"context": "",
"prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]},
"clipped": false,
"$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}]
}'
import json, urllib.request
TOKEN = "YOUR_TOKEN" # or read it from your own secret store
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/estimate",
data=json.dumps({ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }).encode() if True else None,
headers={"Authorization": "Bearer " + TOKEN,
"Content-Type": "application/json"},
method="POST")
print(json.load(urllib.request.urlopen(req)))
const TOKEN = "YOUR_TOKEN";
const res = await fetch("https://api.skillsafe.ai/v1/app-api/estimate", {
method: "POST",
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }),
});
const { ok, data, error } = await res.json();
if (!ok) throw new Error(error.message);
console.log(data);
token := "YOUR_TOKEN" // or os.Getenv of your own variable name
body := []byte(`{ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/estimate", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
String token = "YOUR_TOKEN";
HttpRequest req = HttpRequest.newBuilder()
.uri(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", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }"""))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
require "net/http"; require "json"
token = "YOUR_TOKEN"
uri = URI("https://api.skillsafe.ai/v1/app-api/estimate")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{token}"
req["Content-Type"] = "application/json"
req.body = { "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts JSON.parse(res.body)
<?php
$token = "YOUR_TOKEN";
$ch = curl_init("https://api.skillsafe.ai/v1/app-api/estimate");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token", "Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }');
$out = json_decode(curl_exec($ch), true);
var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var content = new StringContent(@"{ ""task"": ""plan"", ""query"": ""Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent."", ""context"": """", ""prescan"": {""must_not"": [""set a discount precedent""], ""deadlines"": [""11 days""], ""figures"": [""30%""]}, ""clipped"": false, ""$refs"": [{""path"": ""private/skills.jsonl"", ""q"": ""playable"", ""limit"": 60}] }", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/estimate", content);
var json = await res.Content.ReadAsStringAsync();
4. Ask for a plan
Returns one JSON object. Every steps[].skill is an id from the private catalogue; the app refuses to render one that is not.
curl -s -X POST https://api.skillsafe.ai/v1/app-api/run \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"task": "plan",
"query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.",
"context": "",
"prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]},
"clipped": false,
"$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}]
}'
import json, urllib.request
TOKEN = "YOUR_TOKEN" # or read it from your own secret store
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/run",
data=json.dumps({ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }).encode() if True else None,
headers={"Authorization": "Bearer " + TOKEN,
"Content-Type": "application/json"},
method="POST")
print(json.load(urllib.request.urlopen(req)))
const TOKEN = "YOUR_TOKEN";
const res = await fetch("https://api.skillsafe.ai/v1/app-api/run", {
method: "POST",
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }),
});
const { ok, data, error } = await res.json();
if (!ok) throw new Error(error.message);
console.log(data);
token := "YOUR_TOKEN" // or os.Getenv of your own variable name
body := []byte(`{ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
String token = "YOUR_TOKEN";
HttpRequest req = HttpRequest.newBuilder()
.uri(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", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }"""))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
require "net/http"; require "json"
token = "YOUR_TOKEN"
uri = URI("https://api.skillsafe.ai/v1/app-api/run")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{token}"
req["Content-Type"] = "application/json"
req.body = { "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts JSON.parse(res.body)
<?php
$token = "YOUR_TOKEN";
$ch = curl_init("https://api.skillsafe.ai/v1/app-api/run");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token", "Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }');
$out = json_decode(curl_exec($ch), true);
var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var content = new StringContent(@"{ ""task"": ""plan"", ""query"": ""Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent."", ""context"": """", ""prescan"": {""must_not"": [""set a discount precedent""], ""deadlines"": [""11 days""], ""figures"": [""30%""]}, ""clipped"": false, ""$refs"": [{""path"": ""private/skills.jsonl"", ""q"": ""playable"", ""limit"": 60}] }", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/run", content);
var json = await res.Content.ReadAsStringAsync();
5. Execute the confirmed plan
Send back only the steps the user kept, in the order they kept them, with one $refs lookup per step. results[] covers exactly those ids.
curl -s -X POST https://api.skillsafe.ai/v1/app-api/run \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"task": "execute",
"query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.",
"context": "",
"prescan": {"must_not": ["set a discount precedent"]},
"clipped": false,
"plan": [
{"id": "s1", "skill": "objmap-surface-real-objection", "name": "Surface the real objection"},
{"id": "s2", "skill": "voss-calibrated-questions", "name": "Calibrated questions"}
],
"$refs": [
{"path": "private/playbooks.jsonl", "key": "objmap-surface-real-objection"},
{"path": "private/playbooks.jsonl", "key": "voss-calibrated-questions"}
]
}'
import json, urllib.request
TOKEN = "YOUR_TOKEN" # or read it from your own secret store
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/run",
data=json.dumps({ "task": "execute", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"]}, "clipped": false, "plan": [ {"id": "s1", "skill": "objmap-surface-real-objection", "name": "Surface the real objection"}, {"id": "s2", "skill": "voss-calibrated-questions", "name": "Calibrated questions"} ], "$refs": [ {"path": "private/playbooks.jsonl", "key": "objmap-surface-real-objection"}, {"path": "private/playbooks.jsonl", "key": "voss-calibrated-questions"} ] }).encode() if True else None,
headers={"Authorization": "Bearer " + TOKEN,
"Content-Type": "application/json"},
method="POST")
print(json.load(urllib.request.urlopen(req)))
const TOKEN = "YOUR_TOKEN";
const res = await fetch("https://api.skillsafe.ai/v1/app-api/run", {
method: "POST",
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({ "task": "execute", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"]}, "clipped": false, "plan": [ {"id": "s1", "skill": "objmap-surface-real-objection", "name": "Surface the real objection"}, {"id": "s2", "skill": "voss-calibrated-questions", "name": "Calibrated questions"} ], "$refs": [ {"path": "private/playbooks.jsonl", "key": "objmap-surface-real-objection"}, {"path": "private/playbooks.jsonl", "key": "voss-calibrated-questions"} ] }),
});
const { ok, data, error } = await res.json();
if (!ok) throw new Error(error.message);
console.log(data);
token := "YOUR_TOKEN" // or os.Getenv of your own variable name
body := []byte(`{ "task": "execute", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"]}, "clipped": false, "plan": [ {"id": "s1", "skill": "objmap-surface-real-objection", "name": "Surface the real objection"}, {"id": "s2", "skill": "voss-calibrated-questions", "name": "Calibrated questions"} ], "$refs": [ {"path": "private/playbooks.jsonl", "key": "objmap-surface-real-objection"}, {"path": "private/playbooks.jsonl", "key": "voss-calibrated-questions"} ] }`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
String token = "YOUR_TOKEN";
HttpRequest req = HttpRequest.newBuilder()
.uri(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": "execute", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"]}, "clipped": false, "plan": [ {"id": "s1", "skill": "objmap-surface-real-objection", "name": "Surface the real objection"}, {"id": "s2", "skill": "voss-calibrated-questions", "name": "Calibrated questions"} ], "$refs": [ {"path": "private/playbooks.jsonl", "key": "objmap-surface-real-objection"}, {"path": "private/playbooks.jsonl", "key": "voss-calibrated-questions"} ] }"""))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
require "net/http"; require "json"
token = "YOUR_TOKEN"
uri = URI("https://api.skillsafe.ai/v1/app-api/run")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{token}"
req["Content-Type"] = "application/json"
req.body = { "task": "execute", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"]}, "clipped": false, "plan": [ {"id": "s1", "skill": "objmap-surface-real-objection", "name": "Surface the real objection"}, {"id": "s2", "skill": "voss-calibrated-questions", "name": "Calibrated questions"} ], "$refs": [ {"path": "private/playbooks.jsonl", "key": "objmap-surface-real-objection"}, {"path": "private/playbooks.jsonl", "key": "voss-calibrated-questions"} ] }.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts JSON.parse(res.body)
<?php
$token = "YOUR_TOKEN";
$ch = curl_init("https://api.skillsafe.ai/v1/app-api/run");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token", "Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "task": "execute", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"]}, "clipped": false, "plan": [ {"id": "s1", "skill": "objmap-surface-real-objection", "name": "Surface the real objection"}, {"id": "s2", "skill": "voss-calibrated-questions", "name": "Calibrated questions"} ], "$refs": [ {"path": "private/playbooks.jsonl", "key": "objmap-surface-real-objection"}, {"path": "private/playbooks.jsonl", "key": "voss-calibrated-questions"} ] }');
$out = json_decode(curl_exec($ch), true);
var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var content = new StringContent(@"{ ""task"": ""execute"", ""query"": ""Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent."", ""context"": """", ""prescan"": {""must_not"": [""set a discount precedent""]}, ""clipped"": false, ""plan"": [ {""id"": ""s1"", ""skill"": ""objmap-surface-real-objection"", ""name"": ""Surface the real objection""}, {""id"": ""s2"", ""skill"": ""voss-calibrated-questions"", ""name"": ""Calibrated questions""} ], ""$refs"": [ {""path"": ""private/playbooks.jsonl"", ""key"": ""objmap-surface-real-objection""}, {""path"": ""private/playbooks.jsonl"", ""key"": ""voss-calibrated-questions""} ] }", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/run", content);
var json = await res.Content.ReadAsStringAsync();
6. Stream it instead
Same contract as /run, delivered as SSE. From a browser this emits tick heartbeats and then one done carrying the whole output; token-by-token delta frames arrive for non-browser callers. Do not build a progress bar on deltas you may never receive.
curl -s -X POST https://api.skillsafe.ai/v1/app-api/run-stream \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"task": "plan",
"query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.",
"context": "",
"prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]},
"clipped": false,
"$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}]
}'
import json, urllib.request
TOKEN = "YOUR_TOKEN" # or read it from your own secret store
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/run-stream",
data=json.dumps({ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }).encode() if True else None,
headers={"Authorization": "Bearer " + TOKEN,
"Content-Type": "application/json"},
method="POST")
print(json.load(urllib.request.urlopen(req)))
const TOKEN = "YOUR_TOKEN";
const res = await fetch("https://api.skillsafe.ai/v1/app-api/run-stream", {
method: "POST",
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }),
});
const { ok, data, error } = await res.json();
if (!ok) throw new Error(error.message);
console.log(data);
token := "YOUR_TOKEN" // or os.Getenv of your own variable name
body := []byte(`{ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run-stream", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
String token = "YOUR_TOKEN";
HttpRequest req = HttpRequest.newBuilder()
.uri(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", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }"""))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
require "net/http"; require "json"
token = "YOUR_TOKEN"
uri = URI("https://api.skillsafe.ai/v1/app-api/run-stream")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{token}"
req["Content-Type"] = "application/json"
req.body = { "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts JSON.parse(res.body)
<?php
$token = "YOUR_TOKEN";
$ch = curl_init("https://api.skillsafe.ai/v1/app-api/run-stream");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token", "Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "task": "plan", "query": "Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent.", "context": "", "prescan": {"must_not": ["set a discount precedent"], "deadlines": ["11 days"], "figures": ["30%"]}, "clipped": false, "$refs": [{"path": "private/skills.jsonl", "q": "playable", "limit": 60}] }');
$out = json_decode(curl_exec($ch), true);
var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var content = new StringContent(@"{ ""task"": ""plan"", ""query"": ""Our biggest customer says they will churn unless we cut price 30%. Renewal is in 11 days and I do not want to set a discount precedent."", ""context"": """", ""prescan"": {""must_not"": [""set a discount precedent""], ""deadlines"": [""11 days""], ""figures"": [""30%""]}, ""clipped"": false, ""$refs"": [{""path"": ""private/skills.jsonl"", ""q"": ""playable"", ""limit"": 60}] }", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/run-stream", content);
var json = await res.Content.ReadAsStringAsync();