---
title: Agent tool registry
description: Fetch the JSON Schema array of every agent-callable tool. The same registry the Python SDK exposes via `Toolkit.as_json_schema()`.
section: API Reference
order: 16
---
`GET /api/v1/developer/tools.json` serves the agent tool registry as
a JSON Schema array. Dynamic-discovery agent stacks (Vercel AI SDK,
LangChain, raw OpenAI / Anthropic SDKs without the bundled adapters)
fetch this once and have everything they need.

The registry is the **single source of truth** — the Python SDK's
`Toolkit.as_anthropic_tools()` / `as_openai_tools()` / `as_json_schema()`
all derive from it; the backend snapshot is regenerated on every SDK
release via a CI parity check.

## Endpoints

| URL | Notes |
|---|---|
| `/api/v1/developer/tools` | Trailing-slash-tolerant. Returns the full payload. |
| `/api/v1/developer/tools.json` | Same content. Matches the conventional `*.json` URL. |

## Auth

Standard developer-API auth — pass `X-API-Key`. Any role works
(read-only).

```bash
curl -H "X-API-Key: pk_live_…" \
  https://api.pictograph.io/api/v1/developer/tools.json
```

## Response shape

```json
{
  "tools": [
    {
      "name": "upload_dataset_from_folder",
      "description": "Use when the user asks to upload a folder of images …",
      "input_schema": {
        "type": "object",
        "properties": {
          "dataset_name": { "type": "string", "description": "…" },
          "folder":       { "type": "string", "description": "…" }
          // … remaining fields
        },
        "required": ["dataset_name", "folder"],
        "additionalProperties": false
      },
      "required_role": "member",
      "credit_cost": 0,
      "idempotent": false
    }
    // … 27 more entries
  ],
  "version": "1.0.0",
  "count": 28,
  "generated_at": "2026-04-19T…Z"
}
```

## Tool metadata

| Field | Notes |
|---|---|
| `name` | Snake-case identifier. Stable across SDK versions. |
| `description` | Anthropic "use when X" framing. Agents read this to choose between tools. |
| `input_schema` | Pydantic-generated JSON Schema with `extra: forbid`. |
| `required_role` | Minimum org role on the calling API key. Backend re-enforces. |
| `credit_cost` | Approximate cost (0 for read-only / free ops). Agents may gate. |
| `idempotent` | When `true`, agents may safely retry on transient failures. |

## Tool list (v1.0.0)

28 tools across 11 categories. See the [agents overview](/docs/agents.md)
for details and the dispatch pattern.

| Category | Tools |
|---|---|
| Workflows | `upload_dataset_from_folder`, `auto_annotate_dataset`, `train_pipeline`, `full_pipeline` |
| Datasets | `list_datasets`, `get_dataset`, `create_dataset`, `delete_dataset` |
| Images | `upload_image`, `delete_image` |
| Annotations | `get_annotations`, `save_annotations` |
| Auto-annotate | `auto_annotate_point`, `auto_annotate_box`, `auto_annotate_text` |
| Search | `search_by_tag`, `search_by_similarity` |
| Exports | `create_export`, `list_exports`, `download_export` |
| Training | `get_training_status`, `cancel_training` |
| Models | `list_models`, `download_model` |
| Credits | `get_credit_balance`, `estimate_credit_cost` |
| Connectors | `validate_connector`, `import_from_connector` |

## SDK equivalents

```python
from pictograph.agents import create_toolkit

toolkit = create_toolkit()
schema = toolkit.as_json_schema()                # same payload, no HTTP roundtrip
anthropic_tools = toolkit.as_anthropic_tools()   # name/description/input_schema only
openai_tools = toolkit.as_openai_tools()         # OpenAI function-calling format
```

The CLI also dumps the registry locally:

```bash
pictograph agents export-tools -o tools.json
```

## Versioning

The `version` field tracks the SDK release that generated the snapshot.
Tools may be added between minor versions; renames / removals only
happen at major versions and are listed in the changelog.

## Drift protection

The backend snapshot at `routes/developer/_tools_snapshot.json` is
verified against the SDK's live registry on every CI build (via
`scripts/generate_tools_snapshot.py --check`). PRs that change one
without the other fail.