# API v1

The Viresso API provides programmatic access to entries, files, authentication, and other workspace resources.

## Base URL

```
https://app.example.com/api/v1/{workspace}
```

The `{workspace}` segment is the workspace name, not a numeric ID.

Example for a workspace named `acme`:

```
https://app.example.com/api/v1/acme
```

## Required headers

| Header | Required | Value |
|---|---|---|
| `Authorization` | Except hosted auth and tokenized/signed downloads | `Bearer {api_key}` |
| `Accept` | Recommended | `application/json` |
| `Content-Type` | For requests with a body | `application/json`, or `multipart/form-data` for file uploads |

For multipart uploads, let your HTTP client set `Content-Type` with its boundary (for example, curl `-F` or JavaScript `FormData`).

API keys are only accepted in the bearer header. Query parameters such as `token`
are ignored for API-key authentication.

Create API keys in Viresso from **Settings → API Keys**. Hosted authentication access tokens are different: they identify authenticated app users and should not be used as API keys.

## Content queries

Entry list and create endpoints require `contentBucket` and `contentType` as query parameters to identify the target content type:

| Parameter | Required | Description |
|---|---|---|
| `contentBucket` | Yes (list/create) | The content bucket name, e.g. `content` |
| `contentType` | Yes (list/create) | The content type name, e.g. `pages` |
| `locale` | No | Locale code or `*` (default `en-US`) |
| `skipWebhooks` | No | Set `true` to suppress webhook delivery |

Show, update, and delete endpoints resolve the content type from the entry and do not need `contentBucket` or `contentType`.

## Error responses

The API uses standard HTTP status codes:

| Status | Meaning |
|---|---|
| 200 | Success |
| 201 | Entry or file created |
| 202 | Pipeline execution queued |
| 204 | No Content (successful delete or email API request) |
| 400 | Invalid locale or malformed request |
| 403 | Invalid API key, origin mismatch, or forbidden access |
| 404 | Workspace, content type, entry, or file not found |
| 422 | Validation failed — check the `errors` object |
| 429 | Rate limited — check the `Retry-After` header |

### Validation errors (422)

```json
{
  "message": "The title field is required.",
  "errors": {
    "fields.title": [
      "The title field is required."
    ],
    "fields.slug": [
      "The slug field format is invalid."
    ]
  }
}
```

### Authentication errors (403)

```json
{
  "message": "Forbidden"
}
```

Missing scopes or creator permissions return `403` with `This API key is not permitted to perform this action.` Suspended workspaces return `Workspace suspended.` Local and test environments may include additional diagnostic fields. Use status codes and validation fields for programmatic handling.

### Not found (404)

```json
{
  "message": "Not Found"
}
```

## Rate limiting

API requests use separate limits based on the credential or capability being used:

| Endpoint group | Limit and scope |
|---|---|
| Entries | 500 units per minute per API key; one per request, or one per query in a read batch |
| File uploads | 60 requests per minute per API key |
| File deletions | 60 requests per minute per API key |
| Tokenized file downloads | 1,200 requests per minute per capability URL |
| Pipeline execution | 30 requests per minute per API key |
| Transactional mail | 10 requests per minute per API key |
| Hosted auth login | 10 requests per minute per email and 60 per IP |
| Hosted auth verification | 10 requests per minute per OTP and 120 per IP |
| Hosted auth token exchange | 60 requests per minute per IP |
| Hosted auth session validation | 600 requests per minute per access token |

Exceeded requests return `429 Too Many Requests` with a `Retry-After` header. Limits are configurable and disabled by default in local and test environments. See [API Access](/docs/platform/api-access#rate-limiting).

## Locale support

The `locale` query parameter is supported when listing, reading, creating, and updating entries. Entry deletion does not use a locale. See [Localization](/docs/content/localization) for the full guide.

## API endpoints

| Endpoint | Method | Purpose |
|---|---|---|
| [Authentication](/docs/api/authentication) | POST | Log in, verify OTP, exchange auth codes, authenticate tokens |
| [Entries](/docs/api/entries) | GET, POST, PUT, PATCH, DELETE | Full entry CRUD |
| [Entry Localization](/docs/api/entry-localization) | GET, POST, PATCH | Locale parameter reference |
| [Files](/docs/api/files) | POST, GET, DELETE | Upload, read, and delete files; obtain expiring signed downloads and images; access permanent downloads and image proxy URLs |
| [Email](/docs/api/email) | POST | Send transactional emails |
| [Pipelines](/docs/api/pipelines) | POST, GET | Execute saved workflows and poll queued execution status |
| [Errors and Validation](/docs/api/errors-and-validation) | — | HTTP status codes and error formats |
| [Code Examples](/docs/api/code-examples) | — | Laravel, PHP, and Node.js examples |

The additional `GET /api/v2/{workspace}/entries` route always uses cursor pagination and defaults to summary objects. It accepts the same content bucket/type, locale, paging, and API-key parameters; see [Entries API](/docs/api/entries#list-published-entries). Other operations use v1.

## Related pages

- [API Authentication](/docs/api/authentication) — API keys and hosted authentication.
- [API Entries](/docs/api/entries) — Entry CRUD reference.
- [Code Examples](/docs/api/code-examples) — Connect your application to Viresso.
- [Localization](/docs/content/localization) — Locale behavior in the API.
- [API Access](/docs/platform/api-access) — API key management and rate limits.
