Upserts a single contact OR a batch ({ contacts: [...] }, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → date, anything else string). fieldsCreated names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with POST /v1/fields to pin its type.
Custom-field names are folded to one key: words split at spaces, _, - and a lower-to-upper letter change, then joined camelCase (Plan, PLAN and plan are the field plan; team_size and Team Size are teamSize). A key written under its folded name adds a FIELD_NAME_NORMALIZED warning (original, normalized). Two keys that fold to one field (plan and Plan) would lose one value, so they are a 422 FIELD_NAME_COLLISION on a single upsert (nothing written) and a per-row errors[] entry (code: FIELD_NAME_COLLISION) in a batch.
Custom-field values are coerced to the definition’s type (dates → epoch ms, "1,234" → 1234, yes/no → booleans). A value that cannot be coerced ("$49" in a number field) is a 409 FIELD_TYPE_MISMATCH on a single upsert and a per-row errors[] entry (code: FIELD_TYPE_MISMATCH, field) in a batch — the other rows still land. A value that was converted adds one warnings[] entry per field (code: FIELD_TYPE_COERCED, field, from, to); a date written to a date field is not reported. A customFields key is never stored under a core field name. One whose loss would change the contact (subscribed, First Name, consent, a suppression flag or domain opt-out, or an email naming another address) is a 422 CORE_FIELD_IMMUTABLE on a single upsert (nothing written) and a per-row errors[] entry (code: CORE_FIELD_IMMUTABLE, field) in a batch; send firstName, lastName, subscribed and consent at the top level. A key naming a field Brew manages (createdAt, validationStatus) is dropped with a warnings[] entry (code: CORE_FIELD_IGNORED, field) and the contact is still written, and an email key repeating the contact address is ignored.
Dates: a JSON number is epoch milliseconds. A string may be ISO (2026-04-03, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (3 Apr 2026, April 3, 2026, 03-Apr-26), year-first (2026/04/03), compact (20260403), month and year read as the 1st (2026-04), dotted day-first (03.04.2026), or a slash or dash date. A slash or dash date with a day over 12 reads that way (13/04/2026 is 13 April). One that reads either way (03/04/2026) follows the day/month order the batch’s other dates in that field prove, else month/day, with a warnings[] entry (code: DATE_ORDER_ASSUMED, field). Send YYYY-MM-DD to be unambiguous.
Optional consent: { source: "api" | "form" | "import", capturedAt?, policyVersion?, evidence? } records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes subscribed. An inline marketing send later needs the contact to be subscribed, and warns when no record exists.
subscribed: false unsubscribes the contact, new or existing. subscribed: true only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a 422 RESUBSCRIBE_NOT_ALLOWED (nothing written), and a batch row keeps its other fields and adds a warnings[] entry (code: RESUBSCRIBE_SKIPPED, email).
Single: 201 with { contact, created, fieldsCreated, warnings }. Batch: 200 with { summary, fieldsCreated, errors, warnings } — or 207 when some rows failed (per-row errors in errors[]).
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.
Marketing consent provenance to record on this contact. Optional at creation; an inline marketing send to this address later needs the contact to be subscribed and warns when no record exists.
Optional deliverability check on ingestion. When true, each address is validated with the provider (2 credits per address, charged on success) and the verdict is saved to the contact’s validationStatus. Submissions above the inline cap (100 addresses) upsert first and validate as a background job, returning a validationJobId.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Brew Help Docs","colors":{"primary":"#FF772D","light":"#FF772D","dark":"#FF772D"},"logo":{"light":"https://mintcdn.com/brew-796f053a/QjuRdMJynrgWDqeo/logo/lightmode.svg?fit=max\u0026auto=format\u0026n=QjuRdMJynrgWDqeo\u0026q=85\u0026s=5e906ff65142dc905a773e7747b47816","dark":"https://mintcdn.com/brew-796f053a/QjuRdMJynrgWDqeo/logo/darkmode.svg?fit=max\u0026auto=format\u0026n=QjuRdMJynrgWDqeo\u0026q=85\u0026s=d9aa0d94ceaaf92451334849952286c9","href":"https://brew.new/"},"favicon":"https://mintcdn.com/brew-796f053a/QjuRdMJynrgWDqeo/favicon.svg?fit=max\u0026auto=format\u0026n=QjuRdMJynrgWDqeo\u0026q=85\u0026s=bb65587bb488372fc3a5faa7a6b4d2fe","appearance":{"default":"system","strict":false},"background":{"color":{"light":"#f7f7f7","dark":"#262624"}},"navbar":{"links":[{"href":"https://cal.com/team/brewdotnew/brew-demo","label":"Talk with founders"}],"primary":{"type":"button","label":"Log In","href":"https://brew.new/sign-in"}},"footer":{"socials":{"website":"https://www.brew.new","youtube":"https://www.youtube.com/@brewdotnew","twitter":"https://x.com/brewdotnew","linkedin":"https://www.linkedin.com/company/brewdotnew"}},"search":{"prompt":"Ask any question about Brew"},"seo":{"metatags":{"og:image":"https://docs.brew.new/images/og/default.png","description":"Brew is the AI-native email platform for modern teams and AI agents. Describe the email and Brew designs it on brand, builds the audience, and sends it.","keywords":"AI email marketing, Brew, AI-native email platform, on-brand email, email automations, email analytics, AI agents, MCP email server","robots":"index, follow"},"indexing":"all"},"fonts":{"family":"Inter"},"contextual":{"options":["copy","view","claude","chatgpt","grok","perplexity","mcp","cursor","vscode","download-spec"],"display":"header"},"styling":{"latex":true},"navigation":{"global":{},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"brew-796f053a","hasAudioNarration":false,"actualSubdomain":"brew-796f053a","customDomains":["docs.brew.new"],"gitSource":{"type":"github","owner":"getbrew","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"feedback":{"thumbs":true,"edits":true,"issues":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6aee1463523750835f01043f","clientVersion":"0.0.4087","searchFilterCounts":[{"language":"default","tag":"Developers","count":175},{"language":"default","tag":"Public API v1","count":126},{"language":"default","tag":"Changelog","count":86},{"language":"default","tag":"Docs","count":40},{"language":"default","tag":"2026","count":37},{"language":"default","tag":"Integrations","count":33},{"language":"default","tag":"Emails","count":30},{"language":"default","tag":"Automations","count":29},{"language":"default","tag":"Guides","count":27},{"language":"default","tag":"API Contracts","count":14}]},"assistantConfig":{"deflection":{"enabled":true,"email":"philip@brew.new","showHelpButton":true}},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/public-v1/contacts/create-or-update-contacts","slug":"/api-reference/public-v1/contacts/create-or-update-contacts","pageMetadata":{"title":"Create or update contacts","description":"Upserts a single contact OR a batch (`{ contacts: [...] }`, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → `date`, anything else `string`). `fieldsCreated` names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with `POST /v1/fields` to pin its type.\n\nCustom-field names are folded to one key: words split at spaces, `_`, `-` and a lower-to-upper letter change, then joined camelCase (`Plan`, `PLAN` and `plan` are the field `plan`; `team_size` and `Team Size` are `teamSize`). A key written under its folded name adds a `FIELD_NAME_NORMALIZED` warning (`original`, `normalized`). Two keys that fold to one field (`plan` and `Plan`) would lose one value, so they are a `422 FIELD_NAME_COLLISION` on a single upsert (nothing written) and a per-row `errors[]` entry (`code: FIELD_NAME_COLLISION`) in a batch.\n\nCustom-field values are coerced to the definition's type (dates → epoch ms, `\"1,234\"` → 1234, `yes`/`no` → booleans). A value that cannot be coerced (`\"$49\"` in a number field) is a `409 FIELD_TYPE_MISMATCH` on a single upsert and a per-row `errors[]` entry (`code: FIELD_TYPE_MISMATCH`, `field`) in a batch — the other rows still land. A value that was converted adds one `warnings[]` entry per field (`code: FIELD_TYPE_COERCED`, `field`, `from`, `to`); a date written to a `date` field is not reported. A `customFields` key is never stored under a core field name. One whose loss would change the contact (`subscribed`, `First Name`, `consent`, a suppression flag or domain opt-out, or an `email` naming another address) is a `422 CORE_FIELD_IMMUTABLE` on a single upsert (nothing written) and a per-row `errors[]` entry (`code: CORE_FIELD_IMMUTABLE`, `field`) in a batch; send `firstName`, `lastName`, `subscribed` and `consent` at the top level. A key naming a field Brew manages (`createdAt`, `validationStatus`) is dropped with a `warnings[]` entry (`code: CORE_FIELD_IGNORED`, `field`) and the contact is still written, and an `email` key repeating the contact address is ignored.\n\nDates: a JSON number is epoch milliseconds. A string may be ISO (`2026-04-03`, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (`3 Apr 2026`, `April 3, 2026`, `03-Apr-26`), year-first (`2026/04/03`), compact (`20260403`), month and year read as the 1st (`2026-04`), dotted day-first (`03.04.2026`), or a slash or dash date. A slash or dash date with a day over 12 reads that way (`13/04/2026` is 13 April). One that reads either way (`03/04/2026`) follows the day/month order the batch's other dates in that field prove, else month/day, with a `warnings[]` entry (`code: DATE_ORDER_ASSUMED`, `field`). Send `YYYY-MM-DD` to be unambiguous.\n\nOptional `consent: { source: \"api\" | \"form\" | \"import\", capturedAt?, policyVersion?, evidence? }` records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes `subscribed`. An inline marketing send later needs the contact to be subscribed, and warns when no record exists.\n\n`subscribed: false` unsubscribes the contact, new or existing. `subscribed: true` only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a `422 RESUBSCRIBE_NOT_ALLOWED` (nothing written), and a batch row keeps its other fields and adds a `warnings[]` entry (`code: RESUBSCRIBE_SKIPPED`, `email`).\n\nSingle: `201` with `{ contact, created, fieldsCreated, warnings }`. Batch: `200` with `{ summary, fieldsCreated, errors, warnings }` — or `207` when some rows failed (per-row errors in `errors[]`).","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts","href":"/api-reference/public-v1/contacts/create-or-update-contacts","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Upserts a single contact OR a batch (\", _jsx(_components.code, {\n children: \"{ contacts: [...] }\"\n }), \", up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → \", _jsx(_components.code, {\n children: \"date\"\n }), \", anything else \", _jsx(_components.code, {\n children: \"string\"\n }), \"). \", _jsx(_components.code, {\n children: \"fieldsCreated\"\n }), \" names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with \", _jsx(_components.code, {\n children: \"POST /v1/fields\"\n }), \" to pin its type.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Custom-field names are folded to one key: words split at spaces, \", _jsx(_components.code, {\n children: \"_\"\n }), \", \", _jsx(_components.code, {\n children: \"-\"\n }), \" and a lower-to-upper letter change, then joined camelCase (\", _jsx(_components.code, {\n children: \"Plan\"\n }), \", \", _jsx(_components.code, {\n children: \"PLAN\"\n }), \" and \", _jsx(_components.code, {\n children: \"plan\"\n }), \" are the field \", _jsx(_components.code, {\n children: \"plan\"\n }), \"; \", _jsx(_components.code, {\n children: \"team_size\"\n }), \" and \", _jsx(_components.code, {\n children: \"Team Size\"\n }), \" are \", _jsx(_components.code, {\n children: \"teamSize\"\n }), \"). A key written under its folded name adds a \", _jsx(_components.code, {\n children: \"FIELD_NAME_NORMALIZED\"\n }), \" warning (\", _jsx(_components.code, {\n children: \"original\"\n }), \", \", _jsx(_components.code, {\n children: \"normalized\"\n }), \"). Two keys that fold to one field (\", _jsx(_components.code, {\n children: \"plan\"\n }), \" and \", _jsx(_components.code, {\n children: \"Plan\"\n }), \") would lose one value, so they are a \", _jsx(_components.code, {\n children: \"422 FIELD_NAME_COLLISION\"\n }), \" on a single upsert (nothing written) and a per-row \", _jsx(_components.code, {\n children: \"errors[]\"\n }), \" entry (\", _jsx(_components.code, {\n children: \"code: FIELD_NAME_COLLISION\"\n }), \") in a batch.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Custom-field values are coerced to the definition’s type (dates → epoch ms, \", _jsx(_components.code, {\n children: \"\\\"1,234\\\"\"\n }), \" → 1234, \", _jsx(_components.code, {\n children: \"yes\"\n }), \"/\", _jsx(_components.code, {\n children: \"no\"\n }), \" → booleans). A value that cannot be coerced (\", _jsx(_components.code, {\n children: \"\\\"$49\\\"\"\n }), \" in a number field) is a \", _jsx(_components.code, {\n children: \"409 FIELD_TYPE_MISMATCH\"\n }), \" on a single upsert and a per-row \", _jsx(_components.code, {\n children: \"errors[]\"\n }), \" entry (\", _jsx(_components.code, {\n children: \"code: FIELD_TYPE_MISMATCH\"\n }), \", \", _jsx(_components.code, {\n children: \"field\"\n }), \") in a batch — the other rows still land. A value that was converted adds one \", _jsx(_components.code, {\n children: \"warnings[]\"\n }), \" entry per field (\", _jsx(_components.code, {\n children: \"code: FIELD_TYPE_COERCED\"\n }), \", \", _jsx(_components.code, {\n children: \"field\"\n }), \", \", _jsx(_components.code, {\n children: \"from\"\n }), \", \", _jsx(_components.code, {\n children: \"to\"\n }), \"); a date written to a \", _jsx(_components.code, {\n children: \"date\"\n }), \" field is not reported. A \", _jsx(_components.code, {\n children: \"customFields\"\n }), \" key is never stored under a core field name. One whose loss would change the contact (\", _jsx(_components.code, {\n children: \"subscribed\"\n }), \", \", _jsx(_components.code, {\n children: \"First Name\"\n }), \", \", _jsx(_components.code, {\n children: \"consent\"\n }), \", a suppression flag or domain opt-out, or an \", _jsx(_components.code, {\n children: \"email\"\n }), \" naming another address) is a \", _jsx(_components.code, {\n children: \"422 CORE_FIELD_IMMUTABLE\"\n }), \" on a single upsert (nothing written) and a per-row \", _jsx(_components.code, {\n children: \"errors[]\"\n }), \" entry (\", _jsx(_components.code, {\n children: \"code: CORE_FIELD_IMMUTABLE\"\n }), \", \", _jsx(_components.code, {\n children: \"field\"\n }), \") in a batch; send \", _jsx(_components.code, {\n children: \"firstName\"\n }), \", \", _jsx(_components.code, {\n children: \"lastName\"\n }), \", \", _jsx(_components.code, {\n children: \"subscribed\"\n }), \" and \", _jsx(_components.code, {\n children: \"consent\"\n }), \" at the top level. A key naming a field Brew manages (\", _jsx(_components.code, {\n children: \"createdAt\"\n }), \", \", _jsx(_components.code, {\n children: \"validationStatus\"\n }), \") is dropped with a \", _jsx(_components.code, {\n children: \"warnings[]\"\n }), \" entry (\", _jsx(_components.code, {\n children: \"code: CORE_FIELD_IGNORED\"\n }), \", \", _jsx(_components.code, {\n children: \"field\"\n }), \") and the contact is still written, and an \", _jsx(_components.code, {\n children: \"email\"\n }), \" key repeating the contact address is ignored.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Dates: a JSON number is epoch milliseconds. A string may be ISO (\", _jsx(_components.code, {\n children: \"2026-04-03\"\n }), \", with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (\", _jsx(_components.code, {\n children: \"3 Apr 2026\"\n }), \", \", _jsx(_components.code, {\n children: \"April 3, 2026\"\n }), \", \", _jsx(_components.code, {\n children: \"03-Apr-26\"\n }), \"), year-first (\", _jsx(_components.code, {\n children: \"2026/04/03\"\n }), \"), compact (\", _jsx(_components.code, {\n children: \"20260403\"\n }), \"), month and year read as the 1st (\", _jsx(_components.code, {\n children: \"2026-04\"\n }), \"), dotted day-first (\", _jsx(_components.code, {\n children: \"03.04.2026\"\n }), \"), or a slash or dash date. A slash or dash date with a day over 12 reads that way (\", _jsx(_components.code, {\n children: \"13/04/2026\"\n }), \" is 13 April). One that reads either way (\", _jsx(_components.code, {\n children: \"03/04/2026\"\n }), \") follows the day/month order the batch’s other dates in that field prove, else month/day, with a \", _jsx(_components.code, {\n children: \"warnings[]\"\n }), \" entry (\", _jsx(_components.code, {\n children: \"code: DATE_ORDER_ASSUMED\"\n }), \", \", _jsx(_components.code, {\n children: \"field\"\n }), \"). Send \", _jsx(_components.code, {\n children: \"YYYY-MM-DD\"\n }), \" to be unambiguous.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Optional \", _jsx(_components.code, {\n children: \"consent: { source: \\\"api\\\" | \\\"form\\\" | \\\"import\\\", capturedAt?, policyVersion?, evidence? }\"\n }), \" records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes \", _jsx(_components.code, {\n children: \"subscribed\"\n }), \". An inline marketing send later needs the contact to be subscribed, and warns when no record exists.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"subscribed: false\"\n }), \" unsubscribes the contact, new or existing. \", _jsx(_components.code, {\n children: \"subscribed: true\"\n }), \" only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a \", _jsx(_components.code, {\n children: \"422 RESUBSCRIBE_NOT_ALLOWED\"\n }), \" (nothing written), and a batch row keeps its other fields and adds a \", _jsx(_components.code, {\n children: \"warnings[]\"\n }), \" entry (\", _jsx(_components.code, {\n children: \"code: RESUBSCRIBE_SKIPPED\"\n }), \", \", _jsx(_components.code, {\n children: \"email\"\n }), \").\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Single: \", _jsx(_components.code, {\n children: \"201\"\n }), \" with \", _jsx(_components.code, {\n children: \"{ contact, created, fieldsCreated, warnings }\"\n }), \". Batch: \", _jsx(_components.code, {\n children: \"200\"\n }), \" with \", _jsx(_components.code, {\n children: \"{ summary, fieldsCreated, errors, warnings }\"\n }), \" — or \", _jsx(_components.code, {\n children: \"207\"\n }), \" when some rows failed (per-row errors in \", _jsx(_components.code, {\n children: \"errors[]\"\n }), \").\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Create or update contacts","description":"Upserts a single contact OR a batch (`{ contacts: [...] }`, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → `date`, anything else `string`). `fieldsCreated` names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with `POST /v1/fields` to pin its type.\n\nCustom-field names are folded to one key: words split at spaces, `_`, `-` and a lower-to-upper letter change, then joined camelCase (`Plan`, `PLAN` and `plan` are the field `plan`; `team_size` and `Team Size` are `teamSize`). A key written under its folded name adds a `FIELD_NAME_NORMALIZED` warning (`original`, `normalized`). Two keys that fold to one field (`plan` and `Plan`) would lose one value, so they are a `422 FIELD_NAME_COLLISION` on a single upsert (nothing written) and a per-row `errors[]` entry (`code: FIELD_NAME_COLLISION`) in a batch.\n\nCustom-field values are coerced to the definition's type (dates → epoch ms, `\"1,234\"` → 1234, `yes`/`no` → booleans). A value that cannot be coerced (`\"$49\"` in a number field) is a `409 FIELD_TYPE_MISMATCH` on a single upsert and a per-row `errors[]` entry (`code: FIELD_TYPE_MISMATCH`, `field`) in a batch — the other rows still land. A value that was converted adds one `warnings[]` entry per field (`code: FIELD_TYPE_COERCED`, `field`, `from`, `to`); a date written to a `date` field is not reported. A `customFields` key is never stored under a core field name. One whose loss would change the contact (`subscribed`, `First Name`, `consent`, a suppression flag or domain opt-out, or an `email` naming another address) is a `422 CORE_FIELD_IMMUTABLE` on a single upsert (nothing written) and a per-row `errors[]` entry (`code: CORE_FIELD_IMMUTABLE`, `field`) in a batch; send `firstName`, `lastName`, `subscribed` and `consent` at the top level. A key naming a field Brew manages (`createdAt`, `validationStatus`) is dropped with a `warnings[]` entry (`code: CORE_FIELD_IGNORED`, `field`) and the contact is still written, and an `email` key repeating the contact address is ignored.\n\nDates: a JSON number is epoch milliseconds. A string may be ISO (`2026-04-03`, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (`3 Apr 2026`, `April 3, 2026`, `03-Apr-26`), year-first (`2026/04/03`), compact (`20260403`), month and year read as the 1st (`2026-04`), dotted day-first (`03.04.2026`), or a slash or dash date. A slash or dash date with a day over 12 reads that way (`13/04/2026` is 13 April). One that reads either way (`03/04/2026`) follows the day/month order the batch's other dates in that field prove, else month/day, with a `warnings[]` entry (`code: DATE_ORDER_ASSUMED`, `field`). Send `YYYY-MM-DD` to be unambiguous.\n\nOptional `consent: { source: \"api\" | \"form\" | \"import\", capturedAt?, policyVersion?, evidence? }` records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes `subscribed`. An inline marketing send later needs the contact to be subscribed, and warns when no record exists.\n\n`subscribed: false` unsubscribes the contact, new or existing. `subscribed: true` only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a `422 RESUBSCRIBE_NOT_ALLOWED` (nothing written), and a batch row keeps its other fields and adds a `warnings[]` entry (`code: RESUBSCRIBE_SKIPPED`, `email`).\n\nSingle: `201` with `{ contact, created, fieldsCreated, warnings }`. Batch: `200` with `{ summary, fieldsCreated, errors, warnings }` — or `207` when some rows failed (per-row errors in `errors[]`).","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts","href":"/api-reference/public-v1/contacts/create-or-update-contacts","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":["/_mintlify/custom/brew-796f053a/b7b4876a6d26628c/ask-ai-menu.js"],"openApiReferenceData":{"operation":{"operationId":"upsertContacts","tags":["Contacts"],"summary":"Create or update contacts","description":"Upserts a single contact OR a batch (`{ contacts: [...] }`, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → `date`, anything else `string`). `fieldsCreated` names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with `POST /v1/fields` to pin its type.\n\nCustom-field names are folded to one key: words split at spaces, `_`, `-` and a lower-to-upper letter change, then joined camelCase (`Plan`, `PLAN` and `plan` are the field `plan`; `team_size` and `Team Size` are `teamSize`). A key written under its folded name adds a `FIELD_NAME_NORMALIZED` warning (`original`, `normalized`). Two keys that fold to one field (`plan` and `Plan`) would lose one value, so they are a `422 FIELD_NAME_COLLISION` on a single upsert (nothing written) and a per-row `errors[]` entry (`code: FIELD_NAME_COLLISION`) in a batch.\n\nCustom-field values are coerced to the definition's type (dates → epoch ms, `\"1,234\"` → 1234, `yes`/`no` → booleans). A value that cannot be coerced (`\"$49\"` in a number field) is a `409 FIELD_TYPE_MISMATCH` on a single upsert and a per-row `errors[]` entry (`code: FIELD_TYPE_MISMATCH`, `field`) in a batch — the other rows still land. A value that was converted adds one `warnings[]` entry per field (`code: FIELD_TYPE_COERCED`, `field`, `from`, `to`); a date written to a `date` field is not reported. A `customFields` key is never stored under a core field name. One whose loss would change the contact (`subscribed`, `First Name`, `consent`, a suppression flag or domain opt-out, or an `email` naming another address) is a `422 CORE_FIELD_IMMUTABLE` on a single upsert (nothing written) and a per-row `errors[]` entry (`code: CORE_FIELD_IMMUTABLE`, `field`) in a batch; send `firstName`, `lastName`, `subscribed` and `consent` at the top level. A key naming a field Brew manages (`createdAt`, `validationStatus`) is dropped with a `warnings[]` entry (`code: CORE_FIELD_IGNORED`, `field`) and the contact is still written, and an `email` key repeating the contact address is ignored.\n\nDates: a JSON number is epoch milliseconds. A string may be ISO (`2026-04-03`, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (`3 Apr 2026`, `April 3, 2026`, `03-Apr-26`), year-first (`2026/04/03`), compact (`20260403`), month and year read as the 1st (`2026-04`), dotted day-first (`03.04.2026`), or a slash or dash date. A slash or dash date with a day over 12 reads that way (`13/04/2026` is 13 April). One that reads either way (`03/04/2026`) follows the day/month order the batch's other dates in that field prove, else month/day, with a `warnings[]` entry (`code: DATE_ORDER_ASSUMED`, `field`). Send `YYYY-MM-DD` to be unambiguous.\n\nOptional `consent: { source: \"api\" | \"form\" | \"import\", capturedAt?, policyVersion?, evidence? }` records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes `subscribed`. An inline marketing send later needs the contact to be subscribed, and warns when no record exists.\n\n`subscribed: false` unsubscribes the contact, new or existing. `subscribed: true` only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a `422 RESUBSCRIBE_NOT_ALLOWED` (nothing written), and a batch row keeps its other fields and adds a `warnings[]` entry (`code: RESUBSCRIBE_SKIPPED`, `email`).\n\nSingle: `201` with `{ contact, created, fieldsCreated, warnings }`. Batch: `200` with `{ summary, fieldsCreated, errors, warnings }` — or `207` when some rows failed (per-row errors in `errors[]`).","parameters":["db7773ae-0c04-46ad-a550-7e8aeff281ba","ff87cd95-b27f-41df-ab59-aea55afeeab8"],"requestBody":"61d103c3-a901-42e3-a469-855263a99b65","responses":{"200":"c3ba0ec2-dd2f-44d3-b3d0-6c0edd417e55","201":"f8fd6c01-ae32-4221-a5c7-4930ad9a5d62","207":"342400e8-8916-48f4-a86f-f9718227f215","400":"85539d9c-a3a8-4a23-9ab0-9868079927ab","401":"1f4fddcf-9651-43e5-a168-1857fa48cb33","402":"faa6e820-f8f2-4bc3-96a1-44f8403917d3","403":"dde88fc3-513f-43f8-8639-b035d2592764","404":"f5234bd7-b73d-4e21-9d59-60c6f82a7111","409":"c800dfef-40dc-437e-baf1-280edc97b18b","422":"01ed4120-3fed-46c8-a517-9d1a5e8563c4","429":"2042128b-ea9c-4557-aef2-f8fd741e2259","500":"f184c643-2fe4-44fb-a72b-a6f18d87bee0","503":"2e4c51fe-6b4f-4b28-8769-037b239303f6"},"x-brew-scope":"contacts","x-brew-brand-scope":"brand","x-brew-idempotency":"replay","x-brew-credited":true,"method":"post","type":"path","servers":["16779731-d97b-4178-b35d-ab9db802c966","d75b81f5-e341-4448-9191-a43a58d2508e"],"security":["3becd03d-c396-4bc3-84c1-231cdbf0a23e","a3a3e731-b20f-48f7-873a-3123be78670a"],"path":"/v1/contacts","baseUrlOptions":["https://brew.new/api","http://localhost:3000/api"],"title":"Create or update contacts","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"db7773ae-0c04-46ad-a550-7e8aeff281ba":{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.","schema":{"type":"string","minLength":1,"maxLength":100,"isRequired":false,"description":"Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.","uniqueKey":"","typeLabel":"string"},"example":"api-request-2026-04-08-001"},"ff87cd95-b27f-41df-ab59-aea55afeeab8":{"name":"X-Brand-Id","in":"header","required":false,"description":"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`.","schema":{"type":"string","minLength":1,"maxLength":64,"isRequired":false,"description":"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`.","uniqueKey":"","typeLabel":"string"},"example":"kx7b3s7fapqz8mjm12ekz1kxdx87yceg"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["email"],"properties":{"email":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"oneOf.0.email","typeLabel":"string"},"firstName":{"type":"string","uniqueKey":"oneOf.0.firstName","typeLabel":"string"},"lastName":{"type":"string","uniqueKey":"oneOf.0.lastName","typeLabel":"string"},"subscribed":{"type":"boolean","uniqueKey":"oneOf.0.subscribed","typeLabel":"boolean"},"customFields":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"oneOf.0.customFields.additionalProperties","typeLabel":"any"},"uniqueKey":"oneOf.0.customFields","typeLabel":"object"},"consent":{"type":"object","properties":{"source":{"type":"string","enum":["api","form","import"],"description":"Who captured it: `api`, `form`, or `import`. (`app` is reserved for the in-app CSV wizard.)","isRequired":true,"uniqueKey":"oneOf.0.consent.source","typeLabel":"enum\u003cstring>"},"capturedAt":{"type":"string","format":"date-time","description":"ISO 8601; defaults to now.","uniqueKey":"oneOf.0.consent.capturedAt","typeLabel":"string\u003cdate-time>"},"policyVersion":{"type":"string","minLength":1,"maxLength":64,"uniqueKey":"oneOf.0.consent.policyVersion","typeLabel":"string"},"evidence":{"type":"string","minLength":1,"maxLength":500,"uniqueKey":"oneOf.0.consent.evidence","typeLabel":"string"}},"required":["source"],"additionalProperties":false,"description":"Marketing consent provenance to record on this contact. Optional at creation; an inline marketing send to this address later needs the contact to be subscribed and warns when no record exists.","uniqueKey":"oneOf.0.consent","typeLabel":"object"},"validate":{"type":"boolean","description":"Optional deliverability check on ingestion. When true, each address is validated with the provider (2 credits per address, charged on success) and the verdict is saved to the contact’s `validationStatus`. Submissions above the inline cap (100 addresses) upsert first and validate as a background job, returning a `validationJobId`.","uniqueKey":"oneOf.0.validate","typeLabel":"boolean"}},"additionalProperties":false,"uniqueKey":"oneOf.0","typeLabel":"object"},{"type":"object","required":["contacts"],"properties":{"contacts":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","uniqueKey":"oneOf.1.contacts.items.[INDEX].email","typeLabel":"string"},"firstName":{"type":"string","uniqueKey":"oneOf.1.contacts.items.[INDEX].firstName","typeLabel":"string"},"lastName":{"type":"string","uniqueKey":"oneOf.1.contacts.items.[INDEX].lastName","typeLabel":"string"},"subscribed":{"type":"boolean","uniqueKey":"oneOf.1.contacts.items.[INDEX].subscribed","typeLabel":"boolean"},"customFields":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"oneOf.1.contacts.items.[INDEX].customFields.additionalProperties","typeLabel":"any"},"uniqueKey":"oneOf.1.contacts.items.[INDEX].customFields","typeLabel":"object"},"consent":{"type":"object","properties":{"source":{"type":"string","enum":["api","form","import"],"description":"Who captured it: `api`, `form`, or `import`. (`app` is reserved for the in-app CSV wizard.)","isRequired":true,"uniqueKey":"oneOf.1.contacts.items.[INDEX].consent.source","typeLabel":"enum\u003cstring>"},"capturedAt":{"type":"string","format":"date-time","description":"ISO 8601; defaults to now.","uniqueKey":"oneOf.1.contacts.items.[INDEX].consent.capturedAt","typeLabel":"string\u003cdate-time>"},"policyVersion":{"type":"string","minLength":1,"maxLength":64,"uniqueKey":"oneOf.1.contacts.items.[INDEX].consent.policyVersion","typeLabel":"string"},"evidence":{"type":"string","minLength":1,"maxLength":500,"uniqueKey":"oneOf.1.contacts.items.[INDEX].consent.evidence","typeLabel":"string"}},"required":["source"],"additionalProperties":false,"description":"Marketing consent provenance to record on this contact. Optional at creation; an inline marketing send to this address later needs the contact to be subscribed and warns when no record exists.","uniqueKey":"oneOf.1.contacts.items.[INDEX].consent","typeLabel":"object"}},"additionalProperties":false,"uniqueKey":"oneOf.1.contacts.items.[INDEX]","typeLabel":"object"},"minItems":1,"maxItems":1000,"isRequired":true,"uniqueKey":"oneOf.1.contacts","typeLabel":"object[]"},"validate":{"type":"boolean","description":"Optional deliverability check on ingestion. When true, each address is validated with the provider (2 credits per address, charged on success) and the verdict is saved to the contact’s `validationStatus`. Submissions above the inline cap (100 addresses) upsert first and validate as a background job, returning a `validationJobId`.","uniqueKey":"oneOf.1.validate","typeLabel":"boolean"},"consent":{"type":"object","properties":{"source":{"type":"string","enum":["api","form","import"],"description":"Who captured it: `api`, `form`, or `import`. (`app` is reserved for the in-app CSV wizard.)","isRequired":true,"uniqueKey":"oneOf.1.consent.source","typeLabel":"enum\u003cstring>"},"capturedAt":{"type":"string","format":"date-time","description":"ISO 8601; defaults to now.","uniqueKey":"oneOf.1.consent.capturedAt","typeLabel":"string\u003cdate-time>"},"policyVersion":{"type":"string","minLength":1,"maxLength":64,"uniqueKey":"oneOf.1.consent.policyVersion","typeLabel":"string"},"evidence":{"type":"string","minLength":1,"maxLength":500,"uniqueKey":"oneOf.1.consent.evidence","typeLabel":"string"}},"required":["source"],"additionalProperties":false,"description":"Default consent record for every row that does not carry its own `consent`.","uniqueKey":"oneOf.1.consent","typeLabel":"object"}},"additionalProperties":false,"uniqueKey":"oneOf.1","typeLabel":"object"}],"uniqueKey":"","typeLabel":"object"},"examples":{"single":{"title":"single","value":{"email":"jane@example.com","firstName":"Jane","customFields":{"plan":"enterprise"},"consent":{"source":"form","capturedAt":"2026-04-08T12:00:00.000Z","policyVersion":"2026-03","evidence":"newsletter checkbox on /signup"}}},"batch":{"title":"batch","value":{"contacts":[{"email":"jane@example.com","firstName":"Jane"},{"email":"john@example.com","firstName":"John"}],"consent":{"source":"import","policyVersion":"2026-03"}}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"c3ba0ec2-dd2f-44d3-b3d0-6c0edd417e55":{"description":"Batch upsert applied (every row succeeded).","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."},"X-RateLimit-Limit":{"schema":{"type":"integer","description":"Requests allowed in the current rolling rate limit window.","example":100},"required":true,"description":"Requests allowed in the current rolling rate limit window."},"X-RateLimit-Remaining":{"schema":{"type":"integer","description":"Requests remaining in the current rolling rate limit window.","example":99},"required":true,"description":"Requests remaining in the current rolling rate limit window."},"X-RateLimit-Reset":{"schema":{"type":"integer","description":"Unix timestamp in seconds when the oldest recorded request leaves the rolling window.","example":1712592360},"required":true,"description":"Unix timestamp in seconds when the oldest recorded request leaves the rolling window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"inserted":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"summary.inserted","typeLabel":"integer"},"updated":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"summary.updated","typeLabel":"integer"},"failed":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"summary.failed","typeLabel":"integer"}},"required":["inserted","updated","failed"],"additionalProperties":false,"isRequired":true,"uniqueKey":"summary","typeLabel":"object"},"fieldsCreated":{"type":"array","items":{"type":"string","uniqueKey":"fieldsCreated.items.[INDEX]","typeLabel":"string"},"isRequired":true,"uniqueKey":"fieldsCreated","typeLabel":"string[]"},"errors":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].email","typeLabel":"string"},"code":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"row":{"type":"integer","exclusiveMinimum":0,"description":"The 1-based row that failed: `contacts[row - 1]`, or the CSV data row (header and blank lines not counted).","uniqueKey":"errors.items.[INDEX].row","typeLabel":"integer"},"field":{"type":"string","uniqueKey":"errors.items.[INDEX].field","typeLabel":"string"}},"required":["email","code","message"],"additionalProperties":false,"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"errors","typeLabel":"object[]"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"warnings.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"warnings.items.[INDEX].message","typeLabel":"string"},"email":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].email","typeLabel":"string"},"row":{"type":"integer","exclusiveMinimum":0,"description":"The 1-based row it is about (CSV: data row; header and blank lines not counted).","uniqueKey":"warnings.items.[INDEX].row","typeLabel":"integer"},"field":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].field","typeLabel":"string"},"from":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].from","typeLabel":"string"},"to":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].to","typeLabel":"string"},"original":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].original","typeLabel":"string"},"normalized":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].normalized","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"uniqueKey":"warnings.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"warnings","typeLabel":"object[]"},"validation":{"type":"object","properties":{"valid":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.valid","typeLabel":"integer"},"risky":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.risky","typeLabel":"integer"},"invalid":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.invalid","typeLabel":"integer"},"unscored":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.unscored","typeLabel":"integer"},"persistence":{"type":"object","properties":{"matched":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.matched","typeLabel":"integer"},"modified":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.modified","typeLabel":"integer"},"failed":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.failed","typeLabel":"integer"}},"required":["matched","modified","failed"],"additionalProperties":false,"uniqueKey":"validation.persistence","typeLabel":"object"}},"required":["valid","risky","invalid","unscored"],"additionalProperties":false,"uniqueKey":"validation","typeLabel":"object"},"validationJobId":{"type":"string","uniqueKey":"validationJobId","typeLabel":"string"}},"required":["summary","fieldsCreated","errors","warnings"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"summary":{"inserted":2,"updated":0,"failed":0},"fieldsCreated":[],"errors":[],"warnings":[]},"examples":{"Example":{"title":"Example","value":{"summary":{"inserted":2,"updated":0,"failed":0},"fieldsCreated":[],"errors":[],"warnings":[]}}},"exampleType":"examples"}},"exampleType":"examples"},"f8fd6c01-ae32-4221-a5c7-4930ad9a5d62":{"description":"Single upsert applied.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."},"X-RateLimit-Limit":{"schema":{"type":"integer","description":"Requests allowed in the current rolling rate limit window.","example":100},"required":true,"description":"Requests allowed in the current rolling rate limit window."},"X-RateLimit-Remaining":{"schema":{"type":"integer","description":"Requests remaining in the current rolling rate limit window.","example":99},"required":true,"description":"Requests remaining in the current rolling rate limit window."},"X-RateLimit-Reset":{"schema":{"type":"integer","description":"Unix timestamp in seconds when the oldest recorded request leaves the rolling window.","example":1712592360},"required":true,"description":"Unix timestamp in seconds when the oldest recorded request leaves the rolling window."}},"content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"type":"object","properties":{"email":{"type":"string","isRequired":true,"uniqueKey":"contact.email","typeLabel":"string"},"createdAt":{"type":"string","format":"date-time","isRequired":true,"uniqueKey":"contact.createdAt","typeLabel":"string\u003cdate-time>"},"updatedAt":{"type":"string","format":"date-time","isRequired":true,"uniqueKey":"contact.updatedAt","typeLabel":"string\u003cdate-time>"},"firstName":{"type":"string","uniqueKey":"contact.firstName","typeLabel":"string"},"lastName":{"type":"string","uniqueKey":"contact.lastName","typeLabel":"string"},"subscribed":{"type":"boolean","default":true,"uniqueKey":"contact.subscribed","typeLabel":"boolean"},"consent":{"type":"object","properties":{"source":{"type":"string","enum":["api","form","import","app","integration"],"description":"Who captured it: `api` (an API caller asserted it), `form` (a signup form), `import` (a bulk import), `app` (the in-app CSV wizard checkbox), `integration` (an integration sync such as Stripe created the contact; provenance only, not an opt-in).","isRequired":true,"uniqueKey":"contact.consent.source","typeLabel":"enum\u003cstring>"},"capturedAt":{"type":"string","format":"date-time","description":"When it was captured.","isRequired":true,"uniqueKey":"contact.consent.capturedAt","typeLabel":"string\u003cdate-time>"},"policyVersion":{"type":"string","description":"The policy or terms version in force when it was captured.","uniqueKey":"contact.consent.policyVersion","typeLabel":"string"},"evidence":{"type":"string","description":"Free-text evidence: a form URL, a ticket, a checkbox label.","uniqueKey":"contact.consent.evidence","typeLabel":"string"}},"required":["source","capturedAt"],"additionalProperties":false,"uniqueKey":"contact.consent","typeLabel":"object"},"validationStatus":{"type":"string","enum":["valid","risky","invalid"],"description":"The latest verdict. `valid` only ever comes from a deliverability check (`validate: true` on ingest, or POST /v1/contacts/validate), which also sets `lastValidatedAt`. Without a check the free format check on ingest stores `risky` (disposable or role address) or `invalid`, and leaves the field unset otherwise: not validated.","uniqueKey":"contact.validationStatus","typeLabel":"enum\u003cstring>"},"suppressed":{"type":"boolean","default":false,"uniqueKey":"contact.suppressed","typeLabel":"boolean"},"suppressedReason":{"oneOf":[{"type":"string","uniqueKey":"contact.suppressedReason.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"contact.suppressedReason.oneOf.1","typeLabel":"null"}],"uniqueKey":"contact.suppressedReason","typeLabel":"string | null"},"unsubscribedDomains":{"type":"array","items":{"type":"string","uniqueKey":"contact.unsubscribedDomains.items.[INDEX]","typeLabel":"string"},"default":[],"uniqueKey":"contact.unsubscribedDomains","typeLabel":"string[]"},"lastValidatedAt":{"type":"string","format":"date-time","uniqueKey":"contact.lastValidatedAt","typeLabel":"string\u003cdate-time>"},"validationDetails":{"type":"object","properties":{"provider":{"type":"string","enum":["brew"],"isRequired":true,"uniqueKey":"contact.validationDetails.provider","typeLabel":"enum\u003cstring>"},"reason":{"type":"string","uniqueKey":"contact.validationDetails.reason","typeLabel":"string"},"didYouMean":{"type":"string","uniqueKey":"contact.validationDetails.didYouMean","typeLabel":"string"},"risk":{"type":"string","uniqueKey":"contact.validationDetails.risk","typeLabel":"string"},"isDisposable":{"type":"boolean","uniqueKey":"contact.validationDetails.isDisposable","typeLabel":"boolean"},"isRole":{"type":"boolean","uniqueKey":"contact.validationDetails.isRole","typeLabel":"boolean"}},"required":["provider"],"additionalProperties":false,"uniqueKey":"contact.validationDetails","typeLabel":"object"},"importId":{"oneOf":[{"type":"string","uniqueKey":"contact.importId.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"contact.importId.oneOf.1","typeLabel":"null"}],"uniqueKey":"contact.importId","typeLabel":"string | null"},"csvFileName":{"oneOf":[{"type":"string","uniqueKey":"contact.csvFileName.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"contact.csvFileName.oneOf.1","typeLabel":"null"}],"uniqueKey":"contact.csvFileName","typeLabel":"string | null"},"customFields":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"contact.customFields.additionalProperties","typeLabel":"any"},"default":{},"uniqueKey":"contact.customFields","typeLabel":"object"}},"required":["email","createdAt","updatedAt"],"additionalProperties":false,"isRequired":true,"uniqueKey":"contact","typeLabel":"object"},"created":{"type":"boolean","isRequired":true,"uniqueKey":"created","typeLabel":"boolean"},"fieldsCreated":{"type":"array","items":{"type":"string","uniqueKey":"fieldsCreated.items.[INDEX]","typeLabel":"string"},"isRequired":true,"uniqueKey":"fieldsCreated","typeLabel":"string[]"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"warnings.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"warnings.items.[INDEX].message","typeLabel":"string"},"email":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].email","typeLabel":"string"},"row":{"type":"integer","exclusiveMinimum":0,"description":"The 1-based row it is about (CSV: data row; header and blank lines not counted).","uniqueKey":"warnings.items.[INDEX].row","typeLabel":"integer"},"field":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].field","typeLabel":"string"},"from":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].from","typeLabel":"string"},"to":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].to","typeLabel":"string"},"original":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].original","typeLabel":"string"},"normalized":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].normalized","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"uniqueKey":"warnings.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"warnings","typeLabel":"object[]"},"validation":{"type":"object","properties":{"valid":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.valid","typeLabel":"integer"},"risky":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.risky","typeLabel":"integer"},"invalid":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.invalid","typeLabel":"integer"},"unscored":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.unscored","typeLabel":"integer"},"persistence":{"type":"object","properties":{"matched":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.matched","typeLabel":"integer"},"modified":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.modified","typeLabel":"integer"},"failed":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.failed","typeLabel":"integer"}},"required":["matched","modified","failed"],"additionalProperties":false,"uniqueKey":"validation.persistence","typeLabel":"object"}},"required":["valid","risky","invalid","unscored"],"additionalProperties":false,"uniqueKey":"validation","typeLabel":"object"}},"required":["contact","created","fieldsCreated","warnings"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"contact":{"email":"jane@example.com","firstName":"Jane","lastName":"Doe","subscribed":true,"validationStatus":"valid","lastValidatedAt":"2026-04-08T12:01:00.000Z","suppressed":false,"suppressedReason":null,"consent":{"source":"form","capturedAt":"2026-04-08T12:00:00.000Z","policyVersion":"2026-03"},"createdAt":"2026-04-08T12:00:00.000Z","updatedAt":"2026-04-08T12:05:00.000Z","importId":null,"customFields":{"plan":"enterprise","revenue":4200}},"created":true,"fieldsCreated":["plan"],"warnings":[]},"examples":{"Example":{"title":"Example","value":{"contact":{"email":"jane@example.com","firstName":"Jane","lastName":"Doe","subscribed":true,"validationStatus":"valid","lastValidatedAt":"2026-04-08T12:01:00.000Z","suppressed":false,"suppressedReason":null,"consent":{"source":"form","capturedAt":"2026-04-08T12:00:00.000Z","policyVersion":"2026-03"},"createdAt":"2026-04-08T12:00:00.000Z","updatedAt":"2026-04-08T12:05:00.000Z","importId":null,"customFields":{"plan":"enterprise","revenue":4200}},"created":true,"fieldsCreated":["plan"],"warnings":[]}}},"exampleType":"examples"}},"exampleType":"examples"},"342400e8-8916-48f4-a86f-f9718227f215":{"description":"Batch partially applied — inspect `errors[]` for each failed row.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"inserted":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"summary.inserted","typeLabel":"integer"},"updated":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"summary.updated","typeLabel":"integer"},"failed":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"summary.failed","typeLabel":"integer"}},"required":["inserted","updated","failed"],"additionalProperties":false,"isRequired":true,"uniqueKey":"summary","typeLabel":"object"},"fieldsCreated":{"type":"array","items":{"type":"string","uniqueKey":"fieldsCreated.items.[INDEX]","typeLabel":"string"},"isRequired":true,"uniqueKey":"fieldsCreated","typeLabel":"string[]"},"errors":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].email","typeLabel":"string"},"code":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"row":{"type":"integer","exclusiveMinimum":0,"description":"The 1-based row that failed: `contacts[row - 1]`, or the CSV data row (header and blank lines not counted).","uniqueKey":"errors.items.[INDEX].row","typeLabel":"integer"},"field":{"type":"string","uniqueKey":"errors.items.[INDEX].field","typeLabel":"string"}},"required":["email","code","message"],"additionalProperties":false,"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"errors","typeLabel":"object[]"},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"warnings.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"warnings.items.[INDEX].message","typeLabel":"string"},"email":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].email","typeLabel":"string"},"row":{"type":"integer","exclusiveMinimum":0,"description":"The 1-based row it is about (CSV: data row; header and blank lines not counted).","uniqueKey":"warnings.items.[INDEX].row","typeLabel":"integer"},"field":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].field","typeLabel":"string"},"from":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].from","typeLabel":"string"},"to":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].to","typeLabel":"string"},"original":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].original","typeLabel":"string"},"normalized":{"type":"string","minLength":1,"uniqueKey":"warnings.items.[INDEX].normalized","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"uniqueKey":"warnings.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"warnings","typeLabel":"object[]"},"validation":{"type":"object","properties":{"valid":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.valid","typeLabel":"integer"},"risky":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.risky","typeLabel":"integer"},"invalid":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.invalid","typeLabel":"integer"},"unscored":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.unscored","typeLabel":"integer"},"persistence":{"type":"object","properties":{"matched":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.matched","typeLabel":"integer"},"modified":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.modified","typeLabel":"integer"},"failed":{"type":"integer","minimum":0,"isRequired":true,"uniqueKey":"validation.persistence.failed","typeLabel":"integer"}},"required":["matched","modified","failed"],"additionalProperties":false,"uniqueKey":"validation.persistence","typeLabel":"object"}},"required":["valid","risky","invalid","unscored"],"additionalProperties":false,"uniqueKey":"validation","typeLabel":"object"},"validationJobId":{"type":"string","uniqueKey":"validationJobId","typeLabel":"string"}},"required":["summary","fieldsCreated","errors","warnings"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"summary":{"inserted":1,"updated":0,"failed":2},"fieldsCreated":[],"errors":[{"email":"not-an-email","code":"INVALID_EMAIL","message":"not-an-email is not a valid email address."},{"email":"john@example.com","code":"FIELD_TYPE_MISMATCH","field":"customFields.plan","message":"Field 'customFields.plan' is type 'number' but received string '$49'."}],"warnings":[]},"examples":{"Example":{"title":"Example","value":{"summary":{"inserted":1,"updated":0,"failed":2},"fieldsCreated":[],"errors":[{"email":"not-an-email","code":"INVALID_EMAIL","message":"not-an-email is not a valid email address."},{"email":"john@example.com","code":"FIELD_TYPE_MISMATCH","field":"customFields.plan","message":"Field 'customFields.plan' is type 'number' but received string '$49'."}],"warnings":[]}}},"exampleType":"examples"}},"exampleType":"examples"},"85539d9c-a3a8-4a23-9ab0-9868079927ab":{"description":"`BRAND_ID_REQUIRED`: An organization-scoped credential called a brand-scoped operation without naming the brand.\n\n`INVALID_REQUEST`: The body or query failed validation: an unknown key, a wrong type, or a missing required field. `param` names the first offender; with more than one problem, `details.issues[]` lists each one (`{ param?, message }`, at most 20).","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"brandIdRequired":{"title":"brandIdRequired","value":{"error":{"code":"BRAND_ID_REQUIRED","type":"invalid_request","message":"An organization-scoped credential called a brand-scoped operation without naming the brand.","suggestion":"List brands with GET /v1/brands, then name one with the X-Brand-Id header. There is no default brand.","docs":"https://docs.brew.new/api-reference/api/authentication"}}},"invalidRequest":{"title":"invalidRequest","value":{"error":{"code":"INVALID_REQUEST","type":"invalid_request","message":"The body or query failed validation: an unknown key, a wrong type, or a missing required field. `param` names the first offender; with more than one problem, `details.issues[]` lists each one (`{ param?, message }`, at most 20).","suggestion":"Fix the field reported in `param`, and every entry in `details.issues[]` when present, then retry.","docs":"https://docs.brew.new/api-reference/api/errors"}}}},"exampleType":"examples"}},"exampleType":"examples"},"1f4fddcf-9651-43e5-a168-1857fa48cb33":{"description":"`API_KEY_REVOKED`: The API key was revoked.\n\n`AUTHENTICATION_REQUIRED`: No API key or session accompanied the request.\n\n`INVALID_API_KEY`: The API key is malformed or unknown.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"apiKeyRevoked":{"title":"apiKeyRevoked","value":{"error":{"code":"API_KEY_REVOKED","type":"authentication_error","message":"The API key was revoked.","suggestion":"Create a new active API key and retry.","docs":"https://docs.brew.new/api-reference/api/authentication"}}},"authenticationRequired":{"title":"authenticationRequired","value":{"error":{"code":"AUTHENTICATION_REQUIRED","type":"authentication_error","message":"No API key or session accompanied the request.","suggestion":"Provide a valid API key or sign in with an organization session.","docs":"https://docs.brew.new/api-reference/api/authentication"}}},"invalidApiKey":{"title":"invalidApiKey","value":{"error":{"code":"INVALID_API_KEY","type":"authentication_error","message":"The API key is malformed or unknown.","suggestion":"Check the API key format and retry with a valid active key.","docs":"https://docs.brew.new/api-reference/api/authentication"}}}},"exampleType":"examples"}},"exampleType":"examples"},"faa6e820-f8f2-4bc3-96a1-44f8403917d3":{"description":"`INSUFFICIENT_CREDITS`: The credit balance is below what this operation requires; `details.cost` is the amount needed.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"insufficientCredits":{"title":"insufficientCredits","value":{"error":{"code":"INSUFFICIENT_CREDITS","type":"payment_required","message":"The credit balance is below what this operation requires; `details.cost` is the amount needed.","suggestion":"Upgrade your plan or wait for the next billing period to reset. Check your balance up front with GET /v1/usage.","docs":"https://docs.brew.new/api-reference/api/credits","details":{"cost":5,"remaining":0,"planKey":"free"}}}}},"exampleType":"examples"}},"exampleType":"examples"},"dde88fc3-513f-43f8-8639-b035d2592764":{"description":"`ACCOUNT_SUSPENDED`: The organization behind the credential is suspended.\n\n`BRAND_SCOPE_MISMATCH`: A brand-scoped credential named a brand other than the one it is bound to.\n\n`INSUFFICIENT_PERMISSIONS`: The credential lacks the permission scope the operation needs.\n\n`INSUFFICIENT_ROLE`: The caller lacks the access the operation needs: `param` names `member` (access to the brand) or `org_admin` (the organization role).","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"accountSuspended":{"title":"accountSuspended","value":{"error":{"code":"ACCOUNT_SUSPENDED","type":"authorization_error","message":"The organization behind the credential is suspended.","suggestion":"The organization behind this credential is suspended. Contact support@brew.new; do not retry.","docs":"https://docs.brew.new/api-reference/api/authentication"}}},"brandScopeMismatch":{"title":"brandScopeMismatch","value":{"error":{"code":"BRAND_SCOPE_MISMATCH","type":"authorization_error","message":"A brand-scoped credential named a brand other than the one it is bound to.","suggestion":"Omit the brand to use the one this credential is bound to, or use an organization-scoped credential to reach other brands.","docs":"https://docs.brew.new/api-reference/api/authentication"}}},"insufficientPermissions":{"title":"insufficientPermissions","value":{"error":{"code":"INSUFFICIENT_PERMISSIONS","type":"authorization_error","message":"The credential lacks the permission scope the operation needs.","suggestion":"Use an API key or session with the required permission.","docs":"https://docs.brew.new/api-reference/api/authentication"}}},"insufficientRole":{"title":"insufficientRole","value":{"error":{"code":"INSUFFICIENT_ROLE","type":"authorization_error","message":"The caller lacks the access the operation needs: `param` names `member` (access to the brand) or `org_admin` (the organization role).","suggestion":"Ask an organization admin to run this, to add you to the brand, or to make you an admin.","docs":"https://docs.brew.new/api-reference/api/authentication"}}}},"exampleType":"examples"}},"exampleType":"examples"},"f5234bd7-b73d-4e21-9d59-60c6f82a7111":{"description":"`BRAND_NOT_FOUND`: The named or bound brand does not exist in this organization (unknown, deleting, or another organization).","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"brandNotFound":{"title":"brandNotFound","value":{"error":{"code":"BRAND_NOT_FOUND","type":"not_found","message":"The named or bound brand does not exist in this organization (unknown, deleting, or another organization).","suggestion":"List the brands this credential can reach with GET /v1/brands.","docs":"https://docs.brew.new/api-reference/api/errors"}}}},"exampleType":"examples"}},"exampleType":"examples"},"c800dfef-40dc-437e-baf1-280edc97b18b":{"description":"`FIELD_TYPE_MISMATCH`: A value does not match the declared type of its custom field.\n\n`IDEMPOTENCY_CONFLICT`: The same Idempotency-Key was reused with a different request body.\n\n`IDEMPOTENCY_IN_PROGRESS`: A request with this Idempotency-Key is still executing.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"fieldTypeMismatch":{"title":"fieldTypeMismatch","value":{"error":{"code":"FIELD_TYPE_MISMATCH","type":"conflict","message":"A value does not match the declared type of its custom field.","suggestion":"Send a value that matches the field's type. To change the type, delete the field (this clears its value on every contact) and create it again.","docs":"https://docs.brew.new/api-reference/api/errors"}}},"idempotencyConflict":{"title":"idempotencyConflict","value":{"error":{"code":"IDEMPOTENCY_CONFLICT","type":"conflict","message":"The same Idempotency-Key was reused with a different request body.","suggestion":"Reuse the original payload or send a new idempotency key.","docs":"https://docs.brew.new/api-reference/api/idempotency"}}},"idempotencyInProgress":{"title":"idempotencyInProgress","value":{"error":{"code":"IDEMPOTENCY_IN_PROGRESS","type":"conflict","message":"A request with this Idempotency-Key is still executing.","suggestion":"Wait for the original request to finish, then retry the same key to replay its response.","docs":"https://docs.brew.new/api-reference/api/idempotency"}}}},"exampleType":"examples"}},"exampleType":"examples"},"01ed4120-3fed-46c8-a517-9d1a5e8563c4":{"description":"`BATCH_TOO_LARGE`: A batch write exceeds the per-request row cap.\n\n`CORE_FIELD_IMMUTABLE`: The field is a core contact column and cannot be created, changed, or deleted as a custom field.\n\n`FIELD_NAME_COLLISION`: Two keys in one request name the same contact field (`plan` and `Plan`, `team_size` and `Team Size`), so one value would be lost.\n\n`INVALID_EMAIL`: A contact email is not a deliverable address shape.\n\n`MISSING_EMAIL`: A contact row has no `email`, the primary key.\n\n`RESUBSCRIBE_NOT_ALLOWED`: The write set `subscribed` to true on a contact who unsubscribed, and Brew never re-subscribes an opt-out through the API, MCP or an import; `details.email` names the contact.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"batchTooLarge":{"title":"batchTooLarge","value":{"error":{"code":"BATCH_TOO_LARGE","type":"invalid_request","message":"A batch write exceeds the per-request row cap.","suggestion":"Split the request into smaller batches and retry.","docs":"https://docs.brew.new/api-reference/api/errors"}}},"coreFieldImmutable":{"title":"coreFieldImmutable","value":{"error":{"code":"CORE_FIELD_IMMUTABLE","type":"invalid_request","message":"The field is a core contact column and cannot be created, changed, or deleted as a custom field.","suggestion":"Use a custom field name instead.","docs":"https://docs.brew.new/api-reference/api/errors"}}},"fieldNameCollision":{"title":"fieldNameCollision","value":{"error":{"code":"FIELD_NAME_COLLISION","type":"invalid_request","message":"Two keys in one request name the same contact field (`plan` and `Plan`, `team_size` and `Team Size`), so one value would be lost.","suggestion":"Send one of the two keys, or rename one so it names a different field.","docs":"https://docs.brew.new/api-reference/api/errors"}}},"invalidEmail":{"title":"invalidEmail","value":{"error":{"code":"INVALID_EMAIL","type":"invalid_request","message":"A contact email is not a deliverable address shape.","suggestion":"Fix the address named in `param` and retry.","docs":"https://docs.brew.new/api-reference/api/errors"}}},"missingEmail":{"title":"missingEmail","value":{"error":{"code":"MISSING_EMAIL","type":"invalid_request","message":"A contact row has no `email`, the primary key.","suggestion":"Provide an email address for every contact in the request body.","docs":"https://docs.brew.new/api-reference/api/errors"}}},"resubscribeNotAllowed":{"title":"resubscribeNotAllowed","value":{"error":{"code":"RESUBSCRIBE_NOT_ALLOWED","type":"invalid_request","message":"The write set `subscribed` to true on a contact who unsubscribed, and Brew never re-subscribes an opt-out through the API, MCP or an import; `details.email` names the contact.","suggestion":"Drop `subscribed` from the write; a contact who opted out re-subscribes through their own action, or from their contact page in the Brew app once they ask.","docs":"https://docs.brew.new/api-reference/api/errors"}}}},"exampleType":"examples"}},"exampleType":"examples"},"2042128b-ea9c-4557-aef2-f8fd741e2259":{"description":"`RATE_LIMITED`: The credential exhausted the rolling window for this route policy; Retry-After is when the oldest recorded request leaves, and the refused request does not take a slot.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."},"X-RateLimit-Limit":{"schema":{"type":"integer","description":"Requests allowed in the current rolling rate limit window.","example":10},"required":true,"description":"Requests allowed in the current rolling rate limit window."},"X-RateLimit-Remaining":{"schema":{"type":"integer","description":"Requests remaining in the current rolling rate limit window.","example":0},"required":true,"description":"Requests remaining in the current rolling rate limit window."},"X-RateLimit-Reset":{"schema":{"type":"integer","description":"Unix timestamp in seconds when the oldest recorded request leaves the rolling window.","example":1712592360},"required":true,"description":"Unix timestamp in seconds when the oldest recorded request leaves the rolling window."},"Retry-After":{"schema":{"type":"integer","description":"Seconds to wait before retrying the request.","example":42},"required":true,"description":"Seconds to wait before retrying the request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"rateLimited":{"title":"rateLimited","value":{"error":{"code":"RATE_LIMITED","type":"rate_limit","message":"The credential exhausted the rolling window for this route policy; Retry-After is when the oldest recorded request leaves, and the refused request does not take a slot.","suggestion":"Wait the Retry-After time, then retry the same request.","docs":"https://docs.brew.new/api-reference/api/rate-limits","retryAfter":42,"details":{"scope":"credential","limit":10,"remaining":0,"reset":1712592360,"consumed":false}}}}},"exampleType":"examples"}},"exampleType":"examples"},"f184c643-2fe4-44fb-a72b-a6f18d87bee0":{"description":"`INTERNAL_ERROR`: An unexpected failure; the x-request-id header identifies it.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"internalError":{"title":"internalError","value":{"error":{"code":"INTERNAL_ERROR","type":"internal_error","message":"An unexpected failure; the x-request-id header identifies it.","suggestion":"Retry the request. If it keeps failing, contact support with the x-request-id header.","docs":"https://docs.brew.new/api-reference/api/errors"}}}},"exampleType":"examples"}},"exampleType":"examples"},"2e4c51fe-6b4f-4b28-8769-037b239303f6":{"description":"`SERVICE_UNAVAILABLE`: A dependency the operation must consult (billing, the idempotency store) is temporarily unavailable, so the request was refused rather than run unmetered.","headers":{"x-request-id":{"schema":{"type":"string","description":"Unique request identifier. Share this with support when debugging a request.","example":"req_8cac13fd94e6420cacdd75a1aa403a28"},"required":true,"description":"Unique request identifier. Share this with support when debugging a request."},"Retry-After":{"schema":{"type":"integer","description":"Seconds to wait before retrying the request.","example":42},"required":true,"description":"Seconds to wait before retrying the request."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["ACCOUNT_SUSPENDED","API_KEY_REVOKED","AUDIENCE_BUILD_ACTIVE","AUDIENCE_BUILD_ALREADY_ACTIVE","AUDIENCE_EDIT_CONFLICT","AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE","AUDIENCE_NOT_FOUND","AUDIENCE_RUN_NOT_FOUND","AUDIT_NOT_FOUND","AUTHENTICATION_REQUIRED","AUTOMATION_GRAPH_INVALID","AUTOMATION_NOT_FOUND","AUTOMATION_NOT_PAUSABLE","AUTOMATION_NOT_PUBLISHED","AUTOMATION_RUN_NOT_FOUND","AUTOMATION_VERSION_CONFLICT","AUTOMATION_VERSION_NOT_FOUND","BATCH_TOO_LARGE","BRAND_DOMAIN_CONFLICT","BRAND_ID_REQUIRED","BRAND_LIMIT_REACHED","BRAND_NOT_FOUND","BRAND_NOT_READY","BRAND_SCOPE_MISMATCH","CHAT_NOT_FOUND","COMMENT_NOT_FOUND","CONSENT_REQUIRED","CONTACT_NOT_FOUND","CONTENT_OPERATION_FAILED","CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS","CORE_FIELD_IMMUTABLE","DOMAIN_ALREADY_EXISTS","DOMAIN_CLAIMED_ELSEWHERE","DOMAIN_NOT_FOUND","DOMAIN_NOT_READY","DOMAIN_OTHER_BRAND","DOMAIN_PROVIDER_ERROR","DOMAIN_PURPOSE_NOT_ALLOWED","DOMAIN_VERIFICATION_FAILED","DOMAIN_VERIFIED_ELSEWHERE","EMAIL_GENERATION_FAILED","EMAIL_GROUP_NAME_CONFLICT","EMAIL_GROUP_NOT_FOUND","EMAIL_IMAGES_MISSING","EMAIL_IMPORT_FAILED","EMAIL_IMPORT_PERSISTENCE_FAILED","EMAIL_IN_PROGRESS","EMAIL_IN_USE_BY_AUTOMATION","EMAIL_NOT_FOUND","EMAIL_NOT_READY","EMAIL_RESULT_UNAVAILABLE","EMAIL_RUN_AMBIGUOUS","EMAIL_TEMPLATE_INVALID","EMAIL_VERSION_NOT_FOUND","EXPORT_PROVIDER_ERROR","EXPORT_UNSUPPORTED","FIELD_NAME_COLLISION","FIELD_NOT_FOUND","FIELD_TYPE_MISMATCH","FIGMA_ACCESS_DENIED","FIGMA_CONVERSION_FAILED","FIGMA_FRAME_NOT_FOUND","FIGMA_NOT_CONNECTED","FIGMA_UNAVAILABLE","FIGMA_URL_INVALID","FLOW_NOT_FOUND","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","INSIGHT_NOT_FOUND","INSUFFICIENT_CREDITS","INSUFFICIENT_PERMISSIONS","INSUFFICIENT_ROLE","INTEGRATION_NOT_CONNECTED","INTERNAL_ERROR","INVALID_API_KEY","INVALID_EMAIL","INVALID_PAYLOAD","INVALID_REQUEST","LIQUID_RENDER_ERROR","METHOD_NOT_ALLOWED","MISSING_EMAIL","NO_ELIGIBLE_RECIPIENTS","NO_PUBLISHED_AUTOMATION","NOT_FOUND","NOT_IMPLEMENTED","ORG_SCOPE_REQUIRED","PAYLOAD_SCHEMA_EMAIL_REQUIRED","PAYLOAD_TOO_LARGE","PREVIEW_NOT_FOUND","PUBLISH_VALIDATION_FAILED","RATE_LIMITED","RECIPIENT_UNSUBSCRIBED","REFERENCE_EMAIL_NOT_FOUND","RESUBSCRIBE_NOT_ALLOWED","RUN_IN_PROGRESS","RUN_NOT_CANCELLABLE","RUN_NOT_PAUSABLE","RUN_NOT_PAUSED","RUN_NOT_RESUMABLE","RUN_START_FAILED","RUN_STOP_FAILED","SEND_NOT_CANCELLABLE","SEND_NOT_FOUND","SEND_NOT_PAUSABLE","SEND_NOT_RESUMABLE","SEND_QUOTA_EXCEEDED","SERVICE_UNAVAILABLE","TEMPLATE_NOT_FOUND","TEST_RECIPIENT_NOT_ALLOWED","TRIGGER_ALREADY_EXISTS","TRIGGER_EVENT_NOT_FOUND","TRIGGER_HAS_DEPENDENT_AUTOMATIONS","TRIGGER_IMMUTABLE","TRIGGER_INSTANCE_NOT_FOUND","TRIGGER_LIMIT_REACHED","TRIGGER_NOT_FIREABLE","UPLOAD_IN_PROGRESS","UPLOAD_NOT_FOUND","UPLOAD_NOT_RECEIVED"],"isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"type":{"type":"string","enum":["authentication_error","authorization_error","invalid_request","not_found","not_implemented","conflict","rate_limit","payment_required","service_unavailable","internal_error"],"isRequired":true,"uniqueKey":"error.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"suggestion":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"error.suggestion","typeLabel":"string"},"docs":{"type":"string","format":"uri","isRequired":true,"uniqueKey":"error.docs","typeLabel":"string\u003curi>"},"param":{"type":"string","minLength":1,"uniqueKey":"error.param","typeLabel":"string"},"retryAfter":{"type":"integer","minimum":0,"uniqueKey":"error.retryAfter","typeLabel":"integer"},"details":{"type":"object","additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.additionalProperties","typeLabel":"any"},"uniqueKey":"error.details","typeLabel":"object"}},"required":["code","type","message","suggestion","docs"],"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"uniqueKey":"","typeLabel":"object"},"examples":{"serviceUnavailable":{"title":"serviceUnavailable","value":{"error":{"code":"SERVICE_UNAVAILABLE","type":"service_unavailable","message":"A dependency the operation must consult (billing, the idempotency store) is temporarily unavailable, so the request was refused rather than run unmetered.","suggestion":"Retry the request after a short delay.","docs":"https://docs.brew.new/api-reference/api/errors"}}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"3becd03d-c396-4bc3-84c1-231cdbf0a23e":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key","description":"Send your Brew API key as `Authorization: Bearer brew_xxx`.","x-default":"Bearer brew_your_api_key","scopes":[],"schemeName":"bearerAuth"}},"a3a3e731-b20f-48f7-873a-3123be78670a":{"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Send your Brew API key as `X-API-Key: brew_xxx`.","x-default":"brew_your_api_key","scopes":[],"schemeName":"apiKeyAuth"}}},"servers":{"16779731-d97b-4178-b35d-ab9db802c966":{"url":"https://brew.new/api","description":"Production"},"d75b81f5-e341-4448-9191-a43a58d2508e":{"url":"http://localhost:3000/api","description":"Local development"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"API key","description":"Send your Brew API key as `Authorization: Bearer brew_xxx`.","x-default":"Bearer brew_your_api_key","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Send your Brew API key as `Authorization: Bearer brew_xxx`.","format":"bearer","default":"Bearer brew_your_api_key","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"},{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Send your Brew API key as `X-API-Key: brew_xxx`.","x-default":"brew_your_api_key","scopes":[],"schemeName":"apiKeyAuth"},"schema":{"title":"X-API-Key","type":"string","description":"Send your Brew API key as `X-API-Key: brew_xxx`.","isRequired":true,"default":"brew_your_api_key","typeLabel":"string","deprecated":false},"schemeName":"apiKeyAuth","name":"X-API-Key"}],"title":"apiKeyAuth"}]},"originalFileLocation":"api-reference/openapi-public-v1.yaml"},"subdomain":"brew-796f053a","siteName":"Brew Help Docs","title":"Create or update contacts - Brew Help Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-06T17:55:00.415Z","originalFileLocation":"api-reference/public-v1/contacts/create-or-update-contacts.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Upserts a single contact OR a batch ({ contacts: [...] }, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → date, anything else string). fieldsCreated names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with POST /v1/fields to pin its type. Custom-field names are folded to one key: words split at spaces, _, - and a lower-to-upper letter change, then joined camelCase (Plan, PLAN and plan are the field plan; team_size and Team Size are teamSize). A key written under its folded name adds a FIELD_NAME_NORMALIZED warning (original, normalized). Two keys that fold to one field (plan and Plan) would lose one value, so they are a 422 FIELD_NAME_COLLISION on a single upsert (nothing written) and a per-row errors[] entry (code: FIELD_NAME_COLLISION) in a batch. Custom-field values are coerced to the definition\u0026#x27;s type (dates → epoch ms, \u0026quot;1,234\u0026quot; → 1234, yes/no → booleans). A value that cannot be coerced (\u0026quot;$49\u0026quot; in a number field) is a 409 FIELD_TYPE_MISMATCH on a single upsert and a per-row errors[] entry (code: FIELD_TYPE_MISMATCH, field) in a batch — the other rows still land. A value that was converted adds one warnings[] entry per field (code: FIELD_TYPE_COERCED, field, from, to); a date written to a date field is not reported. A customFields key is never stored under a core field name. One whose loss would change the contact (subscribed, First Name, consent, a suppression flag or domain opt-out, or an email naming another address) is a 422 CORE_FIELD_IMMUTABLE on a single upsert (nothing written) and a per-row errors[] entry (code: CORE_FIELD_IMMUTABLE, field) in a batch; send firstName, lastName, subscribed and consent at the top level. A key naming a field Brew manages (createdAt, validationStatus) is dropped with a warnings[] entry (code: CORE_FIELD_IGNORED, field) and the contact is still written, and an email key repeating the contact address is ignored. Dates: a JSON number is epoch milliseconds. A string may be ISO (2026-04-03, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (3 Apr 2026, April 3, 2026, 03-Apr-26), year-first (2026/04/03), compact (20260403), month and year read as the 1st (2026-04), dotted day-first (03.04.2026), or a slash or dash date. A slash or dash date with a day over 12 reads that way (13/04/2026 is 13 April). One that reads either way (03/04/2026) follows the day/month order the batch\u0026#x27;s other dates in that field prove, else month/day, with a warnings[] entry (code: DATE_ORDER_ASSUMED, field). Send YYYY-MM-DD to be unambiguous. Optional consent: { source: \u0026quot;api\u0026quot; | \u0026quot;form\u0026quot; | \u0026quot;import\u0026quot;, capturedAt?, policyVersion?, evidence? } records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes subscribed. An inline marketing send later needs the contact to be subscribed, and warns when no record exists. subscribed: false unsubscribes the contact, new or existing. subscribed: true only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a 422 RESUBSCRIBE_NOT_ALLOWED (nothing written), and a batch row keeps its other fields and adds a warnings[] entry (code: RESUBSCRIBE_SKIPPED, email). Single: 201 with { contact, created, fieldsCreated, warnings }. Batch: 200 with { summary, fieldsCreated, errors, warnings } — or 207 when some rows failed (per-row errors in errors[]).\">\u003cmeta data-mint-head name=\"keywords\" content=\"AI email marketing, Brew, AI-native email platform, on-brand email, email automations, email analytics, AI agents, MCP email server\">\u003cmeta data-mint-head name=\"application-name\" content=\"Brew Help Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"index, follow\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Create or update contacts - Brew Help Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Upserts a single contact OR a batch ({ contacts: [...] }, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → date, anything else string). fieldsCreated names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with POST /v1/fields to pin its type. Custom-field names are folded to one key: words split at spaces, _, - and a lower-to-upper letter change, then joined camelCase (Plan, PLAN and plan are the field plan; team_size and Team Size are teamSize). A key written under its folded name adds a FIELD_NAME_NORMALIZED warning (original, normalized). Two keys that fold to one field (plan and Plan) would lose one value, so they are a 422 FIELD_NAME_COLLISION on a single upsert (nothing written) and a per-row errors[] entry (code: FIELD_NAME_COLLISION) in a batch. Custom-field values are coerced to the definition\u0026#x27;s type (dates → epoch ms, \u0026quot;1,234\u0026quot; → 1234, yes/no → booleans). A value that cannot be coerced (\u0026quot;$49\u0026quot; in a number field) is a 409 FIELD_TYPE_MISMATCH on a single upsert and a per-row errors[] entry (code: FIELD_TYPE_MISMATCH, field) in a batch — the other rows still land. A value that was converted adds one warnings[] entry per field (code: FIELD_TYPE_COERCED, field, from, to); a date written to a date field is not reported. A customFields key is never stored under a core field name. One whose loss would change the contact (subscribed, First Name, consent, a suppression flag or domain opt-out, or an email naming another address) is a 422 CORE_FIELD_IMMUTABLE on a single upsert (nothing written) and a per-row errors[] entry (code: CORE_FIELD_IMMUTABLE, field) in a batch; send firstName, lastName, subscribed and consent at the top level. A key naming a field Brew manages (createdAt, validationStatus) is dropped with a warnings[] entry (code: CORE_FIELD_IGNORED, field) and the contact is still written, and an email key repeating the contact address is ignored. Dates: a JSON number is epoch milliseconds. A string may be ISO (2026-04-03, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (3 Apr 2026, April 3, 2026, 03-Apr-26), year-first (2026/04/03), compact (20260403), month and year read as the 1st (2026-04), dotted day-first (03.04.2026), or a slash or dash date. A slash or dash date with a day over 12 reads that way (13/04/2026 is 13 April). One that reads either way (03/04/2026) follows the day/month order the batch\u0026#x27;s other dates in that field prove, else month/day, with a warnings[] entry (code: DATE_ORDER_ASSUMED, field). Send YYYY-MM-DD to be unambiguous. Optional consent: { source: \u0026quot;api\u0026quot; | \u0026quot;form\u0026quot; | \u0026quot;import\u0026quot;, capturedAt?, policyVersion?, evidence? } records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes subscribed. An inline marketing send later needs the contact to be subscribed, and warns when no record exists. subscribed: false unsubscribes the contact, new or existing. subscribed: true only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a 422 RESUBSCRIBE_NOT_ALLOWED (nothing written), and a batch row keeps its other fields and adds a warnings[] entry (code: RESUBSCRIBE_SKIPPED, email). Single: 201 with { contact, created, fieldsCreated, warnings }. Batch: 200 with { summary, fieldsCreated, errors, warnings } — or 207 when some rows failed (per-row errors in errors[]).\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Brew Help Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://docs.brew.new/images/og/default.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Create or update contacts - Brew Help Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Upserts a single contact OR a batch ({ contacts: [...] }, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → date, anything else string). fieldsCreated names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with POST /v1/fields to pin its type. Custom-field names are folded to one key: words split at spaces, _, - and a lower-to-upper letter change, then joined camelCase (Plan, PLAN and plan are the field plan; team_size and Team Size are teamSize). A key written under its folded name adds a FIELD_NAME_NORMALIZED warning (original, normalized). Two keys that fold to one field (plan and Plan) would lose one value, so they are a 422 FIELD_NAME_COLLISION on a single upsert (nothing written) and a per-row errors[] entry (code: FIELD_NAME_COLLISION) in a batch. Custom-field values are coerced to the definition\u0026#x27;s type (dates → epoch ms, \u0026quot;1,234\u0026quot; → 1234, yes/no → booleans). A value that cannot be coerced (\u0026quot;$49\u0026quot; in a number field) is a 409 FIELD_TYPE_MISMATCH on a single upsert and a per-row errors[] entry (code: FIELD_TYPE_MISMATCH, field) in a batch — the other rows still land. A value that was converted adds one warnings[] entry per field (code: FIELD_TYPE_COERCED, field, from, to); a date written to a date field is not reported. A customFields key is never stored under a core field name. One whose loss would change the contact (subscribed, First Name, consent, a suppression flag or domain opt-out, or an email naming another address) is a 422 CORE_FIELD_IMMUTABLE on a single upsert (nothing written) and a per-row errors[] entry (code: CORE_FIELD_IMMUTABLE, field) in a batch; send firstName, lastName, subscribed and consent at the top level. A key naming a field Brew manages (createdAt, validationStatus) is dropped with a warnings[] entry (code: CORE_FIELD_IGNORED, field) and the contact is still written, and an email key repeating the contact address is ignored. Dates: a JSON number is epoch milliseconds. A string may be ISO (2026-04-03, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (3 Apr 2026, April 3, 2026, 03-Apr-26), year-first (2026/04/03), compact (20260403), month and year read as the 1st (2026-04), dotted day-first (03.04.2026), or a slash or dash date. A slash or dash date with a day over 12 reads that way (13/04/2026 is 13 April). One that reads either way (03/04/2026) follows the day/month order the batch\u0026#x27;s other dates in that field prove, else month/day, with a warnings[] entry (code: DATE_ORDER_ASSUMED, field). Send YYYY-MM-DD to be unambiguous. Optional consent: { source: \u0026quot;api\u0026quot; | \u0026quot;form\u0026quot; | \u0026quot;import\u0026quot;, capturedAt?, policyVersion?, evidence? } records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes subscribed. An inline marketing send later needs the contact to be subscribed, and warns when no record exists. subscribed: false unsubscribes the contact, new or existing. subscribed: true only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a 422 RESUBSCRIBE_NOT_ALLOWED (nothing written), and a batch row keeps its other fields and adds a warnings[] entry (code: RESUBSCRIBE_SKIPPED, email). Single: 201 with { contact, created, fieldsCreated, warnings }. Batch: 200 with { summary, fieldsCreated, errors, warnings } — or 207 when some rows failed (per-row errors in errors[]).\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://docs.brew.new/images/og/default.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/brew-796f053a/Sm1C1504JEJ_FZ8Q/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Brew Help Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#FF772D\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/public-v1/contacts/create-or-update-contacts.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.brew.new/#organization\",\"name\":\"Brew Help Docs\",\"url\":\"https://docs.brew.new\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/brew-796f053a/QjuRdMJynrgWDqeo/logo/lightmode.svg?fit=max\u0026auto=format\u0026n=QjuRdMJynrgWDqeo\u0026q=85\u0026s=5e906ff65142dc905a773e7747b47816\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.brew.new#website\",\"name\":\"Brew Help Docs\",\"url\":\"https://docs.brew.new\",\"publisher\":{\"@id\":\"https://docs.brew.new/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts#webpage\",\"url\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts\",\"name\":\"Create or update contacts\",\"description\":\"Upserts a single contact OR a batch ({ contacts: [...] }, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → date, anything else string). fieldsCreated names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with POST /v1/fields to pin its type. Custom-field names are folded to one key: words split at spaces, _, - and a lower-to-upper letter change, then joined camelCase (Plan, PLAN and plan are the field plan; team_size and Team Size are teamSize). A key written under its folded name adds a FIELD_NAME_NORMALIZED warning (original, normalized). Two keys that fold to one field (plan and Plan) would lose one value, so they are a 422 FIELD_NAME_COLLISION on a single upsert (nothing written) and a per-row errors[] entry (code: FIELD_NAME_COLLISION) in a batch. Custom-field values are coerced to the definition's type (dates → epoch ms, \\\"1,234\\\" → 1234, yes/no → booleans). A value that cannot be coerced (\\\"$49\\\" in a number field) is a 409 FIELD_TYPE_MISMATCH on a single upsert and a per-row errors[] entry (code: FIELD_TYPE_MISMATCH, field) in a batch — the other rows still land. A value that was converted adds one warnings[] entry per field (code: FIELD_TYPE_COERCED, field, from, to); a date written to a date field is not reported. A customFields key is never stored under a core field name. One whose loss would change the contact (subscribed, First Name, consent, a suppression flag or domain opt-out, or an email naming another address) is a 422 CORE_FIELD_IMMUTABLE on a single upsert (nothing written) and a per-row errors[] entry (code: CORE_FIELD_IMMUTABLE, field) in a batch; send firstName, lastName, subscribed and consent at the top level. A key naming a field Brew manages (createdAt, validationStatus) is dropped with a warnings[] entry (code: CORE_FIELD_IGNORED, field) and the contact is still written, and an email key repeating the contact address is ignored. Dates: a JSON number is epoch milliseconds. A string may be ISO (2026-04-03, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (3 Apr 2026, April 3, 2026, 03-Apr-26), year-first (2026/04/03), compact (20260403), month and year read as the 1st (2026-04), dotted day-first (03.04.2026), or a slash or dash date. A slash or dash date with a day over 12 reads that way (13/04/2026 is 13 April). One that reads either way (03/04/2026) follows the day/month order the batch's other dates in that field prove, else month/day, with a warnings[] entry (code: DATE_ORDER_ASSUMED, field). Send YYYY-MM-DD to be unambiguous. Optional consent: { source: \\\"api\\\" | \\\"form\\\" | \\\"import\\\", capturedAt?, policyVersion?, evidence? } records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes subscribed. An inline marketing send later needs the contact to be subscribed, and warns when no record exists. subscribed: false unsubscribes the contact, new or existing. subscribed: true only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a 422 RESUBSCRIBE_NOT_ALLOWED (nothing written), and a batch row keeps its other fields and adds a warnings[] entry (code: RESUBSCRIBE_SKIPPED, email). Single: 201 with { contact, created, fieldsCreated, warnings }. Batch: 200 with { summary, fieldsCreated, errors, warnings } — or 207 when some rows failed (per-row errors in errors[]).\",\"dateModified\":\"2026-11-06T17:55:00.415Z\",\"isPartOf\":{\"@id\":\"https://docs.brew.new#website\"},\"breadcrumb\":{\"@id\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Public API v1\",\"item\":\"https://docs.brew.new/api-reference/public-v1/emails/list-email-designs\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Contacts\",\"item\":\"https://docs.brew.new/api-reference/public-v1/contacts/list-contacts\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Create or update contacts\",\"item\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts#apireference\",\"headline\":\"Create or update contacts\",\"name\":\"Create or update contacts\",\"description\":\"Upserts a single contact OR a batch ({ contacts: [...] }, up to 1000 rows). Unknown custom fields auto-create field definitions on the brand, typed from the batch (native booleans/numbers, ISO-date strings → date, anything else string). fieldsCreated names only the definitions this request created: when two requests create the same new field at once, the first definition wins and the values in the other request are coerced or refused against it, exactly as if it had been sent second. Create the field first with POST /v1/fields to pin its type. Custom-field names are folded to one key: words split at spaces, _, - and a lower-to-upper letter change, then joined camelCase (Plan, PLAN and plan are the field plan; team_size and Team Size are teamSize). A key written under its folded name adds a FIELD_NAME_NORMALIZED warning (original, normalized). Two keys that fold to one field (plan and Plan) would lose one value, so they are a 422 FIELD_NAME_COLLISION on a single upsert (nothing written) and a per-row errors[] entry (code: FIELD_NAME_COLLISION) in a batch. Custom-field values are coerced to the definition's type (dates → epoch ms, \\\"1,234\\\" → 1234, yes/no → booleans). A value that cannot be coerced (\\\"$49\\\" in a number field) is a 409 FIELD_TYPE_MISMATCH on a single upsert and a per-row errors[] entry (code: FIELD_TYPE_MISMATCH, field) in a batch — the other rows still land. A value that was converted adds one warnings[] entry per field (code: FIELD_TYPE_COERCED, field, from, to); a date written to a date field is not reported. A customFields key is never stored under a core field name. One whose loss would change the contact (subscribed, First Name, consent, a suppression flag or domain opt-out, or an email naming another address) is a 422 CORE_FIELD_IMMUTABLE on a single upsert (nothing written) and a per-row errors[] entry (code: CORE_FIELD_IMMUTABLE, field) in a batch; send firstName, lastName, subscribed and consent at the top level. A key naming a field Brew manages (createdAt, validationStatus) is dropped with a warnings[] entry (code: CORE_FIELD_IGNORED, field) and the contact is still written, and an email key repeating the contact address is ignored. Dates: a JSON number is epoch milliseconds. A string may be ISO (2026-04-03, with or without a time and offset), a Unix timestamp in seconds (10 digits) or milliseconds (13), a month name (3 Apr 2026, April 3, 2026, 03-Apr-26), year-first (2026/04/03), compact (20260403), month and year read as the 1st (2026-04), dotted day-first (03.04.2026), or a slash or dash date. A slash or dash date with a day over 12 reads that way (13/04/2026 is 13 April). One that reads either way (03/04/2026) follows the day/month order the batch's other dates in that field prove, else month/day, with a warnings[] entry (code: DATE_ORDER_ASSUMED, field). Send YYYY-MM-DD to be unambiguous. Optional consent: { source: \\\"api\\\" | \\\"form\\\" | \\\"import\\\", capturedAt?, policyVersion?, evidence? } records marketing consent provenance on the contact (per row, or once at batch level as the default). It never changes subscribed. An inline marketing send later needs the contact to be subscribed, and warns when no record exists. subscribed: false unsubscribes the contact, new or existing. subscribed: true only applies to a NEW contact: Brew never re-subscribes a contact who opted out, so a single upsert asking for it is a 422 RESUBSCRIBE_NOT_ALLOWED (nothing written), and a batch row keeps its other fields and adds a warnings[] entry (code: RESUBSCRIBE_SKIPPED, email). Single: 201 with { contact, created, fieldsCreated, warnings }. Batch: 200 with { summary, fieldsCreated, errors, warnings } — or 207 when some rows failed (per-row errors in errors[]).\",\"url\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts\",\"mainEntityOfPage\":{\"@id\":\"https://docs.brew.new/api-reference/public-v1/contacts/create-or-update-contacts#webpage\"},\"image\":\"https://docs.brew.new/images/og/default.png\",\"dateModified\":\"2026-11-06T17:55:00.415Z\",\"publisher\":{\"@id\":\"https://docs.brew.new/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.brew.new#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Brew Help Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Brew Help Docs","nav":{"global":{},"tabs":[{"tab":"Docs","pages":[{"title":"Docs","href":"/get-started/welcome"}]},{"tab":"Guides","pages":[{"title":"Guides","href":"/brew-university"}]},{"tab":"Integrations","pages":[{"title":"Integrations","href":"/integrations/integrations"}]},{"tab":"Developers","groups":[{"group":"Start Here","pages":[{"title":"Build with Brew","href":"/api-reference/overview"},{"title":"API Introduction","href":"/api-reference/api/api-introduction"},{"title":"Send Your First Email from Code","href":"/api-reference/guides/send-your-first-email-from-code"},{"title":"API Catalog","href":"/api-reference/api/api-catalog"}]},{"group":"Public API v1","pages":[{"group":"Emails","pages":[{"title":"List email designs","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/emails","href":"/api-reference/public-v1/emails/list-email-designs"},{"title":"Generate an email design","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails","href":"/api-reference/public-v1/emails/generate-an-email-design"},{"title":"Get an email design","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/emails/{emailId}","href":"/api-reference/public-v1/emails/get-an-email-design"},{"title":"Delete an email design","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/emails/{emailId}","href":"/api-reference/public-v1/emails/delete-an-email-design"},{"title":"Edit an email design","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/emails/{emailId}","href":"/api-reference/public-v1/emails/edit-an-email-design"},{"title":"Import an email","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/import","href":"/api-reference/public-v1/emails/import-an-email"},{"title":"Import a Figma frame","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/figma","href":"/api-reference/public-v1/emails/import-a-figma-frame"},{"title":"Clone an email design","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/{emailId}/clone","href":"/api-reference/public-v1/emails/clone-an-email-design"},{"title":"Restore a historical version","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/{emailId}/restore","href":"/api-reference/public-v1/emails/restore-a-historical-version"},{"title":"Export a design to an ESP","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/{emailId}/export","href":"/api-reference/public-v1/emails/export-a-design-to-an-esp"},{"title":"Audit an email","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/audit","href":"/api-reference/public-v1/emails/audit-an-email"},{"title":"Preview across clients \u0026 devices","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/{emailId}/client-previews","href":"/api-reference/public-v1/emails/preview-across-clients-\u0026-devices"},{"title":"List inbox placement tests","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/emails/{emailId}/inbox-placement-tests","href":"/api-reference/public-v1/emails/list-inbox-placement-tests"},{"title":"Run an inbox placement test","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/emails/{emailId}/inbox-placement-tests","href":"/api-reference/public-v1/emails/run-an-inbox-placement-test"},{"title":"Get inbox placement test results","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/emails/{emailId}/inbox-placement-tests/{testId}","href":"/api-reference/public-v1/emails/get-inbox-placement-test-results"},{"title":"Read a saved email audit","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/emails/audits/{auditId}","href":"/api-reference/public-v1/emails/read-a-saved-email-audit"},{"title":"Read email rendering progress","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/emails/client-previews/{previewId}","href":"/api-reference/public-v1/emails/read-email-rendering-progress"},{"title":"Create an authenticated email canvas embed session","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/canvas/sessions","href":"/api-reference/public-v1/emails/create-an-authenticated-email-canvas-embed-session"},{"title":"Refresh a canvas session","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/canvas/sessions/{sessionId}/refresh","href":"/api-reference/public-v1/emails/refresh-a-canvas-session"},{"title":"Revoke a canvas session","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/canvas/sessions/{sessionId}","href":"/api-reference/public-v1/emails/revoke-a-canvas-session"},{"title":"List email groups","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/email-groups","href":"/api-reference/public-v1/emails/list-email-groups"},{"title":"Create an email group","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/email-groups","href":"/api-reference/public-v1/emails/create-an-email-group"},{"title":"Get an email group","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/email-groups/{groupId}","href":"/api-reference/public-v1/emails/get-an-email-group"},{"title":"Delete an email group","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/email-groups/{groupId}","href":"/api-reference/public-v1/emails/delete-an-email-group"},{"title":"Update an email group","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/email-groups/{groupId}","href":"/api-reference/public-v1/emails/update-an-email-group"},{"title":"Send an email","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/sends","href":"/api-reference/public-v1/emails/send-an-email"},{"title":"Cancel a send","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/sends/{sendId}/cancel","href":"/api-reference/public-v1/emails/cancel-a-send"},{"title":"Pause a gradual send","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/sends/{sendId}/pause","href":"/api-reference/public-v1/emails/pause-a-gradual-send"},{"title":"Resume a paused gradual send","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/sends/{sendId}/resume","href":"/api-reference/public-v1/emails/resume-a-paused-gradual-send"},{"title":"List email comments","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/emails/{emailId}/comments","href":"/api-reference/public-v1/emails/list-email-comments"}]},{"group":"Sends","pages":[{"title":"List sends","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/sends","href":"/api-reference/public-v1/sends/list-sends"},{"title":"Get a send","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/sends/{sendId}","href":"/api-reference/public-v1/sends/get-a-send"}]},{"group":"Analytics","pages":[{"title":"Brand overview (totals, rates, timeseries)","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/analytics/overview","href":"/api-reference/public-v1/analytics/brand-overview-totals-rates-timeseries"},{"title":"Automation performance","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/analytics/automations","href":"/api-reference/public-v1/analytics/automation-performance"},{"title":"Unified events feed","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/analytics/events","href":"/api-reference/public-v1/analytics/unified-events-feed"}]},{"group":"Automations","pages":[{"title":"List automations","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations","href":"/api-reference/public-v1/automations/list-automations"},{"title":"Create an automation","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations","href":"/api-reference/public-v1/automations/create-an-automation"},{"title":"Get an automation","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/{automationId}","href":"/api-reference/public-v1/automations/get-an-automation"},{"title":"Delete an automation","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/automations/{automationId}","href":"/api-reference/public-v1/automations/delete-an-automation"},{"title":"Update or publish an automation","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/automations/{automationId}","href":"/api-reference/public-v1/automations/update-or-publish-an-automation"},{"title":"Test an automation","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/{automationId}/test","href":"/api-reference/public-v1/automations/test-an-automation"},{"title":"Run a manual-audience automation","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/{automationId}/run","href":"/api-reference/public-v1/automations/run-a-manual-audience-automation"},{"title":"List manual-audience runs","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/audience-runs","href":"/api-reference/public-v1/automations/list-manual-audience-runs"},{"title":"Get a manual-audience run","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/audience-runs/{audienceRunId}","href":"/api-reference/public-v1/automations/get-a-manual-audience-run"},{"title":"Pause a manual-audience run","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/audience-runs/{audienceRunId}/pause","href":"/api-reference/public-v1/automations/pause-a-manual-audience-run"},{"title":"Resume a manual-audience run","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/audience-runs/{audienceRunId}/resume","href":"/api-reference/public-v1/automations/resume-a-manual-audience-run"},{"title":"Cancel a manual-audience run","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/audience-runs/{audienceRunId}/cancel","href":"/api-reference/public-v1/automations/cancel-a-manual-audience-run"},{"title":"List automation runs","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/runs","href":"/api-reference/public-v1/automations/list-automation-runs"},{"title":"Get an automation run","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/runs/{automationRunId}","href":"/api-reference/public-v1/automations/get-an-automation-run"},{"title":"Cancel an automation run","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/runs/{automationRunId}/cancel","href":"/api-reference/public-v1/automations/cancel-an-automation-run"},{"title":"Get or create an unsubscribe trigger","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/triggers/brew-events","href":"/api-reference/public-v1/automations/get-or-create-an-unsubscribe-trigger"},{"title":"List triggers","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/triggers","href":"/api-reference/public-v1/automations/list-triggers"},{"title":"Create a trigger","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/triggers","href":"/api-reference/public-v1/automations/create-a-trigger"},{"title":"Get a trigger","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/triggers/{triggerEventId}","href":"/api-reference/public-v1/automations/get-a-trigger"},{"title":"Delete a trigger","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/automations/triggers/{triggerEventId}","href":"/api-reference/public-v1/automations/delete-a-trigger"},{"title":"Update a trigger","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/automations/triggers/{triggerEventId}","href":"/api-reference/public-v1/automations/update-a-trigger"},{"title":"Check a trigger is ready to fire","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/triggers/{triggerEventId}/readiness","href":"/api-reference/public-v1/automations/check-a-trigger-is-ready-to-fire"},{"title":"Fire a trigger","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/triggers/{triggerEventId}/fire","href":"/api-reference/public-v1/automations/fire-a-trigger"},{"title":"Get a trigger payload contract","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/triggers/{triggerEventId}/contract","href":"/api-reference/public-v1/automations/get-a-trigger-payload-contract"},{"title":"Declare a trigger payload contract","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml put /v1/automations/triggers/{triggerEventId}/contract","href":"/api-reference/public-v1/automations/declare-a-trigger-payload-contract"},{"title":"Validate a trigger payload","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/automations/triggers/{triggerEventId}/contract/validate","href":"/api-reference/public-v1/automations/validate-a-trigger-payload"},{"title":"Infer a payload contract from an example","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/payload-contracts/infer","href":"/api-reference/public-v1/automations/infer-a-payload-contract-from-an-example"},{"title":"List trigger instances","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/trigger-instances","href":"/api-reference/public-v1/automations/list-trigger-instances"},{"title":"Get a trigger instance","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/automations/trigger-instances/{triggerInstanceId}","href":"/api-reference/public-v1/automations/get-a-trigger-instance"}]},{"group":"Contacts","pages":[{"title":"List contacts","description":"Lists the brand’s contacts under `{ data, pagination }`, newest first by default.\n\n**Use when** paging through contacts, running a free-text search, or reading one saved audience’s members. Typed filter clauses and counts are `searchContacts`.\n\n**Input** `search` (a whole email address matches only that contact, with its `+` encoded as `%2B`; other text matches any of its words in email, first and last name), `audienceId` (only that saved audience’s members), `sort` (any core column or custom field, default `createdAt`) and `order`, `limit` and `cursor`.\n\n**Returns** `200` with a page of `Contact` rows.\n\n**Errors** `400 INVALID_REQUEST` for an unknown `audienceId`, an unsupported `sort` field or an invalid cursor.\n\n**See also** `getContact`, `searchContacts`, `upsertContacts`, `listContactFields`.","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/contacts","href":"/api-reference/public-v1/contacts/list-contacts"},{"title":"Create or update contacts","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts","href":"/api-reference/public-v1/contacts/create-or-update-contacts"},{"title":"Get a contact","description":"Reads one contact as the bare `Contact` row: core columns, `subscribed`, `consent`, validation state and `customFields`.\n\n**Use when** checking whether an address exists, reading its consent record, or inspecting its custom fields before a send.\n\n**Input** `email` in the path (URL-encoded; matched case-insensitively). `include=openProfile` attaches `openProfile`: the smart-send open-time profile, 48 UTC half-hour open counts (`histogram`), `totalOpens`, `lastOpenedAt`, and once there is enough history `bestOpenMinuteUtc`, `bestSendMinuteUtc` and `confidence`; `null` when the contact has no opens folded yet. It is not bot detection: machine opens cannot be told apart in it (per-event classification is on `getEventsAnalytics`). It needs the `emails` scope as well as `contacts`.\n\n**Returns** `200` with the row.\n\n**Errors** `404 CONTACT_NOT_FOUND` when no contact carries that address; `403 INSUFFICIENT_PERMISSIONS` when `include=openProfile` is asked for without the `emails` scope; `400 INVALID_REQUEST` for an unknown `include` token.\n\n**See also** `listContacts`, `updateContact`, `deleteContact`, `upsertContacts`.","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/contacts/{email}","href":"/api-reference/public-v1/contacts/get-a-contact"},{"title":"Delete a contact","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/contacts/{email}","href":"/api-reference/public-v1/contacts/delete-a-contact"},{"title":"Update a contact","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/contacts/{email}","href":"/api-reference/public-v1/contacts/update-a-contact"},{"title":"Get contacts","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts/search","href":"/api-reference/public-v1/contacts/get-contacts"},{"title":"Validate email deliverability","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts/validate","href":"/api-reference/public-v1/contacts/validate-email-deliverability"},{"title":"Bulk-import contacts from CSV","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts/import-csv","href":"/api-reference/public-v1/contacts/bulk-import-contacts-from-csv"},{"title":"Bulk-import contacts from JSON","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts/import","href":"/api-reference/public-v1/contacts/bulk-import-contacts-from-json"},{"title":"Batch-delete contacts","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/contacts/batch-delete","href":"/api-reference/public-v1/contacts/batch-delete-contacts"}]},{"group":"Contact Fields","pages":[{"title":"List contact fields","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/fields","href":"/api-reference/public-v1/contact-fields/list-contact-fields"},{"title":"Create a contact field","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/fields","href":"/api-reference/public-v1/contact-fields/create-a-contact-field"},{"title":"Get a contact field","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/fields/{fieldName}","href":"/api-reference/public-v1/contact-fields/get-a-contact-field"},{"title":"Delete a contact field","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/fields/{fieldName}","href":"/api-reference/public-v1/contact-fields/delete-a-contact-field"}]},{"group":"Audiences","pages":[{"title":"List audiences","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/audiences","href":"/api-reference/public-v1/audiences/list-audiences"},{"title":"Create an audience","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/audiences","href":"/api-reference/public-v1/audiences/create-an-audience"},{"title":"Get an audience","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/audiences/{audienceId}","href":"/api-reference/public-v1/audiences/get-an-audience"},{"title":"Delete an audience","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/audiences/{audienceId}","href":"/api-reference/public-v1/audiences/delete-an-audience"},{"title":"Update an audience","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/audiences/{audienceId}","href":"/api-reference/public-v1/audiences/update-an-audience"},{"title":"Create an audience from analytics events","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/audiences/from-events","href":"/api-reference/public-v1/audiences/create-an-audience-from-analytics-events"},{"title":"Duplicate an audience","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/audiences/{audienceId}/duplicate","href":"/api-reference/public-v1/audiences/duplicate-an-audience"}]},{"group":"Domains","pages":[{"title":"List domains","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/domains","href":"/api-reference/public-v1/domains/list-domains"},{"title":"Add a domain","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/domains","href":"/api-reference/public-v1/domains/add-a-domain"},{"title":"Get a domain","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/domains/{domainId}","href":"/api-reference/public-v1/domains/get-a-domain"},{"title":"Delete a domain","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/domains/{domainId}","href":"/api-reference/public-v1/domains/delete-a-domain"},{"title":"Update domain settings","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/domains/{domainId}","href":"/api-reference/public-v1/domains/update-domain-settings"},{"title":"Verify a domain","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/domains/{domainId}/verify","href":"/api-reference/public-v1/domains/verify-a-domain"},{"title":"List a domain's unsubscribes","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/domains/{domainId}/unsubscribes","href":"/api-reference/public-v1/domains/list-a-domains-unsubscribes"},{"title":"Add addresses to a domain's unsubscribe list","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/domains/{domainId}/unsubscribes","href":"/api-reference/public-v1/domains/add-addresses-to-a-domains-unsubscribe-list"},{"title":"Remove an address from a domain's unsubscribe list","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/domains/{domainId}/unsubscribes/{email}","href":"/api-reference/public-v1/domains/remove-an-address-from-a-domains-unsubscribe-list"},{"title":"Import a CSV into a domain's unsubscribe list","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/domains/{domainId}/unsubscribes/import","href":"/api-reference/public-v1/domains/import-a-csv-into-a-domains-unsubscribe-list"},{"title":"Export a domain's unsubscribe list","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/domains/{domainId}/unsubscribes/export","href":"/api-reference/public-v1/domains/export-a-domains-unsubscribe-list"},{"title":"Get domain health","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/domains/{domainId}/health","href":"/api-reference/public-v1/domains/get-domain-health"}]},{"group":"Templates","pages":[{"title":"List templates","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/templates","href":"/api-reference/public-v1/templates/list-templates"},{"title":"Get a public template","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/templates/{templateId}","href":"/api-reference/public-v1/templates/get-a-public-template"},{"title":"List flows","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/flows","href":"/api-reference/public-v1/templates/list-flows"},{"title":"Get a flow","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/flows/{slug}","href":"/api-reference/public-v1/templates/get-a-flow"}]},{"group":"Brand","pages":[{"title":"Get the brand bound to this API key","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/brand","href":"/api-reference/public-v1/brand/get-the-brand-bound-to-this-api-key"},{"title":"Update brand identity + design system","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml patch /v1/brand","href":"/api-reference/public-v1/brand/update-brand-identity-+-design-system"},{"title":"Get brand images","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/brand/images","href":"/api-reference/public-v1/brand/get-brand-images"},{"title":"Delete a brand image","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/brand/images/{assetId}","href":"/api-reference/public-v1/brand/delete-a-brand-image"}]},{"group":"Brands","pages":[{"title":"List the brands this credential can reach","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/brands","href":"/api-reference/public-v1/brands/list-the-brands-this-credential-can-reach"},{"title":"Create a brand and start its extraction","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/brands","href":"/api-reference/public-v1/brands/create-a-brand-and-start-its-extraction"},{"title":"Get one brand’s lifecycle state","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/brands/{brandId}","href":"/api-reference/public-v1/brands/get-one-brand’s-lifecycle-state"}]},{"group":"Content","pages":[{"title":"Generate an image","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/content/generate-image","href":"/api-reference/public-v1/content/generate-an-image"},{"title":"Generate a GIF","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/content/gif","href":"/api-reference/public-v1/content/generate-a-gif"},{"title":"Transform an image","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/content/transform","href":"/api-reference/public-v1/content/transform-an-image"},{"title":"Render HTML to a PNG","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/content/html-to-png","href":"/api-reference/public-v1/content/render-html-to-a-png"},{"title":"Add image","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/content/add-image","href":"/api-reference/public-v1/content/add-image"},{"title":"Create an image upload","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/content/image-uploads","href":"/api-reference/public-v1/content/create-an-image-upload"}]},{"group":"Usage","pages":[{"title":"Get usage","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/usage","href":"/api-reference/public-v1/usage/get-usage"}]},{"group":"Integrations","pages":[{"title":"List integrations","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/integrations","href":"/api-reference/public-v1/integrations/list-integrations"}]},{"group":"API Keys","pages":[{"title":"List API keys","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/api-keys","href":"/api-reference/public-v1/api-keys/list-api-keys"},{"title":"Create an API key","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml post /v1/api-keys","href":"/api-reference/public-v1/api-keys/create-an-api-key"},{"title":"Revoke an API key","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml delete /v1/api-keys/{keyId}","href":"/api-reference/public-v1/api-keys/revoke-an-api-key"}]},{"group":"Health","pages":[{"title":"Liveness probe","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/health","href":"/api-reference/public-v1/health/liveness-probe"}]},{"group":"Meta","pages":[{"title":"Machine-readable API catalog","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/help","href":"/api-reference/public-v1/meta/machine-readable-api-catalog"}]},{"group":"Chats","pages":[{"title":"List chats","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/chats","href":"/api-reference/public-v1/chats/list-chats"},{"title":"Get chat context","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/chats/{chatId}","href":"/api-reference/public-v1/chats/get-chat-context"}]},{"group":"Insights","pages":[{"title":"List insights","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/insights","href":"/api-reference/public-v1/insights/list-insights"},{"title":"Get an insight","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/insights/{insightId}","href":"/api-reference/public-v1/insights/get-an-insight"}]},{"group":"Notifications","pages":[{"title":"List notifications","deprecated":null,"version":null,"openapi":"/api-reference/openapi-public-v1.yaml get /v1/notifications","href":"/api-reference/public-v1/notifications/list-notifications"}]}]},{"group":"API Contracts","pages":[{"title":"Authentication and Security","href":"/api-reference/api/authentication"},{"title":"Organization and Brand Credentials","href":"/api-reference/api/organization-and-brand-scope"},{"title":"Data Model","href":"/api-reference/api/data-model"},{"title":"Rate Limits","href":"/api-reference/api/rate-limits"},{"title":"Idempotency","href":"/api-reference/api/idempotency"},{"title":"Pagination","href":"/api-reference/api/pagination"},{"title":"Batch Operations","href":"/api-reference/api/batch-operations"},{"title":"Async Jobs and Polling","href":"/api-reference/api/async-jobs"},{"title":"API Credits","sidebarTitle":"Credits","href":"/api-reference/api/credits"},{"title":"Events and Webhooks","href":"/api-reference/api/events-and-webhooks"},{"title":"API Errors","sidebarTitle":"Errors","href":"/api-reference/api/errors"},{"title":"Response Headers","href":"/api-reference/api/response-headers"},{"title":"API Design Notes","href":"/api-reference/api/design-notes"},{"title":"Migrate to the New v1 Surface","href":"/api-reference/api/v1-migration"}]},{"group":"API Guides","pages":[{"title":"Check Brand Readiness Before Generating","href":"/api-reference/guides/check-brand-readiness"},{"title":"Upload a Local Image","href":"/api-reference/guides/upload-a-local-image"},{"title":"Monitor Email Sends","href":"/api-reference/guides/monitor-campaign-sends"},{"title":"Explore Per-Contact Engagement","href":"/api-reference/guides/per-contact-engagement"},{"title":"Read Brew Insights","href":"/api-reference/guides/read-brew-insights"},{"title":"Typed Payload Contracts","href":"/api-reference/guides/typed-payload-contracts"}]},{"group":"MCP Server","pages":[{"title":"Brew MCP Server","href":"/api-reference/mcp/overview"},{"title":"MCP Quickstart","href":"/api-reference/mcp/quickstart"},{"title":"Connect Your MCP Client","sidebarTitle":"Connect Your Client","href":"/api-reference/mcp/connect-your-client"},{"title":"MCP Tools","href":"/api-reference/mcp/tools"},{"title":"MCP Workflows","href":"/api-reference/mcp/workflows"},{"title":"Sync a CRM into Brew over MCP","href":"/api-reference/mcp/sync-a-crm"},{"title":"Sync Brew and Attio over MCP","href":"/api-reference/mcp/attio"},{"title":"MCP Authentication and Scoping","href":"/api-reference/mcp/authentication-and-scoping"}]},{"group":"CLI","pages":[{"title":"Brew CLI","href":"/api-reference/cli/overview"},{"title":"CLI Quickstart","href":"/api-reference/cli/quickstart"},{"title":"CLI Installation","sidebarTitle":"Installation","href":"/api-reference/cli/installation"},{"title":"CLI Authentication","sidebarTitle":"Authentication","href":"/api-reference/cli/authentication"},{"title":"CLI Commands","sidebarTitle":"Commands","href":"/api-reference/cli/commands"},{"title":"CLI Common Flows","sidebarTitle":"Common Flows","href":"/api-reference/cli/common-flows"},{"title":"Use the CLI from AI Agents","sidebarTitle":"Use from AI Agents","href":"/api-reference/cli/agents"}]},{"group":"SDKs","pages":[{"title":"SDK Overview","href":"/sdks/overview"},{"title":"SDK Authentication","sidebarTitle":"Authentication","href":"/sdks/authentication"},{"title":"Generate Your Own SDK","href":"/sdks/openapi-codegen"},{"title":"TypeScript Installation","href":"/sdks/typescript/installation"},{"title":"TypeScript Quickstart","href":"/sdks/typescript/quickstart"},{"title":"TypeScript Resource Surface","href":"/sdks/typescript/resources"},{"title":"Build a White-Label Email Editor","sidebarTitle":"White-Label Integration","href":"/sdks/typescript/white-label-email-editor"},{"title":"Embed the Email Canvas","href":"/sdks/typescript/embedded-email-canvas"},{"title":"TypeScript Error Handling","href":"/sdks/typescript/error-handling"},{"title":"Agentic Cookbook","href":"/sdks/typescript/agentic-cookbook"}]}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/changelog/overview"}]},{"tab":"Legal","pages":[{"title":"Legal","href":"/legal/terms-of-service"}]}]},"basePath":"","title":"Create or update contacts - Brew Help Docs","buildId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","deploymentId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-CBsVopKK.js","utils-DZAk68jJ.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-D32AYZrP.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-D_A5_cny.js","snippetPresets-xNRfS9th.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BIB25-tq.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-CydJ4w4j.js","shallow-CYPBeQSG.js","getApiPlaygroundDisplay-A5xJVBOu.js","CodeSnippet-BVRTgi3m.js","CodeSnippets-DjD6BSlt.js","Page-Dr40SSJq.js","getPastedJson-D4V4JyrR.js","icon-uhcnG22T.js","MethodPill-CM-ZQdGH.js","DuplicateIcon-B_WnOiNf.js","createIcon-CJsb8utt.js","DynamicMarkdown-D-2HDKEp.js","SectionHeading-KP5xmMgQ.js","axios-vUo_bRtp.js","Markdown-D_k0dg6k.js","clsx-DK3K4Z1S.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-DE3EVdvd.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-fN9H9n9g.js"]}