Quick start

  1. In the DiveOps dashboard, open Settings, Show on your website, API keys.
  2. Turn the surface on and copy a key (men_… for menu, sites and schedule, cat_… for the shop).
  3. Call an endpoint with ?key=:
curl "https://app.diveops.ai/api/public/menu?key=YOUR_KEY"

Endpoints

GET/api/public/menu

The live dive menu: courses, fun dives, packages and trips, grouped by category in display order.

curl "https://app.diveops.ai/api/public/menu?key=YOUR_KEY"
{
  "version": 1,
  "centre": { "name": "Your Dive Centre", "currency": "THB", "accent": "#2CC5AC" },
  "categories": ["Beginner", "Fun Dive", "Specialty"],
  "services": [
    {
      "id": "ec2fbbd0-…", "type": "course", "category": "Beginner",
      "name": "Open Water Course", "description": "…", "price": 11000,
      "duration": "3-4 days", "duration_days": 4, "min_age": 10,
      "is_featured": true, "event_date": null
    }
  ]
}
FieldTypeNotes
iduuidStable. Use it to deep-link into the booking page.
typestringcourse · fun_dive · specialty · package · organised_trip …
categorystringDisplay category (also listed in top-level categories[]).
namestring
descriptionstring|nullCapped at 600 characters.
pricenumber|nullIn the centre currency (centre.currency).
durationstring|nullFree text, e.g. "3-4 days".
duration_daysinteger|null
min_ageinteger|null
is_featuredboolean
event_datedate|nullSet for fixed-date organised trips; expired ones are dropped.
GET/api/public/dive-sites

Active dive sites with GPS, depth and difficulty. Same men_ key.

curl "https://app.diveops.ai/api/public/dive-sites?key=YOUR_KEY"
{
  "version": 1,
  "centre": { "name": "Your Dive Centre", "currency": "THB" },
  "dive_sites": [
    {
      "id": "…", "name": "North Pinnacle", "depth_range": "14-36m",
      "difficulty": "intermediate-advanced", "distance": "45 min by boat",
      "highlights": "Reef sharks and barracuda", "best_for": "Advanced divers",
      "latitude": 7.80, "longitude": 98.40, "updated_at": "2026-06-20T…Z"
    }
  ]
}
FieldTypeNotes
iduuid
namestring
depth_rangestring|null
difficultystringeasy · easy-intermediate · intermediate · intermediate-advanced · advanced
distancestring|null
highlightsstring|null
best_forstring|null
latitude / longitudenumber|nullDecimal degrees.
updated_atdate-time
GET/api/public/schedule

The daily trip plan, already weather-resolved. Only the active option for each date is returned. Optional from and to dates (YYYY-MM-DD); defaults to today to plus 30 days, capped at a 90-day window.

curl "https://app.diveops.ai/api/public/schedule?key=YOUR_KEY&from=2026-07-01&to=2026-07-07"
{
  "version": 1,
  "centre": { "name": "Your Dive Centre", "timezone": "Asia/Bangkok" },
  "from": "2026-07-01", "to": "2026-07-07",
  "days": [
    {
      "date": "2026-07-01", "option": "A",
      "slots": {
        "morning": {
          "planned":  [{ "site_id": "…", "name": "North Pinnacle", "difficulty": "advanced", "latitude": 7.80, "longitude": 98.40, "count": 2 }],
          "fallback": [{ "site_id": "…", "name": "House Reef", "difficulty": "easy", "latitude": null, "longitude": null, "count": 2 }]
        },
        "afternoon": { "planned": [], "fallback": [] },
        "evening":   { "planned": [], "fallback": [] }
      }
    }
  ]
}
FieldTypeNotes
datedate
optionstringThe resolved weather option for the date (e.g. "A"/"B"). Internal A/B variants are not exposed.
slots.{morning,afternoon,evening}objectEach has planned[] and fallback[].
…planned[]arrayThe headline plan. Show this.
…fallback[]arrayBad-weather alternative (display secondary; may be empty).
site.site_iduuid|nullMatches a dive_sites id; null for a free-text entry.
site.name / difficulty / latitude / longitudemixedResolved from the dive site when site_id is set.
site.countintegerNumber of dives at this site in the slot.
GET/api/public/catalogue

Retail shop products with a coarse stock badge. Exact quantities are never exposed. Uses the cat_ key.

curl "https://app.diveops.ai/api/public/catalogue?key=YOUR_SHOP_KEY"
{
  "version": 1,
  "centre": { "name": "Your Dive Centre", "currency": "THB", "accent": "#2CC5AC" },
  "products": [
    { "name": "Mares Avanti Quattro+ Fins", "category": "Fins", "price": 4200, "currency": "THB", "stock": "in" }
  ]
}
FieldTypeNotes
namestring
categorystring|null
pricenumber|null
currencystring
stockstringin · low · out (coarse, never exact quantities).

Building something with DiveOps?

Manage keys in the dashboard under Settings, Show on your website. Need a hand wiring it up?

Get in touch