Mailchimp preferences
Read provider choices and member flags, inspect synchronization choices, subscribe or unsubscribe members, and add active tags. Subscriber-info GET also resubscribes; choose it only when that write is intended. Provider audience state is separate from Wallkit membership and content access.
| Task | Operation |
|---|---|
| Build the configured interest choices | Read interests |
| Subscribe and send selected fields/interests | Subscribe member |
| Read grouped choices | Read grouped choices |
| Read synchronization choices | Read synchronization choices |
| Read and resubscribe member | Read and resubscribe member |
| Read member flags | Read member flags |
| Unsubscribe member | Unsubscribe member |
| Add active tags | Add active tags |
Example clients and synthetic values follow response conventions.
Member and provider context
Use an existing active member and valid resource with custom token and resource headers. Locked/suspended resource relationships fail the shared guard. Configured Firebase resolution follows the API context; see credential transport.
Use the selected resource’s existing Mailchimp key/list configuration. These operations do not provision the integration. Required category choices, target selection and provider effects differ by operation below.
Select the current member or another user
Subscribe, subscriber-info and unsubscribe use the current member unless a caller whose global role is admin or root supplies a nonempty user_id. That eligible caller can select another existing Wallkit user without a target resource-membership check. Other callers’ user_id is ignored. Omitting it selects the current member.
Member-interest and add-tags operations always use the current member. Each operation states its stored-email filtering; the body does not supply a replacement email.
Read configured interests
GET /api/v1/integrations/mailchimp/interests
Use the returned provider interest IDs to build a preference form. This reads Mailchimp directly; it does not read a member’s existing selections or save preferences.
Before you call
Use the member/provider context. This operation also uses the selected resource’s configured category title.
The configured category title is matched exactly against provider categories. Requests ask for up to 50 categories and 50 interests; there is no pagination loop or reader-controlled page parameter. A missing category or missing provider collection yields an empty list. No explicit local interest cache is used.
Request
No request body or action-specific query parameters.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | header | member session token; required | Existing member identity. |
| resource | header | resource public key; required | Selects the configured provider list/category. |
Result
HTTP 200 with items, an array that may be empty.
| Field | Type / presence | Meaning |
|---|---|---|
| items[].id | provider identifier; retained when supplied | Interest ID to use as a key in subscribe’s interests map; not a Wallkit user ID. No universal ID type is imposed. |
| items[].name | string when supplied | Provider name with asterisks removed, lowercased and trimmed. |
| items[].other fields | provider-dependent values; conditional | Additional provider fields pass through, except category_id, list_id, display_order and _links, which are removed. This is an open projection, not a fixed provider schema. |
Example: Build a technology preference choice
This synthetic excerpt assumes the configured provider category contains this interest. Preserve the ID when displaying the normalized label.
curl "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/interests" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/interests`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/interests",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"items": [
{
"id": "interest-example",
"name": "technology"
}
]
}
The response describes available choices, not whether this member is subscribed.
Consequential alternate
Synthetic HTTP 200 excerpt:
{
"items": []
}
An empty list can mean no configured-title match or no returned interests. A provider error response lacking the expected collection can also become empty. Do not treat this as proof of a healthy empty audience.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| 500 | integration_error / Mailchimp integration not configurated | Mailchimp key is missing in the selected resource settings. | Ask the integration owner to check the selected resource’s existing configuration. |
| 200 | items:[] | Category/collection not found in the provider result. | Handle no choices and ask the integration owner to check the configured title/list and provider outcome. |
| Shared failure | No stable action-specific provider error shape | Provider or initialization throws; this action has no dedicated catch. | Inspect the reported failure with the integration owner; do not interpret it as a preference decision. |
Shared identity/resource failures follow credential guidance.
Next task
Use the returned IDs with subscribe. Keep the member’s explicit choice separate from the available catalog.
Subscribe a selected member
POST /api/v1/integrations/mailchimp/subscribe
Before you call
Use the member/provider context. This operation also uses the selected resource’s configured category title.
Use the target-selection rule. Email comes from the selected Wallkit user, sanitized, lowercased and trimmed; the client cannot supply a replacement email here.
Request
Send a JSON object.
| Name | Location | Type / requirement | Meaning / constraints |
|---|---|---|---|
| token | header | member session token; required | Selects the caller and global role. |
| resource | header | resource public key; required | Selects the configured Mailchimp list. |
| user_id | JSON | optional integer-filtered Wallkit ID | Honored only for global admin/root with a nonempty value. Not a provider subscriber ID. |
| merge_fields | JSON | optional map of provider merge tag to value | Omitted/empty sends no merge_fields. Values false, 0, "0", empty string and null are dropped; they do not clear fields. Keys/remaining values have no action-level schema validation. |
| interests | JSON | optional map of provider interest ID to value | Nonempty map is forwarded, including false values. Omitted/empty sends no interests field; it is not a request to clear all interests. No action-level ID/value validation. |
Use IDs from read interests. This request updates selected provider fields, rather than replacing the whole provider record. Provider-specific omitted-field behavior remains unspecified. There is no caller opt-in or consent flag and no duplicate-request suppression; another call repeats the provider PUT.
Result
HTTP 200 merges provider fields at the top level and adds user_id. There is no items or result wrapper. An adapter result that is empty or otherwise false in a boolean check can produce only user_id. A provider error object can also arrive with HTTP 200. Validate the outcome needed by your application rather than treating HTTP 200 alone as subscription confirmation.
| Field | Type / presence | Meaning |
|---|---|---|
| user_id | stored Wallkit integer ID | Selected user; present even when the adapter returns no subscriber data. |
| interests | array; when provider result is truthy; [] possible | Extended interest entries. Empty if member interests or catalog lookup is empty. |
| interests[].id | provider map key | Interest identifier, not a Wallkit ID. |
| interests[].name | string | Normalized catalog name, or Newsletter followed by the unknown key when no match exists within a nonempty catalog. |
| interests[].subscribed | provider value | Raw returned flag; not explicitly cast to Boolean. |
| merge_fields | array; when provider result is truthy; [] possible | Extended merge values. Empty if member merge fields or label lookup is empty. |
| merge_fields[].key | provider map key | Provider merge tag. |
| merge_fields[].name | provider label / null | Null if that tag has no nonempty label in the returned lookup. |
| merge_fields[].value | provider-dependent value | Returned member field data. |
| id, email_address, status, other top-level fields | provider-dependent; optional | Provider passthrough, including possible error fields; _links removed. No closed schema or universal provider-success contract. |
The operation makes synchronous provider calls, not a queued preference update. It does not create a Wallkit membership or establish email delivery, marketing consent or content access.
Example: Subscribe the current member with an interest
Assume the prior interest read returned interest-example and the provider merge-field configuration includes FNAME. The current member is synthetic user 1001, with stored email reader@example.com.
curl -X POST "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/subscribe" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{"merge_fields": {"FNAME": "Reader"}, "interests": {"interest-example": true}}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/subscribe`, {
method: "POST", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({"merge_fields": {"FNAME": "Reader"}, "interests": {"interest-example": true}})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'merge_fields': {'FNAME': 'Reader'}, 'interests': {'interest-example': True}}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/subscribe",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="POST")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"email_address": "reader@example.com",
"status": "subscribed",
"interests": [
{
"id": "interest-example",
"name": "technology",
"subscribed": true
}
],
"merge_fields": [
{
"key": "FNAME",
"name": "First name",
"value": "Reader"
}
],
"user_id": 1001
}
The shown status is provider data. The labels come from follow-up provider reads and may be incomplete.
Consequential alternate
Synthetic HTTP 200 excerpt after a falsey adapter result:
{
"user_id": 1001
}
This identifies the selected Wallkit user only. It does not confirm provider subscription. Stop the application’s success path and ask the integration owner to inspect the provider outcome before submitting again.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| 406 | incorrect_data / Body must be json format | No truthy parsed JSON body. | Send a JSON object with Content-Type: application/json. |
| 404 | user_not_found / User not found | Admin/root target ID did not resolve. | Check the intended existing Wallkit user ID; ordinary members should omit it. |
| 500 | integration_error / Mailchimp integration not configurated | Selected resource lacks configured key. | Ask the integration owner to check the existing resource configuration. |
| 200 | user_id only or provider error fields | No usable provider subscriber result. | Handle an unconfirmed outcome; have the owner inspect it before repeating a write. |
| Shared failure | No stable action-specific provider error shape | PUT or extension read throws. | Account for a possible earlier provider write; inspect state before retrying. |
Use credential guidance for shared member/resource failures.
Next task
Store the application’s interpretation of the provider result separately from access decisions. If the task is to serve content, use the content-access walkthrough.
Read category groups
GET /api/v1/integrations/mailchimp/categories
Build a grouped choice form from the configured Mailchimp list. Unlike the configured-title interest read, this visits the returned categories across that list and preserves their display titles.
Before you call
Use the member/provider context.
Category and per-category interest requests each ask for up to 50 records; no pagination loop is used. Categories with no returned interests are omitted. Reads are synchronous provider calls, with no explicit local catalog cache.
Request
No request body or action-specific query inputs.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | header | member session token; required | Existing caller identity. |
| resource | header | resource public key; required | Selected provider integration. |
Result
HTTP 200 with groups, an array that may be empty.
| Field | Type / presence | Meaning |
|---|---|---|
| groups[].id | provider category identifier | Category key, not the resource ID. Provider type retained. |
| groups[].title | provider title | Display title; not normalized like the configured interest name. |
| groups[].interests | nonempty array | Only returned interests; categories lacking them are skipped. |
| groups[].interests[].id | provider interest identifier | Preference-map key. |
| groups[].interests[].title | provider name | Unmodified display name. |
Example: Display grouped choices
curl "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/categories" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/categories`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/categories",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"groups": [
{
"id": "category-example",
"title": "Newsletters",
"interests": [
{
"id": "interest-example",
"title": "Technology"
}
]
}
]
}
Use the category title for grouping and the interest ID for a chosen preference. These are available choices, not member selection flags.
Consequential alternate
Synthetic HTTP 200 excerpt:
{
"groups": []
}
No categories with returned interests were collected. Missing provider collections can also collapse to empty; do not infer a healthy empty list.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| 409 | integration_error / exception message | Category retrieval or adapter construction throws inside the action catch. | Check the reported provider/configuration condition with the owner; handle no choices separately. |
| 200 | groups:[] | No eligible category/interest collection returned. | Render no choices and ask the owner to inspect the list when unexpected. |
| 500 | integration_error / Mailchimp integration not configurated | Selected resource lacks configured key. | Ask the integration owner to check existing configuration. |
Next task
For a flat catalog restricted to the configured category title, use read interests.
Read synchronization field choices
GET /api/v1/integrations/mailchimp/sync-fields
Read provider merge tags/labels and Wallkit selector strings that can be used to describe configured mappings. The response is a choice catalog, not the saved mappings or member values.
Before you call
Use the member/provider context.
Mailchimp merge-field retrieval asks for up to 50 records with no pagination loop/local cache. Wallkit choices are built from model public fields plus explicit derived selectors, exclusions and sorting. This operation does not save a mapping.
Request
No request body or action-specific query inputs.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | header | member session token; required | Existing caller identity. |
| resource | header | resource public key; required | Selected provider integration. |
Result
HTTP 200 with two separate field catalogs.
| Field | Type / presence | Meaning |
|---|---|---|
| mailchimp | map of provider tag to provider label; empty collection possible | Available merge tags, such as FNAME, and their labels. Missing provider collection becomes empty; not a provider-health check. |
| wallkit | array of strings, sorted | Selector choices such as User.email; they identify possible mapping inputs, not current values. Model groups include User, UserSession, Plan, Subscription, Transaction, Invite, Purchases variants and SubscriptionPrevious, plus explicit derived/context selectors. Duplicate selectors can remain; this is not a universal response schema. |
Example: Inspect two field catalogs
curl "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/sync-fields" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/sync-fields`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/sync-fields",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"mailchimp": {
"FNAME": "First name"
},
"wallkit": [
"User.email"
]
}
This excerpt omits other Wallkit selectors. Choose a provider tag and a meaningful source selector through the integration’s existing configuration process; this read does not apply that mapping.
Consequential alternate
Synthetic HTTP 200 excerpt with no provider merge-field collection:
{
"mailchimp": [],
"wallkit": [
"User.email"
]
}
The Wallkit selector excerpt can still exist while Mailchimp choices are empty. Do not manufacture provider tags from Wallkit names.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| Shared failure | No stable action-specific provider error shape | Provider/initialization throws without a dedicated action catch. | Have the integration owner inspect the reported failure. |
| 200 | mailchimp:[] | Provider merge-field collection absent/empty. | Handle no mapping choices; ask the owner to check the provider list if unexpected. |
| 500 | integration_error / Mailchimp integration not configurated | Selected resource lacks configured key. | Ask the integration owner to check existing configuration. |
Next task
Use supported provider tags when subscribing. Sending merge_fields there writes member values; it does not store synchronization configuration.
Read and resubscribe member information
GET /api/v1/integrations/mailchimp/subscriber-info
Before you call
Use the member/provider context.
Use the target-selection rule.
The stored email is used for the provider member lookup, with email/lower filtering for the hash. The PUT sends the stored email and subscribed statuses; then label lookups extend interests and merge fields. No explicit local subscriber cache or Wallkit membership update occurs. Later reads can fail after the provider write.
Request
No request body.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | header | member session token; required | Existing caller identity. |
| resource | header | resource public key; required | Selected provider integration. |
| user_id | query | optional integer-filtered Wallkit ID | Admin/root target only; omitted in the current-member example. |
Result
HTTP 200 with selected user_id and the same extended subscriber projection as subscribe: interests and merge_fields become arrays when provider processing completes. Other provider fields remain dynamic. The provider PUT outcome replaces the initial GET data.
A returned provider status equal to 404 becomes HTTP 404 subscriber_not_found. Other raw provider error fields are not universally translated. Missing email returns no adapter data and can yield user_id only; provider failures during processing may throw instead. HTTP 200 alone is not confirmation of a usable subscriber result.
Example: Read the current member while accepting resubscription
curl "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/subscriber-info" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/subscriber-info`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/subscriber-info",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"email_address": "reader@example.com",
"status": "subscribed",
"interests": [
{
"id": "interest-example",
"name": "technology",
"subscribed": true
}
],
"merge_fields": [],
"user_id": 1001
}
The shown member data follows a subscribing PUT. Empty merge_fields can mean missing values or unavailable label collection; it does not prove all provider fields were cleared.
Consequential alternate
Synthetic HTTP 404 response when the final provider data reports status 404:
{
"error": "subscriber_not_found",
"error_description": "Subscriber not found",
"req_guid": "example-request"
}
This route already attempted a subscribing PUT before interpreting that result. Check the provider state with the owner before repeating the request.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| 404 | user_not_found / User not found | Selected admin/root target did not resolve. | Check the existing Wallkit user ID. |
| 404 | subscriber_not_found / Subscriber not found | Final provider data reports status 404. | Inspect the selected email/list and provider outcome before another write. |
| Shared failure | No stable action-specific provider error shape | Provider/initialization throws without a dedicated action catch. | Have the integration owner inspect the reported failure. |
| 200 | user_id only / provider error fields | No usable subscriber information. | Handle an unconfirmed result; inspect provider state before resubmitting. |
| 500 | integration_error / Mailchimp integration not configurated | Selected resource lacks configured key. | Ask the integration owner to check existing configuration. |
Next task
For existing flags without this subscribing PUT, use member interests.
Read current member interest flags
GET /api/v1/integrations/mailchimp/subscriber/interests
Read the current member’s interest flags from the configured provider list. This action does not issue the subscriber-info subscribing PUT or select another member by user_id.
Before you call
Use the member/provider context.
Provider lookup uses the current member’s stored email with email/lower filtering for the member hash. This action has no explicit local cache. Missing member data or interests can return an empty array; this does not prove absence of a provider record.
Request
No request body or action-specific query inputs. user_id does not select a target here.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | header | member session token; required | Existing caller identity. |
| resource | header | resource public key; required | Selected provider integration. |
Result
HTTP 200 with interests, an array that may be empty.
| Field | Type / presence | Meaning |
|---|---|---|
| interests[].id | provider map key | Interest ID to match with catalog choices. |
| interests[].subscribed | provider value | Returned preference flag, not explicitly cast to Boolean. |
Names and subscriber status are not included in this projection.
Example: Read two existing flags
curl "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/subscriber/interests" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/subscriber/interests`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/subscriber/interests",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"interests": [
{
"id": "interest-example",
"subscribed": true
},
{
"id": "interest-other",
"subscribed": false
}
]
}
Display these alongside catalog IDs, preserving unknown IDs honestly. A false interest flag is separate from overall audience subscription state.
Consequential alternate
Synthetic HTTP 200 excerpt:
{
"interests": []
}
No countable interest map was returned. A missing provider member result can also yield this; keep it distinct from explicit false flags.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| 409 | integration_error / exception message | Provider lookup throws inside the action catch. | Check the reported failure with the integration owner. |
| 404 | user_not_found / User not found | No current user reached the action. | Check the caller’s existing member context. |
| 200 | interests:[] | No usable interest map. | Handle unknown/empty preferences and inspect provider state when needed. |
| 500 | integration_error / Mailchimp integration not configurated | Selected resource lacks configured key. | Ask the integration owner to check existing configuration. |
Next task
Use the configured interest catalog to label returned IDs, then subscribe only when a provider write is intended.
Unsubscribe a selected member
POST /api/v1/integrations/mailchimp/unsubscribe
Send a synchronous provider PUT with status: unsubscribed for the selected member’s stored email. This does not cancel a Wallkit membership or remove all provider fields/tags.
Before you call
Use the member/provider context.
Use the target-selection rule.
The member hash uses stored email with email/lower filtering; the PUT sends stored email. This differs from subscribe’s trim-normalized email. There is no subscriber label extension, queue or local membership write. A repeat repeats the PUT; no duplicate-suppression guarantee.
Request
Body is optional; a JSON object is used in the example to make the selected target explicit.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | header | member session token; required | Existing caller identity. |
| resource | header | resource public key; required | Selected provider integration. |
| user_id | JSON | optional integer-filtered Wallkit ID | Admin/root target only; empty/omitted uses current member. |
Other fields, including interests and merge_fields, are not sent by this action.
Result
HTTP 200 with raw provider subscriber fields plus user_id; not the extended arrays returned by subscribe.
| Field | Type / presence | Meaning |
|---|---|---|
| user_id | stored Wallkit integer ID | Selected member, present even after a falsey adapter return. |
| interests | raw provider map; conditional | Provider interest ID to raw value; no display labels/array extension. |
| merge_fields | raw provider map; conditional | Merge tag to provider value; no key/name/value array extension. |
| id, email_address, status, other fields | provider-dependent; optional | Raw provider result, except _links removed. Possible provider error fields are not classified universally. |
A falsey provider result can yield user_id only. HTTP 200 is not sufficient to confirm unsubscription, deletion, delivery or consent state.
Example: Unsubscribe the current member
curl -X POST "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/unsubscribe" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/unsubscribe`, {
method: "POST", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/unsubscribe",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="POST")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"email_address": "reader@example.com",
"status": "unsubscribed",
"interests": {
"interest-example": true
},
"merge_fields": {
"FNAME": "Reader"
},
"user_id": 1001
}
The raw maps can remain after overall unsubscription. These are maps, unlike the arrays with added labels returned by subscribe. The interest flag does not override the audience status.
Consequential alternate
Synthetic HTTP 200 excerpt after a falsey adapter result:
{
"user_id": 1001
}
The unsubscription remains unconfirmed. Ask the integration owner to inspect the provider result before repeating.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| 404 | user_not_found / User not found | Admin/root target did not resolve. | Check the existing Wallkit user ID. |
| Shared failure | No stable action-specific provider error shape | Provider/initialization throws without a dedicated action catch. | Have the integration owner inspect the reported failure. |
| 200 | user_id only / provider error fields | No usable unsubscription result. | Handle unconfirmed state and inspect provider state before repeating. |
| 500 | integration_error / Mailchimp integration not configurated | Selected resource lacks configured key. | Ask the integration owner to check existing configuration. |
Next task
For a separate interest-flag read, use member interests. Use subscriptions for Wallkit membership tasks; they are separate from this provider audience update.
Add active tags to the current member
POST /api/v1/integrations/mailchimp/add-tags
Assign the supplied tag names as active in Mailchimp for the current member. This adds/activates selected tags; it does not replace all tags or remove omitted tags.
Before you call
Use the member/provider context.
Only the current caller is used, even if an admin supplies user_id. The stored email is email-filtered, lowercased and trimmed for the provider member hash. Provider calls are synchronous; no Wallkit local tag or membership write is made.
Request
Send a JSON object.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | header | member session token; required | Existing caller identity. |
| resource | header | resource public key; required | Selected provider integration. |
| insert_tags | JSON | optional array of tag-name values | Non-string entries are skipped. String entries are string-filtered/trimmed and sent with status active. No nonempty-name validation or deduplication; repeats/duplicate names are forwarded. Empty/omitted sends an empty tags array rather than removing tags. |
user_id is ignored as a target selector. There is no removal/status override field.
Result
HTTP 200 with no action-specific success fields. The provider return is cast to Boolean; false/exception becomes HTTP 409. Provider data/message IDs are not returned. A truthy provider error-shaped response can pass that Boolean check; HTTP 200 is not a detailed per-tag result.
| Field | Type / presence | Meaning |
|---|---|---|
| Action-specific fields | none | No result/items/tag list is added. Common conditional debug metadata may still appear. |
Example: Activate a reader tag
curl -X POST "${WALLKIT_API_BASE}/api/v1/integrations/mailchimp/add-tags" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{"insert_tags": ["Technology"]}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/mailchimp/add-tags`, {
method: "POST", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({"insert_tags": ["Technology"]})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'insert_tags': ['Technology']}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/mailchimp/add-tags",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="POST")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
[]
The empty JSON array illustrates the no-action-data response with shared debug metadata disabled. No per-tag confirmation is included.
Consequential alternate
Synthetic HTTP 409 response for a false provider return or caught exception:
{
"error": "error_add_user_tag",
"error_description": "Add user tag error",
"req_guid": "example-request"
}
Provider details are not exposed by this error. The application must keep the assignment unconfirmed.
Recovery
| HTTP status | Code / shape | Cause | Next action |
|---|---|---|---|
| 406 | incorrect_data / Body must be json format | No truthy parsed JSON body. | Send a JSON object with Content-Type: application/json. |
| 404 | user_not_found / User not found | No current user reached the action. | Check existing caller context, rather than adding a body user_id. |
| 409 | error_add_user_tag / Add user tag error | Provider return false or caught exception. | Check member/list/tag outcome with the owner before repeating. |
| 500 | integration_error / Mailchimp integration not configurated | Selected resource lacks configured key. | Ask the integration owner to check existing configuration. |
Next task
Use member interest flags for the separate preference task. This operation exposes no complete tag-list response to use as a replacement set.
Follow the task guide
Read the 3rd party integration flows for request order, context choices and response decisions.