# Picture Framing API
> Picture-framing maths as an API, computed locally and deterministically — the mat-cutting and moulding numbers a framer or artist measures a job by. The mat endpoint sizes the mat board around an artwork: the window opening is the art minus a small overlap on each edge (≈ 0.25 inch so the mat holds the print), and the outer mat is the window plus the border widths — give one border or per-side borders, with a heavier bottom for a balanced, bottom-weighted mat, so an 8×10 print with a 2-inch border has a 7.5×9.5 window and an 11.5×13.5 mat. The moulding endpoint computes the frame stick needed: length = inner perimeter + 8 × the moulding width, because each of the four 45-degree mitred corners adds one moulding width — an 11.5×13.5 frame in 1.5-inch moulding needs 62.5 inches, plus any waste allowance. Everything is computed locally and deterministically, so it is instant and private. Ideal for picture-framing, custom-framing, art-gallery and DIY app developers, mat-cutter and moulding-estimating tools, and framing education. Pure local computation — no key, no third-party service, instant. Imperial inches in; lengths in inches and feet. Live, nothing stored. 2 compute endpoints. A planning aid — measure twice, cut once.

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

## Pricing
- **Free** (Free) — 5,750 calls/Mo, 2 req/s
- **Starter** ($5/Mo) — 54,500 calls/Mo, 6 req/s
- **Pro** ($13/Mo) — 234,000 calls/Mo, 15 req/s
- **Mega** ($39/Mo) — 1,280,000 calls/Mo, 40 req/s

## Endpoints

### Framing

#### `GET /v1/mat` — Mat window & outer size

**Parameters:**
- `artwork_width` (query, required, string) — Artwork width (in) Example: `8`
- `artwork_height` (query, required, string) — Artwork height (in) Example: `10`
- `border` (query, optional, string) — Border all sides (in) Example: `2`
- `border_top` (query, optional, string) — Top border (in)
- `border_bottom` (query, optional, string) — Bottom border (weighted)
- `border_sides` (query, optional, string) — Side borders (in)
- `overlap` (query, optional, string) — Mat overlap per edge (in, default 0.25)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/framing-api/v1/mat?artwork_width=8&artwork_height=10&border=2"
```

**Response:**
```json
{
    "data": {
        "note": "The mat window is the artwork minus the overlap on each edge (so the mat holds it). Outer size = window + the borders. A heavier bottom border (weighted/bottom-weighted mat) looks balanced to the eye.",
        "inputs": {
            "overlap": 0.25,
            "border_top": 2,
            "border_sides": 2,
            "artwork_width": 8,
            "border_bottom": 2,
            "artwork_height": 10
        },
        "outer_width": 11.5,
        "outer_height": 13.5,
        "window_width": 7.5,
        "window_height": 9.5
    },
    "meta": {
        "timestamp": "2026-06-06T07:14:09.406Z",
        "request_id": "d6d924f4-8472-4c59-bdc7-7d72b185d6bd"
    },
    "status": "ok",
    "message": "Mat board",
    "success": true
}
```

#### `GET /v1/moulding` — Frame moulding length

**Parameters:**
- `frame_width` (query, required, string) — Frame opening width (in) Example: `11.5`
- `frame_height` (query, required, string) — Frame opening height (in) Example: `13.5`
- `moulding_width` (query, required, string) — Moulding face width (in) Example: `1.5`
- `clearance` (query, optional, string) — Rabbet clearance (in, default 0.125)
- `waste_percent` (query, optional, string) — Waste % (default 0)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/framing-api/v1/moulding?frame_width=11.5&frame_height=13.5&moulding_width=1.5"
```

**Response:**
```json
{
    "data": {
        "note": "Moulding length = inner perimeter + 8 × moulding width (the 45° mitres add one moulding width per corner-cut). Buy a little extra — cuts and short ends add up.",
        "inputs": {
            "clearance": 0.125,
            "frame_width": 11.5,
            "frame_height": 13.5,
            "moulding_width": 1.5
        },
        "rabbet_width": 11.625,
        "rabbet_height": 13.625,
        "inner_perimeter": 50.5,
        "mitre_allowance": 12,
        "moulding_length_feet": 5.208,
        "moulding_length_inches": 62.5
    },
    "meta": {
        "timestamp": "2026-06-06T07:14:09.493Z",
        "request_id": "c91deb57-1512-4a39-aa36-7436aef484dc"
    },
    "status": "ok",
    "message": "Frame moulding",
    "success": true
}
```

### Meta

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

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

**Response:**
```json
{
    "data": {
        "notes": "Imperial inches. Mat overlaps the art ~0.25\" each edge; borders default 2\" (use a heavier bottom for a weighted mat). Moulding adds 8× the moulding width for the corners. A planning aid.",
        "service": "framing-api",
        "endpoints": {
            "GET /v1/mat": "Mat window (over the art) and outer mat size from the artwork and border widths.",
            "GET /v1/meta": "This document.",
            "GET /v1/moulding": "Frame moulding length needed, including the 45° mitre allowance."
        },
        "description": "Picture-framing maths: mat board window & outer size, and frame moulding length with mitre allowance."
    },
    "meta": {
        "timestamp": "2026-06-06T07:14:09.573Z",
        "request_id": "e826dd06-7c8c-4d6b-8872-53fab3a9e5ed"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


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