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

# Introduction

> Build on Replo programmatically with the public API.

The Replo API lets you work with your Replo workspaces and projects programmatically from your own code, automations, or tools like n8n.

## Base URL

All public API endpoints are served from:

```text theme={null}
https://api.replo.app/v1
```

## Authentication

Create a public API key from your Replo Settings, then send it as a bearer token:

```bash theme={null}
curl "https://api.replo.app/v1/products?projectId=$REPLO_PROJECT_ID" \
  -H "Authorization: Bearer $REPLO_PUBLIC_API_KEY" \
  -H "Replo-Api-Version: $REPLO_API_VERSION"
```

Each public API key uses the current permissions of the person who created it, limited by the key's scopes. If either check fails, Replo returns a 404. The same status is used when a resource does not exist, so API responses do not confirm private resource IDs. If a known resource returns a 404, check the key's scopes and its creator's current project access.

## API version

Every request must include the `Replo-Api-Version` header. See [API versioning](/api-reference/versioning) for the current supported version and upgrade guidance.

## Save working documents to Files

Use Files for research and working documents; Assets is a separate media library. Grant your API key `files.read` to list or read files and `files.write` to create, rename, or move them. Copying an Asset also requires `assets.read`. Existing keys do not gain new scopes automatically.

Use the project UUID returned by `GET /v1/projects`. Supply `projectId` when listing or creating files. Requests for an existing `fileId` resolve the project from that file. File ownership and sharing permissions still apply.

```bash theme={null}
curl "https://api.replo.app/v1/files" \
  -H "Authorization: Bearer $REPLO_PUBLIC_API_KEY" \
  -H "Replo-Api-Version: $REPLO_API_VERSION" \
  -H "Content-Type: application/json" \
  --data "{\"projectId\":\"$REPLO_PROJECT_ID\",\"kind\":\"file\",\"name\":\"research.md\",\"source\":{\"type\":\"text\",\"text\":\"# Research\"}}"
```

Omitting `parentId` saves to My Files. Files accept text, base64 data, or an existing Asset as their source, up to 10 MiB. A duplicate name returns `409 conflict` without overwriting. Read contents with `GET /v1/files/{fileId}/content`; the response contains complete text or a download URL valid for 15 minutes.

## Error handling

All errors return a consistent JSON envelope with a `code`, a `message`, and a `doc_url` linking to that code's documentation:

```json theme={null}
{
  "error": {
    "code": "not_found",
    "message": "The requested resource was not found.",
    "doc_url": "https://beta.docs.replo.app/api-reference/errors#not_found"
  }
}
```

See [Errors](/api-reference/errors) for every code and how to recover from it.

## Async operations and polling

Some operations, like agent sessions, run asynchronously. They return immediately with a resource ID, and you poll for status updates.

**Recommended polling pattern:**

1. Call the create endpoint (e.g., `POST /agent/sessions`)
2. Receive 202 Accepted with a session ID
3. Poll the status endpoint every 5-10 seconds (e.g., `GET /agent/sessions/{id}`)
4. If the response includes `pendingInteractions`, the session is blocked waiting on you: resolve each one with `POST /agent/sessions/{id}/interactions/{interactionId}/resolve`, then keep polling
5. Continue until status is `completed` or `failed`

**Handling cold starts:**

New sessions may return 404 for 1-2 seconds during sandbox initialization. Use exponential backoff, with `apiVersion` set to the current version from [API versioning](/api-reference/versioning):

```javascript theme={null}
async function pollWithBackoff(sessionId, maxAttempts = 10) {
  let delay = 1000;
  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(`https://api.replo.app/v1/agent/sessions/${sessionId}`, {
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Replo-Api-Version": apiVersion
      }
    });
    if (response.status === 404 && i < 3) {
      await new Promise(r => setTimeout(r, delay));
      delay *= 2;
      continue;
    }
    return response.json();
  }
}
```

## Idempotency

Some operations are **idempotent**: calling them multiple times with the same input produces the same result.

| Operation                            | Idempotent? | Notes                                                  |
| ------------------------------------ | ----------- | ------------------------------------------------------ |
| `GET` (all)                          | Yes         | Safe to retry                                          |
| `POST /agent/sessions`               | No          | Each call creates a new session                        |
| `POST /agent/sessions/{id}/messages` | No          | Each call starts a new turn                            |
| `POST /agent/sessions/{id}/abort`    | Yes         | Aborting twice is a no-op                              |
| `POST /products`                     | No          | Each call creates a new product                        |
| `PATCH /products/{id}`               | Yes         | Same update can be retried                             |
| `DELETE` (all)                       | Yes         | Safe to retry; a repeat delete returns 404 `not_found` |

When retrying non-idempotent operations after a network failure, check whether the original request succeeded before retrying to avoid duplicates.

## MCP

To work with Replo through Claude or ChatGPT instead of making HTTP requests, [use Replo's MCP connection](/mcp/overview).
