Technical Specification: Website Registration → SFMC Integration

Executive Summary

When a user fills out and submits the registration form on the website, their information (name, email, opt-in status, timestamp, etc.) is sent to Salesforce Marketing Cloud (SFMC) and stored in a Data Extension — essentially a table within SFMC that holds subscriber data.

Once the data is in SFMC, the marketing team can:

The development team will handle the technical API integration on the website backend. The SFMC Admin will need to set up the Data Extension and provide API credentials. No SFMC credentials will be exposed on the website itself — all communication happens server-to-server.

What's needed from the marketing team:

What's needed from the SFMC Admin:


Purpose

This document defines the technical requirements for integrating a website registration form with Salesforce Marketing Cloud (SFMC) via the REST API. The integration will create/update subscriber records in a Data Extension (DE) and optionally trigger Journey Builder campaigns in real time.


1. Architecture Overview

plaintext
[Website Form] → [Web Backend] → [SFMC REST API] → [Data Extension] → [Journey Builder]
                      │
                      ├── 1. Request OAuth2 token (cached, refreshed on expiry)
                      ├── 2. POST registration payload to SFMC
                      └── 3. SFMC upserts DE row → Journey triggers (real-time or batch)

Key design decisions:


2. SFMC Admin Prerequisites

Before development begins, the SFMC Administrator must complete the following:

2.1 Create an Installed Package (API Integration)

  1. Navigate to Setup → Apps → Installed Packages
  2. Create a new Installed Package
  3. Add a component: API Integration (Server-to-Server)
  4. Assign the following scopes:
Scope Required For
Data Extensions (Read and Write) Upserting registration records into the DE
Journeys (Read) Reading journey definitions (if needed)
List and Subscribers (Read and Write) Managing subscriber status
Interactions (Execute) Triggering Journey Builder events (Path B only)

Deliverables to Dev team:

2.2 Create the Target Data Extension

  1. Create a Data Extension in SFMC (e.g., Web_Registrations)
  2. Mark it as Sendable (required for email sends via Journey Builder)
  3. Configure the following fields:
Field Name SFMC Data Type Primary Key? Nullable? Notes
SubscriberKey Text (254) Yes No Unique identifier. Use email address or a generated UUID. Must be unique per contact.
EmailAddress EmailAddress No No User's email address. Must be valid email format.
FirstName Text (100) No Yes User's first name
LastName Text (100) No Yes User's last name
OptInStatus Boolean No No true if user opted in to marketing communications, false otherwise. Default: false
RegistrationTimestamp Date No No ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ (UTC)
Source Text (50) No Yes Hardcoded: Website Registration
IPAddress Text (45) No Yes User's IP address for compliance/audit
UserAgent Text (255) No Yes Browser user agent string
PageURL Text (500) No Yes URL of the page where the form was submitted
  1. Configure Send Relationship: Map SubscriberKey_SubscriberKey and EmailAddressEmail Address

Deliverable to Dev team:

2.3 Configure Journey Builder Entry Source (Path B only — real-time)

If the journey should trigger immediately upon registration:

  1. Create or open the target Journey in Journey Builder
  2. Add an API Event entry source
  3. Configure the event to use the Data Extension created in step 2.2
  4. Map the incoming data fields

Deliverable to Dev team:


3. Authentication (OAuth 2.0 Server-to-Server)

SFMC uses OAuth 2.0 with the client_credentials grant type. The access token must be included as a Bearer token in all subsequent API calls.

3.1 Token Request

http
POST https://[YOUR_SUBDOMAIN].auth.marketingcloudapis.com/v2/token
Content-Type: application/json

{
  "grant_type": "client_credentials",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET",
  "account_id": "YOUR_MID"
}

3.2 Token Response

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsIn...",
  "token_type": "Bearer",
  "expires_in": 1199,
  "rest_instance_url": "https://[YOUR_SUBDOMAIN].rest.marketingcloudapis.com/"
}

3.3 Token Caching Strategy


4. Data Ingestion: Upsert to Data Extension

4.1 Endpoint (Synchronous)

This is the recommended endpoint for single-record upserts from a registration form. It uses the DE's External Key and the primary key field value to perform an upsert (insert if new, update if exists).

http
POST https://[YOUR_SUBDOMAIN].rest.marketingcloudapis.com/hub/v1/dataevents/key:[DE_EXTERNAL_KEY]/rowset
Authorization: Bearer [ACCESS_TOKEN]
Content-Type: application/json

4.2 Request Payload

The payload uses a keys object for the primary key field(s) and a values object for all other fields. If a record with the matching key already exists, the values fields are updated. If not, a new row is inserted.

json
[
  {
    "keys": {
      "SubscriberKey": "user@example.com"
    },
    "values": {
      "EmailAddress": "user@example.com",
      "FirstName": "Jane",
      "LastName": "Doe",
      "OptInStatus": true,
      "RegistrationTimestamp": "2026-06-23T14:52:45Z",
      "Source": "Website Registration",
      "IPAddress": "192.168.1.1",
      "UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
      "PageURL": "https://example.com/register"
    }
  }
]

4.3 Response

Success (200 OK):

json
{
  "results": [
    {
      "rows": 1,
      "errorcode": 0,
      "status": "OK"
    }
  ]
}

Validation Error (400 Bad Request):

json
{
  "results": [
    {
      "rows": 0,
      "errorcode": 1,
      "status": "Error",
      "message": "Unable to save rows for data extension..."
    }
  ]
}

4.4 Alternative: Asynchronous Upsert (High Traffic)

If the registration form receives high traffic or if the backend needs to decouple from SFMC response times, use the async endpoint instead:

