Submit task
curl --request POST \
--url https://api.example.com/v1/tasks \
--header 'Content-Type: application/json' \
--data '
{
"endUserId": "<string>",
"task": "<string>",
"sessionId": "<string>",
"startUrl": "<string>",
"schema": {},
"maxSteps": 123,
"include_html_dump": true
}
'import requests
url = "https://api.example.com/v1/tasks"
payload = {
"endUserId": "<string>",
"task": "<string>",
"sessionId": "<string>",
"startUrl": "<string>",
"schema": {},
"maxSteps": 123,
"include_html_dump": True
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
endUserId: '<string>',
task: '<string>',
sessionId: '<string>',
startUrl: '<string>',
schema: {},
maxSteps: 123,
include_html_dump: true
})
};
fetch('https://api.example.com/v1/tasks', 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://api.example.com/v1/tasks",
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([
'endUserId' => '<string>',
'task' => '<string>',
'sessionId' => '<string>',
'startUrl' => '<string>',
'schema' => [
],
'maxSteps' => 123,
'include_html_dump' => true
]),
CURLOPT_HTTPHEADER => [
"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://api.example.com/v1/tasks"
payload := strings.NewReader("{\n \"endUserId\": \"<string>\",\n \"task\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"startUrl\": \"<string>\",\n \"schema\": {},\n \"maxSteps\": 123,\n \"include_html_dump\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
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://api.example.com/v1/tasks")
.header("Content-Type", "application/json")
.body("{\n \"endUserId\": \"<string>\",\n \"task\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"startUrl\": \"<string>\",\n \"schema\": {},\n \"maxSteps\": 123,\n \"include_html_dump\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/tasks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"endUserId\": \"<string>\",\n \"task\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"startUrl\": \"<string>\",\n \"schema\": {},\n \"maxSteps\": 123,\n \"include_html_dump\": true\n}"
response = http.request(request)
puts response.read_body{
"taskId": "<string>",
"sessionId": "<string>",
"status": "<string>",
"createdAt": {}
}Tasks
Submit task
Submit a new task. Returns immediately with a taskId; poll GET /v1/tasks/ for the result.
POST
/
v1
/
tasks
Submit task
curl --request POST \
--url https://api.example.com/v1/tasks \
--header 'Content-Type: application/json' \
--data '
{
"endUserId": "<string>",
"task": "<string>",
"sessionId": "<string>",
"startUrl": "<string>",
"schema": {},
"maxSteps": 123,
"include_html_dump": true
}
'import requests
url = "https://api.example.com/v1/tasks"
payload = {
"endUserId": "<string>",
"task": "<string>",
"sessionId": "<string>",
"startUrl": "<string>",
"schema": {},
"maxSteps": 123,
"include_html_dump": True
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
endUserId: '<string>',
task: '<string>',
sessionId: '<string>',
startUrl: '<string>',
schema: {},
maxSteps: 123,
include_html_dump: true
})
};
fetch('https://api.example.com/v1/tasks', 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://api.example.com/v1/tasks",
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([
'endUserId' => '<string>',
'task' => '<string>',
'sessionId' => '<string>',
'startUrl' => '<string>',
'schema' => [
],
'maxSteps' => 123,
'include_html_dump' => true
]),
CURLOPT_HTTPHEADER => [
"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://api.example.com/v1/tasks"
payload := strings.NewReader("{\n \"endUserId\": \"<string>\",\n \"task\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"startUrl\": \"<string>\",\n \"schema\": {},\n \"maxSteps\": 123,\n \"include_html_dump\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
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://api.example.com/v1/tasks")
.header("Content-Type", "application/json")
.body("{\n \"endUserId\": \"<string>\",\n \"task\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"startUrl\": \"<string>\",\n \"schema\": {},\n \"maxSteps\": 123,\n \"include_html_dump\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/tasks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"endUserId\": \"<string>\",\n \"task\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"startUrl\": \"<string>\",\n \"schema\": {},\n \"maxSteps\": 123,\n \"include_html_dump\": true\n}"
response = http.request(request)
puts response.read_body{
"taskId": "<string>",
"sessionId": "<string>",
"status": "<string>",
"createdAt": {}
}Request body
string
required
Opaque identifier for the user this task runs on behalf of. See End users. Must be ≤ 256 characters.
string
required
The natural-language prompt. Must be non-empty after trimming.
string
Pass a previous task’s
sessionId to continue a conversation. Omit to start a new session (server mints one and returns it).string
If you know the specific page to start from, pass the URL. Skips the agent’s URL-discovery step.
object
A JSON Schema describing the shape of structured data you want back. When set, the completed task’s
structured_content field contains the conforming object.number
default:"25"
Upper bound on agent steps before the task is forced to finalize. Server clamps to
min(maxSteps, 25).boolean
default:"false"
If true, the last page’s raw HTML is returned on the final task record as
html_dump.Response — 201 Created
string
Newly-created task identifier.
string
Either the session you passed in, or a newly-minted one if you omitted
sessionId.string
Always
"pending" on submission. Poll GET /v1/tasks/{taskId} for terminal state.string (ISO 8601)
Task creation timestamp.
Example
curl "$API_BASE/tasks" -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"endUserId": "alice",
"task": "What is the current top story on Hacker News?"
}'
from stablebrowse import Stablebrowse
client = Stablebrowse()
submission = client.tasks.submit(
end_user_id="alice",
task="What is the current top story on Hacker News?",
)
print(submission.task_id)
import { Stablebrowse } from "@stablebrowse/client";
const client = new Stablebrowse();
const submission = await client.tasks.submit({
endUserId: "alice",
task: "What is the current top story on Hacker News?",
});
console.log(submission.taskId);
Response
{
"taskId": "7f2a...",
"sessionId": "a31d...",
"status": "pending",
"createdAt": "2026-04-21T04:55:34Z"
}
The Python and TypeScript SDKs also offer
tasks.run(...) which submits + polls + returns the completed task in one call. Prefer it over submit + manual polling unless you’re building your own streaming UI.Errors
| Code | Meaning |
|---|---|
400 | task missing or empty, endUserId missing or > 256 chars, invalid JSON body, sessionId owned by another business |
401 | Missing Authorization header |
403 | Revoked API key, or attempt to submit into another business’s sessionId |
429 | Rate limit or quota exceeded; see the response body for specifics |
