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

Quickstart · Waveband Docs