Research public Meta ads with SearchApi, compare creative approaches, and save references for your next campaign.
This is a local example application for developers and technical marketers. It is not a hosted service or a production-ready multi-user deployment.
Watch the full walkthrough on YouTube: How to Scrape Meta Ads Library for Competitor Research.
You need Git and Node.js 24.13.0 or newer. Node 24 is the tested runtime; the app uses Node's built-in SQLite support. No npm packages, cloud account, or separate database installation are required.
git clone https://github.com/SearchApi/ad-observatory.git
cd ad-observatory
npm startOpen http://127.0.0.1:5190. The first visit starts empty and does not search for ads. Stop the server with Ctrl+C. While the repository is private, cloning requires access to the SearchApi organization and this repository.
If you use nvm, run nvm install and nvm use first. A SQLite experimental warning from Node is expected.
If port 5190 is already in use, stop the other process or choose a port:
# macOS / Linux
PORT=5192 npm start# Windows PowerShell
$env:PORT=5192
npm startUse the exact 127.0.0.1 URL printed by the server. Keep the same browser and URL when returning to saved research.
- Create a SearchApi account and obtain your API key.
- Open Connections, connect your key, and close the dialog. Keep the key out of screenshots and recordings.
- Paste an advertiser's Facebook Page or Instagram profile URL, select an audience country and ad status, then choose Add competitor. Alternatively, select Keyword to search the library.
- Add a second advertiser. For example, Shopify and BigCommerce are relevant references for someone marketing an ecommerce platform. Verify the advertiser identity and choose ads relevant to your brief; results change over time.
- Filter by format, inspect the copy and destination, and save individual ads to a collection such as Ecommerce platform - creative research.
- Reopen the collection in My collections. Saved competitors stores advertiser shortcuts separately from your captures.
Searches use your SearchApi allowance and retrieve at most two result pages. An advertiser lookup may add a request. Reopening retained captures does not run another provider search. There is no automatic refresh or scheduled monitoring.
SearchApi retrieves structured public ad records: available text, media URLs, advertiser information, source dates and placements. Ad Observatory adds a gallery, creative grouping, filters, saved competitors, dated captures, collections, exports and individual asset downloads. Optional destination checks inspect a small number of advertised URLs; they are not SearchApi search results.
A long-running ad is a research clue, not proof of conversions, profitability, spend, targeting, or continuous delivery. Absence from a later bounded sample does not prove that an ad stopped. Media remains hosted by its source and can expire; a saved collection is not a permanent video archive.
The key lives in the current tab's memory and is sent to your local backend, which calls SearchApi. The application does not persist the key; reconnect after reloading. Do not commit keys or put them in the URL. No deployment owner's key is bundled or used as a fallback.
The server listens only on 127.0.0.1. Data is created automatically in .data/ad-observatory.sqlite, which is ignored by Git. A browser cookie identifies your workspace; browser storage also retains captures. Collections and saved competitors survive server restarts. Clearing cookies loses access to that workspace; clearing browser storage removes browser-held captures. This example has no login or account recovery.
Do not expose this server with a public tunnel or treat it as a production deployment. Hosting for other users requires an appropriate authentication, authorization, credential-storage and operational design.
Connections → Agent API guide explains the REST endpoints and temporary workspace tokens. This is REST/OpenAPI, not an MCP server. Reading saved research does not call SearchApi; agent searches require the agent token and the caller's SearchApi key. Tokens can be revoked and expire after 30 days.
npm test
npm run buildTests use synthetic examples and isolated databases; they do not spend SearchApi credits. build regenerates the HTML API guide and does not deploy anything. GitHub Actions runs syntax checks, tests, and guide generation on Node 24.13.0.
public/: browser interface and API documentationserver/: request handlers, search normalization and persistencescripts/start.mjs: local HTTP serverscripts/sqlite-store.mjs: local SQLite adapterdrizzle/: automatically applied database migrationstests/: functional and security regression tests
- Connect your key / 401: reconnect a valid SearchApi key in Connections.
- No results: verify the advertiser and try an appropriate country/status. An empty result is not proof of no advertising anywhere.
- Expired media: refresh the advertiser or use available copy and metadata; old CDN links may stop working.
- Rate limit: wait before retrying. Search caching and local request limits bound usage; they are not a substitute for monitoring your SearchApi account.
See CONTRIBUTING.md for local checks, bug reports and pull requests. Never include API keys, workspace tokens or private research data in issues or screenshots.
Ad Observatory is open source under the MIT License. See RELEASE.md for the release checklist.
