openapi: 3.0.3
info:
title: FreightWaves SONAR API
description: >-
The FreightWaves SONAR API delivers freight-market intelligence — index
values (rates, volumes, tender rejections, capacity signals, etc.) by
geography (market, lane, national) and date. Access is via a bearer token
obtained from the Credential authenticate endpoint. Data calls are billable;
lookup calls (indexes, qualifiers, levels, lanes, zip3, latest) are free.
This specification is a faithful capture of the publicly documented SONAR API
reference; it is not published by FreightWaves as OpenAPI.
version: "2.0"
x-generated: '2026-07-19'
x-method: generated
x-source: https://api.sonar.surf/Help/
contact:
name: SONAR Support
url: https://knowledge.gosonar.com/
servers:
- url: https://api.freightwaves.com
description: SONAR API production
security:
- bearerAuth: []
tags:
- name: Authentication
description: Obtain and refresh API bearer tokens.
- name: Data
description: Billable index data queries by item, level, and lane.
- name: Lookup
description: Free reference lookups for valid indexes, qualifiers, levels, lanes, and zip3.
paths:
/Credential/authenticate:
post:
operationId: authenticate
tags: [Authentication]
summary: Authenticate and retrieve an API bearer token
description: >-
Exchange a SONAR username and password for a bearer token valid for one
year. Re-authenticating issues a new token without invalidating previous
tokens; SONAR recommends refreshing the token on a regular cadence.
security: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Credentials'
responses:
'200':
description: A bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthToken'
'401':
description: Invalid username or password.
/data/{index}/{qualifier}/{date}:
get:
operationId: getIndexData
tags: [Data]
summary: Get index data for a single date
description: >-
Return the value of an index for a qualifier (market/lane/level) on a
single date. Billable call.
parameters:
- { name: index, in: path, required: true, schema: { type: string }, example: OTRI, description: Index ticker (e.g. OTRI). }
- { name: qualifier, in: path, required: true, schema: { type: string }, example: ATL, description: Qualifier — market, lane, or level code (e.g. ATL, NATIONAL, XMKT). }
- { name: date, in: path, required: true, schema: { type: string, format: date }, example: '2019-02-20', description: Observation date (YYYY-MM-DD). }
responses:
'200':
description: Index data points.
content:
application/json:
schema:
type: array
items: { $ref: '#/components/schemas/DataPoint' }
'401': { description: Missing or invalid bearer token. }
'429': { description: Rate limit exceeded (100 requests/minute). }
/data/{index}/{qualifier}/{startDate}/{endDate}:
get:
operationId: getIndexDataRange
tags: [Data]
summary: Get index data for a date range
description: >-
Return index values for a qualifier across an inclusive date range.
Billable call.
parameters:
- { name: index, in: path, required: true, schema: { type: string }, example: OTRI }
- { name: qualifier, in: path, required: true, schema: { type: string }, example: ATL }
- { name: startDate, in: path, required: true, schema: { type: string, format: date }, example: '2019-02-01' }
- { name: endDate, in: path, required: true, schema: { type: string, format: date }, example: '2019-02-20' }
responses:
'200':
description: Index data points for the range.
content:
application/json:
schema:
type: array
items: { $ref: '#/components/schemas/DataPoint' }
'401': { description: Missing or invalid bearer token. }
'429': { description: Rate limit exceeded (100 requests/minute). }
/Lookup/Indexes:
get:
operationId: lookupIndexes
tags: [Lookup]
summary: List valid indexes (tickers)
description: Return the set of valid SONAR index tickers. Free call.
responses:
'200': { description: Valid indexes. }
'401': { description: Missing or invalid bearer token. }
/Lookup/Qualifiers:
get:
operationId: lookupQualifiers
tags: [Lookup]
summary: List valid qualifiers and tickers
description: Return valid qualifiers (markets/lanes) and their tickers. Free call.
responses:
'200': { description: Valid qualifiers. }
'401': { description: Missing or invalid bearer token. }
/Lookup/Levels:
get:
operationId: lookupLevels
tags: [Lookup]
summary: List valid qualifier levels
description: Return valid qualifier levels (e.g. NATIONAL, XMKT). Free call.
responses:
'200': { description: Valid levels. }
'401': { description: Missing or invalid bearer token. }
/Lookup/Lanes:
get:
operationId: lookupLanes
tags: [Lookup]
summary: List valid shipping lanes
description: Return valid shipping lanes. Free call.
responses:
'200': { description: Valid lanes. }
'401': { description: Missing or invalid bearer token. }
/Lookup/Zip3:
get:
operationId: lookupZip3
tags: [Lookup]
summary: List zip3 reference information
description: Return zip3 (3-digit ZIP) reference information. Free call.
responses:
'200': { description: Zip3 information. }
'401': { description: Missing or invalid bearer token. }
/Lookup/Latest:
get:
operationId: lookupLatestData
tags: [Lookup]
summary: Get the most recent data points
description: Return the most recent available data points. Free call.
responses:
'200': { description: Latest data points. }
'401': { description: Missing or invalid bearer token. }
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: >-
Bearer token from POST /Credential/authenticate, sent as
`Authorization: Bearer <token>`. Tokens are valid for one year.
schemas:
Credentials:
type: object
required: [username, password]
properties:
username: { type: string }
password: { type: string, format: password }
AuthToken:
type: object
properties:
token: { type: string, description: Bearer token valid for one year. }
DataPoint:
type: object
properties:
index: { type: string, example: OTRI }
qualifier: { type: string, example: ATL }
date: { type: string, format: date }
value: { type: number }