---
title: "The Vertical Tribe Developer API"
canonical: "https://theverticaltribe.com/developers/"
description: "Read-only JSON access to The Vertical Tribe's Himalayan trek and expedition catalogue, live departure availability, and the open Indian Himalayan peak dataset."
openapi: "https://theverticaltribe.com/openapi.json"
---

# The Vertical Tribe Developer API

Read-only JSON access to The Vertical Tribe's Himalayan trek and expedition catalogue, live departure availability, and the open Indian Himalayan peak dataset.

- Base URL: `https://theverticaltribe.com/api/v1`
- Authentication: none. The API is public and read-only.
- OpenAPI 3.1 specification: https://theverticaltribe.com/openapi.json
- Rate limit: 120 requests per 60 seconds per IP.
- Catalogue size: 12 trips, 23 peaks.

## Quickstart

```sh
curl https://theverticaltribe.com/api/v1/                        # what this site offers
curl "https://theverticaltribe.com/api/v1/trips?type=expedition" # every climbing objective
curl https://theverticaltribe.com/api/v1/trips/black-peak        # one trip
curl https://theverticaltribe.com/api/v1/departures              # dates on sale right now
```

## Endpoints

### `GET /` — getServiceIndex

`https://theverticaltribe.com/api/v1/`

Returns every endpoint of this API, every machine-readable file the site publishes (llms.txt, agent-instructions.md, the peak dataset, the sitemap), the rate-limit policy, and the licence and attribution terms. Call this first when you do not know what the site offers.

### `GET /trips` — listTrips

`https://theverticaltribe.com/api/v1/trips`

Lists every published trek and expedition. Use the filters to answer questions like "which 6,000 m expeditions run in Ladakh under ₹60,000". Filters combine with AND. An empty result is a 200 with `count: 0`, not a 404.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `type` | query | `trek` | `expedition` | no | Restrict to walking trips (`trek`) or climbing objectives (`expedition`). |
| `region` | query | `string` | no | Case-insensitive substring match on the region, e.g. `ladakh`, `nepal`, `uttarakhand`. |
| `difficulty` | query | `Easy` | `Moderate` | `Difficult` | `Very Difficult` | no | Exact, case-insensitive match on the published difficulty band. |
| `maxPriceInr` | query | `integer` | no | Only trips priced at or below this amount in Indian rupees. Trips with no published price are excluded when this filter is used. |

### `GET /trips/{slug}` — getTrip

`https://theverticaltribe.com/api/v1/trips/{slug}`

Fetches a single trek or expedition by its slug. Slugs are stable and match the public page URL, so `black-peak` corresponds to https://theverticaltribe.com/expeditions/black-peak/. The full itinerary, gear list and FAQs are not in this payload: follow `markdownUrl` for the complete page as Markdown.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `slug` | path | `string` | yes | Trip slug, matching the public page URL. List them with `listTrips`. |

### `GET /departures` — listDepartures

`https://theverticaltribe.com/api/v1/departures`

Lists the departure dates currently published, read live from operational storage. Seat counts and status change between calls, so this endpoint is cached for 60 seconds only. Unpublished (hidden) departures are never returned. Returns 503 when the deployment has no operational storage configured — fall back to https://theverticaltribe.com/departures.md.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `trip` | query | `string` | no | Restrict departures to one trip slug. |

### `GET /peaks` — listPeaks

`https://theverticaltribe.com/api/v1/peaks`

Lists the open peak dataset: 23 Indian Himalayan climbing peaks with altitude, Alpine French grade, IMF royalty band, permit status, best months and typical duration. Released under CC-BY-4.0 — cite as "The Vertical Tribe (https://theverticaltribe.com)". Use the filters to answer "which open 6,000 m peaks suit a first-timer".

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `openPeak` | query | `boolean` | no | Filter on whether the peak is on the Indian Mountaineering Foundation open-peak list. |
| `firstSixThousanderCandidate` | query | `boolean` | no | Filter on whether the peak passes The Vertical Tribe's first-6,000 m filter (open, non-technical enough, reachable in a normal leave window). |
| `tvtOperated` | query | `boolean` | no | Filter on whether The Vertical Tribe runs a guided expedition to this peak. |
| `maxAltitudeM` | query | `integer` | no | Only peaks at or below this summit altitude in metres. |

