curl --request POST \
--url https://origami.chat/api/v2/agents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "<string>",
"name": "<string>",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"focusTableIds": [],
"attachments": []
}
'import requests
url = "https://origami.chat/api/v2/agents"
payload = {
"prompt": "<string>",
"name": "<string>",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"focusTableIds": [],
"attachments": []
}
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({
prompt: '<string>',
name: '<string>',
workspaceId: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
focusTableIds: [],
attachments: []
})
};
fetch('https://origami.chat/api/v2/agents', 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://origami.chat/api/v2/agents",
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([
'prompt' => '<string>',
'name' => '<string>',
'workspaceId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'focusTableIds' => [
],
'attachments' => [
]
]),
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://origami.chat/api/v2/agents"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"name\": \"<string>\",\n \"workspaceId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"focusTableIds\": [],\n \"attachments\": []\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://origami.chat/api/v2/agents")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"name\": \"<string>\",\n \"workspaceId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"focusTableIds\": [],\n \"attachments\": []\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://origami.chat/api/v2/agents")
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 \"prompt\": \"<string>\",\n \"name\": \"<string>\",\n \"workspaceId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"focusTableIds\": [],\n \"attachments\": []\n}"
response = http.request(request)
puts response.read_body{
"agent": {
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"createdAt": "2023-11-07T05:31:56Z"
},
"run": {
"object": "<string>",
"id": "<string>",
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"prompt": "<string>",
"steps": {
"completed": 1,
"max": 2
},
"startedAt": "2023-11-07T05:31:56Z",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"request": {
"prompt": "<string>",
"focusTableIds": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
]
},
"response": {
"text": "<string>",
"actions": [
{
"tableId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tableName": "<string>",
"columnId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"columnName": "<string>",
"count": 123,
"leadCount": 123,
"deletedAt": "2023-11-07T05:31:56Z"
}
],
"tables": [
{
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"leadCount": 123,
"columns": [
{
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"type": "<string>",
"slug": "<string>",
"autoTrigger": true,
"credits": {
"lifetimeUsed": 123
},
"cells": {
"running": 1,
"errored": 1
},
"stats": {
"avgCreditsPerRun": 123,
"callRate": 0.5,
"totalRuns": 123
},
"qualification": {
"pass": 123,
"fail": 123,
"unsure": 123,
"total": 123
}
}
],
"credits": {
"lifetimeUsed": 123
},
"cells": {
"running": 1,
"errored": 1
},
"url": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"stats": {
"creditsPerLead": 123,
"creditsPerQualifiedLead": 123,
"findMoreEstimatedCredits": 123,
"qualification": {
"rate": 0.5,
"fetchRate": 0.5,
"qualifiedLeads": 123,
"effectiveLeadsPerQualified": 123,
"estimatedQualifiedLeads": 123
},
"funnel": {
"totalSourcedLeads": 123,
"postStaticLeads": 123,
"dedupedLeads": 123,
"dedupRate": 0.5,
"excludedLeads": 123,
"excludedRate": 0.5
},
"running": {
"runningLeads": 123,
"oldestActiveRunStartedAt": "2023-11-07T05:31:56Z"
},
"leadSources": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"avgCreditsPerLead": 123,
"totalCredits": 123,
"totalLeads": 123
}
],
"hasUnknownTotalWithMore": true
}
}
],
"transcriptTruncated": true,
"transcript": [
{
"content": "<string>",
"toolCalls": [
{
"id": "<string>",
"name": "<string>",
"input": "<unknown>"
}
],
"toolCallId": "<string>",
"name": "<string>",
"result": "<string>",
"truncated": true
}
]
},
"todo": {
"pendingQuestions": [
{
"question": "<string>",
"suggestedAnswers": [
"<string>"
],
"freeformOption": "Or something else"
}
],
"nextActions": [
{
"label": "<string>",
"tableSlug": "<string>"
}
]
},
"completedAt": "2023-11-07T05:31:56Z"
},
"workspace": {
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"createdByApi": true
}
}{
"error": "Invalid request body",
"code": "VALIDATION_ERROR",
"details": {
"issues": [
{
"path": "prompt",
"message": "Required"
}
]
}
}{
"error": "Missing API key",
"code": "UNAUTHORIZED"
}{
"error": "Insufficient credits",
"code": "INSUFFICIENT_CREDITS",
"creditsRequired": 5,
"creditsAvailable": 2,
"topUpUrl": "https://origami.chat/settings/billing?source=api",
"message": "Origami needs at least 5 credits to start any run; you have 2.\nTop up: https://origami.chat/settings/billing?source=api\n"
}{
"error": "Workspace limit reached (10/10). Pass an existing workspaceId or upgrade your plan.",
"code": "WORKSPACE_LIMIT_REACHED"
}{
"error": "<string>",
"code": "CONCURRENT_LIMIT_EXCEEDED",
"limit": 123,
"activeSessions": [
{
"agentId": "<string>",
"name": "<string>",
"startedAt": "2023-11-07T05:31:56Z"
}
],
"canUpgrade": true
}Create an agent and admit its first run
Creates a new agent (and, if workspaceId is null and no
focusTableIds are passed, an auto-created workspace), inserts
a synthetic user message carrying the prompt, claims the
per-org concurrent slot, and spawns the agent work in the
background. Responds 202 Accepted with the initial run
object (status: "running"). Poll
GET /agents/{id}/runs/{runId} until status !== "running".
curl --request POST \
--url https://origami.chat/api/v2/agents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "<string>",
"name": "<string>",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"focusTableIds": [],
"attachments": []
}
'import requests
url = "https://origami.chat/api/v2/agents"
payload = {
"prompt": "<string>",
"name": "<string>",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"focusTableIds": [],
"attachments": []
}
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({
prompt: '<string>',
name: '<string>',
workspaceId: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
focusTableIds: [],
attachments: []
})
};
fetch('https://origami.chat/api/v2/agents', 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://origami.chat/api/v2/agents",
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([
'prompt' => '<string>',
'name' => '<string>',
'workspaceId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'focusTableIds' => [
],
'attachments' => [
]
]),
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://origami.chat/api/v2/agents"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"name\": \"<string>\",\n \"workspaceId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"focusTableIds\": [],\n \"attachments\": []\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://origami.chat/api/v2/agents")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"name\": \"<string>\",\n \"workspaceId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"focusTableIds\": [],\n \"attachments\": []\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://origami.chat/api/v2/agents")
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 \"prompt\": \"<string>\",\n \"name\": \"<string>\",\n \"workspaceId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"focusTableIds\": [],\n \"attachments\": []\n}"
response = http.request(request)
puts response.read_body{
"agent": {
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"createdAt": "2023-11-07T05:31:56Z"
},
"run": {
"object": "<string>",
"id": "<string>",
"agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"prompt": "<string>",
"steps": {
"completed": 1,
"max": 2
},
"startedAt": "2023-11-07T05:31:56Z",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"request": {
"prompt": "<string>",
"focusTableIds": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
]
},
"response": {
"text": "<string>",
"actions": [
{
"tableId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tableName": "<string>",
"columnId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"columnName": "<string>",
"count": 123,
"leadCount": 123,
"deletedAt": "2023-11-07T05:31:56Z"
}
],
"tables": [
{
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"workspaceId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"leadCount": 123,
"columns": [
{
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"type": "<string>",
"slug": "<string>",
"autoTrigger": true,
"credits": {
"lifetimeUsed": 123
},
"cells": {
"running": 1,
"errored": 1
},
"stats": {
"avgCreditsPerRun": 123,
"callRate": 0.5,
"totalRuns": 123
},
"qualification": {
"pass": 123,
"fail": 123,
"unsure": 123,
"total": 123
}
}
],
"credits": {
"lifetimeUsed": 123
},
"cells": {
"running": 1,
"errored": 1
},
"url": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"stats": {
"creditsPerLead": 123,
"creditsPerQualifiedLead": 123,
"findMoreEstimatedCredits": 123,
"qualification": {
"rate": 0.5,
"fetchRate": 0.5,
"qualifiedLeads": 123,
"effectiveLeadsPerQualified": 123,
"estimatedQualifiedLeads": 123
},
"funnel": {
"totalSourcedLeads": 123,
"postStaticLeads": 123,
"dedupedLeads": 123,
"dedupRate": 0.5,
"excludedLeads": 123,
"excludedRate": 0.5
},
"running": {
"runningLeads": 123,
"oldestActiveRunStartedAt": "2023-11-07T05:31:56Z"
},
"leadSources": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"avgCreditsPerLead": 123,
"totalCredits": 123,
"totalLeads": 123
}
],
"hasUnknownTotalWithMore": true
}
}
],
"transcriptTruncated": true,
"transcript": [
{
"content": "<string>",
"toolCalls": [
{
"id": "<string>",
"name": "<string>",
"input": "<unknown>"
}
],
"toolCallId": "<string>",
"name": "<string>",
"result": "<string>",
"truncated": true
}
]
},
"todo": {
"pendingQuestions": [
{
"question": "<string>",
"suggestedAnswers": [
"<string>"
],
"freeformOption": "Or something else"
}
],
"nextActions": [
{
"label": "<string>",
"tableSlug": "<string>"
}
]
},
"completedAt": "2023-11-07T05:31:56Z"
},
"workspace": {
"object": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"createdByApi": true
}
}{
"error": "Invalid request body",
"code": "VALIDATION_ERROR",
"details": {
"issues": [
{
"path": "prompt",
"message": "Required"
}
]
}
}{
"error": "Missing API key",
"code": "UNAUTHORIZED"
}{
"error": "Insufficient credits",
"code": "INSUFFICIENT_CREDITS",
"creditsRequired": 5,
"creditsAvailable": 2,
"topUpUrl": "https://origami.chat/settings/billing?source=api",
"message": "Origami needs at least 5 credits to start any run; you have 2.\nTop up: https://origami.chat/settings/billing?source=api\n"
}{
"error": "Workspace limit reached (10/10). Pass an existing workspaceId or upgrade your plan.",
"code": "WORKSPACE_LIMIT_REACHED"
}{
"error": "<string>",
"code": "CONCURRENT_LIMIT_EXCEEDED",
"limit": 123,
"activeSessions": [
{
"agentId": "<string>",
"name": "<string>",
"startedAt": "2023-11-07T05:31:56Z"
}
],
"canUpgrade": true
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Transport-level replay protection — any v2 POST may send it
(1–255 printable ASCII characters; UUIDs recommended). The first
response for a key is recorded and replayed verbatim for retries
with the same key + method/path/body for 24 hours; replayed
responses carry the Idempotency-Replay: true response header.
Reusing a key with a different request — or retrying while the
original is still in flight — returns 409 IDEMPOTENCY_ERROR.
5xx responses are never recorded (the retry re-executes).
1 - 255^[\x21-\x7e]{1,255}$Body
1 - 10000Optional human-readable label. Auto-generated from prompt if absent.
80Table ids to focus the agent on. When the caller also
supplies workspaceId, every id must belong to that
workspace. When workspaceId is omitted, the workspace
is inferred from the first id.
50Bind existing resources to the run. A document is injected as
an attached file the agent reads with ctx.loadFile(path) (its
current path is re-resolved at run start); a table is merged
into focusTableIds. Every attachment must belong to the run's
workspace + org, else 400 INVALID_ATTACHMENT before admission.
20A document (injected as an attached file) or a table (merged into focusTableIds).
- Option 1
- Option 2
Show child attributes
Show child attributes
Public model id. Plan-aware default — highest model unlocked
on the caller's plan (origami-lite for starter,
origami-max for pro+). Resolved server-side to an
internal chat-agent model; the response's request.model
echoes the public id (origami-lite or origami-max),
never an internal name. Legacy aliases origami-fast and
origami-mid are still accepted and normalized to
origami-lite.
origami-lite, origami-max