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

# Introduction

> Base URLs, the response envelope, pagination, content types and which AgentHub API endpoints are meant for external use.

The CorePillar REST API lives under `/api/v1` on each product's host. It's the same API the AgentHub and ModelHub web apps call, plus a small set of endpoints meant for your own code: trace ingestion and OpenTelemetry export.

## Base URLs

| Product | Base URL |
| - | - |
| AgentHub | `https://pillarforge.corepillar.ai/api/v1` |
| ModelHub (chat endpoints) | `https://modelhub.corepillar.ai/api/v1` |

Every path in this reference is relative to the base URL. For example, trace ingestion is:

```text theme={null}
POST https://pillarforge.corepillar.ai/api/v1/traces/ingest
```

## Which endpoints you can call from your code

The endpoints fall into two groups that authenticate differently. [Authentication](/api-reference/authentication) has the details.

| Group | Endpoints | Authenticated by | Intended for |
| - | - | - | - |
| **Ingestion** | `POST /traces/ingest`, `POST /traces` (OTLP), `POST /metrics`, `POST /logs` | A project **tracing key** | Your agents, services and OpenTelemetry exporters. These are the public, stable integration points. |
| **App endpoints** | Everything else: traces, evaluators, collections, members, projects, SSO, tracing keys, Cost Calculator, synthetic data, evaluations, chat | The signed-in user's **browser session** | The AgentHub and ModelHub web apps. |

The app endpoints are documented so you can see what the product does and what each permission unlocks. They require a browser session cookie, and there are no personal API tokens to call them from a script. If you need to automate something beyond ingestion, talk to your CorePillar contact.

<Note>
  There's no CorePillar SDK package. Use any HTTP client for the ingest endpoint, or any standard OpenTelemetry exporter for the OTLP endpoint. See the [Tracing quickstart](/agenthub/developers/tracing-quickstart).
</Note>

## Response envelope

Most endpoints return JSON in one of two shapes.

**Success:**

```json theme={null}
{
  "data": { "trace_id": "quickstart-0001", "project_id": "6f1c2a9e-...", "span_count": 2, "status": "OK" },
  "meta": { "cursor": null, "pageSize": 1 }
}
```

* `data` holds the result: an object or an array.
* `meta` is present only on endpoints that page or count results.

**Error:**

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid trace payload.",
    "details": { "issues": { "formErrors": [], "fieldErrors": { "spans": ["Invalid datetime"] } } }
  }
}
```

* `code` is a stable `SCREAMING_SNAKE_CASE` identifier. Branch on `code`, never on `message`.
* `message` is a human-readable sentence that may change.
* `details` is an object with extra context. It's often empty (`{}`).

The full list is in [Errors](/api-reference/errors).

### Exceptions to the envelope

A few endpoints answer in a different shape because a client outside AgentHub dictates it:

| Endpoint | Response shape |
| - | - |
| `POST /traces`, `POST /metrics`, `POST /logs` | OTLP `Export*ServiceResponse` (protobuf or JSON), because OpenTelemetry exporters parse the body. Errors still use the error envelope. |
| `POST /chat/stream` | Server-sent events (`text/event-stream`). |
| `POST /projects/{projectId}/cost-calculator/generate-scenarios/stream`, `POST /projects/{projectId}/cost-calculator/runs/{runId}/execute/stream` | Newline-delimited JSON (`application/x-ndjson`). |
| `POST /chat/scan`, `POST /chat/attachments`, `GET /chat/conversations` | A bare JSON object without `data`. Errors are `{ "error": { "code", "message" } }` without `details`. |

## Pagination

Most list endpoints return the full list in one response. The exceptions:

| Endpoint | Paging |
| - | - |
| `GET /projects/{projectId}/traces` | Cursor-based. `limit` defaults to 50 and is capped at 100. The response's `meta.cursor` is an opaque string; pass it back as `?cursor=` for the next page. `meta.cursor` is `null` on the last page. `meta.pageSize` is the number of items in this page. |
| `GET /projects/{projectId}/cost-calculator/trace-runs` | Returns at most the 100 most recent OpenTelemetry runs, with `meta.pageSize`. No cursor. |
| `GET /projects/{projectId}/traces/{traceId}/evaluate` | Returns the 5 most recent evaluation runs for the trace. |

Traces are ordered newest first by `started_at`. The cursor marks a `started_at` boundary, so if several traces share exactly the same `started_at` as the last item on a page, some of them can be skipped by the next page.

## Content types

* Send request bodies as `application/json` unless an endpoint says otherwise. The synthetic-data endpoints reject other content types with `415`.
* `POST /chat/attachments` takes `multipart/form-data` with the file in a `file` field.
* The OTLP endpoints take `application/x-protobuf` or `application/json`, optionally `gzip` or `deflate` compressed.
* Timestamps are ISO 8601 strings in UTC. The ingest endpoint requires a trailing `Z`.
* IDs for organizations, projects, evaluators, collections, runs and keys are UUIDs. A trace's `trace_id` is your own string.

## Status codes

| Code | Meaning |
| - | - |
| `200 OK` | Success. |
| `201 Created` | A resource was created (evaluator, collection, project, tracing key, invite, evaluation run). |
| `202 Accepted` | Trace ingested, Cost Calculator run executed, or a model-backed step that returned a usable but partial result. All of these finish before responding; there's no job to poll. |
| `400`, `401`, `403`, `404`, `409`, `413`, `415`, `422`, `429`, `5xx` | See [Errors](/api-reference/errors). |

## Versioning

The version is part of the path (`/api/v1`). There's no version header. Within `v1`, fields may be added to responses, so ignore fields you don't recognize. There is no `v2` today.

## Rate limits

Only one endpoint is rate limited by AgentHub itself: `POST /auth/sso-discovery`, at 30 requests per minute per client IP. Everything else, including ingestion, has no per-key rate limit today. Long-running streaming endpoints can run for up to 800 seconds.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.