Testing
Test the canonical Server API path first. The important gates are key class, /v1/placements response shape, hosted renderer behavior, consent, and beacons. The advanced SDK should only be tested after the core API path is already green.
Test safely
Environments and credentials
Test/Sandbox
Use a Server Test Key (sk_test_...) for integration checks. Test/Sandbox traffic is non-billable, including validation and guardrail diagnostics.
Production dry-run
Use a Server Production Dry-run Key (sk_dry_...). Dry-run is selected by credential class, remains non-billable, and requires no payout setup.
Live boundary
Do not send production_dry_run, production_billing_dry_run, billing_suppressed, or production_live_approved in public request bodies. Billable production/live traffic requires payout readiness, SSP readiness, proof, and explicit live approval.
Credential classes
Dashboard API Keys separates Server Test Key (sk_test_...), Server Production Dry-run Key (sk_dry_...), Server Production Key, and Browser Publishable Key. Do not reuse one class for another environment.
Secret visibility
Raw server secrets are shown only once after create or rotate. Existing masked server-secret previews identify a key but are not usable credentials; create or rotate a server key when you need the full value.
Checklist
Minimum validation path
Use test keys
Use sk_test_*, publishable test keys, and the same Project ID (client_id, WAVEBIRD_CLIENT_ID) first so you can validate the full route chain without billing traffic. In Dashboard API Keys, create or rotate a Server Test Key to copy the full backend-only value; masked previews are for identification and cannot be used as credentials.
Keep key classes separate
Use Server Test Key (sk_test_...) for Test/Sandbox, Server Production Dry-run Key (sk_dry_...) for non-billable dry-run, Server Production Key only after live approval, and Browser Publishable Key only for browser activation. Raw server secrets are shown only once after create or rotate; masked server-secret previews are not usable credentials.
Exercise no-fill and fill
Do not test only the happy path. Validate both filled decisions and no-fill states for your configured formats and constraints.
Exercise optional fields
Test prompt, slot_hint, request-level consent, and advanced overrides separately. Validation errors include request_id and field paths such as slot_hint.max_width.
Confirm beacons
Check rendered and completion beacons for the formats you actually ship. Billing evidence depends on that path, not just on placement creation.
Script Tag
Browser-specific checks
Verify activation against the expected origin, validate consent-required behavior, and confirm that the browser receives only the runtime-safe project config for the active client_id.
Sandbox
Expected negative tests
Beacon validation failures
Intentionally missing asset_token, missing slot_id, invalid event, or stale occurred_at requests should return actionable 400 validation errors in sandbox tests.
A stale timestamp can return BEACON_TOO_LATE. Generate a fresh timestamp for every direct server beacon with new Date().toISOString().
Consent validation failures
Invalid consent purposes should return field-level validation errors. These are expected negative tests when deliberately triggered and should not be treated as production integration failures.
Hosted renderer first
Default integrations should rely on hosted renderer beacons sent to /public/wrapper/v1/beacons. Direct server /v1/beacons is an advanced QA or custom-rendering path.
Direct beacon token handling
Direct server beacons require the sensitive asset_token from placement.asset_token or decision.asset_token. Redact it from logs, screenshots, reports, and client-visible debug output.
Sandbox
Renderer proof diagnostics
Hosted renderer beacons are accepted for sandbox QA even when they are not proof-eligible or billable. Dashboard logs may expose safe diagnostic fields such as proof_source=public_wrapper_renderer, proof_eligible=false, billable=false, non_billable_reason, geometry_reason, renderer_diagnostic_case, contract_exists=true, and renderer_geometry_summary.
Production dry-run validation is still non-billable. Create a Server Production Dry-run Key from Dashboard API Keys, or request one from your wavebird operator, and use the sk_dry_... value as your server-side WAVEBIRD_SECRET_KEY. When dry-run flags or a dry-run key are active, qualifying hosted renderer proof should expose mode=production-dry-run, PRODUCTION_DRY_RUN_NON_BILLABLE, production_dry_run=true, production_live_approved=false, billing_suppressed=true, dry_run_billable_suppressed=true, and proof_would_be_eligible=true. No payout setup is required and production-live-approved is not used for dry-run QA.
If no active SSP demand is available for a production dry-run placement, the placement response should use 409 ssp_not_ready with mode=production-dry-run, production_dry_run=true, production_live_approved=false, and billable=false. Treat that as a dry-run availability/setup blocker, not as a live billing failure.
| Case | Expected reason | Use in QA |
|---|---|---|
tiny | INSUFFICIENT_VISIBLE_AREA | Positive but too-small visible geometry, such as a 1x1 diagnostic slot. |
clipped_8x1_25 | INSUFFICIENT_VISIBLE_AREA | A clipped renderer row with visible/intersection geometry below the paid contract. |
hidden or opacity_zero | HIDDEN_OR_NOT_VIEWABLE | CSS-hidden or transparent renderer evidence that must remain non-billable. |
offscreen | OFFSCREEN | Renderer evidence outside the viewport or intersection path. |
Pre-live
Production dry-run contract
Use the dry-run server key
Production dry-run is a public pre-live validation mode selected by credential class, not by a request-body flag. Use an authorized Server Production Dry-run Key (sk_dry_...) for normal server-side /v1/placements calls. Do not send undocumented production_dry_run, production_billing_dry_run, billing_suppressed, or production_live_approved fields in request bodies; those names are response, log, or dashboard diagnostics only.
Stop at lock-state when gated
If Dashboard shows Phase 4, SSP readiness, payout, or live approval as locked or pending, external preflight tests should verify the visible lock-state and stop unless an authorized dry-run key is available. Test/Sandbox remains the public validation path until production dry-run is explicitly available.
Expect safe blocked responses
A dry-run placement with no active SSP readiness should fail closed with 409 ssp_not_ready. The expected safe response/log semantics are production_dry_run=true, production_billing_dry_run=true, billing_suppressed=true, production_live_approved=false, live_billing=false, and billable=false.
Live billing stays separate
Payout setup is not required for production dry-run. Payout readiness, SSP readiness, and explicit production live approval are required before any billable production/live traffic. Do not use production live keys, click real ads, or claim production billing readiness from dry-run output.
Need rollout review?
Start with the Server API. Use contact only when you need rollout review, enterprise coordination, or non-standard integration help.