Lifecycle of one ad creative
The whole trail of a single creative on this domain: when it was first and last observed, how many days it spanned, whether it is still running, the longest gap inside its life, its day-by-day observations, and the models and prompts that rendered it. Unbounded by any date range — the creative reports its real life. `globalFirstSeenAt`/`globalLastSeenAt` widen that to every organization that ever saw the same creative. Note that identity is a content fingerprint: rotating the copy, image or landing path mints a NEW creative, so this is the life of a creative variant, not of a campaign.
AuthorizationBearer <token>Session JWT signed with HS256. Verification pins the algorithm and rejects expired tokens, per RFC8725.
domainId*stringDomain under analysis
adKey*stringCreative fingerprint from the creatives endpoint: 40 lower-case hex characters. Anything else is rejected with a 400 rather than queried.
activeWithinDays?numberDays since the last observation within which the creative still counts as running. Measured from now, since this endpoint reports the creative's whole life rather than a window.
1 <= value <= 903promptLimit?numberHow many prompts to return in the per-prompt breakdown
1 <= value <= 10020Creative lifecycle
application/json- response
observedFirstSeenAt?stringFirst time this creative was ever observed on this domain, ignoring the requested window. Present on every returned creative — the lifetime is measured over the same rows the creative came from, so it cannot be missing; the field is optional only because it reaches the response through an outer join.
date-timeobservedLastSeenAt?stringMost recent observation on this domain, ignoring the requested window. Present on every returned creative, for the same reason as observedFirstSeenAt.
date-timelifespanDays*numberobservedLastSeenAt minus observedFirstSeenAt, in days with two decimals. 0 means every observation fell on one day, which is a sampling floor — an ad seen once cannot be shown to have lived longer, not an ad that retired the same day.
observedDays*numberDistinct UTC days with at least one observation. Read it against lifespanDays to tell a creative that ran continuously from one seen twice, months apart. Always 1 or more on a returned creative — a returned creative is one that was observed, so this never means "unknown".
observedAds*numberAd cards this creative rendered on this domain, over its whole life. Always 1 or more on a returned creative, for the same reason as observedDays.
stillRunning*booleanWhether the creative was still being served at the end of the window — its last observation falls within activeWithinDays. Its lifespan is a lower bound: the campaign has not ended yet.
globalFirstSeenAt?stringFirst observation of this creative anywhere in the fleet, across all organizations. Earlier than observedFirstSeenAt when another customer saw the ad first.
date-timeglobalLastSeenAt?stringMost recent observation of this creative anywhere in the fleet
date-timeadKey*stringCreative fingerprint the trail belongs to
advertiserKey?stringAdvertiser that ran it. Resolved from the registry, falling back to the observation rows. Absent only when the surface reported neither an advertiser URL, nor a landing page host, nor an advertiser name — the creative is then identified by its copy alone.
advertiserName?stringAdvertiser name as rendered
cardType*stringCanonical card kind. Resolved from the registry, falling back to the observation rows, where the column is never null — so this is always populated.
format?stringVendor creative name, verbatim
title?stringHeadline
body?stringBody copy
ctaProductCopy?stringCall-to-action copy
imageUrl?stringCreative image
targetUrl?stringLanding page
longestGapDays*numberLongest run of consecutive days inside the life with no observation. A large gap against a large lifespan means the creative was rotated back in, not served throughout.
daily*array<>Every UTC day the creative was observed, ascending. Unobserved days are absent.
byModel*array<>Models that rendered it
byPrompt*array<>Prompts it was rendered against, most ad cards first
curl -X GET 'https://api.getmint.ai/api/domains/3fa85f64-5717-4562-b3fc-2c963f66afa6/ads/creatives/9f2c1b7a4e6d3805c1aa27b4d9e0f3a6c85b1d47/lifecycle'{ "observedFirstSeenAt": "2026-04-18T06:02:00.000Z", "observedLastSeenAt": "2026-05-25T10:30:00.000Z", "lifespanDays": 37.19, "observedDays": 31, "observedAds": 412, "stillRunning": true, "globalFirstSeenAt": "2026-04-02T11:45:00.000Z", "globalLastSeenAt": "2026-05-25T10:30:00.000Z", "adKey": "9f2c1b7a4e6d3805c1aa27b4d9e0f3a6c85b1d47", "advertiserKey": "nike.com", "advertiserName": "Nike", "cardType": "product_ad", "format": "product_card_v2", "title": "Nike Pegasus 41", "body": "Responsive cushioning for daily miles.", "ctaProductCopy": "Shop now", "imageUrl": "https://nike.com/img/pegasus41.jpg", "targetUrl": "https://nike.com/t/pegasus-41", "longestGapDays": 6, "daily": [ { "date": "2026-05-25", "ads": 14, "executions": 12 } ], "byModel": [ { "key": "gpt-interface", "label": "best running shoes for flat feet", "ads": 96, "executions": 88 } ], "byPrompt": [ { "key": "gpt-interface", "label": "best running shoes for flat feet", "ads": 96, "executions": 88 } ]}