Drafts, History and planning
Read brand activity and safely manage drafts, Autopilot ideas and held schedules.
These actions use the workspace and brand access on your API key. Every item must belong to the brand in the path. Start with a read, show the proposed change, then ask the user before a write. The production MCP tools and CLI use these same routes.
List drafts
/v1/brands/:brand_id/draftsRequires posts:read. Returns up to 50 unused drafts, newest first, in data.items. Each item has its ID, name, caption preview (up to 280 characters), media count, thumbnail, account IDs and last update time. Add ?label=label_id to return only drafts with that label. Use an ID from the brand labels endpoint. Filtering happens before the 50-draft limit.
Edit or delete an unused draft
/v1/brands/:brand_id/drafts/:draft_id/v1/brands/:brand_id/drafts/:draft_idRequires posts:write. Both actions need confirm_draft_idin the JSON body, matching the path ID, and an idempotency key. Editing acceptsname (1 to 200 characters), caption (up to 20,000 characters), or both. An empty caption clears it. Caption edits require a single shared caption; edit separate platform copy in Wahlu. Media stays unchanged.
Scheduled, queued or published content cannot be edited or deleted here. Deleting a draft keeps its media and never removes a post from a social account.
curl -X PATCH "https://api.wahlu.com/v1/brands/brand_123/drafts/draft_123" \
-H "Authorization: Bearer $WAHLU_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: autumn-draft-edit-1" \
-d '{"confirm_draft_id":"draft_123","name":"Autumn launch"}'Read History
/v1/brands/:brand_id/historyRequires publications:read. Send limit (1 to 50, default 20) and page (starting at 1). The result has items andhas_more. Each item includes its platform, post name, status and dates.permalink_url is a safe public post link, or null when no link is available. This does not fetch engagement data from a social platform.
Read Link in bio
/v1/brands/:brand_id/bio/v1/brands/:brand_id/bio/statsBoth require posts:read. The page read returns data.pagewith the handle, draft and published page, or null if none exists. The stats read accepts days=7 (default) or days=28 and returns views, visitors and link click counts. These routes never edit or publish the page.
Find the active Autopilot plan
/v1/brands/:brand_id/autopilot/planRequires posts:read. Returns data.plan with the active plan ID, status and up to 100 recent week numbers, or null when none exists.has_more_weeks reports whether older weeks exist. This read creates nothing and starts no generation.
Read an Autopilot week
/v1/brands/:brand_id/autopilot/weeks/:week_numberRequires posts:read and a plan_id query parameter. Use the plan ID and a week number from the active-plan read above. The result includes the plan ID, week, status, theme and items. Each item includes its topic, review status and any content or schedule ID. It creates no plan, draft or schedule.
Approve or regenerate an Autopilot idea
/v1/brands/:brand_id/autopilot/weeks/:week_number/items/:item_id/approve/v1/brands/:brand_id/autopilot/weeks/:week_number/items/:item_id/regenerateBoth require a paid plan, posts:write, an idempotency key and a JSON body with plan_id and confirm_item_id. The confirmation must match the path. Approval marks an idea as approved; it does not queue generation, approve a schedule or publish a post.
Any schedule later generated from that idea is held as pending_review, even with auto-approval on. A person must approve it in Wahlu, or use the held-schedule approval route with schedule:write and publish:execute.
Regeneration replaces one unused topic and needs a paid plan. Optional guidance can contain up to 2,000 characters. It does not generate Studio images or videos. If the result is uncertain, the same key cannot start a second regeneration. Read the week before deciding what to do next.
Read notifications
/v1/brands/:brand_id/notificationsRequires notifications:read. Returns only notifications visible to the key owner for this brand. Send limit (1 to 50, default 20),filter=all (default) or filter=unread, and the returnednext_cursor as cursor for the next page. Items contain the type, category, title, message, read state and date. Reading never marks an alert as read.
Approve a held schedule
/v1/brands/:brand_id/schedules/:schedule_id/approveRequires schedule:write and publish:execute. Sendconfirm_schedule_id in the JSON body and an idempotency key. Only a future held API or Autopilot schedule can be approved. Wahlu checks current publishing access and readiness. Approval lets the normal pipeline publish the post at its set time.
Move a schedule to drafts
/v1/brands/:brand_id/schedules/:schedule_id/move-to-draftRequires schedule:write and posts:write. Sendconfirm_schedule_id and an idempotency key. Removes an unsent schedule and keeps its content as a draft. It fails if execution has started or another use remains.
Delete a schedule
/v1/brands/:brand_id/schedules/:schedule_idRequires schedule:write. Send confirm_schedule_id in the JSON body and an idempotency key. Deletes only an unsent schedule before execution starts. Its content and media remain. This never deletes a post from a social platform.
Write responses and retries
Send the key in Idempotency-Key or the body fieldidempotency_key. If both are present, they must match. Each new write above returns 200 with the resource id and an outcome: updated, deleted, approved, moved_to_draft or regenerated. A replay keeps the original outcome and adds Idempotency-Replayed: true. Reusing a key with different input fails. All responses retain the request ID in meta.request_id.
Studio generation, Insights, comment-to-DM and Link in bio editing are not exposed.