Developers
Wavelength REST API
Read and write your organization's process flows, pull the audit log into your security tool, and report on usage. Version 1, JSON over HTTPS.
Quick start
- An owner or admin of your organization opens Wavelength, then Settings, opens the organization, and selects the Security tab. The API keys section is at the bottom.
- They pick the scopes, then select Create key. Copy the key. Wavelength shows it only one time.
- Send the key in the
Authorizationheader of each request.
Base URL:
https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1
Check that the key works:
curl https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1/me \
-H "Authorization: Bearer $WAVELENGTH_API_KEY"
{
"organization": { "id": "4f1c...", "name": "Acme" },
"key": {
"id": "538a...", "label": "Data warehouse sync", "prefix": "wlk_edf0ce27",
"scopes": ["flows:read", "audit:read"], "expires_at": null,
"acts_as": "admin@acme.com"
}
}
Keys and scopes
An API key belongs to one organization. It reads and writes only the flows of that organization. It acts as the owner or admin who made it. The key stops working when that person is no longer an owner or admin. Then an admin makes a new key.
Wavelength keeps only a SHA-256 hash of each key. A key can expire after 30, 90, or 365 days, or never. An admin can revoke a key at any time. An organization can have up to 10 active keys.
| Scope | Allows |
|---|---|
flows:read | GET /flows and GET /flows/{id} |
flows:write | POST /flows and PATCH /flows/{id} |
audit:read | GET /audit |
usage:read | GET /usage |
GET /me works with every key. Each GET /flows/{id}, POST, and PATCH goes into the organization's audit log, with actor_via set to api_key.
Limits
- 600 requests per minute for each key. Above that, the API returns
429with aRetry-Afterheader in seconds. - Up to 200 flows for each page of GET /flows, and up to 500 events for each page of GET /audit.
- Up to 2,000 nodes and 4,000 edges in one flow.
- New flows count against the plan of the person who made the key, the same as flows they make in the app.
Flows
GET /flows flows:read
Lists the organization's flows, newest change first.
| Query parameter | Type | Description |
|---|---|---|
limit | integer | 1 to 200. Default 50. |
offset | integer | Start of the page. Use next_offset from the last page. null means there are no more pages. |
updated_since | ISO 8601 date | Only flows changed at or after this time. |
team_id | UUID | Only flows of this team. |
curl "https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1/flows?limit=50&updated_since=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer $WAVELENGTH_API_KEY"{
"flows": [
{
"id": "b946f68b-2d04-4832-abc4-26b476a3202f",
"title": "Order to cash",
"created_at": "2026-10-11T21:31:00Z",
"updated_at": "2026-10-11T21:40:12Z",
"team_id": null, "folder_id": null, "is_public": false,
"owner": "admin@acme.com"
}
],
"total": 1, "limit": 50, "offset": 0, "next_offset": null
}GET /flows/{id} flows:read
Returns one flow with its graph, transcript, and Mermaid code if it has one. A flow that is not in the organization returns 404.
{
"flow": {
"id": "b946f68b-2d04-4832-abc4-26b476a3202f",
"title": "Order to cash",
"graph_nodes": [
{ "id": "s", "type": "start", "label": "Start", "x": 0, "y": 0 },
{ "id": "a", "type": "step", "label": "Check order", "owner": "Sales ops", "x": 0, "y": 150 }
],
"graph_edges": [ { "id": "e1", "source": "s", "target": "a", "label": "" } ],
"transcript": "...", "diagram_code": null, "annotations": null, "pages": null,
"team_id": null, "folder_id": null, "is_public": false,
"created_at": "2026-10-11T21:31:00Z", "updated_at": "2026-10-11T21:40:12Z",
"owner": "admin@acme.com"
}
}POST /flows flows:write
Makes a new organization flow. Returns 201 and the saved flow.
| Field | Type | Description |
|---|---|---|
title | string | Default "Untitled flow". |
graph_nodes | list | The steps. See Node and edge format. |
graph_edges | list | The arrows between steps. |
transcript | string | Optional source text, for example call notes. |
diagram_code | string | Optional Mermaid code. |
team_id | UUID | Optional team of the organization. |
curl -X POST https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1/flows \
-H "Authorization: Bearer $WAVELENGTH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Order to cash",
"graph_nodes": [
{ "id": "s", "type": "start", "label": "Start" },
{ "id": "a", "label": "Check order", "owner": "Sales ops" },
{ "id": "d", "type": "decision", "label": "In stock?" },
{ "id": "b", "label": "Ship" },
{ "id": "c", "label": "Back order" },
{ "id": "e", "type": "end", "label": "Done" }
],
"graph_edges": [
{ "source": "s", "target": "a" },
{ "source": "a", "target": "d" },
{ "source": "d", "target": "b", "label": "Yes" },
{ "source": "d", "target": "c", "label": "No" },
{ "source": "b", "target": "e" },
{ "source": "c", "target": "e" }
]
}'PATCH /flows/{id} flows:write
Changes the fields that you send. Send graph_nodes and graph_edges together, because they replace the whole graph. Set snapshot to true to keep a version in the flow's history. version_label names that version.
curl -X PATCH https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1/flows/b946f68b-2d04-4832-abc4-26b476a3202f \
-H "Authorization: Bearer $WAVELENGTH_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "title": "Order to cash v2", "snapshot": true, "version_label": "Q4 review" }'Node and edge format
| Node field | Description |
|---|---|
id | Unique in the flow. Default n1, n2, and so on. |
type | start, step, decision, data, system, actor, end, or screen. Default step. |
label | The text on the shape. Up to 500 characters. |
owner | Optional. The role or team that does the step. Wavelength uses it for swimlanes. |
x, y | Optional position. When a node has no position, Wavelength places it: one row for each level of the flow, from the first step down. |
| Edge field | Description |
|---|---|
source | The id of the node where the arrow starts. |
target | The id of the node where the arrow ends. |
label | Optional text on the arrow, for example "Yes". |
id | Optional. Default e1, e2, and so on. |
An edge that points to a node id that is not in graph_nodes returns 400 bad_graph.
Audit log
GET /audit audit:read
Returns audit events, newest first. Events include membership and role changes, settings, sharing, exports, public links, flow views, API key use, SCIM changes, and billing changes.
| Query parameter | Type | Description |
|---|---|---|
limit | integer | 1 to 500. Default 100. |
before_id | integer | Next page: pass next_before_id from the last page. |
action | string | Only this event type, for example flow_shared. |
actor | string | Only events whose actor email contains this text. |
from, to | ISO 8601 date | Time range. |
curl "https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1/audit?limit=100&action=flow_shared&from=2026-10-01" \
-H "Authorization: Bearer $WAVELENGTH_API_KEY"{
"events": [
{
"id": 55, "created_at": "2026-10-11T21:31:54Z",
"actor": "admin@acme.com", "actor_via": "session",
"action": "flow_shared", "target_type": "flow", "target_id": "b946f68b-...",
"detail": { "with": "pat@acme.com", "role": "editor", "title": "Order to cash" }
}
],
"next_before_id": null
}
To push events to your security tool as they happen, set up the audit stream in Settings, Organization, Security. Each POST is signed with HMAC-SHA256.
Usage
GET /usage usage:read
Returns seats, totals, and one row for each member: AI calls, mic minutes, flows made, exports, last active time, and two-step verification status. days is 7, 30, or 90. Default 30.
curl "https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1/usage?days=30" \
-H "Authorization: Bearer $WAVELENGTH_API_KEY"Errors
Every error has the same shape:
{ "error": { "code": "missing_scope", "message": "This key needs the flows:write scope." } }
| HTTP | code | Meaning |
|---|---|---|
| 400 | bad_request, bad_graph, bad_team | The request body or a parameter is not valid. |
| 401 | unauthorized, key_expired | No key, a wrong key, a revoked key, or an expired key. |
| 402 | save_failed | The plan limit of the key owner stops a new flow. |
| 403 | missing_scope, creator_not_admin | The key does not have the scope, or its maker is no longer an owner or admin. |
| 404 | not_found | The flow is not in this organization, or the route does not exist. |
| 429 | rate_limited | More than 600 requests in one minute. Wait for the Retry-After seconds. |
| 500 | internal | A problem on our side. Try again. If it continues, email support@wavelengthflow.com. |
Example: export every flow
This Python script reads every organization flow, one page at a time. The key needs flows:read.
import os, requests
BASE = "https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1"
H = {"Authorization": f"Bearer {os.environ['WAVELENGTH_API_KEY']}"}
offset = 0
while offset is not None:
page = requests.get(f"{BASE}/flows", headers=H, params={"limit": 200, "offset": offset}).json()
for f in page["flows"]:
flow = requests.get(f"{BASE}/flows/{f['id']}", headers=H).json()["flow"]
print(flow["title"], len(flow["graph_nodes"]), "steps")
offset = page["next_offset"]
Use Wavelength from Claude or ChatGPT
The Wavelength AI connector gives Claude and ChatGPT the same actions with your own sign-in. An owner or admin can also ask the AI to read the security settings, change sharing limits, and make or revoke API keys.
Questions about the API, or need a higher limit? Contact sales. Security details are in the Trust Center.