Pinakel · Trademark Analytics API · v1
Integrator Guide
Aggregate trademark analytics — filing trends, Nice-class distribution, owner and representative leaderboards — computed over our worldwide corpus and served as JSON, so you can build your own dashboards without running a warehouse. Base URL:
https://api.pinakelai.com/analytics
Interactive OpenAPI reference: https://api.pinakelai.com/analytics/docs · machine-readable spec: /openapi.json
Also on this host: /data — per-record trademark search, lookup and change tracking, sold and keyed separately.
Authentication
Every request carries your API key in the X-API-Key header
(or as a Bearer token). Keys are scoped per
product: a key sold for analytics returns
403 product_not_enabled on the record API, and vice versa. That
is a provisioning state, not a bad credential — do not rotate the
key; ask us to enable the product.
curl -H "X-API-Key: pk_live_…" \
"https://api.pinakelai.com/analytics/v1/kpis?jurisdiction=US"
Coverage: read this before you render a number
The corpus is being loaded register by register. Every response
carries a coverage block describing exactly what the
figures in it were computed over:
{
"kpis": { … },
"coverage": {
"jurisdiction": "US",
"rows_loaded": 200000,
"backfill_status": "in_progress",
"is_sample": true,
"last_ingested_date": "2026-09-14"
}
}
is_sample is true the figures are
indicative, not exhaustive — that register is a partial load, so
counts are floors and rankings can move as it completes. Surface this in your
UI. It is the one error your users cannot detect for themselves, and the only
thing we ask of anyone reselling these numbers.Live from the warehouse — 98 registers, 4,514,223 records, 98 still sampling. This table is generated per-request and never overstates.
| register | records | backfill | basis |
|---|---|---|---|
| AD | 49,134 | in_progress | sample |
| AE | 0 | not_started | sample |
| AL | 26,801 | in_progress | sample |
| AM | 47,582 | in_progress | sample |
| AP | 8,335 | in_progress | sample |
| AR | 50,000 | in_progress | sample |
| AT | 50,000 | in_progress | sample |
| AU | 50,000 | in_progress | sample |
| BA | 31,003 | in_progress | sample |
| BG | 50,000 | in_progress | sample |
| BH | 50,000 | in_progress | sample |
| BN | 50,000 | in_progress | sample |
| BO | 0 | not_started | sample |
| BQ | 7,727 | in_progress | sample |
| BR | 50,000 | in_progress | sample |
| BT | 24,447 | in_progress | sample |
| BX | 50,000 | in_progress | sample |
| BY | 50,000 | in_progress | sample |
| CA | 50,000 | in_progress | sample |
| CH | 50,000 | in_progress | sample |
| CL | 50,000 | in_progress | sample |
| CN | 50,000 | in_progress | sample |
| CO | 50,000 | in_progress | sample |
| CR | 50,000 | in_progress | sample |
| CU | 50,000 | in_progress | sample |
| CY | 50,000 | in_progress | sample |
| CZ | 50,000 | in_progress | sample |
| DE | 50,000 | in_progress | sample |
| DK | 50,000 | in_progress | sample |
| DO | 0 | not_started | sample |
| DZ | 50,000 | in_progress | sample |
| EC | 50,000 | in_progress | sample |
| EE | 50,000 | in_progress | sample |
| EG | 0 | not_started | sample |
| EM | 50,000 | in_progress | sample |
| ES | 50,000 | in_progress | sample |
| FI | 50,000 | in_progress | sample |
| FR | 50,000 | in_progress | sample |
| GB | 100,000 | in_progress | sample |
| GE | 50,000 | in_progress | sample |
| HK | 50,000 | in_progress | sample |
| HR | 50,000 | in_progress | sample |
| HU | 50,000 | in_progress | sample |
| ID | 50,000 | in_progress | sample |
| IE | 50,000 | in_progress | sample |
| IL | 50,000 | in_progress | sample |
| IN | 50,000 | in_progress | sample |
| IS | 50,000 | in_progress | sample |
| IT | 100,000 | in_progress | sample |
| JO | 50,000 | in_progress | sample |
| JP | 100,000 | in_progress | sample |
| KH | 50,000 | in_progress | sample |
| KR | 50,000 | in_progress | sample |
| KW | 0 | not_started | sample |
| LA | 50,000 | in_progress | sample |
| LT | 50,000 | in_progress | sample |
| LV | 50,000 | in_progress | sample |
| LY | 28,552 | in_progress | sample |
| MD | 50,000 | in_progress | sample |
| ME | 19,645 | in_progress | sample |
| MK | 42,852 | in_progress | sample |
| MM | 20,213 | in_progress | sample |
| MN | 50,000 | in_progress | sample |
| MO | 50,000 | in_progress | sample |
| MX | 50,000 | in_progress | sample |
| MY | 50,000 | in_progress | sample |
| NO | 50,000 | in_progress | sample |
| NZ | 50,000 | in_progress | sample |
| OA | 50,000 | in_progress | sample |
| PA | 50,000 | in_progress | sample |
| PG | 38,465 | in_progress | sample |
| PH | 50,000 | in_progress | sample |
| PL | 50,000 | in_progress | sample |
| PT | 50,000 | in_progress | sample |
| RO | 50,000 | in_progress | sample |
| RS | 0 | not_started | sample |
| RU | 50,000 | in_progress | sample |
| SA | 50,000 | in_progress | sample |
| SD | 44,463 | in_progress | sample |
| SE | 50,000 | in_progress | sample |
| SG | 50,000 | in_progress | sample |
| SI | 50,000 | in_progress | sample |
| SK | 50,000 | in_progress | sample |
| SM | 4,746 | in_progress | sample |
| SX | 14,751 | in_progress | sample |
| TH | 50,000 | in_progress | sample |
| TR | 50,000 | in_progress | sample |
| TT | 50,000 | in_progress | sample |
| TW | 100,000 | in_progress | sample |
| UA | 50,000 | in_progress | sample |
| UG | 50,000 | in_progress | sample |
| US | 200,000 | in_progress | sample |
| UY | 50,000 | in_progress | sample |
| VN | 50,000 | in_progress | sample |
| WO | 50,000 | in_progress | sample |
| WS | 10,756 | in_progress | sample |
| XK | 44,751 | in_progress | sample |
| ZA | 0 | not_started | sample |
Endpoints
All eight take an optional jurisdiction (a 2–4 letter
register code, e.g. US); omit it for every register combined.
Leaderboards take limit (1–500). Responses are an envelope:
{"items": […], "coverage": {…}}.
GET/v1/jurisdictions
Every register we hold analytics for, with counts and year range. The machine-readable coverage table — poll it to discover what is available as the corpus loads.
GET/v1/kpis
Headline totals for a register or the whole corpus: records, live vs dead, distinct owners, registration rate.
GET/v1/filings-by-year
Filing volume per year, split live vs dead. Optional
year_from / year_to (1800–2100).
GET/v1/nice-classes
Distribution of filings across the 45 Nice classes.
GET/v1/top-owners
Largest filers by volume, with their live ratio. limit
defaults to 50.
GET/v1/law-firms
Representative leaderboard: volume, success rate, median days to
registration, distinct clients. limit defaults to 100.
GET/v1/squatting
Owners matching the squatting heuristic — high volume, low registration rate, filings scattered across unrelated classes. A signal to investigate, not a determination.
GET/v1/collateral
Owners with security interests recorded against their marks.
GET/v1/usage
Your key's own month-to-date call count, quota and rate limit, broken down per product, so you can watch consumption without asking us.
Errors & limits
Every non-2xx response carries one envelope:
{"error": {"code": "…", "message": "…", "param": "…"}} —
code is the machine-readable contract, param names
the offending parameter when one exists.
| status | code | meaning |
|---|---|---|
| 400 | invalid_parameter | malformed request — the message says exactly what to fix |
| 401 | unauthorized | missing or unknown API key |
| 403 | key_revoked | revoked key |
| 403 | product_not_enabled | valid key, but it was not sold analytics — do not rotate the key, ask us to enable it |
| 404 | not_found | no such path — check the /analytics prefix |
| 422 | query_too_broad | the query would scan more data than the endpoint allows — narrow it with a jurisdiction filter (do not blind-retry) |
| 429 | rate_limited · quota_exceeded | per-minute rate or monthly quota — see headers |
| 503 | unavailable | transient service problem — safe to retry shortly |
A rate-limit 429 carries Retry-After and
X-RateLimit-Limit / X-RateLimit-Remaining; a quota 429 carries
X-Quota-Limit / X-Quota-Used (resets at month end). Requests
refused with 429 are never counted against your usage.
coverage.last_ingested_date tells you
how current a register's numbers are.Support
Integration questions: support@pinakelai.com · commercial: hello@pinakelai.com