Skip to content
Ads LighthouseStart free trialStart trial

Developers

Ads Lighthouse API

Read saved observations, histories and reports. Update projects, workspace settings and reviews, with the same rules and limits as the app.

The REST API is included in the Scale plan and above, including trials of those plans. The MCP server is included in every plan.

Authentication

Create a key in Settings > API and MCP. The account owner and account admins can create keys. The full key is shown only once. Choose read only, or read and write.

Send the key in the Authorization header of every request. A key acts for the whole account. It stops working as soon as it is revoked, or when the person who created it leaves the account or stops being an admin.

The API does not accept browser sessions or cross-origin browser requests. Keep keys on a server or in a secret manager.

Header
Authorization: Bearer als_your_key

Quick start

List your projects, then read the last 7 days of saved checks for one of them. Every project endpoint accepts the project id, the brand domain or the exact project name.

curl
# List your projects
curl -s https://adslighthouse.com/api/v1/projects \
  -H "Authorization: Bearer $ADS_LIGHTHOUSE_API_KEY"

# Saved checks for one project in the last 7 days, Google on mobile
curl -s -G https://adslighthouse.com/api/v1/projects/nike.example/observations \
  -H "Authorization: Bearer $ADS_LIGHTHOUSE_API_KEY" \
  --data-urlencode "range=7d" \
  --data-urlencode "engine=google" \
  --data-urlencode "device=mobile"
TypeScript (fetch)
const base = "https://adslighthouse.com/api/v1";
const headers = { Authorization: `Bearer ${process.env.ADS_LIGHTHOUSE_API_KEY}` };

// Advertisers seen on the project's searches, busiest first
const response = await fetch(`${base}/projects/nike.example/advertisers?range=30d`, { headers });
if (!response.ok) {
  const { error, request_id } = await response.json();
  throw new Error(`${error.code}: ${error.message} (${request_id})`);
}
const report = await response.json();
for (const advertiser of report.data)
  console.log(advertiser.domain, advertiser.visibility, report.note ?? "");

Endpoints

All paths are relative to the base URL below. Read endpoints need the read scope, and changes need write access. Each endpoint lists its scope and side effects.

