> ## Documentation Index
> Fetch the complete documentation index at: https://noorle.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API Overview

> Noorle's three request surfaces: the management API at api.noorle.com, MCP gateways for tool access, and agent gateways for A2A messaging

Noorle exposes three request surfaces. They are separate hosts with separate
protocols, separate error formats, and separate authentication rules. Pick the
one that matches what you are doing.

| Surface            | Host                          | Protocol                 | Use it for                                                                                |
| ------------------ | ----------------------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
| **Management API** | `api.noorle.com`              | REST over HTTPS          | Uploading plugins, listing capabilities, resolving approval gates, starting workflow runs |
| **MCP gateway**    | `mcp-{handle}.noorle.cloud`   | MCP over Streamable HTTP | Giving an MCP client access to the tools you bound to that gateway                        |
| **Agent gateway**  | `agent-{handle}.noorle.cloud` | A2A over JSON-RPC 2.0    | Sending messages to one of your agents from another system                                |

Each gateway host is derived from the gateway's or agent's **handle**, not its
UUID. Every account gets its own gateway hosts; there is no shared platform-wide
MCP server.

<Note>
  These are the production hosts. Staging uses `noorle.app` and development uses
  `noorle.dev` with the same prefixes.
</Note>

## Management API

Path-versioned under `/v1`. Responses wrap their payload in a `data` envelope:

```json theme={"dark"}
{ "data": [ /* ... */ ] }
```

```bash theme={"dark"}
curl https://api.noorle.com/v1/capabilities \
  -H "Authorization: Bearer eyJhbGc..."
```

The two OAuth routes are the exception — `/oauth/device/authorize` and
`/oauth/token` return their fields bare, with no `data` wrapper.

### What it covers

The management API is a **narrow CLI and integration surface**, not a mirror of
the Portal. It exists so a script, a CI job, or the CLI can do the handful of
things that need to happen without a browser. Read this list before you design
against it.

| Area               | What the API can do                                                                         |
| ------------------ | ------------------------------------------------------------------------------------------- |
| **Capabilities**   | List them; upload a plugin archive                                                          |
| **Plugin builds**  | Create, list, read, cancel                                                                  |
| **Skills**         | Full lifecycle — create, read, update, delete, plus content, bindings, import, and generate |
| **Workflow runs**  | Start a run; read status; cancel; approve; signal                                           |
| **Approval gates** | List what is pending for a thread, a workflow run, or the account; submit a decision        |
| **Autonomy**       | Read and set per-agent, per-user, and account-wide policy; read decision history            |
| **Agents**         | Attach and detach workflows; browse and read the agent's home directory; read its quota     |
| **Gateways**       | Attach and detach workflows                                                                 |
| **Attachments**    | Read account quota; regenerate a presigned URL                                              |

<Warning>
  **Most Portal areas have no API equivalent at all.** There is no create,
  update, or delete for **agents, gateways, connectors, knowledge bases, users,
  API keys, threads, or workflows** — and no endpoints for billing, activity,
  notifications, chat, or profile.

  Note the shape of the two rows above that mention agents and gateways: those
  endpoints manage a workflow *association* and an agent's files. They do not
  create, configure, or delete the agent or gateway itself.
</Warning>

Everything outside that table happens in the [Portal](https://portal.noorle.com).
If you are planning an integration, treat the table as the customer-facing
surface rather than assuming a REST route exists for each screen you can see —
it omits a few narrow, non-CRUD routes that exist for specific integrations
rather than general use: `GET /v1/noorle-cli/config` (CLI bootstrap),
`POST /v1/identity/verify` (link a platform identity), `GET /v1/files/{id}`
(a presigned redirect), and `GET /v1/agents/{agent_id}/skills`.

<Card title="REST reference" icon="brackets-curly" href="/docs/reference/rest/capabilities-list">
  Capabilities, plugin upload, and the OAuth device flow.
</Card>

## MCP gateway

The transport is **Streamable HTTP**, mounted at the gateway origin. There is no
separate `/sse` endpoint and no WebSocket transport — JSON-RPC responses come
back as `text/event-stream` frames on the POST response.

```bash theme={"dark"}
curl -X POST https://mcp-my-gateway.noorle.cloud/ \
  -H "Authorization: Bearer eyJhbGc..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

The gateway advertises **tools only**. It does not implement MCP resources,
prompts, logging, or completions.

<Card title="MCP reference" icon="router" href="/docs/reference/mcp/overview">
  Transport, session posture, `tools/list`, `tools/call`, and what is not implemented.
</Card>

## Agent gateway

A2A 1.0 over JSON-RPC 2.0. Every method is a `POST` to the origin root — the
method name is in the JSON-RPC envelope, not the path. Method names are
PascalCase (`SendMessage`, `GetTask`), not the slash-separated 0.x names.

```bash theme={"dark"}
curl -X POST https://agent-my-agent.noorle.cloud/ \
  -H "Authorization: Bearer eyJhbGc..." \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "SendMessage",
    "params": {
      "message": {
        "messageId": "6f1b...",
        "role": "ROLE_USER",
        "parts": [{"text": "What is the status of order 4471?"}]
      }
    }
  }'
```

The agent card at `GET /.well-known/agent-card.json` is public and tells callers
what authentication to attach.

<Card title="A2A reference" icon="share-nodes" href="/docs/reference/a2a/overview">
  The eleven methods, task lifecycle, streaming, and the agent card.
</Card>

## Authentication at a glance

| Surface        | Accepted credentials                                                                                         |
| -------------- | ------------------------------------------------------------------------------------------------------------ |
| Management API | API key (`ak-…`) or a device-flow JWT, on `Authorization`                                                    |
| MCP gateway    | API key or a JWT minted by **that gateway's own** OAuth server. Public gateways accept unauthenticated calls |
| Agent gateway  | API key belonging to a service principal, or a JWT scoped to that agent                                      |

There is no session cookie on any of these surfaces, and no query-parameter
token form.

<Card title="Authentication" icon="key" href="/docs/reference/authentication">
  Header forms, the device flow, and per-gateway OAuth.
</Card>

## Errors

The three surfaces do not share an error format. The management API returns a
flat JSON body whose `category` field determines the HTTP status; the gateways
return JSON-RPC errors in the response envelope.

<Card title="Errors and limits" icon="triangle-exclamation" href="/docs/reference/errors-and-rate-limits">
  Status mapping, JSON-RPC codes, and the limits that actually exist.
</Card>

## Choosing a surface

```mermaid theme={"dark"}
graph TD
    A["What are you doing?"]
    B["Uploading a plugin,<br/>reading capabilities,<br/>resolving a gate"]
    C["Giving an MCP client<br/>access to tools"]
    D["Sending a message<br/>to an agent"]
    E["Management API<br/>api.noorle.com"]
    F["MCP gateway<br/>mcp-handle.noorle.cloud"]
    G["Agent gateway<br/>agent-handle.noorle.cloud"]

    A --> B
    A --> C
    A --> D
    B --> E
    C --> F
    D --> G
```

## Next steps

* [Authentication](/docs/reference/authentication)
* [Errors and rate limits](/docs/reference/errors-and-rate-limits)
* [REST reference](/docs/reference/rest/capabilities-list)
* [MCP reference](/docs/reference/mcp/overview)
* [A2A reference](/docs/reference/a2a/overview)
