# Agentic API

### **Scope.**

> Customer-facing onboarding for the Blockbrain Agentic API: what it is, how to authenticate, how to make your first call, four end-to-end use cases, and an error-code catalog.
>
> **Per-endpoint reference is intentionally not duplicated here.** The live, always-current reference lives at [agentic.theblockbrain.ai/docs](https://agentic.theblockbrain.ai/docs) (Scalar, auto-rendered from the OpenAPI spec). This page covers what Scalar can't auto-generate — narrative, auth flow, and end-to-end use cases.
>
> **Live OpenAPI spec:** [`agentic.theblockbrain.ai/openapi.json`](https://agentic.theblockbrain.ai/openapi.json) (currently version `0.97.2`).

***

### Overview

The Blockbrain Agentic API exposes Blockbrain's agent platform — chat threads, streaming agent responses, workflows, scheduled messages, custom supervisors, and conversation memory — as a REST API protected by bearer-JWT authentication.

**Base URL:** `https://agentic.theblockbrain.ai`

The endpoints are organised into nine logical groups. Use this table to find the right group; details for each endpoint are in [Scalar](https://agentic.theblockbrain.ai/docs).

| Group                               | What it's for                                                                                                                        | Common starting endpoint                            |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| **DynamicChat** *(v2, recommended)* | Agent-first chat product. Create a thread, send a message, stream the agent's response. Use this for new chat integrations.          | `POST /v2/api/threads`                              |
| **Agents**                          | List available agents and their tools, follow-up questions, and the lower-level streaming endpoint that powers DynamicChat.          | `GET /v1/api/agents`                                |
| **Memory** *(v1)*                   | Lower-level memory store that backs agent threads — message history, working memory, token-usage tracking, bulk export/delete.       | `GET /v1/api/memory/threads/{threadId}/messages`    |
| **Workflows**                       | Run agentic workflows synchronously or asynchronously, poll for status, fetch results, or send events into a running workflow.       | `POST /v1/api/agentic/workflows/run`                |
| **Scheduled Messages**              | Create, list, toggle, and delete recurring scheduled messages that fire into a thread on a cadence.                                  | `POST /v1/api/scheduled-messages`                   |
| **Custom Supervisors**              | Build a multi-agent supervisor over a curated set of sub-agents. CRUD on supervisor configurations + listing of eligible sub-agents. | `GET /v1/api/supervisors/available-agents`          |
| **Custom Agents**                   | Export a custom agent built in the Blockbrain UI as a GitHub issue (used for promotion to a predefined agent).                       | `POST /v1/api/custom-agents/{customAgentId}/export` |
| **Models**                          | List the models the platform exposes, with display metadata. Useful for building model-pickers.                                      | `GET /v1/api/models`                                |
| **System**                          | Health check, structured changelog, [llms.txt](https://llmstxt.org/) for AI-tooling discovery, Scalar docs UI.                       | `GET /healthz`                                      |

> **Memory v1 vs DynamicChat v2 — which threads do I use?** They are two different systems. New chat integrations should use the v2 DynamicChat thread surface (`/v2/api/threads`). The Memory v1 surface (`/v1/api/memory/threads`) is the storage layer that older v1 agents read from; you typically only call it directly if you're migrating data or building memory-management UI.

***

### Authentication

Every protected endpoint expects a bearer JWT in the `Authorization` header:

```
Authorization: Bearer <jwt>
```

The JWT is issued by Blockbrain's identity provider at `auth.theblockbrain.ai`. The agentic API validates the token's signature against the public JWKs at:

```
https://auth.theblockbrain.ai/oauth/v2/keys
```

…then enforces the audience claim, expiration, and signature algorithm (`RS256`).

#### Expected token claims

```json
{
  "sub": "user_12345",
  "external_user_id": "ext_abc",
  "urn:zitadel:iam:org:id": "tenant_xyz",
  "urn:zitadel:iam:org:project:roles": {
    "kb:consumer": { "projectId": "domain" }
  },
  "iat": 1700000000,
  "exp": 1700003600,
  "aud": ["agentic-api-audience"]
}
```

The agentic API derives the calling user from `sub`, the tenant from `urn:zitadel:iam:org:id`, and (when present) the customer-side identifier from `external_user_id`.

#### Acquiring a token

For an **internal Blockbrain user**, the JWT comes from the existing login flow (web app, mobile, etc.) and can be lifted from the active browser session.

For an **external customer integration**, your Blockbrain account team will provision one of:

1. **OAuth 2.0 Client Credentials** against `auth.theblockbrain.ai` (`POST /oauth/v2/token` with `grant_type=client_credentials`, a tenant-issued `client_id` / `client_secret`). Suitable for service-to-service scenarios.
2. **A tenant-issued long-lived API token** minted by your Blockbrain tenant admin and used as a bearer JWT.

Contact your Customer Success Manager for the credentials and the audience claim value to use.

***

### Getting Started

#### Prerequisites

* A bearer JWT.
* An HTTPS-capable HTTP client (`curl`, `httpx`, `fetch`, etc.).

#### List available agents

Confirm authentication works and discover what agents your tenant exposes:

```shell
curl -s https://agentic.theblockbrain.ai/v1/api/agents \
  -H "Authorization: Bearer $TOKEN" \
  | jq
```

Returns a list of agents with their `id`, display metadata, and capabilities. Pick an `agentId` for the next step.

#### Create a chat thread (DynamicChat v2)

```shell
curl -s -X POST https://agentic.theblockbrain.ai/v2/api/threads \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "agentId": "<AGENT_UUID>",
        "title":   "My first thread"
      }' \
  | jq
```

`agentId` is a workspace agent UUID (omit to fall through to a default). Returns a thread object with `threadId`.

#### Send a message and stream the response

```shell
curl -N -X POST "https://agentic.theblockbrain.ai/v2/api/threads/$THREAD_ID/messages" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "messages": [
          { "role": "user", "parts": [{ "type": "text", "text": "Hello!" }] }
        ]
      }'
```

#### Retrieve thread history

```shell
curl -s "https://agentic.theblockbrain.ai/v2/api/threads/$THREAD_ID/messages" \
  -H "Authorization: Bearer $TOKEN" \
  | jq
```

Returns the last 50 messages as AI SDK v6 UIMessages.

***

### AI-tooling shortcut: `llms.txt`

Agentic API publishes a machine-readable summary of every public endpoint at:

```
https://agentic.theblockbrain.ai/llms.txt
```

This follows the [llmstxt.org](https://llmstxt.org/) convention — point your AI coding assistant or MCP client at this URL and it can self-discover endpoints without parsing the full OpenAPI document.

***

### Use cases

End-to-end flows for the four most-asked customer scenarios. Each one is composable — you can wire them together in your application.

#### Build a chatbot frontend (DynamicChat v2)

**Goal:** a chat UI where a user picks a thread, types a message, and watches the agent stream a response.

| Step | Endpoint                                   | Purpose                                                                  |
| ---- | ------------------------------------------ | ------------------------------------------------------------------------ |
| 1    | `GET /v2/api/threads`                      | List the current user's threads on first load.                           |
| 2    | `POST /v2/api/threads`                     | Create a new thread when the user clicks *New chat*.                     |
| 3    | `GET /v2/api/threads/{threadId}/messages`  | Hydrate the message history when a thread is opened.                     |
| 4    | `POST /v2/api/threads/{threadId}/messages` | Send the user's input and stream the agent reply (SSE).                  |
| 5    | `POST /v2/api/threads/{threadId}/agent`    | (Optional) Swap the agent attached to the thread without losing history. |
| 6    | `DELETE /v2/api/threads/{threadId}`        | Remove a thread from the user's history.                                 |
| 7    | `GET /v1/api/agents/follow-up/{threadId}`  | Fetch suggested follow-up questions to render below the latest reply.    |

#### Run an agentic workflow asynchronously

**Goal:** kick off a long-running workflow, poll for progress, fetch results.

| Step | Endpoint                                                                             | Purpose                                                                                                 |
| ---- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
| 1    | `GET /v1/api/agentic/workflows/get-workflows`                                        | Discover the workflows the calling user can invoke.                                                     |
| 2    | `POST /v1/api/agentic/workflows/run`                                                 | Start an async run. Returns an `artificialRunId`.                                                       |
| 3    | `GET /v1/api/agentic/workflows/get-status/run-id/{artificialRunId}/last-id/{lastId}` | Poll for incremental status updates. Pass the previous `lastId` each call to resume where you left off. |
| 4    | `POST /v1/api/workflows/send-event`                                                  | (Optional) Send an event into the running workflow — for human-in-the-loop or branching logic.          |
| 5    | `GET /v1/api/agentic/workflows/get-results/workflow/{workflowId}`                    | Once status reports completion, fetch the structured result.                                            |

> **For short, blocking calls:** use `POST /v1/api/run-workflow` instead — it executes synchronously and returns the result in one round-trip.

#### Schedule a recurring agent message

**Goal:** automate an agent to fire into a thread on a cadence (e.g. *"every weekday at 09:00, summarise yesterday's open issues"*).

| Step | Endpoint                                      | Purpose                                                                |
| ---- | --------------------------------------------- | ---------------------------------------------------------------------- |
| 1    | `POST /v1/api/scheduled-messages`             | Create the schedule (target thread, cron expression, message payload). |
| 2    | `GET /v1/api/scheduled-messages`              | List existing schedules for the user (or filter by `threadId`).        |
| 3    | `PUT /v1/api/scheduled-messages/{id}`         | Edit cadence or payload.                                               |
| 4    | `POST /v1/api/scheduled-messages/{id}/toggle` | Pause or resume without losing the configuration.                      |
| 5    | `DELETE /v1/api/scheduled-messages/{id}`      | Remove permanently.                                                    |

#### Build a custom supervisor over curated sub-agents

**Goal:** wrap several existing agents under a single supervisor agent that delegates intelligently.

| Step | Endpoint                                   | Purpose                                                                           |
| ---- | ------------------------------------------ | --------------------------------------------------------------------------------- |
| 1    | `GET /v1/api/supervisors/available-agents` | List agent IDs eligible to be sub-agents.                                         |
| 2    | `POST /v1/api/supervisors`                 | Create the supervisor configuration with the chosen sub-agents and routing rules. |
| 3    | `GET /v1/api/supervisors`                  | List supervisors in the org for management UI.                                    |
| 4    | `PUT /v1/api/supervisors/{id}`             | Adjust sub-agent set or routing as needs evolve.                                  |
| 5    | `DELETE /v1/api/supervisors/{id}`          | Tear down.                                                                        |

Once created, the supervisor surfaces in the standard `GET /v1/api/agents` listing and is usable through any of the chat flows above.

***

### Error-code catalog

Every endpoint follows the standard HTTP-status conventions below. Endpoint-specific bodies (e.g. *"Thread not found or not owned by caller"* on `404`) are documented in [Scalar](https://agentic.theblockbrain.ai/docs).

| Status  | Meaning                                                                                                                                                                                            | What to do                                                                                                                                                            |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **200** | Success — body contains the resource or stream.                                                                                                                                                    | Proceed.                                                                                                                                                              |
| **201** | Created — typically returned by `POST`s that create a new entity.                                                                                                                                  | Read the `id` from the response and continue.                                                                                                                         |
| **204** | Success, no body — typical for `DELETE`.                                                                                                                                                           | Proceed.                                                                                                                                                              |
| **400** | Bad request — body shape or query params don't match the schema.                                                                                                                                   | Validate request body against the schema in [Scalar](https://agentic.theblockbrain.ai/docs). Common causes: missing required field, wrong content-type, invalid JSON. |
| **401** | Unauthorized — missing, malformed, or expired bearer token.                                                                                                                                        | Re-acquire a token. Confirm `Authorization: Bearer …` header is present and the token has not expired (`exp` claim).                                                  |
| **403** | Forbidden — token is valid but the caller lacks permission for this resource.                                                                                                                      | Check tenant scoping and any required role claims in the JWT.                                                                                                         |
| **404** | Not found — resource does not exist or is not visible to the caller. Note: many endpoints return 404 instead of 403 to avoid leaking existence (e.g. *"Thread not found or not owned by caller"*). | Verify IDs. If you expect access, check tenant/user scoping.                                                                                                          |
| **409** | Conflict — resource state prevents the operation (e.g. duplicate creation).                                                                                                                        | Reconcile client-side state and retry.                                                                                                                                |
| **429** | Rate-limited.                                                                                                                                                                                      | Back off with exponential delay; respect the `Retry-After` header if present.                                                                                         |
| **500** | Internal error on Blockbrain's side.                                                                                                                                                               | Retry with backoff. If persistent, surface to support with the request ID and timestamp.                                                                              |
| **503** | Service temporarily unavailable.                                                                                                                                                                   | Retry; if extended, check `/healthz` and the platform status page.                                                                                                    |

***

### Streaming response format

Two streaming endpoints exist — use the v2 (current) one for new integrations.

| Endpoint                                   | Status                    | Format                                                                                                     |
| ------------------------------------------ | ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `POST /v2/api/agents/{agentId}/stream`     | **Current**               | AI SDK v6 **UIMessage** SSE stream. Each chunk is an SSE `data:` event whose payload is a UIMessage delta. |
| `POST /v2/api/threads/{threadId}/messages` | **Current (DynamicChat)** | Same AI SDK v6 UIMessage SSE format. Thread context is taken from the path; user identity from the JWT.    |
| `POST /v1/api/agents/{agentId}/stream`     | **Deprecated**            | Named-event SSE (`event: <type>` / `data: <json>`). Don't use for new integrations.                        |
| `POST /api/agents/{agentId}/stream`        | **Legacy AI SDK v1**      | Older `data:` chunk format. Maintained for back-compat only.                                               |

**SSE handling tip.** Use a streaming HTTP client (`fetch` with a `ReadableStream` reader, `httpx` async streaming, or the `eventsource` Node library) and parse complete SSE event blocks rather than line-buffering. UIMessage deltas are JSON; concatenate the `text` parts as they arrive to render incremental output.

***

### Service health and discovery

| Endpoint         | Purpose                                                                  |
| ---------------- | ------------------------------------------------------------------------ |
| `GET /healthz`   | Liveness probe. Returns 200 when the service is healthy. Cache-friendly. |
| `GET /changelog` | Structured release notes for the agentic service.                        |
| `GET /llms.txt`  | Machine-readable endpoint summary.                                       |
| `GET /docs`      | The Scalar interactive reference.                                        |

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.blockbrain.ai/for-admins/agentic-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
