curl --request POST \
--url https://gateway.errorbar.ai/v1/reward/sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reward": {
"mode": "single",
"criterionId": "<string>"
},
"rewardBudgetUsd": 123,
"agentic": false,
"ttlHours": 72,
"label": "<string>",
"tasks": [
{
"goal": [
{
"role": "<string>",
"content": "<string>"
}
],
"image": "<string>",
"verifier": [
{
"command": "<string>",
"timeout_sec": 123
}
]
}
]
}
'import requests
url = "https://gateway.errorbar.ai/v1/reward/sessions"
payload = {
"reward": {
"mode": "single",
"criterionId": "<string>"
},
"rewardBudgetUsd": 123,
"agentic": False,
"ttlHours": 72,
"label": "<string>",
"tasks": [
{
"goal": [
{
"role": "<string>",
"content": "<string>"
}
],
"image": "<string>",
"verifier": [
{
"command": "<string>",
"timeout_sec": 123
}
]
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
reward: {mode: 'single', criterionId: '<string>'},
rewardBudgetUsd: 123,
agentic: false,
ttlHours: 72,
label: '<string>',
tasks: [
{
goal: [{role: '<string>', content: '<string>'}],
image: '<string>',
verifier: [{command: '<string>', timeout_sec: 123}]
}
]
})
};
fetch('https://gateway.errorbar.ai/v1/reward/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.errorbar.ai/v1/reward/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reward' => [
'mode' => 'single',
'criterionId' => '<string>'
],
'rewardBudgetUsd' => 123,
'agentic' => false,
'ttlHours' => 72,
'label' => '<string>',
'tasks' => [
[
'goal' => [
[
'role' => '<string>',
'content' => '<string>'
]
],
'image' => '<string>',
'verifier' => [
[
'command' => '<string>',
'timeout_sec' => 123
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.errorbar.ai/v1/reward/sessions"
payload := strings.NewReader("{\n \"reward\": {\n \"mode\": \"single\",\n \"criterionId\": \"<string>\"\n },\n \"rewardBudgetUsd\": 123,\n \"agentic\": false,\n \"ttlHours\": 72,\n \"label\": \"<string>\",\n \"tasks\": [\n {\n \"goal\": [\n {\n \"role\": \"<string>\",\n \"content\": \"<string>\"\n }\n ],\n \"image\": \"<string>\",\n \"verifier\": [\n {\n \"command\": \"<string>\",\n \"timeout_sec\": 123\n }\n ]\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.errorbar.ai/v1/reward/sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reward\": {\n \"mode\": \"single\",\n \"criterionId\": \"<string>\"\n },\n \"rewardBudgetUsd\": 123,\n \"agentic\": false,\n \"ttlHours\": 72,\n \"label\": \"<string>\",\n \"tasks\": [\n {\n \"goal\": [\n {\n \"role\": \"<string>\",\n \"content\": \"<string>\"\n }\n ],\n \"image\": \"<string>\",\n \"verifier\": [\n {\n \"command\": \"<string>\",\n \"timeout_sec\": 123\n }\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.errorbar.ai/v1/reward/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reward\": {\n \"mode\": \"single\",\n \"criterionId\": \"<string>\"\n },\n \"rewardBudgetUsd\": 123,\n \"agentic\": false,\n \"ttlHours\": 72,\n \"label\": \"<string>\",\n \"tasks\": [\n {\n \"goal\": [\n {\n \"role\": \"<string>\",\n \"content\": \"<string>\"\n }\n ],\n \"image\": \"<string>\",\n \"verifier\": [\n {\n \"command\": \"<string>\",\n \"timeout_sec\": 123\n }\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "ACTIVE",
"agentic": true,
"reward": {
"mode": "single",
"criterionId": "<string>"
},
"label": "<string>",
"budget_usd": 123,
"spent_usd": 123,
"expires_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"stopped_at": "2023-11-07T05:31:56Z",
"certificates": [
{}
],
"anchor": {
"criterion_id": "<string>",
"criterion_name": "<string>",
"held": true,
"held_at": "2023-11-07T05:31:56Z",
"held_reason": "<string>",
"pinned_step": "<string>",
"checks": 123,
"history": [
{
"step": "<string>",
"at": "2023-11-07T05:31:56Z",
"n": 123,
"reward_rate": 123,
"anchor_rate": 123,
"anchor_ci": [
123
],
"anchor_corrected": true,
"masked": 123
}
]
},
"task_count": 123
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "Invalid API key",
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}{
"error": {
"message": "Insufficient balance: deploying this endpoint requires at least 1h of runway. Top up and try again.",
"type": "insufficient_quota",
"code": "insufficient_balance"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}Create a reward session
Register the certified reward for YOUR trainer. The reward is validated first (calibrated, non-drift-flagged, population-bound judges — refused with the reason otherwise), the budget is held in the wallet, and the response carries every judge’s signed certificate so the trainer holds the grader’s error rate before the first rollout is scored. Optional anchor: an independent judge the run is checked against mid-run (POST …/anchor). Requires an owner/admin key with platform:write. errorbar never runs the training — that is what makes the certificate independent.
curl --request POST \
--url https://gateway.errorbar.ai/v1/reward/sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reward": {
"mode": "single",
"criterionId": "<string>"
},
"rewardBudgetUsd": 123,
"agentic": false,
"ttlHours": 72,
"label": "<string>",
"tasks": [
{
"goal": [
{
"role": "<string>",
"content": "<string>"
}
],
"image": "<string>",
"verifier": [
{
"command": "<string>",
"timeout_sec": 123
}
]
}
]
}
'import requests
url = "https://gateway.errorbar.ai/v1/reward/sessions"
payload = {
"reward": {
"mode": "single",
"criterionId": "<string>"
},
"rewardBudgetUsd": 123,
"agentic": False,
"ttlHours": 72,
"label": "<string>",
"tasks": [
{
"goal": [
{
"role": "<string>",
"content": "<string>"
}
],
"image": "<string>",
"verifier": [
{
"command": "<string>",
"timeout_sec": 123
}
]
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
reward: {mode: 'single', criterionId: '<string>'},
rewardBudgetUsd: 123,
agentic: false,
ttlHours: 72,
label: '<string>',
tasks: [
{
goal: [{role: '<string>', content: '<string>'}],
image: '<string>',
verifier: [{command: '<string>', timeout_sec: 123}]
}
]
})
};
fetch('https://gateway.errorbar.ai/v1/reward/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.errorbar.ai/v1/reward/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reward' => [
'mode' => 'single',
'criterionId' => '<string>'
],
'rewardBudgetUsd' => 123,
'agentic' => false,
'ttlHours' => 72,
'label' => '<string>',
'tasks' => [
[
'goal' => [
[
'role' => '<string>',
'content' => '<string>'
]
],
'image' => '<string>',
'verifier' => [
[
'command' => '<string>',
'timeout_sec' => 123
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.errorbar.ai/v1/reward/sessions"
payload := strings.NewReader("{\n \"reward\": {\n \"mode\": \"single\",\n \"criterionId\": \"<string>\"\n },\n \"rewardBudgetUsd\": 123,\n \"agentic\": false,\n \"ttlHours\": 72,\n \"label\": \"<string>\",\n \"tasks\": [\n {\n \"goal\": [\n {\n \"role\": \"<string>\",\n \"content\": \"<string>\"\n }\n ],\n \"image\": \"<string>\",\n \"verifier\": [\n {\n \"command\": \"<string>\",\n \"timeout_sec\": 123\n }\n ]\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.errorbar.ai/v1/reward/sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reward\": {\n \"mode\": \"single\",\n \"criterionId\": \"<string>\"\n },\n \"rewardBudgetUsd\": 123,\n \"agentic\": false,\n \"ttlHours\": 72,\n \"label\": \"<string>\",\n \"tasks\": [\n {\n \"goal\": [\n {\n \"role\": \"<string>\",\n \"content\": \"<string>\"\n }\n ],\n \"image\": \"<string>\",\n \"verifier\": [\n {\n \"command\": \"<string>\",\n \"timeout_sec\": 123\n }\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.errorbar.ai/v1/reward/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reward\": {\n \"mode\": \"single\",\n \"criterionId\": \"<string>\"\n },\n \"rewardBudgetUsd\": 123,\n \"agentic\": false,\n \"ttlHours\": 72,\n \"label\": \"<string>\",\n \"tasks\": [\n {\n \"goal\": [\n {\n \"role\": \"<string>\",\n \"content\": \"<string>\"\n }\n ],\n \"image\": \"<string>\",\n \"verifier\": [\n {\n \"command\": \"<string>\",\n \"timeout_sec\": 123\n }\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "ACTIVE",
"agentic": true,
"reward": {
"mode": "single",
"criterionId": "<string>"
},
"label": "<string>",
"budget_usd": 123,
"spent_usd": 123,
"expires_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"stopped_at": "2023-11-07T05:31:56Z",
"certificates": [
{}
],
"anchor": {
"criterion_id": "<string>",
"criterion_name": "<string>",
"held": true,
"held_at": "2023-11-07T05:31:56Z",
"held_reason": "<string>",
"pinned_step": "<string>",
"checks": 123,
"history": [
{
"step": "<string>",
"at": "2023-11-07T05:31:56Z",
"n": 123,
"reward_rate": 123,
"anchor_rate": 123,
"anchor_ci": [
123
],
"anchor_corrected": true,
"masked": 123
}
]
},
"task_count": 123
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}{
"error": {
"message": "Invalid API key",
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}{
"error": {
"message": "Insufficient balance: deploying this endpoint requires at least 1h of runway. Top up and try again.",
"type": "insufficient_quota",
"code": "insufficient_balance"
}
}{
"error": {
"message": "<string>",
"type": "<string>",
"code": "<string>"
}
}Authorizations
Your workspace API key, e.g. sk_sovereign_..., sent as Authorization: Bearer <key>.
Body
- Option 1
- Option 2
Show child attributes
Show child attributes
Held in the wallet at creation; released on stop, expiry or exhaustion. Max 10000.
Whole-trajectory rewards need trace-unit judges; single-turn rewards need request-unit ones.
Session expiry (max 720). Scoring past it is refused and the hold released.
120Show child attributes
Show child attributes
Optional taskset (≤ 2,000). Stored on the session so GET /v1/reward/sessions/{id}/environment?format=tasks hands back tasks.jsonl.
Show child attributes
Show child attributes
Response
Created, with certificates.
OVERBUDGET: the reward budget's kill switch fired. STOPPED: stopped by you or expired.
ACTIVE, COMPLETED, OVERBUDGET, STOPPED, FAILED - Option 1
- Option 2
Show child attributes
Show child attributes
Ledger-true judge spend so far.
One signed judge certificate per reward criterion (see GET /v1/criteria/{id}/certificate): sensitivity, specificity, κ with intervals, trust, what voids it.
Show child attributes
Show child attributes
Tasks stored on the session (0 when the trainer keeps its own).