# Real-Debrid API Contract Reference

**Source:** https://api.real-debrid.com/
**Base URL:** `https://api.real-debrid.com/rest/1.0`
**Auth:** `Authorization: Bearer <api_token>` header

## Endpoints Used for Stream Resolving

### POST /torrents/addMagnet
- **Method:** POST
- **Body:** `magnet=<url_encoded_magnet_link>` (form data)
- **Response:** HTTP 201, `{"id": 12345, "uri": "/torrents/info/12345"}`
- **Errors:** 400, 401, 403, 503

### POST /torrents/selectFiles/{id}
- **Method:** POST
- **Body:** `files=all` or `files=1,2,3` (form data)
- **Response:** HTTP 204 (No Content)
- **Errors:** 202 (already done), 400, 401, 403, 404

### GET /torrents/info/{id}
- **Method:** GET
- **URL param:** `{id}` — numeric torrent ID (NOT info-hash)
- **Response:** HTTP 200, contains `id`, `hash`, `filename`, `bytes`, `status`, `files[]`, `links[]`, `added`
- **Errors:** 401, 403, 404

### POST /unrestrict/link
- **Method:** POST
- **Body:** `link=<url_encoded_hoster_link>` (form data)
- **Response:** HTTP 200, `{"filename": "...", "filesize": N, "link": "https://...", "mimeType": "..."}`
- **Errors:** 400, 401, 403, 503

### GET /torrents/instantAvailability/{hash}
- **Method:** GET
- **Response:** HTTP 200, keyed by hash with provider availability info
- **Errors:** 401

## Full Torrent Flow

1. `POST /torrents/addMagnet` with `magnet=<magnet_url>` → get `id`
2. `POST /torrents/selectFiles/{id}` with `files=all` (required before processing)
3. `GET /torrents/info/{id}` → get `links[]` (download URLs)
4. For each link: `POST /unrestrict/link` with `link=<download_url>` → get playable `link`

## Key Field Mappings

| Response Field | RD Field | Type | Notes |
|---|---|---|---|
| Stream URL | `link` | string | From unrestrict response |
| Filename | `filename` | string | From unrestrict or info response |
| Size (bytes) | `filesize` | int | From unrestrict response (NOT `size`) |
| Cached | `status == "downloaded"` | bool | From info response |
| Torrent ID | `id` | int | From addMagnet response |
| MIME type | `mimeType` | string | From unrestrict response |

## Rate Limits

- 250 requests/minute
- 429 on limit exceeded (counts even refused requests)

## Known Deviations from Common Assumptions

1. **`/torrents/add/{hash}` does NOT exist** — use `/torrents/addMagnet`
2. **`/torrents/stream/{hash}/{file}` does NOT exist** — use `/unrestrict/link` with DDL links
3. **Info endpoint requires numeric torrent ID**, not info-hash
4. **`selectFiles` is mandatory** — without it, links won't be available
5. **Response field is `filesize`**, not `size` in unrestrict response
