Quickstart
What you do in the Waveband console is available over the REST API and MCP, with the same permissions; the few console-only exceptions (such as paying) are listed in Where can I do this? This page takes you from an API key to a campaign that is ready to run, first with curl, then with an AI agent.
1. Create an API key
In the console, go to Developers and create an API key. This flow needs workspaces:read, workspaces:write, campaigns:write, line_items:read, line_items:write, targeting:read, targeting:write, creatives:write, billing:read, and reports:read. The key is shown once: store it in a secret manager.
export WAVEBAND_API_KEY="wbk_..."
2. Find or create a workspace
curl -s https://waveband.io/api/v1/workspaces \ -H "Authorization: Bearer $WAVEBAND_API_KEY"
No workspace yet? POST /api/v1/workspaces with { "name": "Acme Outdoors" }. Then set the advertiser domain and IAB category once; delivery needs them before a campaign can run.
curl -s -X PATCH https://waveband.io/api/v1/workspaces/<workspace-id> \
-H "Authorization: Bearer $WAVEBAND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"advertiserDomain": "acmeoutdoors.com",
"iabCategory": "IAB22"
}'3. Create a campaign
curl -s -X POST https://waveband.io/api/v1/campaigns \
-H "Authorization: Bearer $WAVEBAND_API_KEY" \
-H "Idempotency-Key: my-first-campaign" \
-H "Content-Type: application/json" \
-d '{
"workspaceId": "<workspace-id>",
"name": "Spring CTV Launch",
"channel": "ctv",
"startDate": "2026-12-01",
"budgetUsdMinor": 500000,
"dailyBudgetUsdMinor": 50000,
"goalType": "impressions"
}'Budgets are integer USD minor units (cents): 500000 = $5,000. A campaign with no end date needs a daily budget. All ids are Waveband UUIDs. Creates accept an Idempotency-Key header so retries are safe.
4. Add a line item
curl -s -X POST https://waveband.io/api/v1/line-items \
-H "Authorization: Bearer $WAVEBAND_API_KEY" \
-H "Idempotency-Key: my-first-line-item" \
-H "Content-Type: application/json" \
-d '{
"campaignId": "<campaign-id>",
"name": "CTV: US prospecting",
"startDate": "2026-12-01",
"budgetUsdMinor": 250000,
"bid": {
"type": "fixed_cpm",
"cpmUsdMinor": 2400
},
"targeting": {
"geo": {
"countries": ["US"]
}
}
}'cpmUsdMinor: 2400 is a $24 CPM. See Targeting for every targeting field.
5. Upload a creative and attach it
curl -s -X POST https://waveband.io/api/v1/creatives \
-H "Authorization: Bearer $WAVEBAND_API_KEY" \
-H "Idempotency-Key: my-first-creative" \
-H "Content-Type: application/json" \
-d '{
"workspaceId": "<workspace-id>",
"name": "Spring :30",
"type": "video",
"clickThroughUrl": "https://acmeoutdoors.com/spring",
"assets": [
{
"source": "https://cdn.acmeoutdoors.com/spring-30.mp4",
"mimeType": "video/mp4",
"width": 1920,
"height": 1080,
"durationSeconds": 30
}
]
}'curl -s -X POST https://waveband.io/api/v1/line-items/<line-item-id>/creatives \
-H "Authorization: Bearer $WAVEBAND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"creativeId": "<creative-id>"
}'Video processes asynchronously; GET /api/v1/creatives/{id} shows its status. To make ads in the console instead, see Making ads.
6. Check funding and forecast
curl -s https://waveband.io/api/v1/billing \ -H "Authorization: Bearer $WAVEBAND_API_KEY"
funded is false until the first top-up lands, and nothing delivers before it. On a prepaid wallet, wallet.availableUsdMinor is what can fund delivery. Adding funds needs a person: POST /api/v1/billing/top-up-links returns a checkout URL for them to pay.
curl -s -X POST https://waveband.io/api/v1/forecasts \
-H "Authorization: Bearer $WAVEBAND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "ctv",
"targeting": {
"geo": {
"countries": ["US"]
}
},
"startDate": "2026-12-01",
"endDate": "2026-12-31"
}'The forecast is available supply matching the targeting, not a delivery promise. A busy result means forecast capacity is used up for the minute; retry shortly.
7. Activate and watch it go live
Campaigns and line items start as drafts. When you are ready to spend, send { "status": "active" } to PATCH /api/v1/campaigns/{id}, then to PATCH /api/v1/line-items/{id}. Changes sync to delivery asynchronously: subscribe a webhook to sync.succeeded.v1 / sync.failed.v1 (see Webhooks & events) or poll GET /api/v1/events.
8. Pull results
curl -s "https://waveband.io/api/v1/reports?workspaceId=<workspace-id>&from=2026-12-01&to=2026-12-07&groupBy=campaign" \ -H "Authorization: Bearer $WAVEBAND_API_KEY"
Add format=csv for a CSV export. Metrics are explained in Reports & metrics.
The same flow with an AI agent
Connect an MCP client to https://waveband.io/mcp with the same key (or OAuth); see MCP & AI agents. Then ask in plain language, for example: "Set up a $5,000 CTV campaign for Acme Outdoors in the US starting December 1 at a $24 CPM with this video, check we are funded, forecast it, but do not activate." The agent calls list_workspaces, update_workspace, create_campaign, create_line_item, upload_creative, attach_creative, get_billing, forecast_line_item, run_report. Anything without a dedicated tool goes through waveband_api.
Next
- API reference and the OpenAPI 3.1 document
- TypeScript: generated types and a fetch helper
- Console creatives: Waveforms from Creative Studio and Soundframe audio-led video land as ordinary creatives on the same API.