REST API
REST API guides
The REST API lives at https://wavefront.adwave.com/v1. It takes JSON, answers JSON, and authenticates with a workspace API key (Authentication). Workspace resources are under /v1/workspaces/{ws}, where ws is the workspace slug. Every operation is in the reference and the OpenAPI document.
Generations and kinds
A generation is one piece of asynchronous work. POST …/generations with {"kind", "input"} returns 202 at once; poll GET …/generations/{id} or subscribe to webhooks. GET /v1/kinds returns each kind's input as JSON Schema.
| Kind | Makes | Main input |
|---|---|---|
article | A sourced long-form page with images, structured data and SEO checks | content_type, title, primary_keyword, required_facts; optional sources, slug, links, assignment |
copy | Short copy: social posts, meta descriptions, newsletters | content_type (such as linkedin_post or newsletter) and brief; optional canonical_url, links |
image | One editorial image | prompt, alt; optional aspect_ratio |
strategy | A one-shot content strategy. For ongoing planning, use strategies and the strategist (below) | url and/or description; optional name, goals, audience, avoid |
Statuses: queued and running (working), needs_input (answer its questions with POST …/generations/{id}/inputs), ready_for_review (a version exists), incomplete_budget, and the final failed, cancelled and expired. Cancel with POST …/generations/{id}/cancel. List with GET …/generations, filtered by status, review_status, kind, view, q, strategy, assignment or publishing; an unknown filter value is a 400, never an empty list. Only one active generation may exist per assignment {id, revision} (409 assignment_exists).
Review and revisions
GET …/versions/{vid}returns the package manifest, the review summary (blockers,warnings, what was fixed, SEO checks) and 15-minute links to every file, includingpreview.html. Add?text=1for the text itself.POST …/versions/{vid}/revisionswith{"feedback"}starts the next version. One revision per version runs at a time (409 revision_in_progress).- Approval happens only in the web app. Keys get
403 human_approval_required. Approval is bound to the exact package; if it changes, publishing fails with409 approval_mismatch. - Review together: comments (
GET/POST …/generations/{id}/comments), reviewer requests (PATCH …/generations/{id}withassignee_id),GET …/peopleand theGET …/activityfeed.
Publishing and schedules
GET …/destinationslists where content can go, with each destination'scapabilities(kinds, copy formats, drafts, scheduling) anddefault_mode. Owners add destinations in the web app.POST …/versions/{vid}/publishwith{"destination_id"}and an optionalmode(publish,draftorschedulewithpublish_at, where the destination supports it) returns202and a publication. Follow it withGET …/publications/{id}: itsstatemoves throughqueued,sending,buildingandverifyingtopublished,draft_created,scheduledorfailed.- Publishing a later version of the same content to the same destination updates the existing post in place (
operation: "update"), keeping its URL and slug. - After a page goes live, Wavefront checks it and reports
warnings(missing canonical tag, broken images, noindex and more) and, where turned on, the IndexNow result. Poll untilchecks_pendingisfalse. POST …/schedulespublishes an approved version atpublish_at, or on its calendar date with{"on_calendar_date": true, "time": "09:00"}in the workspace's time zone. Change it withPATCH …/schedules/{id}and cancel it withPOST …/schedules/{id}/cancel. The approval is checked again when it goes out. One schedule per content item and destination (409 schedule_exists).- Social networks and newsletter sends are posted by a person in the web app only; API keys get
403 forbidden. Newsletter tools (Mailchimp, Kit, beehiiv) receive drafts and never send.
Export
For a site Wavefront doesn't publish to, export an article and post it by hand: GET …/versions/{vid}/export?format=html|md|json|zip. Approved versions export for anyone who can read the workspace; a draft needs generations:write.
curl -s "$WF/v1/workspaces/adwave/versions/ver_…/export?format=md" -H "authorization: Bearer $KEY"
curl -s -o article.zip "$WF/v1/workspaces/adwave/versions/ver_…/export?format=zip" -H "authorization: Bearer $KEY"md is Markdown with YAML front matter; front_matter picks and renames its keys (for example front_matter=title,slug,meta_description:description). json is a portable document with body_html, body_markdown, images, categories, tags and JSON-LD. zip holds all of them plus the image files.
Strategies, plans and the calendar
GET …/strategieslists a workspace's strategies;POSTstarts one (optionally with a firstmessageto the strategist).- The strategist researches and edits the plan:
POST …/studio/messagesstarts a turn and returns themessage_idto poll withGET …/studio. One turn at a time (409 conflict). Routes under/studioact on the primary strategy; the same routes exist under/strategies/{sid}/studio. PATCH …/strategies/{sid}/planedits the plan directly. Prefer the item operations (keywords_add,keywords_remove,calendar_upsert,calendar_removeand the rest), which never touch items you didn't name, and sendbase_plan_versionto get409 plan_conflictinstead of overwriting someone else's change.POST …/studio/savewrites the plan into the documents every draft reads.GET …/calendarlists the saved posts across strategies, with where each stands;POST …/calendar/draftdrafts them now.- Autopilot (
PATCH …/autopilot, owners) drafts posts as they come due and can schedule approved ones for their dates.
Backlog
A strategy can keep a backlog of ideas that fills open calendar slots at a cadence. GET …/backlog shows counts and the next ideas; POST …/backlog/ideas appends up to 500; POST …/backlog/import loads a whole backlog (merge or replace); GET …/backlog/preview shows what would be scheduled and why; POST …/backlog/fill fills slots now. Writes need context:write. Invalid ideas are left out and listed in warnings.
{
"id": "12",
"title": "12 Epic Sci-Fi Movies Like Dune",
"format": "blog_post",
"primary_keyword": "movies like dune",
"priority": "high",
"valid_from": "--10-01",
"valid_until": "2027-03-17"
}Context documents
The workspace documents (brief, voice, rules, references) are what every draft reads. GET …/context lists them with summaries; GET …/context/file?path= reads one; PUT …/context/file and DELETE …/context/file?path= change one. Every change is a new, restorable version (GET …/context/versions, POST …/context/restore). Send base_version where offered to get 409 conflict rather than overwrite a newer change. GET/PUT …/writing-rules manage phrases drafts must never use or should avoid.
Search data and suggestions
Once an owner connects Google Search Console, Analytics or Bing Webmaster Tools in the web app, GET …/search-performance returns queries, pages, channels and opportunities (…/search-performance/page?url= for one page). GET …/site-metrics tracks the site's authority and visibility over time. Wavefront also suggests what to do about the data: GET …/suggestions lists them with their evidence, and POST …/suggestions/{id}/approve or /dismiss decides one (generations:write).
Idempotency
Send an Idempotency-Key header (up to 255 characters) on POST …/generations, POST …/strategies, POST …/studio/messages, POST …/generations/{id}/comments and POST …/versions/{vid}/revisions. For 7 days, repeating it with the same body returns the original result with 200 and replayed: true instead of doing the work twice. The same key with a different body is 409 idempotency_conflict.
Pagination
Lists take limit and return next_cursor; pass it back as cursor for the next page, and stop when it is null. Cursors are opaque. A few lists (the backlog, suggestions) page with offset instead, as the reference shows.
Limits and rate limiting
Limits answer 429 with details.retry_after in seconds (and a Retry-After header where it applies). Back off and retry after that long.
| Code | When |
|---|---|
concurrency_limit | Too many generations queued or running in the workspace. Owners set the limit in Settings. |
daily_budget_exceeded | The workspace's daily spending limit, in credits, over the trailing 24 hours. Owners set it in Settings. |
service_budget_exceeded | Wavefront's service-wide daily limit. |
rate_limited | A per-action limit, such as 10 webhook test events and redeliveries a minute per workspace, or one site metrics check every 10 minutes. |
{"error": {"code", "message", "hint"?, "details"?}}. Branch on code, never on message. Every code.