Reference v3
The Shoal API
Four endpoints and one webhook. It is a read API with one write on it, because a focus product whose depth can be set by another system is not a focus product.
Authentication
A bearer token from the account screen. Tokens are scoped to one
team and one of two scopes,
shoal:read or
shoal:write, and there is no
third.
$ curl https://api.vivaocean.example/v3/shoal \
-H "Authorization: Bearer vo_live_9f2c..."
Endpoints
| Method and path | Scope | What it returns |
|---|---|---|
GET /v3/shoal |
read | Everyone currently down, with depth and remaining time |
GET /v3/dives/:id |
read | One dive, including what was held during it |
GET /v3/daylight |
read | The weekly summary, same figures as the email |
POST /v3/pages |
write | Sends an urgent page down the escalation path |
Reading the Shoal
GET /v3/shoal
{
"team": "cartography",
"as_of": "2026-08-10T14:24:11Z",
"down": [
{
"person": "kit@example.com",
"depth": "deep",
"surfaces_at": "2026-08-10T15:11:00Z",
"note": "compiler bug"
},
{
"person": "ines@example.com",
"depth": "shallow",
"surfaces_at": "2026-08-10T14:32:00Z",
"note": null
}
]
}
The response never contains anyone who is surfaced. There is no
"available": true record,
because absence from this list is the only status the product is
willing to assert about a person who is not currently diving.
Sending a page
The one write. It will be refused with
403 if the sender is not on
the recipient's escalation path, and that check happens on the
server rather than in any client.
POST /v3/pages
{
"to": "kit@example.com",
"reason": "prod deploy is stuck at 40%",
"urgent": true
}
201 Created
{ "id": "pg_4Kd9", "delivered_at": "2026-08-10T14:24:17Z", "latency_ms": 6120 }
The webhook
One event,
dive.changed, fired when
anyone on the team goes down, surfaces, or changes depth. Signed
with HMAC-SHA256 in the
VivaOcean-Signature header.
{
"event": "dive.changed",
"at": "2026-08-10T15:11:04Z",
"dive": {
"id": "dv_71Bc",
"person": "kit@example.com",
"from": "deep",
"to": null,
"held_released": { "messages": 9, "mentions": 2, "urgent": 1 }
}
}
"to": null means surfaced.
Retries are five attempts over fifteen minutes and then the event
is dropped, which is stated here rather than discovered later.
VivaOcean is a fictional product. This site exists to show a theme, and every number on it was made up to fill a layout.