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

# Use the API as agent tools

> Turn the CreatorAudit OpenAPI spec into tool/function definitions and call the API from an LLM agent.

LLM agents act through tools — JSON-schema-described functions the model can call. CreatorAudit ships a complete OpenAPI document, so you can generate those tool definitions instead of writing them by hand, then execute the calls the model picks.

## The pattern

<Steps>
  <Step title="Fetch the contract">
    Download the OpenAPI spec from `https://api.creatoraudit.com/v2/openapi.json` (also linked from the [API reference](/api-reference/introduction)). It describes every endpoint, parameter, and response shape.
  </Step>

  <Step title="Generate tool schemas">
    Convert the operations you want to expose into your provider's tool format. Each operation becomes one tool: the path and method are the call target; the parameters and request body become the input JSON schema. This works for Anthropic tool use, OpenAI function calling, and any generic function-calling runtime — they all consume JSON Schema.

    Start small. Expose a handful of read endpoints (`/search`, `/overview`, `/accounts`, `/creators/top`) before adding write endpoints (`POST /accounts`, `POST /videos`).
  </Step>

  <Step title="Execute calls with the bearer key">
    When the model calls a tool, issue the matching HTTP request with `Authorization: Bearer YOUR_API_KEY`, then return the JSON response to the model. Keep the key on your server — never expose it to the model's context or to client-side code.
  </Step>
</Steps>

## A minimal tool layer

The example below defines two read tools — `search` (calls `GET /v2/search`) and `overview` (calls `GET /v2/overview`) — and an executor that runs whichever tool the model picks. Responses are passed through verbatim, so you never hardcode fields that might drift.

<CodeGroup>
  ```python Python theme={null}
  import os
  import httpx

  BASE = "https://api.creatoraudit.com/v2"
  API_KEY = os.environ["CREATORAUDIT_API_KEY"]  # keep server-side

  # Tool schemas in Anthropic tool-use shape. OpenAI function calling uses the
  # same JSON Schema under a "parameters" / "function" wrapper.
  TOOLS = [
      {
          "name": "search",
          "description": "Search tracked accounts, creators, and videos by query.",
          "input_schema": {
              "type": "object",
              "properties": {
                  "q": {"type": "string", "description": "Search query."},
                  "limit": {"type": "integer", "minimum": 1, "maximum": 25},
              },
              "required": ["q"],
          },
      },
      {
          "name": "overview",
          "description": "Organization-level headline figures.",
          "input_schema": {
              "type": "object",
              "properties": {
                  "period": {"type": "string", "description": "e.g. 7d, 30d, 90d."}
              },
          },
      },
  ]

  # Map each tool to its HTTP call. Keep responses opaque — pass them through.
  ROUTES = {
      "search": ("GET", "/search"),
      "overview": ("GET", "/overview"),
  }


  def execute_tool(name: str, args: dict) -> dict:
      method, path = ROUTES[name]
      headers = {"Authorization": f"Bearer {API_KEY}"}
      resp = httpx.request(method, f"{BASE}{path}", params=args, headers=headers)

      request_id = resp.headers.get("X-Request-ID")  # log for tracing

      if resp.status_code >= 400:
          # RFC 9457 problem details: application/problem+json
          problem = resp.json()
          return {
              "error": True,
              "status": resp.status_code,
              "code": problem.get("code"),
              "detail": problem.get("detail"),
              "request_id": request_id,
          }

      return resp.json()  # { "data": [...], "pagination": {...} } or an object
  ```

  ```typescript TypeScript theme={null}
  const BASE = "https://api.creatoraudit.com/v2";
  const API_KEY = process.env.CREATORAUDIT_API_KEY!; // keep server-side

  // Tool schemas in Anthropic tool-use shape. OpenAI function calling uses the
  // same JSON Schema under a "parameters" / "function" wrapper.
  export const tools = [
    {
      name: "search",
      description: "Search tracked accounts, creators, and videos by query.",
      input_schema: {
        type: "object",
        properties: {
          q: { type: "string", description: "Search query." },
          limit: { type: "integer", minimum: 1, maximum: 25 },
        },
        required: ["q"],
      },
    },
    {
      name: "overview",
      description: "Organization-level headline figures.",
      input_schema: {
        type: "object",
        properties: {
          period: { type: "string", description: "e.g. 7d, 30d, 90d." },
        },
      },
    },
  ];

  const routes: Record<string, { method: string; path: string }> = {
    search: { method: "GET", path: "/search" },
    overview: { method: "GET", path: "/overview" },
  };

  export async function executeTool(name: string, args: Record<string, unknown>) {
    const { method, path } = routes[name];
    const url = new URL(`${BASE}${path}`);
    for (const [k, v] of Object.entries(args)) {
      if (v != null) url.searchParams.set(k, String(v));
    }

    const resp = await fetch(url, {
      method,
      headers: { Authorization: `Bearer ${API_KEY}` },
    });

    const requestId = resp.headers.get("X-Request-ID"); // log for tracing

    if (!resp.ok) {
      // RFC 9457 problem details: application/problem+json
      const problem = await resp.json();
      return {
        error: true,
        status: resp.status,
        code: problem.code,
        detail: problem.detail,
        requestId,
      };
    }

    return resp.json(); // { data: [...], pagination: {...} } or an object
  }
  ```
</CodeGroup>

<Note>
  These calls go to the **CreatorAudit API**, not the docs MCP. Mintlify's `/mcp`
  searches the documentation; to call the API as MCP tools instead, see [Connect via
  MCP](/agents/mcp).
</Note>

## What to get right in the loop

<Warning>
  Keep `YOUR_API_KEY` on the server. The model's context, tool arguments, and any
  client-side code should never see it.
</Warning>

* **Paginate in a loop.** Collection responses carry `pagination.next_cursor` and `pagination.has_next`. Pass `cursor` back with `limit` (1–200) and keep going until `has_next` is `false`. Don't make the model manage cursors — handle it in your executor and return aggregated results.
* **Parse RFC 9457 errors.** On any `4xx`/`5xx`, the body is `application/problem+json` with `status`, `title`, `detail`, and a machine-readable `code`. Branch on `status` for control flow and on `code` for specific handling, then hand the model a structured error it can reason about.
* **Log `X-Request-ID`.** Capture the header on every call — success or failure — so any request can be traced. Quote it when you contact support.
* **Use `Idempotency-Key` on writes.** `POST /accounts`, `POST /videos`, and `POST /creators` accept an optional `Idempotency-Key` header. Set a stable key per logical action so retries from an agent loop don't create duplicates.

## Next

* Wrap the API as MCP tools instead — [Connect via MCP](/agents/mcp).
* See full workflows that chain these calls — [Agent recipes](/agents/recipes).
