Planning

A brief in, a held basket out

Prefer this over assembling a plan from /v1/offers yourself: it collapses each domain to its cheapest seller across every supplier, spreads the basket across domains so it does not read as one relationship, and HOLDS the prices for 4 hours. Each line carries why, relevance, subdomain_of, quality_reasons and up to two alternatives held at the shown price. Redeem with POST /v1/orders once per line with quote_id set. Nothing is reserved or charged; quoting is free. Accepts a customer key or dashboard session; the operator token is refused.

post/v1/quote

Request

  • Base URL: https://api.placementapi.com
  • URL: https://api.placementapi.com/v1/quote
  • Auth: HTTP bearer

Request body

linksinteger required

How many placements to plan.

strategy'cheapest' | 'fastest' | 'safest' | 'recommended'

Every strategy honours the same filters, quality gates, footprint cap and budget; cheapest is the default. fastest orders by turnaround, and safest prefers independently measured domains with real search traffic — those three change ordering only. recommended is additive and quality-first: measured-and-passed publishers before unmeasured ones, then the existing placement_score descending, with price (and offer id) only as deterministic ties and budget feasibility. In a deployment whose semantic layer runs in rank mode, recommended also reorders placements by a rank-usable judgment within the explicit demand/leader priorities; it omits nothing, and missing, failed or below-threshold evidence falls back to this same deterministic result and the same price. Its retrieval cut is a bounded quality proxy, not an exact global score ranking.

budget_creditsinteger

Ceiling for the whole basket, in credits.

placement_type'guest_post' | 'niche_edit' | 'link_insert' | 'homepage_link' | 'media_placement'
inventory_mode'named' | 'pre_approval' | 'blind'

The most important field. 'named' = a specific, identified domain you can inspect before ordering. 'pre_approval' = the vendor proposes candidate domains and the buyer approves them BEFORE placement. 'blind' = a promise (e.g. DR50+, finance) where the domain is assigned at fulfilment with no veto. Only 'named' carries a site_id. Never present a pre_approval or blind offer as though a specific site were secured, and never price-compare a specification against a named domain as the same product.

dr_minnumber

Minimum DR, 0-100. Matches the site's claimed DR, or the vendor's guaranteed minimum on blind inventory. Never the measured verified_dr, which is on a 0-1000 scale.

rd_minnumber

Minimum guaranteed Majestic referring domains. Only blind tiers sold on RD carry this guarantee; the RD and DR scales are never translated into each other.

traffic_minnumber

Minimum monthly traffic: measured where known, else claimed, else the blind guarantee floor.

price_maxinteger

Maximum price per placement, USD minor units (cents).

price_mininteger

Price floor, USD minor units. A quality filter, not a budget one: a price far below the going rate for the claimed DR is evidence the DR was bought.

verified_onlyboolean

Only domains measured independently AND passed. Stricter than excluding suspect domains, because it also drops the unmeasured.

include_restrictedboolean

Gambling, adult and piracy sites are excluded unless topic/accepts names the vertical or this is true.

plausibility_min_pctnumber

Keep only placements at or above this percentile of their own price band (placement type x inventory mode x claimed-DR decade). The measured form of price_min.

supplierstring

Opaque supplier token taken from the prefix of any offer_id. Filters to one source without naming it. Real supplier names are not accepted and match nothing.

dr_maxnumber
include_suspectboolean

Suspect domains are excluded unless asked for.

prefer_demandboolean

Order eligible placements by observed demand (distinct buyers in twelve months) before price.

prefer_leadersboolean

Order eligible placements by leader_links for the brief's topic before price. Give a topic so the right leaders count.

exclude_domains_bought_forstring

A target URL or domain. Domains this account already bought for it are left out (excluded.bought_for_target).

exclude_domains_linking_tostring

A target URL or domain. Every domain in its backlink profile is left out (excluded.already_linking) and the response carries profile_hint. Fetches the profile if not cached (counts against the daily profile budget).

target_urlstring uri

The page this plan is for. Remembered per target (campaign memory); the weekly brief and standing orders re-run it.

max_per_domaininteger

Ten links from one site is one relationship.

Response

Held basket.

quote_idstring
quote_tokenstring

Bearer for GET /v1/quotes/{quote_id}?token=… so an approval link can show the plan without a key. Dies with the quote.

view_urlstring uri
target_urlstring nullable
expires_atstring date-time
ttl_seconds14400
bindingtrue

These prices are ours to honour until they lapse, even if the catalogue moves.

strategy'cheapest' | 'fastest' | 'safest' | 'recommended'

The strategy the basket was assembled with, echoed. Every strategy honours the same filters, quality gates, footprint cap and budget. cheapest, fastest and safest change ordering only; recommended in a deployment whose semantic layer runs in rank mode can also reorder placements by a rank-usable judgment, within the explicit demand/leader priorities. No strategy and no judgment removes a placement or an alternative.

requestedinteger
filledinteger
eligibleinteger

Distinct options this brief can buy, before the cap: collapsed domain+placement slots the sourcing read could quote after the filters and, when budgeted, individual affordability. A semantic annotation never removes a slot, so this is the count the deterministic engine would have produced; candidate_coverage holds the pre-semantic counts.

excludedobject

Candidate offers each quality gate removed, keyed by reason (e.g. suspect, restricted, already_linking, bought_for_target). Pre-collapse counts; do not sum with eligible. Every key is a SQL gate: a semantic annotation adds none, because it removes no placement, and the evidence behind a below-threshold judgment is a sampled publisher page rather than the placement actually on offer.

total_creditsinteger

Credits. 1 credit = 1 US cent.

at_median_supplier_creditsinteger

The same basket priced at the median supplier for each domain.

saving_vs_median_creditsinteger

Example response

{
  "lines": [
    {
      "plausibility": {
        "band": "guest_post named DR 50-59"
      }
    }
  ]
}

Changes

No recorded changes to this operation across all 1 revision of this API.