Build on the dive platform.

Divebase is more than a dive log. Every resource (dives, sites, certifications, gear, cylinders, gas and buddies) is exposed through a documented REST API. Authenticate with a personal token and read or write a diver's records from anything you build.

$ curl https://api.divebase.cloud/v1/dives \
    -H "Authorization: Bearer $DIVEBASE_TOKEN"
const res = await fetch(
  "https://api.divebase.cloud/v1/dives",
  { headers: { Authorization: `Bearer ${token}` } }
);
const { data, pagination } = await res.json();
import requests

res = requests.get(
    "https://api.divebase.cloud/v1/dives",
    headers={"Authorization": f"Bearer {token}"},
)
dives = res.json()["data"]
req, _ := http.NewRequest("GET",
  "https://api.divebase.cloud/v1/dives", nil)
req.Header.Set("Authorization", "Bearer "+token)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
$ch = curl_init("https://api.divebase.cloud/v1/dives");
curl_setopt($ch, CURLOPT_HTTPHEADER,
  ["Authorization: Bearer $token"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$dives = json_decode(curl_exec($ch), true)["data"];
200 · responseapplication/json
{
  "data": [
    {
      "id": "0199aa10-7000-7abc-8def-000000000001",
      "started_at": "2026-05-01T10:00:00.000Z",
      "max_depth": "28.5",
      "duration": 3720,
      "mode": "closedcircuit"
    }
  ],
  "pagination": { "current_page": 1, "total_entries": 142 }
}
What you can build

An open base for the diving world to build on

If it lives in a diver's logbook, it can flow in and out over the API. A few of the things that opens up.

Sync existing dive software

Connect a desktop or mobile dive-log app to Divebase and keep dives, profiles, sites and gear in sync, with no more data stranded on one machine.

Migrate & back up logbooks

Pull a full logbook out, push one in. Move divers off legacy tools, script a nightly backup, or build a one-click importer for your own service.

Analytics & integrations

Read dives and profile samples to build dashboards, gas-planning tools, training trackers, or pipe a diver's stats into anything else they use.

The resources

Every record in the logbook, addressable

The same things you manage in the app, each a REST resource with full read and write access scoped to the token's owner.

Dives
/v1/dives

Every logged dive, plus its full profile sample series on read.

Dive sites
/v1/dive_sites

Places you dive: coordinates, difficulty, rating, water type, interests.

Certifications
/v1/certifications

Credentials with agency, number, instructor and renewal dates.

Cylinders
/v1/cylinders

The tanks you own: material, volume, working pressure, defaults.

Gas mixes
/v1/gas_mixes

Air to nitrox to trimix, with oxygen, helium and operating ppO₂.

Equipment
/v1/equipment

Your full gear inventory, with purchase details and service state.

Buddies
/v1/buddies

The people you dive with: contact details, language, certification.

Account
/v1/whoami

Confirm which diver a token belongs to before doing anything else.

Full reference
openapi.yaml

Every field, type and status code is in the spec. Open it →

Authentication

One token, sent as a bearer header

Every request authenticates with a personal API token issued from your account. Send it in the Authorization header on each call; there is no separate login step.

  1. Open Account → API tokensIn the Divebase web app, under your account settings.
  2. Create a token and copy itTokens start with dvb_ and are shown once, at creation.
  3. Send it on every requestAs Authorization: Bearer dvb_…. That's the whole handshake.
Authenticated request
$ curl https://api.divebase.cloud/v1/whoami \
    -H "Authorization: Bearer dvb_a3f9c2e8…"

{
  "data": {
    "id": "01900000-1234-7000-8000-000000000000",
    "email": "diver@example.com",
    "created_at": "2026-05-21T15:24:07.000Z"
  }
}
401 · missing or invalid token
{ "error": { "code": "unauthorized", "message": "Authentication is required." } }
Conventions

Predictable by design

The same shapes everywhere, so a client written for one resource already knows how to read the rest.

Envelopes

Success carries data; failure carries error. Never both.

Pagination

Collections take page & per_page and return a pagination node.

UUIDv7 ids

Every resource is addressed by a canonical hyphenated UUIDv7.

Typed errors

Stable code strings; 422 adds a per-field details array.

422 · validation_error
{
  "error": {
    "code": "validation_error",
    "message": "The submitted data was invalid.",
    "details": [
      { "field": "name", "code": "blank",
        "message": "Name can't be blank" }
    ]
  }
}
A full round trip

Log a dive in one POST

Send the writable fields as flat JSON, with no resource wrapper. Required: started_at, duration, max_depth.

request
$ curl -X POST https://api.divebase.cloud/v1/dives \
    -H "Authorization: Bearer dvb_…" \
    -H "Content-Type: application/json" \
    -d '{
      "started_at": "2026-05-01T10:00:00Z",
      "duration": 3720,
      "max_depth": 28.5,
      "mode": "closedcircuit",
      "rating": 4
    }'
201 CreatedLocation: /v1/dives/{id}
{
  "data": {
    "id": "0199aa10-7000-7abc-8def-000000000001",
    "started_at": "2026-05-01T10:00:00.000Z",
    "duration": 3720,
    "max_depth": "28.5",
    "mode": "closedcircuit",
    "rating": 4,
    "created_at": "2026-06-18T09:12:44.000Z"
  }
}

The whole API, in one spec file

OpenAPI 3.1 describes every endpoint, field, type and status code. Point your client generator, Postman, or editor at it and start in minutes.

openapi: 3.1.0
info:
  title: Divebase API
  version: 1.0.0
servers:
  - url: https://api.divebase.cloud/v1
security:
  - bearerAuth: []

Start building on Divebase

Issue a token from your account, point it at the spec, and integrate the diving world's records into whatever you're building.