placementapi-com · Schema
Offer
One catalogue row from GET /v1/offers. Supplier identity is intentionally not exposed anywhere in this API. You are buying from us; which upstream marketplace fulfils a placement is not something you need or can act on.
CompanyAISEOMarketingBacklinksAutomationTechnology
Properties
| Name | Type | Description |
|---|---|---|
| offer_id | string | Public offer id. Its prefix is the opaque supplier token accepted by the `supplier` filter. |
| placement_type | object | |
| inventory_mode | object | |
| site_id | stringnull | Canonical domain. Only 'named' inventory carries one. |
| price | object | The BUYER price: the figure debited at order time, so a basket costed from this endpoint will not move at checkout. |
| plausibility | object | |
| demand | object | |
| bulk_breaks | object | Supplier volume breaks, as recorded. |
| link_attrs | object | Link attributes as recorded (e.g. links_per_placement, dofollow). |
| content | object | Raw content facts on the listing (e.g. included, word_count_min, author). Prefer order_requirements.content. |
| guarantees | object | Vendor guarantees on blind/pre_approval tiers (e.g. dr_min, referring_domains_min, traffic_min). |
| metrics | object | |
| turnaround_days_est | integernull | |
| incentive | objectnull | A discount for ordering before the next batch closes. Rewards WHEN you order, never how much; spend caps still apply. |
| order_requirements | object | |
| niches_allowed | array | The supplier's own raw labels. Prefer topics. |
| topics | array | Harmonised subjects. |
| accepts | array | Empty means UNKNOWN, not 'accepts nothing'. |
| geo | object | Country, returned per offer; there is no geo filter on GET /v1/offers, filter client-side. |
| languages | object | |
| publisher_notes | stringnull | |
| observed_at | string | |
| age_hours | number | |
| stale | boolean | |
| stale_after_hours | integer |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/placementapi-com/json-schema/placementapi-com-offer-schema.json",
"title": "Offer",
"description": "One catalogue row from GET /v1/offers. Supplier identity is intentionally not exposed anywhere in this API. You are buying from us; which upstream marketplace fulfils a placement is not something you need or can act on.",
"x-generated": "2026-10-30",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/placementapi-com-openapi.json#/components/schemas/Offer",
"type": "object",
"properties": {
"offer_id": {
"type": "string",
"description": "Public offer id. Its prefix is the opaque supplier token accepted by the `supplier` filter."
},
"placement_type": {
"$ref": "#/$defs/PlacementType"
},
"inventory_mode": {
"$ref": "#/$defs/InventoryMode"
},
"site_id": {
"type": [
"string",
"null"
],
"description": "Canonical domain. Only 'named' inventory carries one."
},
"price": {
"type": "object",
"description": "The BUYER price: the figure debited at order time, so a basket costed from this endpoint will not move at checkout.",
"properties": {
"credits": {
"type": "integer",
"description": "Credits. 1 credit = 1 US cent."
},
"usd_minor": {
"type": "integer",
"description": "The same number in cents, so you never have to convert."
},
"currency": {
"type": "string",
"const": "USD"
},
"as_of": {
"type": "string",
"format": "date-time"
}
}
},
"plausibility": {
"$ref": "#/$defs/Plausibility"
},
"demand": {
"$ref": "#/$defs/Demand"
},
"bulk_breaks": {
"description": "Supplier volume breaks, as recorded."
},
"link_attrs": {
"description": "Link attributes as recorded (e.g. links_per_placement, dofollow)."
},
"content": {
"description": "Raw content facts on the listing (e.g. included, word_count_min, author). Prefer order_requirements.content."
},
"guarantees": {
"description": "Vendor guarantees on blind/pre_approval tiers (e.g. dr_min, referring_domains_min, traffic_min)."
},
"metrics": {
"$ref": "#/$defs/OfferMetrics"
},
"turnaround_days_est": {
"type": [
"integer",
"null"
]
},
"incentive": {
"type": [
"object",
"null"
],
"description": "A discount for ordering before the next batch closes. Rewards WHEN you order, never how much; spend caps still apply.",
"properties": {
"discount_pct": {
"type": "number"
},
"price_with_incentive_credits": {
"type": "integer"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"reason": {
"type": "string"
}
}
},
"order_requirements": {
"$ref": "#/$defs/OrderRequirements"
},
"niches_allowed": {
"type": "array",
"items": {
"type": "string"
},
"description": "The supplier's own raw labels. Prefer topics."
},
"topics": {
"type": "array",
"items": {
"type": "string"
},
"description": "Harmonised subjects."
},
"accepts": {
"type": "array",
"items": {
"type": "string"
},
"description": "Empty means UNKNOWN, not 'accepts nothing'."
},
"geo": {
"description": "Country, returned per offer; there is no geo filter on GET /v1/offers, filter client-side."
},
"languages": {},
"publisher_notes": {
"type": [
"string",
"null"
]
},
"observed_at": {
"type": "string",
"format": "date-time"
},
"age_hours": {
"type": "number"
},
"stale": {
"type": "boolean"
},
"stale_after_hours": {
"type": "integer"
}
},
"$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"
}
}
}
},
"OfferMetrics": {
"type": [
"object",
"null"
],
"description": "What we know about the domain, and who says so. Claimed and measured figures are never merged: where they disagree, the measured one is the one to trust. Null when nothing is known.",
"properties": {
"dr": {
"type": [
"number",
"null"
],
"description": "Supplier-claimed Ahrefs-style score, 0-100; the scale dr_min filters on. On a subdomain this is the PARENT's number."
},
"traffic": {
"type": [
"number",
"null"
],
"description": "Verified traffic where measured, else the claim."
},
"source": {
"type": "string",
"description": "Provenance label for dr/traffic. Measured figures are in the verified_* fields."
},
"verification": {
"$ref": "#/$defs/Verification"
},
"quality_reasons": {
"$ref": "#/$defs/QualityReasons"
},
"subdomain_of": {
"type": [
"string",
"null"
],
"description": "Parent domain when the host is a subdomain (blog.example.com, anything.blogspot.com). A subdomain is listed at its parent's DR and inherits none of it: read verified_dr, verified_referring_domains and verified_traffic, which are this host's own."
},
"restricted": {
"$ref": "#/$defs/Restricted"
},
"outbound_external": {
"type": [
"integer",
"null"
],
"description": "Outside domains linked to (Common Crawl; root sites only)."
},
"inbound_domains": {
"type": [
"integer",
"null"
]
},
"cc_pagerank": {
"type": [
"number",
"null"
]
},
"leader_links": {
"$ref": "#/$defs/LeaderLinks"
},
"survival": {
"$ref": "#/$defs/Survival"
},
"placement_score": {
"$ref": "#/$defs/PlacementScore"
},
"verified_organic_keywords": {
"type": [
"integer",
"null"
],
"description": "OUR independent measurement."
},
"verified_spam_score": {
"type": [
"number",
"null"
]
},
"as_of": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"verified_traffic": {
"type": [
"number",
"null"
],
"description": "Independently measured monthly traffic."
},
"verified_dr": {
"type": [
"number",
"null"
],
"description": "DataForSEO backlinks rank, 0-1000. Deliberately NOT rescaled to look like a DR."
},
"verified_referring_domains": {
"type": [
"integer",
"null"
]
}
}
},
"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."
}
}
},
"QualityReasons": {
"type": "array",
"items": {
"type": "string"
},
"description": "Which rules made verification read suspect: high_authority_no_traffic, high_authority_no_keywords, spam_score, subdomain_without_own_footprint, saturated_outbound. Empty when not suspect."
},
"Restricted": {
"type": "array",
"items": {
"type": "string"
},
"description": "gambling / adult / piracy when the site is one, from the domain name and a short topic list. Such rows appear only when asked for (include_restricted, or a topic/accepts naming the vertical)."
},
"Survival": {
"type": [
"object",
"null"
],
"description": "What happened to the placements WE bought on this publisher. Our crawler re-checks every delivered link at 0/7/30/60/90/180/365 days. Null under three orders.",
"properties": {
"orders": {
"type": "integer"
},
"checks": {
"type": "integer"
},
"live_share": {
"type": "number"
},
"live_90d_share": {
"type": [
"number",
"null"
]
},
"median_days_to_missing": {
"type": [
"number",
"null"
]
},
"dofollow_share": {
"type": [
"number",
"null"
]
},
"noindex_share": {
"type": [
"number",
"null"
]
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"Verification": {
"type": [
"string",
"null"
],
"enum": [
"ok",
"suspect",
"unverified",
null
],
"description": "Our independent verdict on the claimed authority; no supplier publishes it. 'suspect' = high link authority with little or no organic search presence, which is what a link farm looks like — do not plan around suspect domains. 'ok' = measured, and search presence matches the rating. 'unverified' = not measured yet, which is not a pass."
}
}
}
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-offer"
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.