{"openapi":"3.1.0","info":{"title":"Time-lapse API","version":"1.0.0","description":"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.","contact":{"name":"PremiumApi","url":"https://www.oanor.com/by/premiumapi"}},"servers":[{"url":"https://api.oanor.com/timelapse-api","description":"oanor gateway"}],"tags":[{"name":"Timelapse"},{"name":"Meta"}],"components":{"securitySchemes":{"oanorKey":{"type":"apiKey","in":"header","name":"x-oanor-key","description":"Get your key at https://www.oanor.com/developer/keys"}}},"security":[{"oanorKey":[]}],"paths":{"/v1/clip-length":{"get":{"operationId":"get_v1_clip_length","tags":["Timelapse"],"summary":"Clip length from shoot, interval, fps","description":"","parameters":[{"name":"shoot_duration_min","in":"query","required":true,"description":"Shoot duration (minutes)","schema":{"type":"string"},"example":"60"},{"name":"interval_seconds","in":"query","required":true,"description":"Interval between frames (s)","schema":{"type":"string"},"example":"5"},{"name":"fps","in":"query","required":true,"description":"Playback frame rate","schema":{"type":"string"},"example":"24"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/interval":{"get":{"operationId":"get_v1_interval","tags":["Timelapse"],"summary":"Interval for a target clip","description":"","parameters":[{"name":"shoot_duration_min","in":"query","required":true,"description":"Shoot duration (minutes)","schema":{"type":"string"},"example":"60"},{"name":"target_clip_seconds","in":"query","required":true,"description":"Target clip length (s)","schema":{"type":"string"},"example":"20"},{"name":"fps","in":"query","required":true,"description":"Playback frame rate","schema":{"type":"string"},"example":"24"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/storage":{"get":{"operationId":"get_v1_storage","tags":["Timelapse"],"summary":"Storage from frames and frame size","description":"","parameters":[{"name":"frame_count","in":"query","required":true,"description":"Number of frames","schema":{"type":"string"},"example":"720"},{"name":"frame_size_mb","in":"query","required":true,"description":"Size of one frame (MB)","schema":{"type":"string"},"example":"25"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/meta":{"get":{"operationId":"get_v1_meta","tags":["Meta"],"summary":"Spec","description":"","parameters":[],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"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}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}}},"x-oanor-pricing":[{"slug":"free","name":"Free","price_cents_month":0,"monthly_call_quota":7400,"rps_limit":2,"hard_limit":true},{"slug":"starter","name":"Starter","price_cents_month":695,"monthly_call_quota":62500,"rps_limit":6,"hard_limit":true},{"slug":"pro","name":"Pro","price_cents_month":2380,"monthly_call_quota":244000,"rps_limit":15,"hard_limit":true},{"slug":"mega","name":"Mega","price_cents_month":7350,"monthly_call_quota":1145000,"rps_limit":40,"hard_limit":true}],"x-oanor-marketplace-url":"https://www.oanor.com/api/timelapse-api"}