curl --request GET \
--url https://brew.new/api/v1/emails/{emailId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://brew.new/api/v1/emails/{emailId}"
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/{emailId}', 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/{emailId}",
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/{emailId}"
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/{emailId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/emails/{emailId}")
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{
"emailId": "V1StGXR8_Z5jdHi6B-myT",
"emailVersionId": "Yc5Kz8Sq2Wn7Lp4Tm1RvX",
"title": "Welcome Email",
"status": "ready",
"subjectLine": "Welcome to Acme",
"previewText": "Your first week, planned.",
"previewImage": "https://cdn.brew.new/p/V1StGXR8_Z5jdHi6B-myT.png",
"updatedAt": "2026-04-08T12:34:56.789Z",
"group": {
"groupId": "grp_welcome",
"groupName": "Welcome"
},
"versions": [
{
"version": "latest",
"emailVersionId": "Yc5Kz8Sq2Wn7Lp4Tm1RvX"
},
{
"version": 1,
"emailVersionId": "Lw9Rn1Vc5KzSGm2Tq7Xp4"
}
]
}Get an email design
Reads one design as the bare EmailSummary row: emailId, the latest emailVersionId (the pin for POST /v1/sends and sendEmail nodes), title, status, subjectLine, previewText, previewImage, updatedAt and group.
Use when inspecting a design before sending it, pinning its latest version, or pulling its rendered HTML or version history.
Input emailId in the path; include=html adds the rendered HTML of the latest version and include=versions the lean { version, emailVersionId } history (comma-separate both).
Returns 200 with the row; the include fields are present only when requested.
Errors 404 EMAIL_NOT_FOUND for an unknown or cross-brand id; 400 INVALID_REQUEST for an unknown include token.
See also listEmails, editEmail, createSend, restoreEmailVersion.
curl --request GET \
--url https://brew.new/api/v1/emails/{emailId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://brew.new/api/v1/emails/{emailId}"
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/{emailId}', 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/{emailId}",
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/{emailId}"
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/{emailId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/emails/{emailId}")
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{
"emailId": "V1StGXR8_Z5jdHi6B-myT",
"emailVersionId": "Yc5Kz8Sq2Wn7Lp4Tm1RvX",
"title": "Welcome Email",
"status": "ready",
"subjectLine": "Welcome to Acme",
"previewText": "Your first week, planned.",
"previewImage": "https://cdn.brew.new/p/V1StGXR8_Z5jdHi6B-myT.png",
"updatedAt": "2026-04-08T12:34:56.789Z",
"group": {
"groupId": "grp_welcome",
"groupName": "Welcome"
},
"versions": [
{
"version": "latest",
"emailVersionId": "Yc5Kz8Sq2Wn7Lp4Tm1RvX"
},
{
"version": 1,
"emailVersionId": "Lw9Rn1Vc5KzSGm2Tq7Xp4"
}
]
}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 - 64Path Parameters
Design id returned by POST /v1/emails and listed by GET /v1/emails.
1 - 64"2SmZOWV3ZQ7W5x6g3m4pA"
Query Parameters
Comma-separated expansions: html (rendered HTML of the latest version), versions (lean { version, emailVersionId } history).
Response
The design row.
11generating, ready, failed Last stable design update. While status is generating, collection reads hold this at createdAt so body chunks do not reorder or invalidate the whole list; the completion transition publishes the final source timestamp.
Show child attributes
Show child attributes
1The design's default inbox subject, persisted on the latest version. Distinct from title (canvas name). Detail-only; absent on rows where it has never been set (via the write surfaces' subjectLine field, or in-app). POST /v1/sends still requires an explicit subject.
The design's inbox preview line, read directly from the latest version's JSX (its single source of truth) — what a send delivers when no explicit previewText override is passed to POST /v1/sends. Detail-only; absent when the design has no .
Show child attributes
Show child attributes
Was this page helpful?