# Fence Calculator API
> Fencing material estimating as an API, computed locally and deterministically. The posts endpoint works out the number of fence sections, line posts and rails for a run from its length and the post spacing, plus the total rail length. The pickets endpoint computes how many pickets or boards a length needs from the picket width and the gap between boards (set the gap to zero for a privacy fence). The materials endpoint produces a full bill of materials in one call — posts, rails, pickets and the concrete for the post holes, in cubic feet and metres and in 80 lb pre-mix bags — from the fence dimensions and the hole size and post depth. Everything is computed locally and deterministically, so it is instant and private. These are estimates: allow extra for waste, gates and corner posts, and follow your local building code for post depth and footing size. Picket width and gap are in inches; length can be feet, yards or metres. Ideal for fencing contractors and estimators, DIY and home-improvement tools, and landscaping and quoting software. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 3 endpoints. This is fencing materials; for paint, tile and concrete use a construction-calculator API and for mulch and gravel use a landscaping 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/fence-api/..."
```

## Pricing
- **Free** (Free) — 11,335 calls/Mo, 2 req/s
- **Starter** ($13/Mo) — 20,950 calls/Mo, 8 req/s
- **Pro** ($33/Mo) — 259,500 calls/Mo, 20 req/s
- **Mega** ($71/Mo) — 1,340,000 calls/Mo, 50 req/s

## Endpoints

### Fence

#### `GET /v1/materials` — Full material bill + concrete

**Parameters:**
- `length` (query, required, string) — Fence length Example: `100`
- `post_spacing` (query, optional, string) — ft (default 8) Example: `8`
- `rails_per_section` (query, optional, string) — default 2 Example: `2`
- `picket_width` (query, optional, string) — in (default 5.5) Example: `5.5`
- `gap` (query, optional, string) — in (default 0.5) Example: `0.5`
- `hole_diameter_in` (query, optional, string) — default 8 Example: `8`
- `post_depth_in` (query, optional, string) — default 24 Example: `24`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/fence-api/v1/materials?length=100&post_spacing=8&rails_per_section=2&picket_width=5.5&gap=0.5&hole_diameter_in=8&post_depth_in=24"
```

**Response:**
```json
{
    "data": {
        "note": "Full bill of materials. Concrete assumes a cylindrical hole minus the post; 80 lb pre-mix bag ≈ 0.6 ft³. Add waste, gates and corner posts.",
        "input": {
            "gap_in": 0.5,
            "length_ft": 100,
            "picket_width_in": 5.5,
            "post_spacing_ft": 8,
            "rails_per_section": 2
        },
        "posts": 14,
        "rails": 26,
        "pickets": 200,
        "concrete": {
            "bags": 13,
            "total_m3": 0.2093,
            "total_ft3": 7.392,
            "per_post_ft3": 0.528
        },
        "sections": 13,
        "rail_total_length_ft": 208
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:17.765Z",
        "request_id": "fdbcb722-2521-40c1-89f1-3859a882835b"
    },
    "status": "ok",
    "message": "Full material bill",
    "success": true
}
```

#### `GET /v1/pickets` — Pickets / boards needed

**Parameters:**
- `length` (query, required, string) — Fence length Example: `100`
- `length_unit` (query, optional, string) — ft|yd|m Example: `ft`
- `picket_width` (query, optional, string) — Picket width (in, default 5.5) Example: `5.5`
- `gap` (query, optional, string) — Gap between boards (in, default 0.5) Example: `0.5`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/fence-api/v1/pickets?length=100&length_unit=ft&picket_width=5.5&gap=0.5"
```

**Response:**
```json
{
    "data": {
        "note": "Pickets = ceil(length ÷ (picket width + gap)). For privacy fences set the gap to 0.",
        "input": {
            "gap_in": 0.5,
            "length_ft": 100,
            "picket_width_in": 5.5
        },
        "pickets": 200,
        "pitch_in": 6,
        "coverage_ft": 100
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:17.864Z",
        "request_id": "d2ddf443-fb20-49a6-8fb4-c40919e9f199"
    },
    "status": "ok",
    "message": "Pickets / boards",
    "success": true
}
```

#### `GET /v1/posts` — Posts, sections & rails

**Parameters:**
- `length` (query, required, string) — Fence length Example: `100`
- `length_unit` (query, optional, string) — ft|yd|m (default ft) Example: `ft`
- `post_spacing` (query, optional, string) — Post spacing ft (default 8) Example: `8`
- `rails_per_section` (query, optional, string) — default 2 Example: `2`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/fence-api/v1/posts?length=100&length_unit=ft&post_spacing=8&rails_per_section=2"
```

**Response:**
```json
{
    "data": {
        "note": "Line posts = sections + 1 (a post at each section boundary plus the ends). Add posts for gates and corners.",
        "input": {
            "length_ft": 100,
            "post_spacing_ft": 8,
            "rails_per_section": 2
        },
        "posts": 14,
        "rails": 26,
        "sections": 13,
        "rail_total_length_ft": 208
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:17.940Z",
        "request_id": "8543d3e6-7c20-4c98-9377-e6b667f32681"
    },
    "status": "ok",
    "message": "Posts & sections",
    "success": true
}
```

### Meta

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

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

**Response:**
```json
{
    "data": {
        "note": "Estimates only — allow extra for waste, gates and corners; follow local code for post depth.",
        "service": "fence",
        "endpoints": {
            "/v1/posts": "Posts, sections and rails for a fence run from length and post spacing.",
            "/v1/pickets": "Number of pickets/boards for a length from picket width and gap.",
            "/v1/materials": "Full bill: posts, rails, pickets and concrete (ft³/m³ and bags)."
        },
        "description": "Fencing material maths: posts and sections, pickets/boards, and a full material bill with concrete for the post holes."
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:18.040Z",
        "request_id": "7d88b82c-a1af-4f7c-ac89-a5f058be56fd"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


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