Oracle Responsys
Sync contacts, enrich profile data, and trigger personalized email campaigns in Oracle Responsys (Oracle Marketing Cloud). Zeotap merges records into Profile Lists, Profile Extension Tables (PETs), and Supplemental Tables, fires custom events, and launches triggered email campaigns — all through the Responsys REST API (v1.3).
Prerequisites
- An Oracle Responsys account with REST API access enabled
- A dedicated API user (create one in Responsys under Account > Users)
- Your account’s login endpoint (the “WS End Point”), found under Account > Global Settings > Account Configuration (for example
https://login2.responsys.netorhttps://login5.responsys.net) - For Campaign Launch: a published email campaign (EMD) and a profile list the recipients belong to
Authentication
Responsys uses Username / Password token authentication.
- In Responsys, create a dedicated API user under Account > Users.
- Find your login endpoint under Account > Global Settings (for example
https://login2.responsys.net). - In Zeotap, enter the API Username, Password, and Authentication Endpoint.
Zeotap exchanges your username and password for a short-lived auth token (valid ~2 hours) and automatically discovers the account-specific REST API endpoint from the login response. You never need to re-authenticate manually — Zeotap stores your credentials securely and mints a fresh token on demand for every sync, refreshing transparently mid-run so long syncs never stall. Optionally override the discovered REST endpoint under the destination’s advanced configuration.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| Authentication Endpoint | Text | Yes | The Responsys login server URL (for example https://login2.responsys.net). |
| REST API Endpoint | Text | No | Override the REST API base URL. Leave blank to use the endpoint returned at login. |
| Default Folder | Text | No | Default Responsys folder for lists and tables that do not include an explicit path. |
Target Settings
The Object Type you choose determines which additional settings appear. List, PET, table, folder, campaign, and event pickers are populated live from your Responsys account, so you can select from real objects instead of typing names.
| Field | Type | Required | Description |
|---|---|---|---|
| Object Type | Select | Yes | Profile List, Profile Extension Table, Supplemental Table, Custom Event, or Campaign Launch (Triggered Email). |
| Profile List Name | Select | Conditional | The profile list to sync to. Required for Profile List, PET, and Campaign Launch. Populated from your account. |
| Profile Extension Table Name | Select | Conditional | The PET linked to the list. Required for Profile Extension Table. Populated from the selected list. |
| Supplemental Table Name | Select | Conditional | The supplemental table to sync to. Required for Supplemental Table. |
| Email Campaign | Select | Conditional | The email campaign to trigger. Required for Campaign Launch. Populated from your account. |
| Folder Name | Select | No | Folder containing the target table or list. Overrides the default folder. |
| Custom Event Name | Select | Conditional | The custom event to fire. Required for Custom Event (which also requires a Profile List — recipients are resolved against it). |
| Match Column | Select | No | Primary column used to match records: RIID_, EMAIL_ADDRESS_, CUSTOMER_ID_, MOBILE_NUMBER_, EMAIL_MD5_HASH_, or EMAIL_SHA256_HASH_. Defaults to EMAIL_ADDRESS_. |
| Second Match Column | Select | No | Optional second column for composite-key matching (same options as Match Column, plus None). When set, a record matches only when both columns match. Select None (the default) for single-column matching. |
| Match Operator | Select | No | How the two match columns combine when a Second Match Column is set: AND (both must match) or NONE (single column). Defaults to AND. |
| Reject Records With Empty Channel | Select | No | Optionally drop records that have no value for a delivery channel (Reject if Email empty / Reject if Mobile empty). Defaults to None, so records keyed by Customer ID / RIID / mobile without an email are still merged. Applies to Profile List merges. |
| Insert On No Match | Toggle | No | Insert a new record when no match is found. Enabled by default. |
| Update On Match | Select | No | REPLACE_ALL overwrites matched records; NO_UPDATE leaves them unchanged. |
| Add Recipients To Profile List Before Firing | Toggle | No | Custom Event only. Merge each batch into the connected profile list before firing the event, so recipients who are not yet list members are created rather than rejected. Off by default. |
| Use Async API (large volumes) | Toggle | No | Submit merges through Responsys’s asynchronous API and poll for completion instead of the synchronous merge. Recommended for large loads that time out synchronously. Applies to Profile List, PET, and Supplemental Table syncs. |
Supported Operations
Sync Modes: Upsert, Insert, Update
Upsert inserts new members and updates existing ones. Insert only adds new members (matched records are left unchanged). Update only updates matched members (no new records inserted). Campaign Launch supports Insert / Add only.
Audience Sync Modes: Add, Remove, Mirror, Upsert
For Profile Lists, Remove and Mirror removals delete the matched members from the list; for PETs they delete the matched PET rows (not the parent list member). Records are identified by the configured Match Column (RIID_, EMAIL_ADDRESS_, CUSTOMER_ID_, or MOBILE_NUMBER_); deletion by a hashed-email match column is not supported by Responsys and is reported as an error. (Supplemental Tables and Custom Events have no removal API.)
Features
- Field Mapping: Yes
- Schema Introspection: Yes — Zeotap fetches the real column set of the selected Profile List, PET, or Supplemental Table so mapping suggestions match your destination.
- Dynamic Target Fields: Yes — list, PET, table, folder, campaign, and event pickers load live from your account.
Required Mapping Fields
| Object | Required Fields |
|---|---|
| Profile List / PET | A recipient identifier: EMAIL_ADDRESS_, or one of RIID_, CUSTOMER_ID_, MOBILE_NUMBER_ |
| Custom Event / Campaign Launch | A recipient identifier: EMAIL_ADDRESS_, or one of RIID_, CUSTOMER_ID_, MOBILE_NUMBER_ |
| Supplemental Table | None — the table is matched on its own declared primary key |
Every object type that addresses a person needs an identifier: a merge has nothing to match on without one, and a Custom Event or Campaign Launch cannot resolve a recipient — Responsys rejects the row with a per-recipient message that says nothing about the mapping. A send with no identifier column mapped is therefore failed by Zeotap before it reaches Responsys, and before any merge step runs, so identity-less rows are never upserted into your profile list.
Default Destination Fields
The four recipient identifiers — RIID_, EMAIL_ADDRESS_, CUSTOMER_ID_, MOBILE_NUMBER_ — are suggested for every object type, because every object type delivers them: merges match on them, Custom Event and Campaign Launch build the Responsys recipient block out of them, and a Supplemental Table sends them as ordinary columns.
The remaining profile-list columns — EMAIL_PERMISSION_STATUS_, POSTAL_STREET_1_, POSTAL_STREET_2_, CITY_, STATE_, POSTAL_CODE_, COUNTRY_ — are suggested only when Object Type is Profile List, since they are columns of the list itself. Map one under a Custom Event or Campaign Launch and the editor flags it as ignored at delivery: it would travel as event data or a personalization variable, and Responsys drops it unless the event or campaign declares a field of that name.
How It Works
Merges (Profile List / PET / Supplemental Table). Zeotap batches rows into groups of 200 (the Responsys per-request maximum) and merges them via POST /rest/api/v1.3/lists/{list}/members (or the PET / supplemental-table equivalent). The merge rule is derived from the sync mode — Upsert sets insertOnNoMatch: true + updateOnMatch: REPLACE_ALL, Insert sets updateOnMatch: NO_UPDATE, Update sets insertOnNoMatch: false. A Responsys HTTP 200 does not guarantee every record succeeded: Zeotap inspects the per-record response and surfaces any row prefixed MERGEFAILED: as a row-level error rather than counting it as a success.
Campaign Launch (Triggered Email). The email’s template and design live in the Responsys campaign; Zeotap sends one personalized message per recipient row. For each batch it first merges the rows into the connected profile list (so brand-new audience members exist), then triggers the campaign via POST /rest/api/v1.3/campaigns/{campaign}/email. Identifier fields (EMAIL_ADDRESS_, RIID_, CUSTOMER_ID_, MOBILE_NUMBER_) identify the recipient; every other mapped field is passed as a dynamic content variable (optionalData) that fills the matching personalization token in the campaign template.
Custom Events. Rows are sent to POST /rest/api/v1.3/events/{event} with identifiers routed to the recipient block (anchored to the configured Profile List via listName), and remaining fields carried as optionalData — useful for triggering Program orchestrations that listen for the event.
By default the event is fired as-is: Responsys resolves each recipient against the anchored profile list and rejects anyone who is not already a member, which surfaces as a row-level error. Enable Add Recipients To Profile List Before Firing to get the same merge-then-send behavior as Campaign Launch — each batch is upserted into the profile list first, then the event fires for that batch. Only profile columns — the columns that actually exist on the connected list, resolved from its schema — are merged, and they then travel only in the merge — the event carries the remaining columns as its properties, matching how Campaign Launch splits merge columns from personalization variables. With the toggle off nothing merges, so profile columns continue to travel as event data instead; that is their only route to Responsys in that configuration. A row counts as delivered only if both the merge and the event succeed. A batch whose merge accepts zero rows does not fire the event at all; a batch whose merge accepts only some rows is still sent whole — Responsys’s merge response does not identify which records it rejected, so the rejected ones cannot be filtered out — but they are reported as failures rather than as delivered.
Two things to weigh before enabling it. The merge creates profiles with Responsys’s default permission status of opt-in, so turning this on means an event sync can add opted-in members to your list — a consent decision, not just a plumbing one. It also doubles the API calls per batch (one merge plus one event per 200 rows) against the ~200 requests/minute throttle.
Async large-volume merges. Enable Use Async API on a Profile List, PET, or Supplemental Table sync to submit each batch through Responsys’s asynchronous API (POST /rest/asyncApi/v1.3/…) and poll the Polling API (GET /rest/asyncApi/v1.3/requests/{requestId}) for completion, rather than holding a synchronous merge connection open. This avoids client-side timeouts on large loads. When the request completes (status SUCCESS), the Polling API returns a per-recipient result (each with success and errorMessage); Zeotap reads it back so rejected rows surface as errors and success/failure counts stay accurate. A request that completes with status ERROR, or one that never leaves IN_PROGRESS within the polling window, fails the batch rather than being reported as a silent success.
Composite-key matching. All merge operations (Profile List, PET, and the Campaign Launch merge step) support matching on two columns. Set a Second Match Column and Match Operator AND to dedupe on a composite key (for example CUSTOMER_ID_ and EMAIL_ADDRESS_). Hashed-email columns (EMAIL_MD5_HASH_, EMAIL_SHA256_HASH_) are available as match columns; note that hash match columns only update existing records and do not insert new ones.
Rate Limits
Responsys throttles high-volume functions (merges, triggered sends) at roughly 200 requests per minute, varying by account service tier. On an API_LIMIT_EXCEEDED / HTTP 429, Zeotap backs off and retries (bounded), then surfaces a row error if the limit persists.
Best Practices
- Choose the Match Column that matches how your audience is keyed.
EMAIL_ADDRESS_is the default; useCUSTOMER_ID_orRIID_when your source data is keyed that way. - Use a Profile Extension Table for wide or frequently-changing attributes to keep the core profile list lean.
- For Campaign Launch and merge-enabled Custom Events, Zeotap decides what to merge by reading the connected profile list’s real column set — a mapped column that exists on the list is merged, and everything else travels with the send. You do not need to follow a naming convention for this to work. If the list’s schema cannot be read (for example the API user lacks access), Zeotap falls back to treating trailing-underscore names as list columns and logs a warning; under that fallback, name your personalization and event-property columns without a trailing underscore.
- Leave Add Recipients To Profile List Before Firing off when the event is a signal about people you already know, and turn it on only when the audience is expected to contain new profiles you intend to create. When it is on, keep Insert On No Match enabled, or no new members will be created.
- Deleting a member removes them entirely and does not create a suppression. To unsubscribe, map
EMAIL_PERMISSION_STATUS_to an opt-out value instead of removing the record.
Troubleshooting
Authentication fails at the login endpoint
Confirm the Authentication Endpoint is your account’s login/WS endpoint (for example https://login2.responsys.net), not the REST API host. The correct value is in Responsys under Account > Global Settings.
Auth token expired mid-sync
You do not need to act — Zeotap refreshes the ~2-hour token automatically. Repeated HTTP 401 errors instead indicate the API user’s password changed or the account lost REST access; re-enter the credentials.
INVALID_PARAMETER on the match column
The chosen match column must exist on the target object. For Profile Extension Tables, Responsys requires the match column without its trailing underscore (RIID, not RIID_) — Zeotap handles this automatically, but a custom match column must still exist on the PET.
Partial merge failures (some rows rejected)
A batch can return HTTP 200 while individual rows fail (for example a malformed email). Zeotap reports these as MERGEFAILED row errors. Check the mapped values for the affected rows.
Rate limit exceeded (API_LIMIT_EXCEEDED)
You are hitting Responsys’s ~200 req/min throttle. Reduce sync frequency or concurrency; Zeotap already backs off and retries automatically.
Campaign Launch: personalization tokens are blank
The mapped column names must match the personalization variable names in the Responsys campaign template. Columns that exist on the connected profile list are excluded from personalization — they belong to the merge — so a personalization variable must not share a name with a list column. If the list schema could not be read, Zeotap falls back to excluding every column ending in an underscore, in which case rename your dynamic content columns so they do not end in _.
Custom event: recipients rejected because they are not list members
Responsys resolves each event recipient against the anchored profile list. If your audience contains people who are not yet members, the event is rejected for those rows. Either sync them into the profile list first with a separate Profile List sync, or enable Add Recipients To Profile List Before Firing on the custom-event target so each batch is merged before the event fires.
Send fails with “no recipient identifier mapped”
A Custom Event or Campaign Launch batch carried none of EMAIL_ADDRESS_, RIID_, CUSTOMER_ID_, MOBILE_NUMBER_, so there is nothing for Responsys to resolve the recipient by. Map one of them. The sync editor requires this before you can save, so this error normally means the sync was created through the REST API or an MCP tool, which do not pass through that check. The batch is failed before any merge runs, so nothing identity-less was written to your profile list.
Send fails with “recipient identifier … mapped but empty on every row”
The mapping is fine — an identifier column is mapped, but its value is blank for every row in the batch. This is a data problem rather than a configuration one: check the source column the identifier is mapped from, and the audience feeding the sync. The message names only the identifier columns actually mapped, so it points at the ones to check. As above, the batch fails before any merge runs.
Custom event merge fails with “no profile columns mapped”
Add Recipients To Profile List Before Firing is on, but none of the mapped columns exist on the connected profile list, so there is nothing to identify the recipient. Map at least one column the list declares — normally an identifier (EMAIL_ADDRESS_, CUSTOMER_ID_, RIID_, or MOBILE_NUMBER_). The error names the list it checked against. If it instead says the schema could not be read, Zeotap fell back to classifying by name, and only columns ending in an underscore count as list columns.
Supplemental table sync fails with a folder error
Supplemental tables are folder-scoped. Set a Folder Name on the target, or a Default Folder on the destination configuration.