Base URL
https://adslighthouse.com/api/v1
MethodPathWhat it doesScope
GET/accountPlan, monthly allowances, usage and rate limitread
GET/projectsProjects in the accountread
POST/projectsCreate a project and start its first checkswrite
GET/projects/{project_id}One project's configuration and data coverageread
PATCH/projects/{project_id}Change a project's monitoring plan, brand or affiliate settingswrite
DELETE/projects/{project_id}Permanently delete a project and its saved datawrite
GET/projects/{project_id}/keywordsMonitored keywords with saved checks and ads in a windowread
POST/projects/{project_id}/keywordsAdd keywords to a projectwrite
DELETE/projects/{project_id}/keywordsStop monitoring several keywordswrite
DELETE/projects/{project_id}/keywords/{keyword_id}Stop monitoring one keywordwrite
GET/projects/{project_id}/observationsSaved checks with the paid ads they foundread
GET/projects/{project_id}/advertisersAdvertiser domains with visibility and signalsread
GET/projects/{project_id}/affiliate-findingsYour affiliate IDs seen behind ads that use your brandread
GET/alert-eventsAlerts fired for the accountread
POST/projects/{project_id}/checksStart an on-demand check of a project's keywordswrite
GET/projects/{project_id}/checksA project's recent background activity and queued searchesread
GET/projects/{project_id}/checks/{run_id}Progress of an on-demand checkread
GET/projects/{project_id}/analyticsChart-ready paid-search and Shopping aggregates for one projectread
GET/projects/{project_id}/organic-observationsOrganic search observations with detailed result contentread
GET/projects/{project_id}/summaryHeadline numbers for a project and windowread
GET/projects/{project_id}/timeseriesChecks, ads and advertisers by local day, week or monthread
GET/projects/{project_id}/advertisers/{domain}One advertiser's metrics, category and saved adsread
GET/projects/{project_id}/competitorsOther advertisers ranked by ad occurrences, with your categoriesread
POST/projects/{project_id}/advertisers/{domain}/classificationSave your team's category for an advertiser domainwrite
GET/projects/{project_id}/keywords/{keyword_id}/reportOne keyword's saved checks, ads and advertisers in a windowread
GET/projects/{project_id}/keywords/{keyword_id}/adsAdvertisers or distinct ads seen for one keywordread
GET/projects/{project_id}/affiliate-idsYour affiliate IDs seen in saved ad URLsread
POST/projects/{project_id}/affiliate-findings/{affiliate_id}/statusSet the review status of a non-compliant affiliate IDwrite
POST/projects/{project_id}/affiliate-findings/statusSet one review status on several non-compliant affiliate IDs at oncewrite
GET/projects/{project_id}/shopping-productsSponsored product listings seen on Google Shopping capturesread
GET/projects/{project_id}/exports/paid-resultsThe rows of the Paid results CSV export, as JSONread
GET/projects/{project_id}/exports/paid-results-by-keywordThe rows of the Paid results By keyword view, as JSONread
GET/projects/{project_id}/exports/affiliate-casesThe rows of the Non-compliant affiliates CSV export, as JSONread
GET/projects/{project_id}/exports/affiliate-cases/{affiliate_id}/adsEvery ad behind one non-compliant affiliate ID, as in the Send report CSVread
GET/projects/{project_id}/advertisers/{domain}/historyWhen and where one advertiser appeared, with the observation scheduleread
GET/projects/{project_id}/advertisers/{domain}/heatmapPresence by local hour and weekdayread
GET/projects/{project_id}/advertisers/{domain}/ad-copyOne advertiser's distinct ad copy, newest firstread
GET/projects/{project_id}/ad-copy-changesRecent ad copy changes across advertisersread
GET/projects/{project_id}/advertisers/{domain}/identityWho Google's Ads Transparency Center says advertises to a domainread
POST/projects/{project_id}/advertisers/{domain}/identityRead Google's Ads Transparency record for an advertiser domain (1 on-demand check)write
GET/projects/{project_id}/advertiser-identity-settingsWhether new advertiser domains are looked up automaticallyread
POST/projects/{project_id}/advertiser-identity-settingsTurn automatic advertiser identity lookups on or offwrite
POST/check-demandForecast the monthly checks and allowance for a proposed changeread
GET/monitoring-optionsMarkets, search engines, devices and schedules you can configureread
GET/locationsFind cities and regions available for monitoring in a marketread
GET/account/time-zoneYour personal time zone preferenceread
PATCH/account/time-zoneChange your personal time zone preferencewrite
GET/account/themeYour personal appearance preferenceread
PATCH/account/themeChange your personal appearance preferencewrite
GET/alert-rulesAlert rules configured in the accountread
POST/alert-rulesCreate an alert rule (email, Slack or webhook)write
GET/alert-rules/{rule_id}One alert ruleread
POST/alert-rules/{rule_id}Enable, disable or change an alert rulewrite
DELETE/alert-rules/{rule_id}Delete an alert rule and its alert historywrite
POST/alert-rules/{rule_id}/testQueue a synthetic alert through a rule's channelwrite
GET/alert-rules/{rule_id}/previewWhat a summary rule's next delivery would contain so farread
POST/alert-rules/{rule_id}/rotate-secretReplace a webhook rule's signing secretwrite
GET/alert-events/{event_id}One alert with its delivery recordread
GET/teamMembers, roles and open invitationsread
POST/team/invitationsEmail an invitation to join the accountwrite
POST/team/invitations/{invitation_id}/resendSend an open invitation again with a new linkwrite
DELETE/team/invitations/{invitation_id}Revoke an open invitationwrite
POST/team/members/{user_id}Make a member an admin or an admin a memberwrite
DELETE/team/members/{user_id}Remove a person from the accountwrite
GET/accountsThe account this credential can useread
GET/account/overviewPlan limits, subscription dates, meters and forecastread
GET/me/email-preferencesYour product email and newsletter preferencesread
POST/me/email-preferencesTurn product emails or the newsletter on or offwrite
GET/projects/{project_id}/google-connectionsYour Google Ads and Search Console connections in a projectread
GET/projects/{project_id}/google-connections/{connection_id}/accountsGoogle Ads customers or Search Console sites a connection can readread
GET/projects/{project_id}/google-connections/{connection_id}/ads-reportKeyword or search term performance from Google Adsread
GET/projects/{project_id}/google-connections/{connection_id}/search-console-reportSearch Console clicks, impressions, CTR and positionread
POST/projects/{project_id}/redirect-tracesQueue a server-side trace of a saved ad destinationwrite
GET/projects/{project_id}/redirect-tracesTraced redirect chains of a projectread
GET/projects/{project_id}/redirect-traces/{trace_id}One traced redirect chainread
GET/projects/{project_id}/redirect-traces/{trace_id}/archive-linkA short-lived link to download a trace's web archive (.warc.gz)read
GET/projects/{project_id}/policy-rulesA project's policy rulesread
POST/projects/{project_id}/policy-rulesDeclare a policy rule for a projectwrite
GET/projects/{project_id}/policy-rules/{rule_id}One policy ruleread
POST/projects/{project_id}/policy-rules/{rule_id}Rename, pause, reconfigure or rescope a policy rulewrite
DELETE/projects/{project_id}/policy-rules/{rule_id}Delete a policy rule and keep its caseswrite
POST/projects/{project_id}/policy-rule-previewWhat a draft rule would match, without saving itread
POST/projects/{project_id}/policy-rule-evaluationCheck saved ads against the enabled rules and record caseswrite
GET/projects/{project_id}/policy-casesCases opened by policy rulesread
GET/projects/{project_id}/policy-cases/{case_id}One case with its timelineread
POST/projects/{project_id}/policy-cases/{case_id}Change a case's status or ownerwrite
GET/projects/{project_id}/policy-cases/{case_id}/evidenceThe saved ads that matched a case's ruleread
POST/projects/{project_id}/policy-cases/{case_id}/notesAdd a note to a case's timelinewrite
GET/projects/{project_id}/trademarkThe project's trademark, registrations, owner and contactread
POST/projects/{project_id}/trademarkSave the project's trademark details for complaintswrite
GET/projects/{project_id}/complaint-packageWhat a platform's trademark complaint form asks for, from one caseread
GET/projects/{project_id}/case-complaintsThe complaints recorded on a case and their outcomesread
POST/projects/{project_id}/case-complaintsRecord that a complaint was filed on a platform's formwrite
POST/projects/{project_id}/case-complaints/{complaint_id}/outcomeRecord what the platform decided about a filed complaintwrite
GET/outreach-templatesThe account's message templates for partners and advertisersread
POST/outreach-templatesAdd one of the account's own outreach templateswrite
POST/outreach-templates/{template_id}Edit a default or one of the account's own templateswrite
DELETE/outreach-templates/{template_id}Delete the account's own template, or restore a defaultwrite
GET/projects/{project_id}/outreach-messageA ready-to-send message for a case from a templateread
POST/projects/{project_id}/outreach-recordsRecord on a case that a message was sent to the partner or advertiserwrite
POST/projects/{project_id}/evidence-packsRequest a PDF of one case for legal teams, networks or a complaintwrite
GET/projects/{project_id}/evidence-packs/{pack_id}Status of one case evidence packread
GET/projects/{project_id}/evidence-packs/{pack_id}/download-linkA short-lived link to download a ready evidence packread
GET/projects/{project_id}/affiliate-findings/{affiliate_id}/caseOne non-compliant affiliate case with its timelineread
POST/projects/{project_id}/affiliate-findings/{affiliate_id}/notesAdd a note to an affiliate case's timelinewrite
POST/projects/{project_id}/reportsRequest a project PDF report for a window and filterswrite
GET/projects/{project_id}/reportsA project's PDF reports, newest firstread
GET/projects/{project_id}/reports/{report_id}Status of one PDF reportread
GET/projects/{project_id}/reports/{report_id}/download-linkA short-lived link to download a ready reportread
GET/account/report-brandingThe account's agency branding for white-label PDFsread
PATCH/account/report-brandingChange the account's agency branding for white-label PDFswrite
DELETE/account/report-brandingRemove the account's agency brandingwrite
POST/feedbackSend product feedback to the Ads Lighthouse teamwrite
GET/projects/{project_id}/reports/{report_id}/pdfDownload a ready PDF reportread
GET/projects/{project_id}/evidence-packs/{pack_id}/pdfDownload a ready case evidence packread
GET/projects/{project_id}/screenshots/{screenshot_id}Download a results-page screenshotread
GET/projects/{project_id}/shopping-products/{product_id}/imageFetch a saved Shopping product imageread
GET/projects/{project_id}/landing-screenshots/{page_id}Download a captured page previewread

