WavefrontDevelopers

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.

KindMakesMain input
articleA sourced long-form page with images, structured data and SEO checkscontent_type, title, primary_keyword, required_facts; optional sources, slug, links, assignment
copyShort copy: social posts, meta descriptions, newsletterscontent_type (such as linkedin_post or newsletter) and brief; optional canonical_url, links
imageOne editorial imageprompt, alt; optional aspect_ratio
strategyA 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, including preview.html. Add ?text=1 for the text itself.
  • POST …/versions/{vid}/revisions with {"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 with 409 approval_mismatch.
  • Review together: comments (GET/POST …/generations/{id}/comments), reviewer requests (PATCH …/generations/{id} with assignee_id), GET …/people and the GET …/activity feed.

Publishing and schedules

  • GET …/destinations lists where content can go, with each destination's capabilities (kinds, copy formats, drafts, scheduling) and default_mode. Owners add destinations in the web app.
  • POST …/versions/{vid}/publish with {"destination_id"} and an optional mode (publish, draft or schedule with publish_at, where the destination supports it) returns 202 and a publication. Follow it with GET …/publications/{id}: its state moves through queued, sending, building and verifying to published, draft_created, scheduled or failed.
  • 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 until checks_pending is false.
  • POST …/schedules publishes an approved version at publish_at, or on its calendar date with {"on_calendar_date": true, "time": "09:00"} in the workspace's time zone. Change it with PATCH …/schedules/{id} and cancel it with POST …/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 …/strategies lists a workspace's strategies; POST starts one (optionally with a first message to the strategist).
  • The strategist researches and edits the plan: POST …/studio/messages starts a turn and returns the message_id to poll with GET …/studio. One turn at a time (409 conflict). Routes under /studio act on the primary strategy; the same routes exist under /strategies/{sid}/studio.
  • PATCH …/strategies/{sid}/plan edits the plan directly. Prefer the item operations (keywords_add, keywords_remove, calendar_upsert, calendar_remove and the rest), which never touch items you didn't name, and send base_plan_version to get 409 plan_conflict instead of overwriting someone else's change.
  • POST …/studio/save writes the plan into the documents every draft reads. GET …/calendar lists the saved posts across strategies, with where each stands; POST …/calendar/draft drafts 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.

An idea
{
  "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.

CodeWhen
concurrency_limitToo many generations queued or running in the workspace. Owners set the limit in Settings.
daily_budget_exceededThe workspace's daily spending limit, in credits, over the trailing 24 hours. Owners set it in Settings.
service_budget_exceededWavefront's service-wide daily limit.
rate_limitedA per-action limit, such as 10 webhook test events and redeliveries a minute per workspace, or one site metrics check every 10 minutes.
Errors are always {"error": {"code", "message", "hint"?, "details"?}}. Branch on code, never on message. Every code.