> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.markup.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.markup.ai/_mcp/server.

# List Agents

GET https://api.markup.ai/agents

List the agents the organization may run, or the full catalog.

The single authoritative source of agent availability for clients (extension,
Console, integrations). By default the returned list already reflects every
per-org gate — style-agent mode, per-agent on/off, and the
no-LLM flag — so clients must not re-derive availability; the `no_llm` flag is
returned alongside so they can render the Style-Agent-only state directly.
Pass `include_unavailable=true` for the full catalog (per-org gates skipped),
e.g. an internal tool resolving an agent id regardless of org config.

Reference: https://docs.markup.ai/developer-reference/api-reference/agents/list-agents

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Query parameters

- `page` (integer, optional, default: 1) — Page number (1-based)
- `page_size` (integer, optional, default: 20) — Items per page (max 100)
- `category` (string, optional, nullable) — Filter agents by category name (case-insensitive substring match)
- `include_unavailable` (boolean, optional, default: false) — Return the full agent catalog instead of only the agents this organization may run. When false (default) the list is filtered by style-agent mode, per-agent on/off, and the no-LLM flag; when true those per-org gates are skipped.

## Response

### 200

Successful Response

- `agents` (list of AgentMetadata, required) — Agents for the current page
- `total` (integer, required) — Total number of agents matching filters
- `page` (integer, required) — Current page number (1-based)
- `page_size` (integer, required) — Number of items per page
- `total_pages` (integer, required) — Total number of pages
- `no_llm` (boolean, required) — When true, the organization has disabled all LLM-powered agents; only the deterministic Style Agent is available and, unless `include_unavailable` is set, `agents` contains it alone (Style-Agent-only).

## Errors

### 401 Unauthorized Error

Authentication failed or no valid API key provided.

- `detail` (string, required) — A description of the error that occurred.
- `status` (integer, required) — The HTTP status code generated by the server for this issue
- `request_id` (string, required) — A unique ID associated with the HTTP request.

### 403 Forbidden Error

Forbidden

- `detail` (string, required) — A description of the error that occurred.
- `status` (integer, required) — The HTTP status code generated by the server for this issue
- `request_id` (string, required) — A unique ID associated with the HTTP request.

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

### 500 Internal Server Error

Internal Server Error

- `detail` (string, required) — A description of the error that occurred.
- `status` (integer, required) — The HTTP status code generated by the server for this issue
- `request_id` (string, required) — A unique ID associated with the HTTP request.

## Types

### AgentMetadata

Metadata about a registered agent.

- `id` (string, required) — Stable agent ID (ag\_\<nanoid>) used for API routing
- `name` (string, required) — Agent name
- `description` (string, optional, nullable) — Agent description
- `input_schema` (map from string to any, optional, nullable) — Input JSON schema
- `output_schema` (map from string to any, optional, nullable) — Output JSON schema
- `categories` (list of string, optional) — Category IDs for discovery and filtering
- `cadence` (enum, optional, default: on_demand) — §2.4 session routing cadence (configured in agents.yaml)
  - Allowed values: `per_chunk`, `per_fragment`, `doc_wide`, `on_demand`
- `ui` (AgentUIMetadata, optional) — UI metadata

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)

### AgentUIMetadata

UI presentation metadata for an agent.

- `title` (string, optional, nullable) — Display name override
- `description` (string, optional, nullable) — Description override for UI
- `icon` (string, optional, default: bot) — Lucide icon key (e.g. 'spell-check')

### ValidationErrorLocItems

- string
- integer

## Examples

**Request**

```json
{}
```

**Response**

```json
{
  "agents": [
    {
      "id": "ag_V9k2mXpLqR3nYwZt",
      "name": "Brand Voice Agent",
      "description": "Analyzes content for brand voice consistency and suggests improvements aligned with your organization's tone guidelines.",
      "input_schema": {},
      "output_schema": {},
      "categories": [
        "brand-voice"
      ],
      "cadence": "on_demand",
      "ui": {
        "title": "Brand Voice",
        "description": "Check and improve content alignment with your brand voice guidelines.",
        "icon": "megaphone"
      }
    }
  ],
  "total": 8,
  "page": 1,
  "page_size": 20,
  "total_pages": 1,
  "no_llm": false
}
```

**SDK Code**

```python Python
import requests

response = requests.get(
    "https://api.markup.ai/agents",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    params={"page_size": 100},
)
print(response.json())

```

```typescript TypeScript
const response = await fetch(
  "https://api.markup.ai/agents?page_size=100",
  {
    headers: { Authorization: "Bearer YOUR_TOKEN" },
  },
);
console.log(await response.json());

```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.markup.ai/agents"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("GET", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.markup.ai/agents")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.markup.ai/agents")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.markup.ai/agents', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.markup.ai/agents");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.markup.ai/agents")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```