Emails

The email endpoints let you explore the emails brands send their subscribers: marketing newsletters, abandoned-cart reminders, and sign-up confirmations. Search every email we track, pull one brand's emails, sample a trending feed, and chart how brands send. On this page, we will look at the email record and every email endpoint.

The email endpoints work the way the ad endpoints do: the same { data, pagination } response, the same pagination, the same fields= selection, and the same brand-side filters.

The email record

Default fields

id, brand_id, timestamp, type, subject, preview_text, from_name, from_email, email_provider, screenshot_url, plus dashboard_url on every row.

All available fields

  • Name
    id
    Type
    string
    Description

    The email's identifier. Every email endpoint takes it, and it is always returned.

  • Name
    brand_id
    Type
    string
    Description

    The brand that sent the email (its domain, e.g. retro-stage.com). Always returned.

  • Name
    timestamp
    Type
    string
    Description

    When the email was sent (ISO 8601, UTC).

  • Name
    type
    Type
    string
    Description

    What kind of email it is: marketing (newsletters and campaigns), abandoned_cart (reminders about a cart left behind), or subscription_confirmation (the welcome after a sign-up). See GET /v1/facets/email-types.

  • Name
    subject
    Type
    string
    Description

    The subject line, as plain text.

  • Name
    preview_text
    Type
    string
    Description

    The preview line shown next to the subject in the inbox, as plain text. Absent when the email has none.

  • Name
    from_name
    Type
    string
    Description

    The sender name shown in the inbox.

  • Name
    from_email
    Type
    string
    Description

    The sender address.

  • Name
    reply_to
    Type
    string
    Description

    The reply-to address, when the email sets one.

  • Name
    email_provider
    Type
    string
    Description

    The email platform the brand sent it with (shopify, klaviyo, omnisend, mailchimp, …), when we can tell.

  • Name
    has_checkout
    Type
    boolean
    Description

    true for an abandoned-cart email. An older flag that type replaces: filter on type=abandoned_cart instead.

  • Name
    has_unsubscribe
    Type
    boolean
    Description

    Whether the email carries an unsubscribe link.

  • Name
    link_count
    Type
    integer
    Description

    How many links the email contains.

  • Name
    image_count
    Type
    integer
    Description

    How many images the email contains.

  • Name
    screenshot_url
    Type
    string
    Description

    A picture of the whole email. Expires 3 days after the response is issued.

  • Name
    dashboard_url
    Type
    string
    Description

    The email's page in the Brandsearch app.

reply_to, has_checkout, has_unsubscribe, link_count, and image_count are returned only when you ask for them with fields=. id, brand_id, screenshot_url, and dashboard_url come back whatever you select. GET /v1/facets/fields lists the fields under emails.

Sort fields

timestamp (the send date, the default), link_count, image_count. Aliases: recent, date, and sent for timestamp; links for link_count; images for image_count.


Email filters

Every endpoint that lists emails accepts these filters.

  • Name
    q
    Type
    string
    Description

    Search the subject line and the preview text. The words must appear in order, and the last one may be the start of a word, so black fri matches "Black Friday". Separate alternatives with two spaces to match any of them (up to 5): black friday cyber monday. Max 200 characters. A small share of emails store punctuation in an encoded form that a phrase containing an apostrophe or an ampersand does not match; searching on the words around it finds them.

  • Name
    type
    Type
    string
    Description

    One or more email types, comma-separated: marketing, abandoned_cart, subscription_confirmation. Case-insensitive. Any other value is a 400 invalid_parameter.

  • Name
    sent_from
    Type
    string
    Description

    Emails sent on or after this date. YYYY-MM-DD means the start of that day in UTC; an ISO 8601 timestamp or unix seconds is an exact moment.

  • Name
    sent_to
    Type
    string
    Description

    Emails sent on or before this date. YYYY-MM-DD includes that whole day in UTC, so sent_from=2026-09-01&sent_to=2026-09-01 returns the emails sent on September 1.

  • Name
    sort_by
    Type
    string
    Description

    timestamp (default), link_count, or image_count, or one of their aliases.

  • Name
    sort_order
    Type
    string
    Description

    desc (default) or asc. Unlike the ad endpoints, sort_order=asc on its own lists the oldest emails first.

  • Name
    fields
    Type
    string
    Description

    Comma-separated list of email fields to return.


