Sell without publishing avails
You do not have to publish availability or open rates to sell on Switchboard. Some sellers would rather hold inventory back and price each campaign on its merits. This guide shows the posture: hold your inventory back, take briefs, and answer with a priced plan. It uses the sandbox seller Acme Broadcasting.
When this fits
Reach for it when exposing a feed would work against you: when signaling unsold inventory softens your price, when pricing depends on who is asking and what they want, or when you would rather your planners assemble the buy than let a buyer pick line items off a menu. It is the same lifecycle and the same approval gate as a published catalog; only the disclosure changes.
Set the policy
Set disclosure on the packages you want to guard. You can still list the package, its type, and its terms; you are withholding availability and price, not the package itself.
PUT /v1/me/catalog
{ "packages": [
{ "package_id": "acme-prime", "type": "daypart",
"definition": { "selling_title": "Prime", "days": ["Mon","Tue","Wed","Thu","Fri"],
"start": "20:00", "end": "23:00", "timezone": "America/New_York" },
"taxonomy_version": "acme-2026q4-v1", "network": "ACME",
"currencies": ["spots","a25_54"],
"disclosure": { "avails_policy": "withheld", "pricing_policy": "quote" } } ] }
Now a buyer who calls GET /sellers/acme/avails on this package gets 409 AVAILS_WITHHELD pointing them to a proposal, not a feed. Use on_request instead of withheld if you would rather answer a scoped avails query (and coarsen it) than decline outright.
Answer a brief with a plan
Briefs arrive as proposal orders in your review queue. Assemble the first pass: line items off your card where they fit, and custom packages minted for the request where nothing published does. Where you cannot meet the whole ask, return the shortfall as unmet[] rather than a silent gap, so the buyer sees exactly what you could and could not fill.
POST /v1/me/orders/{id}/plan
{ "plan": {
"line_items": [
{ "package_id": "acme-prime", "week": "2026-W40", "units": 8, "spot_length": 30,
"rate": { "class": "scatter", "unit_cost": 415.00, "locked_rate_id": "lr_q_7a21" } } ],
"unmet": [ { "requested": "overnight rotations", "reason": "held for a committed buyer" } ],
"expires_at": "2026-09-30T20:00:00Z" } }
If the buyer set an acceptance band, a plan within their stated tolerance books on delivery without another round; otherwise it waits for their confirm.
Quote a price
The rates in your plan are a quote: a rate-card commit with commit_kind: "quote", scoped to the buyer's agreement, carrying a quote_expires_at. You never expose a standing number, and the quote locks under the price-clearance invariant when the buyer confirms. Let it expire and the buyer simply re-requests; nothing books at a stale price.
PUT /v1/me/rate-cards
{ "commit": "acme-yourco-q4-quote-1", "commit_kind": "quote",
"agreement_scope": "agr_71c0d2", "currency": "USD",
"quote_expires_at": "2026-09-30T20:00:00Z",
"entries": [
{ "package_id": "acme-prime", "week": "2026-W40", "advertiser_class": "general",
"spot_length": 30, "guarantee_tier": "ng_preemptible", "class": "scatter",
"gross_rate_unit": 415.00, "locked_rate_id": "lr_q_7a21" } ] }