DevelopersAPI referenceEngagement

Email designs API

REST endpoints for email designs in SKUFlow: 14 operations with parameters, request and response fields, permissions and curl examples.

Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.

OperationEndpointRisk
Get the email themeGET /organizations/{organizationId}/messaging/email-themeread
Change the email themePATCH /organizations/{organizationId}/messaging/email-themewrite
List the email designsGET /organizations/{organizationId}/email-designsread
Get an email template's designGET /organizations/{organizationId}/message-templates/{templateId}/designread
Save an email template's designPUT /organizations/{organizationId}/message-templates/{templateId}/designwrite
Reset an email template's designDELETE /organizations/{organizationId}/message-templates/{templateId}/designsensitive
Preview an email designPOST /organizations/{organizationId}/email-designs/previewwrite
Send a test of an email designPOST /organizations/{organizationId}/email-designs/testwrite
Draft an email theme with AIPOST /organizations/{organizationId}/email-designs/ai/themewrite
Draft an email template's design with AIPOST /organizations/{organizationId}/message-templates/{templateId}/design/draftwrite
The image library for emailsGET /organizations/{organizationId}/email-designs/mediaread
Upload an email imagePOST /organizations/{organizationId}/email-designs/image-upload-urlwrite
Add an uploaded email image to the libraryPOST /organizations/{organizationId}/email-designs/media/uploadswrite
Add an image for emails (content in the request)POST /organizations/{organizationId}/email-designs/media/contentwrite

Get the email theme

GET /organizations/{organizationId}/messaging/email-theme

The brand theme every email shares (Settings → Messaging → Email theme): page, body and header backgrounds, text, link and button colours and button style, font, logo size (small / medium / large or a width in px) and alignment, the accent bar, a banner image, social links, the accent colour, the line under the logo and the footer text. Read-only.

Permissionengagement.read (Owner, Admin, Staff)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolemailDesigns_getTheme (toolset marketing)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/email-theme" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
pageBackgroundstring
cardBackgroundstring
headerBackgroundstring
textColorstring
linkColorstring
buttonColorstring or nullnull = the accent colour.
buttonTextColorstring
buttonStyleenumOne of filled, outline.
buttonRadiusinteger
fontFamilystring
logoSizeenumOne of small, medium, large, custom.
logoWidthinteger
logoAlignenumOne of left, center.
showBrandBarboolean
bannerUrlstring or null
bannerAltstring
socialobject
social.facebookstring or null
social.instagramstring or null
social.googlestring or null
social.yelpstring or null
social.websitestring or null
brandColorstring or nullThe accent colour; null = SKUFlow blue.
headerTextstring or null
footerTextstring or null
logoUrlstring or nullThe business logo (Settings → General); change it with organizations.uploadLogo.
businessNamestringThe name the header and footer show (the sender name).
addressstring or nullThe postal address in the footer (Settings → General).
phonestring or nullThe phone in the footer (Settings → Messaging).

Change the email theme

PATCH /organizations/{organizationId}/messaging/email-theme

