REST API
REST API reference
Every operation of the /v1 API, generated from its OpenAPI document when this page was built. Paths are relative to https://wavefront.adwave.com. Load the OpenAPI document into your API client or code generator for the full request and response schemas.
- Workspaces (5)
- Members (1)
- Context (9)
- Writing rules (2)
- Strategies (8)
- Studio (12)
- Backlog (11)
- Calendar (2)
- Generations (6)
- Versions (5)
- Reviews & comments (4)
- Publishing (3)
- Schedules (5)
- Destinations (2)
- Imports (4)
- Catalog (1)
- Search data (6)
- Site metrics (2)
- Suggestions (7)
- Webhooks (11)
- Integrations (2)
- Billing (5)
- Account (1)
- Web app only (70)
Workspaces
Workspaces you can reach, with their settings, overview and activity.
GET /v1/workspaces
List workspaces you can access
An API key sees only its own workspace (role null).
Scope: any (API key or session)
Responses
| Status | Description |
|---|---|
200 | Workspaces |
401 | unauthorized |
GET /v1/workspaces/{ws}/overview
Counts, review queues, your work, recent activity and spend
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Overview |
404 | not_found |
GET /v1/workspaces/{ws}/counts
Queue sizes for navigation badges
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Counts |
404 | not_found |
GET /v1/workspaces/{ws}/activity
Workspace activity, newest first (audit events for owners only)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
cursor | query | string | |
limit | query | integer |
Responses
| Status | Description |
|---|---|
200 | Activity |
400 | invalid_request |
404 | not_found |
GET /v1/workspaces/{ws}
Workspace name, your role, context source and effective spend and concurrency caps
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Workspace |
401 | unauthorized |
404 | not_found |
Members
The people in a workspace, their roles and pending invitations.
GET /v1/workspaces/{ws}/people
Members with names and roles; owners also see pending invitations. API keys get email: null
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | People |
404 | not_found |
Context
The workspace documents every generation reads: brief, voice, rules and references.
GET /v1/workspaces/{ws}/context
Current context manifest with per-document summaries
Scope: context:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Manifest |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
PUT /v1/workspaces/{ws}/context
Push context (multipart: manifest JSON + file:<path> parts for changed files, and an optional base_version field: 409 conflict if another write landed since)
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body (multipart/form-data)
None.
Responses
| Status | Description |
|---|---|
200 | Push result |
400 | invalid_request |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
422 | Unprocessable (see the code) |
GET /v1/workspaces/{ws}/context/file
Read one context document as text or sanitized HTML
Scope: context:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
path required | query | string | |
format | query | "text" | "html" | |
version | query | integer | An earlier context version; omit for the latest |
Responses
| Status | Description |
|---|---|
200 | Document text or HTML |
400 | invalid_request |
404 | not_found |
PUT /v1/workspaces/{ws}/context/file
Create or replace one document as a new context version. workspace.yaml and calendar.json files are validated (400). 422 context_too_large; 409 context_read_only for Git-managed workspaces
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
path required | string | |
body required | string |
Responses
| Status | Description |
|---|---|
200 | Context version |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
422 | Unprocessable (see the code) |
DELETE /v1/workspaces/{ws}/context/file
Remove one document as a new context version (workspace.yaml can't be removed)
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
path required | query | string |
Responses
| Status | Description |
|---|---|
200 | Context version |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/context/versions
Recent context versions
Scope: context:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Versions |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
POST /v1/workspaces/{ws}/context/restore
Re-push a prior context snapshot as a new latest version. base_version (optional) is the version the caller last saw: 409 conflict if another write landed since
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
version required | integer | |
base_version | integer |
Responses
| Status | Description |
|---|---|
200 | Push result |
400 | invalid_request |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/context/thread
Context chat thread
Scope: context:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Thread |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
POST /v1/workspaces/{ws}/context/chat
Propose and merge context file updates (no wallet charge)
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
message required | string | |
idempotency_key required | string |
Responses
| Status | Description |
|---|---|
200 | Chat turn |
400 | invalid_request |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
Writing rules
Phrases drafts must never use, should avoid or may use, checked on every draft.
GET /v1/workspaces/{ws}/writing-rules
The workspace's copy rules as Settings → Writing rules shows them: never, avoid and allow lists, advanced regexes (owners), and the built-in catalog in numbers
Scope: context:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Writing rules |
400 | invalid_request |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
PUT /v1/workspaces/{ws}/writing-rules
Write the never, avoid and allow lists (and, for owners, advanced regexes) into the copy_checks file as a new context version; other sections are kept
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
never required | array of object | |
avoid required | array of object | |
allow required | array of string | |
advanced | array of object | |
base_version | integer |
Responses
| Status | Description |
|---|---|
200 | Push result |
400 | invalid_request |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Strategies
Content strategies and their plans: pillars, keywords, calendar and cadence.
GET /v1/workspaces/{ws}/strategies
The workspace's strategies, primary first
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
archived | query | "1" | Include archived strategies |
Responses
| Status | Description |
|---|---|
200 | Strategies |
401 | unauthorized |
404 | not_found |
POST /v1/workspaces/{ws}/strategies
Start a strategy from the primary one's brief and voice; `message` starts the strategist at once. If it can't start, the strategy still exists and studio_error says why. A name already in use is 409 slug_exists
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Idempotency-Key | header | string | Retry safely for 7 days: the same key and body replays the original result (200); a different body is 409 idempotency_conflict |
Request body
| Name | Type | Description |
|---|---|---|
name required | string | |
description | string | |
message | string |
Responses
| Status | Description |
|---|---|
200 | Idempotent replay |
201 | Strategy |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/strategies/{sid}
One strategy with plan counts and state
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Responses
| Status | Description |
|---|---|
200 | Strategy |
404 | not_found |
PATCH /v1/workspaces/{ws}/strategies/{sid}
Rename, describe, pause (autopilot skips it) or archive a strategy
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Request body
| Name | Type | Description |
|---|---|---|
name | string | |
description | string | |
status | "active" | "paused" | "archived" |
Responses
| Status | Description |
|---|---|
200 | Strategy |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/strategies/{sid}/plan
The plan draft and its plan_version
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Responses
| Status | Description |
|---|---|
200 | The plan draft |
404 | not_found |
PATCH /v1/workspaces/{ws}/strategies/{sid}/plan
Edit the plan directly, without a strategist turn. Item operations (keywords_add/remove, calendar_upsert/remove, pillars_*, sources_*) change only what they name; brief, voice and calendar.cadence merge field by field; the whole-list fields replace their list. A post with a draft is only dropped by calendar_remove (orphaned_drafts lists them). base_plan_version makes a stale edit a 409 with details.plan_version
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Request body
| Name | Type | Description |
|---|---|---|
patch required | object | |
note | string | |
base_plan_version | integer |
Responses
| Status | Description |
|---|---|
200 | What changed and the studio view |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/studio/plan
The plan draft and its plan_version
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | The plan draft |
404 | not_found |
PATCH /v1/workspaces/{ws}/studio/plan
Edit the plan directly, without a strategist turn. Item operations (keywords_add/remove, calendar_upsert/remove, pillars_*, sources_*) change only what they name; brief, voice and calendar.cadence merge field by field; the whole-list fields replace their list. A post with a draft is only dropped by calendar_remove (orphaned_drafts lists them). base_plan_version makes a stale edit a 409 with details.plan_version
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
patch required | object | |
note | string | |
base_plan_version | integer |
Responses
| Status | Description |
|---|---|
200 | What changed and the studio view |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Studio
The strategist conversation that drafts and edits a strategy's plan.
GET /v1/workspaces/{ws}/studio
The strategist conversation and plan draft
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Studio view |
404 | not_found |
POST /v1/workspaces/{ws}/studio/messages
Send the strategist a message; the turn runs in the background (poll GET). Busy: 409 conflict with details.message_id
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Idempotency-Key | header | string | Retry safely for 7 days: the same key and body replays the original result (200); a different body is 409 idempotency_conflict |
Request body
| Name | Type | Description |
|---|---|---|
message required | string |
Responses
| Status | Description |
|---|---|
200 | Idempotent replay |
202 | Studio view plus message_id (the reply to poll) |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
POST /v1/workspaces/{ws}/studio/messages/{mid}/retry
Run a failed reply again; returns the studio view and the new message_id
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
mid required | path | string |
Responses
| Status | Description |
|---|---|
202 | Studio view |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
POST /v1/workspaces/{ws}/studio/messages/{mid}/undo
Undo the latest plan change
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
mid required | path | string |
Responses
| Status | Description |
|---|---|
200 | Studio view |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/studio/reset
Start a fresh conversation; the plan stays
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Studio view |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/studio/save
Save the plan as workspace documents (a new context version)
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Context version, paths and the studio view |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/strategies/{sid}/studio
The strategist conversation and plan draft
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Responses
| Status | Description |
|---|---|
200 | Studio view |
404 | not_found |
POST /v1/workspaces/{ws}/strategies/{sid}/studio/messages
Send the strategist a message; the turn runs in the background (poll GET). Busy: 409 conflict with details.message_id
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Idempotency-Key | header | string | Retry safely for 7 days: the same key and body replays the original result (200); a different body is 409 idempotency_conflict |
Request body
| Name | Type | Description |
|---|---|---|
message required | string |
Responses
| Status | Description |
|---|---|
200 | Idempotent replay |
202 | Studio view plus message_id (the reply to poll) |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
POST /v1/workspaces/{ws}/strategies/{sid}/studio/messages/{mid}/retry
Run a failed reply again; returns the studio view and the new message_id
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
mid required | path | string |
Responses
| Status | Description |
|---|---|
202 | Studio view |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
POST /v1/workspaces/{ws}/strategies/{sid}/studio/messages/{mid}/undo
Undo the latest plan change
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
mid required | path | string |
Responses
| Status | Description |
|---|---|
200 | Studio view |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/strategies/{sid}/studio/reset
Start a fresh conversation; the plan stays
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Responses
| Status | Description |
|---|---|
200 | Studio view |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/strategies/{sid}/studio/save
Save the plan as workspace documents (a new context version)
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Responses
| Status | Description |
|---|---|
200 | Context version, paths and the studio view |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Backlog
A strategy's idea backlog, which autopilot draws on to fill the calendar.
GET /v1/workspaces/{ws}/backlog
The idea backlog: counts, the next ideas autopilot takes today, and a page of ideas (status=open|used|skipped, limit up to 500, offset)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
status | query | "open" | "used" | "skipped" | |
limit | query | integer | |
offset | query | integer |
Responses
| Status | Description |
|---|---|
200 | Backlog |
400 | invalid_request |
404 | not_found |
POST /v1/workspaces/{ws}/backlog/ideas
Append ideas to the backlog (created on first use). A bad idea, or an id already there, is left out and listed in warnings; 400 when none are valid
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
ideas required | array of object |
Responses
| Status | Description |
|---|---|
201 | Added |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/backlog/import
Load a backlog from JSON ({defaults?, ideas}). mode merge (default) updates ideas with the same id and appends new ones; replace makes the backlog exactly the import. Bad ideas are left out and listed in warnings
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
mode | "merge" | "replace" | Default merge. |
version | 1 | |
defaults | object | |
ideas required | array of object |
Responses
| Status | Description |
|---|---|
200 | Imported |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/backlog/preview
What autopilot would schedule from the backlog over the next days (default 30, up to 90) and the mix that gives, without writing anything: items with why, shares per dimension against targets, spacing conflicts, unfilled slots and the policy as applied. plan=draft tries the unsaved plan's mix; rebalance=1 previews a rebalance. Without a cadence, one post a day is assumed
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
days | query | integer | |
plan | query | "saved" | "draft" | |
rebalance | query | "0" | "1" |
Responses
| Status | Description |
|---|---|
200 | Preview |
400 | invalid_request |
404 | not_found |
POST /v1/workspaces/{ws}/backlog/rebalance
Re-plan this strategy's autopilot items in the fill window that have no draft yet with the editorial mix: they leave the calendar, their ideas reopen (released), and the slots are filled again (added, with why). Items with any draft stay; nothing is cancelled. 409 invalid_state without a cadence
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | What was released and filled |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/strategies/{sid}/backlog
The idea backlog: counts, the next ideas autopilot takes today, and a page of ideas (status=open|used|skipped, limit up to 500, offset)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
status | query | "open" | "used" | "skipped" | |
limit | query | integer | |
offset | query | integer |
Responses
| Status | Description |
|---|---|
200 | Backlog |
400 | invalid_request |
404 | not_found |
POST /v1/workspaces/{ws}/strategies/{sid}/backlog/ideas
Append ideas to the backlog (created on first use). A bad idea, or an id already there, is left out and listed in warnings; 400 when none are valid
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Request body
| Name | Type | Description |
|---|---|---|
ideas required | array of object |
Responses
| Status | Description |
|---|---|
201 | Added |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/strategies/{sid}/backlog/import
Load a backlog from JSON ({defaults?, ideas}). mode merge (default) updates ideas with the same id and appends new ones; replace makes the backlog exactly the import. Bad ideas are left out and listed in warnings
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Request body
| Name | Type | Description |
|---|---|---|
mode | "merge" | "replace" | Default merge. |
version | 1 | |
defaults | object | |
ideas required | array of object |
Responses
| Status | Description |
|---|---|
200 | Imported |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/strategies/{sid}/backlog/preview
What autopilot would schedule from the backlog over the next days (default 30, up to 90) and the mix that gives, without writing anything: items with why, shares per dimension against targets, spacing conflicts, unfilled slots and the policy as applied. plan=draft tries the unsaved plan's mix; rebalance=1 previews a rebalance. Without a cadence, one post a day is assumed
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
days | query | integer | |
plan | query | "saved" | "draft" | |
rebalance | query | "0" | "1" |
Responses
| Status | Description |
|---|---|
200 | Preview |
400 | invalid_request |
404 | not_found |
POST /v1/workspaces/{ws}/strategies/{sid}/backlog/rebalance
Re-plan this strategy's autopilot items in the fill window that have no draft yet with the editorial mix: they leave the calendar, their ideas reopen (released), and the slots are filled again (added, with why). Items with any draft stay; nothing is cancelled. 409 invalid_state without a cadence
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
sid required | path | string | Strategy id or slug |
Responses
| Status | Description |
|---|---|
200 | What was released and filled |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/backlog/fill
Fill open calendar slots from every active strategy's backlog now, as the 30-minute autopilot run does. 409 invalid_state without a cadence
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | What was filled |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Calendar
The saved content calendar, drafting its posts, and personal iCalendar feeds.
GET /v1/workspaces/{ws}/calendar
Every strategy's saved calendar with each post's draft status (?strategy= filters; an unknown strategy is a 404)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
strategy | query | string | Strategy id or slug |
Responses
| Status | Description |
|---|---|
200 | Calendar |
404 | not_found |
POST /v1/workspaces/{ws}/calendar/draft
Draft calendar posts now: item ids, or everything due through a date. Wallet, spend and concurrency limits stop the run early (`stopped`), they are not errors
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
item_ids | array of string | |
strategy | string | |
through | string | |
limit | integer | Default 5. |
Responses
| Status | Description |
|---|---|
200 | Nothing started |
202 | Started |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Generations
Asynchronous generation of articles, images, copy and strategies, and the kinds on offer.
GET /v1/kinds
Generator kinds and their input JSON Schemas
Scope: any (API key or session)
Responses
| Status | Description |
|---|---|
200 | Kinds |
401 | unauthorized |
GET /v1/workspaces/{ws}/generations
List generations (newest first)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
status | query | string | Workflow status, or several comma-separated (e.g. queued,running,needs_input). One of: queued, running, needs_input, ready_for_review, incomplete_budget, failed, cancelled, expired; an unknown one is a 400 |
review_status | query | "pending" | "changes_requested" | "approved" | "superseded" | |
kind | query | string | |
view | query | "awaiting_review" | "mine" | "assigned" | A review queue for the caller |
q | query | string | Search titles and briefs |
latest | query | "1" | One row per piece of content (its newest generation) |
strategy | query | string | Strategy id or slug (404 if unknown): generations whose input.plan.strategy is that strategy, i.e. drafted from its calendar. One-off generations belong to no strategy |
assignment | query | string | Calendar assignment id |
publishing | query | "scheduled" | "published" | "not_scheduled" | Where the content stands at its destinations: scheduled (soonest first), published (newest first) or not_scheduled |
cursor | query | string | next_cursor from the previous page (opaque) |
limit | query | integer |
Responses
| Status | Description |
|---|---|
200 | Page of generations |
400 | invalid_request |
401 | unauthorized |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
POST /v1/workspaces/{ws}/generations
Create a generation
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Idempotency-Key | header | string | Retry safely for 7 days: the same key and body replays the original result (200); a different body is 409 idempotency_conflict |
Request body
| Name | Type | Description |
|---|---|---|
kind required | string | |
input | object | Default {}. |
Responses
| Status | Description |
|---|---|
200 | Idempotent replay of the original result (replayed true) |
202 | Accepted: the generation is queued (replayed false) |
400 | invalid_request |
401 | unauthorized |
402 | insufficient_funds (the wallet or credit balance is too low) or plan_required (the workspace needs a plan or add-on for this; details.feature). Both carry details.billing_url |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
422 | Unprocessable (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
GET /v1/workspaces/{ws}/generations/{id}
Generation with events, versions and the content item's version history
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Generation |
404 | not_found |
POST /v1/workspaces/{ws}/generations/{id}/inputs
Answer a needs_input generation
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
answers required | object |
Responses
| Status | Description |
|---|---|
202 | Resuming |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/generations/{id}/cancel
Cancel a queued, running or waiting generation
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Cancelled |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Versions
The versions a generation produces: manifests, files, exports and revisions.
GET /v1/workspaces/{ws}/versions/{vid}
Version manifest, review summary and 15-minute file URLs
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
vid required | path | string | |
text | query | "1" |
Responses
| Status | Description |
|---|---|
200 | Version |
404 | not_found |
GET /v1/workspaces/{ws}/versions/{vid}/export
Export an article version as clean HTML, Markdown with front matter, portable JSON or a zip. Approved versions for any reader; a draft needs the edit permission (owner or editor session, or a key with generations:write), else 409 not_approved. Images are absolute media URLs; a draft's are 15-minute signed links (x-wavefront-images-expire-at)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
vid required | path | string | |
format | query | "html" | "md" | "json" | "zip" | Default html |
jsonld | query | "1" | html: append the JSON-LD script |
body_only | query | "1" | html, md: leave out the H1 and hero |
front_matter | query | string | md and zip: `none`, or comma-separated `field` or `field:key` (key renames it). Fields: title, h1, slug, seo_title, meta_description, canonical_url, excerpt, date, author, author_url, categories, tags, hero_image, hero_alt, version_id, subtitle, keywords, sources, content_type |
download | query | "1" | Send as an attachment |
Responses
| Status | Description |
|---|---|
200 | The export (zip: article.html, article.md, article.json, images/) |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/versions/{vid}/revisions
Request a revision (creates the next version)
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
vid required | path | string | |
Idempotency-Key | header | string | Retry safely for 7 days: the same key and body replays the original result (200); a different body is 409 idempotency_conflict |
Request body
| Name | Type | Description |
|---|---|---|
feedback required | string |
Responses
| Status | Description |
|---|---|
200 | Idempotent replay (replayed true) |
202 | Revision started |
400 | invalid_request |
402 | insufficient_funds (the wallet or credit balance is too low) or plan_required (the workspace needs a plan or add-on for this; details.feature). Both carry details.billing_url |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
POST /v1/workspaces/{ws}/versions/{vid}/apply
Apply an approved strategy version to the workspace context
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
vid required | path | string |
Responses
| Status | Description |
|---|---|
200 | Context version created |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/contents/{contentId}/versions
Every version of a piece of content, across its revisions
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
contentId required | path | string |
Responses
| Status | Description |
|---|---|
200 | Versions |
404 | not_found |
Reviews & comments
Review requests, approval decisions and the comment thread on a piece of content.
PATCH /v1/workspaces/{ws}/generations/{id}
Ask an owner or editor to review, or clear the request. The reviewer gets an email (at most one per generation per 10 minutes)
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
assignee_id required | string | null |
Responses
| Status | Description |
|---|---|
200 | Generation |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
GET /v1/workspaces/{ws}/generations/{id}/comments
The review thread for this content item, across revisions
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Comments |
404 | not_found |
POST /v1/workspaces/{ws}/generations/{id}/comments
Comment (any member; keys need generations:write)
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string | |
Idempotency-Key | header | string | Retry safely for 7 days: the same key and body replays the original result (200); a different body is 409 idempotency_conflict |
Request body
| Name | Type | Description |
|---|---|---|
body required | string | |
version_id | string |
Responses
| Status | Description |
|---|---|
200 | Idempotent replay |
201 | Comment |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
DELETE /v1/workspaces/{ws}/generations/{id}/comments/{cid}
Delete a comment (its author, or an owner)
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string | |
cid required | path | string |
Responses
| Status | Description |
|---|---|
204 | Deleted |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
Publishing
Publishing approved versions to destinations, and withdrawing them.
POST /v1/workspaces/{ws}/versions/{vid}/publish
Publish an approved version to a destination
Scope: publish
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
vid required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
destination_id required | string | |
mode | "publish" | "draft" | "schedule" | |
publish_at | string (date-time) | |
send_newsletter | boolean | |
image_version_id | string |
Responses
| Status | Description |
|---|---|
202 | Publication queued |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/publications
Publications, newest first
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
status | query | "queued" | "sending" | "building" | "verifying" | "published" | "draft_created" | "scheduled" | "failed" | … | |
state | query | "queued" | "sending" | "building" | "verifying" | "published" | "draft_created" | "scheduled" | "failed" | … | Generic state; matches legacy statuses too, so published includes staged |
destination_id | query | string | |
content_id | query | string | Every publication of one content item across its versions |
cursor | query | string | next_cursor from the previous page |
limit | query | integer |
Responses
| Status | Description |
|---|---|
200 | Page of publications |
400 | invalid_request |
404 | not_found |
GET /v1/workspaces/{ws}/publications/{id}
Publication status and receipt
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Publication |
404 | not_found |
Schedules
Publishing an approved version at a set time or on its calendar date.
GET /v1/workspaces/{ws}/schedules
Schedules by publish time: active ones, or all with state=all
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
state | query | "active" | "all" | |
content_id | query | string | |
from | query | string (date-time) | publish_at at or after |
to | query | string (date-time) | publish_at before |
limit | query | integer |
Responses
| Status | Description |
|---|---|
200 | Schedules |
400 | invalid_request |
404 | not_found |
POST /v1/workspaces/{ws}/schedules
Schedule an approved version to publish at publish_at, or on its calendar date (on_calendar_date, at time in the workspace's time zone). Native where the destination schedules posts itself; otherwise Wavefront starts it within 5 minutes of the time. 409 schedule_exists when the content already has one there
Scope: publish
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
version_id required | string | |
destination_id required | string | |
mode | "publish" | "draft" | |
publish_at | string (date-time) | |
on_calendar_date | boolean | |
time | string |
Responses
| Status | Description |
|---|---|
201 | Scheduled |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/schedules/{id}
A schedule, its publication and its events
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Schedule |
404 | not_found |
PATCH /v1/workspaces/{ws}/schedules/{id}
Move a schedule to a new time; a post the destination holds gets the new time there (an update)
Scope: publish
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
publish_at | string (date-time) | |
on_calendar_date | boolean | |
time | string | |
version_id | string |
Responses
| Status | Description |
|---|---|
200 | Rescheduled |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/schedules/{id}/cancel
Cancel a schedule before its time. A post the destination holds is deleted there (or made a draft where it can't delete); 409 manual_withdraw_required when it can do neither
Scope: publish
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Cancelled |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Destinations
Where content is published (CMSs, sites, webhooks), with their settings and encrypted secrets.
GET /v1/workspaces/{ws}/destinations/types
Destination types this deployment can set up: label, icon, capabilities, config and secret JSON Schemas, field help, OAuth and mapping steps
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Types |
404 | not_found |
GET /v1/workspaces/{ws}/destinations
List publishing destinations with each adapter's capabilities (secrets never returned)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Destinations |
404 | not_found |
Imports
Importing documents into context from Google Drive, Notion and Confluence.
GET /v1/workspaces/{ws}/imports
Document import providers (Google Drive, Notion, Confluence) with whether this server has each set up and the workspace's connection, plus every import. Never the tokens; the account name only for sessions
Scope: context:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Providers and imports |
404 | not_found |
PATCH /v1/workspaces/{ws}/imports/{id}
Turn the daily resync on or off
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
resync required | "off" | "daily" |
Responses
| Status | Description |
|---|---|
200 | Import |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
DELETE /v1/workspaces/{ws}/imports/{id}
Stop tracking an import. Its documents stay
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
204 | Removed |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/imports/{id}/sync
Read the import's sources again now. state is updated (one new context version; restore the one before to undo), unchanged or busy. Documents are removed only when the source confirms they are gone
Scope: context:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Resync result |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
422 | Unprocessable (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
502 | Error |
Catalog
The site's catalog feed of products, listings or other entities that drafts can link to.
POST /v1/workspaces/{ws}/catalog/refresh
Refetch the site catalog feed now instead of waiting for catalog.refresh_hours. Returns url, fetched_at, cached, previous_fetched_at, entities per type, added, removed, skipped and problems. A copy younger than a minute is returned as is (cached: true), so repeated calls don't refetch. 409 invalid_state without a catalog; a feed that can't be read leaves the cache unchanged (503 misconfigured)
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | The refreshed copy |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
503 | Error |
Search data
Search Console, Analytics and Bing connections and the search performance they report.
GET /v1/workspaces/{ws}/google
The Search Console and Analytics connection: status, picked properties, last sync. Never the token; the Google email only for sessions
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Connection |
404 | not_found |
POST /v1/workspaces/{ws}/google/sync
Fetch fresh data now (data synced in the last 10 minutes is returned as is). The cron syncs daily
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Sync state |
403 | forbidden, or a missing API key scope (details.missing) |
409 | conflict (see the code) |
502 | Error |
GET /v1/workspaces/{ws}/bing
The Bing Webmaster Tools connection: status, picked site, last sync. Never the API key
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Connection |
404 | not_found |
POST /v1/workspaces/{ws}/bing/sync
Fetch fresh Bing data now (at most one try per 10 minutes: fresh, or too_soon after a failed try). The cron syncs daily
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Sync state |
403 | forbidden, or a missing API key scope (details.missing) |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
502 | Error |
GET /v1/workspaces/{ws}/search-performance
The last syncs: Search Console totals, queries and pages, Analytics totals, landing pages and channels, each with the prior 28 days; Bing totals, queries and pages over the latest 4 weeks against the 4 before; and opportunities from both engines
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
limit | query | integer | Rows per list (default 50) |
Responses
| Status | Description |
|---|---|
200 | Search performance |
404 | not_found |
GET /v1/workspaces/{ws}/search-performance/page
One page's Search Console, Analytics and Bing numbers, its top Google queries, and a Search Console URL Inspection link
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
url required | query | string (uri) |
Responses
| Status | Description |
|---|---|
200 | Page performance |
400 | invalid_request |
404 | not_found |
Site metrics
Site authority and visibility metrics over time.
GET /v1/workspaces/{ws}/site-metrics
Site authority and visibility metrics with history: each provider's state (on, off with what turns it on for owners, or error), and each metric with its definition, latest, previous and baseline values, changes and points for the workspace's registrable domain. ?metrics= (comma-separated ids), ?from= and ?to= (YYYY-MM-DD) narrow the points
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
metrics | query | string | Comma-separated metric ids (tranco.rank,gsc.clicks) |
from | query | string (date) | First day of points |
to | query | string (date) | Last day of points |
Responses
| Status | Description |
|---|---|
200 | Site metrics |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
POST /v1/workspaces/{ws}/site-metrics/refresh
Queue a check of every free provider, and keyed ones that are due (never twice in their month). Answers 202 with state queued and the current site_metrics; GET …/site-metrics shows checking: true until the check is done. Once every 10 minutes (429 rate_limited with retry_after); 409 conflict while a check runs
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
202 | Queued |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
Suggestions
Strategy suggestions found in the site's search data, to approve or dismiss.
GET /v1/workspaces/{ws}/suggestions
Strategy suggestions from the site's search data, open ones best first: type, title, why (evidence with its numbers and window), impact, the typed actions approval runs, status, and the result. counts by status and last_run_at
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
status | query | string | Comma-separated: proposed, approved, dismissed, done, failed, expired |
limit | query | integer | |
offset | query | integer |
Responses
| Status | Description |
|---|---|
200 | Suggestions |
400 | invalid_request |
404 | not_found |
GET /v1/workspaces/{ws}/suggestions/settings
Suggestion messages (weekly digest, immediate message for a large decay, email) and per-type auto-apply
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Settings |
404 | not_found |
POST /v1/workspaces/{ws}/suggestions/detect
Run the detectors on the stored search data now (they also run after every Google and Bing sync). Within 10 minutes of the last run, returns 200 with state fresh and the open suggestions
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | What the run found |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
GET /v1/workspaces/{ws}/suggestions/{id}
One suggestion
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Suggestion |
404 | not_found |
PATCH /v1/workspaces/{ws}/suggestions/{id}
Edit a proposed suggestion's actions: the feedback text, the share, the ideas, which posts add links. Each action keeps its type and target; actions can be removed, not added
Scope: generations:write (or an owner or editor session); what a key approves never auto-approves
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
actions required | array of object |
Responses
| Status | Description |
|---|---|
200 | Suggestion |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/suggestions/{id}/approve
Approve (optionally with edited actions): Wavefront runs each action through the app's own functions (backlog ideas, revisions, links, plan keywords) and records the result; status becomes done or failed. An action that can't run (a revision already in progress, no budget, a limit) is recorded in result with its error code, and the response is still 200. Ideas and revisions carry the approver's provenance: a person's in the web app, a key's otherwise (never auto-approved). A failed one can be approved again. 409 when already decided
Scope: generations:write (or an owner or editor session); what a key approves never auto-approves
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
note | string | null | |
actions | array of object | |
edited_at | string | null |
Responses
| Status | Description |
|---|---|
200 | Suggestion with result |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/suggestions/{id}/dismiss
Dismiss a proposed (or failed) suggestion. The same finding isn't suggested again for 90 days
Scope: generations:write (or an owner or editor session); what a key approves never auto-approves
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
note | string | null |
Responses
| Status | Description |
|---|---|
200 | Suggestion |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
Webhooks
Event subscriptions that POST signed events to your URL when things happen in a workspace.
GET /v1/workspaces/{ws}/webhooks
Event subscriptions and the event types they can ask for. Never the signing secrets
Scope: webhooks (or an owner session)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Subscriptions |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
POST /v1/workspaces/{ws}/webhooks
Add a webhook: an https URL and the events to send. The response holds the whsec_ signing secret; it is not shown again
Scope: webhooks (or an owner session); subscribing also needs generations:read, and a key changes only subscriptions it created
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Request body
| Name | Type | Description |
|---|---|---|
url required | string | |
events required | array of "generation.ready_for_review" | "generation.review_requested" | "generation.needs_input" | "generation.failed" | "version.approved" | "version.changes_requested" | "publication.published" | "publication.failed" | … | |
description | string | null |
Responses
| Status | Description |
|---|---|
201 | Subscription and secret |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
GET /v1/workspaces/{ws}/webhooks/sample
Sample bodies for one event type, shaped like deliveries plus the webhook-id as id: the workspace's latest events of that type (source recent), or one made-up example (source example). Keys need generations:read too
Scope: webhooks (or an owner session)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
event required | query | "generation.ready_for_review" | "generation.review_requested" | "generation.needs_input" | "generation.failed" | "version.approved" | "version.changes_requested" | "publication.published" | "publication.failed" | … | |
limit | query | integer | A whole number from 1 to 10; anything else is 400 |
Responses
| Status | Description |
|---|---|
200 | Samples |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
GET /v1/workspaces/{ws}/webhooks/{id}
One subscription: status, events, failure run
Scope: webhooks (or an owner session)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Subscription |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
PATCH /v1/workspaces/{ws}/webhooks/{id}
Change the URL, events or description; enabled false pauses it, true turns it back on and clears its failures
Scope: webhooks (or an owner session); subscribing also needs generations:read, and a key changes only subscriptions it created
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Request body
| Name | Type | Description |
|---|---|---|
url | string | |
events | array of "generation.ready_for_review" | "generation.review_requested" | "generation.needs_input" | "generation.failed" | "version.approved" | "version.changes_requested" | "publication.published" | "publication.failed" | … | |
description | string | null | |
enabled | boolean |
Responses
| Status | Description |
|---|---|
200 | Subscription |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
DELETE /v1/workspaces/{ws}/webhooks/{id}
Delete a subscription and its delivery log
Scope: webhooks (or an owner session); subscribing also needs generations:read, and a key changes only subscriptions it created
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
204 | Deleted |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
POST /v1/workspaces/{ws}/webhooks/{id}/rotate-secret
Make a new signing secret (returned once). The old one also signs for 24 hours; another rotation in that time is 409
Scope: webhooks (or an owner session); subscribing also needs generations:read, and a key changes only subscriptions it created
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
200 | Subscription and secret |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
POST /v1/workspaces/{ws}/webhooks/{id}/test
Send a webhook.test event to this subscription now. Shares a per-workspace limit with redeliver (429)
Scope: webhooks (or an owner session); subscribing also needs generations:read, and a key changes only subscriptions it created
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string |
Responses
| Status | Description |
|---|---|
202 | Delivery |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
GET /v1/workspaces/{ws}/webhooks/{id}/deliveries
The delivery log, newest first, kept 30 days
Scope: webhooks (or an owner session)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string | |
limit | query | integer | |
cursor | query | string | next_cursor from the previous page |
Responses
| Status | Description |
|---|---|
200 | Deliveries |
400 | invalid_request |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
GET /v1/workspaces/{ws}/webhooks/{id}/deliveries/{did}
One delivery with the body sent and every attempt. Keys without generations:read get body null
Scope: webhooks (or an owner session)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string | |
did required | path | string |
Responses
| Status | Description |
|---|---|
200 | Delivery |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
POST /v1/workspaces/{ws}/webhooks/{id}/deliveries/{did}/redeliver
Send a finished delivery again: same webhook-id and body, a fresh retry schedule. 409 while it is still being sent or the subscription is off
Scope: webhooks (or an owner session); subscribing also needs generations:read, and a key changes only subscriptions it created
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
id required | path | string | |
did required | path | string |
Responses
| Status | Description |
|---|---|
202 | Delivery |
403 | forbidden, or a missing API key scope (details.missing) |
404 | not_found |
409 | conflict (see the code) |
429 | Rate, spend or concurrency limit (details.retry_after) |
Integrations
Slack, Microsoft Teams, Asana and Trello connections.
GET /v1/workspaces/{ws}/task-sync
Project tool sync: which tools this server offers and the workspace's Asana and Trello connections, with the picked project or board, task counts and the last sync. Never a token
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Connections |
404 | not_found |
POST /v1/workspaces/{ws}/task-sync/{provider}/sync
Queue a sync now. Saved plans, drafts, reviews and publishing queue one too, and the cron reconciles daily
Scope: generations:write
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
provider required | path | "asana" | "trello" |
Responses
| Status | Description |
|---|---|
200 | Skipped: a sync started in the last 30 seconds (too_soon) |
202 | Queued |
403 | forbidden, or a missing API key scope (details.missing) |
409 | conflict (see the code) |
Billing
The plan, the credit balance, credit estimates and public pricing.
GET /v1/pricing
Plans, packs and the trial, with posts a month from the trailing 30-day measured average credits per published post
Scope: none
Responses
| Status | Description |
|---|---|
200 | Pricing |
GET /v1/workspaces/{ws}/billing/balance
The balance alone: credits and plan, by billing mode
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Balance |
404 | not_found |
GET /v1/workspaces/{ws}/billing
The plan, credit balance and history (members)
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Billing |
401 | unauthorized |
404 | not_found |
GET /v1/workspaces/{ws}/billing/estimates
Credit estimates per kind before a run (credits workspaces): the trailing 30-day average and the most a run can hold
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
Responses
| Status | Description |
|---|---|
200 | Estimates |
401 | unauthorized |
404 | not_found |
GET /v1/workspaces/{ws}/billing/checkout/{session}
Confirm a Checkout session and return the updated balance
Scope: generations:read
Parameters
| Name | In | Type | Description |
|---|---|---|---|
ws required | path | string | Workspace slug |
session required | path | string |
Responses
| Status | Description |
|---|---|
200 | Fulfillment |
404 | not_found |
Account
You: your profile, browser sessions and invitations.
GET /v1/me
You: profile, memberships, pending invitations. For an API key: its id, scopes and workspace (id, slug, name)
Scope: any (API key or session)
Responses
| Status | Description |
|---|---|
200 | Me |
401 | unauthorized |
Web app only
These operations need a person signed in to the web app (they are marked x-session-only in the OpenAPI document). API keys and MCP tokens are refused. They are listed so you know what exists, not to call.
Show 70 web-app-only operations
| Operation | Summary |
|---|---|
POST /v1/workspaces | Create a workspace (web session) |
POST /v1/workspaces/{ws}/leave | Leave the workspace (the last active owner cannot) |
PUT /v1/workspaces/{ws}/destinations/{did}/indexnow | Turn IndexNow on or off for a destination (owner). The first time, a key is generated; the site must host /<key>.txt |
PATCH /v1/workspaces/{ws}/destinations/{did} | Edit a destination's name, config (replaced whole; refused while publishing to it), default_mode or secret (owner). Pointing a URL or host field somewhere new needs the whole secret again |
DELETE /v1/workspaces/{ws}/destinations/{did} | Remove a publishing destination (owner); refused while publishing to it |
POST /v1/workspaces/{ws}/destinations/{did}/secret | Rotate a destination's secret (owner): typed fields replace stored ones, or an OAuth grant replaces it all. Never returned |
POST /v1/workspaces/{ws}/destinations/test | Test a destination's settings before saving (owner): runs the adapter's test; 200 with ok, or the stage that failed and why |
POST /v1/workspaces/{ws}/destinations/mapping | The field-mapping step (owner): the adapter's targets and remote fields, and Wavefront's fields to map onto them |
POST /v1/workspaces/{ws}/destinations/oauth/start | Start connecting a destination with OAuth (owner, web session): returns the consent URL and a grant id |
GET /v1/workspaces/{ws}/destinations/oauth/{gid} | An OAuth connection you started: whether it connected, and the form it was started with (never the token) |
POST /v1/workspaces/{ws}/destinations/{did}/test | Send a test with the stored settings (owner). A webhook gets a signed ping event; returns ok, message and the delivery (status code, timing) |
POST /v1/workspaces/{ws}/destinations/{did}/rotate-secret | A new signing secret for a webhook destination (owner), returned once. The old one also signs for 24 hours unless immediately is true |
GET /v1/workspaces/{ws}/social/ayrshare | Social posting through Ayrshare (owner): whether this deployment offers it (and X), the workspace's profile, and the accounts linked to it |
POST /v1/workspaces/{ws}/social/ayrshare/link | A 5-minute Ayrshare page where the owner links the workspace's social accounts (owner, web session). The first call creates the workspace's Ayrshare profile |
PATCH /v1/me | Set your display name (web session) |
POST /v1/me/sessions/revoke-others | Sign out every other browser (web session) |
POST /v1/invitations/{ws}/accept | Accept an invitation sent to your address (web session) |
POST /v1/invitations/{ws}/decline | Decline an invitation sent to your address (web session) |
POST /v1/workspaces/{ws}/versions/{vid}/approve | Approve or request changes (web session only) |
POST /v1/workspaces/{ws}/publications/{id}/withdraw | Withdraw a publication: the destination deletes the item, Wavefront confirms it is gone, then marks it withdrawn (owner session) |
POST /v1/workspaces/{ws}/publications/{id}/withdrawn | Mark a publication withdrawn after deleting it at the destination by hand, for destinations that can't delete (owner session) |
PATCH /v1/workspaces/{ws} | Rename the workspace (owner); the slug never changes |
GET /v1/workspaces/{ws}/members | List members (owner) |
POST /v1/workspaces/{ws}/members | Add a member by email (owner) |
PATCH /v1/workspaces/{ws}/members/{mid} | Change a member's role (owner) |
DELETE /v1/workspaces/{ws}/members/{mid} | Remove a member (owner) |
GET /v1/workspaces/{ws}/api-keys | List API keys (owner) |
POST /v1/workspaces/{ws}/api-keys | Create an API key (owner); the key is shown once |
DELETE /v1/workspaces/{ws}/api-keys/{kid} | Revoke an API key (owner) |
POST /v1/workspaces/{ws}/destinations | Register a destination (owner) with a secret or an OAuth grant; secrets are encrypted at rest. default_mode defaults to draft where the adapter can. A webhook may send an empty secret: the response then carries signing_secret, once |
PATCH /v1/workspaces/{ws}/google | Pick the Search Console site and Analytics property to read (owner), then sync. null clears a pick |
DELETE /v1/workspaces/{ws}/google | Disconnect Google (owner): deletes the token and the synced data |
POST /v1/workspaces/{ws}/google/connect | Start connecting Google (owner, web session only). Returns the consent URL to send the browser to |
GET /v1/workspaces/{ws}/google/properties | Search Console sites and Analytics properties the connected account can read, with the likely site match |
POST /v1/workspaces/{ws}/bing | Connect Bing with a Bing Webmaster API key (owner, web session only). The key is checked with Bing, stored encrypted and never returned; answers with the verified sites to pick from |
PATCH /v1/workspaces/{ws}/bing | Pick the verified Bing site to read (only the owner who connected), then sync. null clears it |
DELETE /v1/workspaces/{ws}/bing | Disconnect Bing (owner): deletes the stored key and the synced Bing data |
GET /v1/workspaces/{ws}/bing/sites | Sites verified in the connected Bing Webmaster account, with the likely match for the workspace's site |
POST /v1/workspaces/{ws}/imports | Import a preview as one context version (web session; the person who previewed). Documents go under imported/<provider>/. resync daily re-reads the source each day. 409 context_read_only for Git-managed workspaces; 422 context_too_large past the document limit |
POST /v1/workspaces/{ws}/imports/preview | Dry run (web session; the person who connected the provider): reads and converts the picked files, pages, databases or spaces, and lists each document's path, size and status (new or skipped, with renamed_from when a path was taken). Nothing is written. The preview can be imported for an hour |
POST /v1/workspaces/{ws}/imports/{provider}/connect | Start connecting google_drive, notion or confluence (owner, web session only). Returns the consent URL. 503 when the server has no client for it |
DELETE /v1/workspaces/{ws}/imports/{provider}/connection | Disconnect a provider (owner). Its imports stop and are removed; imported documents stay |
GET /v1/workspaces/{ws}/imports/{provider}/browse | What the connected account shares (web session; the person who connected): Notion pages and databases, or Confluence spaces (and a space's pages with parent=<space id>). Google Drive files are picked in the Google Picker instead |
POST /v1/workspaces/{ws}/task-sync/{provider}/connect | Start connecting Asana (OAuth) or Trello (authorize page) as an owner in the web app. Returns {url} to send the browser to |
POST /v1/workspaces/{ws}/task-sync/trello | Finish connecting Trello with the token from the return URL's fragment and the state from its query (owner, the same browser that started) |
GET /v1/workspaces/{ws}/task-sync/{provider}/projects | Asana projects or Trello boards the connected account can see (only the owner who connected) |
PATCH /v1/workspaces/{ws}/task-sync/{provider} | Pick the project or board tasks go to (only the owner who connected), then sync. null stops syncing; links to tasks in an earlier project are forgotten |
DELETE /v1/workspaces/{ws}/task-sync/{provider} | Disconnect (owner): revokes the token and forgets the task links. Tasks already made stay in the tool |
PATCH /v1/workspaces/{ws}/suggestions/settings | Owners in the web app: digest weekly|off, urgent, email, auto_apply (types Wavefront carries out without asking; off by default) and auto_apply_published (may revise published posts) |
GET /v1/workspaces/{ws}/slack | The Slack connection: team, channel, status (active, paused, reconnect), the messages it posts, reviewer DMs and recent deliveries. Never the token |
PATCH /v1/workspaces/{ws}/slack | Choose which messages go to Slack, turn reviewer DMs on or off, or pause (enabled false) and resume |
DELETE /v1/workspaces/{ws}/slack | Disconnect Slack: revokes the token and deletes the connection and its log |
POST /v1/workspaces/{ws}/slack/connect | Start Add to Slack (owner, web session only). Returns Slack's install URL, where the installer picks the channel |
POST /v1/workspaces/{ws}/slack/test | Post a test message to the connected channel now. Shares the per-workspace webhook send limit (429) |
GET /v1/workspaces/{ws}/microsoft-teams | The Microsoft Teams connection: the webhook URL's host and label, status (active, paused, reconnect), the messages it posts and recent deliveries. Never the URL |
PUT /v1/workspaces/{ws}/microsoft-teams | Connect Teams with a Workflows webhook URL (https on powerplatform.com or logic.azure.com), or replace the URL; the chosen messages are kept and it turns back on |
PATCH /v1/workspaces/{ws}/microsoft-teams | Choose which messages go to Teams, set the label, or pause (enabled false) and resume |
DELETE /v1/workspaces/{ws}/microsoft-teams | Disconnect Teams: deletes the stored URL and the connection's log |
POST /v1/workspaces/{ws}/microsoft-teams/test | Post a test card to Teams now. Shares the per-workspace webhook send limit (429) |
POST /v1/workspaces/{ws}/members/{mid}/invite | Resend a pending invitation (owner) |
PATCH /v1/workspaces/{ws}/settings | Update spend and concurrency caps (owner; app-managed workspaces, 409 context_read_only for Git-managed ones) |
GET /v1/workspaces/{ws}/calendar/feed | Whether you have a calendar feed URL here (id, created_at, last_used_at). The URL itself is shown only when it's made |
POST /v1/workspaces/{ws}/calendar/feed | Make your secret iCalendar feed URL (GET /cal/<token>.ics; ?strategy= and ?published=0 narrow it). Making a new one revokes the old URL. Shown once |
DELETE /v1/workspaces/{ws}/calendar/feed | Turn your calendar feed URL off |
PATCH /v1/workspaces/{ws}/autopilot | Owners: switch autopilot on or off, its timing, publishing on the date, and the backlog cadence ({per_day, days}) |
PATCH /v1/workspaces/{ws}/autopilot/approval | Owners in the web app: let autopilot approve its own calendar drafts with zero blockers, and request one automatic revision when they have blockers. API keys and MCP get 403 |
POST /v1/workspaces/{ws}/billing/checkout | Start a checkout top-up (owner session) |
POST /v1/workspaces/{ws}/billing/subscribe | Subscribe to the plan in checkout, monthly or annual (owner session) |
POST /v1/workspaces/{ws}/billing/packs | Buy a one-time credit pack in checkout (subscribers, owner session) |
POST /v1/workspaces/{ws}/billing/portal | Open the billing portal: change plan, cancel, card, invoices |