curl --request GET \
--url https://brew.new/api/v1/flows \
--header 'Authorization: Bearer <token>'import requests
url = "https://brew.new/api/v1/flows"
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/flows', 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/flows",
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/flows"
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/flows")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/flows")
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": [
{
"slug": "brew.new",
"brand": {
"name": "Brew",
"logo": "https://cdn.brew.new/brand/fetched-logo/brew.new/logo.png"
},
"title": "Brew onboarding flow",
"type": "signup",
"category": "welcome",
"categoryLabel": "Welcome",
"emailCount": 6,
"spanDays": 14,
"remixCount": 12,
"previewImages": [
"https://cdn.brew.new/email-preview-brew-1.png",
"https://cdn.brew.new/email-preview-brew-2.png",
"https://cdn.brew.new/email-preview-brew-3.png"
],
"publishedAt": "2026-09-01T12:00:00.000Z",
"updatedAt": "2026-09-01T12:00:00.000Z"
}
],
"pagination": {
"limit": 100,
"cursor": null,
"hasMore": false
},
"total": 1,
"isTotalExact": true
}List flows
Lists public email flows, one brand’s real onboarding or newsletter sequence with the day each email landed, as cards under { data, pagination, total }. Organization-wide: the same bounded corpus the gallery shows (a few hundred flows), paged with limit/cursor.
Use when studying how real brands sequence email to plan or remix an automation, or finding the slug to read one flow in full.
Input brand (exact domain), category, type (signup | newsletter), sort (newest | emails | span | remixes), or semantic for relevance-ranked search (then sort is ignored).
Returns 200 with flow cards and total, the number of flows the query matches across every page (filters narrow it; semantic only orders it), so one limit=1 call counts them. isTotalExact is false when the read was cut at 500 flows (the newest, or the 500 nearest a semantic query; filters apply after it), and total is then a floor. A card never carries anchor or steps; every card carries the slug that getFlow takes. A flow holds at most 12 steps: capture keeps the first 12 and cuts the tail, so emailCount: 12 means twelve or more were sent.
Errors 400 INVALID_REQUEST for an unknown query key or value; 503 SERVICE_UNAVAILABLE when semantic search cannot run (no index, or its kill switch); retry without semantic.
See also getFlow, listTemplates.
curl --request GET \
--url https://brew.new/api/v1/flows \
--header 'Authorization: Bearer <token>'import requests
url = "https://brew.new/api/v1/flows"
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/flows', 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/flows",
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/flows"
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/flows")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://brew.new/api/v1/flows")
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": [
{
"slug": "brew.new",
"brand": {
"name": "Brew",
"logo": "https://cdn.brew.new/brand/fetched-logo/brew.new/logo.png"
},
"title": "Brew onboarding flow",
"type": "signup",
"category": "welcome",
"categoryLabel": "Welcome",
"emailCount": 6,
"spanDays": 14,
"remixCount": 12,
"previewImages": [
"https://cdn.brew.new/email-preview-brew-1.png",
"https://cdn.brew.new/email-preview-brew-2.png",
"https://cdn.brew.new/email-preview-brew-3.png"
],
"publishedAt": "2026-09-01T12:00:00.000Z",
"updatedAt": "2026-09-01T12:00:00.000Z"
}
],
"pagination": {
"limit": 100,
"cursor": null,
"hasMore": false
},
"total": 1,
"isTotalExact": true
}Authorizations
Send your Brew API key as Authorization: Bearer brew_xxx.
Query Parameters
Exact brand domain filter for LIST, e.g. brew.new.
1Filter LIST by the flow’s dominant step category (welcome, newsletter, promotion, education, …).
verification, transactional, direct_sales, welcome, promotion, newsletter, education, abandoned_cart, winback, other Filter LIST by how the sequence starts: signup (after creating an account) or newsletter (after subscribing).
newsletter, signup Semantic search over what the sequences are about — “developer onboarding drip”, “trial expiry win-back”. Results come back in relevance order and sort is ignored.
1 - 500LIST order: newest (default), emails (longest sequences first), span (sequences that run the longest first), remixes (most remixed first).
newest, emails, span, remixes Page size (1-100). Defaults to 100.
1 <= x <= 10050
1 - 512Response
A page of flow cards.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Flows this query matches across every page (filters narrow, semantic only orders); a floor when isTotalExact is false.
x >= 0False when the read was cut at 500 flows (the newest, or the 500 nearest a semantic query), so total is a floor.
Was this page helpful?