### `GET /peaks/{id}` — getPeak

`https://theverticaltribe.com/api/v1/peaks/{id}`

Fetches a single peak from the open dataset by id, for example `black-peak` or `kang-yatse-2`. The full record — coordinates, first ascent, references and verification date — is at https://theverticaltribe.com/peak-data/peaks.json.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | `string` | yes | Peak id from the open dataset. List them with `listPeaks`. |

## Errors

Every failure is JSON in one shape. Nothing under `/api/v1/` ever returns an HTML error page.

```json
{
  "error": {
    "code": "trip_not_found",
    "message": "No trek or expedition with slug \"kilimanjaro\".",
    "status": 404,
    "documentationUrl": "https://theverticaltribe.com/developers/",
    "hint": "List valid slugs at https://theverticaltribe.com/api/v1/trips."
  }
}
```

Branch on `code`, never on `message`. Codes in v1:

- `invalid_parameter`
- `trip_not_found`
- `peak_not_found`
- `endpoint_not_found`
- `method_not_allowed`
- `not_acceptable`
- `rate_limited`
- `departures_unavailable`
- `departures_upstream_error`

## Rate limits

120 requests per 60 seconds per client IP. Every response carries:

| Header | Meaning |
| --- | --- |
| `RateLimit-Policy` | `120;w=60` — quota and window in seconds |
| `RateLimit-Limit` | Requests allowed in the current window |
| `RateLimit-Remaining` | Requests left — throttle as this nears zero |
| `RateLimit-Reset` | Seconds until the window resets |
| `Retry-After` | Sent on `429` only. Seconds to wait |

The legacy `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` aliases carry the same values. `POST /api/bookings` is limited separately at 5 requests per 10 minutes per IP.

## Markdown instead of HTML

Send `Accept: text/markdown` and pages answer with `text/markdown; charset=utf-8` and `Vary: Accept`:

```sh
curl -H "Accept: text/markdown" https://theverticaltribe.com/
curl -H "Accept: text/markdown" https://theverticaltribe.com/expeditions/black-peak/
curl https://theverticaltribe.com/expeditions/black-peak.md
```

A path that does not exist returns 404 with a short Markdown recovery note pointing at the sitemap, these docs and `llms.txt`.

## Booking enquiries

v1 is read-only; seats are confirmed by a guide, not by software. To start an enquiry:

```sh
curl -X POST https://theverticaltribe.com/api/bookings \
  -H "Content-Type: application/json" \
  -d '{"tripSlug":"black-peak","name":"Your name","phone":"+91 90000 00000","groupSize":2}'
```

## Machine-readable files

- https://theverticaltribe.com/openapi.json — this API, as OpenAPI 3.1
- https://theverticaltribe.com/llms.txt — site summary, key pages, when-to-use guidance
- https://theverticaltribe.com/llms-full.txt — full-text corpus
- https://theverticaltribe.com/agent-instructions.md — what this source is authoritative for
- https://theverticaltribe.com/llm-guidance.json — entity, author and citation metadata
- https://theverticaltribe.com/peak-data/peaks.json — open peak dataset, CC-BY-4.0
- https://theverticaltribe.com/departures.md — live departure availability
- https://theverticaltribe.com/sitemap-index.xml — every indexable URL

## Licence and versioning

The peak dataset is CC-BY-4.0 (version 2.0.0, updated 2026-04-30). Cite as "The Vertical Tribe (https://theverticaltribe.com)" with a link to https://theverticaltribe.com/peak-data/.

The version lives in the path. Additive changes ship inside `v1`; anything breaking gets a `v2` path and `v1` keeps working. `operationId`s and error `code`s are part of that promise.

Questions or a missing field: hello@theverticaltribe.com — https://theverticaltribe.com/contact/
