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

# Platform overview

> How the API is shaped, what it is scoped to, and what it will not do.

Testorim is a single-origin application: the app, the HTTP API and the
WebSocket used for live runs all serve from `https://app.testorim.com`.

## The API surface

The API-key surface is small and deliberately so. It covers what a pipeline,
a terminal or an integration needs:

| Area       | Endpoints                                                              |
| ---------- | ---------------------------------------------------------------------- |
| Runs       | Trigger, list, get one, cancel one, cancel a batch                     |
| Procedures | List a project's saved tests, get one, export one as a Playwright spec |
| Projects   | List, create, get one                                                  |
| API keys   | List, mint (browser session only), revoke                              |
| Identity   | Who the presented credential belongs to                                |

Full detail, including every response field, is in the
[API reference](/api-reference/introduction).

<Note>
  The API is **unversioned in the URL**. There is no `/v1` prefix. The
  `1.0.0` in the reference is a documentation version, not a server version.
</Note>

## Scoping

An API key is bound to **one user and one workspace**. Every request pins the
workspace to the key's, so a key issued for workspace A can never read or write
workspace B, even if the owning person belongs to both. If that person is
later removed from the workspace, the key stops working.

Every list and lookup is workspace-scoped. A resource in another workspace
returns `404`, never `403`, so the API does not leak the existence of things
you cannot see.

A key held by someone with the `viewer` role is read-only: any request that is
not `GET`, `HEAD` or `OPTIONS` is rejected with `403` and
`code: "read_only_role"`.

## Rate limits

| Limit       | Policy         | Keyed by  | Applies to               |
| ----------- | -------------- | --------- | ------------------------ |
| Global      | 600 / minute   | client IP | every `/api/*` request   |
| Run trigger | 30 / minute    | user      | `POST /api/runs/trigger` |
| Read        | 120 / minute   | user      | `GET /api/runs/active`   |
| Failed auth | 5 / 15 minutes | client IP | rejected credentials     |

A throttled request returns `429` with `{ "error": …, "retryAfter": <seconds> }`
and a `Retry-After` header. There are **no** `X-RateLimit-*` headers, so do not
write a client that depends on them.

Rate limits are separate from plan quotas. Exhausting the workspace's monthly
run allowance also returns `429`, but with no `Retry-After`.

## Request rules

* JSON bodies are capped at 1 MB.
* Any string containing a NUL byte rejects the whole request with `400`.
* Schema failures return `400` with an `issues` array naming each problem.

## Starting a run

`POST /api/runs/trigger` responds **`202 Accepted`** with a run id. It does not
wait for the run. Poll `GET /api/runs/{id}` until the status is terminal, or
let the [CLI](/developers/cli) do it for you.

## What the API does not do

* **No outbound webhooks.** Testorim will not call your server when a run
  finishes. Trigger the run yourself and read the result.
* **No streaming over HTTP.** Live screenshots go over the app's WebSocket,
  which is session-authenticated and not part of the API-key surface.
* **No billing, org or integration management.** Those are app-only.


## Related topics

- [Integrations overview](/integrations/overview.md)
- [API reference](/api-reference/introduction.md)
- [Create a project](/getting-started/create-a-project.md)
- [Projects](/projects/projects.md)
- [Reusable flows](/test-creation/reusable-flows.md)
