Getting Started
Everything you need to start using the Wahlu API.
What is the Wahlu API?
The Wahlu API provides 22 operations for agents and applications. Its thirteen-operation preparation subset discovers accessible context and targets, uploads, imports, inspects, and explicitly repairs media, creates a draft, discovers live TikTok privacy choices, updates that choice on the same draft, preflights it, and creates and reads a Schedule; the full contract also lists media, content and Schedules, reschedules or cancels a Schedule before its run starts, and exposes redacted publish receipts and exact receipt-bound cleanup.
Drafts you create through the API or MCP appear on the brand's Drafts page in Wahlu, labelled From the API, until they are scheduled. Scheduled and published posts move to History.
Base URL
Every public REST route in this reference starts with:
https://api.wahlu.com/v1Quick start
1. Create an API key
Open your Wahlu dashboard, go to Settings → API Keys, and create a key. Choose only the scopes your workflow needs and, if appropriate, restrict it to specific brands.
2. Discover the current context
Start every agent workflow by reading the workspace, accessible brands, granted scopes and resolved next-operation links for the current key.
curl https://api.wahlu.com/v1/context \
-H "Authorization: Bearer wahlu_live_your_api_key_here"const response = await fetch("https://api.wahlu.com/v1/context", {
headers: {
Authorization: "Bearer wahlu_live_your_api_key_here",
},
});
if (!response.ok) throw new Error("Wahlu returned " + response.status);
const { data, meta } = await response.json();
console.log(data.brands, data.api_key.scopes, meta.request_id);3. Follow returned links and IDs
A successful response uses the strict canonical envelope below. Use the returned brand ID and links rather than constructing or guessing identifiers.
{
"success": true,
"data": {
"actor": { "user_id": "user_01k0agent" },
"workspace": { "id": "workspace_01k0acme", "name": "Acme Social" },
"api_key": {
"id": "api_key_01k0agent",
"name": "Content agent",
"scopes": [
"integrations:read",
"integrations:write",
"media:read",
"media:write",
"posts:write",
"schedule:read",
"schedule:write"
],
"brand_access": "restricted",
"brand_ids": ["brand_01k0acme"]
},
"brands": [
{
"id": "brand_01k0acme",
"name": "Acme",
"links": {
"targets": {
"href": "/v1/brands/brand_01k0acme/targets",
"required_scopes": ["integrations:read"]
},
"media_imports": {
"href": "/v1/brands/brand_01k0acme/media/imports",
"method": "POST",
"required_scopes": ["media:write"]
},
"content_items": {
"href": "/v1/brands/brand_01k0acme/content-items",
"method": "POST",
"required_scopes": ["posts:write"]
}
}
}
],
"links": {
"platform_capabilities": {
"href": "/v1/platforms/capabilities",
"required_scopes": []
}
}
},
"meta": { "request_id": "req_context_01k0" }
}Recommended first workflow
Use the held Schedule recipe for the core eleven-operation no-provider workflow. When the selected target is TikTok, first read its live privacy choices and apply one validated value to the same draft before preflight. The compatible GET is read-only; if it cannot safely proceed, a caller withintegrations:write can use the explicit provider-backed POST refresh. That action may refresh stored credentials or integration state, but it changes no content, creates no Schedule, and submits no provider post. The full public API also exposes bounded publish receipt and exact provider cleanup operations after a run. The recipe finishes with a pending_review Schedule and creates no publishing execution, job or provider request.