curl --request POST \
--url https://brew.new/api/v1/emails/{emailId}/export \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"provider": "klaviyo",
"templateName": "Welcome — Brew export"
}
'import requests
url = "https://brew.new/api/v1/emails/{emailId}/export"
payload = {
"provider": "klaviyo",
"templateName": "Welcome — Brew export"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({provider: 'klaviyo', templateName: 'Welcome — Brew export'})
};
fetch('https://brew.new/api/v1/emails/{emailId}/export', 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}/export",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'provider' => 'klaviyo',
'templateName' => 'Welcome — Brew export'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://brew.new/api/v1/emails/{emailId}/export"
payload := strings.NewReader("{\n \"provider\": \"klaviyo\",\n \"templateName\": \"Welcome — Brew export\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://brew.new/api/v1/emails/{emailId}/export")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"provider\": \"klaviyo\",\n \"templateName\": \"Welcome — Brew export\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/emails/{emailId}/export")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"provider\": \"klaviyo\",\n \"templateName\": \"Welcome — Brew export\"\n}"
response = http.request(request)
puts response.read_body{
"emailId": "2SmZOWV3ZQ7W5x6g3m4pA",
"provider": "klaviyo",
"providerName": "Klaviyo",
"templateName": "Welcome — Brew export",
"dryRun": true
}Export a design to an ESP
Export a finished email DESIGN to a connected third-party ESP (Braze, Brevo, HubSpot, Klaviyo, Loops, Mailchimp, Mailjet, Iterable, Postmark, OneSignal, Mailgun, SendGrid) as a reusable TEMPLATE. This is NOT a Brew send — it creates a template in the destination platform and does NOT deliver to recipients, and is unrelated to Brew sending domains or audiences. The provider must already be connected for the brand (connect ESPs in the Brew app). The exported HTML is automatically made ESP-portable; Loops converts supported content to LMX and creates an editable campaign draft to review before sending. Brevo and Mailjet need senderEmail when the account has more than one active sender (with exactly one, it is selected automatically). Pass dryRun: true to validate the design, brand ownership, and ESP connection without creating a template. Free (no credits).
curl --request POST \
--url https://brew.new/api/v1/emails/{emailId}/export \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"provider": "klaviyo",
"templateName": "Welcome — Brew export"
}
'import requests
url = "https://brew.new/api/v1/emails/{emailId}/export"
payload = {
"provider": "klaviyo",
"templateName": "Welcome — Brew export"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({provider: 'klaviyo', templateName: 'Welcome — Brew export'})
};
fetch('https://brew.new/api/v1/emails/{emailId}/export', 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}/export",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'provider' => 'klaviyo',
'templateName' => 'Welcome — Brew export'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://brew.new/api/v1/emails/{emailId}/export"
payload := strings.NewReader("{\n \"provider\": \"klaviyo\",\n \"templateName\": \"Welcome — Brew export\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://brew.new/api/v1/emails/{emailId}/export")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"provider\": \"klaviyo\",\n \"templateName\": \"Welcome — Brew export\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/emails/{emailId}/export")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"provider\": \"klaviyo\",\n \"templateName\": \"Welcome — Brew export\"\n}"
response = http.request(request)
puts response.read_body{
"emailId": "2SmZOWV3ZQ7W5x6g3m4pA",
"provider": "klaviyo",
"providerName": "Klaviyo",
"templateName": "Welcome — Brew export",
"dryRun": true
}Authorizations
Send your Brew API key as Authorization: Bearer brew_xxx.
Headers
Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.
1 - 100The 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"
Body
The connected ESP to export the design to as a template.
braze, brevo, hubspot, klaviyo, mailchimp, mailjet, iterable, postmark, onesignal, mailgun, sendgrid, loops Template name in the ESP. Defaults to the email title.
1 - 100Active sender email for Brevo or Mailjet. Omit when the account has exactly one active sender; Brew selects it automatically.
320Validate the design, brand ownership, and ESP connection without creating a template.
Response
Dry run — the design + ESP connection were validated without creating a template.
Was this page helpful?