> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nozlerouting.com/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /v1/routes

> Returns the route's geometry, total distance, and total duration in our flat Route shape. Use this when you don't have your own routing infrastructure. If you do, construct Route objects directly and pass them to downstream endpoints — this endpoint exists for convenience, not as a required first step.

The `/v1/routes` endpoint computes a driving route between two points. It returns route geometry, total distance, and estimated duration.

## When to Use

Use this endpoint when you don't have your own routing infrastructure. Partners with existing routing layers should skip this endpoint and pass their own `Route` object directly to `/v1/stations/enrich-distances` and `/v1/optimize`.

## Notes

* Addresses can be specified as natural language strings (e.g., "Los Angeles, CA") or as "lat,lng" coordinate pairs
* Routes are computed using driving directions optimized for typical road conditions
* The returned `polyline` field uses the standard Google Polyline Algorithm Format
* Maximum route length depends on routing provider — extremely long routes may return an error


## OpenAPI

````yaml POST /v1/routes
openapi: 3.1.0
info:
  title: Nozle B2B API
  description: >-
    Fuel-route optimization for fleet operators. Takes a route, your stations
    with prices, and a vehicle. Returns the cost-optimal stopping sequence with
    a baseline comparison.


    ## Data Model


    **Nozle is compute-only.** We don't maintain a station database or pricing
    feed — partners bring their own station data, and we do the routing math.
    Specifically:


    - **You provide:** stations with current prices, a vehicle, and trip
    endpoints (or a precomputed route).

    - **We provide:** route geometry, distance enrichment for your stations, the
    optimization algorithm, and a baseline comparison showing what naive
    refueling would cost.


    This separation matters because (a) you almost certainly have more accurate
    price data than any third-party feed could provide, and (b) it keeps the API
    stateless — no syncing, no staleness, no licensing constraints on station
    coverage.


    ## Concepts


    **Route** — A driving path between two points, expressed as total distance,
    total duration, and an encoded polyline (Google Polyline Algorithm Format).
    You can compute one with `/v1/routes` or pass in a route you already have
    from another provider.


    **Station** — A fueling location with coordinates, a price per gallon, and a
    fuel type. After enrichment, stations also carry `miles_from_route_start`
    (their position along the route) and `detour_minutes` (time cost to visit
    them). You bring stations; we annotate them.


    **Vehicle** — A fuel-efficiency profile. Either direct specs (`mpg`,
    `tank_capacity_gallons`, `current_fuel_gallons`) or a year/make/model
    lookup. Direct specs always win when complete; lookup is a convenience for
    partners who don't track tank size.


    **Optimization** — A dynamic-programming search for the stop sequence that
    minimizes `(fuel_cost + λ * detour_time)` while respecting tank capacity and
    a destination fuel reserve. The knob `time_value_dollars_per_minute`
    controls λ — higher values make the optimizer more time-sensitive (skip
    cheap-but-distant stations), lower values prioritize cost.


    ## Authentication


    All endpoints require an `X-API-Key` header. Email
    `rohan.iyer@nozlerouting.com` to request a key.


    ## Pipeline


    Most partners use the three endpoints in sequence:


    1. **`POST /v1/routes`** — compute a driving route between two addresses.

    2. **`POST /v1/stations/enrich-distances`** — annotate your stations with
    route-relative positions and detour times.

    3. **`POST /v1/optimize`** — compute the optimal fueling plan, with savings
    vs. naive baseline.


    Partners with their own routing can skip step 1 and pass a route directly
    into steps 2 and 3.


    ## Quickstart


    Minimal Python example calling all three endpoints. Requires `requests`.
    Replace `YOUR_API_KEY` with the key you received from support.


    **[Download the full example](/examples/quickstart.py)** (`curl
    /examples/quickstart.py > quickstart.py`) for a complete version with error
    handling, structured-error parsing, and curl equivalents in comments for
    partners using other languages.


    ```python

    import requests


    BASE = 'https://api.nozlerouting.com'

    HEADERS = {'X-API-Key': 'YOUR_API_KEY'}


    # 1. Compute a route

    route = requests.post(f'{BASE}/v1/routes', headers=HEADERS, json={
        'origin': 'San Francisco, CA',
        'destination': 'Los Angeles, CA',
    }).json()['route']


    # 2. Enrich your stations with route-relative positions

    stations = [{
        'id': 'STATION_001', 'name': 'Pilot Lost Hills',
        'address': '14808 Warren St, Lost Hills, CA',
        'location': {'lat': 35.6151, 'lng': -119.6588},
        'price_per_gallon': 4.39, 'fuel_type': 'diesel',
    }]

    enriched = requests.post(f'{BASE}/v1/stations/enrich-distances',
        headers=HEADERS, json={'route': route, 'stations': stations}
    ).json()['stations']


    # 3. Optimize

    result = requests.post(f'{BASE}/v1/optimize', headers=HEADERS, json={
        'route': route,
        'stations': enriched,
        'vehicle': {
            'mpg': 6.5,
            'tank_capacity_gallons': 240.0,
            'current_fuel_gallons': 30.0,
        },
    }).json()


    print(f"Recommended stops: {len(result['stops'])}")

    print(f"Net cost:
    ${result['summary']['baseline_comparison']['optimizer_net_fuel_cost']:.2f}")

    ```


    ## Latency


    Approximate response times under typical load (single-region, low concurrent
    traffic):


    - **`/v1/routes`** — ~500-900ms (one Google Maps Directions API call
    dominates).

    - **`/v1/stations/enrich-distances`** — ~300ms-1s for 1-50 stations; scales
    roughly linearly with station count due to Mapbox matrix sizing.

    - **`/v1/optimize`** — ~500ms-2s. Optimizer runtime depends on station count
    and trip distance; trips with more stations and longer distance take longer.


    These are estimates, not SLAs. Set client-side timeouts at 10-15 seconds to
    handle tail latency from upstream providers.


    ## Errors


    All errors return a canonical shape with `error_code`, `message`, optional
    `details`, and `request_id` (always set, useful in support requests). Status
    codes follow standard HTTP semantics: 400 for validation errors, 403 for
    auth, 422 for infeasibility, 429 for rate limits, 500 for unexpected
    failures.


    ## Rate Limits


    Per API key: 60/minute on `/v1/routes`, 120/minute on the other two
    endpoints. Exceeding the limit returns 429 with a `Retry-After` header.


    ## Versioning


    The `/v1/` URL prefix is stable. Within v1, additive changes (new endpoints,
    new optional request fields, new response fields) ship without notice.
    Breaking changes (renamed or removed fields, changed types, changed
    semantics) ship as a new prefix (`/v2/`) with v1 supported in parallel for a
    documented deprecation window. Error codes are stable strings — we add to
    the list but never rename existing ones.
  contact:
    name: Nozle Support
    email: rohan.iyer@nozlerouting.com
  version: 1.0.0