Dates and filters

Reports use the same filters as the app: engine, device, os, country and location. Send one value, repeat the parameter, or pass a JSON array such as engine=["google","bing"]. Values in one filter combine with OR, and different filters combine with AND.

Dates default to the last 30 days. Use range=7d, 14d, 30d or 12m, or range=custom with from and to (YYYY-MM-DD). Days start and end in the time zone of the person who created the key, or in the IANA time zone you pass as time_zone. The response echoes the exact window it used.

Pagination

Lists return data and next_cursor. Pass next_cursor as cursor to get the next page, with the same filters. It is null on the last page. limit accepts 1 to 200 and defaults to 50.

Report rows, such as advertisers, are computed for the whole filtered selection before paging, so shares do not depend on the page size.

Changes and paid checks

Write operations can update projects, keywords, alert rules, team access, policy and affiliate reviews, and personal settings. Some also send invitations or test alerts, request reports, or trace saved ad destinations. Check each endpoint's scope and effects before you call it.

Creating a project and running an on-demand check start searches that use your plan's allowance. Both need an Idempotency-Key header with a unique value, such as a UUID. Repeating a request with the same key returns the first result and does not use your allowance or run the checks again. Reusing a key for a different request returns 409.

Checks run in the background. Poll the check status endpoint, then read the results from the observations endpoint.

