# API reference

> The address, formats and conventions shared by every route of API v1, then each route one by one.

**Address: `https://api.rustine.io/v1`**

- **Authentication**: `Authorization: Bearer rst_…` ([Authentication](https://docs.rustine.io/en/authentication.md)).
- **Format**: JSON in and out, `snake_case` fields, ISO 8601 dates (UTC), UUID ids.
- **Lists**: `{ "object": "list", "data": [...], "has_more": false }`, with `limit` and `starting_after` ([Pagination](https://docs.rustine.io/en/pagination.md)).
- **Errors**: `{ "error": { "type", "code", "message", "doc_url" } }` ([Errors](https://docs.rustine.io/en/api/errors.md)).
- **Writes**: send an `Idempotency-Key` on `POST` requests ([Idempotency](https://docs.rustine.io/en/idempotency.md)).
- **Language**: error messages and issue texts come in the language of the key's owner.

Every response carries `Request-Id` (give it to support), `Rustine-Version` (the contract version that answered, see [Versions](https://docs.rustine.io/en/versioning.md)) and the `X-RateLimit-*` headers ([Rate limits and quotas](https://docs.rustine.io/en/rate-limits.md)).

The full specification is served as-is at [`/openapi.json`](https://docs.rustine.io/openapi.json) (OpenAPI 3.1): import it into Postman, Insomnia or a client generator.

## Routes

- `GET /projects`: [List projects](https://docs.rustine.io/en/api/projects/list.md)
- `POST /projects`: [Create a project](https://docs.rustine.io/en/api/projects/create.md)
- `GET /projects/{project_id}`: [Get a project](https://docs.rustine.io/en/api/projects/get.md)
- `POST /projects/{project_id}/targets`: [Add a site](https://docs.rustine.io/en/api/projects/add-site.md)
- `POST /targets/{target_id}/scans`: [Start a scan](https://docs.rustine.io/en/api/scans/create.md)
- `GET /scans/{scan_id}`: [Get a scan](https://docs.rustine.io/en/api/scans/get.md)
- `GET /projects/{project_id}/scans`: [List a project's scans](https://docs.rustine.io/en/api/scans/list.md)
- `GET /projects/{project_id}/issues`: [List issues](https://docs.rustine.io/en/api/issues/list.md)
- `GET /issues/{issue_id}`: [Get an issue](https://docs.rustine.io/en/api/issues/get.md)
- `POST /issues/{issue_id}/fix`: [Unlock the fix](https://docs.rustine.io/en/api/issues/unlock-fix.md)
- `GET /issues/{issue_id}/fix`: [Read a fix](https://docs.rustine.io/en/api/issues/fix.md)
- `POST /issues/{issue_id}/recheck`: [Recheck an issue](https://docs.rustine.io/en/api/issues/recheck.md)
- `PATCH /issues/{issue_id}`: [Mark an issue](https://docs.rustine.io/en/api/issues/update.md)
- `GET /account`: [Your plan and quotas](https://docs.rustine.io/en/api/account.md)

## Examples

### curl

```bash
curl -i https://api.rustine.io/v1/account \
  -H "Authorization: Bearer $RUSTINE_API_KEY"
```

### Response: 200 OK

```http
HTTP/1.1 200 OK
Content-Type: application/json
Request-Id: req_6f1c0d9a2b7e4c3d5a8b9e0f
Rustine-Version: 2026-10-13
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 119
X-RateLimit-Reset: 1792061520
```
