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

> ## Agent Instructions
> You are reading the Lanesurf Agent API docs. Start with /for-ai-agents.md for the rules an agent must follow.
> The API is at https://agent.lanesurf.com and the MCP server at https://agent.lanesurf.com/mcp. Lanesurf doesn't send webhooks: poll.
> Limits: /rate-limits.md. Keys: /api-keys.md. Safe retries: /idempotency.md. Every route on one page: /api-reference.md.
> Always confirm with the person before accepting a carrier offer or bidding on a load. Never reveal an API key, and never show broker contact details to a carrier.
> The full contract is at /openapi.yaml.
> Sign up with POST /v1/signup (carrier or broker, a work email, an MC and/or DOT number), then POST /v1/signup/{signup_id}/verify. Follow next_step on every signup answer.

# Search loads

> Find loads near a ZIP or city, or by state, equipment and pickup date.

Active loads from Lanesurf brokers that show their loads to carriers. Give `origin_zip` (best),
`origin_city` with `origin_state`, `origin_state`, or `destination_state`; a search with none answers `400`.

**Near a ZIP or city** (`origin_zip`, or `origin_city` + `origin_state`), loads come closest first:

1. same ZIP (`match: same_zip`),
2. within 50, 100 and 150 miles (`within_50_miles`, `within_100_miles`, `within_150_miles`),
3. anywhere else in the same state (`same_state`).

Each load has `deadhead_miles`: straight-line miles from the ZIP or city to the pickup (left out when
the pickup can't be placed). An unknown `origin_zip` answers `400` unless `origin_state` is also given.

**By state** (`origin_state` alone): that state's pickups, newest first.

* `destination_city` matches the last delivery exactly (any letter case).
* `equipment_type` matches when the load's equipment contains it (e.g. `Reefer`).
* `pickup_date` (`YYYY-MM-DD`) is one day; `pickup_from` / `pickup_to` give a range and win over `pickup_date`.
* `total` is the number of loads returned.

Results never include the broker's name, contacts or max rate. `posted_rate` is shown only when the
broker priced the load (`rate_type: priced`). To go for a load, bid on it with `POST /v1/carrier/loads/{load_id}/bids`.

Only **verified** carriers can search (`403 verification_required`).


## OpenAPI

````yaml /openapi.yaml get /v1/carrier/loads/search
openapi: 3.1.0
info:
  title: Lanesurf Agent API
  version: 0.4.0
  summary: >-
    Let any AI agent get a freight load covered, or get a truck loaded, through
    Lanesurf.
  description: >
    Lanesurf finds carriers for freight loads by email, phone and text, and
    negotiates the rate.

    This API lets AI agents (Claude, ChatGPT, Grok, Cursor and others) and
    scripts use Lanesurf directly.


    There are two kinds of caller:


    - **Broker agents** ("cover this load for me"): post a load as JSON fields,
    send any fields
      Lanesurf says are missing, then read carrier offers and pick one. Paths under `/v1/loads`.
    - **Carrier / dispatcher agents** ("find a load for my truck"): post trucks
    and lanes, search
      loads, and bid on a load. Paths under `/v1/carrier`.

    Every request (except signup and `/health`) uses `Authorization: Bearer
    ls_live_...`.


    - A **broker key** belongs to one rep at a brokerage. It reaches only loads
    that brokerage posted
      through this API, whichever of the brokerage's reps posted them. It never reaches loads that came
      from the brokerage's TMS or from other brokerages.
    - A **carrier key** belongs to one carrier signup. Its trucks, lanes and
    bids are its own; no other
      key sees them. Load search covers active loads from Lanesurf brokers that show their loads to carriers' agents,
      without broker identity or contacts. Only **verified** carrier keys can read loads (search, one load, matches) and bid;
      keys whose carrier account is under review (`needs_review`) get `403 verification_required` there.

    Anyone can get a key with `POST /v1/signup` (carrier or broker, a work
    email, an MC and/or DOT number)

    and `POST /v1/signup/{signup_id}/verify`. Every signup reply has
    `next_step`, which tells an agent what

    to do next. A brokerage that signs up starts with carrier outreach off until
    Lanesurf reviews it.


    Broker keys can't call `/v1/carrier/*` and carrier keys can't call
    `/v1/loads/*` (`403 wrong_role`).


    Every response has an `X-Request-Id` header, and every error body a
    `request_id`. Send your own

    `X-Request-Id` (8-64 letters, digits, `.`, `_` or `-`) to have it used
    instead. Quote it to

    Lanesurf support when something fails.


    Every authenticated `/v1` route is limited to 120 requests per minute per
    API key, counted on each Lanesurf

    server (treat it as the most to send). Over the limit you

    get `429 rate_limited` with a `Retry-After` header.


    **Lists.** Your loads (`GET /v1/loads`) come a page at a time: `limit` (1 to
    100, default 25), then send

    `next_cursor` back as `cursor` until it is `null`. Load search (`GET
    /v1/carrier/loads/search`) and truck matches

    (`GET /v1/carrier/trucks/{truck_id}/matches`) take `limit` (1 to 100,
    default 25) and return the closest

    loads first (see each route), with `total` = the number returned. There is
    no `offset` or cursor: to see other loads,

    narrow or change the search. The other lists have no paging and return the
    newest items up to a cap: trucks

    200, lanes 500, bids 200, and a carrier's outreach 50 loads (from the last
    30 days). A load's outreach lists

    every carrier on that load.


    Lanesurf doesn't send webhooks: poll a load (`GET /v1/loads/{id}`) or your
    bids (`GET /v1/carrier/bids`)

    every few minutes.


    Versioning, limits and changes: see https://docs.lanesurf.com/versioning,

    https://docs.lanesurf.com/rate-limits and
    https://docs.lanesurf.com/changelog.
  contact:
    name: Lanesurf support
    url: https://docs.lanesurf.com
    email: support@lanesurf.com
  license:
    name: Proprietary. Use is subject to the Lanesurf Terms of Service
    url: https://www.lanesurf.com/terms
