Quick start
- In the DiveOps dashboard, open Settings, Show on your website, API keys.
- Turn the surface on and copy a key (
men_…for menu, sites and schedule,cat_…for the shop). - 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
}
]
}| Field | Type | Notes |
|---|---|---|
| id | uuid | Stable. Use it to deep-link into the booking page. |
| type | string | course · fun_dive · specialty · package · organised_trip … |
| category | string | Display category (also listed in top-level categories[]). |
| name | string | |
| description | string|null | Capped at 600 characters. |
| price | number|null | In the centre currency (centre.currency). |
| duration | string|null | Free text, e.g. "3-4 days". |
| duration_days | integer|null | |
| min_age | integer|null | |
| is_featured | boolean | |
| event_date | date|null | Set 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"
}
]
}| Field | Type | Notes |
|---|---|---|
| id | uuid | |
| name | string | |
| depth_range | string|null | |
| difficulty | string | easy · easy-intermediate · intermediate · intermediate-advanced · advanced |
| distance | string|null | |
| highlights | string|null | |
| best_for | string|null | |
| latitude / longitude | number|null | Decimal degrees. |
| updated_at | date-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": [] }
}
}
]
}| Field | Type | Notes |
|---|---|---|
| date | date | |
| option | string | The resolved weather option for the date (e.g. "A"/"B"). Internal A/B variants are not exposed. |
| slots.{morning,afternoon,evening} | object | Each has planned[] and fallback[]. |
| …planned[] | array | The headline plan. Show this. |
| …fallback[] | array | Bad-weather alternative (display secondary; may be empty). |
| site.site_id | uuid|null | Matches a dive_sites id; null for a free-text entry. |
| site.name / difficulty / latitude / longitude | mixed | Resolved from the dive site when site_id is set. |
| site.count | integer | Number 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" }
]
}| Field | Type | Notes |
|---|---|---|
| name | string | |
| category | string|null | |
| price | number|null | |
| currency | string | |
| stock | string | in · 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?