# API

The R3DRenderer HTTP API lets you submit osu! replays and pull the finished videos without going through Discord or the web upload form. Same pipeline, same output, same rate caps. If you're building something that batches renders, feeds them into a highlight reel, or embeds them somewhere your users won't see Discord, this is what you want.

**Supporter perk.** API access is one of the things a Ko-fi tip unlocks. Everything below still works to read; you'll just get a `403` when you try to submit or mint a key. Support the project on [Ko-fi](https://ko-fi.com/r3drenderer) and it turns on.

## Authentication

Every request needs an `Authorization` header with a bearer token. You mint tokens on the [settings page](https://r3drenderer.com/settings#api) under API Access. Each token is shown to you once at creation time; the server stores a hash, not the token itself, so if you lose it you have to mint a new one. Revoking a token is instant.

```http
Authorization: Bearer rrdr_your_token_here
```

## Submitting a render

`POST /api/v1/render` accepts a multipart form with the `.osr` file in the `osr` field. The response is a job id you can poll. The same per-user cooldowns and resolution/fps supporter caps apply here as on the web upload; if you hit a cooldown the response tells you how many seconds to wait.

```bash
curl -X POST https://r3drenderer.com/api/v1/render \
  -H "Authorization: Bearer rrdr_your_token_here" \
  -F "osr=@/path/to/replay.osr"
```

```json
{
  "job_id": "01H9QK3ABCDE"
}
```

## Checking status

`GET /api/v1/render/{job_id}` returns the job's current state. Poll at a sane interval, maybe every 3 to 5 seconds. A finished job has a `video_url` field pointing at the rendered `.mp4`. A failed job has a `failure` field with a short reason. Queued jobs stay queued until the worker pool has a free slot; a typical render at 1080p60 takes somewhere between one and three minutes once the worker starts.

```bash
curl https://r3drenderer.com/api/v1/render/01H9QK3ABCDE \
  -H "Authorization: Bearer rrdr_your_token_here"
```

```json
{
  "job_id": "01H9QK3ABCDE",
  "status": "done",
  "video_url": "https://r3drenderer.com/m/01H9QK3ABCDE.mp4?v=123456789",
  "page_url":  "https://r3drenderer.com/v/01H9QK3ABCDE",
  "thumb_url": "https://r3drenderer.com/t/01H9QK3ABCDE.jpg"
}
```

The four possible values of `status` are `queued`, `running`, `done`, and `failed`. Anything else is a bug and worth reporting on the [forum](https://r3drenderer.com/forum).

## Managing tokens

You can list your active tokens over the API as well as mint new ones. Listing returns the hash prefix and the created-at date so you can identify which is which without ever seeing the token value again. Minting a new token returns the full value once, in the response body, and never again.

```bash
curl https://r3drenderer.com/api/v1/keys \
  -H "Authorization: Bearer rrdr_your_token_here"
```

```bash
curl -X POST https://r3drenderer.com/api/v1/keys \
  -H "Authorization: Bearer rrdr_your_token_here"
```

## Beatmap resolution

`POST /api/v1/beatmap/resolve` is a one-shot utility endpoint that takes a beatmap hash or id and returns whatever the renderer would find for it. Useful for validating a replay before submitting the render, or for building tooling that needs to resolve metadata without spending a render slot.

## Rate limits

API access is a supporter tier feature, so free-tier cooldowns don't apply here. There is still a global rate limit on top-tier resolution (1440p) so one user can't monopolise the GPU for hours at a time. When you hit a cap the response is a `429` with a `retry_after` field in seconds. Any other cap you hit (per-day submission ceilings, per-hour beatmap-resolve quota) is documented in the response body when it fires.

## Errors

Errors are JSON with a top-level `error` string and, where useful, an `message`. Common ones you'll actually hit are `401` (bad or missing token), `403` (endpoint requires supporter), `413` (`.osr` over the 5 MB per-file cap), `422` (replay didn't parse), and the `429` cooldown mentioned above. Anything `5xx` means the pipeline broke and Red probably wants to know about it.

Source: [https://r3drenderer.com/api-docs](https://r3drenderer.com/api-docs)
