placementapi-com · Schema
Quote
A costed, HELD basket. Nothing is reserved and nothing is charged until you order, so quoting is free. Prices are held for ttl_seconds (4 hours).
CompanyAISEOMarketingBacklinksAutomationTechnology
Properties
| Name | Type | Description |
|---|---|---|
| quote_id | string | |
| quote_token | string | Bearer for GET /v1/quotes/{quote_id}?token=… so an approval link can show the plan without a key. Dies with the quote. |
| view_url | string | |
| target_url | stringnull | |
| expires_at | string | |
| ttl_seconds | integer | |
| binding | boolean | These prices are ours to honour until they lapse, even if the catalogue moves. |
| strategy | string | 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; `recommen |
| requested | integer | |
| filled | integer | |
| eligible | integer | 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 annotatio |
| candidate_coverage | object | How much of the eligible catalogue the candidate query looked at, from the same snapshot as the lines. Discovery and sourcing counts, taken before any semantic policy runs: a semantic annotation chang |
| decision | objectnull | Aggregate semantic-annotation coverage for this basket. Present only when the request carried customer context, at least one placement was affordable, and a semantic service was reachable — absent oth |
| excluded | object | 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 se |
| total_credits | integer | Credits. 1 credit = 1 US cent. |
| at_median_supplier_credits | integer | The same basket priced at the median supplier for each domain. |
| saving_vs_median_credits | integer | |
| funding | objectnull | |
| lines | array | |
| profile_hint | object | Only when exclude_domains_linking_to was given: the target's profile bands beside the basket's. |
| next | object |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/placementapi-com/json-schema/placementapi-com-quote-schema.json",
"title": "Quote",
"description": "A costed, HELD basket. Nothing is reserved and nothing is charged until you order, so quoting is free. Prices are held for ttl_seconds (4 hours).",
"x-generated": "2026-10-30",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/placementapi-com-openapi.json#/components/schemas/Quote",
"type": "object",
"properties": {
"quote_id": {
"type": "string"
},
"quote_token": {
"type": "string",
"description": "Bearer for GET /v1/quotes/{quote_id}?token=… so an approval link can show the plan without a key. Dies with the quote."
},
"view_url": {
"type": "string",
"format": "uri"
},
"target_url": {
"type": [
"string",
"null"
]
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"ttl_seconds": {
"type": "integer",
"const": 14400
},
"binding": {
"type": "boolean",
"const": true,
"description": "These prices are ours to honour until they lapse, even if the catalogue moves."
},
"strategy": {
"type": "string",
"enum": [
"cheapest",
"fastest",
"safest",
"recommended"
],
"description": "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."
},
"requested": {
"type": "integer"
},
"filled": {
"type": "integer"
},
"eligible": {
"type": "integer",
"description": "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."
},
"candidate_coverage": {
"type": "object",
"description": "How much of the eligible catalogue the candidate query looked at, from the same snapshot as the lines. Discovery and sourcing counts, taken before any semantic policy runs: a semantic annotation changes neither `eligible` nor these counts, because it removes nothing. `eligible` above counts collapsed domain+placement slots; this counts candidate OFFERS before the collapse, so it is the field that shows whether the 4,000-offer retrieval cap bound the result. eligible_offers equal to retrieved_offers means every matching offer was ranked; a larger eligible_offers with truncated true means the basket was chosen from the first 4,000 in the brief's requested priority (demand, leaders, then fastest/safest/cheapest/recommended, with raw price and offer id as the deterministic tiebreak). Raw-price retrieval is an approximation of the final buyer-credit sort, and budget fill can end a basket before the cap matters, so truncated false is not a promise that the basket is globally optimal. `sourced_offers` and the fields beside it describe the second, bound read: the sourcing expansion re-reads every eligible seller of each chosen placement, so the winner per placement is chosen from the whole supplier set rather than from the retrieval cut, and a placement is either sourced whole or not at all. Aggregate counts only.",
"properties": {
"eligible_offers": {
"type": "integer",
"description": "Offers matching eligibility and, when budgeted, individual affordability, before the 4,000-offer cap and before any semantic policy. Exclusion counts retain their original filter-only basis."
},
"retrieved_offers": {
"type": "integer",
"description": "Offers the candidate query returned. Equals eligible_offers unless truncated."
},
"limit": {
"type": "integer",
"description": "The retrieval cap, in offers. 4000."
},
"truncated": {
"type": "boolean",
"description": "eligible_offers exceeded the cap, so selection saw a subset of what matched."
},
"sourced_offers": {
"type": "integer",
"description": "Offers the sourcing expansion returned for the chosen placements. Equal to retrieved_offers when the retrieved rows already carried every seller of every placement; larger when the cut had kept a dearer seller and left a cheaper one outside it."
},
"sourcing_limit": {
"type": "integer",
"description": "The sourcing cap, in offers. 40000."
},
"sourcing_truncated": {
"type": "boolean",
"description": "The expansion did not answer for every chosen placement, so fewer placements were quotable than retrieval found. Never means a placement was priced from a partial supplier set."
},
"dropped_slots": {
"type": "integer",
"description": "Chosen placements the expansion did not return, and so did not quote. Placements, not offers; zero unless sourcing_truncated."
}
}
},
"decision": {
"type": [
"object",
"null"
],
"description": "Aggregate semantic-annotation coverage for this basket. Present only when the request carried customer context, at least one placement was affordable, and a semantic service was reachable — absent otherwise, which is not the same as 'judged and found nothing'. `mode` is the service's mode (off | shadow | rank) or `unavailable` when it was configured for the deployment but could not be built or failed; `status` is the service's own coverage status, or `unavailable` for that same failure. `rank` is the only mode that can change a `recommended` basket, and only in that strategy: a rank-usable annotation may reorder it within the explicit demand/leader priorities, and no judgment — below threshold, unjudged, missing, invalid or failed — removes anything. `shadow` annotates only, and `cheapest`, `fastest` and `safest` are unchanged. The service judges a sampled publisher page resolved by site id, not the offered placement, so no judgment is a verdict on whether to buy a slot. Topical fit is a semantic judgment on the service's own scale, NOT a probability of SEO impact, and it never affects price. Aggregate counts only — no customer ids, provider state or evidence text.",
"properties": {
"mode": {
"type": "string",
"enum": [
"off",
"shadow",
"rank",
"unavailable"
]
},
"status": {
"type": "string",
"enum": [
"ok",
"degraded",
"insufficient_evidence",
"invalid_config",
"unavailable"
]
},
"coverage": {
"type": "object",
"description": "How much of the semantic layer's candidate input was judged for this basket. `total_candidates` is the raw input length, `eligible_candidates` every valid eligible unique candidate id before the page service's own cap, and `selected_candidates` the BOUNDED page-semantic shortlist the service actually selected after its site-diverse fan-out and `maxCandidates` cap — the three are separately meaningful and only ever get smaller in that order, so on a wide brief `eligible_candidates` is larger than the bounded shortlist. Every selected candidate ends in exactly one of `evaluated`, `missing_evidence`, `invalid_evidence` or `runtime_failed`, so those four always sum to `selected_candidates`; a missing, failed or refused reading is never counted as a judgment, and an unselected eligible candidate is counted by none of them. Aggregate counts only.",
"properties": {
"total_candidates": {
"type": "integer",
"description": "The raw candidate input length, before validation, deduplication or any cap."
},
"eligible_candidates": {
"type": "integer",
"description": "Every valid eligible unique candidate id, before the page service's own cap. This is the FULL eligible input set, not the bounded semantic shortlist, and it can exceed `selected_candidates`."
},
"selected_candidates": {
"type": "integer",
"description": "The bounded page-semantic shortlist: the valid eligible unique candidates the service actually selected after its site-diverse fan-out and `maxCandidates` cap. Additive, and the only bounded shortlist denominator: `evaluated + missing_evidence + invalid_evidence + runtime_failed` always equals it."
},
"evaluated": {
"type": "integer"
},
"policy_usable": {
"type": "integer"
},
"missing_evidence": {
"type": "integer"
},
"invalid_evidence": {
"type": "integer"
},
"runtime_failed": {
"type": "integer"
}
}
},
"identity_coverage": {
"type": "object",
"description": "Additive, aggregate-only publisher-identity routing coverage. It answers a second question beside `coverage`, which keeps its own counts and status untouched: when this basket's page layer had no sampled page evidence for a candidate, did the durable publisher identity still settle a requested topic? `status` is `supported` when the routing preference was in force (a `recommended` brief whose confirmed mode was `rank`) and its one bounded identity read answered — which includes a successful empty read, reported as `supported` with zero counts, never as a failure; `unavailable` when that read did not answer or the page service failed so no shortlist exists; and `not_applicable` when no routing preference applied at all (no configured preference, another strategy, no recognized requested topic, or `off`/`shadow`, which annotate only). Counts are `missing_evidence` candidates only: a candidate counts here only when its own page annotation status was exactly `no_evidence` AND its site held a fresh supported primary-identity match for a requested topic, so refused or failed readings (`invalid_evidence`, `unavailable`, `timeout`, runtime failures) are never covered and `coverage.missing_evidence` is never reduced. Every count is over the page service's own bounded SELECTED shortlist — the bounded page-semantic set the service chose out of the full eligible input, so `shortlist_candidates` equals `coverage.selected_candidates` and never `coverage.eligible_candidates` — and `shortlist_candidates` is the annotated part of it — the candidates that came back with an explicit annotation, `no_evidence` included — so it is not a count of candidates the semantics evaluated. Aggregate counts and a fixed status only: no site ids, topics, facets, evidence ids, excerpts, provider payload or confidence values.",
"properties": {
"status": {
"type": "string",
"enum": [
"supported",
"unavailable",
"not_applicable"
]
},
"shortlist_candidates": {
"type": "integer",
"description": "The page service's own bounded shortlist of SELECTED candidates — the candidates it selected and returned an explicit annotation for, including `no_evidence` (the page policy's \"not measured\" reading, not a judgment). For a service that annotates exactly what it selected this is the same set `coverage.selected_candidates` counts, and never `coverage.eligible_candidates`, which is the larger full eligible input before the service's own cap. Not a count of candidates the semantics evaluated; every other count here is a subset of this one."
},
"missing_page_evidence": {
"type": "integer",
"description": "That subset whose page annotation status was exactly `no_evidence`. Same number as `coverage.missing_evidence` when the aggregate is `supported`."
},
"supported_identity_missing_page_evidence": {
"type": "integer",
"description": "The subset of `missing_page_evidence` whose site also held a fresh supported primary-identity match for one of the brief's requested topics. A routing coverage gate passes a degraded page decision only when this equals `missing_evidence`."
}
}
},
"publisher_context_coverage": {
"type": "object",
"description": "Additive, aggregate-only projected publisher-context coverage. It answers a second, separate question beside `coverage` and `identity_coverage`, both of which keep their own counts and statuses untouched: when this basket's page layer had no sampled page evidence for a candidate, did the publisher context the request's OWN route projection supplied cover it? `status` is `supported` only for the frame in which those projected facts were in force — a `recommended` brief whose confirmed mode was `rank`, whose route attempt answered from a structurally valid `state_usable` payload, with the identity composition present and a recognized requested topic; `unavailable` when that frame was in force and the page service answered but the route projection did not supply the context facts (the attempt was not state-usable, so the exact predicates ran); and `not_applicable` when no such frame applied (another strategy, `off`/`shadow`, no identity composition, or no recognized requested topic). Counts describe one annotated shortlist — the page service's own bounded selected shortlist, the set `coverage.selected_candidates` counts, never the larger full eligible input `coverage.eligible_candidates` — and may overlap; they are never summed into a score. `missing_page_evidence` is the page policy's own not-measured reading, and `context_supported_missing_page_evidence` is the SUBSET of `missing_page_evidence` whose candidate site is `context_classified` OR qualifies as exceptional independent authority — the covered part of the page gap, never the page gap itself. A positive primary or prominent match is NOT required for coverage: a classified non-match remains classified, and a publisher whose independent authority clears this catalogue's measured cut-offs covers a missing page reading without any category designation. A refused or failed reading (`invalid_evidence`, `runtime_failed`, `unavailable`, `timeout`) is never covered, a malformed or refusable route attempt is never covered, and `coverage.missing_evidence` is never reduced. Routing completeness requires this covered-subset count to equal `missing_page_evidence`, so a page gap that is only partly covered is not routing-complete. Aggregate counts and a fixed status only: no site ids, topics, facets, evidence ids, excerpts, URLs, provider payload or confidence values.",
"properties": {
"status": {
"type": "string",
"enum": [
"supported",
"unavailable",
"not_applicable"
]
},
"shortlist_candidates": {
"type": "integer",
"description": "The page service's own bounded shortlist of SELECTED candidates — the candidates it selected and returned an explicit annotation for, including `no_evidence` (the page policy's \"not measured\" reading, not a judgment). The routing gate requires it to equal `coverage.selected_candidates`, and it is never `coverage.eligible_candidates`, which is the larger full eligible input before the service's own cap. Not a count of candidates the semantics evaluated; every other count here is a subset of this one."
},
"context_classified": {
"type": "integer",
"description": "That subset whose site the projection reports as classified at all. Coverage only: it is not a positive topic match, a preference, a score or an eligibility term."
},
"primary_topic_matches": {
"type": "integer",
"description": "That subset whose site held a supported requested primary-identity match. Reported beside the other bases and never required for coverage; counts may overlap."
},
"prominent_profile_matches": {
"type": "integer",
"description": "That subset whose site held a requested PROMINENT sampled profile topic — a sampled publisher URL distribution over publisher-supplied sitemap metadata, not a primary identity. Reported, never required for coverage; counts may overlap."
},
"exceptional_authority": {
"type": "integer",
"description": "That subset whose root domain the existing independent-authority reading qualifies (measured quality `ok`, fresh independent traffic and Common Crawl PageRank at or above this catalogue's measured cut-offs, nothing from a seller's own claims). Reach is not editorial relevance and claims no SEO impact."
},
"missing_page_evidence": {
"type": "integer",
"description": "That subset whose page annotation status was exactly `no_evidence`. Same number as `coverage.missing_evidence` when the aggregate is `supported`."
},
"context_supported_missing_page_evidence": {
"type": "integer",
"description": "The SUBSET of `missing_page_evidence` whose candidate site is `context_classified` OR qualifies as exceptional independent authority — the covered part of the page gap, never the page gap itself. Classification is coverage, not a requested-topic match, so a positive primary or prominent match is not required for a candidate to be counted here, and a challenged reading (`invalid_evidence`, `runtime_failed`, `unavailable`, `timeout`) is never covered. Routing completeness requires this covered-subset count to equal `missing_page_evidence`: a page gap covered only in part is not routing-complete."
}
}
}
}
},
"excluded": {
"type": "object",
"additionalProperties": {
"type": "integer"
},
"description": "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_credits": {
"type": "integer",
"description": "Credits. 1 credit = 1 US cent."
},
"at_median_supplier_credits": {
"type": "integer",
"description": "The same basket priced at the median supplier for each domain."
},
"saving_vs_median_credits": {
"type": "integer"
},
"funding": {
"type": [
"object",
"null"
],
"properties": {
"balance_credits": {
"type": "integer"
},
"sufficient": {
"type": "boolean"
},
"shortfall_credits": {
"type": "integer"
}
}
},
"lines": {
"type": "array",
"items": {
"$ref": "#/$defs/QuoteLine"
}
},
"profile_hint": {
"type": "object",
"description": "Only when exclude_domains_linking_to was given: the target's profile bands beside the basket's.",
"properties": {
"target_domain": {
"type": "string"
},
"referring_domains_fetched": {
"type": "integer"
},
"profile_rank_bands_share": {
"type": "object"
},
"profile_rank_bands_basis": {
"type": "string"
},
"carried_referring_domains": {
"type": "integer"
},
"profile_dr_bands_share": {
"type": "object"
},
"profile_dr_bands_basis": {
"type": "string"
},
"profile_heaviest_dr_band": {},
"basket_dr_bands": {
"type": "object"
},
"dr_band_suggested": {}
}
},
"next": {
"type": "object",
"properties": {
"order": {
"type": "string"
},
"note": {
"type": "string"
}
}
}
},
"$defs": {
"ContentOption": {
"type": "object",
"description": "A writing tier purchasable with the placement. Tiers are normalised across every supplier: 'supplied' = you provide the copy; 'included' = writing is in the price; 'standard' = purchasable, AI-drafted and human-edited; 'native' = purchasable, native expert writer; 'papi_written' = Placement Papi drafts to the spec for a flat 1,500 credits charged with the order, buyer approves before it goes out.",
"properties": {
"tier": {
"type": "string",
"enum": [
"supplied",
"included",
"standard",
"native",
"papi_written"
]
},
"vendor_label": {
"type": [
"string",
"null"
],
"description": "Pass as content_tier for content_mode 'service'."
},
"price_credits": {
"type": "integer",
"description": "Add-on cost. Credits. 1 credit = 1 US cent."
},
"word_count": {
"type": [
"integer",
"null"
]
},
"note": {
"type": [
"string",
"null"
]
}
}
},
"ContentSpec": {
"type": [
"object",
"null"
],
"description": "The brief to write against when the buyer supplies copy. Null when copy cannot be supplied.",
"properties": {
"word_count_min": {
"type": [
"integer",
"null"
]
},
"word_count_max": {
"type": [
"integer",
"null"
]
},
"links_allowed": {
"type": "integer"
},
"anchor_types_forbidden": {
"type": "array",
"items": {
"type": "string"
}
},
"rules": {
"type": "array",
"items": {
"type": "string"
},
"description": "Editorial rules in the publisher's own words."
}
}
},
"Demand": {
"type": [
"object",
"null"
],
"description": "Observed demand: distinct buyers who bought the domain in twelve months and the niches they bought for. Null under the three-buyer floor. Nothing about any one buyer is ever here.",
"properties": {
"buyers_12m": {
"type": "integer"
},
"purchases_12m": {
"type": "integer"
},
"niches": {
"type": "array",
"items": {
"type": "object",
"properties": {
"topic": {
"type": "string"
},
"buyers": {
"type": "integer"
}
}
}
}
}
},
"InventoryMode": {
"type": "string",
"enum": [
"named",
"pre_approval",
"blind"
],
"description": "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."
},
"LeaderLinks": {
"type": [
"object",
"null"
],
"description": "Common Crawl web graph, root sites only (null on subdomains): how many of a topic's top-ranking sites the domain links to, keyed by topic.",
"additionalProperties": {
"type": "object",
"properties": {
"linked": {
"type": "integer"
},
"of": {
"type": "integer"
}
}
}
},
"MarketReference": {
"type": [
"object",
"null"
],
"description": "The median ASK of comparable placements (same type, inventory mode and claimed-DR decade), not a clearing price — say 'market reference', never 'fair value'. own_asks is the spread of asks across suppliers for this exact domain and type, as counts and credits only. ask_history is null under 14 days of observations. Null on a thin band.",
"properties": {
"reference_credits": {
"type": "integer"
},
"method": {
"type": "string",
"const": "band_median_v1"
},
"comparables_n": {
"type": "integer"
},
"vs_reference_pct": {
"type": "number",
"description": "This price against the reference, in percent; negative is cheaper."
},
"assessment": {
"type": "string",
"enum": [
"under",
"at",
"over"
],
"description": "±15% band around the reference."
},
"own_asks": {
"type": "object",
"properties": {
"listings": {
"type": "integer"
},
"suppliers": {
"type": "integer"
},
"lowest": {
"type": "integer"
},
"median": {
"type": "integer"
},
"highest": {
"type": "integer"
}
}
},
"ask_history": {
"type": [
"object",
"null"
],
"properties": {
"first_seen_at": {
"type": "string",
"format": "date-time"
},
"days_observed": {
"type": "integer"
},
"first_credits": {
"type": "integer"
},
"change_pct": {
"type": "number"
}
}
}
}
},
"OrderRequirements": {
"type": [
"object",
"null"
],
"description": "What you MUST send, what you MAY send, and what you can buy, normalised across suppliers. `required` lists the fields to include in POST /v1/orders. Read `confidence`: 'observed' and 'documented' are reliable; 'assumed' means the confirmation step may ask for something not listed.",
"properties": {
"required": {
"type": "array",
"items": {
"type": "string"
},
"description": "Always includes target_url; anchor_text is absent only where the publisher writes the anchor."
},
"optional": {
"type": "array",
"items": {
"type": "string"
}
},
"content": {
"type": "object",
"properties": {
"supplied_allowed": {
"type": "boolean",
"description": "Whether you may write the article yourself."
},
"spec": {
"$ref": "#/$defs/ContentSpec"
},
"options": {
"type": "array",
"items": {
"$ref": "#/$defs/ContentOption"
}
},
"due_days": {
"type": [
"integer",
"null"
],
"description": "Days a supplied article may take to arrive after ordering (14); null where the publisher writes."
}
}
},
"speed": {
"type": "object",
"properties": {
"standard_days": {
"type": [
"integer",
"null"
]
},
"expedited_days": {
"type": [
"integer",
"null"
]
},
"expedited_surcharge_bps": {
"type": [
"integer",
"null"
]
}
}
},
"confirmation_required": {
"type": "boolean",
"description": "True when a human at the supplier confirms the line before it is placed; treat the order as pending rather than done."
},
"rules": {
"type": "array",
"items": {
"type": "string"
},
"description": "Placement rules the buyer must respect regardless of who writes the copy."
},
"confidence": {
"type": "string",
"enum": [
"observed",
"documented",
"assumed"
]
}
}
},
"PlacementScore": {
"type": [
"object",
"null"
],
"description": "Placement Score v1: { score 0-100, version, confidence high|medium|low, components each 0-100 or null, capped }. Weights (authority 25 / visibility 25 / quality 30 / graph 10 / survival 10) are stated, not fitted; unmeasured components drop out and the rest re-weight; a suspect publisher never scores above 40. Derived from the fields beside it, so it can be checked. Does NOT include observed effectiveness, relevance to your brief, or supplier reliability. Quote the components, not just the number.",
"properties": {
"score": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"version": {
"type": "string"
},
"confidence": {
"type": "string",
"enum": [
"high",
"medium",
"low"
],
"description": "Share of the weight that had a measurement behind it."
},
"components": {
"type": "object",
"properties": {
"authority": {
"type": [
"number",
"null"
]
},
"visibility": {
"type": [
"number",
"null"
]
},
"quality": {
"type": [
"number",
"null"
]
},
"graph": {
"type": [
"number",
"null"
]
},
"survival": {
"type": [
"number",
"null"
]
}
}
},
"capped": {
"type": [
"string",
"null"
],
"enum": [
"suspect",
null
]
}
}
},
"PlacementType": {
"type": "string",
"enum": [
"guest_post",
"niche_edit",
"link_insert",
"homepage_link",
"media_placement"
]
},
"Plausibility": {
"type": [
"object",
"null"
],
"description": "Where this price sits among comparable domains (same placement type, inventory mode and claimed-DR decade). flag 'low' = under the 10th percentile, which is bought authority more often than it is a bargain; 'high' = above the 90th. Null when the band had too few domains to describe.",
"properties": {
"pct": {
"type": "number",
"minimum": 0,
"maximum": 100
},
"band": {
"type": "string"
},
"flag": {
"type": "string",
"enum": [
"low",
"ok",
"high"
]
},
"n": {
"type": "integer",
"description": "Domains behind the distribution."
# --- truncated at 32 KB (41 KB total) ---
# Full source: https://artifacts.apis.io/placementapi-com/json-schema/placementapi-com-quote-schema.json
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/placementapi-com-quote"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.