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

# Overview

> The Surface Area REST API — worlds and world sessions first, then traces, scores and the rest — covering base URL, HTTP Basic authentication, pagination, timestamps, error shape, and the ingestion and MCP endpoints.

The Surface Area REST API drives a project over HTTPS from any language. It covers [worlds](/worlds) — create one, open a live session against a task, call the session's tools, seed it, grade it, and read back what it scored — plus traces, scores and datasets.

Use the API when a service needs the platform's world rather than a copy on its own disk.

```bash theme={null}
# Open a live session, then drive it
curl "$GATEWAY_HOST/api/public/world-sessions" \
  -u "$GATEWAY_PUBLIC_KEY:$GATEWAY_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slug":"acme-crm","task":"refund-double-charge","surfaces":["api"]}'
```

<Info>
  To send traces from an application, use the [Python SDK](/sdk) or a raw [OTLP](#send-traces-over-otlp-preferred-for-ingestion) exporter instead of hand-written calls. The SDK batches, retries, and formats spans for you. The endpoints below are for reading resources and for custom integrations.
</Info>

## Reach the API at /api/public

Every endpoint lives under the `/api/public` path on your Surface Area host. On the hosted platform the base URL is `https://withgateway.ai/api/public`; on a self-hosted instance, swap in your own host.

The examples on these pages use the same three environment variables as the SDK.

```bash theme={null}
export GATEWAY_HOST="https://withgateway.ai"
export GATEWAY_PUBLIC_KEY="pk-lf-..."
export GATEWAY_SECRET_KEY="sk-lf-..."
```

## Authenticate with HTTP Basic auth

Authenticate with your project's API key pair using HTTP Basic auth. The public key (`pk-lf-...`) is the username and the secret key (`sk-lf-...`) is the password. Generate a pair under Project Settings, then send it on every request.

```bash theme={null}
curl "$GATEWAY_HOST/api/public/traces" \
  -u "$GATEWAY_PUBLIC_KEY:$GATEWAY_SECRET_KEY"
```

The `-u` flag builds the `Authorization: Basic <base64>` header for you. To build the header by hand, base64-encode the two keys joined by a colon.

```bash theme={null}
# Equivalent to the -u form above
echo -n "$GATEWAY_PUBLIC_KEY:$GATEWAY_SECRET_KEY" | base64
# Authorization: Basic <the encoded value>
```

Keys are scoped to a single project, and the resource endpoints resolve the project from the key. An organization-scoped key is rejected on these routes with a 401 and a message asking whether you are using an organization key.

<Info>
  Keep the secret key in an environment variable or secrets manager. Never inline it in source files, commit it, or paste it into an agent prompt.
</Info>

## Page through list results

List endpoints return a fixed envelope: a `data` array plus a `meta` object with the current page and totals. Request a page with the `page` and `limit` query parameters.

| Parameter | Type | Default | Notes |
| - | - | - | - |
| `page` | integer | `1` | One-based. The first page is `page=1`. |
| `limit` | integer | `50` | Items per page. Maximum `100`. |

```json theme={null}
{
  "data": [ /* ... */ ],
  "meta": {
    "page": 1,
    "limit": 50,
    "totalItems": 1280,
    "totalPages": 26
  }
}
```

Read `totalPages`, or divide `totalItems` by `limit`, to know how many pages remain. A few high-volume endpoints (such as `GET /v2/observations`) use an opaque `cursor` instead of `page`; their reference rows say so.

## Timestamps are ISO 8601

Send and read timestamps as ISO 8601 strings with an offset, for example `2024-01-15T09:00:00Z`. Time-range filters on list endpoints use `fromTimestamp` (inclusive) and `toTimestamp` (exclusive).

```bash theme={null}
curl -G "$GATEWAY_HOST/api/public/traces" \
  -u "$GATEWAY_PUBLIC_KEY:$GATEWAY_SECRET_KEY" \
  --data-urlencode "fromTimestamp=2024-01-01T00:00:00Z" \
  --data-urlencode "toTimestamp=2024-02-01T00:00:00Z"
```

## Errors return JSON with a message

Every error responds with a JSON body carrying a human-readable `message`. Most errors add an `error` field naming the error type; validation errors instead list the specific field problems under `error`.

```json theme={null}
{
  "message": "Invalid request data",
  "error": [
    { "path": ["limit"], "message": "Number must be less than or equal to 100" }
  ]
}
```

The status code tells you what to do next.

| Status | Meaning | Typical cause |
| - | - | - |
| `400` | Bad request | A query parameter or body field failed validation. |
| `401` | Unauthorized | Missing or invalid keys, or an organization key on a project route. |
| `403` | Forbidden | Access denied, or ingestion suspended after exceeding a usage threshold. |
| `404` | Not found | No resource with the given id in this project. |
| `405` | Method not allowed | The path exists but not for that HTTP method. |
| `429` | Too many requests | You hit a rate limit. Back off and retry. |
| `5xx` | Server error | A `500` internal error, or `524` when a query runs too long. |

Ingestion is the exception. A batch ingestion call returns `207 Multi-Status` with per-event `successes` and `errors`, so one bad event does not fail the whole batch.

## Send traces over OTLP (preferred for ingestion)

Surface Area accepts traces over the OpenTelemetry Protocol (OTLP) at `POST /api/public/otel/v1/traces`. `tracing.init()` points at the same endpoint.

The endpoint accepts an OTLP `ExportTraceServiceRequest` as either Protocol Buffers (`Content-Type: application/x-protobuf`) or JSON (`Content-Type: application/json`), and it decompresses gzipped bodies. Authenticate with the same HTTP Basic keys.

```bash theme={null}
curl "$GATEWAY_HOST/api/public/otel/v1/traces" \
  -u "$GATEWAY_PUBLIC_KEY:$GATEWAY_SECRET_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @spans.json
```

A companion metrics endpoint lives at `POST /api/public/otel/v1/metrics`. For the full export walkthrough, including batching, flushing, and endpoint overrides, see [Export to Surface Area](/tracing/export).

## Ingest events in a batch

The batch ingestion endpoint, `POST /api/public/ingestion`, accepts a mixed list of trace, observation, and score events in one call. It backs the SDK's own ingestion path.

Send a JSON body with a `batch` array and optional `metadata`. Each event needs a `type`, an `id`, a `timestamp`, and a `body`. The response is `207 Multi-Status`.

```bash theme={null}
curl "$GATEWAY_HOST/api/public/ingestion" \
  -u "$GATEWAY_PUBLIC_KEY:$GATEWAY_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "batch": [
      {
        "type": "trace-create",
        "id": "b8f1...-event-id",
        "timestamp": "2024-01-15T09:00:00Z",
        "body": { "id": "my-trace-id", "name": "chat-request" }
      }
    ]
  }'
```

<Info>
  Use OTLP or the SDK first. Batch ingestion is the lower-level path the SDK builds on.
</Info>

## Query and manage from the MCP endpoint

Surface Area exposes a Model Context Protocol (MCP) endpoint at `POST /api/public/mcp` so AI assistants can query and manage a project over JSON-RPC 2.0. Authenticate with either the HTTP Basic key pair (one project) or a personal access token.

With a personal access token, send `Authorization: Bearer pat_...` and name the project in the query string as `?project_id=<id>`. Set the `Accept` header to `application/json, text/event-stream`, since the endpoint may answer with plain JSON or a server-sent-events stream.

```bash theme={null}
curl "$GATEWAY_HOST/api/public/mcp?project_id=<project-id>" \
  -H "Authorization: Bearer pat_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

For the local proxy, client wiring for Claude Code and Cursor, and the full tool list, see [Set up the MCP server](/mcp/setup).

## Where to go next

* [Core Resources](/rest-api/resources): the route tables and a worked `curl` example for every resource.
* [Tracing](/tracing): instrument an agent and export its spans.
* [MCP Server](/mcp): drive Surface Area from an AI assistant.


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