# Timecode API
> Convert SMPTE timecode for video, film and broadcast. Turn a timecode (HH:MM:SS:FF) into an absolute frame number or into real-time seconds, and turn a frame count back into a timecode — at 23.976, 24, 25, 29.97, 30, 50, 59.94 or 60 fps. Crucially it handles drop-frame correctly: at 29.97 and 59.94 fps it drops the right frame numbers each minute (notated with a semicolon, 01:00:00;00) so an hour of timecode lines up with an hour of real time, and it computes real seconds with the exact fractional rate (30000/1001). Perfect for NLE and editing tools, subtitle and caption timing, playout and broadcast automation, and media asset management. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 4 endpoints. Distinct from date/time, duration and relative-time tools.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/timecode-api/..."
```

## Pricing
- **Free** (Free) — 860 calls/Mo, 2 req/s
- **Starter** ($2/Mo) — 7,100 calls/Mo, 8 req/s
- **Pro** ($20/Mo) — 130,000 calls/Mo, 20 req/s
- **Mega** ($56/Mo) — 670,000 calls/Mo, 50 req/s

## Endpoints

### Timecode

#### `GET /v1/from-frames` — Frame number to timecode

**Parameters:**
- `frames` (query, required, string) — Frame count Example: `107892`
- `fps` (query, required, string) — 23.976|24|25|29.97|30|50|59.94|60 Example: `29.97`
- `drop` (query, optional, string) — true/false (auto for 29.97/59.94)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/timecode-api/v1/from-frames?frames=107892&fps=29.97"
```

**Response:**
```json
{
    "data": {
        "fps": "29.97",
        "frames": 107892,
        "timecode": "01:00:00;00",
        "drop_frame": true
    },
    "meta": {
        "timestamp": "2026-06-02T16:51:45.150Z",
        "request_id": "41e2ef93-ff15-44c7-8f9f-64d2c9957b24"
    },
    "status": "ok",
    "message": "Frames to timecode",
    "success": true
}
```

#### `GET /v1/to-frames` — Timecode to frame number

**Parameters:**
- `timecode` (query, required, string) — HH:MM:SS:FF (;FF for drop-frame) Example: `01:00:00;00`
- `fps` (query, required, string) — 23.976|24|25|29.97|30|50|59.94|60 Example: `29.97`
- `drop` (query, optional, string) — true/false (auto for 29.97/59.94)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/timecode-api/v1/to-frames?timecode=01%3A00%3A00%3B00&fps=29.97"
```

**Response:**
```json
{
    "data": {
        "fps": "29.97",
        "frames": 107892,
        "timecode": "01:00:00;00",
        "drop_frame": true
    },
    "meta": {
        "timestamp": "2026-06-02T16:51:45.253Z",
        "request_id": "668a4ecd-2df8-40fb-b5aa-8ced8b763222"
    },
    "status": "ok",
    "message": "Timecode to frames",
    "success": true
}
```

#### `GET /v1/to-seconds` — Timecode to real-time seconds

**Parameters:**
- `timecode` (query, required, string) — HH:MM:SS:FF Example: `01:00:00;00`
- `fps` (query, required, string) — 23.976|24|25|29.97|30|50|59.94|60 Example: `29.97`
- `drop` (query, optional, string) — true/false (auto for 29.97/59.94)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/timecode-api/v1/to-seconds?timecode=01%3A00%3A00%3B00&fps=29.97"
```

**Response:**
```json
{
    "data": {
        "fps": "29.97",
        "frames": 107892,
        "seconds": 3599.9964,
        "timecode": "01:00:00;00",
        "drop_frame": true
    },
    "meta": {
        "timestamp": "2026-06-02T16:51:45.357Z",
        "request_id": "1febe9b0-789c-4c40-984b-f5635dd5adf7"
    },
    "status": "ok",
    "message": "Timecode to seconds",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/timecode-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "name": "Timecode API",
        "notes": "Drop-frame (notated with ; before the frames) only applies to 29.97 and 59.94 fps and is the broadcast default there; pass drop=false for non-drop. Real seconds use the exact rate (e.g. 30000/1001).",
        "version": "v1",
        "endpoints": [
            {
                "path": "/v1/to-frames",
                "params": {
                    "fps": "23.976|24|25|29.97|30|50|59.94|60",
                    "drop": "true/false (auto for 29.97/59.94)",
                    "timecode": "HH:MM:SS:FF (required)"
                },
                "returns": "total frame number"
            },
            {
                "path": "/v1/from-frames",
                "params": {
                    "fps": "frame rate (required)",
                    "drop": "true/false",
                    "frames": "integer (required)"
                },
                "returns": "the timecode string"
            },
            {
                "path": "/v1/to-seconds",
                "params": {
                    "fps": "frame rate (required)",
                    "timecode": "HH:MM:SS:FF (required)"
                },
                "returns": "real-time seconds"
            },
            {
                "path": "/v1/meta",
                "params": [],
                "returns": "this document"
            }
        ],
        "description": "Convert SMPTE timecode to and from frame counts and real-time seconds, with
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/timecode-api
OpenAPI spec: https://www.oanor.com/api/timecode-api/openapi.json