servers: []
security: []
tags:
  - name: v1
    description: >-
      Stable v1 endpoints for fleet partners. These are the only endpoints
      partners should integrate with.
paths:
  /v1/routes:
    post:
      tags:
        - v1
      summary: Compute a driving route between two addresses
      description: >-
        Returns the route's geometry, total distance, and total duration in our
        flat Route shape. Use this when you don't have your own routing
        infrastructure. If you do, construct Route objects directly and pass
        them to downstream endpoints — this endpoint exists for convenience, not
        as a required first step.
      operationId: post_routes_v1_routes_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RouteRequest'
        required: true
      responses:
        '200':
          description: Route computed successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RouteResponse'
              example:
                route:
                  total_distance_miles: 2015.3
                  total_duration_minutes: 1834.2
                  start:
                    lat: 34.0522
                    lng: -118.2437
                  end:
                    lat: 41.8781
                    lng: -87.6298
                  polyline: encoded_polyline_string...
                request_id: req_abc123def456
        '400':
          description: >-
            Validation error (e.g. empty origin, identical origin and
            destination, request shape invalid).
        '403':
          description: Missing or invalid API key.
        '404':
          description: No driving route exists between the given origin and destination.
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: Rate limit exceeded (60 requests/minute per key).
        '500':
          description: Internal error. Include the request_id when contacting support.
      security:
        - APIKeyHeader: []
components:
  schemas:
    RouteRequest:
      properties:
        origin:
          type: string
          maxLength: 200
          minLength: 1
          title: Origin
        destination:
          type: string
          maxLength: 200
          minLength: 1
          title: Destination
      type: object
      required:
        - origin
        - destination
      title: RouteRequest
    RouteResponse:
      properties:
        route:
          $ref: '#/components/schemas/Route'
        request_id:
          type: string
          title: Request Id
      type: object
      required:
        - route
        - request_id
      title: RouteResponse
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    Route:
      properties:
        total_distance_miles:
          type: number
          exclusiveMinimum: 0
          title: Total Distance Miles
          description: Total driving distance from start to end, in miles.
        total_duration_minutes:
          type: number
          exclusiveMinimum: 0
          title: Total Duration Minutes
          description: Total driving time from start to end, in minutes (no stops).
        start:
          $ref: '#/components/schemas/Coordinates'
          description: Starting coordinates.
        end:
          $ref: '#/components/schemas/Coordinates'
          description: Ending coordinates.
        polyline:
          anyOf:
            - type: string
            - type: 'null'
          title: Polyline
          description: >-
            Encoded polyline tracing the route. Same format as Google Maps
            `overview_polyline.points`. Either `polyline` or `waypoints` is
            required.
        waypoints:
          anyOf:
            - items:
                $ref: '#/components/schemas/Coordinates'
              type: array
            - type: 'null'
          title: Waypoints
          description: >-
            Explicit list of lat/lng points along the route. Alternative to
            `polyline` if you don't have an encoded form. Either `polyline` or
            `waypoints` is required.
      type: object
      required:
        - total_distance_miles
        - total_duration_minutes
        - start
        - end
      title: Route
      description: |-
        Internal route representation. Flat shape — upstream adapters normalize
        Google/Mapbox responses into this before it hits B2B code.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    Coordinates:
      properties:
        lat:
          type: number
          maximum: 90
          minimum: -90
          title: Lat
          description: Latitude in degrees, -90 to 90.
        lng:
          type: number
          maximum: 180
          minimum: -180
          title: Lng
          description: Longitude in degrees, -180 to 180.
      type: object
      required:
        - lat
        - lng
      title: Coordinates
      description: WGS84 lat/lng pair.
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key

````