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

  1. 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.
  2. They pick the scopes, then select Create key. Copy the key. Wavelength shows it only one time.
  3. Send the key in the Authorization header 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.

ScopeAllows
flows:readGET /flows and GET /flows/{id}
flows:writePOST /flows and PATCH /flows/{id}
audit:readGET /audit
usage:readGET /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 429 with a Retry-After header 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 parameterTypeDescription
limitinteger1 to 200. Default 50.
offsetintegerStart of the page. Use next_offset from the last page. null means there are no more pages.
updated_sinceISO 8601 dateOnly flows changed at or after this time.
team_idUUIDOnly 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.

FieldTypeDescription
titlestringDefault "Untitled flow".
graph_nodeslistThe steps. See Node and edge format.
graph_edgeslistThe arrows between steps.
transcriptstringOptional source text, for example call notes.
diagram_codestringOptional Mermaid code.
team_idUUIDOptional 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 fieldDescription
idUnique in the flow. Default n1, n2, and so on.
typestart, step, decision, data, system, actor, end, or screen. Default step.
labelThe text on the shape. Up to 500 characters.
ownerOptional. The role or team that does the step. Wavelength uses it for swimlanes.
x, yOptional position. When a node has no position, Wavelength places it: one row for each level of the flow, from the first step down.
Edge fieldDescription
sourceThe id of the node where the arrow starts.
targetThe id of the node where the arrow ends.
labelOptional text on the arrow, for example "Yes".
idOptional. 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 parameterTypeDescription
limitinteger1 to 500. Default 100.
before_idintegerNext page: pass next_before_id from the last page.
actionstringOnly this event type, for example flow_shared.
actorstringOnly events whose actor email contains this text.
from, toISO 8601 dateTime 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." } }
HTTPcodeMeaning
400bad_request, bad_graph, bad_teamThe request body or a parameter is not valid.
401unauthorized, key_expiredNo key, a wrong key, a revoked key, or an expired key.
402save_failedThe plan limit of the key owner stops a new flow.
403missing_scope, creator_not_adminThe key does not have the scope, or its maker is no longer an owner or admin.
404not_foundThe flow is not in this organization, or the route does not exist.
429rate_limitedMore than 600 requests in one minute. Wait for the Retry-After seconds.
500internalA 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.