Changes how every email looks from the next one sent (automations, Send buttons, campaigns): only the fields sent change. A white logo on a white header is invisible: set headerBackground to a dark colour. Logo size: logoSize small | medium | large, or custom with logoWidth in px (kept within a phone's width). Preview first with POST /email-designs/preview and theme. Sends nothing.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_updateTheme (toolset marketing)

Request body

FieldTypeRequiredDescription
pageBackgroundstringNoAround the email (#rrggbb).
cardBackgroundstringNoThe email's body (#rrggbb).
headerBackgroundstringNoBehind the logo (#rrggbb): a dark one makes a white logo visible.
textColorstringNo
linkColorstringNo
buttonColorstring or nullNoButtons; null = the accent colour.
buttonTextColorstringNoText on a filled button.
buttonStyleenumNoOne of filled, outline.
buttonRadiusintegerNoButton corners, px. 0–24.
fontFamilyenumNoAn email-safe font stack. One of system, arial, helvetica, verdana, tahoma, trebuchet, georgia, times, courier.
logoSizeenumNosmall 32 px, medium 48 px (the default), large 72 px tall; custom = logoWidth. One of small, medium, large, custom.
logoWidthintegerNoThe logo's width in px when logoSize is custom (never wider than the screen). 40–480.
logoAlignenumNoOne of left, center.
showBrandBarbooleanNoThe accent-coloured bar across the top.
bannerUrlstring or nullNoA banner image under the header: an uploaded image's url or https://; null removes it. Up to 1000 characters.
bannerAltstringNoUp to 200 characters.
socialobjectNoSocial links (https://), shown in the footer; null removes one.
social.facebookstring or nullNoUp to 500 characters.
social.instagramstring or nullNoUp to 500 characters.
social.googlestring or nullNoUp to 500 characters.
social.yelpstring or nullNoUp to 500 characters.
social.websitestring or nullNoUp to 500 characters.
brandColorempty string or string or nullNoThe accent colour (#rrggbb); empty or null = SKUFlow blue.
headerTextstring or nullNoA line under the logo. Up to 120 characters.
footerTextstring or nullNoYour footer text (website, hours, licence), above your address and unsubscribe. Up to 500 characters.

Example

curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/messaging/email-theme" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"pageBackground":"string","cardBackground":"string","headerBackground":"string"}'

Response

200: the answer's fields
FieldTypeDescription
pageBackgroundstring
cardBackgroundstring
headerBackgroundstring
textColorstring
linkColorstring
buttonColorstring or nullnull = the accent colour.
buttonTextColorstring
buttonStyleenumOne of filled, outline.
buttonRadiusinteger
fontFamilystring
logoSizeenumOne of small, medium, large, custom.
logoWidthinteger
logoAlignenumOne of left, center.
showBrandBarboolean
bannerUrlstring or null
bannerAltstring
socialobject
social.facebookstring or null
social.instagramstring or null
social.googlestring or null
social.yelpstring or null
social.websitestring or null
brandColorstring or nullThe accent colour; null = SKUFlow blue.
headerTextstring or null
footerTextstring or null
logoUrlstring or nullThe business logo (Settings → General); change it with organizations.uploadLogo.
businessNamestringThe name the header and footer show (the sender name).
addressstring or nullThe postal address in the footer (Settings → General).
phonestring or nullThe phone in the footer (Settings → Messaging).

List the email designs

GET /organizations/{organizationId}/email-designs

Every email template (invoices, quotes, receipts, request confirmations and reminders, the Send buttons' emails, automations, marketing) and whether it has its own design or uses the default design (the theme and the template's text). Campaign designs are on each campaign (GET …/marketing/campaigns/{campaignId}/design). Read-only.

Permissionengagement.read (Owner, Admin, Staff)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolemailDesigns_list (toolset marketing)

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields

An array of objects:

FieldTypeDescription
templateIdstring
namestring
subjectstring or null
purposeenumOne of TRANSACTIONAL, MARKETING.
systemKeystring or null
isSystemboolean
groupenumtransactional: invoices, quotes, receipts, request confirmations and the Send buttons; automation: other automations; marketing: win-back and other marketing. One of transactional, automation, marketing.
recordKindenum or nullOne of invoice, quote, payment.
custombooleanHas its own design (else the default design with the theme).
updatedAtstring (date-time) or null

Get an email template's design

GET /organizations/{organizationId}/message-templates/{templateId}/design

The template's block design (custom: true), or the starter it would begin from (custom: false: the default design plus its locked blocks), with the blocks it must keep (required: the message, a transactional email's summary such as the invoice's pay link, the footer). Read-only.

Permissionengagement.read (Owner, Admin, Staff)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolemailDesigns_get (toolset marketing)

Parameters

NameInTypeRequiredDescription
templateIdpathstringYesAn email message template id, from GET /email-designs (or GET /message-templates).

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/message-templates/{templateId}/design" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
targetobject
target.kindenumOne of template, campaign.
target.idstring
target.namestring
target.subjectstring or null
target.bodystringThe message block's text (edit it on the template or campaign).
target.preheaderstring or null
target.purposeenumOne of TRANSACTIONAL, MARKETING.
target.systemKeystring or null
target.editablebooleanFalse for a campaign that started (only drafts and scheduled ones change).
custombooleanTrue: the email uses this design. False: the default design; document is the starter.
documentobject
document.versioninteger
document.blocksarray of object
document.blocks[].idstring
document.blocks[].typeenumOne of header, heading, text, image, button, divider, spacer, columns, social, message, record, footer.
requiredarray of objectBlocks this email must keep (they can move and change style, not be deleted).
required[].typeenumOne of message, footer, record.
required[].kindenumOne of invoice, quote, payment.
recordKindenum or nullOne of invoice, quote, payment.
updatedAtstring (date-time) or null

Save an email template's design

PUT /organizations/{organizationId}/message-templates/{templateId}/design

Replaces the template's design: every email it sends uses it from the next one (automations, the Send buttons, batch sends). 400 when a required block is missing (required from GET …/design) or a block is invalid. Sends nothing; check it first with POST /email-designs/preview or /email-designs/test.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_update (toolset marketing)

Parameters

NameInTypeRequiredDescription
templateIdpathstringYesAn email message template id, from GET /email-designs (or GET /message-templates).

Request body

FieldTypeRequiredDescription
documentobjectYesThe design: { version: 1, blocks: [...] }. Blocks (each { id, type, style: { background, paddingTop, paddingBottom, paddingX } }): header { showHeaderText, showBanner }, heading { text, level 1-3, align }, text { text with **bold**, *italic*, label and {{merge.fields}} }, image { url (an uploaded image's url or https://), alt, href, width % , align }, button { label, url (https://… or a merge link such as {{links.invoice}}), align, fullWidth }, divider { color, thickness }, spacer { height }, columns { columns: 2-3 × { blocks: heading/text/image/button }, stackOnMobile }, social { align }, message (the template's or campaign's text), record { kind invoice|quote|visit|payment|membership, showButton, buttonLabel }, footer (your address and the unsubscribe link). GET the design first and send it back changed.
document.version1NoDefault 1.
document.blocksarray of objectYesUp to 60 items.

Example

curl -X PUT "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/message-templates/{templateId}/design" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"document":{"blocks":[{"id":"id_id","type":"header"}]}}'

Response

200: the answer's fields
FieldTypeDescription
targetobject
target.kindenumOne of template, campaign.
target.idstring
target.namestring
target.subjectstring or null
target.bodystringThe message block's text (edit it on the template or campaign).
target.preheaderstring or null
target.purposeenumOne of TRANSACTIONAL, MARKETING.
target.systemKeystring or null
target.editablebooleanFalse for a campaign that started (only drafts and scheduled ones change).
custombooleanTrue: the email uses this design. False: the default design; document is the starter.
documentobject
document.versioninteger
document.blocksarray of object
document.blocks[].idstring
document.blocks[].typeenumOne of header, heading, text, image, button, divider, spacer, columns, social, message, record, footer.
requiredarray of objectBlocks this email must keep (they can move and change style, not be deleted).
required[].typeenumOne of message, footer, record.
required[].kindenumOne of invoice, quote, payment.
recordKindenum or nullOne of invoice, quote, payment.
updatedAtstring (date-time) or null

Reset an email template's design

DELETE /organizations/{organizationId}/message-templates/{templateId}/design

Destructive: deletes the template's own design; its emails go back to the default design (the theme and the template's text). The template itself is kept.

Permissionengagement.manage (Owner, Admin)
Risksensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP toolemailDesigns_reset (toolset marketing)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Parameters

NameInTypeRequiredDescription
templateIdpathstringYesAn email message template id, from GET /email-designs (or GET /message-templates).

Example

curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/message-templates/{templateId}/design" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
targetobject
target.kindenumOne of template, campaign.
target.idstring
target.namestring
target.subjectstring or null
target.bodystringThe message block's text (edit it on the template or campaign).
target.preheaderstring or null
target.purposeenumOne of TRANSACTIONAL, MARKETING.
target.systemKeystring or null
target.editablebooleanFalse for a campaign that started (only drafts and scheduled ones change).
custombooleanTrue: the email uses this design. False: the default design; document is the starter.
documentobject
document.versioninteger
document.blocksarray of object
document.blocks[].idstring
document.blocks[].typeenumOne of header, heading, text, image, button, divider, spacer, columns, social, message, record, footer.
requiredarray of objectBlocks this email must keep (they can move and change style, not be deleted).
required[].typeenumOne of message, footer, record.
required[].kindenumOne of invoice, quote, payment.
recordKindenum or nullOne of invoice, quote, payment.
updatedAtstring (date-time) or null

Preview an email design

POST /organizations/{organizationId}/email-designs/preview

Renders an email with a design (unsaved document, else the saved one, else the default) and the theme (plus unsaved theme changes): the template's or campaign's text, merge fields filled with examples (or a real customerId's, no links made). Returns the HTML exactly as sent, the plain-text alternative and any locked block missing. Nothing is saved or sent.

Permissionengagement.read (Owner, Admin, Staff)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_preview (toolset marketing)

Request body

FieldTypeRequiredDescription
documentobjectNoAn unsaved design to preview; omit for the saved one (or the default).
document.version1NoDefault 1.
document.blocksarray of objectYesUp to 60 items.
templateIdstringNoPreview this email template's design and text.
campaignIdstringNoPreview this campaign's design and text.
themeobjectNoTheme changes not saved yet (the theme panel's live preview).
theme.pageBackgroundstringNoAround the email (#rrggbb).
theme.cardBackgroundstringNoThe email's body (#rrggbb).
theme.headerBackgroundstringNoBehind the logo (#rrggbb): a dark one makes a white logo visible.
theme.textColorstringNo
theme.linkColorstringNo
theme.buttonColorstring or nullNoButtons; null = the accent colour.
theme.buttonTextColorstringNoText on a filled button.
theme.buttonStyleenumNoOne of filled, outline.
theme.buttonRadiusintegerNoButton corners, px. 0–24.
theme.fontFamilyenumNoAn email-safe font stack. One of system, arial, helvetica, verdana, tahoma, trebuchet, georgia, times, courier.
theme.logoSizeenumNosmall 32 px, medium 48 px (the default), large 72 px tall; custom = logoWidth. One of small, medium, large, custom.
theme.logoWidthintegerNoThe logo's width in px when logoSize is custom (never wider than the screen). 40–480.
theme.logoAlignenumNoOne of left, center.
theme.showBrandBarbooleanNoThe accent-coloured bar across the top.
theme.bannerUrlstring or nullNoA banner image under the header: an uploaded image's url or https://; null removes it. Up to 1000 characters.
theme.bannerAltstringNoUp to 200 characters.
theme.socialobjectNoSocial links (https://), shown in the footer; null removes one.
theme.social.facebookstring or nullNoUp to 500 characters.
theme.social.instagramstring or nullNoUp to 500 characters.
theme.social.googlestring or nullNoUp to 500 characters.
theme.social.yelpstring or nullNoUp to 500 characters.
theme.social.websitestring or nullNoUp to 500 characters.
theme.brandColorempty string or string or nullNoThe accent colour (#rrggbb); empty or null = SKUFlow blue.
theme.headerTextstring or nullNoA line under the logo. Up to 120 characters.
theme.footerTextstring or nullNoYour footer text (website, hours, licence), above your address and unsubscribe. Up to 500 characters.
customerIdstringNoFill merge fields from this customer (GET /customers); examples when omitted.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs/preview" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"document":{"blocks":[{"id":"id_id","type":"header"}]},"templateId":"template_id","campaignId":"campaign_id"}'

Response

200: the answer's fields
FieldTypeDescription
subjectstring
preheaderstring or null
htmlstringThe email's HTML, exactly as sent (merge fields filled).
textstringThe plain-text alternative.
unresolvedarray of stringMerge fields with no value in this preview.
problemsarray of stringWhy the design could not be saved as it is (a locked block missing).
purposeenumOne of TRANSACTIONAL, MARKETING.

Send a test of an email design

POST /organizations/{organizationId}/email-designs/test

SENDS AN EMAIL to you (no customer): the design as previewed, merge fields filled with examples, subject marked "[Test]", to to (default your account's email) through the email provider (test mode only logs it). Logged in the message log with source TEST.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_sendTest (toolset marketing)

Request body

FieldTypeRequiredDescription
documentobjectNoAn unsaved design to preview; omit for the saved one (or the default).
document.version1NoDefault 1.
document.blocksarray of objectYesUp to 60 items.
templateIdstringNoPreview this email template's design and text.
campaignIdstringNoPreview this campaign's design and text.
themeobjectNoTheme changes not saved yet (the theme panel's live preview).
theme.pageBackgroundstringNoAround the email (#rrggbb).
theme.cardBackgroundstringNoThe email's body (#rrggbb).
theme.headerBackgroundstringNoBehind the logo (#rrggbb): a dark one makes a white logo visible.
theme.textColorstringNo
theme.linkColorstringNo
theme.buttonColorstring or nullNoButtons; null = the accent colour.
theme.buttonTextColorstringNoText on a filled button.
theme.buttonStyleenumNoOne of filled, outline.
theme.buttonRadiusintegerNoButton corners, px. 0–24.
theme.fontFamilyenumNoAn email-safe font stack. One of system, arial, helvetica, verdana, tahoma, trebuchet, georgia, times, courier.
theme.logoSizeenumNosmall 32 px, medium 48 px (the default), large 72 px tall; custom = logoWidth. One of small, medium, large, custom.
theme.logoWidthintegerNoThe logo's width in px when logoSize is custom (never wider than the screen). 40–480.
theme.logoAlignenumNoOne of left, center.
theme.showBrandBarbooleanNoThe accent-coloured bar across the top.
theme.bannerUrlstring or nullNoA banner image under the header: an uploaded image's url or https://; null removes it. Up to 1000 characters.
theme.bannerAltstringNoUp to 200 characters.
theme.socialobjectNoSocial links (https://), shown in the footer; null removes one.
theme.social.facebookstring or nullNoUp to 500 characters.
theme.social.instagramstring or nullNoUp to 500 characters.
theme.social.googlestring or nullNoUp to 500 characters.
theme.social.yelpstring or nullNoUp to 500 characters.
theme.social.websitestring or nullNoUp to 500 characters.
theme.brandColorempty string or string or nullNoThe accent colour (#rrggbb); empty or null = SKUFlow blue.
theme.headerTextstring or nullNoA line under the logo. Up to 120 characters.
theme.footerTextstring or nullNoYour footer text (website, hours, licence), above your address and unsubscribe. Up to 500 characters.
tostring (email)NoWhere to send the test; default your account's email. Up to 254 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs/test" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"document":{"blocks":[{"id":"id_id","type":"header"}]},"templateId":"template_id","campaignId":"campaign_id"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
statusstringSENT, SENT_TEST (test mode), SKIPPED or FAILED.
statusReasonstring or null
toAddressstring or null
subjectstring or null

Draft an email theme with AI

POST /organizations/{organizationId}/email-designs/ai/theme

Claude drafts the email theme's looks (accent, header and page backgrounds, text and link colours, buttons, font, logo alignment) from the business's brand: its website's theme, the logo's colours (logoColors, read from the logo by the caller) and its trade, plus an optional request. Text stays readable (contrast checked); no texts, logo or social links are changed. Uses AI credits (402 when none are left); source TEMPLATE when AI is off (a theme from the brand without AI). Nothing is saved: preview with POST /email-designs/preview theme, apply with PATCH /messaging/email-theme.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_draftTheme (toolset marketing)

Request body

FieldTypeRequiredDescription
promptstringNoOptional wishes: "darker header, rounded buttons, centred logo". Up to 600 characters.
logoColorsarray of stringNoThe logo's main colours (#rrggbb, most used first), when known. Up to 5 items.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs/ai/theme" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"string","logoColors":["string"]}'

Response

200: the answer's fields
FieldTypeDescription
themeobjectThe drafted theme change (looks only: colours, buttons, font, logo alignment). Preview it with POST /email-designs/preview theme, apply it with PATCH /messaging/email-theme.
theme.brandColorstring or null
theme.headerBackgroundstring
theme.pageBackgroundstring
theme.cardBackgroundstring
theme.textColorstring
theme.linkColorstring
theme.buttonColorstring or null
theme.buttonTextColorstring
theme.buttonStyleenumOne of filled, outline.
theme.buttonRadiusinteger
theme.fontFamilystring
theme.logoAlignenumOne of left, center.
theme.showBrandBarboolean
sourceenumAi: Claude drafted it. TEMPLATE: AI is off or unavailable (a starter from your brand). One of AI, FAKE, TEMPLATE.
basedOnenumWhere the colours came from: the website's theme, the logo, the trade's style. One of website, logo, trade, default.
notesarray of stringWhy it looks this way (shown under the preview).

Draft an email template's design with AI

POST /organizations/{organizationId}/message-templates/{templateId}/design/draft

Claude lays out the template's email as blocks from a short request ("bold, with a request-a-quote button"), using only the business's facts: images from its library, its links and merge fields; no prices or discounts that were not given. The message, a transactional email's summary (pay / approve link) and the footer are kept. Uses AI credits (402 when none are left); source TEMPLATE when AI is off (a starter layout). Nothing is saved: preview with POST /email-designs/preview document, save with PUT …/design. Read GET …/design first to see what must be kept.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_draftDesign (toolset marketing)

Parameters

NameInTypeRequiredDescription
templateIdpathstringYesAn email message template id, from GET /email-designs (or GET /message-templates).

Request body

FieldTypeRequiredDescription
promptstringYesWhat the email should look like: "summer promo, bold, with a coupon button". Up to 600 characters.
documentobjectNoThe design being edited with unsaved changes (the draft builds on it); omit for the saved one.
document.version1NoDefault 1.
document.blocksarray of objectYesUp to 60 items.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/message-templates/{templateId}/design/draft" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"string"}'

Response

200: the answer's fields
FieldTypeDescription
documentobjectThe drafted design ({ version: 1, blocks }), valid for this email and keeping its locked blocks and footer. Not saved: preview it with POST /email-designs/preview document, save it with PUT …/design.
document.versioninteger
document.blocksarray of object
document.blocks[].idstring
document.blocks[].typeenumOne of header, heading, text, image, button, divider, spacer, columns, social, message, record, footer.
sourceenumAi: Claude drafted it. TEMPLATE: AI is off or unavailable (a starter from your brand). One of AI, FAKE, TEMPLATE.
notesarray of stringThe AI's note on the design.
warningsarray of stringWhat was left out of the AI's draft and why: an image not in the library, a link or price you didn't give, a merge field that doesn't exist.

The image library for emails

GET /organizations/{organizationId}/email-designs/media

The business's images (its uploads and the stock photos it used on its website), most recently used first, paged by cursor: put an item's url in an image block or the theme's banner. Read-only.

Permissionengagement.read (Owner, Admin, Staff)
Riskread, OAuth scope skuflow.read. Read: reads only.
MCP toolemailDesigns_media (toolset marketing)

Parameters

NameInTypeRequiredDescription
cursorquerystringNoUp to 100 characters.
limitqueryintegerNo1–200.

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs/media" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY"

Response

200: the answer's fields
FieldTypeDescription
itemsarray of object
items[].idstring
items[].sourceenumOne of UPLOAD, STOCK.
items[].urlstringWhat to put in a section's image field.
items[].thumbUrlstring or null
items[].altstring
items[].widthinteger or null
items[].heightinteger or null
items[].providerstring or nullStock: UNSPLASH or PEXELS.
items[].providerIdstring or null
items[].authorstring or nullStock: the photographer, credited on the site.
items[].authorUrlstring or null
items[].sourceUrlstring or null
items[].createdAtstring (date-time)
items[].lastUsedAtstring (date-time)
nextCursorstring or null

Upload an email image

POST /organizations/{organizationId}/email-designs/image-upload-url

Step 1 of adding an image to an email: a signed URL to PUT the file to (same Content-Type) and the url to put in an image block. Then POST /email-designs/media/uploads. AI callers use POST /email-designs/media/content instead.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_createImageUploadUrl (toolset marketing)

Request body

FieldTypeRequiredDescription
contentTypeenumYesOne of image/jpeg, image/png, image/webp.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs/image-upload-url" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contentType":"image/jpeg"}'

Response

200: the answer's fields
FieldTypeDescription
signedUploadUrlstring (uri)
urlstring

Add an uploaded email image to the library

POST /organizations/{organizationId}/email-designs/media/uploads

Step 2 of uploading, after the PUT to the signed URL: the image joins the business's library. url must be one POST /email-designs/image-upload-url gave this business (404 otherwise).

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_confirmImageUpload (toolset marketing)

Request body

FieldTypeRequiredDescription
urlstringYesUp to 300 characters.
widthinteger or nullNo1–20000.
heightinteger or nullNo1–20000.
altstring or nullNoUp to 300 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs/media/uploads" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}'

Response

200: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of UPLOAD, STOCK.
urlstringWhat to put in a section's image field.
thumbUrlstring or null
altstring
widthinteger or null
heightinteger or null
providerstring or nullStock: UNSPLASH or PEXELS.
providerIdstring or null
authorstring or nullStock: the photographer, credited on the site.
authorUrlstring or null
sourceUrlstring or null
createdAtstring (date-time)
lastUsedAtstring (date-time)

Add an image for emails (content in the request)

POST /organizations/{organizationId}/email-designs/media/content

Adds a JPEG, PNG or WebP image to the business's library in one call: send contentBase64 or a public sourceUrl (up to 10 MB). Returns the library entry; put its url in an image block (PUT …/design) or the theme's bannerUrl.

Permissionengagement.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_uploadImage (toolset marketing)

Request body

FieldTypeRequiredDescription
altstring or nullNoAlternative text describing the image. Up to 300 characters.
fileNamestringNoThe file's name, e.g. receipt.jpg (default: from the URL, else 'file'). Up to 500 characters.
contentTypestringNoMIME type, e.g. image/jpeg or application/pdf. Optional: taken from a data: URL, the URL's answer or the file's first bytes. Up to 200 characters.
contentBase64stringNoThe file's bytes as base64 (a data: URL is accepted too). Up to 10 MB. Give this or sourceUrl.
sourceUrlstring (uri)NoA public http(s) URL SKUFlow downloads the file from (up to 10 MB, 20 s, 3 redirects; private and internal addresses are refused). Give this or contentBase64. Up to 2000 characters.

Example

curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/email-designs/media/content" \
  -H "Authorization: Bearer $SKUFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"alt":"string","fileName":"string","contentType":"string"}'

Response

201: the answer's fields
FieldTypeDescription
idstring
sourceenumOne of UPLOAD, STOCK.
urlstringWhat to put in a section's image field.
thumbUrlstring or null
altstring
widthinteger or null
heightinteger or null
providerstring or nullStock: UNSPLASH or PEXELS.
providerIdstring or null
authorstring or nullStock: the photographer, credited on the site.
authorUrlstring or null
sourceUrlstring or null
createdAtstring (date-time)
lastUsedAtstring (date-time)

On this page