# Photography Exposure API
> Photographic exposure maths as an API, computed locally and deterministically — the exposure-value, equivalent-exposure and Sunny-16 numbers a photographer, camera-app developer or educator works the exposure triangle with. The exposure-value endpoint gives EV = log₂(aperture² ÷ shutter) and the ISO-100-normalised EV100 (subtracting log₂(ISO/100)) — every one-EV step is a stop, a doubling or halving of light — so bright sun reads about EV 15 and a typical interior EV 6–8, and equal-EV settings give the same exposure. The equivalent endpoint applies the reciprocity at the heart of the triangle: exposure ∝ shutter × ISO ÷ f-number², so when you close the aperture or drop the ISO it returns the new shutter that keeps the brightness constant — going from f/2.8 to f/5.6 needs four times the shutter time. The sunny16 endpoint gives the classic meterless rule: in bright sun shoot f/16 at about 1/ISO (1/125 s at ISO 100), opening up in stops for softer light — slight overcast f/11, overcast f/8, heavy overcast f/5.6, open shade f/4, and f/22 on snow or sand — solving the shutter for your chosen ISO and aperture. Everything is computed locally and deterministically, so it is instant and private. Ideal for camera and photography apps, exposure-calculator and teaching tools, and metering and automation utilities. Pure local computation — no key, no third-party service, instant. 3 compute endpoints. For depth of field and hyperfocal distance use a photography (optics) 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/exposure-api/..."
```

## Pricing
- **Free** (Free) — 8,800 calls/Mo, 2 req/s
- **Starter** ($8/Mo) — 86,000 calls/Mo, 6 req/s
- **Pro** ($27/Mo) — 352,000 calls/Mo, 15 req/s
- **Mega** ($83/Mo) — 1,620,000 calls/Mo, 40 req/s

## Endpoints

### Exposure

#### `GET /v1/equivalent` — Equivalent-exposure shutter

**Parameters:**
- `aperture` (query, required, string) — Base aperture (f-number) Example: `2.8`
- `shutter_s` (query, required, string) — Base shutter (seconds) Example: `0.01`
- `iso` (query, optional, string) — Base ISO (default 100) Example: `100`
- `new_aperture` (query, required, string) — New aperture (f-number) Example: `5.6`
- `new_iso` (query, optional, string) — New ISO (default = base) Example: `100`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/exposure-api/v1/equivalent?aperture=2.8&shutter_s=0.01&iso=100&new_aperture=5.6&new_iso=100"
```

**Response:**
```json
{
    "data": {
        "note": "Equivalent exposure keeps the light constant when you change a setting: exposure ∝ shutter × ISO ÷ f-number², so closing the aperture or lowering the ISO must be paid back with a longer shutter — new shutter = old × (ISO_old/ISO_new) × (N_new²/N_old²). Going from f/2.8 to f/5.6 (two stops smaller) needs four times the shutter time for the same brightness. This is the reciprocity at the heart of the exposure triangle.",
        "inputs": {
            "iso": 100,
            "new_iso": 100,
            "aperture": 2.8,
            "shutter_s": 0.01,
            "new_aperture": 5.6
        },
        "new_shutter_s": 0.04,
        "new_shutter_label": "1/25",
        "shutter_change_stops": 2
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:06.809Z",
        "request_id": "0a284665-c1e0-4b8a-8174-bee620145c23"
    },
    "status": "ok",
    "message": "Equivalent exposure",
    "success": true
}
```

#### `GET /v1/exposure-value` — EV and EV100

**Parameters:**
- `aperture` (query, required, string) — Aperture (f-number) Example: `16`
- `shutter_s` (query, required, string) — Shutter time (seconds) Example: `0.01`
- `iso` (query, optional, string) — ISO (default 100) Example: `100`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/exposure-api/v1/exposure-value?aperture=16&shutter_s=0.01&iso=100"
```

**Response:**
```json
{
    "data": {
        "note": "Exposure value EV = log₂(N² ÷ shutter), where N is the f-number — it pins down the aperture/shutter combination, and every one-EV step is a 'stop' (a doubling or halving of light). EV100 normalises it to ISO 100 by subtracting log₂(ISO/100), giving the scene brightness the meter saw: bright sun is about EV 15, a typical interior EV 6–8. Equal-EV settings give the same exposure — the basis of the exposure triangle.",
        "ev100": 14.644,
        "inputs": {
            "iso": 100,
            "aperture": 16,
            "shutter_s": 0.01
        },
        "ev_settings": 14.644
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:06.907Z",
        "request_id": "fadcd74d-ce75-435e-937e-d660d9734d1f"
    },
    "status": "ok",
    "message": "Exposure value",
    "success": true
}
```

#### `GET /v1/sunny16` — Sunny-16 settings

**Parameters:**
- `iso` (query, optional, string) — ISO (default 100) Example: `100`
- `aperture` (query, optional, string) — Aperture (f-number, default 16) Example: `16`
- `condition` (query, optional, string) — snow_sand|sunny|slight_overcast|overcast|heavy_overcast|open_shade Example: `sunny`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/exposure-api/v1/sunny16?iso=100&aperture=16&condition=sunny"
```

**Response:**
```json
{
    "data": {
        "note": "The Sunny-16 rule: in bright sun set the aperture to f/16 and the shutter to about 1/ISO (1/125 s at ISO 100) for a correct exposure with no meter — EV 15. Softer light opens up in stops: slight overcast f/11 (EV 14), overcast f/8 (EV 13), heavy overcast f/5.6, open shade f/4; snow or sand needs f/22 (EV 16). Here the shutter is solved for your chosen aperture and ISO at the condition's brightness.",
        "ev100": 15,
        "inputs": {
            "iso": 100,
            "aperture": 16,
            "condition": "sunny"
        },
        "recommended_shutter_s": 0.007813,
        "recommended_shutter_label": "1/128"
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:07.004Z",
        "request_id": "93afc2fa-3e35-4448-b507-18b8590b618f"
    },
    "status": "ok",
    "message": "Sunny-16",
    "success": true
}
```

### Meta

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

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

**Response:**
```json
{
    "data": {
        "notes": "f-numbers, seconds, ISO, EV. EV = log₂(N²/t); EV100 = EV − log₂(ISO/100); exposure ∝ t·ISO/N². Conditions: snow_sand, sunny, slight_overcast, overcast, heavy_overcast, open_shade. For depth of field / hyperfocal use a photography (optics) API.",
        "service": "exposure-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/sunny16": "Sunny-16 shutter for a lighting condition, ISO and aperture.",
            "GET /v1/equivalent": "New shutter for equal exposure when aperture/ISO change.",
            "GET /v1/exposure-value": "EV and EV100 from aperture, shutter and ISO."
        },
        "description": "Photographic exposure maths: exposure value (EV) from aperture/shutter/ISO, equivalent-exposure reciprocity, and Sunny-16 settings."
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:07.095Z",
        "request_id": "6b5cbe9f-6cd0-4d3a-b0e9-48d9917612cb"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


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