servers:
  - url: https://agent.lanesurf.com
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Broker loads
    description: A broker's agent posts a load and gets it covered.
  - name: Authentication
    description: >-
      Sign up as a carrier or a brokerage with a work email and a one-time code,
      and see who a key belongs to.
  - name: Broker setup
    description: >-
      What Lanesurf's agents tell carriers about a brokerage, and whether
      carrier outreach is on.
  - name: Carrier trucks
    description: A carrier's agent says where its trucks are and when they're free.
  - name: Carrier lanes
    description: A carrier's agent saves the lanes the carrier runs (its terminals).
  - name: Carrier loads
    description: A carrier's agent finds loads, bids on one, and follows its bids.
  - name: System
    description: Service health.
paths:
  /v1/carrier/loads/search:
    get:
      tags:
        - Carrier loads
      summary: Search loads near a ZIP or city, or by state
      description: >
        Active loads from Lanesurf brokers that show their loads to carriers.
        Give `origin_zip` (best),

        `origin_city` with `origin_state`, `origin_state`, or
        `destination_state`; a search with none answers

        400. Near a ZIP or city, loads come closest first: same ZIP, then within
        50, 100 and 150 miles, then

        the same state, each with `deadhead_miles` and `match`. `origin_state`
        alone lists that state's

        pickups, newest first. `destination_city` matches the last delivery
        exactly (any letter case). `equipment_type` matches when the load's

        equipment contains it. `pickup_date` is one day; `pickup_from` /
        `pickup_to` give a range and win over

        `pickup_date`. `total` is the number of loads returned. Results never
        include the broker's name,

        contacts or max rate; `posted_rate` only when the broker priced the
        load. Only verified carriers can

        search (403 `verification_required`).
      operationId: searchLoads
      parameters:
        - name: origin_zip
          in: query
          description: 5-digit ZIP where the truck is. Ranks loads near it.
          schema:
            type: string
            pattern: ^[0-9]{5}$
            example: '79901'
        - name: origin_state
          in: query
          description: >-
            State or province: its 2-letter code, or its name. With
            `origin_city`: loads near the city. Alone: that state's pickups.
          schema:
            type: string
            minLength: 2
            maxLength: 30
            example: TX
        - name: origin_city
          in: query
          description: >-
            Where the truck is, with `origin_state`. Ranks loads near it; a city
            we can't place matches only that exact city.
          schema:
            type: string
            example: Dallas
        - name: destination_state
          in: query
          description: 'Delivery state or province: its 2-letter code, or its name.'
          schema:
            type: string
            minLength: 2
            maxLength: 30
            example: GA
        - name: destination_city
          in: query
          description: Last delivery city (exact, any case).
          schema:
            type: string
        - name: equipment_type
          in: query
          description: Matches loads whose equipment contains this text.
          schema:
            type: string
            example: Reefer
        - name: pickup_date
          in: query
          description: One pickup day (YYYY-MM-DD).
          schema:
            type: string
            format: date
        - name: pickup_from
          in: query
          description: Earliest pickup day (YYYY-MM-DD). Wins over `pickup_date`.
          schema:
            type: string
            format: date
        - name: pickup_to
          in: query
          description: >-
            Latest pickup day (YYYY-MM-DD). Wins over `pickup_date`. Before
            `pickup_from` answers 400.
          schema:
            type: string
            format: date
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: Matching loads.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CarrierLoadList'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/VerifiedCarrierOnly'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/Internal'
        '502':
          $ref: '#/components/responses/Upstream'
        '503':
          $ref: '#/components/responses/CarrierUnavailable'
