# Provly API Documentation > Full plaintext documentation of the Provly public API and MCP server, meant to be read by LLM agents in one request. Human-friendly version: https://provly.co/docs Provly is a winning-product research platform: ads (Meta/Facebook/Instagram, TikTok, Google/YouTube), advertisers, e-commerce shops, the products they advertise and the marketing emails they send. The Provly API and MCP server give your code and your AI agents the same data. Base URL: `https://provly.co/api/v1` · MCP: `https://provly.co/api/v1/mcp` · OpenAPI: `https://provly.co/api/v1/openapi.json` --- # Quickstart > Make your first request in under a minute. :::steps ### Pick a plan with API access The public API and the MCP server are included in the **Pro** and **Business** plans. [Compare plans](https://provly.co/app/billing). ### Create an API key Open **Provly → Settings → API** and click **Create key**. Copy it right away: the full key is shown only once. [Open API settings](https://provly.co/app?settings=api) ### Call the API Every request sends the key in the `Authorization` header. :::tabs ```bash title="cURL" export PROVLY_API_KEY="pvly_live_…" curl "https://provly.co/api/v1/ads?query=collagen&countries=TR&active=true&min_running_days=30&limit=5" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```js title="JavaScript" const res = await fetch("https://provly.co/api/v1/ads?query=collagen&countries=TR&active=true&min_running_days=30&limit=5", { headers: { Authorization: `Bearer ${process.env.PROVLY_API_KEY}` }, }) const { data, pagination } = await res.json() ``` ```python title="Python" import os, requests res = requests.get( "https://provly.co/api/v1/ads", params={"query": "collagen", "countries": "TR", "active": "true", "min_running_days": 30, "limit": 5}, headers={"Authorization": f"Bearer {os.environ['PROVLY_API_KEY']}"}, ) ads = res.json()["data"] ``` ::: ### Or plug it into your AI assistant Point Claude, ChatGPT or Cursor at the MCP server and ask in plain language. See [MCP server](/docs/mcp). ::: :::tip Ads that are **still active** and have run for **30+ days** are usually profitable: `active=true&min_running_days=30` is the single most useful filter for product research. ::: --- # Authentication > API keys, where to send them and how to keep them safe. Provly authenticates every request with a **workspace API key**. Keys start with `pvly_live_` and belong to a workspace, not to a person: anyone holding one can read your workspace's data and use its rate limit. ## Sending the key ```http title="Header" Authorization: Bearer pvly_live_… ``` `x-api-key: pvly_live_…` is accepted too, for tools that cannot set an Authorization header. ## Managing keys - Create up to **10 active keys** per workspace in [Settings → API](https://provly.co/app?settings=api). - Name keys by where they run (`n8n production`, `Claude Desktop`) so you know which one to revoke. - **Revoke** a key from the same screen; it stops working within 30 seconds. - Only a SHA-256 hash is stored. A lost key cannot be recovered, create a new one. ## Verify a key ```bash curl https://provly.co/api/v1/me -H "Authorization: Bearer $PROVLY_API_KEY" ``` :::warning Never ship a key in browser or mobile code. Call Provly from your server, an automation tool or an MCP client. ::: ## OAuth (MCP connectors) Browser-based agents (ChatGPT connectors, claude.ai) sign in with **OAuth 2.1** instead of a header: authorization code with PKCE, dynamic client registration and refresh tokens. The consent screen lets the user approve with their Provly account or a pasted API key; either way the connection acts as a workspace key. | Endpoint | URL | | -------- | --- | | Authorization server metadata | `https://provly.co/.well-known/oauth-authorization-server` | | Protected resource metadata | `https://provly.co/.well-known/oauth-protected-resource` | | Register | `POST https://provly.co/api/oauth/register` | | Authorize | `https://provly.co/oauth/authorize` | | Token | `POST https://provly.co/api/oauth/token` | Access tokens start with `pvly_oat_` and last one hour; clients refresh them automatically. ## Board and tracker endpoints Boards belong to the user who created the key: `/boards` reads and writes that person's swipe file. Trackers belong to the workspace. --- # Rate limits > Per-plan request limits and the headers that report them. Limits apply **per workspace** and count every request: a REST call and an MCP tool call both count as one. | Plan | Per second | Per minute | Per hour | Per day | | -------- | ---------- | ---------- | -------- | ------- | | Pro | 20 | 120 | 1,200 | 24,000 | | Business | 40 | 250 | 6,000 | 50,000 | ## Response headers | Header | Meaning | | ------ | ------- | | `X-RateLimit-Limit` / `X-RateLimit-Remaining` | The per-minute window | | `X-RateLimit-Daily-Limit` / `X-RateLimit-Daily-Remaining` | The per-day window | | `Retry-After` | On `429`, seconds to wait | | `X-Request-Id` | Quote it when you contact support | `GET /usage` returns every window at once. ## Handling 429 :::tabs ```js title="JavaScript" async function provly(url, init = {}, tries = 3) { const res = await fetch(url, { ...init, headers: { Authorization: `Bearer ${process.env.PROVLY_API_KEY}`, ...init.headers } }) if (res.status === 429 && tries > 0) { await new Promise((r) => setTimeout(r, Number(res.headers.get("retry-after") ?? 1) * 1000)) return provly(url, init, tries - 1) } return res.json() } ``` ```python title="Python" import time, requests def provly(url, tries=3, **kw): res = requests.get(url, headers={"Authorization": f"Bearer {KEY}"}, **kw) if res.status_code == 429 and tries: time.sleep(int(res.headers.get("Retry-After", 1))) return provly(url, tries - 1, **kw) return res.json() ``` ::: :::note Need more? Business has twice the Pro limits; contact us for higher volumes. ::: --- # Errors > One error envelope, stable codes. Every error has the same shape. Branch on `code`, not on the message text. ```json title="Error body" { "error": { "code": "rate_limited", "message": "Rate limit exceeded; retry in 12s", "request_id": "req_4e1c0b9a7f2d4c6b8a10" } } ``` | Status | Code | Meaning | | ------ | ---- | ------- | | 400 | `invalid_request` | Missing or malformed parameter | | 401 | `missing_api_key` | No Authorization header | | 401 | `invalid_api_key` | Unknown key | | 401 | `credential_revoked` | The key was revoked | | 401 | `credential_not_found` | The key's workspace no longer exists | | 402 | `quota_exhausted` | Plan limit of boards, saved ads or trackers reached | | 403 | `workspace_public_api_disabled` | The plan has no API access (Pro or Business needed) | | 404 | `not_found` | No ad, advertiser, shop, product, email, board or tracker with that id | | 429 | `rate_limited` | Wait `Retry-After` seconds | | 500 | `internal_error` | Unexpected failure; retry, then contact us with the request id | --- # Pagination & filters > Cursors, list parameters and valid filter values. ## Envelope List endpoints return: ```json { "data": [ … ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` Pass `cursor=` to get the next page. `next_cursor: null` means you reached the end. `limit` is 1–50 (default 20). ```bash curl "https://provly.co/api/v1/ads?query=serum&limit=50&cursor=eyJzIjpbMTcy…" -H "Authorization: Bearer $PROVLY_API_KEY" ``` ## Lists Query-string lists are comma separated (`countries=TR,DE`) or repeated (`countries=TR&countries=DE`). JSON bodies (`POST /ads/query`) take arrays. ## Valid values Don't guess niche slugs, Shopify app ids or email types: read them from the facets endpoint, which also returns how many records use each value. ```bash curl https://provly.co/api/v1/facets/niches -H "Authorization: Bearer $PROVLY_API_KEY" curl "https://provly.co/api/v1/facets/shop-apps?search=klaviyo" -H "Authorization: Bearer $PROVLY_API_KEY" ``` Facets: `niches`, `platforms`, `formats`, `countries`, `languages`, `shop-platforms`, `shop-apps`, `technologies`, `themes`, `email-campaign-types`, `email-promotion-types`. ## Dates and ids - Dates are ISO 8601 in UTC. - Ids are opaque strings. Ad and advertiser ids start with their source (`meta_library_…`, `tiktok_…`); keep them as they are. --- # MCP server > Give Claude, ChatGPT, Cursor and other agents live access to Provly. Provly runs a remote **Model Context Protocol** server. Agents get the whole API as tools, and each tool call counts as one request against your plan. ```text title="Server URL" https://provly.co/api/v1/mcp ``` - **Transport:** Streamable HTTP (stateless JSON responses) - **Auth:** OAuth 2.1 sign-in (browser apps like ChatGPT and claude.ai) or `Authorization: Bearer pvly_live_…` (Claude Code, Cursor, scripts) - **Protocol:** 2025-06-18, 2025-03-26 and 2024-11-05 :::cards - [Claude](/docs/integrations/claude) — Claude Code, Claude Desktop and claude.ai - [ChatGPT](/docs/integrations/chatgpt) — Custom connectors and the Responses API - [Cursor & Windsurf](/docs/integrations/cursor) — One mcp.json entry - [n8n & Zapier](/docs/integrations/n8n) — Automations over REST or MCP ::: ## Tools | Tool | Does | | ---- | ---- | | `lookup` | Brand / domain / @handle → advertiser and shop ids. Call first. | | `list_facets` | Valid values of every filter | | `search_ads` | Ads by keyword, platform or network, niche, country, run time | | `get_ad`, `get_ad_media_url`, `get_similar_ads` | One ad, its media file, look-alike creatives | | `search_advertisers`, `get_advertiser`, `get_advertiser_ads` | Brands and their ads | | `search_shops`, `get_shop`, `get_shop_ads`, `get_shop_products`, `get_similar_shops` | Stores, tech stack, ads, products, competitors | | `search_products`, `get_product` | Product research with presets | | `search_emails`, `get_email` | Marketing emails | | `list_trackers`, `get_tracker_ads`, `track_brand`, `untrack` | Spyder trackers | | `list_boards`, `create_board`, `update_board`, `delete_board`, `list_board_items`, `save_ad_to_board`, `remove_ad_from_board` | Swipe-file boards | | `get_usage`, `get_workspace`, `get_freshness` | Limits and data freshness | :::note Every OAuth connection acts as a workspace API key: revoking the key in Settings → API disconnects the app. Tools that change the account (`track_brand`, `untrack`, board writes) are marked as non-read-only, so clients ask you before running them. ::: ## Test it by hand ```bash curl -X POST https://provly.co/api/v1/mcp \ -H "Authorization: Bearer $PROVLY_API_KEY" -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` --- # Claude > Connect Provly to Claude Code, Claude Desktop and claude.ai. :::tabs ```bash title="Claude Code" claude mcp add --transport http provly https://provly.co/api/v1/mcp \ --header "Authorization: Bearer $PROVLY_API_KEY" ``` ```json title="Claude Desktop" { "mcpServers": { "provly": { "command": "npx", "args": ["-y", "mcp-remote", "https://provly.co/api/v1/mcp", "--header", "Authorization:Bearer pvly_live_…"] } } } ``` ::: **Claude Desktop:** Settings → Developer → Edit Config, paste the block above into `claude_desktop_config.json` and restart Claude. ## claude.ai (web and mobile) :::steps ### Add a custom connector In claude.ai open **Settings → Connectors → Add custom connector** and paste `https://provly.co/api/v1/mcp`. ### Connect Click **Connect**. Provly's consent page opens: **Allow** with your account or paste an API key. That's it: no headers, it works in the browser and on mobile. ::: ## Try these prompts - *Look up gymshark and list its longest-running active ads. What angles do they share?* - *Find Turkish pet-supplies ads running 30+ days and group them by product.* - *Which Shopify stores are similar to pawfect.co, and what apps do they use?* - *Save the 5 best hooks to a new board called "Q4 hooks".* --- # ChatGPT > Use Provly from ChatGPT connectors and the OpenAI API. ## OpenAI Responses API ```python title="Python" from openai import OpenAI client = OpenAI() resp = client.responses.create( model="gpt-5", tools=[{ "type": "mcp", "server_label": "provly", "server_url": "https://provly.co/api/v1/mcp", "headers": {"Authorization": "Bearer pvly_live_…"}, "require_approval": "never", }], input="Find winning skincare products advertised in Germany this month.", ) print(resp.output_text) ``` ## ChatGPT connector (OAuth) :::steps ### Add the connector In ChatGPT open **Settings → Apps & Connectors → Create** (developer mode). Name it *Provly* and paste the server URL `https://provly.co/api/v1/mcp`. Authentication: **OAuth**. ### Sign in ChatGPT opens Provly's consent page. Click **Allow** with your Provly account, or paste a workspace API key. You are sent back to ChatGPT, connected. ### Ask away Turn the connector on in a chat and ask, e.g. *"Find winning pet products advertised in Turkey this month."* ::: :::note Allowing with your account creates a key named after the app in **Settings → API**. Revoke that key to disconnect. ::: --- # Cursor & Windsurf > One entry in mcp.json. ```json title="~/.cursor/mcp.json · ~/.codeium/windsurf/mcp_config.json" { "mcpServers": { "provly": { "url": "https://provly.co/api/v1/mcp", "headers": { "Authorization": "Bearer pvly_live_…" } } } } ``` Clients that only speak stdio can use the `mcp-remote` bridge: ```json { "mcpServers": { "provly": { "command": "npx", "args": ["-y", "mcp-remote", "https://provly.co/api/v1/mcp", "--header", "Authorization:Bearer pvly_live_…"] } } } ``` --- # n8n & Zapier > Scheduled reports and alerts over REST. :::steps ### Add a credential In n8n create a **Header Auth** credential: name `Authorization`, value `Bearer pvly_live_…`. ### Call an endpoint Use an **HTTP Request** node, e.g. `GET https://provly.co/api/v1/trackers` then `GET https://provly.co/api/v1/trackers/{{ $json.id }}/ads?sort=newest&limit=10`. ### Send the digest Pipe the ads to Slack, email or a sheet. Run it daily with a **Schedule** trigger. ::: n8n's **MCP Client Tool** node also works with `https://provly.co/api/v1/mcp` inside AI Agent workflows. :::tip `GET /system/freshness` needs no key: check it first and skip the run when nothing new arrived. ::: --- # Agent recipes > Proven multi-step workflows for research agents. ## Analyze a competitor 1. `lookup(q="gymshark.com")` → advertiser id and shop domain 2. `get_advertiser(id)` → activity, platforms, formats 3. `get_advertiser_ads(id, active=true, sort="longest_running")` → the winners 4. `get_shop(domain)` and `get_similar_shops(domain)` → stack and competitors ## Find winning products in a niche 1. `list_facets(facet="niches")` → pick a slug 2. `search_products(preset="new_winners", niches=["pet-supplies"])` 3. For each product, `search_ads(query=, min_running_days=30)` to confirm demand 4. `get_similar_ads(id)` → other sellers of the same product ## Build a swipe file 1. `search_ads(query="before after", formats=["video"], active=true, min_running_days=14)` 2. `create_board(name="Before/after hooks")` 3. `save_ad_to_board(board_id, ad_id)` for the best ones ## Weekly competitor digest 1. `list_trackers()` 2. `get_tracker_ads(id, sort="newest", limit=10)` for each 3. Summarize new angles and offers per brand :::tip Rules of thumb for agents: call `lookup` before any brand-specific tool, read `list_facets` instead of guessing ids, and check `get_usage` before loops of more than ~50 calls. ::: --- # API reference # System Version and health (no key needed), and data freshness (key required). ## GET / — API metadata Name, version and status of the public API. Handy as a first connectivity check. No API key needed. ```bash curl "https://provly.co/api/v1" ``` ```json { "name": "Provly Public API", "version": "v1", "status": "ok", "docs": "https://provly.co/docs" } ``` ## GET /health — Health check A lightweight liveness probe for uptime monitors. No API key needed. ```bash curl "https://provly.co/api/v1/health" ``` ```json { "status": "ok", "timestamp": "2026-09-26T08:30:00.000Z", "uptime": 86400 } ``` ## GET /system/freshness — Data freshness When the newest ad entered Provly and how many ads were discovered in the last 24 hours. Use it to decide whether to re-run a daily report. MCP tool: `get_freshness`. ```bash curl "https://provly.co/api/v1/system/freshness" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "latest_ad_discovered_at": "2026-09-26T08:21:00.000Z", "latest_ad_started_at": "2026-09-26T00:00:00.000Z", "ads_discovered_24h": 4210, "lag_minutes": 9, "generated_at": "2026-09-26T08:30:00.000Z" } } ``` --- # Identity & usage The key, its workspace and the rate-limit counters. ## GET /me — Current credential The key, its workspace and the plan limits. Use it to verify authentication. MCP tool: `get_workspace`. ```bash curl "https://provly.co/api/v1/me" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "key": { "id": "b1e4…", "name": "Production", "prefix": "pvly_live_Ab12Cd" }, "workspace": { "id": "ws_123", "name": "Acme" }, "plan": { "id": "pro", "name": "Pro", "limits": { "perSecond": 20, "perMinute": 120, "perHour": 1200, "perDay": 24000 } } } } ``` ## GET /usage — Rate-limit usage Requests used and remaining in the current second, minute, hour and day. Call it before large loops. MCP tool: `get_usage`. ```bash curl "https://provly.co/api/v1/usage" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "second": { "limit": 20, "used": 1, "remaining": 19 }, "minute": { "limit": 120, "used": 14, "remaining": 106 }, "hour": { "limit": 1200, "used": 230, "remaining": 970 }, "day": { "limit": 24000, "used": 1840, "remaining": 22160 } } } ``` ## GET /workspace — Workspace The workspace bound to the key, the credential and the resource limits of its plan (tracked brands, boards, saved ads). MCP tool: `get_workspace`. ```bash curl "https://provly.co/api/v1/workspace" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "workspace": { "id": "ws_123", "name": "Acme", "plan": "pro" }, "credential": { "id": "b1e4…", "name": "Production", "prefix": "pvly_live_Ab12Cd", "created_at": "2026-09-01T10:00:00.000Z", "last_used_at": "2026-09-26T08:29:00.000Z" }, "limits": { "rate": { "perSecond": 20, "perMinute": 120, "perHour": 1200, "perDay": 24000 }, "tracked_brands": 10, "boards": 50, "saved_ads": 2000 } } } ``` --- # Discovery Resolve names to ids and list every accepted filter value. ## GET /lookup — Resolve a brand, domain or handle Turns a brand name, a domain (`gymshark.com`) or an Instagram handle (`@gymshark`) into Provly advertisers and shops. **Call it first** whenever the user names a brand, then use the returned ids. MCP tool: `lookup`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `q` | query | string | yes | Brand name, domain or @handle. | ```bash curl "https://provly.co/api/v1/lookup?q=pawfect.co" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "advertisers": [ { "id": "meta_library_104587213", "name": "Pawfect Co.", "description": "Smart products for happy pets", "avatar": "https://media.provly.co/avatars/104587213.jpg", "websites": [ "pawfect.co" ], "niches": [ "pet-supplies" ], "verified": false, "active_ads": 42, "total_ads": 318, "new_ads_30d": 17, "eu_reach_30d": 1250000, "facebook_likes": 58000, "instagram_followers": 91000, "main_country": "TR", "countries": [ "TR", "DE", "NL" ], "provly_url": "https://provly.co/app/brands/meta_library_104587213" } ], "shops": [ { "domain": "pawfect.co", "name": "Pawfect Co.", "description": "Smart products for happy pets", "platform": "shopify", "theme": { "name": "Dawn", "version": "15.0.0" }, "apps": [ { "name": "Judge.me", "category": "reviews" }, { "name": "Klaviyo", "category": "email" } ], "pixels": [ "Meta Pixel", "TikTok Pixel", "Google Analytics 4" ], "currency": "TRY", "language": "tr", "catalog": { "products": 64, "price_min": 199, "price_max": 4499, "price_avg": 1180 }, "active_ads": 42, "monthly_visits": 184000, "traffic_growth_30d": 0.21, "country": "TR", "niches": [ "pet-supplies" ], "socials": { "instagram": "https://instagram.com/pawfect.co" }, "provly_url": "https://provly.co/app/stores/pawfect.co" } ] } } ``` ## GET /facets/{facet} — Filter values Every value a filter accepts, with live counts: niches, platforms, formats, countries, languages, shop platforms, Shopify apps, technologies, themes and email types. Agents should read these instead of guessing ids. MCP tool: `list_facets`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `facet` | path | string | yes | One of `niches`, `platforms`, `formats`, `countries`, `languages`, `shop-platforms`, `shop-apps`, `technologies`, `themes`, `email-campaign-types`, `email-promotion-types`. | | `search` | query | string | no | Case-insensitive substring filter. | | `limit` | query | integer | no | 1–500. Default `100`. | ```bash curl "https://provly.co/api/v1/facets/niches" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "value": "pet-supplies", "count": 18234 }, { "value": "beauty-care", "count": 51210 } ], "meta": { "facet": "niches", "total": 18 } } ``` --- # Ads Search, read and compare ads across Meta, TikTok and Google. ## GET /ads — Search ads Search ads from Meta (Facebook, Instagram), TikTok and Google/YouTube by keyword and filters. Lists are comma separated. Paginate with `cursor`. MCP tool: `search_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Keywords matched in ad copy, headline, transcript and brand name. | | `platforms` | query | string[] (facebook | instagram | tiktok | google | youtube | messenger | audience_network | threads) | no | Publisher platforms, comma separated. | | `formats` | query | string[] (video | image | carousel | dco | dpa) | no | Creative formats. | | `niches` | query | string[] (fashion | beauty-care | health-supplements | home-garden | food-drink | electronics-tech | sports-outdoors | pet-supplies | baby-parenting | toys-games | arts-hobbies | gifts-events | books-education | travel-luggage | automotive | business-industrial | apps | other) | no | Niche slugs; see `GET /facets/niches`. | | `countries` | query | string[] | no | ISO 3166-1 alpha-2 country codes the ad targets. | | `languages` | query | string[] | no | Ad languages (ISO 639-1). | | `active` | query | boolean | no | `true` for ads still running, `false` for stopped ones. | | `min_running_days` | query | integer | no | Minimum days the ad has run. 30+ usually means a profitable ad. | | `domain` | query | string | no | Landing-page domain. | | `advertiser_id` | query | string | no | Only this advertiser's ads (ids come from `/lookup`). | | `sort` | query | string (newest | oldest | longest_running | most_relevant) | no | Order of results. Defaults to `most_relevant` with a query, else `newest`. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/ads?query=collagen&platforms=facebook%2Cinstagram&countries=TR%2CDE&min_running_days=30&domain=gymshark.com" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` ## POST /ads/query — Query ads (JSON) The same search as `GET /ads` with a JSON body, so arrays and long queries stay readable. An empty body `{}` is valid. MCP tool: `search_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | body | string | no | Keywords matched in ad copy, headline, transcript and brand name. | | `platforms` | body | string[] (facebook | instagram | tiktok | google | youtube | messenger | audience_network | threads) | no | Publisher platforms, comma separated. | | `formats` | body | string[] (video | image | carousel | dco | dpa) | no | Creative formats. | | `niches` | body | string[] (fashion | beauty-care | health-supplements | home-garden | food-drink | electronics-tech | sports-outdoors | pet-supplies | baby-parenting | toys-games | arts-hobbies | gifts-events | books-education | travel-luggage | automotive | business-industrial | apps | other) | no | Niche slugs; see `GET /facets/niches`. | | `countries` | body | string[] | no | ISO 3166-1 alpha-2 country codes the ad targets. | | `languages` | body | string[] | no | Ad languages (ISO 639-1). | | `active` | body | boolean | no | `true` for ads still running, `false` for stopped ones. | | `min_running_days` | body | integer | no | Minimum days the ad has run. 30+ usually means a profitable ad. | | `domain` | body | string | no | Landing-page domain. | | `advertiser_id` | body | string | no | Only this advertiser's ads (ids come from `/lookup`). | | `sort` | body | string (newest | oldest | longest_running | most_relevant) | no | Order of results. Defaults to `most_relevant` with a query, else `newest`. | | `limit` | body | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | body | string | no | The `next_cursor` of the previous page. | ```bash curl -X POST "https://provly.co/api/v1/ads/query" \ -H "Authorization: Bearer $PROVLY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"collagen","platforms":"facebook,instagram","countries":"TR,DE","min_running_days":30,"domain":"gymshark.com"}' ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` ## GET /ads/{id} — Get an ad One ad with copy, media, run dates, targeting, reach and the video transcript. MCP tool: `get_ad`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Ad id. | ```bash curl "https://provly.co/api/v1/ads/meta_library_1203944578113742" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } } ``` ## GET /ads/{id}/media-url — Ad media URL The best media file of the ad (video, else image) as a direct URL, with a suggested filename. Metadata only: the file itself is not proxied. MCP tool: `get_ad_media_url`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Ad id. | ```bash curl "https://provly.co/api/v1/ads/meta_library_1203944578113742/media-url" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "ad_id": "meta_library_1203944578113742", "type": "video", "url": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "filename": "meta_library_1203944578113742.mp4" } } ``` ## GET /ads/{id}/similar — Similar ads Creatives semantically close to this one (copy, visuals, transcript), across all advertisers. Great for finding every seller of the same product. MCP tool: `get_similar_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Ad id. | | `limit` | query | integer | no | 1–30. Default `10`. | ```bash curl "https://provly.co/api/v1/ads/meta_library_1203944578113742/similar" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742", "similarity": 0.912 } ] } ``` --- # Networks The ads search locked to one ad network. ## GET /tiktok/ads — TikTok ads `GET /ads` locked to TikTok (Creative Center top ads and TikTok advertisers). MCP tool: `search_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Keywords matched in ad copy, headline, transcript and brand name. | | `formats` | query | string[] (video | image | carousel | dco | dpa) | no | Creative formats. | | `niches` | query | string[] (fashion | beauty-care | health-supplements | home-garden | food-drink | electronics-tech | sports-outdoors | pet-supplies | baby-parenting | toys-games | arts-hobbies | gifts-events | books-education | travel-luggage | automotive | business-industrial | apps | other) | no | Niche slugs; see `GET /facets/niches`. | | `countries` | query | string[] | no | ISO 3166-1 alpha-2 country codes the ad targets. | | `languages` | query | string[] | no | Ad languages (ISO 639-1). | | `active` | query | boolean | no | `true` for ads still running, `false` for stopped ones. | | `min_running_days` | query | integer | no | Minimum days the ad has run. 30+ usually means a profitable ad. | | `domain` | query | string | no | Landing-page domain. | | `advertiser_id` | query | string | no | Only this advertiser's ads (ids come from `/lookup`). | | `sort` | query | string (newest | oldest | longest_running | most_relevant) | no | Order of results. Defaults to `most_relevant` with a query, else `newest`. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/tiktok/ads?query=collagen&countries=TR%2CDE&min_running_days=30&domain=gymshark.com" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "tiktok" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` ## GET /google-ads — Google & YouTube ads `GET /ads` locked to Google Ads Transparency Center: Search, Shopping, Display and YouTube. MCP tool: `search_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Keywords matched in ad copy, headline, transcript and brand name. | | `formats` | query | string[] (video | image | carousel | dco | dpa) | no | Creative formats. | | `niches` | query | string[] (fashion | beauty-care | health-supplements | home-garden | food-drink | electronics-tech | sports-outdoors | pet-supplies | baby-parenting | toys-games | arts-hobbies | gifts-events | books-education | travel-luggage | automotive | business-industrial | apps | other) | no | Niche slugs; see `GET /facets/niches`. | | `countries` | query | string[] | no | ISO 3166-1 alpha-2 country codes the ad targets. | | `languages` | query | string[] | no | Ad languages (ISO 639-1). | | `active` | query | boolean | no | `true` for ads still running, `false` for stopped ones. | | `min_running_days` | query | integer | no | Minimum days the ad has run. 30+ usually means a profitable ad. | | `domain` | query | string | no | Landing-page domain. | | `advertiser_id` | query | string | no | Only this advertiser's ads (ids come from `/lookup`). | | `sort` | query | string (newest | oldest | longest_running | most_relevant) | no | Order of results. Defaults to `most_relevant` with a query, else `newest`. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/google-ads?query=collagen&countries=TR%2CDE&min_running_days=30&domain=gymshark.com" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "google" ], "format": "image", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` ## GET /meta/ads — Meta ads `GET /ads` locked to Meta: Facebook, Instagram, Messenger, Audience Network and Threads. MCP tool: `search_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Keywords matched in ad copy, headline, transcript and brand name. | | `formats` | query | string[] (video | image | carousel | dco | dpa) | no | Creative formats. | | `niches` | query | string[] (fashion | beauty-care | health-supplements | home-garden | food-drink | electronics-tech | sports-outdoors | pet-supplies | baby-parenting | toys-games | arts-hobbies | gifts-events | books-education | travel-luggage | automotive | business-industrial | apps | other) | no | Niche slugs; see `GET /facets/niches`. | | `countries` | query | string[] | no | ISO 3166-1 alpha-2 country codes the ad targets. | | `languages` | query | string[] | no | Ad languages (ISO 639-1). | | `active` | query | boolean | no | `true` for ads still running, `false` for stopped ones. | | `min_running_days` | query | integer | no | Minimum days the ad has run. 30+ usually means a profitable ad. | | `domain` | query | string | no | Landing-page domain. | | `advertiser_id` | query | string | no | Only this advertiser's ads (ids come from `/lookup`). | | `sort` | query | string (newest | oldest | longest_running | most_relevant) | no | Order of results. Defaults to `most_relevant` with a query, else `newest`. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/meta/ads?query=collagen&countries=TR%2CDE&min_running_days=30&domain=gymshark.com" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` --- # Advertisers Brands and Facebook pages with their activity and ads. ## GET /advertisers — Search advertisers Advertisers (brands / Facebook pages) running ads, by name, sorted by active ads, new ads in 30 days or EU reach. MCP tool: `search_advertisers`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Brand name. | | `sort` | query | string (active | launched | reach) | no | Order. Default `active`. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | ```bash curl "https://provly.co/api/v1/advertisers" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_104587213", "name": "Pawfect Co.", "description": "Smart products for happy pets", "avatar": "https://media.provly.co/avatars/104587213.jpg", "websites": [ "pawfect.co" ], "niches": [ "pet-supplies" ], "verified": false, "active_ads": 42, "total_ads": 318, "new_ads_30d": 17, "eu_reach_30d": 1250000, "facebook_likes": 58000, "instagram_followers": 91000, "main_country": "TR", "countries": [ "TR", "DE", "NL" ], "provly_url": "https://provly.co/app/brands/meta_library_104587213" } ], "pagination": { "total": 1284, "next_cursor": null } } ``` ## GET /advertisers/{id} — Get an advertiser Profile, counters and ad analytics: average run time, platform and format breakdown. MCP tool: `get_advertiser`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Advertiser id. | ```bash curl "https://provly.co/api/v1/advertisers/meta_library_104587213" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "meta_library_104587213", "name": "Pawfect Co.", "description": "Smart products for happy pets", "avatar": "https://media.provly.co/avatars/104587213.jpg", "websites": [ "pawfect.co" ], "niches": [ "pet-supplies" ], "verified": false, "active_ads": 42, "total_ads": 318, "new_ads_30d": 17, "eu_reach_30d": 1250000, "facebook_likes": 58000, "instagram_followers": 91000, "main_country": "TR", "countries": [ "TR", "DE", "NL" ], "provly_url": "https://provly.co/app/brands/meta_library_104587213", "analytics": { "total_ads": 318, "active_ads": 42, "avg_running_days": 23, "by_platform": [ { "key": "facebook", "count": 301 } ], "by_format": [ { "key": "video", "count": 188 } ] } } } ``` ## GET /advertisers/{id}/ads — An advertiser's ads The ads of one advertiser. `active=true&sort=longest_running` returns its proven winners. MCP tool: `get_advertiser_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Advertiser id. | | `active` | query | boolean | no | Only running ads. | | `sort` | query | string (newest | oldest | longest_running | most_relevant) | no | Order. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/advertisers/meta_library_104587213/ads" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` --- # Shops E-commerce stores: tech stack, catalog, traffic, ads, emails and look-alikes. ## GET /shops — Search shops E-commerce stores (Shopify, WooCommerce, ikas, …) by name, platform, niche and active ads. MCP tool: `search_shops`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Store name or domain. | | `platform` | query | string[] | no | Store platforms; see `/facets/shop-platforms`. | | `niches` | query | string[] | no | Niche slugs. | | `min_active_ads` | query | integer | no | Minimum live ads. | | `sort` | query | string (active_ads | traffic | products | newest) | no | Order. Default `active_ads`. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | ```bash curl "https://provly.co/api/v1/shops?platform=shopify" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "domain": "pawfect.co", "name": "Pawfect Co.", "description": "Smart products for happy pets", "platform": "shopify", "theme": { "name": "Dawn", "version": "15.0.0" }, "apps": [ { "name": "Judge.me", "category": "reviews" }, { "name": "Klaviyo", "category": "email" } ], "pixels": [ "Meta Pixel", "TikTok Pixel", "Google Analytics 4" ], "currency": "TRY", "language": "tr", "catalog": { "products": 64, "price_min": 199, "price_max": 4499, "price_avg": 1180 }, "active_ads": 42, "monthly_visits": 184000, "traffic_growth_30d": 0.21, "country": "TR", "niches": [ "pet-supplies" ], "socials": { "instagram": "https://instagram.com/pawfect.co" }, "provly_url": "https://provly.co/app/stores/pawfect.co" } ], "pagination": { "total": 1284, "next_cursor": null } } ``` ## GET /shops/{domain} — Get a shop Store analysis for one domain: platform, theme, apps, pixels, catalog and prices, active ads and traffic. MCP tool: `get_shop`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `domain` | path | string | yes | Store domain (a URL works too). | ```bash curl "https://provly.co/api/v1/shops/pawfect.co" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "domain": "pawfect.co", "name": "Pawfect Co.", "description": "Smart products for happy pets", "platform": "shopify", "theme": { "name": "Dawn", "version": "15.0.0" }, "apps": [ { "name": "Judge.me", "category": "reviews" }, { "name": "Klaviyo", "category": "email" } ], "pixels": [ "Meta Pixel", "TikTok Pixel", "Google Analytics 4" ], "currency": "TRY", "language": "tr", "catalog": { "products": 64, "price_min": 199, "price_max": 4499, "price_avg": 1180 }, "active_ads": 42, "monthly_visits": 184000, "traffic_growth_30d": 0.21, "country": "TR", "niches": [ "pet-supplies" ], "socials": { "instagram": "https://instagram.com/pawfect.co" }, "provly_url": "https://provly.co/app/stores/pawfect.co" } } ``` ## GET /shops/{domain}/ads — A shop's ads Ads whose landing page is on this domain, from every advertiser. MCP tool: `get_shop_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `domain` | path | string | yes | Store domain. | | `active` | query | boolean | no | Only running ads. | | `sort` | query | string (newest | oldest | longest_running | most_relevant) | no | Order. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/shops/pawfect.co/ads" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` ## GET /shops/{domain}/products — A shop's products The shop's products seen in ads, with prices and ad counters. MCP tool: `get_shop_products`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `domain` | path | string | yes | Store domain. | | `sort` | query | string (active_ads | newest | price_asc | price_desc | longest) | no | Order. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | ```bash curl "https://provly.co/api/v1/shops/pawfect.co/products" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "pawfect.co:autobox", "title": "AutoBox self-cleaning litter box", "shop": "pawfect.co", "url": "https://pawfect.co/products/autobox", "image": "https://media.provly.co/products/autobox.jpg", "price": 3999, "compare_at_price": 5499, "currency": "TRY", "active_ads": 9, "total_ads": 23, "longest_running_days": 86, "platforms": [ "facebook", "instagram" ], "niches": [ "pet-supplies" ], "added_to_store_at": "2026-06-18T00:00:00.000Z", "provly_url": "https://provly.co/app/products/pawfect.co%3Aautobox" } ], "pagination": { "total": 1284, "next_cursor": null } } ``` ## GET /shops/{domain}/similar — Similar shops Competitors: sites with overlapping audiences first (`match: similar_site`), then stores of the same niche (`match: same_niche`), by active ads. MCP tool: `get_similar_shops`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `domain` | path | string | yes | Store domain. | | `limit` | query | integer | no | 1–30. Default `12`. | ```bash curl "https://provly.co/api/v1/shops/pawfect.co/similar" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "domain": "catlife.com.tr", "name": "Pawfect Co.", "description": "Smart products for happy pets", "platform": "shopify", "theme": { "name": "Dawn", "version": "15.0.0" }, "apps": [ { "name": "Judge.me", "category": "reviews" }, { "name": "Klaviyo", "category": "email" } ], "pixels": [ "Meta Pixel", "TikTok Pixel", "Google Analytics 4" ], "currency": "TRY", "language": "tr", "catalog": { "products": 64, "price_min": 199, "price_max": 4499, "price_avg": 1180 }, "active_ads": 42, "monthly_visits": 184000, "traffic_growth_30d": 0.21, "country": "TR", "niches": [ "pet-supplies" ], "socials": { "instagram": "https://instagram.com/pawfect.co" }, "provly_url": "https://provly.co/app/stores/pawfect.co", "match": "similar_site" } ], "meta": { "shop": "pawfect.co" } } ``` ## GET /shops/{domain}/emails — A shop's emails Marketing emails this shop sent, newest first. MCP tool: `search_emails`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `domain` | path | string | yes | Store domain. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/shops/pawfect.co/emails" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "em_7298813", "sent_at": "2026-09-21T09:12:00.000Z", "subject": "%30 indirim sadece bu hafta 🐾", "preheader": "AutoBox'ta sezonun en iyi fiyatı", "sender": "Pawfect Co.", "campaign_type": "Newsletter", "category": "Promotional Campaign", "promotion_type": "Discount %", "event": null, "language": "turkish", "country": "TR", "screenshot": "https://media.provly.co/emails/em_7298813.png", "shop": { "domain": "pawfect.co", "name": "Pawfect Co.", "active_ads": 42 }, "body_preview": "Kedinizin kumunu 14 gün boyunca unutun…" } ], "pagination": { "total": 1284, "next_cursor": "1726908720000" } } ``` --- # Products Products found in ads, with prices and ad counters. ## GET /products — Search products Product research: products found in ads. Presets: `new_winners` (found in the last 14 days, 2+ active ads), `scaling` (5+ active ads), `evergreen` (an ad running 30+ days), `on_sale`, `fresh_products` (added to the store in the last 30 days). MCP tool: `search_products`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Product title keywords. | | `preset` | query | string (new_winners | scaling | evergreen | on_sale | fresh_products) | no | A ready-made research filter. | | `niches` | query | string[] | no | Niche slugs. | | `shop` | query | string | no | Store domain. | | `price_min` | query | number | no | Minimum price. | | `price_max` | query | number | no | Maximum price. | | `sort` | query | string (active_ads | newest | price_asc | price_desc | longest) | no | Order. Default `active_ads`. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | ```bash curl "https://provly.co/api/v1/products" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "pawfect.co:autobox", "title": "AutoBox self-cleaning litter box", "shop": "pawfect.co", "url": "https://pawfect.co/products/autobox", "image": "https://media.provly.co/products/autobox.jpg", "price": 3999, "compare_at_price": 5499, "currency": "TRY", "active_ads": 9, "total_ads": 23, "longest_running_days": 86, "platforms": [ "facebook", "instagram" ], "niches": [ "pet-supplies" ], "added_to_store_at": "2026-06-18T00:00:00.000Z", "provly_url": "https://provly.co/app/products/pawfect.co%3Aautobox" } ], "pagination": { "total": 1284, "next_cursor": null } } ``` ## GET /products/{id} — Get a product One product with price, store and ad counters. MCP tool: `get_product`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Product id. | ```bash curl "https://provly.co/api/v1/products/pawfect.co%3Aautobox" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "pawfect.co:autobox", "title": "AutoBox self-cleaning litter box", "shop": "pawfect.co", "url": "https://pawfect.co/products/autobox", "image": "https://media.provly.co/products/autobox.jpg", "price": 3999, "compare_at_price": 5499, "currency": "TRY", "active_ads": 9, "total_ads": 23, "longest_running_days": 86, "platforms": [ "facebook", "instagram" ], "niches": [ "pet-supplies" ], "added_to_store_at": "2026-06-18T00:00:00.000Z", "provly_url": "https://provly.co/app/products/pawfect.co%3Aautobox" } } ``` --- # Emails Marketing emails stores send: newsletters, promotions, flows. ## GET /emails — Search emails Marketing emails stores sent, newest first. Types come from `/facets/email-campaign-types` and `/facets/email-promotion-types`. MCP tool: `search_emails`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `query` | query | string | no | Words in subject, sender or body. | | `shop` | query | string | no | Store domain. | | `campaign_types` | query | string[] | no | e.g. Newsletter, Welcome. | | `promotion_types` | query | string[] | no | e.g. Discount %, Free Delivery. | | `languages` | query | string[] | no | e.g. english, turkish. | | `sent_after` | query | string | no | ISO date. | | `sent_before` | query | string | no | ISO date. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/emails?query=black%20friday" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "em_7298813", "sent_at": "2026-09-21T09:12:00.000Z", "subject": "%30 indirim sadece bu hafta 🐾", "preheader": "AutoBox'ta sezonun en iyi fiyatı", "sender": "Pawfect Co.", "campaign_type": "Newsletter", "category": "Promotional Campaign", "promotion_type": "Discount %", "event": null, "language": "turkish", "country": "TR", "screenshot": "https://media.provly.co/emails/em_7298813.png", "shop": { "domain": "pawfect.co", "name": "Pawfect Co.", "active_ads": 42 }, "body_preview": "Kedinizin kumunu 14 gün boyunca unutun…" } ], "pagination": { "total": 1284, "next_cursor": "1726908720000" } } ``` ## GET /emails/{id} — Get an email One email with its full text body and screenshot. MCP tool: `get_email`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Email id. | ```bash curl "https://provly.co/api/v1/emails/em_7298813" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "em_7298813", "sent_at": "2026-09-21T09:12:00.000Z", "subject": "%30 indirim sadece bu hafta 🐾", "preheader": "AutoBox'ta sezonun en iyi fiyatı", "sender": "Pawfect Co.", "campaign_type": "Newsletter", "category": "Promotional Campaign", "promotion_type": "Discount %", "event": null, "language": "turkish", "country": "TR", "screenshot": "https://media.provly.co/emails/em_7298813.png", "shop": { "domain": "pawfect.co", "name": "Pawfect Co.", "active_ads": 42 }, "body": "Kedinizin kumunu 14 gün boyunca unutun…" } } ``` --- # Trackers Spyder: brands and keywords your workspace follows. ## GET /trackers — List trackers The brands and keywords your workspace follows in Spyder, with scan status. MCP tool: `list_trackers`. ```bash curl "https://provly.co/api/v1/trackers" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "3f8aa146-6f96-46e8-9781-64db5166f9a8", "kind": "brand", "label": "Pawfect Co.", "query": null, "advertiser_id": "meta_library_104587213", "countries": [ "TR" ], "enabled": true, "interval_minutes": 720, "total_ads": 318, "last_run_at": "2026-09-26T06:00:00.000Z", "last_status": "ok", "created_at": "2026-08-01T10:20:00.000Z", "provly_url": "https://provly.co/app/spyder" } ], "meta": { "limit": 10 } } ``` ## POST /trackers — Track a brand or keyword Follow an advertiser (id from `/lookup`) or a keyword. Provly rescans it on the interval and new ads show up in `/trackers/{id}/ads`. Counts against the plan's tracked-brand limit (`402 quota_exhausted` when full); tracking an advertiser twice returns the existing tracker with `created: false`. MCP tool: `track_brand`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `advertiser_id` | body | string | no | Advertiser to follow. | | `query` | body | string | no | Or: keyword to follow. | | `countries` | body | string[] | no | ISO codes to scan. | | `interval_minutes` | body | integer | no | Rescan interval, min 60. Default `720`. | ```bash curl -X POST "https://provly.co/api/v1/trackers" \ -H "Authorization: Bearer $PROVLY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"countries":["TR"]}' ``` ```json { "data": { "id": "3f8aa146-6f96-46e8-9781-64db5166f9a8", "kind": "brand", "label": "Pawfect Co.", "query": null, "advertiser_id": "meta_library_104587213", "countries": [ "TR" ], "enabled": true, "interval_minutes": 720, "total_ads": 318, "last_run_at": "2026-09-26T06:00:00.000Z", "last_status": "ok", "created_at": "2026-08-01T10:20:00.000Z", "provly_url": "https://provly.co/app/spyder" }, "created": true } ``` ## GET /trackers/{id} — Get a tracker One tracker. MCP tool: `list_trackers`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Tracker id. | ```bash curl "https://provly.co/api/v1/trackers/3f8aa146-6f96-46e8-9781-64db5166f9a8" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "3f8aa146-6f96-46e8-9781-64db5166f9a8", "kind": "brand", "label": "Pawfect Co.", "query": null, "advertiser_id": "meta_library_104587213", "countries": [ "TR" ], "enabled": true, "interval_minutes": 720, "total_ads": 318, "last_run_at": "2026-09-26T06:00:00.000Z", "last_status": "ok", "created_at": "2026-08-01T10:20:00.000Z", "provly_url": "https://provly.co/app/spyder" } } ``` ## DELETE /trackers/{id} — Stop tracking Deletes the tracker. The ads already collected stay searchable. MCP tool: `untrack`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Tracker id. | ```bash curl -X DELETE "https://provly.co/api/v1/trackers/3f8aa146-6f96-46e8-9781-64db5166f9a8" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "3f8aa146-6f96-46e8-9781-64db5166f9a8", "deleted": true } } ``` ## GET /trackers/{id}/ads — A tracker's ads Ads of the tracked brand (or matching the tracked keyword). `sort=newest` shows what launched since your last look. MCP tool: `get_tracker_ads`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Tracker id. | | `active` | query | boolean | no | Only running ads. | | `sort` | query | string (newest | oldest | longest_running | most_relevant) | no | Order. | | `limit` | query | integer | no | Results per page, 1–50. Default `20`. | | `cursor` | query | string | no | The `next_cursor` of the previous page. | ```bash curl "https://provly.co/api/v1/trackers/3f8aa146-6f96-46e8-9781-64db5166f9a8/ads" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": "eyJzIjpbMTcy…" } } ``` --- # Boards Your swipe file: boards and the ads saved in them. ## GET /boards — List boards Boards of the key's owner, with the number of saved ads in each. MCP tool: `list_boards`. ```bash curl "https://provly.co/api/v1/boards" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e", "name": "Winning hooks", "description": "Ads with a strong first 3 seconds", "ad_count": 24, "share_url": null, "created_at": "2026-09-02T14:00:00.000Z", "provly_url": "https://provly.co/app/swipefile?board=8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e" } ] } ``` ## POST /boards — Create a board Creates a board. Counts against the plan's board limit. MCP tool: `create_board`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `name` | body | string | yes | Board name, max 80 characters. | | `description` | body | string | no | Optional description. | ```bash curl -X POST "https://provly.co/api/v1/boards" \ -H "Authorization: Bearer $PROVLY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Winning hooks"}' ``` ```json { "data": { "id": "8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e", "name": "Winning hooks", "description": "Ads with a strong first 3 seconds", "ad_count": 0, "share_url": null, "created_at": "2026-09-02T14:00:00.000Z", "provly_url": "https://provly.co/app/swipefile?board=8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e" } } ``` ## GET /boards/{id} — Get a board One board. MCP tool: `list_boards`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Board id. | ```bash curl "https://provly.co/api/v1/boards/8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e", "name": "Winning hooks", "description": "Ads with a strong first 3 seconds", "ad_count": 24, "share_url": null, "created_at": "2026-09-02T14:00:00.000Z", "provly_url": "https://provly.co/app/swipefile?board=8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e" } } ``` ## PATCH /boards/{id} — Update a board Rename a board or turn its public share link on or off. MCP tool: `update_board`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Board id. | | `name` | body | string | no | New name. | | `shared` | body | boolean | no | `true` creates a public read-only link (`share_url`), `false` removes it. | ```bash curl -X PATCH "https://provly.co/api/v1/boards/8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e" \ -H "Authorization: Bearer $PROVLY_API_KEY" \ -H "Content-Type: application/json" \ -d '{}' ``` ```json { "data": { "id": "8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e", "name": "Winning hooks", "description": "Ads with a strong first 3 seconds", "ad_count": 24, "share_url": "https://provly.co/share/Zm9vYmFy", "created_at": "2026-09-02T14:00:00.000Z", "provly_url": "https://provly.co/app/swipefile?board=8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e" } } ``` ## DELETE /boards/{id} — Delete a board Deletes the board. Its ads stay in the swipe file. MCP tool: `delete_board`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Board id. | ```bash curl -X DELETE "https://provly.co/api/v1/boards/8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "id": "8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e", "deleted": true } } ``` ## GET /boards/{id}/items — List a board's ads The ads saved in the board, newest save first. MCP tool: `list_board_items`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Board id. | | `limit` | query | integer | no | 1–200. Default `50`. | ```bash curl "https://provly.co/api/v1/boards/8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e/items" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": [ { "id": "meta_library_1203944578113742", "advertiser": { "id": "meta_library_104587213", "name": "Pawfect Co." }, "platforms": [ "facebook", "instagram" ], "format": "video", "headline": "The self-cleaning litter box cats love", "body": "No scooping for 14 days. 30-day money-back guarantee.", "cta": "Shop now", "landing_url": "https://pawfect.co/products/autobox", "is_active": true, "started_at": "2026-07-02T00:00:00.000Z", "ended_at": null, "running_days": 86, "countries": [ "TR", "DE" ], "languages": [ "tr" ], "niches": [ "pet-supplies" ], "media": { "image": null, "video": "https://media.provly.co/meta/1203944578113742.mp4", "thumbnail": "https://media.provly.co/meta/1203944578113742.jpg", "video_duration": 27 }, "reach": 184200, "engagement": null, "duplicates": 6, "transcript": "Tired of scooping every day? …", "provly_url": "https://provly.co/app?ad=meta_library_1203944578113742" } ], "pagination": { "total": 1284, "next_cursor": null } } ``` ## POST /boards/{id}/items — Save an ad to a board Saves the ad to the swipe file and files it into the board (idempotent). Counts against the plan's saved-ads limit. MCP tool: `save_ad_to_board`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Board id. | | `ad_id` | body | string | yes | Ad to save. | ```bash curl -X POST "https://provly.co/api/v1/boards/8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e/items" \ -H "Authorization: Bearer $PROVLY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"ad_id":"meta_library_1203944578113742"}' ``` ```json { "data": { "board_id": "8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e", "ad_id": "meta_library_1203944578113742", "added": true } } ``` ## DELETE /boards/{id}/items/{ad_id} — Remove an ad from a board Takes the ad out of the board; it stays in the swipe file. MCP tool: `remove_ad_from_board`. | Parameter | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `id` | path | string | yes | Board id. | | `ad_id` | path | string | yes | Ad id. | ```bash curl -X DELETE "https://provly.co/api/v1/boards/8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e/items/meta_library_1203944578113742" \ -H "Authorization: Bearer $PROVLY_API_KEY" ``` ```json { "data": { "board_id": "8b7c6d5e-4f3a-4b2c-9d1e-0f1a2b3c4d5e", "ad_id": "meta_library_1203944578113742", "removed": true } } ```