Driving Reg Router from code
Base URL https://api.skillsafe.ai/v1/app-api. Every reply is an envelope:
{"ok":true,"data":{...}} on success and
{"ok":false,"error":{"code","message","status","details"}} on failure.
Check ok before reading data.
The two beats
This app has no lanes a user picks. It has two calls: one proposes a plan, the other executes the
plan the user confirmed. Send task on every call.
| task | what it does | fields |
|---|---|---|
plan | Propose a plan | query |
execute | Write the memo | query, steps |
The run body is the input object. Wrapping it as
{"input":{...}} returns 200 and silently hides every field from the model.
Errors
| code | status | what it means |
|---|---|---|
unauthorized | 401 | No token, or the token was revoked. Mint a new one on the tokens page. |
forbidden | 403 | The token is valid but not allowed here — this is what a reference declared access:"run" returns to a browser. |
not_found | 404 | Unknown app or endpoint. A private app returns 404 rather than 403 to anyone who is not the publisher. |
validation_error | 400 | The input did not match the declared schema. details.violations names the field. |
insufficient_credits | 402 | Balance below min_credits. Call /estimate first and compare against /me. |
rate_limited | 429 | Back off and retry. Never tight-loop. |
Step 1 — get a token
Open the tokens page and copy the token this browser holds. Paste it
wherever these samples say YOUR_TOKEN.
Step 2 — who am I
/me carries only subject_type, subject_id and credits. Signed-in means subject_type === "user".
curl -s "https://api.skillsafe.ai/v1/app-api/me" -H "Authorization: Bearer YOUR_TOKEN"
import json, urllib.request
TOKEN = "YOUR_TOKEN"
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/me",
method="GET",
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as r:
print(json.load(r))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" },
});
console.log(await res.json());token := "YOUR_TOKEN"
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")
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.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
puts 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",
]);
echo curl_exec($ch);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");
Console.WriteLine(await res.Content.ReadAsStringAsync());Step 3 — price it first
/estimate costs nothing and creates no job. It returns hold_credits
(what is reserved, priced at the full output cap) and min_credits. Show the hold as
reserved, never as the price — the settled charge is usually far lower.
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":"We want to start posting client testimonials on our website."}'import json, urllib.request
TOKEN = "YOUR_TOKEN"
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/estimate",
method="POST",
data=json.dumps({
"task": "plan",
"query": "We want to start posting client testimonials on our website."
}).encode(),
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as r:
print(json.load(r))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": "We want to start posting client testimonials on our website."
}),
});
console.log(await res.json());token := "YOUR_TOKEN"
payload := []byte(`{"task":"plan","query":"We want to start posting client testimonials on our website."}`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/estimate", bytes.NewReader(payload))
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")
.POST(HttpRequest.BodyPublishers.ofString(
"""
{"task":"plan","query":"We want to start posting client testimonials on our website."}
"""))
.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\":\"We want to start posting client testimonials on our website.\"}.to_json rescue req.body = '{"task":"plan","query":"We want to start posting client testimonials on our website."}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
puts 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_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"task":"plan","query":"We want to start posting client testimonials on our website."}');
echo curl_exec($ch);var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var body = new StringContent(@"{""task"":""plan"",""query"":""We want to start posting client testimonials on our website.""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/estimate", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());Step 4 — run
Pass an Idempotency-Key header on every run. Replaying the same key returns the
stored result as plain JSON instead of a stream, and is not charged again.
1. task: "plan"
One sentence in, an ordered plan out. The reply is a single JSON object; there is no prose around it.
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":"We want to start posting client testimonials on our website."}'import json, urllib.request
TOKEN = "YOUR_TOKEN"
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/run",
method="POST",
data=json.dumps({
"task": "plan",
"query": "We want to start posting client testimonials on our website."
}).encode(),
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as r:
print(json.load(r))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": "We want to start posting client testimonials on our website."
}),
});
console.log(await res.json());token := "YOUR_TOKEN"
payload := []byte(`{"task":"plan","query":"We want to start posting client testimonials on our website."}`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run", bytes.NewReader(payload))
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")
.POST(HttpRequest.BodyPublishers.ofString(
"""
{"task":"plan","query":"We want to start posting client testimonials on our website."}
"""))
.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\":\"We want to start posting client testimonials on our website.\"}.to_json rescue req.body = '{"task":"plan","query":"We want to start posting client testimonials on our website."}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
puts 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_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"task":"plan","query":"We want to start posting client testimonials on our website."}');
echo curl_exec($ch);var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var body = new StringContent(@"{""task"":""plan"",""query"":""We want to start posting client testimonials on our website.""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/run", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());2. task: "execute"
The confirmed steps back in, the memo out. The reply is Markdown with one ## Step n — Name (id) heading per step.
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":"We want to start posting client testimonials on our website.","steps":"[{\"order\":1,\"id\":\"advice-line\",\"name\":\"Is this investment advice?\"},{\"order\":2,\"id\":\"marketing-rule-testimonial\",\"name\":\"Testimonial conditions\"}]"}'import json, urllib.request
TOKEN = "YOUR_TOKEN"
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/run",
method="POST",
data=json.dumps({
"task": "execute",
"query": "We want to start posting client testimonials on our website.",
"steps": "[{\"order\":1,\"id\":\"advice-line\",\"name\":\"Is this investment advice?\"},{\"order\":2,\"id\":\"marketing-rule-testimonial\",\"name\":\"Testimonial conditions\"}]"
}).encode(),
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as r:
print(json.load(r))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": "We want to start posting client testimonials on our website.",
"steps": "[{\"order\":1,\"id\":\"advice-line\",\"name\":\"Is this investment advice?\"},{\"order\":2,\"id\":\"marketing-rule-testimonial\",\"name\":\"Testimonial conditions\"}]"
}),
});
console.log(await res.json());token := "YOUR_TOKEN"
payload := []byte(`{"task":"execute","query":"We want to start posting client testimonials on our website.","steps":"[{\"order\":1,\"id\":\"advice-line\",\"name\":\"Is this investment advice?\"},{\"order\":2,\"id\":\"marketing-rule-testimonial\",\"name\":\"Testimonial conditions\"}]"}`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run", bytes.NewReader(payload))
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")
.POST(HttpRequest.BodyPublishers.ofString(
"""
{"task":"execute","query":"We want to start posting client testimonials on our website.","steps":"[{\"order\":1,\"id\":\"advice-line\",\"name\":\"Is this investment advice?\"},{\"order\":2,\"id\":\"marketing-rule-testimonial\",\"name\":\"Testimonial conditions\"}]"}
"""))
.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\":\"We want to start posting client testimonials on our website.\",\"steps\":\"[{\\"order\\":1,\\"id\\":\\"advice-line\\",\\"name\\":\\"Is this investment advice?\\"},{\\"order\\":2,\\"id\\":\\"marketing-rule-testimonial\\",\\"name\\":\\"Testimonial conditions\\"}]\"}.to_json rescue req.body = '{"task":"execute","query":"We want to start posting client testimonials on our website.","steps":"[{\"order\":1,\"id\":\"advice-line\",\"name\":\"Is this investment advice?\"},{\"order\":2,\"id\":\"marketing-rule-testimonial\",\"name\":\"Testimonial conditions\"}]"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
puts 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_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"task":"execute","query":"We want to start posting client testimonials on our website.","steps":"[{\"order\":1,\"id\":\"advice-line\",\"name\":\"Is this investment advice?\"},{\"order\":2,\"id\":\"marketing-rule-testimonial\",\"name\":\"Testimonial conditions\"}]"}');
echo curl_exec($ch);var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var body = new StringContent(@"{""task"":""execute"",""query"":""We want to start posting client testimonials on our website."",""steps"":""[{\""order\"":1,\""id\"":\""advice-line\"",\""name\"":\""Is this investment advice?\""},{\""order\"":2,\""id\"":\""marketing-rule-testimonial\"",\""name\"":\""Testimonial conditions\""}]""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/run", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());Step 5 — streaming
/run-stream is Server-Sent Events. From a browser it emits tick
heartbeats and then one done frame carrying the whole output — not token
deltas — so treat ticks as liveness and done as the result.
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":"We want to start posting client testimonials on our website."}'import json, urllib.request
TOKEN = "YOUR_TOKEN"
req = urllib.request.Request(
"https://api.skillsafe.ai/v1/app-api/run-stream",
method="POST",
data=json.dumps({
"task": "plan",
"query": "We want to start posting client testimonials on our website."
}).encode(),
headers={"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as r:
print(json.load(r))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": "We want to start posting client testimonials on our website."
}),
});
console.log(await res.json());token := "YOUR_TOKEN"
payload := []byte(`{"task":"plan","query":"We want to start posting client testimonials on our website."}`)
req, _ := http.NewRequest("POST", "https://api.skillsafe.ai/v1/app-api/run-stream", bytes.NewReader(payload))
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")
.POST(HttpRequest.BodyPublishers.ofString(
"""
{"task":"plan","query":"We want to start posting client testimonials on our website."}
"""))
.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\":\"We want to start posting client testimonials on our website.\"}.to_json rescue req.body = '{"task":"plan","query":"We want to start posting client testimonials on our website."}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
puts 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_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"task":"plan","query":"We want to start posting client testimonials on our website."}');
echo curl_exec($ch);var token = "YOUR_TOKEN";
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var body = new StringContent(@"{""task"":""plan"",""query"":""We want to start posting client testimonials on our website.""}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.skillsafe.ai/v1/app-api/run-stream", body);
Console.WriteLine(await res.Content.ReadAsStringAsync());What comes back
task: "plan" returns one JSON object with read, regimes,
steps[] (each with id, name, regime,
cite, why, needs and an optional alt),
skipped[] and ask.
task: "execute" returns Markdown: one ## Step n — Name (id) section per
confirmed step, each with Obligation, What to do,
Evidence to keep and Watch out, then
## Not triggered and ## First move.
On the catalogue
The procedures this app routes over live in a private reference corpus in the release, declared
access: "run". It is resolved server-side and appended to the model's context; it is
never served to a page and is not readable through this API. Asking for it returns
403.
Reg Router is a map of what to check with a chief compliance officer or counsel. It is not legal advice.