GET/v1/emails/search

Search emails

Search every email we track across all brands, newest first. Combine the email filters with any brand-side filter to narrow it to the brands you care about.

Costs 1 credit per email returned.

Search and email filters

q, type, sent_from, sent_to, sort_by, sort_order, fields: see email filters.

Brand-side filters

All brand-side filters work here: niche, monthly_visits_min/max, markets, country_code, currency_code, apps, techs, payments, platform, min_revenue_*, max_revenue_*, meta_ads_active, product_count_min/max, and their _exclude forms.

Results come from at most 10,000 of the brands a brand-side filter matches, and pagination.total counts only their emails. A broad filter such as niche=Fashion matches far more brands than that, so narrow it (by country or traffic, for example) when you need complete results. brand_ids is not limited this way.

  • Name
    brand_ids
    Type
    string
    Description

    Comma-separated brand IDs (max 200). Only emails from these brands are returned.

Pagination & output

  • Name
    page
    Type
    integer
    Description

    Page number. Default 1. A search can be paged through its first 10,000 results; a page past that is a 400 invalid_parameter whose details.max_page names the last page you can reach.

  • Name
    page_size
    Type
    integer
    Description

    Results per page (1-100). Default 20.

  • Name
    max_emails_per_brand
    Type
    integer
    Description

    Cap how many emails from any single brand appear on a page (1-20). pagination.total still counts every matching email, and a page can come back a little shorter than page_size when a few brands send most of the top results.

Request

GET
/v1/emails/search
curl -G https://api.brandsearch.co/v1/emails/search \
  -H "X-API-Key: bsk_your_api_key" \
  -d q="black friday" \
  -d niche=Fashion \
  -d sent_from=2026-01-01 \
  -d page_size=2

Response

{
  "data": [
    {
      "id": "3510c738f80186f20e6dfae84a4c8543",
      "brand_id": "freecountry.com",
      "timestamp": "2026-07-26T19:01:03.635000+00:00",
      "type": "marketing",
      "subject": "60% Off Select Styles + Free Shipping Today Only!",
      "preview_text": "FINAL HOURS: 55% OFF all summer styles during our Black Friday in July Sale!",
      "from_name": "Free Country",
      "from_email": "noreply@freecountry.com",
      "screenshot_url": "https://cdn.brandsearch.co/emails/3510c738f80186f20e6dfae84a4c8543.png",
      "dashboard_url": "https://app.brandsearch.co/emails/3510c738f80186f20e6dfae84a4c8543"
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 2,
    "total": 10,
    "total_pages": 5
  }
}

POST/v1/emails/query

Query emails (JSON body)

The same search as GET /v1/emails/search, with the filters in a JSON body. Use it when the filter set is too long for a URL. List filters (type, brand_ids, niche, apps, markets, …) take real arrays, and page / page_size go inside the body. An unknown key is a 400 validation_error.

Costs 1 credit per email returned.

cURL

curl https://api.brandsearch.co/v1/emails/query \
  -H "X-API-Key: bsk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": ["abandoned_cart"],
    "brand_ids": ["retro-stage.com", "ryzesuperfoods.com"],
    "sent_from": "2026-06-01",
    "page": 1,
    "page_size": 20
  }'

GET/v1/brands/:brand_id/emails

List a brand's emails

One brand's emails, newest first: the Emails tab of the brand's page in the Brandsearch app. An unknown brand returns an empty page rather than an error.

Accepts the email filters (q, type, sent_from, sent_to, sort_by, sort_order, fields), plus page (default 1) and page_size (1-100, default 20).

Costs 1 credit per email returned.

Request

GET
/v1/brands/:brand_id/emails
curl -G https://api.brandsearch.co/v1/brands/retro-stage.com/emails \
  -H "X-API-Key: bsk_your_api_key" \
  -d type=abandoned_cart \
  -d page_size=2

Response

