Back to Documentation

API Reference

The Taiso API is an OpenAPI-described REST service. The authoritative reference is generated from the running server, so it is always current — the links below are the canonical source, not this page.

Live reference

  • Swagger UI — browse and send authenticated requests from the browser.
  • ReDoc — the same schema in a reading-oriented layout.
  • openapi.json — the raw spec, for generating a client.

Base URL and versioning

Production is https://api.taiso.ai. Every endpoint is namespaced under /api/v2; the version is part of the path, so a future v3 will not change v2 behaviour.

Authentication

Send your API key as a bearer token on every request:

Authorization: Bearer <your-api-key>

See Authentication for key creation, scoping, and rotation.

Endpoint groups

PathPurpose
/api/v2/projectsProjects — the container for files, chats, and generated output
/api/v2/filesFile upload and retrieval
/api/v2/chatsServer-side conversation state
/api/v2/sopsSOP definitions, versioning, and rollback
/api/v2/jobsAsynchronous execution, status polling, cancellation
/api/v2/agentsAgent definitions and invocation
/api/v2/llmDirect LLM calls, including streaming chat
/api/v2/toolsExternal tools — web search, MCP, PDF, and others
/api/v2/searchSearch across project data
/api/v2/assistAssist endpoints
/api/v2/usersAccount and profile management
/api/v2/healthService health

Long-running work

SOP and agent execution is asynchronous. Submitting work returns a job id; poll GET /api/v2/jobs/{id} until it reaches a terminal state. Jobs can also be cancelled while in flight.

Webhooks

Instead of polling, give a job (POST /api/v2/jobs), a SOP run or an agent run a webhook_url (an https URL on port 443). When it ends — completed, failed or cancelled, or for a strict SOP run missing inputs, incomplete — Taiso POSTs its result there once. A retry sends the same body and delivery_id, so dedupe on delivery_id. One secret signs all your webhooks, so before acting on one, check its job or run is one you created.

Every webhook is signed. Your signing secret is on your API Keys page (or GET /api/v2/webhooks/signing-secret with your key). Check the X-Taiso-Signature header: t is a Unix time and v1 the hex HMAC-SHA256 of <t>.<raw body>, keyed with the whole secret. Refuse a t more than five minutes old. After a rotation, for 24 hours, a second v1 is made with your previous secret: accept the webhook if either matches.

import hashlib, hmac, time

def signed_by_taiso(header: str, body: bytes, secret: str) -> bool:
    parts = [p.split("=", 1) for p in header.split(",") if "=" in p]
    t = next((v for k, v in parts if k == "t"), "")
    if not t.isdigit() or abs(time.time() - int(t)) > 300:
        return False
    want = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
    # Compare bytes: compare_digest raises on a str that is not ASCII.
    return any(hmac.compare_digest(want.encode(), v.encode()) for k, v in parts if k == "v1")

Need help?

This page is a starting point. For anything it does not cover, reach out.