SFMC Engagement Development
Generate production-grade Salesforce Marketing Cloud Engagement artifacts — AMPscript, Server-Side JavaScript, REST/SOAP API clients, Journey Builder configurations, Automation Studio workflows, and data extension models — with correct syntax, governor / throttle awareness, and an understanding of the SFMC security and business-unit model.
Before Writing Any Code
Identify the SFMC surface. Is this:
- Content personalization inside an email or CloudPage (AMPscript or SSJS)?
- An automation — Query Activity, Filter, Data Extract, Script Activity?
- A journey — entry source, activities, decision splits, goals?
- An external integration — REST / SOAP API from an outside system (Salesforce core, a web app, an ERP)?
- A Marketing Cloud Connect sync with core Salesforce?
The answer changes which reference doc matters most.
Identify the data model. SFMC separates Lists (legacy, flat) from Data Extensions (relational, modern). Contacts are keyed by Subscriber Key, not email — email is just an attribute. Sendable DEs require a SubscriberKey relationship. Get this wrong and sends fail silently or send to the wrong audience.
Read reference/data-extensions/de-vs-list.md and reference/data-extensions/sendable-des.md.
Identify the business unit. Multi-BU orgs route sends, automations, and packages per BU. An installed package / API integration lives at Enterprise level but operates against specific BUs via mid= headers / businessUnit overrides. Cross-BU data visibility depends on Enterprise 2.0 configuration.
Read reference/apis/business-units-and-packages.md.
Identify the auth flow. Modern SFMC uses OAuth 2.0 via Installed Packages. Two modes:
client_credentials — server-to-server, no user context, simplest.
jwt_bearer — user-context integrations, MFA-compatible, required for some scopes.
Read reference/apis/oauth-flows.md.
AMPscript vs SSJS — choose deliberately
| Dimension |
AMPscript |
Server-Side JavaScript |
| Runs in |
Emails, CloudPages, some automations |
Emails, CloudPages, Script Activities |
| Syntax |
%%[ ... ]%% blocks, inline %%=...=%% |
<script runat="server" language="javascript"> ... </script> |
| Ergonomics |
Terse but peculiar; good for personalization |
Full JS; good for logic, HTTP calls, JSON |
| Speed |
Faster for simple lookups |
Slower; use for logic that AMPscript can't express |
| HTTP callouts |
Limited |
Core.HTTP.*, WSProxy (SOAP) |
| DE manipulation |
Lookup, LookupRows, UpsertData, InsertData, UpdateData |
Platform.Function.Lookup, WSProxy.retrieve/create/update |
Default rule: use AMPscript for personalization inside email/CloudPage content. Use SSJS when you need JSON handling, external HTTP, or complex logic. Do not mix modes inside a single block unnecessarily — pick one per content area.
Read reference/ampscript/ampscript-language-overview.md and reference/ssjs/ssjs-core-library.md before choosing.
Journey Builder Rules
- Re-entry mode matters. "No re-entry" vs "Re-entry anytime" vs "Re-entry only after exiting" — choosing wrong traps or double-sends contacts.
- Wait By Attribute ≠ Wait By Duration. Wait By Attribute references a datetime on the contact record and waits until that moment; Wait By Duration is a fixed delta. Use the former for "send N days before birthday," never a calculated delta.
- Goals evaluate on exit, not continuously (unless configured otherwise). Understand "goal met = contact exits" semantics before depending on them.
- Transactional journeys (via Transactional Messaging API) are a separate system — real-time, no throttling via send classifications, different audit trail.
Read reference/journey-builder/journey-configuration.md, reference/journey-builder/re-entry-and-goals.md, and reference/journey-builder/transactional-messaging-api.md.
Data Extension Rules
- Sendable DE requires a primary key AND a SubscriberKey relationship mapping. Without it, the DE doesn't appear in the Send flow.
- Relational DEs work like database tables — join via
LookupRows in AMPscript, Retrieve with filters in SSJS/SOAP. Plan your keys before you load data.
- Retention policies apply per-DE and delete data automatically. Defaults are aggressive; verify retention on every new DE or you'll silently lose history.
- Shared DEs (Enterprise 2.0) let child BUs read from parent DEs. Write permissions and override semantics matter.
Read reference/data-extensions/de-structure-and-keys.md and reference/data-extensions/retention-policies.md.
Automation Studio Rules
- Query Activities run SQL (ANSI-SQL-ish dialect) against DEs. Target must exist and have matching columns. No joins across BUs (unless shared DE).
- File Drop automations fire when a file lands in the Enhanced FTP. Filename masking with wildcards is your main trigger filter.
- Scheduled vs Triggered — schedule for time-based recurrence; trigger for event-driven. A single automation can have both (e.g., a scheduled nightly run with a manual trigger-on-demand option).
- Error notifications go to the "Run As" user by default — verify that's a real monitored mailbox, not someone who left.
Read reference/automation-studio/automation-activities.md and reference/automation-studio/scheduling-and-triggering.md (TODO).
API Rules
- Always use the installed-package OAuth flow. No username/password API auth in modern SFMC.
- The REST token endpoint is tenant-specific:
https://<your-tenant-subdomain>.auth.marketingcloudapis.com/v2/token. Do not hardcode auth.exacttargetapis.com or similar — that was the legacy shared endpoint.
- REST is JSON and covers Assets, Journeys, Contacts, Transactional Messaging. SOAP covers Retrieves, Sends, Subscribers, DE rows — still required for many operations.
- Rate limits apply per package per minute. Back off on 429s with exponential delay.
Read reference/apis/rest-api-overview.md, reference/apis/soap-api-overview.md, and reference/apis/oauth-flows.md.
Marketing Cloud Connect
- MC Connect is a managed package installed in core Salesforce that connects to SFMC. Enables sending from Salesforce (via the Send Email button, triggered sends, journey entry), syncing reports, and exposing Contact/Lead data to SFMC.
- Sync data sources replicate Salesforce objects to Synchronized Data Extensions — different from regular DEs, read-only, auto-updating.
- The MC Connect user (in Salesforce) needs specific permissions: "Marketing Cloud User" checkbox on the User record, plus access to MC-related objects.
- Do not rely on MC Connect for high-volume real-time sync — it's batch-oriented. For real-time, use the REST API directly from Apex / Flow.
Read reference/mc-connect/mc-connect-overview.md and reference/mc-connect/sync-data-extensions.md (TODO).
Code Style
- AMPscript: block style with
%%[ ... ]%%, one statement per line, meaningful variable names (@firstName, not @x). Always wrap Lookup / LookupRows in a null-check or IIF fallback.
- SSJS: wrap in
Platform.Load("Core", "1.1.1") when using Core library. Use try/catch around HTTP calls. Never debug in production templates — remove before going live.
- Apex (for REST client): Named Credential for the token endpoint and the REST base URL. Token caching in a
Cache.Org partition — MC tokens last ~20 minutes, don't re-auth on every callout. HttpCallout-based client with typed response wrappers.
- JavaScript (for Node client): use the official
fuel-rest / fuel-soap SDKs or a thin axios wrapper. Implement token refresh-on-401.
Reference Docs
Read the relevant reference doc BEFORE generating code. Files marked (TODO) are scaffolded but not yet distilled — pull official docs via exa.ai and distill per scripts/distillation-template.md.
| Topic |
File |
| Journey configuration (entry, activities, goals) |
reference/journey-builder/journey-configuration.md |
| Re-entry modes and goals |
reference/journey-builder/re-entry-and-goals.md |
| Transactional Messaging API |
reference/journey-builder/transactional-messaging-api.md |
| Email Studio content and sends |
reference/email-studio/email-studio-overview.md (TODO) |
| Send classifications and throttling |
reference/email-studio/send-classifications.md |
| Automation Studio activities |
reference/automation-studio/automation-activities.md |
| Scheduling and triggering |
reference/automation-studio/scheduling-and-triggering.md (TODO) |
| AMPscript language overview |
reference/ampscript/ampscript-language-overview.md |
| AMPscript personalization patterns |
reference/ampscript/personalization-patterns.md (TODO) |
| AMPscript Lookup / LookupRows / UpsertData |
reference/ampscript/lookup-and-data-functions.md |
| SSJS Core library |
reference/ssjs/ssjs-core-library.md |
| SSJS WSProxy (SOAP via JS) |
reference/ssjs/wsproxy.md |
| CloudPage types and SmartCapture |
reference/cloudpages/cloudpage-overview.md |
| DE vs List |
reference/data-extensions/de-vs-list.md |
| Sendable DE setup |
reference/data-extensions/sendable-des.md |
| DE structure and keys |
reference/data-extensions/de-structure-and-keys.md |
| Retention policies |
reference/data-extensions/retention-policies.md |
| REST API overview |
reference/apis/rest-api-overview.md |
| SOAP API overview |
reference/apis/soap-api-overview.md |
| OAuth flows (client_credentials, JWT) |
reference/apis/oauth-flows.md |
| Business Units and installed packages |
reference/apis/business-units-and-packages.md |
| MC Connect overview |
reference/mc-connect/mc-connect-overview.md |
| Sync data extensions |
reference/mc-connect/sync-data-extensions.md (TODO) |
| Common pitfalls |
reference/common-pitfalls.md |
Templates
Use these as starting points when generating integrations:
| Pattern |
Directory |
| AMPscript personalization block |
templates/ampscript-personalization/ |
| SSJS data retrieve + HTTP |
templates/ssjs-data-retrieve/ (TODO) |
| REST API OAuth + Journey API (Node) |
templates/rest-api-oauth-node/ (TODO) |
| REST API OAuth (Apex + Named Credential) |
templates/rest-api-oauth-apex/ |
| Fire a Journey from Salesforce |
templates/journey-api-entry/ (TODO) |
| Query Activity SQL + target DE |
templates/sql-query-activity/ (TODO) |
Checklists
Offer relevant checklists when setting up or going live:
| Checklist |
File |
| New journey checklist |
checklists/new-journey-checklist.md (TODO) |
| Production go-live |
checklists/mc-production-go-live.md (TODO) |
| API package setup |
checklists/mc-api-package-setup.md |
1---2name: sfmc-engagement3description: Build Salesforce Marketing Cloud Engagement (classic SFMC) integrations and content — Journey Builder journeys, Email Studio sends, Mobile Studio messages, Automation Studio activities, AMPscript personalization, Server-Side JavaScript, CloudPages, Data Extensions, REST/SOAP APIs, and Marketing Cloud Connect to core Salesforce. Use this skill whenever the user mentions SFMC, Marketing Cloud, Marketing Cloud Engagement, Journey Builder, Email Studio, Mobile Studio, Automation Studio, Content Builder, CloudPage, AMPscript, SSJS, Server-Side JavaScript, Data Extension, DE, sendable DE, relational DE, Query Activity, SQL Query Activity, Data Extract, File Import, Filter Activity, Script Activity, subscriber, subscriber key, Contact Builder, list, publication list, REST API (Marketing Cloud), SOAP API, Fuel SDK, WSProxy, installed package, OAuth 2.0 with SFMC, JWT bearer, client_credentials, send classification, delivery profile, sender profile, Marketing Cloud Connect, MC Connect, sync data source, Journey Builde4---56# SFMC Engagement Development78Generate production-grade Salesforce Marketing Cloud Engagement artifacts — AMPscript, Server-Side JavaScript, REST/SOAP API clients, Journey Builder configurations, Automation Studio workflows, and data extension models — with correct syntax, governor / throttle awareness, and an understanding of the SFMC security and business-unit model.910## Before Writing Any Code11121. **Identify the SFMC surface.** Is this:13 - **Content personalization** inside an email or CloudPage (AMPscript or SSJS)?14 - **An automation** — Query Activity, Filter, Data Extract, Script Activity?15 - **A journey** — entry source, activities, decision splits, goals?16 - **An external integration** — REST / SOAP API from an outside system (Salesforce core, a web app, an ERP)?17 - **A Marketing Cloud Connect** sync with core Salesforce?1819 The answer changes which reference doc matters most.20212. **Identify the data model.** SFMC separates *Lists* (legacy, flat) from *Data Extensions* (relational, modern). Contacts are keyed by **Subscriber Key**, not email — email is just an attribute. Sendable DEs require a `SubscriberKey` relationship. Get this wrong and sends fail silently or send to the wrong audience.22 Read `reference/data-extensions/de-vs-list.md` and `reference/data-extensions/sendable-des.md`.23243. **Identify the business unit.** Multi-BU orgs route sends, automations, and packages per BU. An installed package / API integration lives at Enterprise level but operates against specific BUs via `mid=` headers / `businessUnit` overrides. Cross-BU data visibility depends on Enterprise 2.0 configuration.25 Read `reference/apis/business-units-and-packages.md`.26274. **Identify the auth flow.** Modern SFMC uses OAuth 2.0 via **Installed Packages**. Two modes:28 - **`client_credentials`** — server-to-server, no user context, simplest.29 - **`jwt_bearer`** — user-context integrations, MFA-compatible, required for some scopes.30 Read `reference/apis/oauth-flows.md`.3132## AMPscript vs SSJS — choose deliberately3334| Dimension | AMPscript | Server-Side JavaScript |35|---|---|---|36| Runs in | Emails, CloudPages, some automations | Emails, CloudPages, Script Activities |37| Syntax | `%%[ ... ]%%` blocks, inline `%%=...=%%` | `<script runat="server" language="javascript"> ... </script>` |38| Ergonomics | Terse but peculiar; good for personalization | Full JS; good for logic, HTTP calls, JSON |39| Speed | Faster for simple lookups | Slower; use for logic that AMPscript can't express |40| HTTP callouts | Limited | `Core.HTTP.*`, `WSProxy` (SOAP) |41| DE manipulation | `Lookup`, `LookupRows`, `UpsertData`, `InsertData`, `UpdateData` | `Platform.Function.Lookup`, `WSProxy.retrieve/create/update` |4243**Default rule:** use AMPscript for personalization inside email/CloudPage content. Use SSJS when you need JSON handling, external HTTP, or complex logic. Do not mix modes inside a single block unnecessarily — pick one per content area.4445Read `reference/ampscript/ampscript-language-overview.md` and `reference/ssjs/ssjs-core-library.md` before choosing.4647## Journey Builder Rules4849- **Re-entry mode matters.** "No re-entry" vs "Re-entry anytime" vs "Re-entry only after exiting" — choosing wrong traps or double-sends contacts.50- **Wait By Attribute ≠ Wait By Duration.** Wait By Attribute references a datetime on the contact record and waits until that moment; Wait By Duration is a fixed delta. Use the former for "send N days before birthday," never a calculated delta.51- **Goals evaluate on exit, not continuously** (unless configured otherwise). Understand "goal met = contact exits" semantics before depending on them.52- **Transactional journeys** (via Transactional Messaging API) are a separate system — real-time, no throttling via send classifications, different audit trail.5354Read `reference/journey-builder/journey-configuration.md`, `reference/journey-builder/re-entry-and-goals.md`, and `reference/journey-builder/transactional-messaging-api.md`.5556## Data Extension Rules5758- **Sendable DE requires** a primary key AND a SubscriberKey relationship mapping. Without it, the DE doesn't appear in the Send flow.59- **Relational DEs** work like database tables — join via `LookupRows` in AMPscript, `Retrieve` with filters in SSJS/SOAP. Plan your keys before you load data.60- **Retention policies** apply per-DE and delete data automatically. Defaults are aggressive; verify retention on every new DE or you'll silently lose history.61- **Shared DEs** (Enterprise 2.0) let child BUs read from parent DEs. Write permissions and override semantics matter.6263Read `reference/data-extensions/de-structure-and-keys.md` and `reference/data-extensions/retention-policies.md`.6465## Automation Studio Rules6667- **Query Activities** run SQL (ANSI-SQL-ish dialect) against DEs. Target must exist and have matching columns. No joins across BUs (unless shared DE).68- **File Drop automations** fire when a file lands in the Enhanced FTP. Filename masking with wildcards is your main trigger filter.69- **Scheduled vs Triggered** — schedule for time-based recurrence; trigger for event-driven. A single automation can have both (e.g., a scheduled nightly run with a manual trigger-on-demand option).70- **Error notifications** go to the "Run As" user by default — verify that's a real monitored mailbox, not someone who left.7172Read `reference/automation-studio/automation-activities.md` and `reference/automation-studio/scheduling-and-triggering.md` (TODO).7374## API Rules7576- Always use the **installed-package OAuth flow**. No username/password API auth in modern SFMC.77- The **REST token endpoint** is *tenant-specific*: `https://<your-tenant-subdomain>.auth.marketingcloudapis.com/v2/token`. Do not hardcode `auth.exacttargetapis.com` or similar — that was the legacy shared endpoint.78- REST is JSON and covers **Assets, Journeys, Contacts, Transactional Messaging**. SOAP covers **Retrieves, Sends, Subscribers, DE rows** — still required for many operations.79- Rate limits apply per package per minute. Back off on 429s with exponential delay.8081Read `reference/apis/rest-api-overview.md`, `reference/apis/soap-api-overview.md`, and `reference/apis/oauth-flows.md`.8283## Marketing Cloud Connect8485- **MC Connect** is a managed package installed in core Salesforce that connects to SFMC. Enables sending from Salesforce (via the Send Email button, triggered sends, journey entry), syncing reports, and exposing Contact/Lead data to SFMC.86- Sync data sources replicate Salesforce objects to **Synchronized Data Extensions** — different from regular DEs, read-only, auto-updating.87- The MC Connect user (in Salesforce) needs specific permissions: "Marketing Cloud User" checkbox on the User record, plus access to MC-related objects.88- **Do not rely on MC Connect** for high-volume real-time sync — it's batch-oriented. For real-time, use the REST API directly from Apex / Flow.8990Read `reference/mc-connect/mc-connect-overview.md` and `reference/mc-connect/sync-data-extensions.md` (TODO).9192## Code Style9394- **AMPscript**: block style with `%%[ ... ]%%`, one statement per line, meaningful variable names (`@firstName`, not `@x`). Always wrap `Lookup` / `LookupRows` in a null-check or `IIF` fallback.95- **SSJS**: wrap in `Platform.Load("Core", "1.1.1")` when using Core library. Use `try/catch` around HTTP calls. Never `debug` in production templates — remove before going live.96- **Apex (for REST client)**: Named Credential for the token endpoint and the REST base URL. Token caching in a `Cache.Org` partition — MC tokens last ~20 minutes, don't re-auth on every callout. `HttpCallout`-based client with typed response wrappers.97- **JavaScript (for Node client)**: use the official `fuel-rest` / `fuel-soap` SDKs or a thin `axios` wrapper. Implement token refresh-on-401.9899## Reference Docs100101Read the relevant reference doc BEFORE generating code. Files marked (TODO) are scaffolded but not yet distilled — pull official docs via exa.ai and distill per `scripts/distillation-template.md`.102103| Topic | File |104|---|---|105| Journey configuration (entry, activities, goals) | `reference/journey-builder/journey-configuration.md` |106| Re-entry modes and goals | `reference/journey-builder/re-entry-and-goals.md` |107| Transactional Messaging API | `reference/journey-builder/transactional-messaging-api.md` |108| Email Studio content and sends | `reference/email-studio/email-studio-overview.md` (TODO) |109| Send classifications and throttling | `reference/email-studio/send-classifications.md` |110| Automation Studio activities | `reference/automation-studio/automation-activities.md` |111| Scheduling and triggering | `reference/automation-studio/scheduling-and-triggering.md` (TODO) |112| AMPscript language overview | `reference/ampscript/ampscript-language-overview.md` |113| AMPscript personalization patterns | `reference/ampscript/personalization-patterns.md` (TODO) |114| AMPscript Lookup / LookupRows / UpsertData | `reference/ampscript/lookup-and-data-functions.md` |115| SSJS Core library | `reference/ssjs/ssjs-core-library.md` |116| SSJS WSProxy (SOAP via JS) | `reference/ssjs/wsproxy.md` |117| CloudPage types and SmartCapture | `reference/cloudpages/cloudpage-overview.md` |118| DE vs List | `reference/data-extensions/de-vs-list.md` |119| Sendable DE setup | `reference/data-extensions/sendable-des.md` |120| DE structure and keys | `reference/data-extensions/de-structure-and-keys.md` |121| Retention policies | `reference/data-extensions/retention-policies.md` |122| REST API overview | `reference/apis/rest-api-overview.md` |123| SOAP API overview | `reference/apis/soap-api-overview.md` |124| OAuth flows (client_credentials, JWT) | `reference/apis/oauth-flows.md` |125| Business Units and installed packages | `reference/apis/business-units-and-packages.md` |126| MC Connect overview | `reference/mc-connect/mc-connect-overview.md` |127| Sync data extensions | `reference/mc-connect/sync-data-extensions.md` (TODO) |128| Common pitfalls | `reference/common-pitfalls.md` |129130## Templates131132Use these as starting points when generating integrations:133134| Pattern | Directory |135|---|---|136| AMPscript personalization block | `templates/ampscript-personalization/` |137| SSJS data retrieve + HTTP | `templates/ssjs-data-retrieve/` (TODO) |138| REST API OAuth + Journey API (Node) | `templates/rest-api-oauth-node/` (TODO) |139| REST API OAuth (Apex + Named Credential) | `templates/rest-api-oauth-apex/` |140| Fire a Journey from Salesforce | `templates/journey-api-entry/` (TODO) |141| Query Activity SQL + target DE | `templates/sql-query-activity/` (TODO) |142143## Checklists144145Offer relevant checklists when setting up or going live:146147| Checklist | File |148|---|---|149| New journey checklist | `checklists/new-journey-checklist.md` (TODO) |150| Production go-live | `checklists/mc-production-go-live.md` (TODO) |151| API package setup | `checklists/mc-api-package-setup.md` |