components:
  parameters:
    Limit:
      name: limit
      in: query
      description: >-
        How many loads to return, a whole number from 1 to 100. Defaults to 25.
        Anything else answers 400.
      schema:
        type: integer
        default: 25
        minimum: 1
        maximum: 100
  schemas:
    CarrierLoadList:
      type: object
      required:
        - loads
        - total
      properties:
        loads:
          type: array
          items:
            $ref: '#/components/schemas/CarrierLoad'
        total:
          type: integer
          description: The number of loads in this answer.
    CarrierLoad:
      type: object
      description: >-
        A load as a carrier sees it. Never includes the broker's name, contacts
        or max rate.
      required:
        - load_id
        - equipment_type
        - origin
        - destination
        - rate_type
      properties:
        load_id:
          type: string
          format: uuid
        equipment_type:
          type: string
          example: Reefer
        origin:
          description: The first pickup.
          allOf:
            - $ref: '#/components/schemas/Place'
        destination:
          description: The last delivery.
          allOf:
            - $ref: '#/components/schemas/Place'
        pickup_date:
          type: string
          description: >-
            The first pickup: its date (YYYY-MM-DD) when the broker gave a date,
            or its time window start (or end) with the UTC offset.
        delivery_date:
          type: string
          description: The last delivery, in the same form as pickup_date.
        stops:
          type: array
          description: >-
            Every stop in order, when the load has more than two (`origin` and
            `destination` are the first and last).
          items:
            type: object
            required:
              - type
              - state
            properties:
              type:
                type: string
                enum:
                  - pickup
                  - delivery
                  - both
                  - stop
                description: >-
                  `both`: pick up and deliver there. `stop`: the broker didn't
                  say which.
              city:
                type: string
              state:
                type: string
              date:
                type: string
                description: As pickup_date.
        temperature:
          type: number
          description: The reefer setpoint (°F), when the broker gave one.
        open:
          type: boolean
          description: >
            `GET /v1/carrier/loads/{load_id}` only. `true` while the load is
            open for bids. `false` when it left

            the market (covered, paused or deleted): you can still read a load
            you bid on, but not bid on it.
        weight_lbs:
          type: integer
        commodity:
          type: string
        total_miles:
          type: number
        posted_rate:
          type: number
          description: Only when the broker priced the load.
        rate_type:
          type: string
          enum:
            - priced
            - ask_first
          description: >-
            `priced`: `posted_rate` is set. `ask_first`: no rate shown; bid
            without a rate to ask for one.
        deadhead_miles:
          type: integer
          description: >-
            Near-searches and truck matches only. Straight-line miles from the
            searched ZIP or city (or the truck) to the pickup.
        match:
          type: string
          enum:
            - same_zip
            - within_50_miles
            - within_100_miles
            - within_150_miles
            - same_state
          description: Near-searches and truck matches only. How close the pickup is.
      example:
        load_id: 9e8d7c6b-5a49-4382-9172-6f5e4d3c2b1a
        equipment_type: Reefer
        origin:
          city: Dallas
          state: TX
        destination:
          city: Atlanta
          state: GA
        pickup_date: '2026-10-23T08:00:00-05:00'
        delivery_date: '2026-10-24T14:00:00-04:00'
        weight_lbs: 38000
        commodity: Produce
        total_miles: 781
        posted_rate: 2100
        rate_type: priced
    Error:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
          description: A message for people.
          example: invalid API key
        code:
          type: string
          description: A stable machine-readable code. Branch on this, not on `error`.
          enum:
            - missing_api_key
            - invalid_api_key
            - wrong_role
            - verification_required
            - invalid_request
            - missing_fields
            - not_found
            - already_covered
            - invalid_state
            - already_bid
            - bid_decided
            - idempotency_in_progress
            - idempotency_key_reused
            - idempotency_key_required
            - load_rejected
            - offer_changed
            - bid_update_limit
            - existing_customer
            - already_redeemed
            - rate_limited
            - invalid_code
            - signup_expired
            - broker_name_taken
            - broker_name_mismatch
            - unavailable
            - upstream_error
            - internal
          example: invalid_api_key
        missing:
          type: array
          description: '`missing_fields` only: exact field names or paths still needed.'
          items:
            type: string
        next_step:
          allOf:
            - $ref: '#/components/schemas/NextStep'
          description: >-
            On signup errors and on every broker load tool's errors
            (`list_loads`, `post_load`, `get_load`, `load_outreach`, accept,
            decline, covered).
        current_rate:
          type: number
          description: '`offer_changed` only: the offer''s rate now.'
        request_id:
          type: string
          description: >-
            This request's id (also the `X-Request-Id` response header). Quote
            it to Lanesurf support.
          example: req_0192f3a4-7b1c-7d2e-9f00-1a2b3c4d5e6f
    Place:
      type: object
      required:
        - state
      properties:
        city:
          type: string
          example: Atlanta
        state:
          type: string
          example: GA
          description: US state or Canadian province code (any case; stored upper-case).
    NextStep:
      type: string
      description: >-
        For the agent. Exactly what to do next and which MCP tool to call (REST
        path in brackets).
  responses:
    BadRequest:
      description: >-
        `invalid_request`: the request is malformed or a value is invalid. The
        message says which. Don't retry unchanged.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: >-
        `missing_api_key` (no `Authorization` header) or `invalid_api_key`
        (wrong, malformed or revoked key).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid API key
            code: invalid_api_key
    VerifiedCarrierOnly:
      description: >
        `verification_required`: only verified carriers can do this. A carrier
        account under review

        (`needs_review`) can post and manage trucks and lanes and list its own
        bids, but can't search loads,

        read a load, get truck matches, list outreach or bid. A broker key gets
        `wrong_role`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: >-
              your carrier account is under review; until Lanesurf verifies it
              you can manage trucks and lanes and list your bids, but you can't
              search loads, view loads, get matches or bid
            code: verification_required
    TooManyRequests:
      description: >
        `rate_limited`: too many requests. Signup has limits per contact, per
        carrier and per IP (the 300 per 10 minutes

        limit groups IPv6 addresses by /64). Every authenticated `/v1` route is
        limited to 120 requests per minute

        per API key, counted on each Lanesurf server. Wait `Retry-After`

        seconds, then retry.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: too many requests for this API key; slow down
            code: rate_limited
    Internal:
      description: '`internal`: unexpected error. Safe to retry later.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Upstream:
      description: >-
        `upstream_error`: a Lanesurf system behind the API failed. Safe to retry
        later.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: a Lanesurf system behind the API failed; try again later
            code: upstream_error
    CarrierUnavailable:
      description: >-
        `unavailable`: Lanesurf couldn't check the API key right now (the key
        may be fine; don't ask for a new one): wait `Retry-After` (30) seconds
        and send the same request again. Or carrier routes can't run right now;
        retry later.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    RetryAfter:
      description: Seconds to wait before trying again.
      schema:
        type: integer
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: ls_live_<key>
      description: One key per broker rep or per carrier signup. Keep it secret.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.