---
title: "Report placements bought anywhere"
method: POST
path: "/v1/observations/purchases"
tags: ["Research"]
---

# Report placements bought anywhere

`POST /v1/observations/purchases`

## Request

- Base URL: `https://api.placementapi.com`
- URL: `https://api.placementapi.com/v1/observations/purchases`
- Auth: none required

Open to all; rate limited per address (5,000 rows/hour). Send your API key to be counted as a distinct buyer; anonymous reports are stored but count as one buyer per sending address. Feeds demand and niche taste, read only in aggregate behind a three-buyer floor. Anchor text is never stored, only its type; a buyer_ref that looks like an email is hashed; duplicates within 30 days are one observation. Nothing sent here is returned to another caller.

## Request body

- object
  - `buyer_ref` string, required
  - `target_domain` string, required
  - `target_url` string, uri, nullable
  - `target_topics` string[], nullable
  - `target_category` string, nullable
  - `rows` object[], required
    - `placement_domain` string, required
    - `placement_type` 'guest_post' | 'niche_edit' | 'link_insert' | 'homepage_link' | 'media_placement' | 'null', nullable
    - `price_paid_credits` integer, nullable
    - `vendor_label` string, nullable
    - `anchor_type` string, nullable
    - `purchased_at` string, nullable
    - `raw` unknown

## Response `201`

OK

- object
  - `accepted` integer
  - `enriched` integer
  - `not_carried` integer
  - `duplicates` integer
  - `rejected` unknown[]
    - unknown

## Other responses

- `400`: `bad_request`, or nothing accepted (same counts body).
- `429`: Rate limited. 1,000 requests and 20,000 returned rows per key per hour, a monthly row entitlement that grows with credits purchased, and a maximum offset of 10,000. Carries `Retry-After` and `X-RateLimit-*` / `X-Quota-Rows-*` headers.
- `503`: `server_misconfigured` when the store is not configured; `upstream_unfunded` when the measurement provider's prepaid balance is exhausted (fresh profiles, gap maps and SERPs pause; cached results and catalogue are unaffected); `upstream_unavailable` on a provider error; `payments_unavailable` when card payments are not configured.

---

[API](https://skmtc.dev/placementapi/apis/placement-api.md) · [All operations](https://skmtc.dev/placementapi/apis/placement-api/llms.txt) · [OpenAPI document](https://skmtc.dev/placementapi/apis/placement-api/revisions/fc4e7866eaf7?raw)
