curl --request GET \
--url https://brew.new/api/v1/emails \
--header 'Authorization: Bearer <token>'import requests
url = "https://brew.new/api/v1/emails"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://brew.new/api/v1/emails', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://brew.new/api/v1/emails",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://brew.new/api/v1/emails"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://brew.new/api/v1/emails")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/emails")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"emailId": "V1StGXR8_Z5jdHi6B-myT",
"emailVersionId": "Yc5Kz8Sq2Wn7Lp4Tm1RvX",
"title": "Welcome Email",
"status": "ready",
"previewImage": "https://cdn.brew.new/p/V1StGXR8_Z5jdHi6B-myT.png",
"updatedAt": "2026-04-08T12:34:56.789Z",
"group": {
"groupId": "grp_welcome",
"groupName": "Welcome"
}
},
{
"emailId": "H7sQm2Lx9cT4vBn1KpWzE",
"emailVersionId": "Lw9Rn1Vc5KzSGm2Tq7Xp4",
"title": "May product digest",
"status": "ready",
"updatedAt": "2026-04-07T09:00:00.000Z",
"group": null
}
],
"pagination": {
"limit": 100,
"cursor": null,
"hasMore": false
}
}List email designs
Lists the brand’s designs, newest first on the sortBy timestamp, as { data, pagination }. Each row carries emailId, the latest emailVersionId, title, status, previewImage (when captured), updatedAt, group ({ groupId, groupName } or null when Ungrouped) and its creator.
Use when browsing designs or finding the emailId to send, edit or inspect. One design with its HTML or version history is getEmail.
Input status (generating, ready, failed), groupId (grp_… or ungrouped), sortBy (updatedAt default, or createdAt) with an inclusive from/to ISO 8601 window on that timestamp, limit and cursor.
Returns 200 with a page of EmailSummary rows and a pagination envelope (cursor is null on the last page). createdBy is the creator exactly as the Brew emails list shows it: a person’s name (Former member once they leave the brand), API or MCP for a credential with no person, or the two joined (Name · MCP); createdByUserId is that person’s stable user id. createdBy is absent when the creator cannot be named, with createdByUserId still present.
Errors 400 INVALID_REQUEST for an unknown query key, an invalid status or a reversed window.
See also getEmail, listEmailGroups, listTemplates (the public gallery).
curl --request GET \
--url https://brew.new/api/v1/emails \
--header 'Authorization: Bearer <token>'import requests
url = "https://brew.new/api/v1/emails"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://brew.new/api/v1/emails', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://brew.new/api/v1/emails",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://brew.new/api/v1/emails"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://brew.new/api/v1/emails")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/emails")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"emailId": "V1StGXR8_Z5jdHi6B-myT",
"emailVersionId": "Yc5Kz8Sq2Wn7Lp4Tm1RvX",
"title": "Welcome Email",
"status": "ready",
"previewImage": "https://cdn.brew.new/p/V1StGXR8_Z5jdHi6B-myT.png",
"updatedAt": "2026-04-08T12:34:56.789Z",
"group": {
"groupId": "grp_welcome",
"groupName": "Welcome"
}
},
{
"emailId": "H7sQm2Lx9cT4vBn1KpWzE",
"emailVersionId": "Lw9Rn1Vc5KzSGm2Tq7Xp4",
"title": "May product digest",
"status": "ready",
"updatedAt": "2026-04-07T09:00:00.000Z",
"group": null
}
],
"pagination": {
"limit": 100,
"cursor": null,
"hasMore": false
}
}Authorizations
Send your Brew API key as Authorization: Bearer brew_xxx.
Headers
The brand this request acts on. REQUIRED for organization-scoped credentials (otherwise 400 BRAND_ID_REQUIRED — there is no default brand); list ids with GET /v1/brands. Brand-scoped credentials may omit it, and sending a different brand returns 403 BRAND_SCOPE_MISMATCH. A brand outside your organization returns 404 BRAND_NOT_FOUND.
1 - 64Query Parameters
Only designs whose title contains this text (case-insensitive), or whose title, subject line, preview or visible text matches its words (full-text over each design’s first 16,384 characters; the other filters apply to the 1,024 best matches).
1 - 200Only designs in this status (generating, ready, failed).
generating, ready, failed Only designs in one group (grp_…, or ungrouped).
1 - 64The timestamp the page is ordered by, newest first, and that from/to bound. Defaults to updatedAt.
updatedAt, createdAt Inclusive lower bound on the sortBy timestamp (ISO 8601).
Inclusive upper bound on the sortBy timestamp (ISO 8601).
Page size (1-100). Defaults to 100.
1 <= x <= 10050
1 - 512Was this page helpful?