package main
import (
"context"
"fmt"
"log"
"os"
"github.com/AhaSend/ahasend-go"
"github.com/AhaSend/ahasend-go/api"
"github.com/AhaSend/ahasend-go/models/common"
"github.com/AhaSend/ahasend-go/models/requests"
"github.com/google/uuid"
)
func main() {
client := api.NewAPIClient(api.WithAPIKey(os.Getenv("AHASEND_API_KEY")))
accountID := uuid.MustParse(os.Getenv("AHASEND_ACCOUNT_ID"))
ctx := context.Background()
listID := uuid.MustParse("22222222-2222-4222-8222-222222222222")
templateID := uuid.MustParse("33333333-3333-4333-8333-333333333333")
// The campaign copies the campaign template's design; later changes to
// the template do not reach it. Every field but Name can be set later.
response, _, err := client.CampaignsAPI.CreateCampaign(ctx, accountID, requests.CreateCampaignRequest{
Name: "October newsletter",
Subject: ahasend.String("Our news for October, {{ first_name }}"),
Preheader: ahasend.String("Three things we shipped this month"),
From: &common.SenderAddress{
Email: "news@yourdomain.com",
Name: ahasend.String("Example"),
},
ListIDs: []uuid.UUID{listID},
TemplateID: &templateID,
})
if err != nil {
log.Fatalf("Error creating campaign: %v", err)
}
fmt.Printf("Created campaign %s, ready: %t\n", response.ID, response.Ready != nil && *response.Ready)
}
import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
// The SDK sends a fresh Idempotency-Key automatically and reuses it on its own retries.
const campaign = await client.campaigns.create({
name: "October newsletter",
subject: "What is new in October",
preheader: "Three things we shipped this month",
from: { email: "news@example.com", name: "Example" },
list_ids: ["00000000-0000-4000-8000-000000000010"],
template_id: "00000000-0000-4000-8000-000000000013",
});
console.log("Campaign created.", { id: campaign.id, ready: campaign.ready });
Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.
POST
/
v2
/
accounts
/
{account_id}
/
campaigns
AhaSend Go SDK
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/AhaSend/ahasend-go"
"github.com/AhaSend/ahasend-go/api"
"github.com/AhaSend/ahasend-go/models/common"
"github.com/AhaSend/ahasend-go/models/requests"
"github.com/google/uuid"
)
func main() {
client := api.NewAPIClient(api.WithAPIKey(os.Getenv("AHASEND_API_KEY")))
accountID := uuid.MustParse(os.Getenv("AHASEND_ACCOUNT_ID"))
ctx := context.Background()
listID := uuid.MustParse("22222222-2222-4222-8222-222222222222")
templateID := uuid.MustParse("33333333-3333-4333-8333-333333333333")
// The campaign copies the campaign template's design; later changes to
// the template do not reach it. Every field but Name can be set later.
response, _, err := client.CampaignsAPI.CreateCampaign(ctx, accountID, requests.CreateCampaignRequest{
Name: "October newsletter",
Subject: ahasend.String("Our news for October, {{ first_name }}"),
Preheader: ahasend.String("Three things we shipped this month"),
From: &common.SenderAddress{
Email: "news@yourdomain.com",
Name: ahasend.String("Example"),
},
ListIDs: []uuid.UUID{listID},
TemplateID: &templateID,
})
if err != nil {
log.Fatalf("Error creating campaign: %v", err)
}
fmt.Printf("Created campaign %s, ready: %t\n", response.ID, response.Ready != nil && *response.Ready)
}
import { AhaSendClient } from "@ahasend/sdk";
const client = AhaSendClient.fromEnv();
// The SDK sends a fresh Idempotency-Key automatically and reuses it on its own retries.
const campaign = await client.campaigns.create({
name: "October newsletter",
subject: "What is new in October",
preheader: "Three things we shipped this month",
from: { email: "news@example.com", name: "Example" },
list_ids: ["00000000-0000-4000-8000-000000000010"],
template_id: "00000000-0000-4000-8000-000000000013",
});
console.log("Campaign created.", { id: campaign.id, ready: campaign.ready });
The AhaSend API creates a draft marketing campaign. Access requires campaigns:write.Only name is required. You can set all other fields in this request, or later with Update Campaign. The response gives ready and issues: while the campaign has issues, it cannot be sent. See Issues.Design:
The design comes from one source:
content.mjml creates an advanced design, and content.html creates an html design. content.markup creates a simple design from AhaML: a content.html beside it is ignored, and a content.mjml beside it is refused. With content that has none of them, set editor. An editor that does not agree with the content is refused.
editor without content creates an empty design, which you can complete in the dashboard’s editor.
template_id copies the design of a campaign template. The copy belongs to the campaign: later changes to the campaign template do not change it. A campaign template with no HTML is refused. A template_id that names no campaign template of your account is refused with 400campaign template not found. template_id cannot go with editor or content.
Without any of them, the campaign has no design yet.
Content rules:
MJML must pass strict validation. For a validation error, the message gives the line of each problem.
AhaML must follow the AhaML rules. A refused write lists the problems in errors, each with its line and column when it has a place in the AhaML. See AhaML errors.
In MJML and HTML, images and stylesheets must use full https:// URLs, such as https://example.com/logo.png. The API refuses relative paths, such as images/logo.png, and http:, //, data:, cid: and other schemes. A URL that starts with a template variable, such as {{ logo_url }}, is allowed. AhaML URLs follow the AhaML URL rules. The API cannot upload files.
The MJML, the HTML, the AhaML and a text written by hand can each be at most 200 KB.
The HTML must have an unsubscribe link before you can send the campaign. In AhaML, write it as <Link href="{{ unsubscribe_url }}">…</Link>. See Unsubscribe link.
Sender, subject and audience:
from.email must be on a domain of your account with valid DNS records. A paused domain is accepted here, but Send Campaign and Test Campaign refuse it.
reply_to is an address only, without a display name.
In subject and preheader, line breaks become spaces, and spaces at the start and end are removed. An empty subject or preview text counts as none.
The API checks the subject, the preview text, the sender and the reply-to by the same rules as the dashboard, and its error messages use the same words.
list_ids and segment_ids hold the lists and segments of your account to send to. exclude_list_ids and exclude_segment_ids hold the lists and segments whose contacts get no message. A list or segment that you give twice counts once. See Audience for the rules.
An audience field that you send must leave the campaign at least one list or segment to send to, so list_ids can be [] with a segment in segment_ids. A list or segment that does not exist, more than 50 lists or 10 segments, or a list or segment that is both included and excluded is refused with 400.
When a segment of the audience is being built again, the API answers 409 with The campaign's audience is being updated. Try again in a minute. This refusal is stored for the Idempotency-Key, so retry with a new key.
This operation accepts an Idempotency-Key header. See Idempotency.
API key for authentication. Non-empty Security Requirement values are
AhaSend API-key roles. Roles listed within one requirement object are
jointly required; separate requirement objects are alternatives.
Optional idempotency key for safe request retries. Must be a unique string for each logical request.
An identical request with a completed stored outcome returns the original status and body. An in-progress
execution returns 409, a changed method/path/body returns 422, and a released 5xx execution may run again.
Keys for non-secret responses expire after 24 hours. API-key create responses include a one-time secret_key,
so successful encrypted replay responses for those operations expire after 5 minutes.
A new draft campaign. Every field but name can be set later with
Update Campaign. The design comes from at most one source: an
editor, content, both, or a template_id. With none of them the
campaign has no design yet.
The lists to send to, in order. A list named twice counts once.
Each must be a list of this account. A campaign uses at most 50
lists and 10 segments, included and excluded together, and an
audience field that is set must leave it at least one list or
segment to send to, so [] is accepted with segment_ids.
The segments to send to. A segment named twice counts once. Each must be a segment of this account. A contact reached through a list and a segment gets one message, recorded under the list. Responses return the segments by ID.
Lists whose contacts get no message from the campaign. A contact with any membership of one, whatever its status, is left out, also when an included list or segment reaches it. A list cannot be both in list_ids and here. Exclusions need at least one list or segment to send to. Responses return the lists by ID.
Segments whose members get no message from the campaign, also when an included list or segment reaches them. A segment cannot be both in segment_ids and here. Exclusions need at least one list or segment to send to. Responses return the segments by ID.
The editor of the design. Without content the campaign gets an empty design of this editor, which the dashboard's editor opens. With content, it is required when the content holds none of markup, mjml and html, and must agree with it otherwise; markup means simple, also beside html. Not accepted with template_id, whose editor the design keeps.
The content of the design, by the rules of TemplateContentInput. A campaign has no draft, so where those rules name the draft, they mean the campaign's design. Not accepted with template_id.
A campaign template whose design the campaign copies. The copy is the campaign's own; later changes to the template do not reach it. A campaign template with no HTML is refused.
Response
Campaign created
A campaign as List Campaigns returns it, without its audience, content and issues.
The sender. Null until a complete sender is set, and when its domain was deleted. name is an empty string when the campaign has no sender name, so the object can be sent back as it is.
The lists whose contacts the campaign does not send to, by ID. A contact with any membership of one of them, whatever its status, is left out. A list that was deleted is left out.
Warnings about the AhaML in content.markup, up to the first 100; empty when there are none. Present only in the answer to a write that carried content.markup.
Maximum array length: 100
Show child attributes
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"AhaSend","description":"AhaSend is a European transactional email service for developers: send through a REST API, SMTP relay, CLI or the official Node.js and Go SDKs, with data stored in the EU and 1,000 free emails per month.","colors":{"primary":"#066fd1","light":"#F8FAFC","dark":"#0F172A"},"logo":{"light":"https://mintcdn.com/ahasend/F35Ozd-1GsftDpcH/logo.png?fit=max\u0026auto=format\u0026n=F35Ozd-1GsftDpcH\u0026q=85\u0026s=ca1d4c27f7c2811598e65cb25a21323c","dark":"https://mintcdn.com/ahasend/F35Ozd-1GsftDpcH/logo-dark.png?fit=max\u0026auto=format\u0026n=F35Ozd-1GsftDpcH\u0026q=85\u0026s=bb6b9068b30f93fd1ea216e2a7c1d137","href":"https://ahasend.com/"},"favicon":"https://mintcdn.com/ahasend/F35Ozd-1GsftDpcH/favicon.png?fit=max\u0026auto=format\u0026n=F35Ozd-1GsftDpcH\u0026q=85\u0026s=ac855c16b6cb74b8c5965d2e7ef3e324","appearance":{"strict":false},"navbar":{"links":[{"href":"https://dash.ahasend.com","label":"Login"}],"primary":{"type":"button","label":"Get Started","href":"https://dash.ahasend.com/user/register"}},"footer":{"socials":{"x":"https://x.com/aha_send","linkedin":"https://www.linkedin.com/company/ahasend","github":"https://github.com/ahasend"},"links":[{"header":"Resources","items":[{"label":"Pricing","href":"https://ahasend.com/pricing"},{"label":"Support","href":"mailto:support@ahasend.com"},{"label":"Status","href":"https://status.ahasend.com"},{"label":"Security","href":"https://ahasend.com/security"}]},{"header":"Company","items":[{"label":"Blog","href":"https://ahasend.com/blog"},{"label":"Feedback Board","href":"https://ahasend.sleekplan.app/"}]},{"header":"Legal","items":[{"label":"Imprint","href":"https://ahasend.com/imprint"},{"label":"Terms of Service","href":"https://ahasend.com/terms"},{"label":"Privacy Policy","href":"https://ahasend.com/privacy"},{"label":"Data Processing Agreement","href":"https://ahasend.com/dpa"}]}]},"seo":{"metatags":{"canonical":"https://ahasend.com/docs","twitter:site":"@aha_send"},"organization":{"name":"AhaSend","legalName":"AhaSend B.V.","url":"https://ahasend.com","sameAs":["https://x.com/aha_send","https://www.linkedin.com/company/ahasend","https://github.com/ahasend"]}},"integrations":{"telemetry":{"enabled":true},"cookies":{"key":"cookieConsent","value":"true"}},"errors":{"404":{"redirect":true}},"contextual":{"options":["copy","view","chatgpt","claude"],"display":"header"},"thumbnails":{"appearance":"dark","background":"https://mintcdn.com/ahasend/Gpf8BnLpzpIKQ4dU/images/social-background.svg?fit=max\u0026auto=format\u0026n=Gpf8BnLpzpIKQ4dU\u0026q=85\u0026s=df32e1edef517352b8437c75feecbf6e"},"markdown":{"instructions":["AhaSend stores all message data in the EU. See /facts.","The API base URL is https://api.ahasend.com. Send the API key in the Authorization: Bearer header. See /api-reference/authentication.","Use send.ahasend.com for SMTP. Ports 25, 587 and 2525 use STARTTLS. Port 465 is not supported. See /smtp.","For send-only integrations, create an API Key v2 under Credentials → Add and scope it to messages:send:{your-domain}. See /send-api/credentials and /api-reference/scopes."]},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"ahasend","hasAudioNarration":false,"actualSubdomain":"ahasend","customDomains":["ahasend.com"],"gitSource":{"type":"github","owner":"ahasend","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae676bdbfc5f43dec480549","collectionId":"3ae1f8a4-6f5e-450f-b047-b31a038b1ee5","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae676bdbfc5f43dec480549"},"feedback":{"thumbs":true},"entitlements":{},"buildId":"6ae676bdbfc5f43dec480549","clientVersion":"0.0.4044","searchFilterCounts":[{"language":"default","tag":"API Reference","count":148},{"language":"default","tag":"API reference","count":114},{"language":"default","tag":"Documentation","count":68},{"language":"default","tag":"Guides","count":52},{"language":"default","tag":"Integrations","count":41},{"language":"default","tag":"Webhooks","count":29},{"language":"default","tag":"CLI","count":25},{"language":"default","tag":"Commands","count":15},{"language":"default","tag":"Domain Authentication","count":13},{"language":"default","tag":"Campaigns","count":12}]},"assistantConfig":{},"basePath":"/docs","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"privacy":{"consentBanner":{"enabled":false}},"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"#content-container table{display:table}#content-container table thead th{text-align:left}"},{"filePath":"roadmap.css","content":".rm{display:flex;flex-direction:column;gap:2.5rem;margin-top:1.5rem}.rm-head{display:flex;align-items:center;gap:.65rem;margin-bottom:1rem}.rm-badge{display:inline-flex;align-items:center;margin:0;border:0;font-size:.78rem;font-weight:600;letter-spacing:.02em;padding:.28rem .75rem;border-radius:999px;line-height:1}.rm-badge.is-active{background:#fdebd0;color:#854f0b}.rm-badge.is-planned{background:#e6f1fb;color:#0c447c}.rm-badge.is-shipped{background:#e1f5ee;color:#0f6e56}.rm-list{display:flex;flex-direction:column;gap:.65rem}.rm-card{display:flex;gap:.9rem;padding:.9rem 1.05rem;background:#fff;border:1px solid #e5e7eb;border-radius:.7rem;transition:transform .15s ease,box-shadow .15s ease}.rm-card:hover{transform:translateY(-1px);box-shadow:0 4px 14px rgba(0,0,0,.06)}.rm-accent{flex:0 0 3px;border-radius:2px}.rm-card.is-active .rm-accent{background:#ba7517}.rm-card.is-planned .rm-accent{background:#378add}.rm-card.is-shipped .rm-accent{background:#1d9e75}.rm-card.is-sub{margin-left:2rem;position:relative}.rm-card p,.rm-card.is-sub .rm-title{font-size:.9rem}.rm-card.is-sub::after,.rm-card.is-sub::before{content:\"\";position:absolute;left:-1.15rem;pointer-events:none}.rm-card.is-sub::before{top:-.65rem;height:calc(100% + .65rem);border-left:1.5px solid #d1d5db}.rm-card.is-sub::after{top:50%;width:.85rem;border-top:1.5px solid #d1d5db}.rm-card .rm-title{margin:0 0 .2rem;font-size:.97rem;font-weight:600;line-height:1.35;color:#111827}.rm-card p{margin:0;line-height:1.55;color:#4b5563}.rm-date,.rm-tag{display:inline-block}.rm-date{margin-top:.5rem;font-size:.78rem;font-weight:600;color:#0f6e56}.rm-tag{margin-left:.5rem;font-size:.66rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:.16rem .5rem;border-radius:999px;vertical-align:middle;line-height:1.4;color:#fff;box-shadow:0 1px 2px rgba(0,0,0,.15)}.rm-tag.is-new{background:#6d28d9}.rm-tag.is-product{background:#be123c}.rm-tag.is-improvement{background:#0e7490}.rm-tag.is-early{background:#1d4ed8}.rm-tag.is-bugfix{background:#c2410c}.dark .rm-card{background:rgba(255,255,255,.025);border-color:rgba(255,255,255,.09)}.dark .rm-card p{color:#9ca3af}.dark .rm-badge.is-active{background:rgba(186,117,23,.18);color:#fac074}.dark .rm-badge.is-planned{background:rgba(55,138,221,.18);color:#85b7eb}.dark .rm-badge.is-shipped{background:rgba(29,158,117,.18);color:#5dcaa5}.dark .rm-date{color:#5dcaa5}.dark .rm-card.is-sub::after,.dark .rm-card.is-sub::before{border-color:rgba(255,255,255,.18)}.rm-note{margin-top:2.5rem;font-size:.85rem;color:#6b7280}.dark .rm-note{color:#9ca3af}.dark .rm-card .rm-title{color:#e7e9ee}.rm-jump{margin:-.5rem 0 0;font-size:.88rem}.rm-jump a{color:#2296ff;text-decoration:none;font-weight:500}.rm-jump a:hover{text-decoration:underline}.rm-badge[id]{scroll-margin-top:6rem}"}],"page":{"pagePath":"api-reference/campaigns/create-campaign","slug":"/api-reference/campaigns/create-campaign","pageMetadata":{"title":"Create a Campaign via the API","sidebarTitle":"Create Campaign","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaigns","description":"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.","href":"/api-reference/campaigns/create-campaign"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{Heading}=_components;if(!Heading)_missingMdxReference(`Heading`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`The AhaSend API creates a draft marketing campaign. Access requires `,_jsx(_components.code,{children:`campaigns:write`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Only `,_jsx(_components.code,{children:`name`}),` is required. You can set all other fields in this request, or later with `,_jsx(_components.a,{href:`/api-reference/campaigns/update-campaign`,children:`Update Campaign`}),`. The response gives `,_jsx(_components.code,{children:`ready`}),` and `,_jsx(_components.code,{children:`issues`}),`: while the campaign has issues, it cannot be sent. See `,_jsx(_components.a,{href:`/api-reference/campaigns/overview#issues`,children:`Issues`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Design:`}),`\nThe design comes from one source:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`content.mjml`}),` creates an `,_jsx(_components.code,{children:`advanced`}),` design, and `,_jsx(_components.code,{children:`content.html`}),` creates an `,_jsx(_components.code,{children:`html`}),` design. `,_jsx(_components.code,{children:`content.markup`}),` creates a `,_jsx(_components.code,{children:`simple`}),` design from `,_jsx(_components.a,{href:`/send-api/ahaml`,children:`AhaML`}),`: a `,_jsx(_components.code,{children:`content.html`}),` beside it is ignored, and a `,_jsx(_components.code,{children:`content.mjml`}),` beside it is refused. With `,_jsx(_components.code,{children:`content`}),` that has none of them, set `,_jsx(_components.code,{children:`editor`}),`. An `,_jsx(_components.code,{children:`editor`}),` that does not agree with the content is refused.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`editor`}),` without `,_jsx(_components.code,{children:`content`}),` creates an empty design, which you can complete in the dashboard’s editor.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`template_id`}),` copies the design of a `,_jsx(_components.a,{href:`/api-reference/campaign-templates/create-campaign-template`,children:`campaign template`}),`. The copy belongs to the campaign: later changes to the campaign template do not change it. A campaign template with no HTML is refused. A `,_jsx(_components.code,{children:`template_id`}),` that names no campaign template of your account is refused with `,_jsx(_components.code,{children:`400`}),` `,_jsx(_components.code,{children:`campaign template not found`}),`. `,_jsx(_components.code,{children:`template_id`}),` cannot go with `,_jsx(_components.code,{children:`editor`}),` or `,_jsx(_components.code,{children:`content`}),`.`]}),`\n`,_jsx(_components.li,{children:`Without any of them, the campaign has no design yet.`}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Content rules:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`MJML must pass strict validation. For a validation error, the message gives the line of each problem.`}),`\n`,_jsxs(_components.li,{children:[`AhaML must follow the `,_jsx(_components.a,{href:`/send-api/ahaml`,children:`AhaML rules`}),`. A refused write lists the problems in `,_jsx(_components.code,{children:`errors`}),`, each with its line and column when it has a place in the AhaML. See `,_jsx(_components.a,{href:`/send-api/ahaml#errors`,children:`AhaML errors`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`In MJML and HTML, images and stylesheets must use full `,_jsx(_components.code,{children:`https://`}),` URLs, such as `,_jsx(_components.code,{children:`https://example.com/logo.png`}),`. The API refuses relative paths, such as `,_jsx(_components.code,{children:`images/logo.png`}),`, and `,_jsx(_components.code,{children:`http:`}),`, `,_jsx(_components.code,{children:`//`}),`, `,_jsx(_components.code,{children:`data:`}),`, `,_jsx(_components.code,{children:`cid:`}),` and other schemes. A URL that starts with a template variable, such as `,_jsx(_components.code,{children:`{{ logo_url }}`}),`, is allowed. AhaML URLs follow the `,_jsx(_components.a,{href:`/send-api/ahaml#urls`,children:`AhaML URL rules`}),`. The API cannot upload files.`]}),`\n`,_jsx(_components.li,{children:`The MJML, the HTML, the AhaML and a text written by hand can each be at most 200 KB.`}),`\n`,_jsxs(_components.li,{children:[`The HTML must have an unsubscribe link before you can send the campaign. In AhaML, write it as `,_jsx(_components.code,{children:`\u003cLink href=\"{{ unsubscribe_url }}\">…\u003c/Link>`}),`. See `,_jsx(_components.a,{href:`/api-reference/campaigns/overview#unsubscribe-link`,children:`Unsubscribe link`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Sender, subject and audience:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`from.email`}),` must be on a domain of your account with valid DNS records. A paused domain is accepted here, but Send Campaign and Test Campaign refuse it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`reply_to`}),` is an address only, without a display name.`]}),`\n`,_jsxs(_components.li,{children:[`In `,_jsx(_components.code,{children:`subject`}),` and `,_jsx(_components.code,{children:`preheader`}),`, line breaks become spaces, and spaces at the start and end are removed. An empty subject or preview text counts as none.`]}),`\n`,_jsx(_components.li,{children:`The API checks the subject, the preview text, the sender and the reply-to by the same rules as the dashboard, and its error messages use the same words.`}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`list_ids`}),` and `,_jsx(_components.code,{children:`segment_ids`}),` hold the lists and segments of your account to send to. `,_jsx(_components.code,{children:`exclude_list_ids`}),` and `,_jsx(_components.code,{children:`exclude_segment_ids`}),` hold the lists and segments whose contacts get no message. A list or segment that you give twice counts once. See `,_jsx(_components.a,{href:`/api-reference/campaigns/overview#audience`,children:`Audience`}),` for the rules.`]}),`\n`,_jsxs(_components.li,{children:[`An audience field that you send must leave the campaign at least one list or segment to send to, so `,_jsx(_components.code,{children:`list_ids`}),` can be `,_jsx(_components.code,{children:`[]`}),` with a segment in `,_jsx(_components.code,{children:`segment_ids`}),`. A list or segment that does not exist, more than 50 lists or 10 segments, or a list or segment that is both included and excluded is refused with `,_jsx(_components.code,{children:`400`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`To find the ID of a list or a segment, use `,_jsx(_components.a,{href:`/api-reference/lists/get-lists`,children:`List Lists`}),` or `,_jsx(_components.a,{href:`/api-reference/segments/get-segments`,children:`List Segments`}),`, or see `,_jsx(_components.a,{href:`/api-reference/campaigns/overview#build-and-send-a-campaign`,children:`where to find the ID`}),` in the dashboard.`]}),`\n`,_jsxs(_components.li,{children:[`When a segment of the audience is being built again, the API answers `,_jsx(_components.code,{children:`409`}),` with `,_jsx(_components.code,{children:`The campaign's audience is being updated. Try again in a minute.`}),` This refusal is stored for the `,_jsx(_components.code,{children:`Idempotency-Key`}),`, so retry with a new key.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`This operation accepts an `,_jsx(_components.code,{children:`Idempotency-Key`}),` header. See `,_jsx(_components.a,{href:`/api-reference/idempotency`,children:`Idempotency`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`related-guides`,children:`Related Guides`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/api-reference/authentication`,children:`API authentication`}),`, `,_jsx(_components.a,{href:`/api-reference/scopes`,children:`Permission scopes`}),`, `,_jsx(_components.a,{href:`/api-reference/idempotency`,children:`Idempotency`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/api-reference/campaigns/overview`,children:`Campaigns API overview`}),`, `,_jsx(_components.a,{href:`/api-reference/campaigns/test-campaign`,children:`Test Campaign`}),`, `,_jsx(_components.a,{href:`/api-reference/campaigns/send-campaign`,children:`Send Campaign`}),`, `,_jsx(_components.a,{href:`/api-reference/errors`,children:`API errors`}),`, `,_jsx(_components.a,{href:`/api-reference/rate-limits`,children:`API rate limits`}),`.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Create a Campaign via the API","sidebarTitle":"Create Campaign","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaigns","description":"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.","href":"/api-reference/campaigns/create-campaign"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Related Guides","slug":"related-guides","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/ahasend/2374706ad872d133/ahasend-utm.js"],"openApiReferenceData":{"operation":{"summary":"Create Campaign","description":"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.","operationId":"createCampaign","tags":["Campaigns"],"parameters":["fc0f7377-3bf7-4378-b658-dcbdf82d327d","df51197f-cb41-4e60-a3f6-91a6b972b5a9"],"security":["e2988ccb-01b3-4c01-b58e-48731f963186"],"requestBody":"dadf168e-c533-47a5-ac84-566b27dd25ba","responses":{"201":"5ca8031d-0f44-4e49-aafe-459dfd239420","400":"b8bf1655-3537-4599-a65a-ae4c0c02b52e","401":"b770fc38-0d81-4a5c-a793-5a5a5acd4653","403":"7d7bd992-4f14-40ef-af90-e92de7681dcd","409":"eb4f606d-13f5-4359-9ff3-c2d3080c3497","422":"a0c68f83-0f87-4b33-82ef-0c1ce5c33fa2","429":"70d3d7c3-14df-4ca5-b8b4-798965d59a15","500":"42f4e27e-bd25-433f-84ed-73b258ef1fba","503":"ecd2efdc-35f0-496c-b895-323d76cbec0b"},"x-code-samples":[{"lang":"go","label":"AhaSend Go SDK","source":"package main\n\nimport (\n \"context\"\n \"fmt\"\n \"log\"\n \"os\"\n\n \"github.com/AhaSend/ahasend-go\"\n \"github.com/AhaSend/ahasend-go/api\"\n \"github.com/AhaSend/ahasend-go/models/common\"\n \"github.com/AhaSend/ahasend-go/models/requests\"\n \"github.com/google/uuid\"\n)\n\nfunc main() {\n client := api.NewAPIClient(api.WithAPIKey(os.Getenv(\"AHASEND_API_KEY\")))\n accountID := uuid.MustParse(os.Getenv(\"AHASEND_ACCOUNT_ID\"))\n ctx := context.Background()\n\n listID := uuid.MustParse(\"22222222-2222-4222-8222-222222222222\")\n templateID := uuid.MustParse(\"33333333-3333-4333-8333-333333333333\")\n\n // The campaign copies the campaign template's design; later changes to\n // the template do not reach it. Every field but Name can be set later.\n response, _, err := client.CampaignsAPI.CreateCampaign(ctx, accountID, requests.CreateCampaignRequest{\n Name: \"October newsletter\",\n Subject: ahasend.String(\"Our news for October, {{ first_name }}\"),\n Preheader: ahasend.String(\"Three things we shipped this month\"),\n From: \u0026common.SenderAddress{\n Email: \"news@yourdomain.com\",\n Name: ahasend.String(\"Example\"),\n },\n ListIDs: []uuid.UUID{listID},\n TemplateID: \u0026templateID,\n })\n if err != nil {\n log.Fatalf(\"Error creating campaign: %v\", err)\n }\n fmt.Printf(\"Created campaign %s, ready: %t\\n\", response.ID, response.Ready != nil \u0026\u0026 *response.Ready)\n}\n"},{"lang":"javascript","label":"Node.js 22+ (AhaSend SDK)","source":"import { AhaSendClient } from \"@ahasend/sdk\";\n\nconst client = AhaSendClient.fromEnv();\n// The SDK sends a fresh Idempotency-Key automatically and reuses it on its own retries.\nconst campaign = await client.campaigns.create({\n name: \"October newsletter\",\n subject: \"What is new in October\",\n preheader: \"Three things we shipped this month\",\n from: { email: \"news@example.com\", name: \"Example\" },\n list_ids: [\"00000000-0000-4000-8000-000000000010\"],\n template_id: \"00000000-0000-4000-8000-000000000013\",\n});\nconsole.log(\"Campaign created.\", { id: campaign.id, ready: campaign.ready });\n"}],"method":"post","type":"path","servers":["b5fdc511-65a3-4ae3-b4c1-31f6415bb096"],"path":"/v2/accounts/{account_id}/campaigns","baseUrlOptions":["https://api.ahasend.com"],"title":"Create Campaign","codeSamples":[{"label":"AhaSend Go SDK","lang":"go","source":"package main\n\nimport (\n \"context\"\n \"fmt\"\n \"log\"\n \"os\"\n\n \"github.com/AhaSend/ahasend-go\"\n \"github.com/AhaSend/ahasend-go/api\"\n \"github.com/AhaSend/ahasend-go/models/common\"\n \"github.com/AhaSend/ahasend-go/models/requests\"\n \"github.com/google/uuid\"\n)\n\nfunc main() {\n client := api.NewAPIClient(api.WithAPIKey(os.Getenv(\"AHASEND_API_KEY\")))\n accountID := uuid.MustParse(os.Getenv(\"AHASEND_ACCOUNT_ID\"))\n ctx := context.Background()\n\n listID := uuid.MustParse(\"22222222-2222-4222-8222-222222222222\")\n templateID := uuid.MustParse(\"33333333-3333-4333-8333-333333333333\")\n\n // The campaign copies the campaign template's design; later changes to\n // the template do not reach it. Every field but Name can be set later.\n response, _, err := client.CampaignsAPI.CreateCampaign(ctx, accountID, requests.CreateCampaignRequest{\n Name: \"October newsletter\",\n Subject: ahasend.String(\"Our news for October, {{ first_name }}\"),\n Preheader: ahasend.String(\"Three things we shipped this month\"),\n From: \u0026common.SenderAddress{\n Email: \"news@yourdomain.com\",\n Name: ahasend.String(\"Example\"),\n },\n ListIDs: []uuid.UUID{listID},\n TemplateID: \u0026templateID,\n })\n if err != nil {\n log.Fatalf(\"Error creating campaign: %v\", err)\n }\n fmt.Printf(\"Created campaign %s, ready: %t\\n\", response.ID, response.Ready != nil \u0026\u0026 *response.Ready)\n}\n"},{"label":"Node.js 22+ (AhaSend SDK)","lang":"javascript","source":"import { AhaSendClient } from \"@ahasend/sdk\";\n\nconst client = AhaSendClient.fromEnv();\n// The SDK sends a fresh Idempotency-Key automatically and reuses it on its own retries.\nconst campaign = await client.campaigns.create({\n name: \"October newsletter\",\n subject: \"What is new in October\",\n preheader: \"Three things we shipped this month\",\n from: { email: \"news@example.com\", name: \"Example\" },\n list_ids: [\"00000000-0000-4000-8000-000000000010\"],\n template_id: \"00000000-0000-4000-8000-000000000013\",\n});\nconsole.log(\"Campaign created.\", { id: campaign.id, ready: campaign.ready });\n"}],"requiredOnlyExamples":false,"requestExampleType":"codeSamples","responseExampleType":"generated"},"dependencies":{"parameters":{"fc0f7377-3bf7-4378-b658-dcbdf82d327d":{"name":"account_id","in":"path","required":true,"description":"Account ID","schema":{"type":"string","format":"uuid","isRequired":true,"description":"Account ID","uniqueKey":"","typeLabel":"string\u003cuuid>"}},"df51197f-cb41-4e60-a3f6-91a6b972b5a9":{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional idempotency key for safe request retries. Must be a unique string for each logical request.\nAn identical request with a completed stored outcome returns the original status and body. An in-progress\nexecution returns 409, a changed method/path/body returns 422, and a released 5xx execution may run again.\nKeys for non-secret responses expire after 24 hours. API-key create responses include a one-time `secret_key`,\nso successful encrypted replay responses for those operations expire after 5 minutes.\n","schema":{"type":"string","maxLength":255,"isRequired":false,"description":"Optional idempotency key for safe request retries. Must be a unique string for each logical request.\nAn identical request with a completed stored outcome returns the original status and body. An in-progress\nexecution returns 409, a changed method/path/body returns 422, and a released 5xx execution may run again.\nKeys for non-secret responses expire after 24 hours. API-key create responses include a one-time `secret_key`,\nso successful encrypted replay responses for those operations expire after 5 minutes.\n","uniqueKey":"","typeLabel":"string"},"example":"user-12345-create-domain-20240101"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"description":"A new draft campaign. Every field but `name` can be set later with\nUpdate Campaign. The design comes from at most one source: an\n`editor`, `content`, both, or a `template_id`. With none of them the\ncampaign has no design yet.\n","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Campaign name. Spaces around it are dropped.","isRequired":true,"uniqueKey":"name","typeLabel":"string"},"subject":{"oneOf":[{"type":"string","description":"The subject line. Line breaks become spaces and spaces around it are dropped; an empty subject is no subject.","uniqueKey":"subject.oneOf.0","typeLabel":"string"},{"type":"null","description":"The subject line. Line breaks become spaces and spaces around it are dropped; an empty subject is no subject.","uniqueKey":"subject.oneOf.1","typeLabel":"null"}],"uniqueKey":"subject","typeLabel":"string | null"},"preheader":{"oneOf":[{"type":"string","description":"The preview text, cleaned as `subject` is.","uniqueKey":"preheader.oneOf.0","typeLabel":"string"},{"type":"null","description":"The preview text, cleaned as `subject` is.","uniqueKey":"preheader.oneOf.1","typeLabel":"null"}],"uniqueKey":"preheader","typeLabel":"string | null"},"from":{"oneOf":[{"type":"object","description":"The sender. `email` must be on a domain of this account with valid DNS. A paused domain is accepted here and refused when the campaign is sent.","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"The email address.","isRequired":true,"uniqueKey":"from.oneOf.0.email","typeLabel":"string\u003cemail>"},"name":{"type":"string","description":"The display name.","uniqueKey":"from.oneOf.0.name","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"from.oneOf.0","typeLabel":"object"},{"type":"null","description":"The sender. `email` must be on a domain of this account with valid DNS. A paused domain is accepted here and refused when the campaign is sent.","uniqueKey":"from.oneOf.1","typeLabel":"null"}],"uniqueKey":"from","typeLabel":"object | null"},"reply_to":{"oneOf":[{"type":"string","format":"email","description":"The reply-to address, an address only, without a display name.","uniqueKey":"reply_to.oneOf.0","typeLabel":"string\u003cemail>"},{"type":"null","format":"email","description":"The reply-to address, an address only, without a display name.","uniqueKey":"reply_to.oneOf.1","typeLabel":"null"}],"uniqueKey":"reply_to","typeLabel":"string\u003cemail> | null"},"list_ids":{"type":"array","maxItems":50,"items":{"type":"string","format":"uuid","uniqueKey":"list_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"The lists to send to, in order. A list named twice counts once.\nEach must be a list of this account. A campaign uses at most 50\nlists and 10 segments, included and excluded together, and an\naudience field that is set must leave it at least one list or\nsegment to send to, so `[]` is accepted with `segment_ids`.\n","uniqueKey":"list_ids","typeLabel":"string\u003cuuid>[]"},"segment_ids":{"type":"array","maxItems":10,"items":{"type":"string","format":"uuid","uniqueKey":"segment_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"The segments to send to. A segment named twice counts once. Each must be a segment of this account. A contact reached through a list and a segment gets one message, recorded under the list. Responses return the segments by ID.","uniqueKey":"segment_ids","typeLabel":"string\u003cuuid>[]"},"exclude_list_ids":{"type":"array","maxItems":50,"items":{"type":"string","format":"uuid","uniqueKey":"exclude_list_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"Lists whose contacts get no message from the campaign. A contact with any membership of one, whatever its status, is left out, also when an included list or segment reaches it. A list cannot be both in `list_ids` and here. Exclusions need at least one list or segment to send to. Responses return the lists by ID.","uniqueKey":"exclude_list_ids","typeLabel":"string\u003cuuid>[]"},"exclude_segment_ids":{"type":"array","maxItems":10,"items":{"type":"string","format":"uuid","uniqueKey":"exclude_segment_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"Segments whose members get no message from the campaign, also when an included list or segment reaches them. A segment cannot be both in `segment_ids` and here. Exclusions need at least one list or segment to send to. Responses return the segments by ID.","uniqueKey":"exclude_segment_ids","typeLabel":"string\u003cuuid>[]"},"editor":{"type":"string","enum":["advanced","simple","html"],"description":"The editor of the design. Without `content` the campaign gets an empty design of this editor, which the dashboard's editor opens. With `content`, it is required when the content holds none of `markup`, `mjml` and `html`, and must agree with it otherwise; `markup` means `simple`, also beside `html`. Not accepted with `template_id`, whose editor the design keeps.","uniqueKey":"editor","typeLabel":"enum\u003cstring>"},"content":{"type":"object","additionalProperties":false,"description":"The content of the design, by the rules of `TemplateContentInput`. A campaign has no draft, so where those rules name the draft, they mean the campaign's design. Not accepted with `template_id`.","properties":{"mjml":{"type":"string","minLength":1,"description":"The MJML source. Only for `advanced` templates. It is compiled in\nstrict mode, and every problem strict validation finds is refused\nwith its line. Images must use full `https://` URLs: the API cannot\nupload files.\n","uniqueKey":"content.mjml","typeLabel":"string"},"html":{"type":"string","minLength":1,"description":"The HTML. Only for `html` templates; the HTML of a `simple`\ntemplate is made from its design, which `markup` changes, and is\naccepted only as described above. Images and stylesheets must use\nfull `https://` URLs: the API cannot upload files.\n","uniqueKey":"content.html","typeLabel":"string"},"text":{"oneOf":[{"type":"string","description":"The plain text version. Null makes it from the HTML.","uniqueKey":"content.text.oneOf.0","typeLabel":"string"},{"type":"null","description":"The plain text version. Null makes it from the HTML.","uniqueKey":"content.text.oneOf.1","typeLabel":"null"}],"uniqueKey":"content.text","typeLabel":"string | null"},"text_is_custom":{"type":"boolean","description":"Accepted so a read `content` can be sent back, and ignored. The text rules decide it.","uniqueKey":"content.text_is_custom","typeLabel":"boolean"},"markup":{"oneOf":[{"type":"string","description":"The design as AhaSend Markup (AhaML). Only for `simple` designs;\non a create, and on a campaign with no design yet, it means\n`editor: simple`. The stored design is the JSON and HTML read from\nit, and the answer lists warnings about it in `markup_warnings`.\nNull is the same as no `markup`, and an empty string is refused.\nThe writes that carry it count against a per-account limit, beside\nthe API's own rate limit.\n","example":"\u003cEmail version=\"1\">\n \u003cHeading level=\"3\">Welcome\u003c/Heading>\n \u003cParagraph>Thanks for signing up.\u003c/Paragraph>\n\u003c/Email>\n","uniqueKey":"content.markup.oneOf.0","typeLabel":"string"},{"type":"null","description":"The design as AhaSend Markup (AhaML). Only for `simple` designs;\non a create, and on a campaign with no design yet, it means\n`editor: simple`. The stored design is the JSON and HTML read from\nit, and the answer lists warnings about it in `markup_warnings`.\nNull is the same as no `markup`, and an empty string is refused.\nThe writes that carry it count against a per-account limit, beside\nthe API's own rate limit.\n","example":"\u003cEmail version=\"1\">\n \u003cHeading level=\"3\">Welcome\u003c/Heading>\n \u003cParagraph>Thanks for signing up.\u003c/Paragraph>\n\u003c/Email>\n","uniqueKey":"content.markup.oneOf.1","typeLabel":"null"}],"uniqueKey":"content.markup","typeLabel":"string | null"},"markup_error":{"description":"Accepted so a read `content` can be sent back, and ignored, whatever it holds.","uniqueKey":"content.markup_error","typeLabel":"any"}},"uniqueKey":"content","typeLabel":"object"},"template_id":{"type":"string","format":"uuid","description":"A campaign template whose design the campaign copies. The copy is the campaign's own; later changes to the template do not reach it. A campaign template with no HTML is refused.","uniqueKey":"template_id","typeLabel":"string\u003cuuid>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"name":"\u003cstring>","subject":"\u003cstring>","preheader":"\u003cstring>","from":{"email":"jsmith@example.com","name":"\u003cstring>"},"reply_to":"jsmith@example.com","list_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"segment_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"exclude_list_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"exclude_segment_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"content":{"mjml":"\u003cstring>","html":"\u003cstring>","text":"\u003cstring>","text_is_custom":true,"markup":"\u003cEmail version=\"1\">\n \u003cHeading level=\"3\">Welcome\u003c/Heading>\n \u003cParagraph>Thanks for signing up.\u003c/Paragraph>\n\u003c/Email>\n","markup_error":"\u003cunknown>"},"template_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a"}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"5ca8031d-0f44-4e49-aafe-459dfd239420":{"description":"Campaign created","headers":{"Idempotent-Replayed":{"description":"Indicates that this response is a stored replay of a previous identical request.\nWhen this header is absent, the response is not a stored replay. Ordinary fresh\nresponses do not send `false`; that value is reserved for an in-progress 409.\n","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"type":"object","description":"A campaign as List Campaigns returns it, without its audience, content and issues.","required":["list_ids","segment_ids","exclude_list_ids","exclude_segment_ids","editor","content","ready","issues","object","id","created_at","updated_at","name","subject","preheader","from","reply_to","status","status_reason","send_at","send_resumes_at","finished_at"],"properties":{"object":{"type":"string","enum":["campaign"],"description":"Object type identifier","isRequired":true,"uniqueKey":"object","typeLabel":"enum\u003cstring>"},"id":{"type":"string","format":"uuid","description":"Campaign ID","isRequired":true,"uniqueKey":"id","typeLabel":"string\u003cuuid>"},"created_at":{"type":"string","format":"date-time","description":"When the campaign was created","isRequired":true,"uniqueKey":"created_at","typeLabel":"string\u003cdate-time>"},"updated_at":{"type":"string","format":"date-time","description":"When the campaign's own fields last changed","isRequired":true,"uniqueKey":"updated_at","typeLabel":"string\u003cdate-time>"},"name":{"type":"string","description":"Campaign name, as it appears in the dashboard. Recipients do not see it.","isRequired":true,"uniqueKey":"name","typeLabel":"string"},"subject":{"oneOf":[{"type":"string","description":"The subject line. Null until one is set.","isRequired":true,"uniqueKey":"subject.oneOf.0","typeLabel":"string"},{"type":"null","description":"The subject line. Null until one is set.","isRequired":true,"uniqueKey":"subject.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"subject","typeLabel":"string | null"},"preheader":{"oneOf":[{"type":"string","description":"The preview text, which most inboxes show after the subject. Null until one is set.","isRequired":true,"uniqueKey":"preheader.oneOf.0","typeLabel":"string"},{"type":"null","description":"The preview text, which most inboxes show after the subject. Null until one is set.","isRequired":true,"uniqueKey":"preheader.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"preheader","typeLabel":"string | null"},"from":{"oneOf":[{"type":"object","description":"The sender. Null until a complete sender is set, and when its domain was deleted. `name` is an empty string when the campaign has no sender name, so the object can be sent back as it is.","required":["email"],"example":{"email":"noreply@example.com","name":"Example Corp"},"properties":{"email":{"type":"string","format":"email","description":"The email address. A `from` address must be on a domain defined in your account with valid DNS records.","isRequired":true,"uniqueKey":"from.oneOf.0.email","typeLabel":"string\u003cemail>"},"name":{"type":"string","description":"The display name shown with the address. It can hold any Unicode text; the API encodes it for the header. On a send with substitutions or a template, a name with non-ASCII text can use `{{ name }}` references only; other template syntax in it is refused.","uniqueKey":"from.oneOf.0.name","typeLabel":"string"}},"isRequired":true,"uniqueKey":"from.oneOf.0","typeLabel":"object"},{"type":"null","description":"The sender. Null until a complete sender is set, and when its domain was deleted. `name` is an empty string when the campaign has no sender name, so the object can be sent back as it is.","isRequired":true,"uniqueKey":"from.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"from","typeLabel":"object | null"},"reply_to":{"oneOf":[{"type":"string","format":"email","description":"The reply-to address. Null when none is set.","isRequired":true,"uniqueKey":"reply_to.oneOf.0","typeLabel":"string\u003cemail>"},{"type":"null","format":"email","description":"The reply-to address. Null when none is set.","isRequired":true,"uniqueKey":"reply_to.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"reply_to","typeLabel":"string\u003cemail> | null"},"status":{"type":"string","enum":["draft","validating","waiting_for_review","scheduled","sending","paused","sent","canceled","failed"],"description":"Where the campaign is in its life. Only a `draft` can be changed or\ndeleted.\n\n- `draft`: being prepared.\n- `validating`: scheduled, and its lists and segments are being checked.\n- `waiting_for_review`: held for a review before it sends.\n- `scheduled`: accepted, waiting for its send time.\n- `sending`: sending now.\n- `paused`: sending stopped for now; `status_reason` says why.\n- `sent`: every message was sent.\n- `canceled`: stopped before it finished; `status_reason` says why.\n- `failed`: could not be sent; `status_reason` says why.\n","isRequired":true,"uniqueKey":"status","typeLabel":"enum\u003cstring>"},"status_reason":{"oneOf":[{"type":"string","description":"Why the campaign is in its status, when there is a reason to give. Null otherwise.","isRequired":true,"uniqueKey":"status_reason.oneOf.0","typeLabel":"string"},{"type":"null","description":"Why the campaign is in its status, when there is a reason to give. Null otherwise.","isRequired":true,"uniqueKey":"status_reason.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"status_reason","typeLabel":"string | null"},"send_at":{"oneOf":[{"type":"string","format":"date-time","description":"When the campaign sends or sent, in UTC. Null until it is scheduled.","isRequired":true,"uniqueKey":"send_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When the campaign sends or sent, in UTC. Null until it is scheduled.","isRequired":true,"uniqueKey":"send_at.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"send_at","typeLabel":"string\u003cdate-time> | null"},"send_resumes_at":{"oneOf":[{"type":"string","format":"date-time","description":"When a send that reached the account's daily marketing limit continues, in UTC. Null otherwise.","isRequired":true,"uniqueKey":"send_resumes_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When a send that reached the account's daily marketing limit continues, in UTC. Null otherwise.","isRequired":true,"uniqueKey":"send_resumes_at.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"send_resumes_at","typeLabel":"string\u003cdate-time> | null"},"finished_at":{"oneOf":[{"type":"string","format":"date-time","description":"When the send ended, in UTC. Null until then.","isRequired":true,"uniqueKey":"finished_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When the send ended, in UTC. Null until then.","isRequired":true,"uniqueKey":"finished_at.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"finished_at","typeLabel":"string\u003cdate-time> | null"},"list_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"list_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"The lists the campaign sends to, in the order they were saved. A list that was deleted is left out.","isRequired":true,"uniqueKey":"list_ids","typeLabel":"string\u003cuuid>[]"},"segment_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"segment_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"The segments the campaign sends to, by ID. A segment that was deleted is left out.","isRequired":true,"uniqueKey":"segment_ids","typeLabel":"string\u003cuuid>[]"},"exclude_list_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"exclude_list_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"The lists whose contacts the campaign does not send to, by ID. A contact with any membership of one of them, whatever its status, is left out. A list that was deleted is left out.","isRequired":true,"uniqueKey":"exclude_list_ids","typeLabel":"string\u003cuuid>[]"},"exclude_segment_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"exclude_segment_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"The segments whose members the campaign does not send to, by ID. A segment that was deleted is left out.","isRequired":true,"uniqueKey":"exclude_segment_ids","typeLabel":"string\u003cuuid>[]"},"editor":{"oneOf":[{"type":"string","description":"The editor of the campaign's design. Null while the campaign has no design.","enum":["advanced","simple","html"],"isRequired":true,"uniqueKey":"editor.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","description":"The editor of the campaign's design. Null while the campaign has no design.","isRequired":true,"uniqueKey":"editor.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"editor","typeLabel":"enum\u003cstring> | null"},"content":{"oneOf":[{"type":"object","description":"The content of the campaign's design. Null while it has no design, or its design has neither HTML nor text.","required":["text_is_custom"],"properties":{"text_is_custom":{"type":"boolean","description":"Whether the text was written rather than made from the HTML. A text made from the HTML is made again whenever the design changes.","isRequired":true,"uniqueKey":"content.oneOf.0.text_is_custom","typeLabel":"boolean"},"mjml":{"type":"string","description":"The MJML source. Only for `advanced` templates.","uniqueKey":"content.oneOf.0.mjml","typeLabel":"string"},"html":{"type":"string","description":"The HTML of an `html` template, or the HTML made from the design of a `simple` template.","uniqueKey":"content.oneOf.0.html","typeLabel":"string"},"text":{"type":"string","description":"The plain text version of the email.","uniqueKey":"content.oneOf.0.text","typeLabel":"string"},"markup":{"oneOf":[{"type":"string","description":"The design as AhaSend Markup (AhaML). Only for `simple` designs, and then always present. Null when AhaML cannot be made; `markup_error` then says why.","example":"\u003cEmail version=\"1\">\n \u003cHeading level=\"3\">Welcome\u003c/Heading>\n \u003cParagraph>Thanks for signing up.\u003c/Paragraph>\n\u003c/Email>\n","uniqueKey":"content.oneOf.0.markup.oneOf.0","typeLabel":"string"},{"type":"null","description":"The design as AhaSend Markup (AhaML). Only for `simple` designs, and then always present. Null when AhaML cannot be made; `markup_error` then says why.","example":"\u003cEmail version=\"1\">\n \u003cHeading level=\"3\">Welcome\u003c/Heading>\n \u003cParagraph>Thanks for signing up.\u003c/Paragraph>\n\u003c/Email>\n","uniqueKey":"content.oneOf.0.markup.oneOf.1","typeLabel":"null"}],"uniqueKey":"content.oneOf.0.markup","typeLabel":"string | null"},"markup_error":{"type":"object","required":["code","message"],"description":"Why `markup` is null. Only present when it is. In the answer to a write, it says only that the answer holds no AhaML; the write itself succeeded. A write answer replayed for its `Idempotency-Key` gives the `markup_error` of the first answer; read the object again to get its AhaML.","properties":{"code":{"type":"string","enum":["no_design","html_block","unmapped_block","bad_stored_value","renderer_unavailable","rate_limited"],"description":"- `no_design`: the design has no blocks yet.\n- `html_block`: the design holds an HTML block, which AhaML\n cannot show. Remove the block in the dashboard to read and\n write the design as AhaML.\n- `unmapped_block`: the design holds a block or a mark that\n AhaML has no tag for. The message names its type.\n- `bad_stored_value`: the design holds a value that AhaML\n cannot write. The message names the block and the attribute.\n- `renderer_unavailable`: AhaML cannot be made now. Read the\n design again later.\n- `rate_limited`: the account reads and writes AhaML more\n often than its limit allows. Read the design again in a\n second. A caller that does not use AhaML is never slowed\n by this limit.\n","isRequired":true,"uniqueKey":"content.oneOf.0.markup_error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"What went wrong, in words for a person.","isRequired":true,"uniqueKey":"content.oneOf.0.markup_error.message","typeLabel":"string"}},"example":{"code":"html_block","message":"The design holds an HTML block, which AhaML cannot show; remove the block in the dashboard to read and write the design as AhaML"},"uniqueKey":"content.oneOf.0.markup_error","typeLabel":"object"}},"isRequired":true,"uniqueKey":"content.oneOf.0","typeLabel":"object"},{"type":"null","description":"The content of the campaign's design. Null while it has no design, or its design has neither HTML nor text.","isRequired":true,"uniqueKey":"content.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"content","typeLabel":"object | null"},"ready":{"oneOf":[{"type":"boolean","description":"Whether the draft has no issue, so it can be sent. Null unless the campaign is a draft.","isRequired":true,"uniqueKey":"ready.oneOf.0","typeLabel":"boolean"},{"type":"null","description":"Whether the draft has no issue, so it can be sent. Null unless the campaign is a draft.","isRequired":true,"uniqueKey":"ready.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"ready","typeLabel":"boolean | null"},"issues":{"oneOf":[{"type":"array","items":{"type":"object","required":["code","message"],"description":"A reason the campaign cannot be sent yet.","properties":{"code":{"type":"string","enum":["sender_missing","lists_missing","subject_missing","preheader_missing","design_missing","text_broken","text_unchecked","unsubscribe_link_missing"],"description":"- `sender_missing`: the campaign has no complete sender, or its domain was deleted.\n- `lists_missing`: the campaign has no list or segment that still exists.\n- `subject_missing`: the campaign has no subject.\n- `preheader_missing`: the campaign has no preview text.\n- `design_missing`: the campaign has no design, or its design has no HTML.\n- `text_broken`: the subject, the preview text or the design holds template syntax that cannot be rendered, so every message would fail.\n- `text_unchecked`: the subject, the preview text and the design could not be checked right now. Nothing is wrong with them that is known; try again in a moment. Under load it can come and go between reads.\n- `unsubscribe_link_missing`: the HTML does not use `{{ unsubscribe_url }}`, with or without filters.\n","isRequired":true,"uniqueKey":"issues.oneOf.0.items.[INDEX].code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"What to do, in the words the dashboard uses.","isRequired":true,"uniqueKey":"issues.oneOf.0.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"issues.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The reasons the draft cannot be sent yet, in a fixed order; empty when it is ready. Null unless the campaign is a draft.","isRequired":true,"uniqueKey":"issues.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The reasons the draft cannot be sent yet, in a fixed order; empty when it is ready. Null unless the campaign is a draft.","isRequired":true,"uniqueKey":"issues.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"issues","typeLabel":"object[] | null"},"markup_warnings":{"type":"array","maxItems":100,"items":{"type":"object","description":"One problem of AhaSend Markup (AhaML) that a write refused, or one warning about AhaML a write stored.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong, as a code that stays the same. The AhaML reference\nlists every code. A warning's code is `jinja_in_text`: text holds\n`{{`, which stays text; use a `\u003cVar>` for a variable.\n","isRequired":true,"uniqueKey":"markup_warnings.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"What is wrong, in words for a person.","isRequired":true,"uniqueKey":"markup_warnings.items.[INDEX].message","typeLabel":"string"},"line":{"type":"integer","minimum":1,"description":"The line where the problem starts, counted from 1. Left out when the problem has no place in the AhaML, as for a size limit.","uniqueKey":"markup_warnings.items.[INDEX].line","typeLabel":"integer"},"column":{"type":"integer","minimum":1,"description":"The column where the problem starts, counted from 1 in Unicode characters. Left out with `line`.","uniqueKey":"markup_warnings.items.[INDEX].column","typeLabel":"integer"},"path":{"type":"string","description":"The element of the problem, each tag with its position among its siblings of the same tag, such as `Email > Section[2] > Paragraph[1]`. Left out with `line`.","uniqueKey":"markup_warnings.items.[INDEX].path","typeLabel":"string"},"hint":{"type":"string","description":"How to fix the problem, when a fix is known. Warnings have none.","uniqueKey":"markup_warnings.items.[INDEX].hint","typeLabel":"string"}},"uniqueKey":"markup_warnings.items.[INDEX]","typeLabel":"object"},"description":"Warnings about the AhaML in `content.markup`, up to the first 100; empty when there are none. Present only in the answer to a write that carried `content.markup`.","uniqueKey":"markup_warnings","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"object":"campaign","id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","created_at":"2023-11-07T05:31:56Z","updated_at":"2023-11-07T05:31:56Z","name":"\u003cstring>","subject":"\u003cstring>","preheader":"\u003cstring>","from":{"email":"noreply@example.com","name":"Example Corp"},"reply_to":"jsmith@example.com","status":"draft","status_reason":"\u003cstring>","send_at":"2023-11-07T05:31:56Z","send_resumes_at":"2023-11-07T05:31:56Z","finished_at":"2023-11-07T05:31:56Z","list_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"segment_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"exclude_list_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"exclude_segment_ids":["3c90c3cc-0d44-4b50-8888-8dd25736052a"],"editor":"advanced","content":{"text_is_custom":true,"mjml":"\u003cstring>","html":"\u003cstring>","text":"\u003cstring>","markup":"\u003cEmail version=\"1\">\n \u003cHeading level=\"3\">Welcome\u003c/Heading>\n \u003cParagraph>Thanks for signing up.\u003c/Paragraph>\n\u003c/Email>\n","markup_error":{"code":"html_block","message":"The design holds an HTML block, which AhaML cannot show; remove the block in the dashboard to read and write the design as AhaML"}},"ready":true,"issues":[{"code":"sender_missing","message":"\u003cstring>"}],"markup_warnings":[{"code":"\u003cstring>","message":"\u003cstring>","line":2,"column":2,"path":"\u003cstring>","hint":"\u003cstring>"}]}}},"exampleType":"generated"}},"exampleType":"generated"},"b8bf1655-3537-4599-a65a-ae4c0c02b52e":{"description":"Invalid request: the body or a field, a list, segment or campaign template that does not exist, too many lists or segments, or an audience with no list or segment to send to. The message names the field and the problem. Refused AhaML in `content.markup` also lists its problems in `errors`.","content":{"application/json":{"schema":{"type":"object","description":"The 400 answer of a write that takes `content.markup`. Every 400 of\nsuch a write has `message`. When the write refuses AhaSend Markup\n(AhaML), `errors` lists the problems found, in document order, up to\nthe first 100, and `message` says how many there are in all.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description. For refused AhaML, how many problems it has.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"errors":{"type":"array","maxItems":100,"items":{"type":"object","description":"One problem of AhaSend Markup (AhaML) that a write refused, or one warning about AhaML a write stored.","required":["code","message"],"properties":{"code":{"type":"string","description":"What is wrong, as a code that stays the same. The AhaML reference\nlists every code. A warning's code is `jinja_in_text`: text holds\n`{{`, which stays text; use a `\u003cVar>` for a variable.\n","isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"string"},"message":{"type":"string","description":"What is wrong, in words for a person.","isRequired":true,"uniqueKey":"errors.items.[INDEX].message","typeLabel":"string"},"line":{"type":"integer","minimum":1,"description":"The line where the problem starts, counted from 1. Left out when the problem has no place in the AhaML, as for a size limit.","uniqueKey":"errors.items.[INDEX].line","typeLabel":"integer"},"column":{"type":"integer","minimum":1,"description":"The column where the problem starts, counted from 1 in Unicode characters. Left out with `line`.","uniqueKey":"errors.items.[INDEX].column","typeLabel":"integer"},"path":{"type":"string","description":"The element of the problem, each tag with its position among its siblings of the same tag, such as `Email > Section[2] > Paragraph[1]`. Left out with `line`.","uniqueKey":"errors.items.[INDEX].path","typeLabel":"string"},"hint":{"type":"string","description":"How to fix the problem, when a fix is known. Warnings have none.","uniqueKey":"errors.items.[INDEX].hint","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"description":"The problems of refused AhaML. Left out for every other 400.","uniqueKey":"errors","typeLabel":"object[]"}},"example":{"message":"content.markup has 1 problem","errors":[{"code":"unknown_attribute","message":"Paragraph has no attribute \"color\"","line":4,"column":14,"path":"Email > Section[2] > Paragraph[1]","hint":"wrap the text in \u003cColor value=\"...\"> instead"}]},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"content.markup has 1 problem","errors":[{"code":"unknown_attribute","message":"Paragraph has no attribute \"color\"","line":4,"column":14,"path":"Email > Section[2] > Paragraph[1]","hint":"wrap the text in \u003cColor value=\"...\"> instead"}]}}},"exampleType":"generated"}},"exampleType":"generated"},"b770fc38-0d81-4a5c-a793-5a5a5acd4653":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","description":"Human-readable API error. The server currently sends no stable machine\nerror code. In particular, clients must not parse `message` to\ndistinguish IP-allow-list, scope, ownership, plan, self-lockout,\nsuppression-duplicate, or other errors that share an HTTP status.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"example":{"message":"Error message"},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"Error message"}}},"exampleType":"generated"}},"exampleType":"generated"},"7d7bd992-4f14-40ef-af90-e92de7681dcd":{"description":"Missing `campaigns:write` scope","content":{"application/json":{"schema":{"type":"object","description":"Human-readable API error. The server currently sends no stable machine\nerror code. In particular, clients must not parse `message` to\ndistinguish IP-allow-list, scope, ownership, plan, self-lockout,\nsuppression-duplicate, or other errors that share an HTTP status.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"example":{"message":"Error message"},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"Error message"}}},"exampleType":"generated"}},"exampleType":"generated"},"eb4f606d-13f5-4359-9ff3-c2d3080c3497":{"description":"Either a segment of the new campaign's audience is being rebuilt\n(`The campaign's audience is being updated. Try again in a\nminute.`), or an execution with this idempotency key is still in\nprogress. The in-progress case is identified only by\n`Idempotent-Replayed: false` plus a positive integer `Retry-After`;\nretry it after that many seconds with the same key. The audience\nrefusal is stored for the `Idempotency-Key` like other client\nerrors: an identical request with the same key replays it with\n`Idempotent-Replayed: true` for 24 hours, so retry it with a new\nkey. A fresh refusal has neither header. The message is not a\nstable discriminator.\n","headers":{"Idempotent-Replayed":{"description":"`false` with a positive `Retry-After` means an execution is in\nprogress. `true` means a stored 409 was replayed. Absent means a\nfresh refusal.\n","schema":{"type":"string","enum":["true","false"]}},"Retry-After":{"description":"Positive whole number of seconds after which the in-progress execution\nlease may be retried with the same key and unchanged request.\n","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","description":"Human-readable API error. The server currently sends no stable machine\nerror code. In particular, clients must not parse `message` to\ndistinguish IP-allow-list, scope, ownership, plan, self-lockout,\nsuppression-duplicate, or other errors that share an HTTP status.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"example":{"message":"Error message"},"uniqueKey":"","typeLabel":"object"},"example":{"message":"The campaign's audience is being updated. Try again in a minute."},"examples":{"Example":{"title":"Example","value":{"message":"The campaign's audience is being updated. Try again in a minute."}}},"exampleType":"examples"}},"exampleType":"examples"},"a0c68f83-0f87-4b33-82ef-0c1ce5c33fa2":{"description":"Idempotency key was already used with a different HTTP method, resolved\nrequest path, or request body. This response includes neither\n`Idempotent-Replayed` nor `Retry-After`.\n","content":{"application/json":{"schema":{"type":"object","description":"Human-readable API error. The server currently sends no stable machine\nerror code. In particular, clients must not parse `message` to\ndistinguish IP-allow-list, scope, ownership, plan, self-lockout,\nsuppression-duplicate, or other errors that share an HTTP status.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"example":{"message":"Error message"},"uniqueKey":"","typeLabel":"object"},"example":{"message":"idempotency key was already used with a different request payload"},"examples":{"Example":{"title":"Example","value":{"message":"idempotency key was already used with a different request payload"}}},"exampleType":"examples"}},"exampleType":"examples"},"70d3d7c3-14df-4ca5-b8b4-798965d59a15":{"description":"Too many requests: the API's rate limit, or the limit on writes that carry `content.markup`. A 429 is not stored for the `Idempotency-Key`, so a retry may use the same key.","content":{"application/json":{"schema":{"type":"object","description":"Human-readable API error. The server currently sends no stable machine\nerror code. In particular, clients must not parse `message` to\ndistinguish IP-allow-list, scope, ownership, plan, self-lockout,\nsuppression-duplicate, or other errors that share an HTTP status.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"example":{"message":"Error message"},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"Error message"}}},"exampleType":"generated"}},"exampleType":"generated"},"42f4e27e-bd25-433f-84ed-73b258ef1fba":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","description":"Human-readable API error. The server currently sends no stable machine\nerror code. In particular, clients must not parse `message` to\ndistinguish IP-allow-list, scope, ownership, plan, self-lockout,\nsuppression-duplicate, or other errors that share an HTTP status.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"example":{"message":"Error message"},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"Error message"}}},"exampleType":"generated"}},"exampleType":"generated"},"ecd2efdc-35f0-496c-b895-323d76cbec0b":{"description":"The write could not be finished now, for one of two reasons. Nothing\nwas written.\n\n- The template or campaign changed in the dashboard or through\n another request while this one was writing it. Only a write of a\n transactional template that already exists, after it retried by\n itself, and an update of a campaign whose body changed, can get\n this.\n- AhaSend Markup (AhaML) in `content.markup` could not be read now:\n the service that reads it is down, failed or busy.\n\nRetry after `Retry-After` seconds, with the same `Idempotency-Key`.\n","headers":{"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","description":"Human-readable API error. The server currently sends no stable machine\nerror code. In particular, clients must not parse `message` to\ndistinguish IP-allow-list, scope, ownership, plan, self-lockout,\nsuppression-duplicate, or other errors that share an HTTP status.\n","additionalProperties":false,"required":["message"],"properties":{"message":{"type":"string","description":"Error description","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"example":{"message":"Error message"},"uniqueKey":"","typeLabel":"object"},"examples":{"changed":{"title":"changed","value":{"message":"template is being changed by another request, try again"}},"markup":{"title":"markup","value":{"message":"content.markup cannot be read now, try again"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"e2988ccb-01b3-4c01-b58e-48731f963186":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"aha-sk-64-CHARACTER-RANDOM-STRING","description":"API key for authentication. Non-empty Security Requirement values are\nAhaSend API-key roles. Roles listed within one requirement object are\njointly required; separate requirement objects are alternatives.\n","scopes":["campaigns:write"],"schemeName":"BearerAuth"}}},"servers":{"b5fdc511-65a3-4ae3-b4c1-31f6415bb096":{"url":"https://api.ahasend.com","description":"Production server"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"aha-sk-64-CHARACTER-RANDOM-STRING","description":"API key for authentication. Non-empty Security Requirement values are\nAhaSend API-key roles. Roles listed within one requirement object are\njointly required; separate requirement objects are alternatives.\n","scopes":["campaigns:write"],"schemeName":"BearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"API key for authentication. Non-empty Security Requirement values are\nAhaSend API-key roles. Roles listed within one requirement object are\njointly required; separate requirement objects are alternatives.\n","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"BearerAuth","name":"Authorization"}],"title":"BearerAuth"}]},"originalFileLocation":"openapi.yaml"},"subdomain":"ahasend","siteName":"AhaSend","title":"Create a Campaign via the API - AhaSend","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-26T21:03:07.243Z","originalFileLocation":"api-reference/campaigns/create-campaign.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.\">\u003cmeta data-mint-head name=\"application-name\" content=\"AhaSend\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Create a Campaign via the API - AhaSend\">\u003cmeta data-mint-head property=\"og:description\" content=\"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"AhaSend\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://ahasend.com/docs/api-reference/campaigns/create-campaign\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://ahasend.mintlify.app/_mintlify/api/og/v2?division=Campaigns\u0026amp;title=Create+a+Campaign+via+the+API\u0026amp;description=Create+a+draft+AhaSend+marketing+campaign+with+its+sender%2C+audience%2C+subject%2C+preview+text+and+design%2C+from+MJML%2C+HTML%2C+AhaML+or+a+campaign+template.\u0026amp;theme=fec911c84bb9f722051c4af3\u0026amp;signature=ee9fd990e3aaefe4ff780f098e06f10d32812502d184384c2d0c2d3ac3a37db4\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Create a Campaign via the API - AhaSend\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://ahasend.mintlify.app/_mintlify/api/og/v2?division=Campaigns\u0026amp;title=Create+a+Campaign+via+the+API\u0026amp;description=Create+a+draft+AhaSend+marketing+campaign+with+its+sender%2C+audience%2C+subject%2C+preview+text+and+design%2C+from+MJML%2C+HTML%2C+AhaML+or+a+campaign+template.\u0026amp;theme=fec911c84bb9f722051c4af3\u0026amp;signature=ee9fd990e3aaefe4ff780f098e06f10d32812502d184384c2d0c2d3ac3a37db4\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/ahasend/4BjAcdwrGYDKJCaO/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"AhaSend\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#066fd1\">\u003clink data-mint-head rel=\"canonical\" href=\"https://ahasend.com/docs/api-reference/campaigns/create-campaign\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/api-reference/campaigns/create-campaign.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://ahasend.com/#organization\",\"name\":\"AhaSend\",\"legalName\":\"AhaSend B.V.\",\"url\":\"https://ahasend.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/ahasend/F35Ozd-1GsftDpcH/logo.png?fit=max\u0026auto=format\u0026n=F35Ozd-1GsftDpcH\u0026q=85\u0026s=ca1d4c27f7c2811598e65cb25a21323c\"},\"sameAs\":[\"https://x.com/aha_send\",\"https://www.linkedin.com/company/ahasend\",\"https://github.com/ahasend\"]},{\"@type\":\"WebSite\",\"@id\":\"https://ahasend.com/docs#website\",\"name\":\"AhaSend\",\"url\":\"https://ahasend.com/docs\",\"publisher\":{\"@id\":\"https://ahasend.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign#webpage\",\"url\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign\",\"name\":\"Create a Campaign via the API\",\"description\":\"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.\",\"dateModified\":\"2026-10-26T21:03:07.243Z\",\"isPartOf\":{\"@id\":\"https://ahasend.com/docs#website\"},\"breadcrumb\":{\"@id\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"API reference\",\"item\":\"https://ahasend.com/docs/api-reference/messages/create-message\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Campaigns\",\"item\":\"https://ahasend.com/docs/api-reference/campaigns/overview\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Create a Campaign via the API\",\"item\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign#apireference\",\"headline\":\"Create a Campaign via the API\",\"name\":\"Create a Campaign via the API\",\"description\":\"Create a draft AhaSend marketing campaign with its sender, audience, subject, preview text and design, from MJML, HTML, AhaML or a campaign template.\",\"url\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign\",\"mainEntityOfPage\":{\"@id\":\"https://ahasend.com/docs/api-reference/campaigns/create-campaign#webpage\"},\"dateModified\":\"2026-10-26T21:03:07.243Z\",\"publisher\":{\"@id\":\"https://ahasend.com/#organization\"},\"isPartOf\":{\"@id\":\"https://ahasend.com/docs#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"AhaSend\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"AhaSend","nav":{"global":null,"tabs":[{"tab":"Documentation","icon":"book-open","pages":[{"title":"Documentation","href":""}]},{"tab":"API Reference","icon":"code","groups":[{"group":"Overview","pages":[{"title":"Email API Reference (v2)","sidebarTitle":"Introduction","icon":"book","href":"/api-reference"},{"title":"API Authentication with Bearer API Keys","sidebarTitle":"Authentication","icon":"key","href":"/api-reference/authentication"},{"title":"API Key Scopes and Permissions","sidebarTitle":"Scopes","icon":"lock","href":"/api-reference/scopes"},{"title":"API Rate Limits and 429 Handling","sidebarTitle":"Rate Limits","icon":"gauge-high","href":"/api-reference/rate-limits"},{"title":"Idempotency Keys for Safe API Retries","icon":"repeat","sidebarTitle":"Idempotency","href":"/api-reference/idempotency"},{"title":"API Error Codes and Error Responses","icon":"triangle-exclamation","sidebarTitle":"Errors","href":"/api-reference/errors"}]},{"group":"API reference","pages":[{"group":"Messages","icon":"envelope","pages":[{"title":"Send an Email via the API","sidebarTitle":"Create Message","openapi":"openapi.yaml POST /v2/accounts/{account_id}/messages","href":"/api-reference/messages/create-message"},{"title":"Send a Transactional Template via the API","sidebarTitle":"Create Template Message","openapi":"openapi.yaml POST /v2/accounts/{account_id}/messages/template","href":"/api-reference/messages/create-template-message"},{"title":"Send Email with CC and BCC via the API","sidebarTitle":"Create Conversation","openapi":"openapi.yaml POST /v2/accounts/{account_id}/messages/conversation","href":"/api-reference/messages/create-conversation"},{"title":"Get a Message by ID via the API","sidebarTitle":"Get Message","openapi":"openapi.yaml GET /v2/accounts/{account_id}/messages/{message_id}","href":"/api-reference/messages/get-message"},{"title":"List and Search Sent Emails via the API","sidebarTitle":"List Messages","openapi":"openapi.yaml GET /v2/accounts/{account_id}/messages","href":"/api-reference/messages/get-messages"},{"title":"Cancel a Scheduled Email via the API","sidebarTitle":"Cancel Message","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/messages/{message_id}/cancel","href":"/api-reference/messages/cancel-message"}]},{"group":"Transactional Templates","icon":"file-lines","pages":[{"title":"Create a Transactional Template via the API","sidebarTitle":"Create Template","openapi":"openapi.yaml POST /v2/accounts/{account_id}/templates","href":"/api-reference/templates/create-template"},{"title":"Get a Transactional Template via the API","sidebarTitle":"Get Template","openapi":"openapi.yaml GET /v2/accounts/{account_id}/templates/{template_id}","href":"/api-reference/templates/get-template"},{"title":"Get a Published Transactional Template via the API","sidebarTitle":"Get Published Template","openapi":"openapi.yaml GET /v2/accounts/{account_id}/templates/{template_id}/published","href":"/api-reference/templates/get-published-template"},{"title":"List Transactional Templates via the API","sidebarTitle":"List Templates","openapi":"openapi.yaml GET /v2/accounts/{account_id}/templates","href":"/api-reference/templates/get-templates"},{"title":"Update a Transactional Template via the API","sidebarTitle":"Update Template","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/templates/{template_id}","href":"/api-reference/templates/update-template"},{"title":"Publish a Template Draft via the API","sidebarTitle":"Publish Template","openapi":"openapi.yaml POST /v2/accounts/{account_id}/templates/{template_id}/publish","href":"/api-reference/templates/publish-template"},{"title":"Discard a Template Draft via the API","sidebarTitle":"Discard Template Draft","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/templates/{template_id}/draft","href":"/api-reference/templates/discard-template-draft"},{"title":"List Template Versions via the API","sidebarTitle":"List Template Versions","openapi":"openapi.yaml GET /v2/accounts/{account_id}/templates/{template_id}/versions","href":"/api-reference/templates/get-template-versions"},{"title":"Get a Template Version via the API","sidebarTitle":"Get Template Version","openapi":"openapi.yaml GET /v2/accounts/{account_id}/templates/{template_id}/versions/{version_id}","href":"/api-reference/templates/get-template-version"},{"title":"Restore a Template Version via the API","sidebarTitle":"Restore Template Version","openapi":"openapi.yaml POST /v2/accounts/{account_id}/templates/{template_id}/versions/{version_id}/restore","href":"/api-reference/templates/restore-template-version"},{"title":"Delete a Transactional Template via the API","sidebarTitle":"Delete Template","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/templates/{template_id}","href":"/api-reference/templates/delete-template"}]},{"group":"Campaigns","icon":"bullhorn","pages":[{"title":"Campaigns API Overview","sidebarTitle":"Introduction","description":"Build, test and send AhaSend marketing campaigns through the API: set the sender, audience, subject and design, fix the issues, then read stats and recipients.","icon":"bullhorn","href":"/api-reference/campaigns/overview"},{"title":"Create a Campaign via the API","sidebarTitle":"Create Campaign","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaigns","href":"/api-reference/campaigns/create-campaign"},{"title":"Get a Campaign via the API","sidebarTitle":"Get Campaign","openapi":"openapi.yaml GET /v2/accounts/{account_id}/campaigns/{campaign_id}","description":"Retrieve an AhaSend marketing campaign by ID with its status, sender, audience and design, and for a draft, the issues that stop it from being sent.","href":"/api-reference/campaigns/get-campaign"},{"title":"List Campaigns via the API","sidebarTitle":"List Campaigns","openapi":"openapi.yaml GET /v2/accounts/{account_id}/campaigns","href":"/api-reference/campaigns/get-campaigns"},{"title":"Update a Campaign via the API","sidebarTitle":"Update Campaign","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/campaigns/{campaign_id}","href":"/api-reference/campaigns/update-campaign"},{"title":"Duplicate a Campaign via the API","sidebarTitle":"Duplicate Campaign","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaigns/{campaign_id}/duplicate","href":"/api-reference/campaigns/duplicate-campaign"},{"title":"Send a Campaign Test via the API","sidebarTitle":"Test Campaign","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaigns/{campaign_id}/test","href":"/api-reference/campaigns/test-campaign"},{"title":"Send or Schedule a Campaign via the API","sidebarTitle":"Send Campaign","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaigns/{campaign_id}/send","href":"/api-reference/campaigns/send-campaign"},{"title":"Unschedule a Campaign via the API","sidebarTitle":"Unschedule Campaign","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaigns/{campaign_id}/unschedule","href":"/api-reference/campaigns/unschedule-campaign"},{"title":"Get Campaign Stats via the API","sidebarTitle":"Get Campaign Stats","openapi":"openapi.yaml GET /v2/accounts/{account_id}/campaigns/{campaign_id}/stats","href":"/api-reference/campaigns/get-campaign-stats"},{"title":"List Campaign Recipients via the API","sidebarTitle":"List Campaign Recipients","openapi":"openapi.yaml GET /v2/accounts/{account_id}/campaigns/{campaign_id}/recipients","href":"/api-reference/campaigns/get-campaign-recipients"},{"title":"Delete a Campaign via the API","sidebarTitle":"Delete Campaign","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/campaigns/{campaign_id}","href":"/api-reference/campaigns/delete-campaign"}]},{"group":"Campaign Templates","icon":"palette","pages":[{"title":"Create a Campaign Template via the API","sidebarTitle":"Create Template","openapi":"openapi.yaml POST /v2/accounts/{account_id}/campaign-templates","href":"/api-reference/campaign-templates/create-campaign-template"},{"title":"Get a Campaign Template via the API","sidebarTitle":"Get Template","openapi":"openapi.yaml GET /v2/accounts/{account_id}/campaign-templates/{template_id}","href":"/api-reference/campaign-templates/get-campaign-template"},{"title":"List Campaign Templates via the API","sidebarTitle":"List Templates","openapi":"openapi.yaml GET /v2/accounts/{account_id}/campaign-templates","href":"/api-reference/campaign-templates/get-campaign-templates"},{"title":"Update a Campaign Template via the API","sidebarTitle":"Update Template","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/campaign-templates/{template_id}","href":"/api-reference/campaign-templates/update-campaign-template"},{"title":"Delete a Campaign Template via the API","sidebarTitle":"Delete Template","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/campaign-templates/{template_id}","href":"/api-reference/campaign-templates/delete-campaign-template"}]},{"group":"Contacts","icon":"address-book","pages":[{"title":"Contacts API Overview","sidebarTitle":"Introduction","icon":"address-book","href":"/api-reference/contacts/overview"},{"title":"Create a Contact via the API","sidebarTitle":"Create Contact","openapi":"openapi.yaml POST /v2/accounts/{account_id}/contacts","href":"/api-reference/contacts/create-contact"},{"title":"Get a Contact via the API","sidebarTitle":"Get Contact","openapi":"openapi.yaml GET /v2/accounts/{account_id}/contacts/{id_or_email}","href":"/api-reference/contacts/get-contact"},{"title":"List Contacts via the API","sidebarTitle":"List Contacts","openapi":"openapi.yaml GET /v2/accounts/{account_id}/contacts","href":"/api-reference/contacts/get-contacts"},{"title":"Update a Contact via the API","sidebarTitle":"Update Contact","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/contacts/{id_or_email}","href":"/api-reference/contacts/update-contact"},{"title":"Delete a Contact via the API","sidebarTitle":"Delete Contact","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/contacts/{id_or_email}","href":"/api-reference/contacts/delete-contact"},{"title":"Create or Update Contacts in a Batch via the API","sidebarTitle":"Batch Upsert Contacts","openapi":"openapi.yaml POST /v2/accounts/{account_id}/contacts/batch","href":"/api-reference/contacts/batch-upsert-contacts"}]},{"group":"Lists","icon":"list-ul","pages":[{"title":"Lists API Overview","sidebarTitle":"Introduction","icon":"list-ul","href":"/api-reference/lists/overview"},{"title":"Create a List via the API","sidebarTitle":"Create List","openapi":"openapi.yaml POST /v2/accounts/{account_id}/lists","href":"/api-reference/lists/create-list"},{"title":"Get a List via the API","sidebarTitle":"Get List","openapi":"openapi.yaml GET /v2/accounts/{account_id}/lists/{list_id}","href":"/api-reference/lists/get-list"},{"title":"List Contact Lists via the API","sidebarTitle":"List Lists","openapi":"openapi.yaml GET /v2/accounts/{account_id}/lists","href":"/api-reference/lists/get-lists"},{"title":"Update a List via the API","sidebarTitle":"Update List","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/lists/{list_id}","href":"/api-reference/lists/update-list"},{"title":"Delete a List via the API","sidebarTitle":"Delete List","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/lists/{list_id}","href":"/api-reference/lists/delete-list"},{"title":"List the Contacts on a List via the API","sidebarTitle":"List Contacts on a List","openapi":"openapi.yaml GET /v2/accounts/{account_id}/lists/{list_id}/contacts","href":"/api-reference/lists/get-list-contacts"},{"title":"Add or Update a List Contact via the API","sidebarTitle":"Add or Update List Contact","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/lists/{list_id}/contacts/{id_or_email}","href":"/api-reference/lists/upsert-list-contact"},{"title":"Add Contacts to a List in a Batch via the API","sidebarTitle":"Batch Add List Contacts","openapi":"openapi.yaml POST /v2/accounts/{account_id}/lists/{list_id}/contacts/batch","href":"/api-reference/lists/batch-add-list-contacts"},{"title":"Remove a Contact from a List via the API","sidebarTitle":"Remove List Contact","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/lists/{list_id}/contacts/{id_or_email}","href":"/api-reference/lists/delete-list-contact"},{"title":"List a Contact's Lists via the API","sidebarTitle":"List Contact's Lists","openapi":"openapi.yaml GET /v2/accounts/{account_id}/contacts/{id_or_email}/lists","href":"/api-reference/lists/get-contact-lists"}]},{"group":"Segments","icon":"filter","pages":[{"title":"Segments API Overview","sidebarTitle":"Introduction","icon":"filter","href":"/api-reference/segments/overview"},{"title":"Preview a Segment via the API","sidebarTitle":"Preview Segment","openapi":"openapi.yaml POST /v2/accounts/{account_id}/segments/preview","href":"/api-reference/segments/preview-segment"},{"title":"Create a Segment via the API","sidebarTitle":"Create Segment","openapi":"openapi.yaml POST /v2/accounts/{account_id}/segments","href":"/api-reference/segments/create-segment"},{"title":"Get a Segment via the API","sidebarTitle":"Get Segment","openapi":"openapi.yaml GET /v2/accounts/{account_id}/segments/{segment_id}","href":"/api-reference/segments/get-segment"},{"title":"List Segments via the API","sidebarTitle":"List Segments","openapi":"openapi.yaml GET /v2/accounts/{account_id}/segments","href":"/api-reference/segments/get-segments"},{"title":"Update a Segment via the API","sidebarTitle":"Update Segment","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/segments/{segment_id}","href":"/api-reference/segments/update-segment"},{"title":"Delete a Segment via the API","sidebarTitle":"Delete Segment","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/segments/{segment_id}","href":"/api-reference/segments/delete-segment"},{"title":"List the Contacts in a Segment via the API","sidebarTitle":"List Segment Contacts","openapi":"openapi.yaml GET /v2/accounts/{account_id}/segments/{segment_id}/contacts","href":"/api-reference/segments/get-segment-contacts"},{"title":"List a Contact's Segments via the API","sidebarTitle":"List Contact's Segments","openapi":"openapi.yaml GET /v2/accounts/{account_id}/contacts/{id_or_email}/segments","href":"/api-reference/segments/get-contact-segments"}]},{"group":"Suppressions","icon":"ban","pages":[{"title":"Add an Address to the Suppression List via the API","sidebarTitle":"Create Suppression","openapi":"openapi.yaml POST /v2/accounts/{account_id}/suppressions","href":"/api-reference/suppressions/create-suppression"},{"title":"List Suppressed Addresses via the API","sidebarTitle":"List Suppressions","openapi":"openapi.yaml GET /v2/accounts/{account_id}/suppressions","href":"/api-reference/suppressions/get-suppressions"},{"title":"Remove a Suppression via the API","sidebarTitle":"Delete Suppression","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/suppressions","href":"/api-reference/suppressions/delete-suppression"},{"title":"Delete All Suppressions via the API","sidebarTitle":"Delete All Suppressions","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/suppressions/all","href":"/api-reference/suppressions/wipe-suppressions"}]},{"group":"SMTP Credentials","icon":"user-shield","pages":[{"title":"Create SMTP Credentials via the API","sidebarTitle":"Create SMTP Credential","openapi":"openapi.yaml POST /v2/accounts/{account_id}/smtp-credentials","href":"/api-reference/smtp-credentials/create-smtp-credential"},{"title":"Get an SMTP Credential via the API","sidebarTitle":"Get SMTP Credential","openapi":"openapi.yaml GET /v2/accounts/{account_id}/smtp-credentials/{smtp_credential_id}","href":"/api-reference/smtp-credentials/get-smtp-credential"},{"title":"List SMTP Credentials via the API","sidebarTitle":"List SMTP Credentials","openapi":"openapi.yaml GET /v2/accounts/{account_id}/smtp-credentials","href":"/api-reference/smtp-credentials/get-smtp-credentials"},{"title":"Delete an SMTP Credential via the API","sidebarTitle":"Delete SMTP Credential","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/smtp-credentials/{smtp_credential_id}","href":"/api-reference/smtp-credentials/delete-smtp-credential"}]},{"group":"Webhooks","icon":"webhook","pages":[{"title":"Create a Webhook via the API","sidebarTitle":"Create Webhook","openapi":"openapi.yaml POST /v2/accounts/{account_id}/webhooks","href":"/api-reference/webhooks/create-webhook"},{"title":"Get a Webhook via the API","sidebarTitle":"Get Webhook","openapi":"openapi.yaml GET /v2/accounts/{account_id}/webhooks/{webhook_id}","href":"/api-reference/webhooks/get-webhook"},{"title":"List Webhooks via the API","sidebarTitle":"List Webhooks","openapi":"openapi.yaml GET /v2/accounts/{account_id}/webhooks","href":"/api-reference/webhooks/get-webhooks"},{"title":"Update a Webhook via the API","sidebarTitle":"Update Webhook","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/webhooks/{webhook_id}","href":"/api-reference/webhooks/update-webhook"},{"title":"Delete a Webhook via the API","sidebarTitle":"Delete Webhook","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/webhooks/{webhook_id}","href":"/api-reference/webhooks/delete-webhook"}]},{"group":"Routes","icon":"route","pages":[{"title":"Create an Inbound Email Route via the API","sidebarTitle":"Create Route","openapi":"openapi.yaml POST /v2/accounts/{account_id}/routes","href":"/api-reference/routes/create-route"},{"title":"Get an Inbound Email Route via the API","sidebarTitle":"Get Route","openapi":"openapi.yaml GET /v2/accounts/{account_id}/routes/{route_id}","href":"/api-reference/routes/get-route"},{"title":"List Inbound Email Routes via the API","sidebarTitle":"List Routes","openapi":"openapi.yaml GET /v2/accounts/{account_id}/routes","href":"/api-reference/routes/get-routes"},{"title":"Update an Inbound Email Route via the API","sidebarTitle":"Update Route","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/routes/{route_id}","href":"/api-reference/routes/update-route"},{"title":"Delete an Inbound Email Route via the API","sidebarTitle":"Delete Route","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/routes/{route_id}","href":"/api-reference/routes/delete-route"}]},{"group":"Domains","icon":"globe","pages":[{"title":"Add a Sending Domain via the API","sidebarTitle":"Create Domain","openapi":"openapi.yaml POST /v2/accounts/{account_id}/domains","href":"/api-reference/domains/create-domain"},{"title":"Get a Domain and Its DNS Records via the API","sidebarTitle":"Get Domain","openapi":"openapi.yaml GET /v2/accounts/{account_id}/domains/{domain}","href":"/api-reference/domains/get-domain"},{"title":"List Sending Domains via the API","sidebarTitle":"List Domains","openapi":"openapi.yaml GET /v2/accounts/{account_id}/domains","href":"/api-reference/domains/get-domains"},{"title":"Update a Sending Domain via the API","sidebarTitle":"Update Domain","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/domains/{domain}","href":"/api-reference/domains/update-domain"},{"title":"Check Domain DNS Records via the API","sidebarTitle":"Check Domain DNS","openapi":"openapi.yaml POST /v2/accounts/{account_id}/domains/{domain}/check-dns","href":"/api-reference/domains/check-dns"},{"title":"Delete a Sending Domain via the API","sidebarTitle":"Delete Domain","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/domains/{domain}","href":"/api-reference/domains/delete-domain"}]},{"group":"Accounts","icon":"building","pages":[{"title":"Get Account Details via the API","sidebarTitle":"Get Account","openapi":"openapi.yaml GET /v2/accounts/{account_id}","href":"/api-reference/accounts/get-account"},{"title":"Update Account Settings via the API","sidebarTitle":"Update Account","openapi":"openapi.yaml PUT /v2/accounts/{account_id}","href":"/api-reference/accounts/update-account"},{"title":"List Account Members via the API","sidebarTitle":"List Account Members","openapi":"openapi.yaml GET /v2/accounts/{account_id}/members","href":"/api-reference/accounts/get-account-members"},{"title":"Add an Account Member via the API","sidebarTitle":"Add Account Member","openapi":"openapi.yaml POST /v2/accounts/{account_id}/members","href":"/api-reference/accounts/create-account-member"},{"title":"Remove an Account Member via the API","sidebarTitle":"Remove Account Member","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/members/{user_id}","href":"/api-reference/accounts/delete-account-member"}]},{"group":"Sub-Accounts","icon":"sitemap","pages":[{"title":"Sub-Accounts API Overview","sidebarTitle":"Introduction","icon":"sitemap","href":"/api-reference/sub-accounts/overview"},{"title":"Create a Sub-Account via the API","sidebarTitle":"Create Sub-Account","openapi":"openapi.yaml POST /v2/accounts/{account_id}/sub-accounts","href":"/api-reference/sub-accounts/create-sub-account"},{"title":"List Sub-Accounts via the API","sidebarTitle":"List Sub-Accounts","openapi":"openapi.yaml GET /v2/accounts/{account_id}/sub-accounts","href":"/api-reference/sub-accounts/get-sub-accounts"},{"title":"Get a Sub-Account via the API","sidebarTitle":"Get Sub-Account","openapi":"openapi.yaml GET /v2/accounts/{account_id}/sub-accounts/{sub_account_id}","href":"/api-reference/sub-accounts/get-sub-account"},{"title":"Update a Sub-Account via the API","sidebarTitle":"Update Sub-Account","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/sub-accounts/{sub_account_id}","href":"/api-reference/sub-accounts/update-sub-account"},{"title":"Pause a Sub-Account via the API","sidebarTitle":"Pause Sub-Account","openapi":"openapi.yaml POST /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/suspend","href":"/api-reference/sub-accounts/suspend-sub-account"},{"title":"Resume a Sub-Account via the API","sidebarTitle":"Resume Sub-Account","openapi":"openapi.yaml POST /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/unsuspend","href":"/api-reference/sub-accounts/unsuspend-sub-account"},{"title":"Unpause a Sub-Account Domain via the API","sidebarTitle":"Unpause Sub-Account Domain","openapi":"openapi.yaml POST /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/domains/{domain}/unpause","href":"/api-reference/sub-accounts/unpause-sub-account-domain"},{"title":"Delete a Sub-Account via the API","sidebarTitle":"Delete Sub-Account","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/sub-accounts/{sub_account_id}","href":"/api-reference/sub-accounts/delete-sub-account"},{"title":"Get Sub-Account Usage via the API","sidebarTitle":"Sub-Account Usage","openapi":"openapi.yaml GET /v2/accounts/{account_id}/sub-accounts/usage","href":"/api-reference/sub-accounts/get-sub-accounts-usage"}]},{"group":"Sub-Account API Keys","icon":"key","pages":[{"title":"Create a Sub-Account API Key via the API","sidebarTitle":"Create API Key","openapi":"openapi.yaml POST /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/api-keys","href":"/api-reference/sub-accounts/create-sub-account-api-key"},{"title":"Get a Sub-Account API Key via the API","sidebarTitle":"Get API Key","openapi":"openapi.yaml GET /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/api-keys/{key_id}","href":"/api-reference/sub-accounts/get-sub-account-api-key"},{"title":"List Sub-Account API Keys via the API","sidebarTitle":"List API Keys","openapi":"openapi.yaml GET /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/api-keys","href":"/api-reference/sub-accounts/get-sub-account-api-keys"},{"title":"Update a Sub-Account API Key via the API","sidebarTitle":"Update API Key","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/api-keys/{key_id}","href":"/api-reference/sub-accounts/update-sub-account-api-key"},{"title":"Delete a Sub-Account API Key via the API","sidebarTitle":"Delete API Key","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/sub-accounts/{sub_account_id}/api-keys/{key_id}","href":"/api-reference/sub-accounts/delete-sub-account-api-key"}]},{"group":"Reports","icon":"chart-line","pages":[{"title":"Get Email Deliverability Statistics via the API","sidebarTitle":"Deliverability Report","openapi":"openapi.yaml GET /v2/accounts/{account_id}/statistics/transactional/deliverability","href":"/api-reference/reports/get-deliverability-report"},{"title":"Get Email Bounce Statistics via the API","sidebarTitle":"Bounce Report","openapi":"openapi.yaml GET /v2/accounts/{account_id}/statistics/transactional/bounce","href":"/api-reference/reports/get-bounce-report"},{"title":"Get Email Delivery Time Statistics via the API","sidebarTitle":"Delivery Time Report","openapi":"openapi.yaml GET /v2/accounts/{account_id}/statistics/transactional/delivery-time","href":"/api-reference/reports/get-delivery-time-report"}]},{"group":"API Keys","icon":"key","pages":[{"title":"Create an API Key via the API","sidebarTitle":"Create API Key","openapi":"openapi.yaml POST /v2/accounts/{account_id}/api-keys","href":"/api-reference/api-keys/create-api-key"},{"title":"Get an API Key via the API","sidebarTitle":"Get API Key","openapi":"openapi.yaml GET /v2/accounts/{account_id}/api-keys/{key_id}","href":"/api-reference/api-keys/get-api-key"},{"title":"List API Keys via the API","sidebarTitle":"List API Keys","openapi":"openapi.yaml GET /v2/accounts/{account_id}/api-keys","href":"/api-reference/api-keys/get-api-keys"},{"title":"Update an API Key via the API","sidebarTitle":"Update API Key","openapi":"openapi.yaml PUT /v2/accounts/{account_id}/api-keys/{key_id}","href":"/api-reference/api-keys/update-api-key"},{"title":"Delete an API Key via the API","sidebarTitle":"Delete API Key","openapi":"openapi.yaml DELETE /v2/accounts/{account_id}/api-keys/{key_id}","href":"/api-reference/api-keys/delete-api-key"}]},{"group":"Utility endpoints","icon":"bolt","pages":[{"title":"Test Your API Key with the Ping Endpoint","sidebarTitle":"Ping","openapi":"openapi.yaml GET /v2/ping","href":"/api-reference/utility/ping"}]}]},{"group":"Webhooks","pages":[{"title":"Webhook Events and Payload Reference","sidebarTitle":"Introduction","icon":"webhook","href":"/api-reference/webhooks/index"},{"title":"Verify Webhook and Route Signatures (HMAC)","sidebarTitle":"Security","icon":"shield-check","href":"/api-reference/webhooks/security"},{"title":"Webhook and Route Retry Policy","sidebarTitle":"Retry Policy","icon":"repeat","href":"/api-reference/webhooks/retry-policy"},{"group":"Message Events","icon":"envelope","pages":[{"title":"message.reception Webhook Event","sidebarTitle":"Reception","openapi":"webhooks.yaml webhook message.reception","href":"/api-reference/webhooks/message-reception"},{"title":"message.delivered Webhook Event","sidebarTitle":"Delivered","openapi":"webhooks.yaml webhook message.delivered","href":"/api-reference/webhooks/message-delivered"},{"title":"message.transient_error (Deferred) Webhook Event","sidebarTitle":"Deferred","openapi":"webhooks.yaml webhook message.transient_error","href":"/api-reference/webhooks/message-transient_error"},{"title":"message.failed Webhook Event","sidebarTitle":"Failed","openapi":"webhooks.yaml webhook message.failed","href":"/api-reference/webhooks/message-failed"},{"title":"message.bounced Webhook Event","sidebarTitle":"Bounced","openapi":"webhooks.yaml webhook message.bounced","href":"/api-reference/webhooks/message-bounced"},{"title":"message.suppressed Webhook Event","sidebarTitle":"Suppressed","openapi":"webhooks.yaml webhook message.suppressed","href":"/api-reference/webhooks/message-suppressed"},{"title":"message.opened Webhook Event","sidebarTitle":"Opened","openapi":"webhooks.yaml webhook message.opened","href":"/api-reference/webhooks/message-opened"},{"title":"message.clicked Webhook Event","sidebarTitle":"Clicked","openapi":"webhooks.yaml webhook message.clicked","href":"/api-reference/webhooks/message-clicked"},{"title":"message.unsubscribed Webhook Event","sidebarTitle":"Unsubscribed","openapi":"webhooks.yaml webhook message.unsubscribed","href":"/api-reference/webhooks/message-unsubscribed"},{"title":"message.complained Webhook Event","sidebarTitle":"Complained","openapi":"webhooks.yaml webhook message.complained","href":"/api-reference/webhooks/message-complained"}]},{"group":"Suppression Events","icon":"ban","pages":[{"title":"suppression.created Webhook Event","sidebarTitle":"Suppression Created","openapi":"webhooks.yaml webhook suppression.created","href":"/api-reference/webhooks/suppression-created"},{"title":"suppression.deleted Webhook Event","sidebarTitle":"Suppression Deleted","openapi":"webhooks.yaml webhook suppression.deleted","href":"/api-reference/webhooks/suppression-deleted"}]},{"group":"Domain Events","icon":"globe","pages":[{"title":"domain.dns_error Webhook Event","sidebarTitle":"DNS Error","openapi":"webhooks.yaml webhook domain.dns_error","href":"/api-reference/webhooks/domain-dns_error"}]},{"group":"Contact Events","icon":"address-book","pages":[{"title":"contact.created Webhook Event","sidebarTitle":"Contact Created","openapi":"webhooks.yaml webhook contact.created","href":"/api-reference/webhooks/contact-created"},{"title":"contact.updated Webhook Event","sidebarTitle":"Contact Updated","openapi":"webhooks.yaml webhook contact.updated","href":"/api-reference/webhooks/contact-updated"},{"title":"contact.deleted Webhook Event","sidebarTitle":"Contact Deleted","openapi":"webhooks.yaml webhook contact.deleted","href":"/api-reference/webhooks/contact-deleted"},{"title":"contact.added_to_list Webhook Event","sidebarTitle":"Contact Added to List","openapi":"webhooks.yaml webhook contact.added_to_list","href":"/api-reference/webhooks/contact-added_to_list"},{"title":"contact.removed_from_list Webhook Event","sidebarTitle":"Contact Removed from List","openapi":"webhooks.yaml webhook contact.removed_from_list","href":"/api-reference/webhooks/contact-removed_from_list"},{"title":"contact.subscribed Webhook Event","sidebarTitle":"Contact Subscribed","openapi":"webhooks.yaml webhook contact.subscribed","href":"/api-reference/webhooks/contact-subscribed"},{"title":"contact.unsubscribed Webhook Event","sidebarTitle":"Contact Unsubscribed","openapi":"webhooks.yaml webhook contact.unsubscribed","href":"/api-reference/webhooks/contact-unsubscribed"},{"title":"contact.complained Webhook Event","sidebarTitle":"Contact Complained","openapi":"webhooks.yaml webhook contact.complained","href":"/api-reference/webhooks/contact-complained"}]}]},{"group":"Message Routing","pages":[{"title":"Inbound Email Routing API Overview","sidebarTitle":"Introduction","icon":"route","href":"/api-reference/routes/index"},{"title":"message.routing Inbound Email Webhook Event","sidebarTitle":"Message Routing","openapi":"webhooks.yaml webhook message.routing","href":"/api-reference/routes/route-message"}]},{"group":"API v1 (legacy)","pages":[{"title":"API v1 vs v2: Differences and Migration","sidebarTitle":"v1 vs v2","icon":"code-compare","href":"/api-reference/v1/v1-vs-v2"},{"title":"Send Email with API v1 (Legacy)","sidebarTitle":"Send Email (Legacy)","icon":"paper-plane","openapi":"openapi-v1.yaml POST /v1/email/send","href":"/api-reference/v1/index"}]}]},{"tab":"CLI","icon":"square-terminal","pages":[{"title":"CLI","href":"/cli"}]},{"tab":"Guides","icon":"plug","pages":[{"title":"Guides","href":"/guides"}]},{"tab":"Changelog","icon":"clock-rotate-left","pages":[{"title":"Changelog","href":"/changelog"}]},{"tab":"Roadmap","icon":"map","pages":[{"title":"Roadmap","href":"/roadmap"}]}]},"basePath":"","title":"Create a Campaign via the API - AhaSend","buildId":"dpl_6cCEiK8XNNvaLBBkWzcBhdE9QfLC","deploymentId":"dpl_6cCEiK8XNNvaLBBkWzcBhdE9QfLC","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-CLz2_Z5D.js","utils-7A5jZhOT.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-BVWmkKuv.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-4SOfrh0F.js","snippetPresets-CMc8KicP.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-Ba9tX7z3.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-Be8krXvv.js","shallow-CBC3K1uB.js","getApiPlaygroundDisplay-4tKcUAYo.js","CodeSnippet-C1Xa06ft.js","CodeSnippets-vqiz27A_.js","Page-DeQN5MDd.js","getPastedJson-NUwRfM32.js","icon-DkIVqWh9.js","MethodPill-qmhT7_wz.js","DuplicateIcon-_gWp1vhn.js","createIcon-NA1p_TVA.js","DynamicMarkdown-Bas9A7wq.js","SectionHeading-a1cS-24U.js","axios-vUo_bRtp.js","Markdown-D3ZTwq_a.js","clsx-BcghKhHb.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-B66mVNPp.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-DmooSyTN.js"]}