GetResponse
Add the people who submit your forms to a GetResponse list, filling their contact details from the answers you mapped.
GetResponse is an add-on for Forms. Once your GetResponse account is connected, every form you edit gains a GetResponse panel in its sidebar where you describe one or more actions. An action can create or update a contact in a GetResponse list, or remove the contact from it.
The names offered in the panel are your GetResponse campaigns, because a campaign is what GetResponse calls a contact list. Everything else about the form is unchanged: validation, messages, redirects, notification emails and the Submissions list all behave as they did before. GetResponse delivery runs after the entry is stored, so a provider refusal cannot erase it.
Where to find it
Two places, because there are two kinds of setting. The account connection is site-wide, at XPAC → Integrations on the GetResponse tab, whose screen is headed GetResponse Settings. What each form sends is per-form, in the GetResponse panel of the document sidebar while you edit that form.
Forms has to be active
The plugin does nothing on its own. Without XPAC Forms it registers no settings tab, no panel and no routes, and shows an admin notice asking for Forms instead.
Connecting your account
Create an API key in your GetResponse account. The plugin reads your campaigns, reads the custom fields on your account, and creates contacts, so the key needs to be allowed to do all three.
Paste it into the Api Key field at XPAC → Integrations → GetResponse and save. That single key serves every form on the site.
Only if yours is a GetResponse MAX account, turn on MAX platform and choose your MAX platform endpoint — either https://api3.getresponse360.com/v3 or https://api3.getresponse360.pl/v3, whichever GetResponse gave you. Leave the toggle off for an ordinary GetResponse account; turning it on for one stops everything working.
Missing credentials do not hide your actions
The GetResponse panel and its saved actions remain visible when the key is missing or revoked. Account-backed pickers show the connection error, and a submission still creates its Forms entry before the queued delivery is marked failed. Correct the connection, then retry it from XPAC → Forms → Deliveries.
Treat the key as a secret
The settings screen uses a password control, but the value is still a credential stored in WordPress. Limit settings access, use a revocable key, and rotate it if it ever leaks.
MAX accounts: your account domain is taken from this site
With MAX platform on, every request also tells GetResponse which account domain it belongs to, and the plugin fills that in with this website's own web address. There is no field for it. If your MAX account is registered against a different domain — a marketing domain, or the live site while you are working on a staging copy — GetResponse will refuse everything, and the only symptom is that the list dropdown never fills.
Adding someone to a list
Edit the form, open the GetResponse panel and press the round + button (Add action). The Create contact modal opens.
Map the fields. Each row pairs a Local field from your form with a Remote field on the GetResponse contact, and you add as many rows as you need. One of them has to be Email; read the warning below before you save.
Choose Create or update contact or Remove contact in the action. A form can hold several actions, and Conditional Logic can decide which apply to a submission.
One row must map to Email
GetResponse identifies a contact by their email address, so the action editor will not let you save an action whose mapping has no Email row: Save stays disabled and says what is missing, and a warning sits under the mapping rows until you add it.
The row on its own is not quite enough — make that form field required as well. If the row is there but the visitor left the field blank there is no address to send, so no contact is created and the action is recorded as a failed delivery.
Mapping fields
- Local field lists every field in the form that holds a value, under its label, or under its field name where the label is blank.
- Remote field offers Name and Email first, then every custom field on your GetResponse account, each shown under its own name with underscores turned into spaces.
- That custom-field list is the same whichever list you pick, because in GetResponse the custom fields belong to the account rather than to a campaign.
- A row with either half left empty is ignored, so a half-finished mapping costs nothing.
- One answer can feed several GetResponse fields: map the same Local field to two different Remote fields and both are sent.
- The other direction does not work, because a GetResponse field holds one value. Two rows aimed at the same Remote field send only the first one.
Two rows on Email, or on Name, send only the first one
Email and Name are single fields like any other, so pointing two rows at either one is a mapping mistake rather than a second address: the row nearest the top wins and the ones below it send nothing. A form carrying Email and Alternate email sends the first as the contact's address. One row for Email, at most one for Name, and everything else pointed at a real custom field.
Multiple answers, and file uploads
A field that can hold several answers at once — a checkbox group with more than one box ticked — is sent to a custom field as the list of answers, which is the shape GetResponse's own multi-value fields take. Mapped to Email or to Name, where only one value fits, the answers are joined with a comma; an address built that way is not an address, so keep multi-answer fields off those two rows. A file upload field is no use on any row: what reaches GetResponse is the internal reference number of the uploaded file, not the file or a link to it.
The list and custom-field pickers read GetResponse's results page by page until the account has no more, rather than stopping at the provider's first page.
Both dropdowns are read once per editing session
The list dropdown is filled the first time the panel renders, and the custom fields the first time you open an action; both are then held for the rest of the session. A list or a custom field you create in GetResponse while the editor is open will not appear until you reload the page.
Consent is yours to get
The campaign controls confirmation
This integration sends no confirmation request of its own. Whether GetResponse asks the person to confirm is decided by that campaign's opt-in settings. Configure the campaign rather than assuming the plugin establishes confirmed consent.
Autoresponder cycle day defaults to 0 on a new action. Set another day to start
there, or leave it empty to put the contact on no cycle. Tags are also explicit
per-action settings.
Either way, getting consent is down to you and to the form you built. Say plainly on the form what submitting it signs the visitor up to, ask for it explicitly rather than by implication, and keep the record: the form's own Submissions list holds their answers, including whatever consent box you added.
Deliveries, retries and duplicate limits
Forms writes the entry first and schedules GetResponse afterwards. The visitor does not wait, and a remote failure cannot erase the submission. The Deliveries screen retains GetResponse's explanation. Each accepted action is marked done, so a retry of one failed action does not repeat its successful siblings.
Configuration, authentication and validation failures reported as 400/401/403/404/410/422 are left failed for an administrator to fix. Rate limits, 5xx replies and transport failures are retried after about 1, 5, 30 and 120 minutes, for at most five attempts. Restore the key or action configuration, then retry a permanent failure manually.
An existing contact is an expected outcome: depending on Update a contact that is already on the list, it is updated or left alone. Remove likewise treats an absent contact as already removed. GetResponse exposes no documented request idempotency key; instead, its duplicate-contact response is treated as an outcome and the action either stops there or converges through the configured update. Replaying a create/update or remove action therefore converges on contact state.
The delivery loads current custom-field definitions before posting any contact. If that metadata lookup has a transient outage, the attempt is retried without first issuing the contact request.
Editing and removing an action
Each row in the panel shows the action's name — Create contact — with a pencil (Edit action) that reopens the modal and a red X (Remove action) that asks Are you sure you want to remove the item? before acting.
Use the switch on a row to pause or resume that action without losing its settings. The X removes the selected row after confirmation; other actions keep their order and settings.
For developers
Settings are stored in the shared xpac option under three keys —
getresponse_api_key, getresponse_is_max_user and getresponse_max_endpoint — read
in one go with getBulk('getresponse') at packages/GetResponse/Addon.php:187-193.
They are written by a password field, a toggle and a two-option radio on the
Integrations settings module (:74-135); the radio is hidden behind
showIf: getresponse_is_max_user (:124-127). The module is registered without
show_in_rest (packages/Shared/Settings/Settings.php:481), so the option is not
exposed on /wp/v2/settings; it is readable and writable on the settings module's own
routes, wp-react-settings/xpac/read and …/update, both gated on manage_options
(packages/Shared/Settings/Rest.php:27-37).
Per-form actions live in the form's form_settings post meta on the xpac-form post
type, under a getresponse key, registered on the Forms meta schema
(Addon.php:237-278) and therefore readable and writable over the REST API at
/wp-json/wp/v2/xpac-form/<id>. The default is an empty items array (:289-296):
{
"getresponse": {
"items": [
{
"status": true,
"action": "subscribe",
"list": "aBcDe",
"map": [{ "local": "email", "remote": "email" }]
}
]
}
}list is a GetResponse campaignId, taken from /campaigns. action is
subscribe or unsubscribe. remote is either the
reserved string email or name, or a numeric GetResponse customFieldId (:425-435).
Items carry additionalProperties: true (:271), which is what lets Conditional Logic
store its own condition object on an item with no schema entry of its own. Write
status when you write this meta directly: Forms' shared filter reads $item['status']
with no fallback (Forms/core/base/Utils.php:58).
Two routes back the editor UI, both requiring manage_options (Addon.php:303-327):
GET /wp-json/xpac/v1/form/getresponse/lists
GET /wp-json/xpac/v1/form/getresponse/custom-fieldslists answers { lists: [{ id, name }] } from /campaigns (:354-389).
custom-fields answers { fields: [{ value, label }] } from /custom-fields, with
Name and Email prepended and each remaining label built as
join(' ', explode('_', ucfirst($field->name))) (:396-438). It takes no list
parameter — GetResponse custom fields are account-wide — and the editor's
getFields() declares no argument either (assets/packages/getresponse/requests.js:20),
and the editor's store holds it in a single account-wide slot, read once per editing
session however many campaigns the form's actions target
(assets/packages/getresponse/useStoreData.js:75-135). A GetResponse failure is not turned into an HTTP error:
both routes catch the exception and answer 200 with a message key instead
(:362-366, :405-409), and the editor renders that message where the dropdown would
be (assets/packages/getresponse/Components/FormSettings.js:33).
packages/GetResponse/Client.php sends the key as the X-Auth-Token: api-key …
header (:69), never in a URL or a query parameter. With is_max_user on it also
sends X-Domain, filled from parse_url(get_site_url(), PHP_URL_HOST) (:49-52,
:74-76) with no way to override it, and swaps the base URL for the MAX endpoint
chosen in settings. Requests retain GetResponse's message and HTTP status for the
shared delivery classifier. Contact creation, update and removal are supported;
creation may include tags and a configured dayOfCycle, or omit the cycle field
entirely. Client uses a filterable ten-second timeout through
xpac_getresponse_request_timeout.
subscribe() is registered through xpac_forms_submit_callbacks, but Forms schedules
it after the entry exists. Deliveries\Runner invokes it off-request, and each accepted
action records a stable delivery key so later attempts skip it.
The package fires no hooks of its own in PHP — there is no do_action and no
apply_filters anywhere in it — and registers no blocks. That is a fact about its
design rather than a gap in this reference: everything it does is a callback on
somebody else's contract, which is also why it has no generated hook reference page.
It attaches to five Forms hooks — xpac_forms_init to bootstrap (Addon.php:171,
fired at Forms/Bootstrap.php:93, itself on init:200), xpac_forms_post_meta_schema
and xpac_forms_post_meta_default_values for the shape of its settings (fired at
Forms/core/base/PostType.php:126 and :118), xpac_forms_post_script_dependencies
to load its editor panel (PostType.php:329), and xpac_forms_submit_callbacks for
the send — plus rest_api_init for its routes and plugins_loaded/admin_notices in
Bootstrap.php.
On the editor side the panel is contributed from JavaScript through the
xpac-forms-form-panels filter (assets/packages/getresponse/index.js:32, applied at
assets/packages/forms/hooks/useFormPanels.js:62). It declares no priority, which is
why it sorts below every core Forms panel and why its position relative to other
add-ons' panels is not stable (useSortedAndFilteredPanels.js:18-21). Its action modal
fires the one hook this package owns, xpac-forms-after-settings-modal-content
(assets/packages/getresponse/Components/Modal.js:112), passing the action's current
options with an onChange callback and the module id xpac-getresponse; Conditional
Logic is the only listener (assets/packages/conditional-logic/forms/admin.js:76).
The package's only licensing touchpoint is Updater::register() in Bootstrap.php:54.
Nothing in Addon.php checks a licence.