Getting started

Quickstart

The shortest Server API path is: create a Server Test Key, call /v1/placements from your backend, pass the filled placement to the browser, load /v1/render.js, and callwavebird.renderPlacement(). No SDK or withTurn() helper is required for this REST path.

Start in the dashboard

Create a workspace, open Dashboard API Keys, and create a Server Test Key for the backend. Copy the newly revealed sk_test_... value when it is created or rotated; existing server secrets are intentionally shown only as masked previews. Also copy the Project ID (client_id, WAVEBIRD_CLIENT_ID) formatted like wbproj_..., and configure local allowed origins before browser testing.

Keep the server key on your backend. Browser activation uses a separate publishable key. See key classes and authentication for production credentials and rotation.

WAVEBIRD_API_BASE_URL=https://api.wavebird.ai
WAVEBIRD_SECRET_KEY=sk_test_your_server_test_key
WAVEBIRD_CLIENT_ID=wbproj_your_project_id
NEXT_PUBLIC_WAVEBIRD_PUBLISHABLE_KEY=pk_publishable_your_browser_key

Continue with the REST and renderer guide, then use the testing checklist to verify the result.

Server API placement request

Recommended backend path. For dashboard Test projects using wavebird_consent, first record the actual session decision through POST /v1/consent with the same client_id and session_id; inline flags alone return 403 consent_not_current.

Server API placement request

create-placement.shbash
1curl -X POST https://api.wavebird.ai/v1/placements?wait_ms=1500 \2  -H "Authorization: Bearer sk_test_wavebird_demo_secret" \3  -H "Content-Type: application/json" \4  -d '{5    "client_id": "wbproj_demo_8jK42",6    "session_id": "sess_demo_123",7    "job_type": "chat",8    "slots_requested": 1,9    "slot_hint": {10      "position": "below",11      "max_width": 728,12      "max_height": 9013    },14    "overrides": {15      "allowed_formats": ["banner", "clip", "native"],16      "timing": "during"17    },18    "consent": {19      "semantic_targeting": false,20      "prompt_shared": false,21      "gdpr_applies": false,22      "consent_source": "wavebird_consent"23    }24  }'
Explore other endpoint examples

Sandbox request

Copy a complete request

Choose an endpoint, then copy its documented cURL request. The default placement request includes client_id, session_id, and job_type.

POST /v1/placements

create-placement.shbash
1curl -X POST https://api.wavebird.ai/v1/placements?wait_ms=1500 \2  -H "Authorization: Bearer sk_test_wavebird_demo_secret" \3  -H "Content-Type: application/json" \4  -d '{5    "client_id": "wbproj_demo_8jK42",6    "session_id": "sess_demo_123",7    "job_type": "chat",8    "slots_requested": 1,9    "slot_hint": {10      "position": "below",11      "max_width": 728,12      "max_height": 9013    },14    "overrides": {15      "allowed_formats": ["banner", "clip", "native"],16      "timing": "during"17    },18    "consent": {19      "semantic_targeting": false,20      "prompt_shared": false,21      "gdpr_applies": false,22      "consent_source": "wavebird_consent"23    }24  }'

Validate decisions

Check filled, pending, and no-fill paths before live traffic.

Validate consent

Projects using wavebird_consent require a current stored consent record for the authenticated tenant, client_id, and session_id. Record the actual user decision through /v1/consent before placement; inline flags cannot replace or expand that permission.

Validate rendering

Confirm renderPlacement creates one hosted frame, reaches a rendered state, and reports frame_error without positive signals when media cannot load.

Need help with your integration?

Share the affected endpoint, request ID, and the behavior you expected. Leave out keys and user content.

Contact the team