Agents API

An agent is an AI assistant your team configures once in the portal — its instructions, its knowledge collections, and the exact list of tools it may use — and then triggers from anywhere: chat, schedules, webhooks, workflows, or this API.

What makes a Senaiy Lab agent different from a bare LLM call:

  • A tool allowlist, not tool access. The agent can only call what you granted.
  • Human approval gates. Tools marked sensitive (creating an invoice, updating a record) pause the run until someone approves it in the portal. The API reports this honestly as Waiting Approval.
  • Budgets and caps. Max cost per run, concurrency caps, step limits.
  • A full audit trail. Every model call and tool call is a recorded step with tokens, duration and USD cost.

The three calls

# 1. start
curl -X POST https://platform.senaiy.ai/v1/agents/{agent-id}/runs \
  -H "Authorization: Bearer sk-sf-..." \
  -d '{"input": "Prepare the weekly summary", "session_ref": "user-42"}'
# → {"message": {"run_id": "...", "status": "Queued"}}

# 2. poll
curl https://platform.senaiy.ai/v1/runs/{run_id} -H "Authorization: Bearer sk-sf-..."
# status: Queued → Running → Completed | Failed | Cancelled | Waiting Approval

# 3. inspect
curl https://platform.senaiy.ai/v1/runs/{run_id}/steps -H "Authorization: Bearer sk-sf-..."

session_ref groups runs into a conversation: pass the same value (a user id, a ticket number) and the agent remembers the earlier turns.

Attaching files to a run

Pass input_files — a list of AI File ids (upload them with the knowledge upload endpoint) — and the run routes each one by type:

  • Images are shown to the agent's model directly (needs a vision-capable model).
  • Audio is transcribed by the org's speech-to-text model; the transcript is added to the input.
  • Documents and data (.csv, .xlsx, .json, .docx, .pptx, .pdf, …) are staged into the agent's code sandbox at in/<file> for run_python / run_shell.
curl -X POST https://platform.senaiy.ai/v1/agents/{agent-id}/runs \
  -H "Authorization: Bearer sk-sf-..." \
  -d '{"input": "Summarize this report", "input_files": ["FILE-abc123"]}'

Keys are project-scoped: GET /v1/agents lists only the agents of the key's own project, and only those can be run.

Python helper (tested verbatim against production)

import requests, time

class SenaiyAgents:
    """Minimal client for the Senaiy Lab agents API: run, wait, inspect."""

    def __init__(self, api_key, base_url="https://platform.senaiy.ai/v1"):
        self.base = base_url.rstrip("/")
        self.http = requests.Session()
        self.http.headers["Authorization"] = f"Bearer {api_key}"

    def _call(self, method, path, **kwargs):
        response = self.http.request(method, f"{self.base}{path}", timeout=60, **kwargs)
        response.raise_for_status()
        return response.json()["message"]   # platform REST wraps results in "message"

    def run(self, agent, input, session_ref=None, timeout=300):
        """Start a run and wait for a terminal (or approval-parked) state."""
        body = {"input": input, **({"session_ref": session_ref} if session_ref else {})}
        run_id = self._call("POST", f"/agents/{agent}/runs", json=body)["run_id"]
        deadline = time.time() + timeout
        while time.time() < deadline:
            run = self._call("GET", f"/runs/{run_id}")
            if run["status"] in ("Completed", "Failed", "Cancelled", "Waiting Approval"):
                return run
            time.sleep(2)
        raise TimeoutError(f"run {run_id} still {run['status']} after {timeout}s")

    def steps(self, run_id):
        """Full step trace: model calls, tool calls, costs."""
        return self._call("GET", f"/runs/{run_id}/steps")["data"]


client = SenaiyAgents(api_key="sk-sf-...")
run = client.run("your-agent-id", "Prepare the weekly summary")
print(run["status"], run.get("output"))
for step in client.steps(run["id"]):
    print(step["step_type"], step["status"], step["rated_cost"])

A run that returns Waiting Approval is parked at a human gate — approve it in the portal and poll again; the run resumes exactly where it stopped. Long-running runs can also notify you: register a webhook for run.completed instead of polling.

When to use an agent vs. a raw model call

Use the inference API when your own code owns the logic and just needs a model. Use an agent when you want the platform to own it: tools, knowledge, memory, approvals and audit — and your code only asks and receives.

Discard
Save
This page has been updated since your last edit. Your draft may contain outdated content. Load Latest Version

On this page

Review Changes ← Back to Content
Message Status Space Raised By Last update on