# Highway Vertical Curve API
> Vertical (parabolic) road-curve geometry as an API, computed locally and deterministically — the K-value, profile-elevation and design-length numbers a highway engineer or surveyor lays a crest or sag curve out with. The geometry endpoint takes the incoming and outgoing grades and the length and returns the algebraic grade difference A = g2 − g1 (negative is a crest, positive a sag), the K value = length ÷ |A| (the headline number on every design chart), the high or low point offset −g1·L/A from the PVC, and — given the PVI station and elevation — the PVC and PVT coordinates and the turning-point station and elevation. The elevation endpoint evaluates the parabola at any station: elevation = PVC elevation + (g1/100)·x + (A/(200·L))·x², with the instantaneous grade g1 + (A/L)·x that sweeps smoothly from g1 to g2 — the smooth change of grade that makes the ride and sight line comfortable. The min-length endpoint gives the AASHTO minimum length for stopping sight distance: crest L = A·S² ÷ 2158 and sag (headlight) L = A·S² ÷ (400 + 3.5·S), with the controlling K, because a crest hides the road over the hump and a sag limits the headlight reach at night. Everything is computed locally and deterministically, so it is instant and private. Ideal for highway- and rail-design tools, surveying and civil-engineering utilities, and CAD/GIS profile work. Pure local computation — no key, no third-party service, instant. US units (ft, %, mph). 3 compute endpoints. For horizontal curves use a horizontal-curve API; for slope conversion a slope 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/verticalcurve-api/..."
```

## Pricing
- **Free** (Free) — 5,000 calls/Mo, 2 req/s
- **Starter** ($12/Mo) — 52,000 calls/Mo, 6 req/s
- **Pro** ($38/Mo) — 220,000 calls/Mo, 15 req/s
- **Mega** ($118/Mo) — 1,130,000 calls/Mo, 40 req/s

## Endpoints

### Curve

#### `GET /v1/elevation` — Elevation and grade at a station

**Parameters:**
- `pvc_elevation_ft` (query, required, string) — PVC elevation (ft) Example: `94`
- `grade_in_pct` (query, required, string) — Incoming grade g1 (%) Example: `3`
- `grade_out_pct` (query, required, string) — Outgoing grade g2 (%) Example: `-2`
- `length_ft` (query, required, string) — Curve length (ft) Example: `400`
- `distance_from_pvc_ft` (query, required, string) — Distance from PVC (ft) Example: `240`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/verticalcurve-api/v1/elevation?pvc_elevation_ft=94&grade_in_pct=3&grade_out_pct=-2&length_ft=400&distance_from_pvc_ft=240"
```

**Response:**
```json
{
    "data": {
        "note": "Elevation on the curve = PVC elevation + (g1/100)·x + (A/(200·L))·x², the parabola, with x measured along the road from the PVC. The instantaneous grade is g1 + (A/L)·x, which sweeps smoothly from g1 to g2 — that steady change of grade is what makes the ride and the sight line comfortable. Set up the road profile by evaluating this at each station.",
        "inputs": {
            "length_ft": 400,
            "grade_in_pct": 3,
            "grade_out_pct": -2,
            "pvc_elevation_ft": 94,
            "distance_from_pvc_ft": 240
        },
        "elevation_ft": 97.6,
        "grade_at_point_pct": 0
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:02.851Z",
        "request_id": "1ad0d206-9a3e-4916-be3a-466e6b34be18"
    },
    "status": "ok",
    "message": "Elevation",
    "success": true
}
```

#### `GET /v1/geometry` — K value, type and turning point

**Parameters:**
- `grade_in_pct` (query, required, string) — Incoming grade g1 (%) Example: `3`
- `grade_out_pct` (query, required, string) — Outgoing grade g2 (%) Example: `-2`
- `length_ft` (query, required, string) — Curve length (ft) Example: `400`
- `pvi_station_ft` (query, optional, string) — PVI station (ft) for coordinates Example: `5000`
- `pvi_elevation_ft` (query, optional, string) — PVI elevation (ft) for coordinates Example: `100`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/verticalcurve-api/v1/geometry?grade_in_pct=3&grade_out_pct=-2&length_ft=400&pvi_station_ft=5000&pvi_elevation_ft=100"
```

**Response:**
```json
{
    "data": {
        "note": "A vertical curve is a parabola joining two grades: the algebraic difference A = g2 − g1 (negative = crest, positive = sag), and the K value = length ÷ |A| is the length per percent — the headline number on every design chart. The high or low point, where the grade passes through zero, sits at −g1·L/A from the PVC; if that falls outside the curve the summit/sag is at one end. Give the PVI station and elevation to get the PVC/PVT and turning-point coordinates.",
        "inputs": {
            "length_ft": 400,
            "grade_in_pct": 3,
            "grade_out_pct": -2
        },
        "k_value": 80,
        "curve_type": "crest",
        "pvc_station_ft": 4800,
        "pvt_station_ft": 5200,
        "pvc_elevation_ft": 94,
        "pvt_elevation_ft": 96,
        "turning_point_offset_ft": 240,
        "algebraic_grade_diff_pct": -5,
        "turning_point_station_ft": 5040,
        "turning_point_elevation_ft": 97.6
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:02.947Z",
        "request_id": "0a1c1c52-0729-491e-adbc-3b7d2b46a712"
    },
    "status": "ok",
    "message": "Curve geometry",
    "success": true
}
```

#### `GET /v1/min-length` — Minimum length for sight distance

**Parameters:**
- `grade_diff_pct` (query, required, string) — Algebraic grade difference A (%) Example: `5`
- `sight_distance_ft` (query, required, string) — Stopping sight distance (ft) Example: `570`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/verticalcurve-api/v1/min-length?grade_diff_pct=5&sight_distance_ft=570"
```

**Response:**
```json
{
    "data": {
        "note": "Minimum curve length for stopping sight distance (AASHTO, S < L): crest L = A·S² ÷ 2158, sag (headlight) L = A·S² ÷ (400 + 3.5·S). A crest hides the road over the hump, a sag limits the headlight reach at night, so each needs enough length for the driver to see and stop. Dividing by A gives the controlling K value to round up to a design standard.",
        "sag_k": 135.66,
        "inputs": {
            "grade_diff_pct": 5,
            "sight_distance_ft": 570
        },
        "crest_k": 150.56,
        "sag_min_length_ft": 678.3,
        "crest_min_length_ft": 752.8
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:03.046Z",
        "request_id": "1743f438-2160-4694-9de1-8ddf48b87194"
    },
    "status": "ok",
    "message": "Min length",
    "success": true
}
```

### Meta

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

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

**Response:**
```json
{
    "data": {
        "notes": "US units (ft, %, mph). A = g2−g1; K = L/|A|; elevation = PVC + (g1/100)x + (A/200L)x²; turning point at −g1·L/A from PVC; crest Lmin = A·S²/2158, sag = A·S²/(400+3.5S). For horizontal curves use a horizontal-curve API; for slope conversion a slope API.",
        "service": "verticalcurve-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/geometry": "A, K, crest/sag, high/low point and PVC/PVT from the grades and length.",
            "GET /v1/elevation": "Elevation and grade at a distance from the PVC.",
            "GET /v1/min-length": "Minimum crest/sag length for a stopping sight distance."
        },
        "description": "Vertical (parabolic) road-curve geometry: K value & turning point, elevation at a station, and AASHTO minimum length for sight distance."
    },
    "meta": {
        "timestamp": "2026-06-07T08:18:03.128Z",
        "request_id": "7b267a00-1428-4e8e-88f3-033c4a19df86"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


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