Articles on: Features Explained

๐Ÿ”— Public API

The Gethookd Public API lets you pull ad intelligence, competitor tracking data, saved collections, and AI-generated creatives directly into your own dashboards, reports, or internal tools โ€” no browser needed.


Whether you're building an internal analytics pipeline, syncing ad data to a spreadsheet, or automating your creative workflow, the API gives you programmatic access to the same features you use in the Gethookd app.



Before You Start


  • Plan required: every annual plan (Starter, Pro, Team or Agency), or a monthly Team or Agency plan. Monthly Starter and Pro don't include API access.
  • Credits: Reads cost 0.01 credits per item returned. Writes are billed in units, and one unit costs the same as one item read โ€” some writes are free, others take a few units. See Credits & Billing below.
  • Where to go: Log in to Gethookd โ†’ API & MCP in the left sidebar โ†’ REST API tab
  • Base URL: https://app.gethookd.ai/api/v1/
  • API reference: app.gethookd.ai/api/docs/v1 โ€” the full, always-current reference for every endpoint and parameter (also linked as View API reference on the API & MCP page). No token needed to read it.



Step 1: Generate Your API Key


  1. Go to API & MCP in the left sidebar and open the REST API tab
  2. Select the scopes your token needs from the dropdown. You can pick individual scopes (like "Explore Read" or "Brand Spy Write") or use All Features (Read) or All Features (Full Access) for broader access.
  3. Click Generate API Key
  4. Your new token appears in the table โ€” click the copy button to copy it to your clipboard
  5. Important: Store your token securely. You can reveal and copy it again later, but treat it like a password.


You can generate multiple keys with different scopes and revoke any key at any time.



Step 2: Authenticate Your Requests


Every API request must include your token in the Authorization header:


Authorization: Bearer YOUR_API_TOKEN


Test your token by calling the auth check endpoint:


GET /api/v1/authcheck


A successful response looks like:


{
  "errors": false,
  "data": {
    "authenticated": true,
    "workspace": {
      "id": 123,
      "name": "Your Workspace"
    },
    "scopes": ["explore:read"]
  }
}


If you see "authenticated": true, you're good to go.



Endpoints


Explore โ€” Search the Ad Library


Search and filter across 21M+ ads, just like the Explore page in the app.


GET /api/v1/explore


Scope required: explore:read


Query parameters:


Parameter

Type

Description

page

integer

Page number (default: 1)

per_page

integer

Results per page, 1โ€“100 (default: 20)

query

string

Free-text search (e.g., "supplements"). Runs as a keyword search: ads are matched on the words you type, and ads that only have a similar meaning are not added. The search mode can't be changed โ€” sending semantic_mode returns a 422.

sort_column

string

