# Time-lapse API
> Time-lapse photography maths as an API, computed locally and deterministically — the clip-length, interval and storage numbers a photographer, filmmaker or camera app plans a sequence with. The clip-length endpoint trades a long shoot for a short clip: the frames captured = the shoot duration ÷ the interval, and the clip length = those frames ÷ the playback frame rate — shooting for 60 minutes at one frame every 5 seconds gives 720 frames, and at 24 fps that plays back in 30 seconds, a 120× speed-up. Longer intervals compress time harder but can stutter on fast motion. The interval endpoint works backwards from a target clip: the frames needed = the target clip length × the frame rate, and the interval = the shoot duration ÷ those frames, so a 60-minute shoot for a 20-second clip at 24 fps needs 480 frames, one every 7.5 seconds. The storage endpoint sizes the card and disk: total storage = the frame count × the size of one frame, and because time-lapse shoots full-resolution stills (RAW ~20–30 MB each), 720 RAW frames at 25 MB is about 18 GB for a single 30-second clip — which is why a long lapse eats cards fast. Everything is computed locally and deterministically, so it is instant and private. Ideal for time-lapse and intervalometer apps, photography-planning tools, and production calculators. Pure local computation — no key, no third-party service, instant. 3 compute endpoints. For video bitrate and file size use a bitrate API.

## 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/timelapse-api/..."
```

## Pricing
- **Free** (Free) — 7,400 calls/Mo, 2 req/s
- **Starter** ($7/Mo) — 62,500 calls/Mo, 6 req/s
- **Pro** ($24/Mo) — 244,000 calls/Mo, 15 req/s
- **Mega** ($74/Mo) — 1,145,000 calls/Mo, 40 req/s

## Endpoints

### Timelapse

#### `GET /v1/clip-length` — Clip length from shoot, interval, fps

**Parameters:**
- `shoot_duration_min` (query, required, string) — Shoot duration (minutes) Example: `60`
- `interval_seconds` (query, required, string) — Interval between frames (s) Example: `5`
- `fps` (query, required, string) — Playback frame rate Example: `24`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/timelapse-api/v1/clip-length?shoot_duration_min=60&interval_seconds=5&fps=24"
```

**Response:**
```json
{
    "data": {
        "note": "A time-lapse trades a long shoot for a short clip: the frames captured = the shoot duration ÷ the interval, and the clip length = those frames ÷ the playback frame rate. Shooting for 60 minutes at one frame every 5 seconds gives 720 frames, and at 24 fps that plays back in 30 seconds — a 120× speed-up. Longer intervals compress time harder but can stutter on fast motion.",
        "inputs": {
            "fps": 24,
            "interval_seconds": 5,
            "shoot_duration_min": 60
        },
        "frame_count": 720,
        "clip_length_seconds": 30,
        "clip_length_formatted": "0:30"
    },
    "meta": {
        "timestamp": "2026-06-07T08:17:51.448Z",
        "request_id": "ae9b780b-6f27-4462-9574-ae66c9a6923c"
    },
    "status": "ok",
    "message": "Clip length",
    "success": true
}
```

#### `GET /v1/interval` — Interval for a target clip

**Parameters:**
- `shoot_duration_min` (query, required, string) — Shoot duration (minutes) Example: `60`
- `target_clip_seconds` (query, required, string) — Target clip length (s) Example: `20`
- `fps` (query, required, string) — Playback frame rate Example: `24`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/timelapse-api/v1/interval?shoot_duration_min=60&target_clip_seconds=20&fps=24"
```

**Response:**
```json
{
    "data": {
        "note": "To hit a target clip length, work backwards: the frames needed = the target clip length × the frame rate, and the interval = the shoot duration ÷ those frames. A 60-minute shoot for a 20-second clip at 24 fps needs 480 frames, so shoot one every 7.5 seconds. Round the interval to what the intervalometer allows, then re-check the clip length.",
        "inputs": {
            "fps": 24,
            "shoot_duration_min": 60,
            "target_clip_seconds": 20
        },
        "frames_needed": 480,
        "interval_seconds": 7.5
    },
    "meta": {
        "timestamp": "2026-06-07T08:17:51.544Z",
        "request_id": "9e417085-969a-44a9-993b-60663816eabf"
    },
    "status": "ok",
    "message": "Interval",
    "success": true
}
```

#### `GET /v1/storage` — Storage from frames and frame size

**Parameters:**
- `frame_count` (query, required, string) — Number of frames Example: `720`
- `frame_size_mb` (query, required, string) — Size of one frame (MB) Example: `25`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/timelapse-api/v1/storage?frame_count=720&frame_size_mb=25"
```

**Response:**
```json
{
    "data": {
        "note": "Card and disk planning: total storage = the frame count × the size of one frame. RAW stills run ~20–30 MB each, large JPEGs ~5–10 MB, so 720 RAW frames at 25 MB is about 18 GB — for one 30-second clip. Time-lapse eats cards fast because every second of output is dozens of full-resolution stills; size the card for the whole shoot plus a margin.",
        "inputs": {
            "frame_count": 720,
            "frame_size_mb": 25
        },
        "total_gb": 17.578,
        "total_mb": 18000
    },
    "meta": {
        "timestamp": "2026-06-07T08:17:51.621Z",
        "request_id": "fe65fa05-cfd2-48fc-aa4a-2a0da804433e"
    },
    "status": "ok",
    "message": "Storage",
    "success": true
}
```

### Meta

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

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

**Response:**
```json
{
    "data": {
        "notes": "Seconds, frames, MB. frames = shoot/interval; clip = frames/fps; interval = shoot/(clip·fps); storage = frames·size. For video bitrate/file size use a bitrate API.",
        "service": "timelapse-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/storage": "Total storage from frame count and per-frame size.",
            "GET /v1/interval": "Shooting interval needed for a target clip length.",
            "GET /v1/clip-length": "Frame count and clip length from shoot duration, interval and fps."
        },
        "description": "Time-lapse maths: clip length from shoot duration/interval/fps, the interval for a target clip, and storage needed."
    },
    "meta": {
        "timestamp": "2026-06-07T08:17:51.714Z",
        "request_id": "9bd46b90-496d-4db6-ae49-f87d775ce5f7"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


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