Start an on-demand check
curl -s -X POST https://adslighthouse.com/api/v1/projects/nike.example/checks \
  -H "Authorization: Bearer $ADS_LIGHTHOUSE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"device": "mobile"}'

How to read the results

An observation is one saved check: one search result page for a keyword, engine, device and location at one moment. It shows that an ad appeared. It does not prove a purchased keyword, spend or an infringement.

visibility is the share of saved observations in the selection where a domain showed at least one ad. It is not impression share. ads_observed counts ad occurrences, not unique advertisers. When a report is based on few observations, the note field says so.

get_analytics returns chart-ready aggregates for the selected project, window and filters. Its active_keywords count covers the whole project and ignores the window and observation filters. Imported studies do not record engine or country, so they are left out when you filter by either. Shopping data is null when the plan does not include Shopping.

Observations and related history rows are kept for three UTC calendar months. An empty older window does not prove an advertiser or ad was absent: the records may have expired.

Errors

Errors use one envelope with a stable code, a message and, for invalid input, field details. Every response carries a request_id; include it if you contact us.

Error response
{
  "error": {
    "code": "invalid_request",
    "message": "The request has invalid parameters.",
    "details": [{ "field": "os", "message": "Operating system does not match device" }]
  },
  "request_id": "5f0c1c1e-8f7a-4c52-9a55-2f1c3e8b7d10"
}
StatusCodesMeaning
400invalid_request, idempotency_key_requiredInvalid parameters, body or cursor.
401unauthorizedMissing, invalid or revoked key.
403insufficient_scope, plan_required, quota_exceededThe key is read only, the plan does not include the API, or the allowance is used up.
404not_foundNo such project, keyword or check in this account.
409idempotency_key_reusedThe key was used for a different request.
429rate_limitedToo many requests. Wait for Retry-After.
503unavailableA required file or service is temporarily unavailable.

Rate limits

Each key or connected app may make 120 requests per minute. Responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 response includes Retry-After in seconds. After repeated failed authentication, an address is blocked for a few minutes.

Questions

Can I use the API on the Starter or Growth plan?

The REST API and API keys are included in Scale, Business and Enterprise, including trials of those plans. Every plan, Starter and Growth included, can connect an AI assistant to the MCP server by signing in and export any report table to CSV or Excel.

Does the API run searches when I read data?

No. Read endpoints only return saved checks. Searches run on your monitoring schedule, or when you create a project or start an on-demand check.

Are landing page captures available?

Some ad reports include metadata for a saved landing-page preview. REST clients can fetch its private JPEG when one exists, and MCP returns the preview metadata and an app link. New previews are built from saved HTML and may load static styles, images and fonts when the preview is generated, so those assets can differ from the original capture. Scripts and nested documents stay disabled. The API does not return captured page text or full HTML.

See who's advertising on your brand today.

Start your 7-day free trial. Cancel anytime.