Validate decisions
Check filled, pending, and no-fill paths before live traffic.
Getting started
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.
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_keyContinue with the REST and renderer guide, then use the testing checklist to verify the result.
Recommended default path for backend-owned integrations.
Server API placement request
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 }'Sandbox 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
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 }'Check filled, pending, and no-fill paths before live traffic.
Dashboard-created Test projects require current lifecycle consent. Pass request-level consent with /v1/placements or sync the session through /v1/consent.
Confirm renderPlacement creates one hosted frame, reaches a rendered state, and reports frame_error without positive signals when media cannot load.
Share the affected endpoint, request ID, and the behavior you expected. Leave out keys and user content.