# Seaports API
> Search a database of 17,000+ seaports worldwide from UN/LOCODE. Find ports by name and country, look one up by its UN/LOCODE, or find all ports near a coordinate (radius search). Each record includes the UN/LOCODE, coordinates, country and connected transport modes (rail, road, airport) — ideal for shipping, freight, supply-chain and logistics applications.

## 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/ports-api/..."
```

## Pricing
- **Free** (Free) — 1,500 calls/Mo, 2 req/s
- **Starter** ($9/Mo) — 50,000 calls/Mo, 8 req/s
- **Pro** ($26/Mo) — 250,000 calls/Mo, 20 req/s
- **Mega** ($69/Mo) — 1,000,000 calls/Mo, 50 req/s

## Endpoints

### Ports

#### `GET /v1/nearby` — Seaports near a coordinate (radius search)

**Parameters:**
- `lat` (query, required, string) — Latitude (-90..90) Example: `53.55`
- `lon` (query, required, string) — Longitude (-180..180) Example: `9.99`
- `radius_km` (query, optional, string) — Search radius in km (1-5000, default 200) Example: `100`
- `limit` (query, optional, string) — Max results (1-100, default 20) Example: `20`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/ports-api/v1/nearby?lat=53.55&lon=9.99&radius_km=100&limit=20"
```

**Response:**
```json
{
    "data": {
        "count": 20,
        "center": {
            "lat": 53.55,
            "lon": 9.99
        },
        "results": [
            {
                "name": "Hamburg-Mitte",
                "locode": "DEHTJ",
                "country": "DE",
                "latitude": 53.55,
                "longitude": 10.0167,
                "connections": {
                    "rail": false,
                    "road": true,
                    "airport": false
                },
                "distance_km": 1.76,
                "subdivision": "HH",
                "country_name": "Germany"
            },
            {
                "name": "Hamburg",
                "locode": "DEHAM",
                "country": "DE",
                "latitude": 53.5167,
                "longitude": 9.9333,
                "connections": {
                    "rail": true,
                    "road": true,
                    "airport": true
                },
                "distance_km": 5.27,
                "subdivision": "HH",
                "country_name": "Germany"
            },
            {
                "name": "Altenwerder",
                "locode": "DEHHV",
                "country": "DE",
                "latitude": 53.5167,
                "longitude": 9.9167,
                "connections": {
                    "rail": false,
                    "road": true,
                    "airport": false
                },
                "distance_km": 6.1,
         
…(truncated, see openapi.json for full schema)
```

#### `GET /v1/port` — A single seaport by UN/LOCODE

**Parameters:**
- `locode` (query, required, string) — 5-character UN/LOCODE Example: `NLRTM`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/ports-api/v1/port?locode=NLRTM"
```

**Response:**
```json
{
    "data": {
        "name": "Rotterdam",
        "locode": "NLRTM",
        "country": "NL",
        "latitude": 51.9167,
        "longitude": 4.5,
        "connections": {
            "rail": true,
            "road": true,
            "airport": true
        },
        "subdivision": "ZH",
        "country_name": "The Netherlands"
    },
    "meta": {
        "timestamp": "2026-05-31T00:48:52.150Z",
        "request_id": "4b138d12-338c-4060-b39d-a9a055c1902f"
    },
    "status": "ok",
    "message": "Port retrieved",
    "success": true
}
```

#### `GET /v1/search` — Search seaports by name and country

**Parameters:**
- `q` (query, optional, string) — Port name or UN/LOCODE (substring) Example: `rotterdam`
- `country` (query, optional, string) — Filter by ISO-2 country code Example: `NL`
- `limit` (query, optional, string) — Results per page (1-100, default 20) Example: `20`
- `offset` (query, optional, string) — Pagination offset Example: `0`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/ports-api/v1/search?q=rotterdam&country=NL&limit=20&offset=0"
```

**Response:**
```json
{
    "data": {
        "count": 1,
        "limit": 20,
        "total": 1,
        "offset": 0,
        "filters": {
            "q": "rotterdam",
            "country": "NL"
        },
        "results": [
            {
                "name": "Rotterdam",
                "locode": "NLRTM",
                "country": "NL",
                "latitude": 51.9167,
                "longitude": 4.5,
                "connections": {
                    "rail": true,
                    "road": true,
                    "airport": true
                },
                "subdivision": "ZH",
                "country_name": "The Netherlands"
            }
        ]
    },
    "meta": {
        "timestamp": "2026-05-31T00:48:52.223Z",
        "request_id": "3484e989-50ff-4019-9432-28831a25338e"
    },
    "status": "ok",
    "message": "Search completed",
    "success": true
}
```

### Countries

#### `GET /v1/countries` — Countries with seaport counts

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

**Response:**
```json
{
    "data": {
        "count": 232,
        "countries": [
            {
                "ports": 1765,
                "country": "US"
            },
            {
                "ports": 1562,
                "country": "JP"
            },
            {
                "ports": 1350,
                "country": "GB"
            },
            {
                "ports": 879,
                "country": "DE"
            },
            {
                "ports": 808,
                "country": "FR"
            },
            {
                "ports": 765,
                "country": "CN"
            },
            {
                "ports": 741,
                "country": "NO"
            },
            {
                "ports": 580,
                "country": "CA"
            },
            {
                "ports": 531,
                "country": "NL"
            },
            {
                "ports": 484,
                "country": "BE"
            },
            {
                "ports": 432,
                "country": "ES"
            },
            {
                "ports": 377,
                "country": "AU"
            },
            {
                "ports": 377,
                "country": "PH"
            },
            {
                "ports": 358,
                "country": "GR"
            },
            {
                "ports": 327,
                "country": "IT"
            },
            {
                "ports": 317,
                "country": 
…(truncated, see openapi.json for full schema)
```

### Meta

#### `GET /v1/meta` — Dataset totals & source

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

**Response:**
```json
{
    "data": {
        "total": 17596,
        "fields": [
            "locode",
            "name",
            "country",
            "country_name",
            "subdivision",
            "latitude",
            "longitude",
            "connections"
        ],
        "source": "UN/LOCODE (locations with seaport function)",
        "countries": 232,
        "with_coordinates": 11829
    },
    "meta": {
        "timestamp": "2026-05-31T00:48:52.368Z",
        "request_id": "3680e68c-19e2-4a39-9ea6-55463630b703"
    },
    "status": "ok",
    "message": "Meta retrieved",
    "success": true
}
```


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