curl -X POST https://api.getspine.ai/v1/run \
-H "X-API-KEY: sk_spine_..." \
-F "prompt=Summarize this sales data" \
-F "template=memo" \
-F "files=@sales-data.csv;type=text/csv"
import requests
response = requests.post(
"https://api.getspine.ai/v1/run",
headers={"X-API-KEY": "sk_spine_..."},
data={"prompt": "Summarize this sales data", "template": "memo"},
files={"files": ("sales-data.csv", open("sales-data.csv", "rb"), "text/csv")},
)
run = response.json()["data"]
print(run["run_id"])
import fs from "node:fs";
const form = new FormData();
form.set("prompt", "Summarize this sales data");
form.set("template", "memo");
form.append("files", new Blob([fs.readFileSync("sales-data.csv")]), "sales-data.csv");
const res = await fetch("https://api.getspine.ai/v1/run", {
method: "POST",
headers: { "X-API-KEY": "sk_spine_..." },
body: form,
});
const { data } = await res.json();
console.log(data.run_id);
{
"success": true,
"data": {
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"poll_url": "/v1/run/550e8400-e29b-41d4-a716-446655440000",
"estimated_duration_ms": 900000
}
}{
"success": false,
"error": "Invalid template: foo. Valid templates: app, auto, deep_research, excel, landing_page, memo, report, slides"
}{
"success": false,
"error": "X-API-KEY header required"
}{
"success": false,
"error": "<string>"
}Create a run
Submit a prompt to trigger an async canvas run. Agents orchestrate a
DAG of blocks to satisfy the prompt; poll GET /v1/run/{run_id}
until status becomes completed, partial, or failed.
curl -X POST https://api.getspine.ai/v1/run \
-H "X-API-KEY: sk_spine_..." \
-F "prompt=Summarize this sales data" \
-F "template=memo" \
-F "files=@sales-data.csv;type=text/csv"
import requests
response = requests.post(
"https://api.getspine.ai/v1/run",
headers={"X-API-KEY": "sk_spine_..."},
data={"prompt": "Summarize this sales data", "template": "memo"},
files={"files": ("sales-data.csv", open("sales-data.csv", "rb"), "text/csv")},
)
run = response.json()["data"]
print(run["run_id"])
import fs from "node:fs";
const form = new FormData();
form.set("prompt", "Summarize this sales data");
form.set("template", "memo");
form.append("files", new Blob([fs.readFileSync("sales-data.csv")]), "sales-data.csv");
const res = await fetch("https://api.getspine.ai/v1/run", {
method: "POST",
headers: { "X-API-KEY": "sk_spine_..." },
body: form,
});
const { data } = await res.json();
console.log(data.run_id);
{
"success": true,
"data": {
"run_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"poll_url": "/v1/run/550e8400-e29b-41d4-a716-446655440000",
"estimated_duration_ms": 900000
}
}{
"success": false,
"error": "Invalid template: foo. Valid templates: app, auto, deep_research, excel, landing_page, memo, report, slides"
}{
"success": false,
"error": "X-API-KEY header required"
}{
"success": false,
"error": "<string>"
}Try this in the developer playground
webhook_url field. See Webhooks for the event schema and signature verification.Authorizations
An API key from the Spine developer portal. Keys are prefixed with
sk_spine_ and shown only once at creation. Keep them server-side.
Body
What you want the agents to do.
"Create a Q1 performance report with charts"
Preset block configuration. Ignored when blocks is provided.
Defaults to auto.
auto, deep_research, report, slides, memo, excel, app, landing_page JSON-encoded array of block types to override the template, e.g.
["document-block","table-block","image-block"]. Precedence:
blocks > template > auto.
"[\"document-block\",\"table-block\",\"web-block\"]"
Behavioral guidance applied across all agent layers (tone, rigor, audience, citation requirements, etc.).
"Write for a C-suite executive audience. Cite all sources."
Reserved for future webhook delivery — not yet honored.
Optional file attachments. Images (PNG, JPEG, GIF, WEBP, SVG) become image-blocks; documents (PDF, DOCX, XLSX, CSV, TXT, MD, YAML, JSON, ZIP) become indexed file-blocks.