{"openapi":"3.1.0","info":{"title":"Zeebra API","version":"1.0.0","description":"Contacts, lists, segments, templates and campaigns of one Zeebra workspace. Authenticate with an API key from Settings → API: `Authorization: Bearer <key>`. Full access keys can do everything; signups keys can only call add_signup, so they are safe in website code. Up to 300 requests a minute per key. Errors answer `{\"error\": {\"code\", \"message\"}}`."},"servers":[{"url":"https://zeebra.ai/api/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"Workspace"},{"name":"Contacts"},{"name":"Accounts"},{"name":"Duplicates"},{"name":"Business groups"},{"name":"Tags"},{"name":"Properties"},{"name":"Topics"},{"name":"Suppressions"},{"name":"Lists"},{"name":"Segments"},{"name":"Templates"},{"name":"Campaigns"},{"name":"Sending"},{"name":"Signups"},{"name":"Public pages"},{"name":"Webhooks"}],"paths":{"/overview":{"get":{"operationId":"get_overview","summary":"Get the overview","description":"The workspace at a glance: contacts by lead type and status, lists, segments, campaigns by status, email results of the last 30 days, and whether it can send. A good first call.","tags":["Workspace"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts":{"get":{"operationId":"list_contacts","summary":"List contacts","description":"Lists the workspace's contacts, newest first, a page at a time. Filter on any filterable property, custom ones included (filter, or a rule tree in where, like segments), and sort on any sortable property (prefix with - for descending).","tags":["Contacts"],"parameters":[{"name":"filter","in":"query","description":"Property key => value. Keys: q (search: every word in a name, email, company or searchable property), email, tag (name), list_id, account_id (their company, see list_accounts), segment_id, created_after (date), or any filterable property key (get_segment_fields lists them; custom ones are field:<key>). A value is \"operator:value\" with the property's operators (contains:acme, gte:10, between:1,5, in_period:last_30_days, within_last:7, is_set:), or just a value: is for text, in for choices (comma separated), eq for numbers, has_any for multiple choice, true or false for yes-or-no.","schema":{"type":"object","description":"Property key => value. Keys: q (search: every word in a name, email, company or searchable property), email, tag (name), list_id, account_id (their company, see list_accounts), segment_id, created_after (date), or any filterable property key (get_segment_fields lists them; custom ones are field:<key>). A value is \"operator:value\" with the property's operators (contains:acme, gte:10, between:1,5, in_period:last_30_days, within_last:7, is_set:), or just a value: is for text, in for choices (comma separated), eq for numbers, has_any for multiple choice, true or false for yes-or-no.","additionalProperties":true,"examples":[{"status":"active","lead_type":"opted_in","field:plan":"is:Pro","created_at":"in_period:this_month"}]},"style":"deepObject","explode":true},{"name":"where","in":"query","description":"A rule tree like a segment's, for AND/OR: {\"match\": \"all\"|\"any\", \"rules\": [{\"field\": \"city\", \"op\": \"is\", \"value\": \"London\"}, {\"match\": \"any\", \"rules\": [...]}]}. Applied with filter.","schema":{"type":"object","description":"A rule tree like a segment's, for AND/OR: {\"match\": \"all\"|\"any\", \"rules\": [{\"field\": \"city\", \"op\": \"is\", \"value\": \"London\"}, {\"match\": \"any\", \"rules\": [...]}]}. Applied with filter.","additionalProperties":true,"examples":[{"match":"any","rules":[{"field":"city","op":"is","value":"London"},{"field":"field:plan","op":"in","value":["pro"]}]}]},"style":"deepObject","explode":true},{"name":"sort","in":"query","description":"Up to 3 sortable property keys, comma separated, - for descending: -created_at (the default), email, field:plan,-last_engaged_at.","schema":{"type":"string","description":"Up to 3 sortable property keys, comma separated, - for descending: -created_at (the default), email, field:plan,-last_engaged_at.","maxLength":200}},{"name":"page","in":"query","description":"Page number, from 1.","schema":{"type":"integer","description":"Page number, from 1.","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Items per page, up to 100.","schema":{"type":"integer","description":"Items per page, up to 100.","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"last_page":{"type":"integer"}}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"add_contact","summary":"Add a contact","description":"Adds one contact. Opted-in contacts get campaigns and need a consent note saying how they agreed; prospects never get campaigns. Refuses an address that already exists or is on a do-not-email list. Use add_signup for people signing up on a website.","tags":["Contacts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","maxLength":254,"examples":["sara@example.com"]},"first_name":{"type":"string","maxLength":120,"examples":["Sara"]},"last_name":{"type":"string","maxLength":120},"title":{"type":"string","maxLength":200},"company":{"type":"string","description":"Their company's name: they join the account of that name, made if there is none. Left out, a work email's domain finds or makes it.","maxLength":200},"account_id":{"type":"integer","description":"Their company: an account of the workspace (list_accounts). Wins over company.","minimum":1},"phone":{"type":"string","maxLength":50},"city":{"type":"string","maxLength":120},"lead_type":{"type":"string","description":"opted_in: agreed to get your emails. prospect: not yet (the default).","enum":["opted_in","prospect"],"default":"prospect","examples":["opted_in"]},"consent_note":{"type":"string","description":"Required for opted_in: how they agreed, e.g. \"Signed up at our booth, 3 May\".","maxLength":250,"examples":["Signed up at our booth"]},"fields":{"type":"object","description":"Custom property values by key (see list_properties), checked against each property's type and rules. Required properties need a value.","additionalProperties":true,"examples":[{"ticket_type":"VIP"}]},"tags":{"type":"array","description":"Tag names; new ones are created.","maxItems":20,"items":{"type":"string"}},"list_ids":{"type":"array","description":"Lists to add the contact to.","maxItems":20,"items":{"type":"integer"}}},"required":["email"],"additionalProperties":false},"example":{"email":"sara@example.com","first_name":"Sara","lead_type":"opted_in","consent_note":"Signed up at our booth","fields":{"ticket_type":"VIP"}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/contacts/{id}":{"get":{"operationId":"get_contact","summary":"Get a contact","description":"Gets one contact with its tags, custom property values, country, consent record, the ids of the lists it is on, and its history: every status change with who made it and how (the newest 100), opt-ins with their consent, and list cleanup's emails. list_contact_emails has the emails it got.","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The contact's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"patch":{"operationId":"update_contact","summary":"Update a contact","description":"Changes a contact's name, company (account_id, or a company name) and other properties. Only what you send changes; in fields, a null value clears that custom property. The email address, lead type and status have their own rules and can't be changed here. A contact shared with the business group changes in every workspace of it; in a workspace with view access its shared fields (names, company, job title, phone, city) are refused.","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The contact's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"first_name":{"type":["string","null"],"maxLength":120},"last_name":{"type":["string","null"],"maxLength":120},"title":{"type":["string","null"],"maxLength":200},"company":{"type":["string","null"],"description":"Their company's name: they join the account of that name (made if there is none); null takes them out of theirs.","maxLength":200},"account_id":{"type":["integer","null"],"description":"Their company: an account of the workspace (list_accounts), or null for none. Wins over company."},"phone":{"type":["string","null"],"maxLength":50},"city":{"type":["string","null"],"maxLength":120},"fields":{"type":"object","description":"Custom property values by key; null clears one.","additionalProperties":true,"examples":[{"ticket_type":"VIP"}]}},"additionalProperties":false},"example":{"fields":{"ticket_type":"VIP"}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_contact","summary":"Delete a contact","description":"Deletes a contact and its history. If they had unsubscribed, bounced or complained, the address stays on the do-not-email list.","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The contact's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/contacts/{id}/emails":{"get":{"operationId":"list_contact_emails","summary":"List a contact's emails","description":"Lists the campaign emails a contact got, newest first, a page at a time: each with its campaign, when it was sent and delivered or bounced, their first real open and click (machine opens never count), the links they clicked, and whether they unsubscribed or marked it as spam from it.","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The contact's id.","minimum":1}},{"name":"page","in":"query","description":"Page number, from 1.","schema":{"type":"integer","description":"Page number, from 1.","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Items per page, up to 100.","schema":{"type":"integer","description":"Items per page, up to 100.","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ContactEmail"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"last_page":{"type":"integer"}}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts/{id}/status":{"post":{"operationId":"change_contact_status","summary":"Change a contact's status","description":"Sets a contact's status. Unsubscribed, bounced and complained are final: the address goes on the do-not-email list and only the person can come back by signing up again.","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The contact's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["active","pending","dormant","unsubscribed","bounced","complained"],"examples":["unsubscribed"]},"note":{"type":"string","description":"Why, kept in the contact's history.","maxLength":250}},"required":["status"],"additionalProperties":false},"example":{"status":"unsubscribed"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts/tag":{"post":{"operationId":"tag_contacts","summary":"Tag contacts","description":"Adds a tag to up to 1,000 contacts. The tag is created if it doesn't exist (names match without case).","tags":["Contacts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contact_ids":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"integer"},"examples":[[12,13]]},"tag":{"type":"string","maxLength":50,"examples":["VIP"]}},"required":["contact_ids","tag"],"additionalProperties":false},"example":{"contact_ids":[12,13],"tag":"VIP"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts/untag":{"post":{"operationId":"untag_contacts","summary":"Untag contacts","description":"Takes a tag off up to 1,000 contacts. The tag itself stays (delete_tag removes it everywhere).","tags":["Contacts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contact_ids":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"integer"},"examples":[[12,13]]},"tag":{"type":"string","maxLength":50,"examples":["VIP"]}},"required":["contact_ids","tag"],"additionalProperties":false},"example":{"contact_ids":[12,13],"tag":"VIP"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts/imports":{"post":{"operationId":"import_contacts","summary":"Import contacts from CSV","description":"Imports a CSV (with a header row) in the background, cleaning addresses like the import page: typos flagged, role, throwaway and undeliverable addresses skipped, suppressed ones never added. Columns are matched by their headers unless you give a mapping. Existing contacts are updated, and their status only gets stricter. Check progress with get_import.","tags":["Contacts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"csv":{"type":"string","description":"The file's text, up to 10 MB.","maxLength":10000000,"examples":["email,first_name\nsara@example.com,Sara"]},"mapping":{"type":"object","description":"Header => email, first_name, last_name, name, title, company, company_domain, company_industry, company_city, phone, city, country, status, unsubscribed, tags, field:<custom property key>, or null to skip. Left out: guessed from the headers.","additionalProperties":true},"lead_type":{"type":"string","enum":["opted_in","prospect"],"examples":["prospect"]},"consent_confirmed":{"type":"boolean","description":"Required true for opted_in: you confirm these people agreed to get your emails."},"consent_note":{"type":"string","description":"How they agreed (kept on each contact).","maxLength":250},"list_id":{"type":"integer","description":"Add everyone imported to this list.","minimum":1},"tag_ids":{"type":"array","description":"Tag everyone imported.","maxItems":20,"items":{"type":"integer"}},"keep_role_addresses":{"type":"boolean","description":"Keep info@, sales@… addresses (skipped by default)."},"file_name":{"type":"string","description":"A name for the import, shown on the import page.","maxLength":200}},"required":["csv","lead_type"],"additionalProperties":false},"example":{"csv":"email,first_name\nsara@example.com,Sara","lead_type":"prospect"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Import"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/contacts/imports/{id}":{"get":{"operationId":"get_import","summary":"Get an import","description":"Shows an import's progress and report: created, updated, skipped and flagged counts by reason.","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The import's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Import"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts/export":{"get":{"operationId":"export_contacts","summary":"Export contacts as CSV","description":"Returns the contacts matching the filters (as in list_contacts) as CSV text that import_contacts reads back, up to 50,000 rows. Emails and phones found through Zeebra are left out where their licence forbids export.","tags":["Contacts"],"parameters":[{"name":"filter","in":"query","description":"The same filters as list_contacts.","schema":{"type":"object","description":"The same filters as list_contacts.","additionalProperties":true},"style":"deepObject","explode":true},{"name":"where","in":"query","description":"The same rule tree as list_contacts.","schema":{"type":"object","description":"The same rule tree as list_contacts.","additionalProperties":true},"style":"deepObject","explode":true}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/accounts":{"get":{"operationId":"list_accounts","summary":"List accounts","description":"Lists the workspace's companies (accounts), by name, a page at a time, each with how many contacts it has. Filter on any filterable account property, custom ones included, like list_contacts (filter, or a rule tree in where), and sort on any sortable one. list_contacts with filter account_id lists an account's contacts.","tags":["Accounts"],"parameters":[{"name":"q","in":"query","description":"Search: every word in the name, domain or a searchable property.","schema":{"type":"string","description":"Search: every word in the name, domain or a searchable property.","maxLength":200}},{"name":"filter","in":"query","description":"Property key => value, as in list_contacts: name, domain, industry, city, country, owner_id, employees, contacts_count, created_at, field:<key>… A value is \"operator:value\" (contains:tech, gte:10, is_set:) or just a value.","schema":{"type":"object","description":"Property key => value, as in list_contacts: name, domain, industry, city, country, owner_id, employees, contacts_count, created_at, field:<key>… A value is \"operator:value\" (contains:tech, gte:10, is_set:) or just a value.","additionalProperties":true,"examples":[{"city":"London","contacts_count":"gt:0"}]},"style":"deepObject","explode":true},{"name":"where","in":"query","description":"A rule tree like a segment's, for AND/OR, on account properties.","schema":{"type":"object","description":"A rule tree like a segment's, for AND/OR, on account properties.","additionalProperties":true},"style":"deepObject","explode":true},{"name":"sort","in":"query","description":"Up to 3 sortable property keys, comma separated, - for descending: name (the default), -contacts_count, -created_at.","schema":{"type":"string","description":"Up to 3 sortable property keys, comma separated, - for descending: name (the default), -contacts_count, -created_at.","maxLength":200}},{"name":"page","in":"query","description":"Page number, from 1.","schema":{"type":"integer","description":"Page number, from 1.","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Items per page, up to 100.","schema":{"type":"integer","description":"Items per page, up to 100.","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Account"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"last_page":{"type":"integer"}}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"add_account","summary":"Add an account","description":"Adds a company to the workspace. Its domain is cleaned (https://www.acme.com/about becomes acme.com), must be the company's own (not gmail.com or a social profile) and one account's only; a website fills in a missing domain. Contacts added later with a work email at the domain join it.","tags":["Accounts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":200,"examples":["Northwind Events"]},"domain":{"type":"string","maxLength":255,"examples":["riyadhevents.sa"]},"website":{"type":"string","maxLength":500},"industry":{"type":"string","maxLength":120},"city":{"type":"string","maxLength":120},"country":{"type":"string","description":"A country code (SA) or name.","maxLength":60},"phone":{"type":"string","description":"Without a \"+\", read as a number of the workspace's default country.","maxLength":50},"employees":{"type":"integer","minimum":0},"description":{"type":"string","maxLength":5000},"owner_id":{"type":"integer","description":"A team member's user id. Defaults to the API key's member, when it has one."},"fields":{"type":"object","description":"Custom property values by key (list_properties with entity account). Required properties need a value.","additionalProperties":true}},"required":["name"],"additionalProperties":false},"example":{"name":"Northwind Events","domain":"riyadhevents.sa"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/accounts/{id}":{"get":{"operationId":"get_account","summary":"Get an account","description":"Gets one of the workspace's companies with its custom property values and how many contacts it has.","tags":["Accounts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The account's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"patch":{"operationId":"update_account","summary":"Update an account","description":"Changes a company's properties. Only what you send changes; null clears a property (not the name). Renaming it renames it on its contacts (their company).","tags":["Accounts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The account's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":200},"domain":{"type":["string","null"],"maxLength":255,"examples":["riyadhevents.sa"]},"website":{"type":["string","null"],"maxLength":500},"industry":{"type":["string","null"],"maxLength":120},"city":{"type":["string","null"],"maxLength":120},"country":{"type":["string","null"],"description":"A country code (SA) or name.","maxLength":60},"phone":{"type":["string","null"],"description":"Without a \"+\", read as a number of the workspace's default country.","maxLength":50},"employees":{"type":["integer","null"],"minimum":0},"description":{"type":["string","null"],"maxLength":5000},"owner_id":{"type":["integer","null"],"description":"A team member's user id."},"fields":{"type":"object","description":"Custom property values by key (list_properties with entity account); null clears one.","additionalProperties":true}},"additionalProperties":false},"example":{"domain":"riyadhevents.sa"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_account","summary":"Delete an account","description":"Deletes a company. Its contacts are kept, without a company link (their company name stays).","tags":["Accounts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The account's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/duplicates":{"get":{"operationId":"list_duplicates","summary":"List duplicate suggestions","description":"Lists pairs of contacts or accounts that look like the same one, newest first, with both records' values and why they matched (email, phone, domain, name, rule:<id>, manual). Pairs come from scans: scan_duplicates runs one, and a workspace that scanned is scanned again daily.","tags":["Duplicates"],"parameters":[{"name":"type","in":"query","description":"contact or account.","schema":{"type":"string","description":"contact or account.","enum":["contact","account"],"default":"contact"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","rejected","merged"],"default":"pending"}},{"name":"page","in":"query","description":"Page number, from 1.","schema":{"type":"integer","description":"Page number, from 1.","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Items per page, up to 100.","schema":{"type":"integer","description":"Items per page, up to 100.","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/duplicates/scan":{"post":{"operationId":"scan_duplicates","summary":"Scan for duplicates","description":"Starts a scan of the workspace's contacts or accounts for duplicates in the background; list_duplicates shows what it finds.","tags":["Duplicates"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"contact or account.","enum":["contact","account"],"default":"contact"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/duplicates/{id}/reject":{"post":{"operationId":"reject_duplicate","summary":"Reject a duplicate suggestion","description":"Marks a suggested pair as not duplicates: it leaves the list and scans don't suggest it again.","tags":["Duplicates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The suggestion's id (list_duplicates).","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts/{id}/merge":{"post":{"operationId":"merge_contacts","summary":"Merge two contacts","description":"Merges a duplicate contact (id) into another (into_id, the one kept) and deletes the duplicate. The kept contact keeps its values, and takes the duplicate's where it has none or where you name the property in take. Lists, tags, topics, campaign emails and history move to it. The strictest status wins (unsubscribed, bounced or complained is never undone), and an opted-in contact's consent is kept. unmerge_duplicates undoes it.","tags":["Duplicates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The duplicate: merged into the other, then deleted.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"into_id":{"type":"integer","description":"The record kept.","minimum":1},"take":{"type":"array","description":"Property keys whose value comes from the duplicate even where the kept record has one (\"phone\", \"field:plan\").","items":{"type":"string"}}},"required":["into_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":false,"openWorld":false}}},"/accounts/{id}/merge":{"post":{"operationId":"merge_accounts","summary":"Merge two accounts","description":"Merges a duplicate company (id) into another (into_id, the one kept) and deletes the duplicate. The kept account keeps its values, and takes the duplicate's where it has none or where you name the property in take. Its contacts move to the kept account, and segments filtering on the duplicate's id use the kept one. Shared with a business group: the kept account keeps its shared link, or takes the duplicate's. unmerge_duplicates undoes it.","tags":["Duplicates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The duplicate: merged into the other, then deleted.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"into_id":{"type":"integer","description":"The record kept.","minimum":1},"take":{"type":"array","description":"Property keys whose value comes from the duplicate even where the kept record has one (\"phone\", \"field:plan\").","items":{"type":"string"}}},"required":["into_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":false,"openWorld":false}}},"/duplicates/merges/{id}/unmerge":{"post":{"operationId":"unmerge_duplicates","summary":"Undo a merge","description":"Undoes a merge (its merge_id from merge_contacts or merge_accounts): the merged record comes back and everything that moved goes back. Refused, with the reason, when something the merge changed was changed again since.","tags":["Duplicates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The merge's merge_id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/business-group":{"get":{"operationId":"get_business_group","summary":"Get the business group","description":"Gets the business group the workspace is in (business_group, null when it isn't in one): its name, this workspace's access (edit: changes to shared records reach every workspace; view: their common fields can't be changed here), whether new contacts and companies are shared at once, the names of its workspaces, and how many contacts and companies it shares.","tags":["Business groups"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/contacts/{id}/share":{"post":{"operationId":"share_contact","summary":"Share a contact","description":"Shares a contact (and its company) with every workspace of the business group. A workspace that has a contact with the same email gets it linked, not copied; the others get a copy. The copies keep one profile (name, email, phone, job title, company, city, country) and one consent: opted in anywhere is opted in everywhere, and unsubscribing, bouncing or complaining anywhere applies everywhere. Tags, lists, notes and custom properties stay each workspace's own.","tags":["Business groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The contact's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"unshare_contact","summary":"Stop sharing a contact","description":"Stops sharing this workspace's copy of a contact: it stays here as a plain contact, and the other workspaces keep theirs. Nothing is deleted.","tags":["Business groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The contact's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contact"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/accounts/{id}/share":{"post":{"operationId":"share_account","summary":"Share an account","description":"Shares a company (account) with every workspace of the business group. A workspace with a company of the same domain (else the same name) gets it linked; the others get a copy. The copies keep one name, domain, website, industry, size, phone and location; owner, notes and custom properties stay each workspace's own.","tags":["Business groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The account's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"unshare_account","summary":"Stop sharing an account","description":"Stops sharing this workspace's copy of a company: it stays here as a plain company. Nothing is deleted.","tags":["Business groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The account's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Account"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/tags":{"get":{"operationId":"list_tags","summary":"List tags","description":"Lists the workspace's tags with how many contacts have each.","tags":["Tags"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_tag","summary":"Create a tag","description":"Creates a tag. tag_contacts also creates tags as it goes.","tags":["Tags"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":50,"examples":["VIP"]},"color":{"type":"string","description":"Defaults to one picked from the name.","enum":["zinc","red","amber","green","blue","violet","pink"]}},"required":["name"],"additionalProperties":false},"example":{"name":"VIP"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tag"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/tags/{id}":{"patch":{"operationId":"update_tag","summary":"Rename or recolour a tag","description":"Changes a tag's name or colour.","tags":["Tags"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The tag's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":50},"color":{"type":"string","enum":["zinc","red","amber","green","blue","violet","pink"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tag"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_tag","summary":"Delete a tag","description":"Deletes a tag and takes it off every contact. The contacts stay.","tags":["Tags"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The tag's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/properties":{"get":{"operationId":"list_properties","summary":"List properties","description":"Lists everything a contact (or an account, one of your companies) has, in order: system properties (email, first_name, status, tags…) and the workspace's custom ones, keyed \"field:<key>\". A custom property's <key> is what contacts' fields use, and {{custom.<key>}} puts its value in an email. Each says its type, rules, options and segment operators.","tags":["Properties"],"parameters":[{"name":"entity","in":"query","description":"contact (the default) or account: your companies (the Companies page; see list_accounts).","schema":{"type":"string","description":"contact (the default) or account: your companies (the Companies page; see list_accounts).","enum":["contact","account"],"default":"contact"}},{"name":"include_archived","in":"query","description":"Also list archived custom properties.","schema":{"type":"boolean","description":"Also list archived custom properties.","default":false}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Property"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_property","summary":"Create a property","description":"Adds a custom property. Its key is made from the label (\"Ticket type\" becomes ticket_type) unless you give one, and never changes. Select and multi_select properties need their options.","tags":["Properties"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entity":{"type":"string","description":"contact (the default) or account: your companies (the Companies page; see list_accounts).","enum":["contact","account"],"default":"contact"},"label":{"type":"string","maxLength":60,"examples":["Ticket type"]},"type":{"type":"string","enum":["text","long_text","number","currency","date","select","multi_select","boolean","email","phone","url","country","user"],"examples":["select"]},"key":{"type":"string","description":"Lowercase letters, digits and underscores. Defaults to one made from the label.","maxLength":40},"description":{"type":"string","maxLength":250},"options":{"type":"array","description":"Choices of a select or multi_select property: {label, color?}, and the value when changing an existing option (values never change, labels can).","maxItems":200,"items":{"type":"object","additionalProperties":true},"examples":[[{"label":"VIP","color":"amber"},{"label":"Standard"}]]},"settings":{"type":"object","description":"Validation by type. text: min_length, max_length, regex. long_text: min_length, max_length. number: min, max, decimals. currency: currency (like EUR; default the billing currency), min, max, decimals. date: date_rule (any, past, future, range), date_from, date_to. multi_select: min_selections, max_selections.","additionalProperties":true,"examples":[{"max_length":40}]},"group":{"type":["string","null"],"description":"A group key from list_properties (contact_info, work, other…). Left out on create: \"other\".","maxLength":40},"required":{"type":"boolean","description":"Contacts can't be added or saved without it (imports and signups skip it)."},"searchable":{"type":"boolean","description":"Text types only: the contacts search matches it."}},"required":["label","type"],"additionalProperties":false},"example":{"label":"Ticket type","type":"select","options":[{"label":"VIP","color":"amber"},{"label":"Standard"}],"settings":{"max_length":40}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Property"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/properties/{id}":{"patch":{"operationId":"update_property","summary":"Update a property","description":"Changes a custom property's label, description, options, rules, group or flags. Its key and type stay, so stored values, segments and merge tags keep working. System properties: use update_system_property.","tags":["Properties"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The custom property's id (from list_properties).","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","maxLength":60},"description":{"type":["string","null"],"maxLength":250},"options":{"type":"array","description":"Choices of a select or multi_select property: {label, color?}, and the value when changing an existing option (values never change, labels can).","maxItems":200,"items":{"type":"object","additionalProperties":true},"examples":[[{"label":"VIP","color":"amber"},{"label":"Standard"}]]},"settings":{"type":"object","description":"Validation by type. text: min_length, max_length, regex. long_text: min_length, max_length. number: min, max, decimals. currency: currency (like EUR; default the billing currency), min, max, decimals. date: date_rule (any, past, future, range), date_from, date_to. multi_select: min_selections, max_selections.","additionalProperties":true,"examples":[{"max_length":40}]},"group":{"type":["string","null"],"description":"A group key from list_properties (contact_info, work, other…). Left out on create: \"other\".","maxLength":40},"required":{"type":"boolean"},"searchable":{"type":"boolean"}},"additionalProperties":false},"example":{"options":[{"label":"VIP","color":"amber"},{"label":"Standard"}],"settings":{"max_length":40}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Property"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/properties/{id}/archive":{"post":{"operationId":"archive_property","summary":"Archive a property","description":"Hides a custom property everywhere. Its values stay on records and come back with restore_property; segments using it keep working.","tags":["Properties"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The custom property's id (from list_properties).","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Property"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/properties/{id}/restore":{"post":{"operationId":"restore_property","summary":"Restore a property","description":"Brings an archived custom property back, with its values.","tags":["Properties"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The custom property's id (from list_properties).","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Property"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/properties/system/{key}":{"patch":{"operationId":"update_system_property","summary":"Change a system property","description":"Changes how a system property (first_name, company, city…) shows in this workspace: its label (null: the default), description, group, whether it is required and whether record pages hide it. Never its type.","tags":["Properties"],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","description":"The system property's key, like company.","maxLength":40}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"entity":{"type":"string","description":"contact (the default) or account: your companies (the Companies page; see list_accounts).","enum":["contact","account"],"default":"contact"},"label":{"type":["string","null"],"maxLength":60},"description":{"type":["string","null"],"maxLength":250},"group":{"type":["string","null"],"description":"A group key from list_properties (contact_info, work, other…). Left out on create: \"other\".","maxLength":40},"required":{"type":"boolean"},"hidden":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Property"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/topics":{"get":{"operationId":"list_topics","summary":"List topics","description":"Lists the kinds of email people can unsubscribe from on their own (newsletter, event invites…).","tags":["Topics"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Topic"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_topic","summary":"Create a topic","description":"Adds a topic. Contacts are in it unless they leave, or only once they join when default_subscribed is false.","tags":["Topics"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":60,"examples":["Event invites"]},"description":{"type":"string","maxLength":200},"default_subscribed":{"type":"boolean","default":true}},"required":["name"],"additionalProperties":false},"example":{"name":"Event invites"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Topic"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/topics/{id}":{"patch":{"operationId":"update_topic","summary":"Update a topic","description":"Changes a topic's name, description or default.","tags":["Topics"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The topic's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":60},"description":{"type":["string","null"],"maxLength":200},"default_subscribed":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Topic"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_topic","summary":"Delete a topic","description":"Deletes a topic and people's choices for it. Templates and campaigns that used it go to everyone again.","tags":["Topics"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The topic's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/suppressions":{"get":{"operationId":"list_suppressions","summary":"List suppressions","description":"Lists the workspace's do-not-email list, newest first: unsubscribes, bounces, complaints and addresses added by hand.","tags":["Suppressions"],"parameters":[{"name":"q","in":"query","description":"Part of an address.","schema":{"type":"string","description":"Part of an address.","maxLength":254}},{"name":"reason","in":"query","schema":{"type":"string","enum":["bounce","complaint","unsubscribe","manual"]}},{"name":"page","in":"query","description":"Page number, from 1.","schema":{"type":"integer","description":"Page number, from 1.","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Items per page, up to 100.","schema":{"type":"integer","description":"Items per page, up to 100.","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Suppression"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"last_page":{"type":"integer"}}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"add_suppressions","summary":"Add to the do-not-email list","description":"Adds up to 1,000 addresses to the do-not-email list. Contacts with these addresses are unsubscribed. Invalid addresses are skipped.","tags":["Suppressions"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"emails":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"string"},"examples":[["someone@example.com"]]},"note":{"type":"string","maxLength":250}},"required":["emails"],"additionalProperties":false},"example":{"emails":["someone@example.com"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/suppressions/{id}":{"delete":{"operationId":"remove_suppression","summary":"Remove from the do-not-email list","description":"Removes an address added by hand. Unsubscribes, bounces and complaints can't be removed: the person has to sign up again.","tags":["Suppressions"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The suppression's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/lists":{"get":{"operationId":"list_lists","summary":"List lists","description":"Lists the workspace's contact lists with how many contacts each has. list_contacts with filter list_id shows who is on one.","tags":["Lists"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/List"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_list","summary":"Create a list","description":"Creates an empty list. Add contacts with add_to_list.","tags":["Lists"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"examples":["Berlin expo 2026"]}},"required":["name"],"additionalProperties":false},"example":{"name":"Berlin expo 2026"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/List"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/lists/{id}":{"get":{"operationId":"get_list","summary":"Get a list","description":"Gets one list and its contact count.","tags":["Lists"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The list's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/List"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"patch":{"operationId":"update_list","summary":"Rename a list","description":"Renames a list.","tags":["Lists"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The list's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/List"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_list","summary":"Delete a list","description":"Deletes a list. Its contacts are kept.","tags":["Lists"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The list's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/lists/{id}/contacts":{"post":{"operationId":"add_to_list","summary":"Add contacts to a list","description":"Adds up to 1,000 of the workspace's contacts to a list. Contacts already on it are left as they are.","tags":["Lists"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The list's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contact_ids":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"integer"},"examples":[[12,13]]}},"required":["contact_ids"],"additionalProperties":false},"example":{"contact_ids":[12,13]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/List"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"remove_from_list","summary":"Remove contacts from a list","description":"Takes up to 1,000 contacts off a list. The contacts are kept.","tags":["Lists"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The list's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contact_ids":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"integer"},"examples":[[12,13]]}},"required":["contact_ids"],"additionalProperties":false},"example":{"contact_ids":[12,13]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/List"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/segments":{"get":{"operationId":"list_segments","summary":"List segments","description":"Lists the workspace's segments with their last counted size (count_segment counts again).","tags":["Segments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Segment"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_segment","summary":"Create a segment","description":"Saves a segment. Rules that can't be worked out are refused, never dropped (a dropped rule would widen who gets emailed).","tags":["Segments"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"examples":["Opted in, last 30 days"]},"rules":{"type":"object","description":"A rule tree: {\"match\": \"all\"|\"any\", \"rules\": [{\"field\": \"lead_type\", \"op\": \"in\", \"value\": [\"opted_in\"]}, {\"match\": \"any\", \"rules\": [...]}]}. Groups nest up to 3 deep. Dates also take {\"op\": \"in_period\", \"value\": \"last_month\"} and between [\"2026-01-01\", \"2026-03-31\"]; numbers between [1, 5]. get_segment_fields lists the fields, operators and periods.","additionalProperties":true,"examples":[{"match":"all","rules":[{"field":"lead_type","op":"in","value":["opted_in"]},{"field":"created_at","op":"within_last","value":30}]}]}},"required":["name","rules"],"additionalProperties":false},"example":{"name":"Opted in, last 30 days","rules":{"match":"all","rules":[{"field":"lead_type","op":"in","value":["opted_in"]},{"field":"created_at","op":"within_last","value":30}]}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Segment"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/segments/fields":{"get":{"operationId":"get_segment_fields","summary":"Get segment fields","description":"Lists what segment rules can filter on (every filterable contact property, custom ones as field:<key>) and the operators of each kind of field. Read this before writing rules.","tags":["Segments"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/segments/{id}":{"get":{"operationId":"get_segment","summary":"Get a segment","description":"Gets a segment and its rules.","tags":["Segments"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The segment's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Segment"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"patch":{"operationId":"update_segment","summary":"Update a segment","description":"Renames a segment or replaces its rules.","tags":["Segments"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The segment's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"rules":{"type":"object","description":"A rule tree: {\"match\": \"all\"|\"any\", \"rules\": [{\"field\": \"lead_type\", \"op\": \"in\", \"value\": [\"opted_in\"]}, {\"match\": \"any\", \"rules\": [...]}]}. Groups nest up to 3 deep. Dates also take {\"op\": \"in_period\", \"value\": \"last_month\"} and between [\"2026-01-01\", \"2026-03-31\"]; numbers between [1, 5]. get_segment_fields lists the fields, operators and periods.","additionalProperties":true,"examples":[{"match":"all","rules":[{"field":"lead_type","op":"in","value":["opted_in"]},{"field":"created_at","op":"within_last","value":30}]}]}},"additionalProperties":false},"example":{"rules":{"match":"all","rules":[{"field":"lead_type","op":"in","value":["opted_in"]},{"field":"created_at","op":"within_last","value":30}]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Segment"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_segment","summary":"Delete a segment","description":"Deletes a segment. Refused while another segment uses it. Its contacts are kept.","tags":["Segments"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The segment's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/segments/{id}/count":{"get":{"operationId":"count_segment","summary":"Count a segment","description":"Counts the contacts in a segment now, and how many of them can be emailed (active, with a good address).","tags":["Segments"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The segment's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/templates":{"get":{"operationId":"list_templates","summary":"List templates","description":"Lists the workspace's email templates, last changed first (without their content; get_template has it).","tags":["Templates"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Template"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_template","summary":"Create a template","description":"Saves reusable email content. Write markdown (format markdown), full or partial HTML (format html), or an editor document (format editor). Merge tags: {{first_name|there}} (with a fallback), {{email}}, {{custom.<key>}}. The unsubscribe footer with your postal address is added for you.","tags":["Templates"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"examples":["Monthly newsletter"]},"format":{"type":"string","description":"markdown, html or editor.","enum":["editor","html","markdown"],"examples":["markdown"]},"subject":{"type":"string","maxLength":200,"examples":["What's new in May"]},"preview_text":{"type":["string","null"],"description":"Shown next to the subject in the inbox.","maxLength":200},"markdown":{"type":["string","null"],"maxLength":200000,"examples":["Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")"]},"html":{"type":["string","null"],"maxLength":500000},"document":{"type":["object","null"],"description":"A Tiptap editor document (format editor).","additionalProperties":true},"topic_id":{"type":["integer","null"],"description":"The topic it belongs to (list_topics); people who left the topic don't get it.","minimum":1},"theme":{"type":["string","null"],"description":"A colour theme; null uses the workspace's.","enum":["standard","letter","newsroom","oasis","sand","night","typewriter","poster"]}},"required":["name","format"],"additionalProperties":false},"example":{"name":"Monthly newsletter","format":"markdown","subject":"What's new in May","markdown":"Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Template"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/templates/{id}":{"get":{"operationId":"get_template","summary":"Get a template","description":"Gets a template with its content.","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The template's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Template"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"patch":{"operationId":"update_template","summary":"Update a template","description":"Changes a template. Only the fields you send change. Campaigns made from it keep their own copy. Merge tags: {{first_name|there}} (with a fallback), {{email}}, {{custom.<key>}}. The unsubscribe footer with your postal address is added for you.","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The template's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"format":{"type":"string","description":"markdown, html or editor.","enum":["editor","html","markdown"],"examples":["markdown"]},"subject":{"type":"string","maxLength":200,"examples":["What's new in May"]},"preview_text":{"type":["string","null"],"description":"Shown next to the subject in the inbox.","maxLength":200},"markdown":{"type":["string","null"],"maxLength":200000,"examples":["Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")"]},"html":{"type":["string","null"],"maxLength":500000},"document":{"type":["object","null"],"description":"A Tiptap editor document (format editor).","additionalProperties":true},"topic_id":{"type":["integer","null"],"description":"The topic it belongs to (list_topics); people who left the topic don't get it.","minimum":1},"theme":{"type":["string","null"],"description":"A colour theme; null uses the workspace's.","enum":["standard","letter","newsroom","oasis","sand","night","typewriter","poster"]}},"additionalProperties":false},"example":{"format":"markdown","subject":"What's new in May","markdown":"Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Template"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_template","summary":"Delete a template","description":"Deletes a template. Campaigns made from it keep their content.","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The template's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/templates/{id}/preview":{"post":{"operationId":"preview_template","summary":"Preview a template","description":"Renders a template as it will be sent: subject, preheader, HTML, plain text, size and content warnings, filled in for one of your contacts or with sample values.","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The template's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"contact_id":{"type":"integer","description":"Fill merge tags for this contact.","minimum":1}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/templates/{id}/test":{"post":{"operationId":"send_test_template","summary":"Send a test of a template","description":"Emails a test of the template to a member of the workspace (never to contacts), from one of its senders.","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The template's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"A workspace member's address.","format":"email","maxLength":254,"examples":["you@company.com"]},"sender_id":{"type":"integer","description":"Who it is from (list_senders); the default sender when left out.","minimum":1}},"required":["to"],"additionalProperties":false},"example":{"to":"you@company.com"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":true}}},"/campaigns":{"get":{"operationId":"list_campaigns","summary":"List campaigns","description":"Lists campaigns, newest first, with their status and counts (without content).","tags":["Campaigns"],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["draft","scheduled","sending","paused","sent","canceled"]}},{"name":"page","in":"query","description":"Page number, from 1.","schema":{"type":"integer","description":"Page number, from 1.","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Items per page, up to 100.","schema":{"type":"integer","description":"Items per page, up to 100.","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Campaign"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"last_page":{"type":"integer"}}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_campaign","summary":"Create a campaign","description":"Creates a draft from a template (template_id) or with new content, from the default sender. Choose the audience with lists and segments; exclusions are taken out. Only opted-in contacts who can be emailed get it. Merge tags: {{first_name|there}} (with a fallback), {{email}}, {{custom.<key>}}. The unsubscribe footer with your postal address is added for you.","tags":["Campaigns"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120,"examples":["May newsletter"]},"template_id":{"type":"integer","description":"Copy this template's content.","minimum":1},"format":{"type":"string","description":"markdown, html or editor.","enum":["editor","html","markdown"],"examples":["markdown"]},"subject":{"type":"string","maxLength":200,"examples":["What's new in May"]},"preview_text":{"type":["string","null"],"description":"Shown next to the subject in the inbox.","maxLength":200},"markdown":{"type":["string","null"],"maxLength":200000,"examples":["Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")"]},"html":{"type":["string","null"],"maxLength":500000},"document":{"type":["object","null"],"description":"A Tiptap editor document (format editor).","additionalProperties":true},"topic_id":{"type":["integer","null"],"description":"The topic it belongs to (list_topics); people who left the topic don't get it.","minimum":1},"theme":{"type":["string","null"],"description":"A colour theme; null uses the workspace's.","enum":["standard","letter","newsroom","oasis","sand","night","typewriter","poster"]},"sender_id":{"type":"integer","description":"Who it is from (list_senders).","minimum":1},"audience":{"type":"object","description":"Who gets it: {\"lists\": [ids], \"segments\": [ids]}.","additionalProperties":true,"examples":[{"lists":[3],"segments":[]}]},"exclusions":{"type":"object","description":"Who never gets it, even if in the audience: {\"lists\": [ids], \"segments\": [ids]}.","additionalProperties":true},"audience_limit":{"type":["integer","null"],"description":"Only the N most engaged recipients; send_campaign_to_more reaches the rest later.","minimum":1,"maximum":1000000},"publish_to":{"type":"string","description":"Where it goes: email (the default), both (email, and the workspace's public pages once it goes out) or web (the public pages only: no email goes out, and send_campaign takes confirm_recipients 0).","enum":["email","both","web"],"examples":["both"]}},"required":["name"],"additionalProperties":false},"example":{"name":"May newsletter","format":"markdown","subject":"What's new in May","markdown":"Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")","audience":{"lists":[3],"segments":[]},"publish_to":"both"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/campaigns/{id}":{"get":{"operationId":"get_campaign","summary":"Get a campaign","description":"Gets a campaign with its content, audience and counts.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"patch":{"operationId":"update_campaign","summary":"Update a campaign","description":"Changes a draft or scheduled campaign that hasn't started: content, sender, topic, audience. Only the fields you send change. Merge tags: {{first_name|there}} (with a fallback), {{email}}, {{custom.<key>}}. The unsubscribe footer with your postal address is added for you.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"format":{"type":"string","description":"markdown, html or editor.","enum":["editor","html","markdown"],"examples":["markdown"]},"subject":{"type":"string","maxLength":200,"examples":["What's new in May"]},"preview_text":{"type":["string","null"],"description":"Shown next to the subject in the inbox.","maxLength":200},"markdown":{"type":["string","null"],"maxLength":200000,"examples":["Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")"]},"html":{"type":["string","null"],"maxLength":500000},"document":{"type":["object","null"],"description":"A Tiptap editor document (format editor).","additionalProperties":true},"topic_id":{"type":["integer","null"],"description":"The topic it belongs to (list_topics); people who left the topic don't get it.","minimum":1},"theme":{"type":["string","null"],"description":"A colour theme; null uses the workspace's.","enum":["standard","letter","newsroom","oasis","sand","night","typewriter","poster"]},"sender_id":{"type":"integer","description":"Who it is from (list_senders).","minimum":1},"audience":{"type":"object","description":"Who gets it: {\"lists\": [ids], \"segments\": [ids]}.","additionalProperties":true,"examples":[{"lists":[3],"segments":[]}]},"exclusions":{"type":"object","description":"Who never gets it, even if in the audience: {\"lists\": [ids], \"segments\": [ids]}.","additionalProperties":true},"audience_limit":{"type":["integer","null"],"description":"Only the N most engaged recipients; send_campaign_to_more reaches the rest later.","minimum":1,"maximum":1000000},"publish_to":{"type":"string","description":"Where it goes: email (the default), both (email, and the workspace's public pages once it goes out) or web (the public pages only: no email goes out, and send_campaign takes confirm_recipients 0).","enum":["email","both","web"],"examples":["both"]}},"additionalProperties":false},"example":{"format":"markdown","subject":"What's new in May","markdown":"Hi {{first_name|there}},\n\nHere is what's new.\n\n[Read more](https://example.com \"button\")","audience":{"lists":[3],"segments":[]},"publish_to":"both"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_campaign","summary":"Delete a campaign","description":"Deletes a draft. A campaign that was scheduled or sent can be canceled instead.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/campaigns/{id}/duplicate":{"post":{"operationId":"duplicate_campaign","summary":"Duplicate a campaign","description":"Makes a new draft with the same content, sender, topic and audience.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/campaigns/{id}/test":{"post":{"operationId":"send_test_campaign","summary":"Send a test of a campaign","description":"Emails a test to a member of the workspace (never to contacts), so the user can check it before sending.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"A workspace member's address.","format":"email","maxLength":254,"examples":["you@company.com"]}},"required":["to"],"additionalProperties":false},"example":{"to":"you@company.com"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":true}}},"/campaigns/{id}/review":{"get":{"operationId":"review_campaign","summary":"Review a campaign","description":"Runs the checks before sending. blocks must be fixed first; warnings can be accepted. checks lists every check: id, level (block or warning), passed, message (what to fix) and label (a short line for the ones that passed, or null). A web-only campaign (web_only true) only gets the content checks, and its audience is 0. audience.recipients is the count to show the user and pass as confirm_recipients, with who is skipped and why. pace says how it would go out if sent now: spread_hours (0 = straight away), the domain warm-up cap when it holds part of it to later days, and first_slice, the never-emailed contacts that go first; gmail_paused says so while Gmail rate limits the sending domain (what is sent waits until gmail_paused_until).","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/campaigns/{id}/tips":{"get":{"operationId":"get_campaign_tips","summary":"Get tips for more opens","description":"Tips on the saved content that tend to land email in spam or cost opens: a subject in capitals, runs of !!! or ???, classic spam phrases, a fake Re: or Fwd:, link shorteners, images with little text, too many links, no preview text, and up to three more from the AI content check when it runs. They never stop a send. tips: at most 3, most important first, each with code (the rule, or ai), field (subject, preview_text or content), quote (the exact words it is about) and tip (what to change). Empty when nothing stands out. ai: whether the AI check read this content.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/campaigns/{id}/send":{"post":{"operationId":"send_campaign","summary":"Send a campaign now","description":"Starts sending to the reviewed audience. Can't be undone: show the user the subject and the recipient count from review_campaign, and get their go-ahead first. A web-only campaign goes on the public pages instead (confirm_recipients 0).","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_recipients":{"type":"integer","description":"The recipient count from review_campaign, after the user confirmed it. Refused if the audience changed since. 0 for a web-only campaign (publish_to web): nobody gets an email.","minimum":0,"examples":[1250]}},"required":["confirm_recipients"],"additionalProperties":false},"example":{"confirm_recipients":1250}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":false,"openWorld":true}}},"/campaigns/{id}/schedule":{"post":{"operationId":"schedule_campaign","summary":"Schedule a campaign","description":"Schedules sending for later (up to a year ahead). A time without an offset is in the workspace's timezone. The audience is worked out when sending starts. Confirm with the user first, like send_campaign.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_recipients":{"type":"integer","description":"The recipient count from review_campaign, after the user confirmed it. Refused if the audience changed since. 0 for a web-only campaign (publish_to web): nobody gets an email.","minimum":0,"examples":[1250]},"scheduled_at":{"type":"string","format":"date-time","examples":["2026-11-02T09:00:00+03:00"]}},"required":["confirm_recipients","scheduled_at"],"additionalProperties":false},"example":{"confirm_recipients":1250,"scheduled_at":"2026-11-02T09:00:00+03:00"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":false,"openWorld":true}}},"/campaigns/{id}/unschedule":{"post":{"operationId":"unschedule_campaign","summary":"Unschedule a campaign","description":"Takes a scheduled campaign that hasn't started back to a draft. Nothing was sent.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/campaigns/{id}/send-more":{"post":{"operationId":"send_campaign_to_more","summary":"Send a campaign to more people","description":"Raises the audience limit of a sent or sending campaign (null: everyone), and the next people in the same order get it. Can't be undone: confirm with the user first.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"audience_limit":{"type":["integer","null"],"description":"The new total; null sends to everyone in the audience.","minimum":1,"maximum":1000000}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":false,"openWorld":true}}},"/campaigns/{id}/pause":{"post":{"operationId":"pause_campaign","summary":"Pause a campaign","description":"Pauses a scheduled or sending campaign. Emails already handed to Amazon SES still go; the rest wait.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}}},"/campaigns/{id}/resume":{"post":{"operationId":"resume_campaign","summary":"Resume a campaign","description":"Resumes a paused campaign, so sending carries on. If it paused itself for high bounce or complaint rates, resuming accepts those rates. Confirm with the user first.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":false,"openWorld":true}}},"/campaigns/{id}/cancel":{"post":{"operationId":"cancel_campaign","summary":"Cancel a campaign","description":"Stops a campaign for good: nobody else gets it. A scheduled campaign that hasn't started goes back to a draft.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Campaign"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":false,"openWorld":false}}},"/campaigns/{id}/report":{"get":{"operationId":"get_campaign_report","summary":"Get a campaign's report","description":"The results of a campaign: counts (sent, delivered, opens, clicks, bounces, complaints, unsubscribes), rates, the most clicked links, results by inbox provider, opens hour by hour, and how it compares with recent campaigns. Machine opens (Apple Mail Privacy Protection and the like) are counted apart.","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The campaign's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/domains":{"get":{"operationId":"list_domains","summary":"List sending domains","description":"Lists the domains the workspace sends from, whether each is verified, and the DNS records to add (DKIM, MAIL FROM, DMARC) with which are in place.","tags":["Sending"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"add_domain","summary":"Add a sending domain","description":"Adds a domain to send from and returns the DNS records to add at its DNS provider. Use a subdomain such as news.example.com, so campaigns never affect the main domain's email. Then check_domain once the records are in.","tags":["Sending"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"examples":["news.example.com"]}},"required":["domain"],"additionalProperties":false},"example":{"domain":"news.example.com"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Domain"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":true}}},"/domains/{id}/check":{"post":{"operationId":"check_domain","summary":"Check a sending domain","description":"Asks Amazon SES and DNS whether the domain's records are in place, and returns its status. DNS changes can take up to an hour to show.","tags":["Sending"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The domain's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Domain"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":true}}},"/senders":{"get":{"operationId":"list_senders","summary":"List senders","description":"Lists who the workspace's emails can be from (name, address, reply-to), the default first. Senders on an unverified domain can't send yet.","tags":["Sending"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Sender"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/test-emails":{"get":{"operationId":"list_test_emails","summary":"List test emails","description":"The newest test emails, from any member or key, with what became of each from Amazon SES's events: sent, delivered, delayed, bounced (detail says why; suppressed when the address is on SES's suppression list), complained, rejected or failed. Check it after a send_test_* to see whether the test arrived. Give campaign_id or template_id for that one's tests.","tags":["Sending"],"parameters":[{"name":"campaign_id","in":"query","description":"Only tests of this campaign.","schema":{"type":"integer","description":"Only tests of this campaign.","minimum":1}},{"name":"template_id","in":"query","description":"Only tests of this template.","schema":{"type":"integer","description":"Only tests of this template.","minimum":1}},{"name":"limit","in":"query","description":"How many, newest first.","schema":{"type":"integer","description":"How many, newest first.","minimum":1,"maximum":50,"default":10}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TestEmail"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/signup-forms":{"get":{"operationId":"list_signup_forms","summary":"List signup forms","description":"Lists the workspace's signup forms with their public id (form_id in add_signup), signup counts, and whether our content check holds their own confirmation or welcome email (\"in_review\", or \"rejected\" with our team's note): meanwhile new signups get the built-in confirmation email and no welcome email.","tags":["Signups"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SignupForm"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/signups":{"post":{"operationId":"add_signup","summary":"Add a signup","description":"Signs someone up to the workspace's emails, like a signup form. With confirmed opt-in (the default, and always for someone who unsubscribed before) they get a confirmation email and stay pending until they click it. People already subscribed are left as they are. Works with a signups key.","tags":["Signups"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","maxLength":254,"examples":["sara@example.com"]},"first_name":{"type":"string","maxLength":120,"examples":["Sara"]},"form_id":{"type":"string","description":"A signup form's public id: its list, topics, confirmation and welcome emails apply.","maxLength":40},"topics":{"type":"array","description":"Without a form: topic ids or keys to join.","maxItems":20,"items":{"type":"string"}},"double_opt_in":{"type":"boolean","description":"Without a form: false skips the confirmation email (only if you confirmed them yourself)."},"page_url":{"type":"string","description":"Where they signed up, kept with their consent.","maxLength":500},"keep_email":{"type":"boolean","description":"Sign up an address that looks like a typo anyway."},"fields":{"type":"object","description":"Custom contact property values by key (see list_properties), checked like add_contact. Required properties aren't required here.","additionalProperties":true,"examples":[{"ticket_type":"VIP"}]}},"required":["email"],"additionalProperties":false},"example":{"email":"sara@example.com","first_name":"Sara","fields":{"ticket_type":"VIP"}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"signups","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":true}}},"/website-domain":{"post":{"operationId":"set_website_domain","summary":"Set the public pages' domain","description":"Puts the workspace's public pages (its published campaigns) on a subdomain of its own, like news.example.com. The answer lists the two DNS records to add: a CNAME that points the subdomain at Zeebra, and a TXT record that proves it's yours. It goes live once check_website_domain finds both, and right away when they're already in. One domain at a time: remove a live one first. Tracked and unsubscribe links stay on Zeebra's own domain.","tags":["Public pages"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string","description":"A subdomain of a domain you manage. A link works too.","maxLength":253,"examples":["news.example.com"]}},"required":["host"],"additionalProperties":false},"example":{"host":"news.example.com"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebsiteDomain"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":true}},"delete":{"operationId":"remove_website_domain","summary":"Remove the public pages' domain","description":"Takes the public pages off their own domain: they go back to their address on Zeebra, and links to the domain redirect there while it still points at Zeebra.","tags":["Public pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/website-domain/check":{"post":{"operationId":"check_website_domain","summary":"Check the public pages' domain","description":"Looks up the DNS records of the public pages' domain again. One being set up goes live once both are in; for a live one, says whether its CNAME still points at Zeebra. DNS changes can take up to an hour to show.","tags":["Public pages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebsiteDomain"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":true}}},"/webhooks/events":{"get":{"operationId":"list_webhook_event_types","summary":"List webhook event types","description":"Lists the events an endpoint can subscribe to, with what each means. Every event is sent as {id, type, created_at, workspace_id, data}, signed in the Zeebra-Signature header.","tags":["Webhooks"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/webhooks":{"get":{"operationId":"list_webhooks","summary":"List webhook endpoints","description":"Lists the workspace's webhook endpoints, the events each gets, and whether it is on.","tags":["Webhooks"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"post":{"operationId":"create_webhook","summary":"Add a webhook endpoint","description":"Adds an HTTPS endpoint that gets the chosen events. The answer has its signing secret (secret): store it now, it is never shown again. Verify each delivery's Zeebra-Signature header with it. Up to 10 endpoints per workspace.","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"An https:// URL on a public host.","maxLength":2000,"examples":["https://example.com/webhooks/zeebra"]},"events":{"type":"array","description":"Event types (list_webhook_event_types), or [\"*\"] for every event, including ones added later.","minItems":1,"maxItems":20,"items":{"type":"string"},"examples":[["contact.unsubscribed","email.bounced"]]},"description":{"type":["string","null"],"description":"What it is for, e.g. \"atndr CRM sync\".","maxLength":200}},"required":["url","events"],"additionalProperties":false},"example":{"url":"https://example.com/webhooks/zeebra","events":["contact.unsubscribed","email.bounced"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/webhooks/{id}":{"get":{"operationId":"get_webhook","summary":"Get a webhook endpoint","description":"Gets one webhook endpoint (never its secret).","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook endpoint's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}},"patch":{"operationId":"update_webhook","summary":"Change a webhook endpoint","description":"Changes an endpoint's URL, events or description, or switches it off or back on (enabled). Switching it on clears its failures. Only the fields sent change.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook endpoint's id.","minimum":1}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2000},"events":{"type":"array","description":"Event types (list_webhook_event_types), or [\"*\"] for every event, including ones added later.","minItems":1,"maxItems":20,"items":{"type":"string"},"examples":[["contact.unsubscribed","email.bounced"]]},"description":{"type":["string","null"],"description":"What it is for, e.g. \"atndr CRM sync\".","maxLength":200},"enabled":{"type":"boolean"}},"additionalProperties":false},"example":{"events":["contact.unsubscribed","email.bounced"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":true,"openWorld":false}},"delete":{"operationId":"delete_webhook","summary":"Delete a webhook endpoint","description":"Deletes an endpoint and its delivery log. It gets nothing more.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook endpoint's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":true,"idempotent":true,"openWorld":false}}},"/webhooks/{id}/secret":{"post":{"operationId":"rotate_webhook_secret","summary":"Rotate a webhook secret","description":"Gives the endpoint a new signing secret (in secret, shown once). For 24 hours deliveries carry a signature with the old secret too, so the receiver can switch without missing events.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook endpoint's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":false}}},"/webhooks/{id}/test":{"post":{"operationId":"test_webhook","summary":"Send a test event","description":"Sends a webhook.test event to the endpoint now (once, no retries; even when it is switched off) and returns the delivery: its status, the endpoint's HTTP status and answer.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook endpoint's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookDelivery"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":true}}},"/webhooks/{id}/deliveries":{"get":{"operationId":"list_webhook_deliveries","summary":"List webhook deliveries","description":"The endpoint's newest deliveries first (the last 100 are kept): each event, its status, attempts, and the endpoint's last answer. A retrying delivery says when it is tried next.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook endpoint's id.","minimum":1}},{"name":"status","in":"query","description":"Only deliveries with this status.","schema":{"type":"string","description":"Only deliveries with this status.","enum":["pending","sending","retrying","succeeded","failed"]}},{"name":"page","in":"query","description":"Page number, from 1.","schema":{"type":"integer","description":"Page number, from 1.","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Items per page, up to 100.","schema":{"type":"integer","description":"Items per page, up to 100.","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"last_page":{"type":"integer"}}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":true,"destructive":false,"idempotent":true,"openWorld":false}}},"/webhooks/{id}/deliveries/{delivery_id}/resend":{"post":{"operationId":"resend_webhook_delivery","summary":"Resend a webhook delivery","description":"Sends a delivery's event to its endpoint again, now, with the same event id (so the receiver can tell it's a repeat). Returns the new delivery.","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook endpoint's id.","minimum":1}},{"name":"delivery_id","in":"path","required":true,"schema":{"type":"integer","description":"The delivery's id.","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookDelivery"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/unauthorized"},"402":{"$ref":"#/components/responses/subscription_required"},"403":{"$ref":"#/components/responses/forbidden"},"422":{"$ref":"#/components/responses/validation_failed"},"429":{"$ref":"#/components/responses/rate_limited"},"430":{"$ref":"#/components/responses/not_found"}},"x-zeebra-ability":"full","x-zeebra-hints":{"readOnly":false,"destructive":false,"idempotent":false,"openWorld":true}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"A workspace API key, e.g. 12|zeebra_…"}},"schemas":{"Contact":{"type":"object","description":"Someone the workspace can email.","properties":{"id":{"type":"integer"},"email":{"type":["string","null"]},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"title":{"type":["string","null"]},"company":{"type":["string","null"],"description":"Their company's name (the account's, when linked)."},"account_id":{"type":["integer","null"],"description":"Their company in the workspace (see list_accounts)."},"phone":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 code: where they signed up, confirmed or first clicked a link from. Their IP address is never kept. Null until then."},"lead_type":{"type":"string","enum":["opted_in","prospect"],"description":"opted_in contacts get campaigns; prospects never do."},"status":{"type":"string","enum":["active","pending","dormant","unsubscribed","bounced","complained"]},"email_issue":{"type":["string","null"],"enum":["invalid","typo","role","disposable","no_mx",null]},"email_suggestion":{"type":["string","null"]},"source":{"type":"string","enum":["import","zeebra","manual","api","form","shared"],"description":"How it was added: import, zeebra (saved from Zeebra's data), manual, api, form (a signup), or shared (a copy made when another workspace of the business group shared it)."},"shared":{"type":"boolean","description":"Shared with the workspace's business group: its name, email, phone, job title, company and location are the same in every connected workspace (see share_contact)."},"fields":{"type":"object","additionalProperties":true,"description":"Custom property values by key (see list_properties)."},"tags":{"type":"array","items":{"type":"string"}},"consent":{"type":["object","null"],"properties":{"source":{"type":["string","null"]},"at":{"type":["string","null"],"format":"date-time"},"note":{"type":["string","null"]}}},"last_sent_at":{"type":["string","null"],"format":"date-time"},"last_opened_at":{"type":["string","null"],"format":"date-time"},"last_clicked_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"history":{"type":"array","description":"get_contact only: the newest changes first. event: status_changed, opted_in, last_chance_sent or kept; actor: who acted (member, admin, api, import, ses, unsubscribe_link, signup_form, opt_out, keep_link, business_group (another workspace of the group: the note says which) or system).","items":{"type":"object","properties":{"id":{"type":"integer"},"event":{"type":["string","null"]},"from":{"type":["string","null"]},"to":{"type":["string","null"]},"via":{"type":["string","null"]},"actor":{"type":"string"},"by":{"type":["string","null"]},"note":{"type":["string","null"]},"consent":{"type":["object","null"],"properties":{"source":{"type":["string","null"]},"at":{"type":["string","null"],"format":"date-time"},"note":{"type":["string","null"]}}},"at":{"type":"string","format":"date-time"}}}}}},"ContactEmail":{"type":"object","description":"A campaign email one contact got.","properties":{"id":{"type":"integer"},"campaign":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"subject":{"type":"string"}}},"status":{"type":"string","description":"sent: handed to Amazon SES. delivered: their server took it. bounced, complained: it bounced, or they marked it as spam."},"provider":{"type":["string","null"],"description":"Their inbox provider: gmail, outlook, yahoo, icloud or other."},"sent_at":{"type":["string","null"],"format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"},"opened_at":{"type":["string","null"],"format":"date-time","description":"Their first real open. Machine opens (Apple Mail Privacy Protection, scanners) never count."},"clicked_at":{"type":["string","null"],"format":"date-time","description":"Their first real click."},"bounced_at":{"type":["string","null"],"format":"date-time"},"complained_at":{"type":["string","null"],"format":"date-time"},"unsubscribed_at":{"type":["string","null"],"format":"date-time"},"clicked_links":{"type":"array","items":{"type":"string"},"description":"The links they clicked, first click first."}}},"Account":{"type":"object","description":"One of the workspace's companies (the Companies page).","properties":{"id":{"type":"integer"},"name":{"type":"string"},"domain":{"type":["string","null"],"description":"Contacts with a work email at this domain join the account. One account per domain."},"website":{"type":["string","null"]},"industry":{"type":["string","null"]},"city":{"type":["string","null"]},"country":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 code."},"phone":{"type":["string","null"],"description":"E.164, like +442079460958."},"employees":{"type":["integer","null"]},"description":{"type":["string","null"]},"owner_id":{"type":["integer","null"],"description":"The team member who looks after it (a user id)."},"shared":{"type":"boolean","description":"Shared with the workspace's business group: its name, domain, website, industry, size, phone and location are the same in every connected workspace (see share_account)."},"fields":{"type":"object","additionalProperties":true,"description":"Custom property values by key (list_properties with entity account)."},"contacts_count":{"type":["integer","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Tag":{"type":"object","description":"A label on contacts.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"color":{"type":"string","enum":["zinc","red","amber","green","blue","violet","pink"]},"contacts_count":{"type":["integer","null"]}}},"Property":{"type":"object","description":"Something a contact or company has: a system column or a custom property of the workspace.","properties":{"key":{"type":"string","description":"System properties: their column (\"first_name\"). Custom ones: \"field:<key>\"; the <key> is what contacts' fields use and {{custom.<key>}} puts in an email."},"entity":{"type":"string","enum":["contact","account","company","person"]},"id":{"type":["integer","null"],"description":"Custom properties only: use it to update, archive or restore."},"label":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["text","long_text","number","currency","date","datetime","select","multi_select","boolean","email","phone","url","country","user"]},"storage":{"type":"string","enum":["column","value","relation"]},"source":{"type":"string","description":"The column, custom value key or relation it is stored in."},"group":{"type":"string"},"group_label":{"type":["string","null"]},"position":{"type":"integer"},"is_system":{"type":"boolean"},"read_only":{"type":"boolean","description":"Changes only through its own operation, or not at all."},"required":{"type":"boolean"},"lock_required":{"type":"boolean"},"hidden":{"type":"boolean"},"searchable":{"type":"boolean"},"filterable":{"type":"boolean"},"sortable":{"type":"boolean"},"filter_kind":{"type":["string","null"]},"operators":{"type":"array","items":{"type":"string"},"description":"Segment rule operators (see get_segment_fields)."},"options":{"type":["array","null"],"items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"},"color":{"type":["string","null"],"enum":["zinc","red","amber","green","blue","violet","pink",null]}}}},"settings":{"type":"object","additionalProperties":true,"description":"Validation: min_length, max_length, regex, min, max, decimals, currency, date_rule, date_from, date_to, min_selections, max_selections (by type)."},"archived_at":{"type":["string","null"],"format":"date-time"}}},"Topic":{"type":"object","description":"A kind of email people can unsubscribe from on its own.","properties":{"id":{"type":"integer"},"key":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"default_subscribed":{"type":"boolean"}}},"List":{"type":"object","description":"A static list of contacts.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"contacts_count":{"type":["integer","null"]},"created_at":{"type":["string","null"],"format":"date-time"}}},"Segment":{"type":"object","description":"Contacts matching rules, worked out when used.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"rules":{"type":"object","additionalProperties":true},"cached_count":{"type":["integer","null"]},"counted_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Template":{"type":"object","description":"Reusable email content.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"format":{"type":"string","enum":["editor","html","markdown"]},"subject":{"type":"string"},"preview_text":{"type":["string","null"]},"markdown":{"type":["string","null"]},"html":{"type":["string","null"]},"document":{"type":["object","null"],"additionalProperties":true},"topic_id":{"type":["integer","null"]},"theme":{"type":["string","null"]},"test_sent_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Campaign":{"type":"object","description":"An email to opted-in contacts.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","enum":["draft","scheduled","sending","paused","sent","canceled"]},"subject":{"type":"string"},"preview_text":{"type":["string","null"]},"format":{"type":"string","enum":["editor","html","markdown"]},"markdown":{"type":["string","null"]},"html":{"type":["string","null"]},"document":{"type":["object","null"],"additionalProperties":true},"sender_id":{"type":["integer","null"]},"topic_id":{"type":["integer","null"]},"theme":{"type":["string","null"]},"audience":{"type":"object","properties":{"lists":{"type":"array","items":{"type":"integer"}},"segments":{"type":"array","items":{"type":"integer"}}}},"exclusions":{"type":"object","properties":{"lists":{"type":"array","items":{"type":"integer"}},"segments":{"type":"array","items":{"type":"integer"}}}},"audience_limit":{"type":["integer","null"]},"publish_to":{"type":"string","enum":["email","both","web"],"description":"Where it goes: email, both (email and the public pages) or web (the public pages only, no email)."},"web_url":{"type":["string","null"],"description":"Its public page, once it is there (published and gone out)."},"pause_reason":{"type":["string","null"]},"stats":{"type":"object","additionalProperties":{"type":"integer"}},"scheduled_at":{"type":["string","null"],"format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"test_sent_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Domain":{"type":"object","description":"A domain the workspace sends from.","properties":{"id":{"type":"integer"},"domain":{"type":"string"},"verified":{"type":"boolean"},"dkim_status":{"type":"string"},"mail_from_status":{"type":"string"},"dmarc_policy":{"type":["string","null"]},"dns_records":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string"},"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"ok":{"type":"boolean"}}}},"last_checked_at":{"type":["string","null"],"format":"date-time"}}},"WebsiteDomain":{"type":"object","description":"The public pages' own domain, a subdomain of the workspace's.","properties":{"host":{"type":"string"},"status":{"type":"string","enum":["pending","live"],"description":"pending until both DNS records are found, then live: the public pages are at https://<host>."},"live":{"type":"boolean"},"cname_found":{"type":["boolean","null"],"description":"As last checked: the CNAME points at Zeebra."},"txt_found":{"type":["boolean","null"],"description":"As last checked: the TXT record that proves it's yours is in."},"dns_records":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string"},"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"ok":{"type":"boolean"}}},"description":"The records to add where the domain's DNS is managed. Once it's live, only the CNAME stays."},"checked_at":{"type":["string","null"],"format":"date-time"},"live_at":{"type":["string","null"],"format":"date-time"}}},"Sender":{"type":"object","description":"Who an email is from.","properties":{"id":{"type":"integer"},"from_name":{"type":"string"},"from_email":{"type":"string"},"reply_to":{"type":["string","null"]},"is_default":{"type":"boolean"},"domain_id":{"type":"integer"},"verified":{"type":"boolean"}}},"SignupForm":{"type":"object","description":"A signup form for the workspace's own website.","properties":{"id":{"type":"integer"},"form_id":{"type":"string","description":"Its public id: form_id in add_signup, and in the embed code."},"name":{"type":"string"},"double_opt_in":{"type":"boolean"},"welcome_enabled":{"type":"boolean"},"list_id":{"type":["integer","null"]},"signups_count":{"type":"integer"},"confirmed_count":{"type":"integer"},"email_review":{"type":"object","description":"The content check of its own confirmation and welcome emails: null while each goes out.","properties":{"confirmation":{"type":["object","null"],"properties":{"status":{"type":"string","enum":["in_review","rejected"]},"note":{"type":["string","null"]}}},"welcome":{"type":["object","null"],"properties":{"status":{"type":"string","enum":["in_review","rejected"]},"note":{"type":["string","null"]}}}}},"last_signup_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"}}},"Suppression":{"type":"object","description":"An address the workspace never emails.","properties":{"id":{"type":"integer"},"email":{"type":"string"},"reason":{"type":"string","enum":["bounce","complaint","unsubscribe","manual"]},"note":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"}}},"Import":{"type":"object","description":"A CSV import of contacts.","properties":{"id":{"type":"integer"},"status":{"type":"string","enum":["mapping","queued","processing","completed","failed"]},"name":{"type":"string"},"lead_type":{"type":"string"},"rows_total":{"type":"integer"},"created_count":{"type":"integer"},"updated_count":{"type":"integer"},"skipped":{"type":"object","additionalProperties":{"type":"integer"}},"flagged":{"type":"object","additionalProperties":{"type":"integer"}},"list_id":{"type":["integer","null"]},"error":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}}},"Error":{"type":"object","description":"What went wrong.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","subscription_required","forbidden","not_found","method_not_allowed","conflict","too_large","validation_failed","rate_limited","server_error","upstream_error"]},"message":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["code","message"]}}},"TestEmail":{"type":"object","description":"A test email and what became of it, from Amazon SES's events.","properties":{"id":{"type":"integer"},"kind":{"type":"string","description":"What it tested: campaign-test, template-test, signup-confirmation-test or signup-welcome-test."},"from":{"type":"string"},"to":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string","enum":["sending","sent","delayed","delivered","bounced","complained","rejected","failed"],"description":"sending, then sent (Amazon SES took it), delivered (their server took it: check spam if it isn't in the inbox), delayed (still trying), or bounced, complained, rejected or failed (see detail)."},"detail":{"type":["string","null"],"description":"The receiving server's or Amazon SES's words: why it bounced, was delayed, rejected or failed."},"suppressed":{"type":"boolean","description":"The address is on Amazon SES's suppression list after an earlier bounce or complaint, so SES doesn't send to it."},"ses_message_id":{"type":["string","null"]},"sent_by":{"type":["string","null"],"description":"The member who sent it, or null from an API key."},"sent_at":{"type":"string","format":"date-time"},"status_at":{"type":["string","null"],"format":"date-time"}}},"WebhookEndpoint":{"type":"object","description":"An HTTPS endpoint the workspace sends signed events to.","properties":{"id":{"type":"integer"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["contact.created","contact.updated","contact.unsubscribed","contact.opted_in","email.delivered","email.opened","email.clicked","email.bounced","email.complained","campaign.sent","*"]},"description":"The events it gets; [\"*\"] is every event, including ones added later."},"enabled":{"type":"boolean","description":"Switched-off endpoints get nothing. Zeebra switches one off by itself after 20 failed attempts in a row over at least 24 hours."},"disabled_reason":{"type":["string","null"]},"consecutive_failures":{"type":"integer","description":"Failed attempts in a row; a success resets it."},"last_success_at":{"type":["string","null"],"format":"date-time"},"last_failure_at":{"type":["string","null"],"format":"date-time"},"secret":{"type":"string","description":"create_webhook and rotate_webhook_secret only: the signing secret (whsec_…). It is never shown again."},"created_at":{"type":["string","null"],"format":"date-time"}}},"WebhookDelivery":{"type":"object","description":"One event sent to one endpoint, with its last attempt.","properties":{"id":{"type":"integer"},"endpoint_id":{"type":"integer"},"event_id":{"type":"string","description":"The event's id (evt_…), the same on a resend."},"event_type":{"type":"string"},"status":{"type":"string","enum":["pending","sending","retrying","succeeded","failed"],"description":"pending, sending, retrying (next_attempt_at says when), succeeded, or failed after the last retry."},"attempts":{"type":"integer"},"response_status":{"type":["integer","null"],"description":"The endpoint's HTTP status on the last attempt."},"response_body":{"type":["string","null"],"description":"The first 1,000 characters of its answer."},"duration_ms":{"type":["integer","null"]},"error":{"type":["string","null"]},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"}}},"WebhookEventType":{"type":"object","description":"An event an endpoint can subscribe to.","properties":{"type":{"type":"string"},"description":{"type":"string"}}}},"responses":{"unauthorized":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"subscription_required":{"description":"Subscription required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"forbidden":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"not_found":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"method_not_allowed":{"description":"Method not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"conflict":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"too_large":{"description":"Too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"validation_failed":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"rate_limited":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"server_error":{"description":"Server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"upstream_error":{"description":"Upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}