Sort by: created_at, start_date, days_active, used_count, popularity, performance_score (performance tier), ad_spend_range_score (estimated spend, 1 = lowest, 6 = highest), brand_rank_pct_impressions (the ad's rank inside its own brand โ€” use asc for best-first, the same order Explore shows by default), body_length (ad copy length โ€” desc puts the longest first)

sort_direction

string

asc or desc (default: desc)

start-date

date

Start of date range (YYYY-MM-DD). Requires end-date.

end-date

date

End of date range (must be >= start-date)

status

string

active or inactive

ad-format

string

Comma-separated: image, video, carousels, multi_images, multi_videos, dcos, dpas, events, page_likes, multi_medias, gated. Ads Meta only shows to logged-in viewers ("Hidden by Meta") are left out unless you include gated. A value that isn't an ad format returns a 422.

run-time

integer

Minimum days active

language

string

Comma-separated 2-letter codes: EN, ES, DE, etc.

platform

string

Comma-separated: facebook, instagram

niche

string

Comma-separated niche IDs. Get the current list from GET /api/v1/niches (free). Names aren't accepted โ€” a value that isn't an existing niche ID returns a 422.

performance_scores

string

Comma-separated: testing, scaling, growing, optimized, winning

used_count

integer

Minimum creative usage count

video_lengths

string

less_than_1_min, 1_to_3_min, 3_to_5_min, more_than_5_min

eu_transparency

integer

0 or 1

eu_total_reach

integer

Minimum EU reach

gender_audience

string

all, men, women

age_audience

string

Age brackets: 13-17, 18-24, 25-34, 35-44, 45-54, 55-64, 65+

location

string

2-letter country codes: US, DE, GB, etc.

ad_spend_range

string

Spend bucket IDs (1โ€“6)

excluded_brands

string

Brand IDs to exclude

creative_categories

string

Category IDs (see below)

cta_types

string

CTA types: SHOP_NOW, LEARN_MORE, SIGN_UP, DOWNLOAD, etc.

active_ads_count

integer

Minimum active ads per brand

ads_per_brand_limit

integer

Limit results per brand (1โ€“50)

min_ad_copy_length

integer

Minimum character length of the ad copy (e.g. 1000 to target long-form ads)

max_ad_copy_length

integer

Maximum character length of the ad copy

technologies

string

Comma-separated technology names found on the ad's landing page (e.g. Shopify, Checkout Champ). Use the names exactly as GET /api/v1/technologies returns them โ€” spacing matters, capitalisation doesn't. Add include=technologies to get each ad's technology list back in the results.

page_type

string

Landing-page type slug(s) from the Page Types endpoint (e.g. PDP, Funnel, Listicle, Advertorial)


Niche IDs (call GET /api/v1/niches for the live list): 1=Accessories, 2=Alcohol, 3=App/Software, 4=Automotive, 5=Beauty, 6=Book/Publishing, 7=Business/Professional, 8=Charity/NFP, 9=Info, 10=Entertainment, 11=Fashion, 12=Finance, 13=Food/Drink, 14=Games, 15=Government, 16=Health/Wellness, 17=Home/Garden, 18=Insurance, 19=Jewelry/Watches, 20=Kids/Baby, 21=Media/News, 22=Medical, 23=Pets, 24=Real Estate, 25=Service Business, 26=Sports/Outdoors, 27=Tech, 28=Travel, 29=Other, 30=Supplements


Creative Category IDs: 1=Before and After, 2=Testimonial/Reviews, 8=Promotion/Discount, 11=FAQ Explainers, 12=Holiday/Seasonal, 14=Humor/Fun, 16=Reasons Why, 17=Facts and Stats, 18=Features and Benefits, 19=Media and Press, 20=Us vs Them


Performance Score Tiers (boundaries): The performance_score field is a 0โ€“100 number; the named tiers used by the performance_scores filter map as follows.


Tier

Range

testing

1โ€“40

scaling

41โ€“60

growing

61โ€“80

optimized

81โ€“90

winning

91+


Example request:


GET /api/v1/explore?query=skincare&platform=facebook&status=active&per_page=10&sort_column=days_active&sort_direction=desc


Example response:


{
  "errors": false,
  "data": [
    {
      "id": 123,
      "external_id": "9999999",
      "platform": "facebook, instagram",
      "display_format": "video",
      "title": "Great offer",
      "body": "...",
      "landing_page": "https://example.com",
      "cta_type": "SHOP_NOW",
      "cta_text": "Shop Now",
      "start_date": "2025-01-05",
      "end_date": null,
      "days_active": 21,
      "active_in_library": 1,
      "used_count": 4,
      "performance_score": 120,
      "performance_score_title": "Winning",
      "share_url": "https://app.gethookd.ai/share/ad/123...",
      "brand": {
        "external_id": "2016485295279615",
        "name": "Acme",
        "logo_url": "https://...",
        "active_ads": 109
      },
      "media": [
        {
          "type": "video",
          "url": "https://...",
          "thumbnail_url": "https://..."
        }
      ]
    }
  ],
  "used_credits": 0.10,
  "remaining_credits": 199.90,
  "sorting": { "column": "days_active", "direction": "desc" },
  "filters": { "platforms": ["facebook"] }
}


Reading the Numbers in a Response


Any response that carries a count also tells you what was counted and when:


  • meta.count_basis_code โ€” what the number actually counts, so you never compare two numbers that measure different things.
  • meta.as_of โ€” when that number was measured.


When you filter by country, meta.excluded_no_geo tells you how many ads were left out because they carry no country data โ€” so a smaller result set is explained rather than silently short.


Invalid values are refused up front instead of failing vaguely: a country that isn't a two-letter code, a language, niche or ad format we don't recognise, or a brand_id that doesn't exist, comes back as a 422 naming the parameter โ€” never as an empty result. A parameter name we don't recognise (a typo such as nich=) is never quietly ignored either: the response carries a warnings list naming it, or the request is refused with a 422.



Get a Single Ad


Look up one ad by its internal ID. Returns the same ad object you get from Explore โ€” media, copy, performance score, and brand details.


Scope required: explore:read ยท Cost: free (no credits)


GET /api/v1/ads/{ad_id}


Transcribe Video Ads


Request transcripts for video ads, then poll until they're ready. Transcription runs in the background.


Scope required: explore:read ยท Cost: free (no API credits) ยท Your plan must include transcripts.


Call

What it does

POST /api/v1/ads/{ad_id}/transcribe

Request a transcript for one ad. If one already exists it comes back straight away.

POST /api/v1/ads/transcribe

Request transcripts for up to 50 ads at once: { "ad_ids": [1, 2, 3] }

GET /api/v1/ads/transcription-status?ad_ids[]=1&ad_ids[]=2

Check progress and read finished transcripts for up to 50 ads. complete is true when every video is done.



Brands โ€” Search the Catalog


Search Gethookd's full brand catalog, or look up one brand by ID. Handy for finding a brand's internal ID before adding it to Brand Spy.


Scope required: brand-spy:read ยท Cost: free (no credits)


Search brands


GET /api/v1/brands


Parameter

Type

Description

search

string

Free-text match against the brand name

parent_categories

string

Niche / category IDs (comma-separated)

sort_column

string

name, active_ads, or created_at (default: name)

sort_direction

string

asc or desc

page

integer

Page number (default: 1)

per_page

integer

Results per page, 1โ€“100 (default: 20)


Get a brand by ID


GET /api/v1/brands/{brand_id}


Returns the brand's name, logo, external ID, and active ad count.



Page Types โ€” Reference Data


Returns the list of active landing-page types (each with an id, slug, and title) โ€” for example PDP, Funnel, Listicle, and Advertorial. Pass a slug to the page_type filter on the Explore endpoint to narrow results to ads pointing at that kind of page.


Scope required: any valid token ยท Cost: free (no credits)


GET /api/v1/page-types



Brand Spy โ€” Track Competitors


Monitor competitors' ad activity programmatically. List your spied brands, view their ads, add new brands, or remove them.


Scope required: brand-spy:read (for GET), brand-spy:write (for POST/DELETE)


List your spied brands


GET /api/v1/brandspy


Parameter

Type

Description

page

integer

Page number (default: 1)

per_page

integer

Results per page, 1โ€“100 (default: 20)

sort_column

string

created_at, active_ads, inactive_ads, last_spied_at, ads_change, growth_percent. Any other value returns a 422.

sort_direction

string

asc or desc


Get a brand's ads


GET /api/v1/brandspy/{brand_id}


Parameter

Type

Description

per_page

integer

Ads per page, 1โ€“100 (default: 20)

status

string

active or inactive

platform

string

Filter by platform: facebook, instagram, tiktok, etc.


Returns the brand details plus a paginated list of their ads.


Add a brand to spy on


POST /api/v1/brandspy


Body (JSON):


{ "brand_id": 12345 }


Returns the newly spied brand. If the brand is already being spied on, you'll get a 409 Conflict.


Remove a spied brand


DELETE /api/v1/brandspy/{brand_id}


Get a brand's top-performing ads


GET /api/v1/brandspy/{brand_id}/top-ads


Returns a brand's currently-running ads, ranked by performance. brand_id accepts the brand's internal ID or its spied-brand record ID.


Scope required: brand-spy:read ยท Cost: free (no credits)


Parameter

Type

Description

limit

integer

Number of ads to return, 1โ€“50 (default: 10)

platform

string

Filter by platform: facebook, instagram, tiktok, etc.


Get a brand's top hooks


GET /api/v1/brandspy/{brand_id}/top-hooks


A hook is the opening line of a video ad, taken from its transcript. This returns the hooks of the brand's running ads with duplicates merged, ranked by how long the ad has run. limit 1โ€“50 (default 10), plus page. For one ad's hooks, call GET /api/v1/ads/{ad_id}/hooks. Both are free and only read transcripts that already exist.



Swipe File โ€” Saved Ads


Access your saved ads collection. List, save, and remove ads from your swipe file.


Scope required: swipe-file:read (for GET), swipe-file:write (for POST/DELETE)


List saved ads


GET /api/v1/swipefile


Parameter

Type

Description

page

integer

Page number (default: 1)

per_page

integer

Results per page, 1โ€“100 (default: 20)

sort_column

string

created_at, start_date, days_active, used_count

sort_direction

string

asc or desc

creative_categories

string

Comma-separated creative category IDs (same IDs as on Explore)

languages

string

Comma-separated 2-letter codes: EN, ES, DE, etc.

platforms

string

Comma-separated: facebook, instagram, tiktok

performance_scores

string

Comma-separated: testing, scaling, growing, optimized, winning

video_lengths

string

less_than_1_min, 1_to_3_min, 3_to_5_min, more_than_5_min

display_formats

string

Comma-separated: image, video, carousel


These filters mirror the in-app Swipe File filter panel, so the API can now return the same subsets you'd see by ticking filters in the UI.


Save an ad


POST /api/v1/swipefile


Body (JSON):


{ "ad_id": 12345 }


Remove a saved ad


DELETE /api/v1/swipefile/{ad_id}



Boards โ€” Organize Collections


Create and manage boards (folders) to organize ads into themed collections.


Scope required: boards:read (for GET), boards:write (for POST/PUT/DELETE)


List boards


GET /api/v1/boards


Parameter

Type

Description

page

integer

Page number (default: 1)

per_page

integer

Results per page, 1โ€“100 (default: 20)

sort_column

string

created_at, updated_at, name

sort_direction

string

asc or desc


Create a board


POST /api/v1/boards


Body (JSON):


{ "name": "Q1 Winners", "description": "Top-performing ads from Q1" }


Get board details with ads


GET /api/v1/boards/{board_id}


Update a board


PUT /api/v1/boards/{board_id}


Body (JSON):


{ "name": "Updated Name", "folder_id": 12 }


Send at least one field. folder_id (an ID from GET /api/v1/folders) moves the board into that folder.


Delete a board


DELETE /api/v1/boards/{board_id}


Add an ad to a board


POST /api/v1/boards/{board_id}/ads


Body (JSON):


{ "ad_id": 12345 }


Remove an ad from a board


DELETE /api/v1/boards/{board_id}/ads/{ad_id}


More board operations


Call

What it does

GET /api/v1/boards/{board_id}/ads

Page through one board's ads (page, per_page 1โ€“100, sort_column, sort_direction). Each ad also shows the performance score it had when it was added to the board, next to its live score.

POST /api/v1/boards/{board_id}/ads/bulk

Add up to 100 ads in one call: { "ad_ids": [1, 2, 3] }. The response says, per ad, whether it was added, already_on_board or not_found โ€” you're only charged for the ones added.

POST /api/v1/boards/{board_id}/copy

Duplicate a board with all its ads (up to 1,000). Optional name and folder_id.

GET /api/v1/folders

List the folders your boards live in (free). Pass a folder's ID as folder_id on GET /api/v1/boards to list just that folder, or add search to find boards by name.


Safe retries: send an Idempotency-Key header (any unique string up to 255 characters) with POST /api/v1/boards. Retrying with the same key within 24 hours returns the original response instead of creating a second board.



Saved Searches โ€” Reusable Explore Filters


Save the filter combinations you reach for most often (niche + creative category + languages + ad spend range, etc.) and reuse them programmatically. Saved Searches live on your workspace and can be created, listed, updated, and deleted entirely through the API.


Scope required: searches:read (for GET), searches:write (for POST/PUT/DELETE)


List saved searches


GET /api/v1/searches


Parameter

Type

Description

page

integer

Page number (default: 1)

per_page

integer

Results per page, 1โ€“100 (default: 20)



POST /api/v1/searches


Body (JSON):


{
  "name": "US Supplements โ€” Winners",
  "parent_categories": [30],
  "creative_categories": [1, 2, 18],
  "languages": [1],
  "excluded_brands": [123, 456],
  "gender_audience": "all",
  "age_audience": "25-34,35-44",
  "ad_spend_range": "5,6",
  "ads_per_brand_limit": 4
}


Field

Type

Required

Description

name

string

Yes

Display name, max 120 chars

parent_categories

array of integers

No

Niche IDs (see Niche IDs under Explore), max 50

creative_categories

array of integers

No

Creative category IDs, max 50

languages

array of integers

No

Internal language IDs, max 20

excluded_brands

array of integers

No

Brand IDs to exclude, max 100

gender_audience

string

No

all, men, or women

age_audience

string

No

Comma-separated age brackets (e.g. 25-34,35-44)

ad_spend_range

string

No

Comma-separated spend bucket IDs (1โ€“6)

ads_per_brand_limit

integer

No

Limit per brand, 1โ€“50


If you try to create a saved search with a name you have already used in this workspace, the API returns a clear validation error instead of silently creating a duplicate.



GET /api/v1/searches/{search_id}


Returns the saved-search record with the same fields you sent on create.



PUT /api/v1/searches/{search_id}


Body uses the same shape as the create endpoint. Only fields you include are updated.



DELETE /api/v1/searches/{search_id}


A 403 (not 404) is returned if you try to access a saved search that belongs to a different user โ€” by design, to avoid leaking IDs.



Clone Ads โ€” AI Ad Generation


Generate AI-powered ad variations based on existing ads, list your generation history, and retrieve results.


Scope required: clone-ads:read (for GET), clone-ads:write (for POST)


List clone history


GET /api/v1/clone-ads


Parameter

Type

Description

per_page

integer

Results per page, 1โ€“100 (default: 20)

sort_direction

string

asc or desc

search

string

Only clone ads whose title or source brand name contains this text


Each item in the response now includes:


  • variations_count โ€” how many variations the prompt requested
  • aspect_ratio โ€” Square, Portrait, or Landscape
  • model_slug โ€” which underlying model produced the generation
  • media[].is_product_reference โ€” true for the product image you provided, false for AI-generated outputs


This matches what you see on the Clone Ads history view in the app.


Generate cloned ad variations


POST /api/v1/clone-ads


Body (JSON):


{
  "ad_id": 12345,
  "prompt": "Make it more playful and summer-themed",
  "aspect_ratio": "Square",
  "variations_count": 3
}


Field

Type

Required

Description

ad_id

integer

Yes

The ad to use as inspiration

prompt

string

No

Custom instructions for the AI (max 4,000 chars)

aspect_ratio

string

No

Square (1:1), Portrait (9:16), Landscape (16:9), Portrait (2:3), Landscape (3:2), Portrait (3:4) or Landscape (4:3). The short names Square, Portrait and Landscape still work.

variations_count

integer

No

Number of variations to generate, 1โ€“10 (default: 3)

model_slug

string

No

Which image model to use. List the current models, and what each costs per variation, with GET /api/v1/clone-ads/models (free). Leave it out to use the default model.

reference_media_ids

array

No

Up to 5 images from your earlier clone ads to steer the result (IDs from GET /api/v1/clone-ads/{clone_id})

product_reference_image_ids

array

No

Up to 5 of your saved product images to steer the result (IDs from GET /api/v1/products/{product_id})


Note: Generation is asynchronous. The response returns the job details immediately. Poll the detail endpoint to check when your images are ready.


Get clone details


GET /api/v1/clone-ads/{clone_id}


Returns the generation details including all generated image variations and their URLs.



Credits & Billing


  • Cost: 0.01 credits per item returned (per ad, per brand, per board)
  • When you're charged: Only when data is successfully returned. Empty results cost nothing.
  • Writes are billed in units. One unit costs the same as one item read. Each kind of write takes a set number of units โ€” some are free, and creating something new takes the most.
  • See your current rates in the app: open Credits & Usage from your profile menu and click see what actions cost. The API & MCP group shows what one unit costs and how many units each write takes.
  • Clone Ads through the API are charged in two parts: a small request charge when you make the call, plus the image generation itself โ€” the same per-variation cost as generating clone ads inside the app, which depends on the model and the number of variations. The create response includes a billing breakdown with both parts (immediate_used_credits, deferred_used_credits and total_expected_used_credits), and GET /api/v1/clone-ads/models lists each model's cost per variation.
  • Every response includes used_credits and remaining_credits so you can track your balance.


If you run out of credits mid-request, you'll receive:


{
  "errors": true,
  "message": "Not enough credits",
  "data": {
    "feature": "public_api",
    "credits_needed": 0.16,
    "remaining_credits": "0.04",
    "feature_cost": 0.01
  }
}


Status code: 402 Payment Required



Rate Limits


To keep the API fast and fair for everyone, requests are limited per token, in three windows: per second, per minute and per hour. Your limits depend on your plan โ€” higher plans get more. The same limits apply to the MCP server.


You don't need to look them up: every response tells you your own limits in the headers below.


Every response includes rate limit headers so you know where you stand:


Header

Description

X-RateLimit-Limit-Second

Your per-second limit

X-RateLimit-Remaining-Second

Requests remaining this second

X-RateLimit-Limit-Minute

Your per-minute limit

X-RateLimit-Remaining-Minute

Requests remaining this minute

X-RateLimit-Limit-Hour

Your per-hour limit

X-RateLimit-Remaining-Hour

Requests remaining this hour

X-RateLimit-Reset-Second, X-RateLimit-Reset-Minute, X-RateLimit-Reset-Hour

When each window resets, as a Unix timestamp

Retry-After

Seconds to wait (only on 429 responses)


If you exceed a limit, you'll get a 429 Too Many Requests response. Just wait for the Retry-After period and try again. The response body tells you which limit you hit:


{
  "errors": true,
  "message": "Too many requests. Please slow down and try again later.",
  "limit_exceeded": "per_minute",
  "limit_bucket": "per_token_per_minute",
  "limit": 300,
  "retry_after": 12
}


Two kinds of call have an extra limit of their own: adding ads to a board (2 single adds per second per board, or 1 bulk add per second per board โ€” use the bulk endpoint to fill a board quickly), and searching the brand catalog (GET /api/v1/brands, 60 per minute).



Scopes Reference


Scopes control what each API token can access. When generating a token, you choose which scopes to grant.


Scope

Allows

explore:read

Search and filter the ad library

brand-spy:read

List spied brands and view their ads

brand-spy:write

Add or remove spied brands

swipe-file:read

List saved ads

swipe-file:write

Save or remove ads from swipe file

boards:read

List and view boards

boards:write

Create, update, delete boards and manage ads in boards

clone-ads:read

List clone history and view results

clone-ads:write

Generate new cloned ad variations

searches:read

List and view saved searches

searches:write

Create, update, and delete saved searches

brand-assets:read

List and view your brand profiles and products

brand-assets:write

Create, update, and delete brand profiles and products

shops:read

Search and view Shops (when your plan includes Shops)

account:read

Read your own notification and profile settings

account:write

Change your own notification and profile settings

support:write

Send a support request


Shorthand scope names: Token creation now also accepts the no-hyphen forms swipefile:read, swipefile:write, brandspy:read, and brandspy:write. They are stored as the canonical hyphenated form, so all downstream behavior is identical.


If a request requires a scope your token doesn't have, you'll get:


{
  "errors": true,
  "message": "Forbidden. Missing scope: brand-spy:read"
}


Status code: 403 Forbidden



Error Handling


All error responses follow the same format:


{
  "errors": true,
  "message": "Description of what went wrong"
}


Status Code

Meaning

401

Missing, invalid, or expired token

402

Not enough credits

403

Token is missing a required scope

404

Resource not found (e.g., brand or board doesn't exist), or the URL isn't an API endpoint

409

Conflict (e.g., brand already being spied on)

422

Validation error (invalid parameters)

429

Rate limit exceeded โ€” check Retry-After header



Troubleshooting


"Unauthenticated" error
Make sure your Authorization header starts with Bearer (with a space) followed by your full token. Double-check that the token hasn't been revoked.


My token stopped working
API access follows your subscription. If your subscription is paused or a payment is overdue, API calls are refused until it's active again โ€” your keys aren't deleted. And when someone is removed from a workspace, the API keys they created for it stop working straight away.


"Not enough credits" on every request
Check your remaining credits on your plan dashboard. You can purchase credit add-on packs or upgrade your plan for more credits.


"Forbidden. Missing scope" error
Your token doesn't have the right permissions for this endpoint. Generate a new token with the required scope.


Empty results when filtering
Try broadening your filters. Remove one filter at a time to identify which one is too restrictive. Make sure date ranges and niche/category IDs are valid.


Rate limited (429 errors)
Slow down your request rate. Check the Retry-After header and wait that many seconds before retrying. Consider adding a small delay between requests in your code.



Workflow Ideas & Integration Tips


The API really shines when you connect it to other tools. Here are some ready-to-use workflows to get you started.


1. Competitor Strategy Brief (Zapier + Google Docs)


Tools: Zapier, Google Docs, Gethookd API


How it works:

  1. Set a Zapier schedule trigger (e.g., every Monday morning)
  2. Use the Explore endpoint to pull the top 20 active ads for a competitor's niche
  3. Feed the ad copy and CTA data into a Google Doc template
  4. Share the doc automatically with your team via Slack or email


Great for: Weekly competitive intelligence reports without lifting a finger.



2. Niche Trend Tracker (Make + Google Sheets)


Tools: Make (formerly Integromat), Google Sheets, Gethookd API


How it works:

  1. Schedule a Make scenario to run daily
  2. Call the Explore endpoint filtered by your niche (e.g., niche=30 for Supplements) and sorted by start_date desc
  3. Append new ads to a Google Sheet with columns: brand, headline, CTA, days active, performance score
  4. Add a chart to visualize trends over time


Great for: Spotting emerging creative trends and seasonal patterns in your niche.



3. AI-Powered Copy Analysis (API + Claude or ChatGPT)


Tools: Any AI assistant (Claude, ChatGPT, etc.), Gethookd API


How it works:

  1. Pull the top 50 active ads in your niche with sort_column=days_active&sort_direction=desc
  2. Extract the body and cta_type fields from the response
  3. Paste into your AI tool with a prompt like: "Analyze these 50 ad copies. What are the top 5 hooks used? What CTAs convert best? Give me 3 new ad angles I haven't seen."


Great for: Turning raw ad data into actionable creative strategy in minutes.



4. Auto-Save Winning Ads to Boards (Custom Script)


Tools: A simple script (Python, Node.js, etc.), Gethookd API


How it works:

  1. Run a daily cron job that calls the Explore endpoint with performance_scores=winning&status=active
  2. For each ad returned, call POST /api/v1/boards/{board_id}/ads to add it to your "Winners" board
  3. Optional: check if the ad is already saved to avoid duplicates


import requests

headers = {"Authorization": "Bearer YOUR_TOKEN"}

# Get winning ads
ads = requests.get(
"https://app.gethookd.ai/api/v1/explore",
params={"performance_scores": "winning", "status": "active", "per_page": 20},
headers=headers
).json()["data"]

# Save to board
for ad in ads:
requests.post(
f"https://app.gethookd.ai/api/v1/boards/YOUR_BOARD_ID/ads",
json={"ad_id": ad["id"]},
headers=headers
)


Great for: Building a curated collection of proven winners on autopilot.



5. Agency Client Reporting (Zapier + Notion or Airtable)


Tools: Zapier, Notion or Airtable, Gethookd API


How it works:

  1. Use the Brand Spy endpoint to pull each client's competitor ads weekly
  2. Push the data into a Notion database or Airtable base, one row per ad
  3. Share a filtered view with each client showing only their competitors
  4. Bonus: add a Zapier step to email the client a summary


Great for: Agencies who want to deliver ongoing competitive intelligence to clients without manual work.



6. Clone Ad Variations on Autopilot (Custom Script)


Tools: A script + Gethookd API


How it works:

  1. Pull top-performing ads from Explore (e.g., performance_scores=winning)
  2. For each ad, call POST /api/v1/clone-ads with a custom prompt (e.g., "Make it holiday-themed")
  3. Poll GET /api/v1/clone-ads/{clone_id} until images are ready
  4. Download the generated images or push them to your design tool


Great for: Quickly generating creative variations for A/B testing without a designer.



Tips & Best Practices


Tip

Why It Matters

Start with authcheck

Always verify your token works before building a full workflow

Use specific scopes

Generate tokens with only the scopes each workflow needs โ€” easier to revoke if compromised

Add per_page=1 for testing

Saves credits while you're building and debugging your integration

Cache responses locally

Avoid burning credits by re-fetching the same data โ€” cache results for at least a few hours

Handle 429s gracefully

Add retry logic with the Retry-After header value so your automation doesn't break

Monitor remaining_credits

Every response includes your balance โ€” set up an alert when credits drop below a threshold

Combine endpoints

Use Explore to discover ads, then Boards to organize them, then Clone Ads to generate variations โ€” one pipeline, three endpoints



FAQs


Does using the API cost extra beyond my plan?
No extra subscription cost โ€” API access is included with every annual plan and with monthly Team and Agency. You pay with the same credits included in your plan. Each item returned costs 0.01 credits.


Can I use the API on the Starter plan?
Yes, on an annual Starter plan. Monthly Starter doesn't include API access โ€” switch to annual billing, or move up to Team or Agency, from your account settings.


I'm on a monthly Team or Agency plan. Do I have API access?
Yes. API access is included on monthly Team and Agency โ€” you don't need annual billing.


Do I need an annual plan for API access?
Only on Starter or Pro. Team and Agency include API access on monthly billing too.


I'm on a free trial. Do I have API access?
If you picked Team or Agency (monthly or annual), or any annual plan, yes โ€” API access is part of that plan from the start.


How do I revoke a compromised token?
Go to API & MCP โ†’ REST API tab, find the key in the table, and click Revoke. The token stops working immediately. Then generate a new one.


Can I create multiple API tokens?
Yes! You can generate as many tokens as you need โ€” for example, one per integration or team member. Each can be revoked independently.


Is there a way to test the API without writing code?
The API reference lists every endpoint with its parameters and example responses. To try a call without code, add per_page=1 and send it from any HTTP client with your token.


What format are dates in?
All dates in requests and responses use YYYY-MM-DD format (e.g., 2025-06-15).


Can I use the API with AI tools like Claude Code or ChatGPT?
Yes! Pull ad data from the Explore endpoint and feed it into your favourite AI tool to analyze competitor hooks, copy patterns, and CTAs across a niche. For example, you could pull the top 50 active skincare ads and ask AI to summarize the most common hooks and calls to action being used.


Can I connect the API to Zapier or Make?
Absolutely. Use the Explore endpoint as a data source in Zapier or Make to auto-export ads matching your filters to Google Sheets or Airtable on a schedule, send a Slack notification when you pull fresh ads for your niche, or feed ad data into any tool in your workflow.


What can I build with custom scripts?
Anything that benefits from fresh ad data on autopilot โ€” internal dashboards that pull winning ads daily, automated competitor creative reports for agency clients, or scripts that track ad trends in your niche over time and flag new patterns.




Updated on: 13/10/2026

Was this article helpful?

Share your feedback

Cancel

Thank you!