POST
/v1/placementsCreate placement
Use this as the default Server API entry point. It combines job creation and first-decision wait so your frontend can hand the response to the hosted renderer instead of manually building media DOM.
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| wait_ms | integer | Optional | Optional long-poll wait time in milliseconds. Defaults should stay short, for example 1500. |
| client_id | string | Required | Project identifier. |
| session_id | string | Required | Stable publisher session identifier. |
| job_type | string | Required | Workload category such as chat, search, agent, or summarization. |
| slot_hint | object | Optional | Placement position and maximum dimensions. |
| overrides | object | Optional | Request-level format, timing, bidfloor, and publisher overrides. |
| consent | object | Optional | Consent state or consent reference for this request. |
Returns
| Name | Type | Description |
|---|---|---|
| slot_id | string | Slot identifier for diagnostics and advanced compatibility. |
| status | string | Decision state, usually pending or ready. |
| placement | object | null | Hosted-render placement descriptor when a fill is ready. |
| placement.render | object | Hosted frame descriptor with frame_url, script_url, media_type, dimensions, label, sponsor, and click URL. |
| decision | object | null | Canonical decision payload retained for compatibility and debugging. |
Request example
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"],16 "timing": "during"17 },18 "consent": {19 "semantic_targeting": false,20 "prompt_shared": false,21 "consent_source": "publisher"22 }23 }'Response example
Response
response.jsonjson
1{2 "slot_id": "slot_demo_123",3 "status": "ready",4 "placement": {5 "image_url": "https://api.wavebird.ai/v1/test-assets/banner?...",6 "video_url": null,7 "click_url": "https://sponsor.example",8 "sponsor_name": "Demo Sponsor",9 "width": 728,10 "height": 90,11 "format": "banner",12 "asset_token": "wbat_asset_demo",13 "ad_label_text": "Sponsored",14 "render": {15 "strategy": "hosted_frame",16 "frame_url": "https://api.wavebird.ai/v1/render/wbat_asset_demo",17 "script_url": "https://api.wavebird.ai/v1/render.js",18 "media_type": "image",19 "width": 728,20 "height": 90,21 "aspect_ratio": "728/90",22 "label_text": "Sponsored",23 "sponsor_name": "Demo Sponsor",24 "click_url": "https://sponsor.example"25 }26 },27 "decision": {28 "fill": true,29 "format": "banner",30 "asset_token": "wbat_asset_demo"31 }32}Errors
unauthorized401Missing secret key.
forbidden403Wrong key type for the request.
rate_limited429Key exceeded its rate limit; retry after the Retry-After header.
validation_error400The request body failed validation.