# Staircase Calculator API
> Staircase geometry as an API, computed locally and deterministically. The calc endpoint takes the total rise (floor-to-floor height) and works out the number of steps, the exact riser height, the tread depth, the total run, the stringer (hypotenuse) length and the stair angle, and checks the result against building-code limits and the Blondel comfort rule (2 × riser + tread ≈ 24–25 in). The check endpoint validates a given riser and tread against typical US IRC limits — maximum riser 7.75 in, minimum tread 10 in — and reports the angle and comfort. The stringer endpoint returns the stringer length and angle from a total rise and total run. Dimensions are handled internally in inches but accept inches, centimetres, millimetres and metres. Everything is computed locally and deterministically, so it is instant and private. Code limits are typical US IRC values — always confirm your local building code. Ideal for construction and carpentry tools, deck and home-improvement apps, and architecture and CAD software. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 3 endpoints. This is staircase geometry; for paint, tile and concrete quantities use a construction-calculator API and for roof pitch use a roofing 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/stair-api/..."
```

## Pricing
- **Free** (Free) — 11,835 calls/Mo, 2 req/s
- **Starter** ($13/Mo) — 21,450 calls/Mo, 8 req/s
- **Pro** ($33/Mo) — 264,500 calls/Mo, 20 req/s
- **Mega** ($71/Mo) — 1,365,000 calls/Mo, 50 req/s

## Endpoints

### Stairs

#### `GET /v1/calc` — Steps, riser, tread, stringer, angle

**Parameters:**
- `total_rise` (query, required, string) — Floor-to-floor rise Example: `108`
- `unit` (query, optional, string) — in|cm|mm|m (default in) Example: `in`
- `target_riser` (query, optional, string) — Preferred riser (default 7) Example: `7`
- `tread` (query, optional, string) — Tread depth (default 10) Example: `10`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/stair-api/v1/calc?total_rise=108&unit=in&target_riser=7&tread=10"
```

**Response:**
```json
{
    "data": {
        "note": "Steps = round(total rise ÷ target riser); actual riser = total rise ÷ steps. There is one fewer tread than risers. Blondel 2R+T should be 24–25 in.",
        "input": {
            "unit": "in",
            "tread_in": 10,
            "total_rise_in": 108,
            "target_riser_in": 7
        },
        "steps": 15,
        "issues": [],
        "risers": 15,
        "treads": 14,
        "total_run": {
            "cm": 355.6,
            "mm": 3556,
            "feet": 11.6667,
            "inches": 140
        },
        "tread_depth": {
            "cm": 25.4,
            "mm": 254,
            "feet": 0.8333,
            "inches": 10
        },
        "riser_height": {
            "cm": 18.29,
            "mm": 182.9,
            "feet": 0.6,
            "inches": 7.2
        },
        "angle_degrees": 35.75,
        "code_compliant": true,
        "stringer_length": {
            "cm": 449.11,
            "mm": 4491.1,
            "feet": 14.7347,
            "inches": 176.816
        },
        "blondel_2r_plus_t": 24.4,
        "comfortable_blondel": true
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:15.879Z",
        "request_id": "5b73c77d-69dc-455c-b857-a460606ddf91"
    },
    "status": "ok",
    "message": "Staircase calculation",
    "success": true
}
```

#### `GET /v1/check` — Code compliance of a riser/tread

**Parameters:**
- `riser` (query, required, string) — Riser height Example: `7`
- `tread` (query, required, string) — Tread depth Example: `11`
- `unit` (query, optional, string) — in|cm|mm|m Example: `in`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/stair-api/v1/check?riser=7&tread=11&unit=in"
```

**Response:**
```json
{
    "data": {
        "note": "Checks a riser/tread against typical US IRC limits and the Blondel comfort rule (2·riser + tread).",
        "input": {
            "unit": "in",
            "riser_in": 7,
            "tread_in": 11
        },
        "issues": [],
        "limits": {
            "max_riser_in": 7.75,
            "min_tread_in": 10,
            "blondel_range": [
                24,
                25
            ]
        },
        "angle_degrees": 32.47,
        "code_compliant": true,
        "blondel_2r_plus_t": 25,
        "comfortable_blondel": true
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:15.973Z",
        "request_id": "51690354-fc84-4f6a-967a-03143bd09338"
    },
    "status": "ok",
    "message": "Code compliance check",
    "success": true
}
```

#### `GET /v1/stringer` — Stringer length from rise & run

**Parameters:**
- `total_rise` (query, required, string) — Total rise Example: `108`
- `total_run` (query, required, string) — Total run Example: `140`
- `unit` (query, optional, string) — in|cm|mm|m Example: `in`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/stair-api/v1/stringer?total_rise=108&total_run=140&unit=in"
```

**Response:**
```json
{
    "data": {
        "note": "Stringer length = √(total rise² + total run²) (the hypotenuse of the staircase).",
        "input": {
            "unit": "in",
            "total_run_in": 140,
            "total_rise_in": 108
        },
        "angle_degrees": 37.65,
        "stringer_length": {
            "cm": 449.11,
            "mm": 4491.1,
            "feet": 14.7347,
            "inches": 176.816
        }
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:16.056Z",
        "request_id": "b08f1f4b-641e-40a1-a9d1-e07277021ea8"
    },
    "status": "ok",
    "message": "Stringer length",
    "success": true
}
```

### Meta

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

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

**Response:**
```json
{
    "data": {
        "note": "Internally inches (accepts in/cm/mm/m). Limits are typical US IRC values — confirm your local code.",
        "limits": {
            "max_riser_in": 7.75,
            "min_tread_in": 10,
            "blondel_range": [
                24,
                25
            ]
        },
        "service": "stair",
        "endpoints": {
            "/v1/calc": "Number of steps, riser, tread, total run, stringer length, angle and code check from a total rise.",
            "/v1/check": "Validate a riser/tread against IRC limits and the Blondel comfort rule.",
            "/v1/stringer": "Stringer (hypotenuse) length and angle from total rise and total run."
        },
        "description": "Staircase maths: steps/riser/tread from a total rise, code compliance check, and stringer length."
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:16.154Z",
        "request_id": "eae2985d-a27f-401c-a8ea-c5b7322c207c"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


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