DevelopersAPI reference

Marketing API

REST endpoints for marketing in SKUFlow: 4 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 a campaign email's designGET /organizations/{organizationId}/marketing/campaigns/{campaignId}/designread
Save a campaign email's designPUT /organizations/{organizationId}/marketing/campaigns/{campaignId}/designwrite
Reset a campaign email's designDELETE /organizations/{organizationId}/marketing/campaigns/{campaignId}/designsensitive
Draft a campaign email's design with AIPOST /organizations/{organizationId}/marketing/campaigns/{campaignId}/design/draftwrite

Get a campaign email's design

GET /organizations/{organizationId}/marketing/campaigns/{campaignId}/design

The campaign email's block design (custom: true) or the starter (custom: false). A campaign's own blocks may replace its message; the footer (address and unsubscribe) stays. Read-only.

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

Parameters

NameInTypeRequiredDescription
campaignIdpathstringYesA marketing campaign id, from GET /marketing/campaigns.

Example

curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/marketing/campaigns/{campaignId}/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 a campaign email's design

PUT /organizations/{organizationId}/marketing/campaigns/{campaignId}/design

Replaces the campaign email's design (a draft or scheduled campaign only; 400 otherwise). Customers get it when the campaign sends. Sends nothing.

Permissionmarketing.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_updateCampaign (toolset marketing)
PlanMarketing campaigns: the Grow plan and up.

Parameters

NameInTypeRequiredDescription
campaignIdpathstringYesA marketing campaign id, from GET /marketing/campaigns.

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/marketing/campaigns/{campaignId}/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 a campaign email's design

DELETE /organizations/{organizationId}/marketing/campaigns/{campaignId}/design

Destructive: deletes the campaign email's own design (a draft or scheduled campaign only); it goes back to the default design with the campaign's text.

Permissionmarketing.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_resetCampaign (toolset marketing)
ApprovalOver MCP, this tool always waits for your approval in SKUFlow. See Approvals.

Parameters

NameInTypeRequiredDescription
campaignIdpathstringYesA marketing campaign id, from GET /marketing/campaigns.

Example

curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/marketing/campaigns/{campaignId}/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

Draft a campaign email's design with AI

POST /organizations/{organizationId}/marketing/campaigns/{campaignId}/design/draft

Claude lays out the campaign email as blocks from a short request ("summer promo, bold, with a coupon button"): a heading and short text around the campaign's message, buttons to the business's own links, images from its library; no prices, discounts or coupon codes that the request or the campaign text does not state. The footer (address and unsubscribe) is kept. Needs the campaigns feature. Uses AI credits (402 when none are left); source TEMPLATE when AI is off. Nothing is saved: preview with POST /email-designs/preview document and campaignId, save with PUT …/marketing/campaigns/{campaignId}/design.

Permissionmarketing.manage (Owner, Admin)
Riskwrite, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it.
MCP toolemailDesigns_draftCampaignDesign (toolset marketing)
PlanMarketing campaigns: the Grow plan and up.

Parameters

NameInTypeRequiredDescription
campaignIdpathstringYesA marketing campaign id, from GET /marketing/campaigns.

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/marketing/campaigns/{campaignId}/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.

On this page