Small enough to hold in your head.
Eight endpoints, one prepaid balance, and a machine-readable schema so an agent can configure itself. Every response says how old its price is.
quickstart
Two requests to a live link.
- 1
Quote a plan
A brief in, a costed basket out. Cheapest seller for each domain, spread across domains, held at that price for 30 minutes.
- 2
Order the lines
Redeem the quote and pay what you were quoted. Cancel free until the morning batch.
export PLACEMENT_KEY="pk_live_…"
# 1. ten finance links, DR50+, cheapest seller for each,
# fakes excluded, one per domain. Price held 30 minutes.
curl -X POST https://api.placementapi.com/v1/quote \
-H "Authorization: Bearer $PLACEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"links":10,"topic": "finance","dr_min":50,
"strategy": "cheapest","budget_credits":500000}'
# 2. buy a line at the price you were quoted
curl -X POST https://api.placementapi.com/v1/orders \
-H "Authorization: Bearer $PLACEMENT_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"quote_id": "qt_9f2c…",
"offer_id": "s1a2b3c4:fintechweekly.com:guest_post",
"target_url": "https://acme.com/pricing"}'endpoints
The whole surface.
/v1/offersSearch inventory. Filter by DR, price, topic, geo, language, turnaround.
/v1/quoteA brief in, a costed basket out. Cheapest seller per domain, spread across domains, price held 30 minutes.
/v1/sites/{domain}One domain, every way to buy it, cheapest first, with the price spread.
/v1/ordersPlace an order. Charges immediately. Idempotency-Key required.
/v1/orders/{id}/cancelFull refund until the order reaches a supplier.
/v1/ordersDelivery state: in_progress, overdue, refund_eligible.
/v1/creditsBalance, spend limits, and every entry behind them.
/v1/schemaThe whole API, machine-readable, so an agent configures itself.
Every response carries observed_at and a stale flag, so nothing is priced without saying how old that price is. Reads are metered: 1,000 requests and 20,000 rows per hour, plus a monthly allowance that grows with credits purchased.
billing
Credits, pegged to something real.
1 credit = 1 US cent. No invented unit, no conversion table, no rate card to decode at reconciliation time.
Credits leave the account when an order is placed, because link buying is pay-first everywhere. What we add is the accounting on the other side:
- Past its promised turnaround: flagged, and logged against that supplier's on-time rate
- Still undelivered 21 days later: credits returned automatically
- Delivered late: counted, so you can stop buying from whoever keeps doing it
Unspent credits are refundable for 90 days, and never expire. Terms.
{
"balance_credits": 76600,
"balance_usd": "766.00",
"funding": {
"cash_on_hand_credits": 51200,
"pending_credits": 25400
},
"limits": {
"per_order_max_credits": 50000,
"daily_max_credits": 100000,
"remaining_today_credits": 76600
},
"refund_grace_days": 21
}pooled buying
Volume credits.
Suppliers discount on volume
No single agency places enough with any one supplier to reach the tiers that matter. Pooled across every buyer here, we do.
Most of it comes back
Returned as ordinary credits, weighted by what you bought. Not a loyalty scheme: it is your share of a rate you helped earn.
After delivery, not before
A discount on an order that never ran is not a discount, so credits follow delivery and are issued against what a supplier actually invoiced.
Or skip the REST surface entirely.
The same product is a remote MCP server. Seven tools, one command, with ordering behind a separate key scope.