{
  "data": [
    {
      "id": "bfd7c60dd0d6156e78f6b186beb96095",
      "brand_id": "retro-stage.com",
      "timestamp": "2026-09-15T23:44:52.186000+00:00",
      "type": "abandoned_cart",
      "subject": "Hurry! Your cart is about to expire!",
      "preview_text": "This is your last chance",
      "from_name": "Retro Stage - Chic Vintage Dresses and Accessories",
      "from_email": "service@retro-stage.com",
      "screenshot_url": "https://cdn.brandsearch.co/emails/bfd7c60dd0d6156e78f6b186beb96095.png",
      "dashboard_url": "https://app.brandsearch.co/emails/bfd7c60dd0d6156e78f6b186beb96095"
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 2,
    "total": 8,
    "total_pages": 4
  }
}

GET/v1/emails/discover

Discover emails

A random sample of marketing emails from trending brands: brands in top markets and currencies with real traffic, or recently added. Build an inspiration feed around it. The sample changes on every call unless you pin seed.

Costs 1 credit per email returned.

  • Name
    limit
    Type
    integer
    Description

    Sample size (1-500). Default 30.

  • Name
    seed
    Type
    string
    Description

    Reproducibility seed (max 64 characters). The same seed and filters return the same sample. The response echoes the seed it used.

  • Name
    max_emails_per_brand
    Type
    integer
    Description

    Cap how many emails from any single brand appear in the sample (1-20).

  • Name
    type
    Type
    string
    Description

    Replaces the default, marketing, with the types you list.

  • Name
    sent_from
    Type
    string
    Description

    The sample spans every send date unless you set this. Pass a recent date for recent emails only.

q, sent_to, and fields work as in the email filters, and the brand-side filters narrow the brands the sample is drawn from. brand_ids and country_code are not supported here and are ignored: use search to pull specific brands.

cURL

curl -G https://api.brandsearch.co/v1/emails/discover \
  -H "X-API-Key: bsk_your_api_key" \
  -d limit=2 \
  -d seed=newsletter-ideas

Response

{
  "data": [
    {
      "id": "87fc2d07e5dc120b437aaa2d354ebfe3",
      "brand_id": "maydetea.com",
      "timestamp": "2026-05-20T23:33:02.404000+00:00",
      "type": "marketing",
      "subject": "Almost Brewed!",
      "preview_text": "Don't let this be the one that got away ☕️",
      "from_name": "Mayde Tea",
      "from_email": "hello@maydetea.com",
      "screenshot_url": "https://cdn.brandsearch.co/emails/87fc2d07e5dc120b437aaa2d354ebfe3.png",
      "dashboard_url": "https://app.brandsearch.co/emails/87fc2d07e5dc120b437aaa2d354ebfe3"
    }
  ],
  "seed": "newsletter-ideas",
  "count": 2
}

GET/v1/emails/:email_id

Get an email

One email, by the id a list response gave you. Takes fields=. An unknown id is a 404 ad_not_found, and is not charged.

Costs 1 credit.

cURL

curl -G https://api.brandsearch.co/v1/emails/90f2c592da1c8d06770513ed7702abdf \
  -H "X-API-Key: bsk_your_api_key" \
  -d fields=subject,link_count,image_count,has_checkout,has_unsubscribe

Response

{
  "id": "90f2c592da1c8d06770513ed7702abdf",
  "brand_id": "retro-stage.com",
  "subject": "Halloween Is Coming! Secure Your Spooky Style. 🕸️",
  "link_count": 49,
  "image_count": 31,
  "has_checkout": false,
  "has_unsubscribe": true,
  "screenshot_url": "https://cdn.brandsearch.co/emails/90f2c592da1c8d06770513ed7702abdf.png",
  "dashboard_url": "https://app.brandsearch.co/emails/90f2c592da1c8d06770513ed7702abdf"
}

GET/v1/emails/:email_id/download

Download an email screenshot

Returns the screenshot's image bytes rather than a link. screenshot_url expires, and some clients cannot fetch images from another host at all; this route serves the same picture over your API connection.

Costs 1 credit, charged only when the image is served. An email whose screenshot is missing returns 404 ad_media_unavailable and is not charged.

  • Name
    size
    Type
    string
    Description

    full (default) for the original PNG, or compact for a JPEG at most 800 px wide and 8,000 px tall, much lighter for a long email.

  • Name
    media
    Type
    string
    Description

    auto (default) or image, both the screenshot. An email has no video, so media=video is a 400 ad_media_not_video.

Response headers: Content-Disposition, X-Ad-Media-Kind: image, X-Ad-Media-Size (full or compact), and X-Ad-Platform: email.

cURL

curl -G https://api.brandsearch.co/v1/emails/bfd7c60dd0d6156e78f6b186beb96095/download \
  -H "X-API-Key: bsk_your_api_key" \
  -d size=compact \
  -o email.jpg

POST/v1/emails/:email_id/ai-analysis

AI analysis of an email

An AI creative breakdown of the email, read from its screenshot: concept, angle, hook, target audience, funnel stage, copy strategy, suggested tests, and more. It is the same analysis the email view of the Brandsearch app produces, and the two share results, so an email analysed in the app comes back instantly here and the other way round.

Costs 14 AI credits, and no request credit. A previously generated analysis comes back free. Pass {"force_regenerate": true} to run it again, which charges again. 402 insufficient_ai_credits when your balance cannot cover it; nothing is generated or charged. When the email's screenshot cannot be read, the analysis is refused with 503 service_unavailable and nothing is charged; try again later.

GET on the same path returns a previously generated analysis for free, or 404 ai_analysis_not_found when there is none yet.

The response has the same shape as the AI analysis of an ad.

cURL

curl -X POST https://api.brandsearch.co/v1/emails/90f2c592da1c8d06770513ed7702abdf/ai-analysis \
  -H "X-API-Key: bsk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{}'

Response

{
  "analysis": {
    "concept": "Halloween Vintage Style Sale",
    "angle": "Seasonal urgency and diverse vintage-inspired spooky fashion at discounted prices.",
    "hook": "Halloween Is Coming! Secure Your Spooky Style.",
    "funnelStage": "MOF",
    "cta": "SHOP NOW",
    "...": "..."
  },
  "model": "BrandSearch",
  "generated_at": "2026-09-24T19:56:14.026429+00:00",
  "cached": false,
  "cost": 14,
  "ai_credits": { "used": 433, "total": 2000, "remaining": 1567 }
}

POST/v1/emails/aggregates

Email aggregates

Breakdowns over any slice of emails: how many, which types, which brands send the most, and on which days. The body takes the same filters as POST /v1/emails/query, without pagination.

Costs a flat 1 credit, however many emails the slice holds.

  • Name
    window
    Type
    object
    Description

    email_count, and the first_sent and last_sent dates of the slice.

  • Name
    type_mix
    Type
    object
    Description

    Emails per type: marketing, abandoned_cart, subscription_confirmation, and other for the rare email without one.

  • Name
    brand_mix
    Type
    object
    Description

    The 50 brands with the most emails in the slice, with their counts.

  • Name
    send_day
    Type
    object
    Description

    Emails per calendar day (UTC). Days without an email are left out.

  • Name
    send_weekday
    Type
    object
    Description

    The same counts summed per weekday (UTC), monday to sunday.

cURL

curl https://api.brandsearch.co/v1/emails/aggregates \
  -H "X-API-Key: bsk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"brand_ids": ["retro-stage.com"]}'

Response

{
  "window": {
    "email_count": 634,
    "first_sent": "2026-03-20T14:12:41.316Z",
    "last_sent": "2026-09-24T17:52:11.135Z"
  },
  "type_mix": {
    "marketing": 626,
    "abandoned_cart": 8,
    "subscription_confirmation": 0,
    "other": 0
  },
  "brand_mix": { "retro-stage.com": 634 },
  "send_day": { "2026-03-20": 6, "2026-03-21": 5, "...": "..." },
  "send_weekday": {
    "monday": 81,
    "tuesday": 79,
    "wednesday": 94,
    "thursday": 87,
    "friday": 96,
    "saturday": 105,
    "sunday": 92
  }
}

Errors

The email endpoints return the same errors as the ad endpoints:

  • 400 invalid_parameter or 400 validation_error for a bad value, with details.parameter naming it. Nothing is charged.
  • 404 ad_not_found for an unknown email id.
  • 404 ad_media_unavailable when an email's screenshot is missing (download only).
  • 402 insufficient_ai_credits and 404 ai_analysis_not_found on the AI analysis.

See Errors for the full list.

Was this page helpful?