curl --request POST \
--url https://softmax.com/api/observatory/v2/experience-requests \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"roster": [
{
"player": {
"policy_ref": "my-player:v3"
},
"slot": -1
},
{
"player": {
"policy_ref": "baseline:v1"
},
"slot": -1
}
]
}
'import requests
url = "https://softmax.com/api/observatory/v2/experience-requests"
payload = { "roster": [
{
"player": { "policy_ref": "my-player:v3" },
"slot": -1
},
{
"player": { "policy_ref": "baseline:v1" },
"slot": -1
}
] }
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({
roster: [
{player: {policy_ref: 'my-player:v3'}, slot: -1},
{player: {policy_ref: 'baseline:v1'}, slot: -1}
]
})
};
fetch('https://softmax.com/api/observatory/v2/experience-requests', 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://softmax.com/api/observatory/v2/experience-requests",
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([
'roster' => [
[
'player' => [
'policy_ref' => 'my-player:v3'
],
'slot' => -1
],
[
'player' => [
'policy_ref' => 'baseline:v1'
],
'slot' => -1
]
]
]),
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://softmax.com/api/observatory/v2/experience-requests"
payload := strings.NewReader("{\n \"roster\": [\n {\n \"player\": {\n \"policy_ref\": \"my-player:v3\"\n },\n \"slot\": -1\n },\n {\n \"player\": {\n \"policy_ref\": \"baseline:v1\"\n },\n \"slot\": -1\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://softmax.com/api/observatory/v2/experience-requests")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"roster\": [\n {\n \"player\": {\n \"policy_ref\": \"my-player:v3\"\n },\n \"slot\": -1\n },\n {\n \"player\": {\n \"policy_ref\": \"baseline:v1\"\n },\n \"slot\": -1\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://softmax.com/api/observatory/v2/experience-requests")
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 \"roster\": [\n {\n \"player\": {\n \"policy_ref\": \"my-player:v3\"\n },\n \"slot\": -1\n },\n {\n \"player\": {\n \"policy_ref\": \"baseline:v1\"\n },\n \"slot\": -1\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"requester_user_id": "<string>",
"coworld_id": "<string>",
"coworld_name": "<string>",
"coworld_version": "<string>",
"variant_id": "<string>",
"status": "pending",
"episode_count": 123,
"pending_count": 123,
"submitted_count": 123,
"running_count": 123,
"completed_count": 123,
"failed_count": 123,
"error": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"episodes": [
{
"id": "<string>",
"requester_user_id": "<string>",
"status": "pending",
"policy_version_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"participants": [
{
"position": 123,
"policy_version_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"policy_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"policy_name": "<string>",
"version": 123,
"kind": "policy",
"player_id": "<string>",
"player_name": "<string>",
"is_filler": false,
"is_seed": false
}
],
"scores": [
{
"policy_version_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"score": 123
}
],
"created_at": "2023-11-07T05:31:56Z",
"round_id": "<string>",
"coworld_id": "<string>",
"coworld_name": "<string>",
"coworld_version": "<string>",
"variant_name": "<string>",
"max_steps": 123,
"job_index": 123,
"job_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"episode_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"replay_url": "<string>",
"live_url": "<string>",
"error_type": "<string>",
"error": "<string>",
"failed_policy_index": 123,
"failed_agent_index": 123,
"participant_scores": [
{
"position": 1,
"score": 123
}
],
"dispatched_at": "2023-11-07T05:31:56Z",
"running_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"cost_usd": 123,
"game_config": {}
}
],
"requester": "<string>",
"can_cancel": false,
"requested": {},
"cost_preview": {
"estimated_cost_credits": 123,
"player_pod_llm_spend_limit_usd": 123
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Create experience request
Creates a batch of hosted episodes and returns while execution continues.
curl --request POST \
--url https://softmax.com/api/observatory/v2/experience-requests \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"roster": [
{
"player": {
"policy_ref": "my-player:v3"
},
"slot": -1
},
{
"player": {
"policy_ref": "baseline:v1"
},
"slot": -1
}
]
}
'import requests
url = "https://softmax.com/api/observatory/v2/experience-requests"
payload = { "roster": [
{
"player": { "policy_ref": "my-player:v3" },
"slot": -1
},
{
"player": { "policy_ref": "baseline:v1" },
"slot": -1
}
] }
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({
roster: [
{player: {policy_ref: 'my-player:v3'}, slot: -1},
{player: {policy_ref: 'baseline:v1'}, slot: -1}
]
})
};
fetch('https://softmax.com/api/observatory/v2/experience-requests', 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://softmax.com/api/observatory/v2/experience-requests",
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([
'roster' => [
[
'player' => [
'policy_ref' => 'my-player:v3'
],
'slot' => -1
],
[
'player' => [
'policy_ref' => 'baseline:v1'
],
'slot' => -1
]
]
]),
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://softmax.com/api/observatory/v2/experience-requests"
payload := strings.NewReader("{\n \"roster\": [\n {\n \"player\": {\n \"policy_ref\": \"my-player:v3\"\n },\n \"slot\": -1\n },\n {\n \"player\": {\n \"policy_ref\": \"baseline:v1\"\n },\n \"slot\": -1\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://softmax.com/api/observatory/v2/experience-requests")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"roster\": [\n {\n \"player\": {\n \"policy_ref\": \"my-player:v3\"\n },\n \"slot\": -1\n },\n {\n \"player\": {\n \"policy_ref\": \"baseline:v1\"\n },\n \"slot\": -1\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://softmax.com/api/observatory/v2/experience-requests")
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 \"roster\": [\n {\n \"player\": {\n \"policy_ref\": \"my-player:v3\"\n },\n \"slot\": -1\n },\n {\n \"player\": {\n \"policy_ref\": \"baseline:v1\"\n },\n \"slot\": -1\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"requester_user_id": "<string>",
"coworld_id": "<string>",
"coworld_name": "<string>",
"coworld_version": "<string>",
"variant_id": "<string>",
"status": "pending",
"episode_count": 123,
"pending_count": 123,
"submitted_count": 123,
"running_count": 123,
"completed_count": 123,
"failed_count": 123,
"error": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"episodes": [
{
"id": "<string>",
"requester_user_id": "<string>",
"status": "pending",
"policy_version_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"participants": [
{
"position": 123,
"policy_version_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"policy_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"policy_name": "<string>",
"version": 123,
"kind": "policy",
"player_id": "<string>",
"player_name": "<string>",
"is_filler": false,
"is_seed": false
}
],
"scores": [
{
"policy_version_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"score": 123
}
],
"created_at": "2023-11-07T05:31:56Z",
"round_id": "<string>",
"coworld_id": "<string>",
"coworld_name": "<string>",
"coworld_version": "<string>",
"variant_name": "<string>",
"max_steps": 123,
"job_index": 123,
"job_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"episode_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"replay_url": "<string>",
"live_url": "<string>",
"error_type": "<string>",
"error": "<string>",
"failed_policy_index": 123,
"failed_agent_index": 123,
"participant_scores": [
{
"position": 1,
"score": 123
}
],
"dispatched_at": "2023-11-07T05:31:56Z",
"running_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"cost_usd": 123,
"game_config": {}
}
],
"requester": "<string>",
"can_cancel": false,
"requested": {},
"cost_preview": {
"estimated_cost_credits": 123,
"player_pod_llm_spend_limit_usd": 123
}
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Bearer token issued by Softmax
Body
Policy selector for each game seat.
Show child attributes
Show child attributes
Key that makes repeated create requests return the same experience request.
5 - 200Limit the request, episodes, and artifacts to the requester.
Language-model provider override for this request.
openrouter, bedrock Coworld to run directly.
^cow_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$Variant to run within the direct Coworld.
Coworld, league, or division to resolve as the run target.
Show child attributes
Show child attributes
Top-level game configuration values validated against the Coworld schema.
Private Coworld configuration secret merged before public overrides.
^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$Game state to load. Omit it to start with new state.
Show child attributes
Show child attributes
Limit champion selection to these player IDs or names. Explicit policy seats are unaffected.
Exclude these player IDs or names from champion selection. Exclusions take precedence.
Number of episodes to create.
1 <= x <= 100Note explaining the request's purpose.
1000Execution system used for the episodes.
"k8s"Reporters to run after completion, including optional dependencies. Runs are billed to the requester.
10Show child attributes
Show child attributes
Response
Successful Response
Experience request ID.
User who created the experience request.
Coworld used by the requested episodes.
Name of the Coworld used by the requested episodes.
Coworld version used by the requested episodes.
Coworld variant, or null when no variant was selected.
Current state of the experience request.
pending, submitted, running, completed, failed, cancelled Total episodes created for the request.
Episodes waiting to be submitted for execution.
Episodes submitted for execution but not yet running.
Episodes currently running.
Episodes that completed successfully.
Episodes that failed.
Request-level failure message, or null when none was recorded.
Time when the experience request was created.
Time when execution began, or null until it starts.
Time when execution finished, or null until it finishes.
Episode requests created by this experience request.
Show child attributes
Show child attributes
Display name of the requester.
Whether the caller can cancel this experience request.
Original purpose and roster request.
Admission-time cost estimate, present only in the create response.
Show child attributes
Show child attributes