Creative ranking
How much each creative sold in the period, with campaign spend and measured traffic. It is the join the gateway alone cannot make: it knows a sale happened, not which ad produced it.
Parameters
| Parameter | Type | Default |
|---|---|---|
from | YYYY-MM-DD | 30 days ago |
to | YYYY-MM-DD | today |
limit | 1–100 | 20 |
convertTo | ISO-4217 | — |
convertTo works as on the other endpoints: a three-letter ISO-4217 code (BRL, USD, EUR), each sale own day rate, all or nothing — if a day rate is missing the ranking comes back split by currency and conversion is null, which never means rate 1.
Example
curl "https://public-api.passkey.global/v1/creatives/ranking?from=2026-08-01&to=2026-08-31&limit=20" \
-H "Authorization: Bearer passkey_prd_..."{
"from": "2026-08-01",
"to": "2026-08-31",
"creatives": [
{
"contentId": "A7K2M9P4",
"name": "Video1",
"fileName": "criativo-agosto-01.mp4",
"currency": "BRL",
"revenueCents": 890000,
"salesCount": 31,
"landingClicks": 4820,
"checkoutClicks": 612,
"landingVisitors": 3970,
"checkoutVisitors": 548,
"previousPosition": 4,
"campaigns": [
{
"platformCampaignId": "1800000000000000",
"campaignName": "AGO — Catálogo",
"advertiserId": "7291845003219",
"salesCount": 31,
"revenueCents": 890000,
"spendCents": 214000,
"impressions": 182400,
"clicks": 5100,
"ctr": 2.79,
"currency": "BRL"
}
]
}
],
"conversion": null,
"platformMetrics": {
"collectedAt": "2026-09-17T11:42:00.000Z",
"status": "fresh",
"nextAttemptInSeconds": 620
}
}Platform metrics
spendCents, impressions, clicks and ctr are not measured by us: they come from TikTok and Meta. The platformMetrics block says when they were last fetched.
| Field | What it says |
|---|---|
collectedAt | when the most outdated platform was last queried. Null = never |
status | fresh, refreshing or never |
nextAttemptInSeconds | how long until a read can schedule the next refresh |
status: "never" is not a wait: it is an ad account that has never been collected. Connect it in the dashboard.
Null is not zero
This is the most important convention here, and the one that most changes decisions:
| Null field | Means |
|---|---|
spendCents, impressions, clicks, ctr | not measured: that campaign had no metric collection in the window. Never "spent zero" |
landingClicks, checkoutVisitors… | no measurement: no beacon in the window — script not installed, or no traffic |
previousPosition | the creative did not sell in the previous period (new to the ranking) |
What this endpoint does not return
Workspace name, PassKey campaign name and media type are left out. That is how PassKey organises the work, not what you need to join data: for that, the contentId, the creative name and the original file are enough.
The campaignName inside campaigns[] stays: that one is the campaign name on the platform, the same you see in your ads manager.
Clicks vs. visitors
Two rulers for the same event, side by side on purpose: landingClicks counts page loads, and landingVisitors counts distinct visitors per day.
Measured in production: 18.4% inflation between them, and that is the floor. For funnel and conversion, visitors is the honest ruler; clicks is for raw volume.
One creative, several campaigns
The campaigns array breaks the result down by platform campaign, and platformCampaignId is the TikTok/Meta id — the key you use to join with your own ad account reports.
spendCents is the whole campaign spend, not this creative share. The platform does not report spend per creative: if the campaign runs ten creatives, the same value shows on all ten. Group by platformCampaignId before dividing.