Developers

Wavelength REST API

Make process flows from text with AI, read and change them, export them, and pull the organization audit log and usage. Version 1, JSON over HTTPS. The n8n node uses this API.

Quick start

There are two kinds of key. A personal key acts as you, on every flow you can open. Make one in Wavelength: open Settings, then API keys. A personal key needs a paid plan or an organization seat. An organization key acts for one organization, on its flows only:

  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

Personal keys. A personal key acts as the person who made it. It reads and changes every flow that person can open, including flows shared with them. Its scopes are flows:read and flows:write. It stops working if the person is no longer on a paid plan or in an organization. A person can have up to 10 active personal keys.

Organization keys. An organization 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, GET /flows/search, GET /flows/{id}, GET /flows/{id}/export, GET /flows/{id}/review, POST /flows/{id}/summaries
flows:writePOST /flows, POST /flows/generate, PATCH and DELETE /flows/{id}, POST /flows/{id}/edit, /notes, /duplicate, and /publish, DELETE /flows/{id}/publish
audit:readGET /audit (organization keys only)
usage:readGET /usage (organization keys only)

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 and AI calls (generate, edit, notes, summaries) count against the plan of the person who made the key, the same as 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" }'

POST /flows/generate flows:write

Turns a transcript, call notes, or a plain description into a new flow with AI. Wavelength lays out the diagram. Returns 201 and the saved flow.

FieldTypeDescription
textstringRequired. Up to 100,000 characters.
titlestringOptional. Wavelength picks a title when it is empty.
directionstringvertical (default) or horizontal.
team_idUUIDOptional. Save the flow in this team.
curl -X POST https://lnzcwfswvljbijqszxxn.supabase.co/functions/v1/api/v1/flows/generate \
  -H "Authorization: Bearer $WAVELENGTH_API_KEY" -H "Content-Type: application/json" \
  -d '{"text": "The rep qualifies the lead in HubSpot. If the budget is over 50k, the AE books a demo."}'

GET /flows/search flows:read

Searches flow titles, steps, and transcripts. Query parameters: q (required, 2 characters or more) and limit (1 to 100, default 20). Returns matches with the matched steps and a transcript snippet.

DELETE /flows/{id} flows:write

Deletes the flow. Returns {"deleted": true, "id": "..."}.

POST /flows/{id}/edit flows:write

Changes the flow from a plain instruction with AI, for example "Add a manager approval before the refund". Saves a version. Body: instruction (string).

POST /flows/{id}/notes flows:write

Adds new notes or transcript text to the flow with AI. Wavelength reuses steps that are already on the diagram and adds the text to the transcript. Body: text (string).

POST /flows/{id}/duplicate flows:write

Copies the flow. Body: title (optional, default the old title plus "(copy)"). Returns 201.

GET /flows/{id}/export flows:read

Exports the flow. Query parameter format: mermaid, svg, drawio, or json. Returns content as text, or graph_nodes and graph_edges for JSON.

GET /flows/{id}/review flows:read

Finds gaps in the flow: steps with no connection, dead ends, decisions with one branch, branches with no label, steps with no owner, and links that AI guessed. Returns the lists and a questions list to ask on the next call. No AI cost.

POST /flows/{id}/summaries flows:read

Writes a summary. Body: type. overview returns summary and gaps. recaps returns customer_recap, handoff, and leadership. systems_in_scope returns text with each system and its inputs and outputs (no AI cost).

POST /flows/{id}/publish flows:write

Turns on the public read-only link. Body: summary (optional). Returns public_url. DELETE /flows/{id}/publish turns the link off.

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"

n8n node

The community node n8n-nodes-wavelength calls this API. In n8n, open Settings, then Community nodes, and install n8n-nodes-wavelength. Make a Wavelength API credential and paste a personal or organization 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.