http
POST https://[YOUR_SUBDOMAIN].rest.marketingcloudapis.com/data/v1/async/dataextensions/key:[DE_EXTERNAL_KEY]/rows
Authorization: Bearer [ACCESS_TOKEN]
Content-Type: application/json

Payload format differs slightly (flat object, no keys/values split):

json
{
  "items": [
    {
      "SubscriberKey": "user@example.com",
      "EmailAddress": "user@example.com",
      "FirstName": "Jane",
      "LastName": "Doe",
      "OptInStatus": true,
      "RegistrationTimestamp": "2026-06-23T14:52:45Z",
      "Source": "Website Registration"
    }
  ]
}

Note: The async endpoint returns a requestId that can be used to check the status of the operation. It does not guarantee immediate upsert — the data is queued and processed by SFMC. Use this only if you don't need synchronous confirmation.


5. Journey Builder Trigger (Real-Time Option)

If the journey should fire immediately upon registration (e.g., instant welcome email, double opt-in confirmation), use the Journey Builder Event API instead of (or in addition to) the DE upsert. This endpoint injects the contact into the journey and writes the data to the journey's backing DE in a single call.

5.1 Endpoint

http
POST https://[YOUR_SUBDOMAIN].rest.marketingcloudapis.com/interaction/v1/events
Authorization: Bearer [ACCESS_TOKEN]
Content-Type: application/json

5.2 Request Payload

json
{
  "ContactKey": "user@example.com",
  "EventDefinitionKey": "APIEvent-xxxx-xxxx-xxxx-xxxx",
  "EstablishContactKey": true,
  "Data": {
    "EmailAddress": "user@example.com",
    "FirstName": "Jane",
    "LastName": "Doe",
    "OptInStatus": true,
    "RegistrationTimestamp": "2026-06-23T14:52:45Z",
    "Source": "Website Registration"
  }
}

Field descriptions:

5.3 Response

Success (201 Created):

json
{
  "eventInstanceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

5.4 Path A vs Path B Decision Guide

Criteria Path A (DE Upsert Only) Path B (Journey Event API)
Real-time journey trigger No — requires batch automation Yes — fires immediately
Data stored in DE Yes Yes (journey's backing DE)
Use case Audience building, segmentation, scheduled sends Welcome emails, double opt-in, transactional sends
API calls per registration 1 (auth + upsert) 1 (auth + event)
Complexity Lower Slightly higher (requires SFMC Admin to configure API Event)
Recommended for Newsletter signups, lead capture Immediate confirmation/welcome flows

Recommendation: If you need an immediate welcome email or double opt-in confirmation, use Path B. If you just need to collect data for audience building and scheduled campaigns, use Path A. You can also use both — upsert to a primary DE for record-keeping (Path A) and fire the journey event (Path B) for the immediate send.


6. Error Handling Requirements

The Dev team must implement handling for the following HTTP response codes:

HTTP Status Meaning Required Action
200 / 201 Success Log success, continue
400 Bad Request — payload schema mismatch, missing required field, or invalid data type Log the full request payload and response body. Do not retry — fix the payload.
401 Unauthorized — token expired or invalid Refresh the OAuth2 token and retry the request once. If the retry also returns 401, alert the team (credentials may be invalid).
403 Forbidden — insufficient scopes or IP not allowlisted Check Installed Package scopes. SFMC may require IP allowlisting for API access.
409 Conflict — duplicate primary key (sync endpoint) Typically handled by the upsert logic. If using insert-only, treat as a duplicate and skip.
429 Too Many Requests — rate limit exceeded Implement exponential backoff retry (e.g., 1s, 2s, 4s, 8s). Log and alert if retries are exhausted.
500 / 502 / 503 SFMC server error Retry with exponential backoff (up to 3 attempts). If all retries fail, queue the payload for later processing.

6.1 Retry & Queue Strategy


7. Security Requirements


8. Data Flow Summary

plaintext
1. User submits registration form on website
2. Web backend validates input (email format, required fields, sanitization)
3. Web backend checks cached OAuth2 token:
   a. If valid → use cached token
   b. If expired → request new token from SFMC auth endpoint
4. Web backend constructs JSON payload with registration data
5. Web backend sends POST to SFMC REST API:
   a. Path A: /hub/v1/dataevents/key:[DE_KEY]/rowset (DE upsert)
   b. Path B: /interaction/v1/events (Journey trigger)
6. SFMC processes the request:
   a. Path A: Upserts row in Data Extension
   b. Path B: Injects contact into Journey + writes to backing DE
7. Web backend handles response:
   a. Success → log and return success to user
   b. Error → retry (401/429/5xx) or queue for later (400/persistent failures)
8. SFMC Admin uses DE data for:
   a. Audience segmentation and filtering
   b. Journey Builder entry sources (batch automations)
   c. Email send definitions

9. Open Questions for Stakeholders

  1. Journey timing: Should the welcome/confirmation email send immediately (Path B) or is a batch/scheduled send acceptable (Path A)?
  2. Subscriber Key strategy: Will EmailAddress serve as the SubscriberKey, or will you use a generated UUID/internal user ID? This must be consistent across all SFMC integrations.
  3. Double opt-in: Does the registration require email verification (double opt-in) before the contact is considered active? If so, the journey should include a verification email step.
  4. Additional fields: Are there any fields beyond what's listed in the DE schema (Section 2.2) that need to be captured (e.g., phone number, company name, country, marketing preferences)?
  5. Existing contacts: How should the integration handle a user who already exists in SFMC with a different email? Should it update, skip, or create a duplicate?
  6. Compliance: Are there GDPR/CAN-SPAM/CASL requirements for consent capture and timestamp logging that need additional fields or workflows?