Quickstart: place your first order
Ten minutes, sandbox credentials, one order on air (in the sandbox sense). The sandbox seller is Acme Broadcasting; it behaves like a real seller, including the approval pause. This walks the catalog path because it is the fastest way to see an order move; it is not the only front door. When a seller withholds avails or prices per campaign, or when you would rather send a brief than pick line items, start with a proposal instead. Both are first-class.
1. Get a token
curl -s https://auth.sandbox.switchboard.simulmedia.com/oauth/token \ -d grant_type=client_credentials \ -d client_id=$SWB_CLIENT_ID -d client_secret=$SWB_CLIENT_SECRET
2. Browse the catalog
curl -s https://api.sandbox.switchboard.simulmedia.com/v1/sellers/acme/catalog \ -H "Authorization: Bearer $TOKEN" { "packages": [ { "package_id": "acme-prime", "type": "daypart", "definition": { "selling_title": "Prime", "days": ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"], "start": "20:00", "end": "23:00" }, "taxonomy_version": "acme-2026q4-v1", "network": "ACME", "currencies": ["spots","hh","p2plus","a25_54"], "guarantee_tiers": ["ng_preemptible","guaranteed"], "deal_types": ["preemptible","fixed","audience_as_aired","audience_guaranteed"] } ] }
3. Check avails and rates
curl -s "https://api.sandbox.switchboard.simulmedia.com/v1/sellers/acme/avails?package_id=acme-prime&weeks=2026-W40,2026-W41" \ -H "Authorization: Bearer $TOKEN" { "avails": [ { "week": "2026-W40", "grain": "week", "state": "available", "basis": "actual", "spots": { "available": 42, "total": 80 }, "sellout_level": 0.62, "rates": [ { "class": "scatter", "advertiser_class": "general", "spot_length": 30, "gross_rate_unit": 405.00, "locked_rate_id": "lr_88c1" } ] } ] }
4. Place the order
Catalog orders reference package IDs and locked rates; because you ordered against published availability and a current rate version, there is no confirmation round-trip.
curl -s https://api.sandbox.switchboard.simulmedia.com/v1/orders \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{ "seller": "acme", "deal_type": "preemptible", "external_order_id": "q4-campaign-042", "rate_version": "acme-2026q4-v1", "line_items": [ { "package_id": "acme-prime", "week": "2026-W40", "units": 10, "spot_length": 30, "rate": { "class": "scatter", "unit_cost": 405.00, "locked_rate_id": "lr_88c1" } }, { "package_id": "acme-prime", "week": "2026-W41", "units": 10, "spot_length": 30, "rate": { "class": "scatter", "unit_cost": 405.00, "locked_rate_id": "lr_88c1" } }], "buyer_metadata": { "advertiser": "YourClient", "campaign": "Q4-2026" }, "notify_url": "https://yourapp.example.com/webhooks/switchboard" }' { "order_id": "ord_9f3a12c4b7e1", "status": "submitted" }
5. Watch it move
Your notify_url receives events as the order validates and enters seller_review (a person at the seller approves; in the sandbox this takes about a minute). At any time the snapshot is authoritative:
curl -s https://api.sandbox.switchboard.simulmedia.com/v1/orders/ord_9f3a12c4b7e1 \ -H "Authorization: Bearer $TOKEN"
On approval you receive a placement_receipt (the booking receipt: the seller's order ID, daylocks applied, timestamp) as the order lands in placed: the buy is booked. When the flight has run, a final completed event closes the order; the sandbox compresses that wait to about a minute. Discovered, ordered, approved, placed. No email involved.
POST /v1/webhooks/endpoints; unregistered hosts fail order creation fast with a 422 so you never wonder why events did not arrive.