# Getting started

Auth, scopes, rate limits, errors, idempotency and pagination, once.

Everything platform-wide lives on this page: auth, rate limits, errors, idempotency, pagination. Individual service pages document only their own resources.

## Base URL

```http
https://api.rsx.group/{project}/{version}/{group}/{action}
```

Actions come from a fixed vocabulary: `get` and `list` are `GET`; `add`, `update` and `remove` are `POST`. Versions are major-overhaul-only. `v1` stays `v1` until the API is rethought, and deprecations get a published sunset date, never a silent removal.

## Authentication

Every request carries an API key. Keys are issued from your RSX ID, shown once at creation, and prefixed `rsx_live_` so they are identifiable in your own config and logs without being guessable.

```bash
curl https://api.rsx.group/example/v1/widgets/list \
  -H "Authorization: Bearer rsx_live_..."
```

Keys hold **scopes** shaped like the URLs they unlock, for example `example:widgets:add`, or with a trailing wildcard, `example:widgets:*`. A request outside your key's scopes returns `403` [invalid-scope](/errors/invalid-scope) naming the scope you are missing. Rotate keys with `/platform/v1/keys/rotate`: the old key keeps working for a grace window while you swap the new one in.

## Rate limits

Limits are per key (a token bucket: a burst of 60, refilling at 10 a second by default). Every response reports where you stand:

```http
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 41
```

Exceeding the limit returns `429` [rate-limit-exceeded](/errors/rate-limit-exceeded) with a `Retry-After` header in seconds. Honour it.

## Errors

Every error, from every service, is RFC 7807 `application/problem+json`:

```json
{
  "type": "https://docs.rsx.group/errors/invalid-scope",
  "title": "Invalid scope",
  "status": 403,
  "detail": "API key does not have the 'example:widgets:add' scope.",
  "instance": "/example/v1/widgets/add",
  "requestId": "0198f2b1-..."
}
```

The `type` URL resolves to a page in the [error reference](/errors) explaining the failure and the fix. Include the `requestId` when reporting a problem; it pinpoints your exact request in our logs.

## Idempotency

Every `add` action requires an `Idempotency-Key` header. Reusing the key within 24 hours returns the original response instead of creating a duplicate, so retries on timeouts are safe by default.

```bash
curl -X POST https://api.rsx.group/example/v1/widgets/add \
  -H "Authorization: Bearer rsx_live_..." \
  -H "Idempotency-Key: 5b8f2d1a-..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Acrylic Panel", "quantity": 12}'
```

## Responses and pagination

Success responses wrap payloads in `{ data }`, with `{ data, meta }` on `list` actions. `meta.cursor` is an opaque token: pass it back as `?cursor=` to fetch the next page; `null` means you have reached the end.

## Request tracing

Every response carries `X-Request-Id`. Send your own `X-Correlation-Id` to stitch a multi-call workflow together across our logs, and the platform propagates it unchanged.

## Machine-readable specs

Every service publishes OpenAPI 3.1 at `https://api.rsx.group/{project}/{version}/openapi.json`, generated from the same schemas that validate requests, so it cannot drift from behaviour. Point your own tooling at it freely, and read the rendered version under [API](/api).

---

Published at https://docs.rsx.group/guides/getting-started (revision 1, 2026-10-12).
