Dedicated account manager
Custom data + relations use case · For B2B shops or key-account setups where each customer is followed by a dedicated account manager. The goal: segment by manager, send targeted campaigns to their portfolio, and dynamically display the right contact's details across all messages.
The business need
You have a team of account managers (10 to 100 people). Each shop customer is assigned at most one dedicated manager who follows them, advises them and supports them through orders.
You want to be able to:
- Segment contacts by account manager ("Alice's portfolio").
- Send bulk campaigns targeting an account manager's portfolio.
- Personalize emails and SMS with the right manager's details (name, photo, phone, email) — no conditional logic in templates.
The ShopiMind solution
Two custom data definitions chained:
- Account manager — your team's reference list.
- Assignment — customer ↔ manager link.
The assignment references the Contact entity by id_customer or email, without pre-resolving the ShopiMind identifier.
The data model
"Account manager" definition
Your team's reference list. One row = one manager.
responsable_id(text) — uniqueness key (your internal HR/CRM identifier).first_name,last_name(text) — for the signature.email,phone(text) — for direct contact in messages.photo_url(text) — for emails with visual signatures.
"Assignment" definition
The customer ↔ manager link. A customer has 0 or 1 manager.
contact_id(number) — relation to the Contact entity.responsable_id(number) — relation to the Account manager definition.assigned_at(date) — start of the relationship.- Uniqueness key:
contact_id— only one active manager per customer.
Implementation
1. Create the "Account manager" definition
curl -X POST 'https://core.shopimind.com/v1/custom-data-definitions' \
-H 'spm-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"name": "ResponsableCommercial",
"description": "Catalog of account managers",
"unique_keys": ["responsable_id"],
"fields": [
{ "name": "responsable_id", "label": "Manager ID", "type": "text", "required": true },
{ "name": "first_name", "label": "First name", "type": "text", "required": true },
{ "name": "last_name", "label": "Last name", "type": "text", "required": true },
{ "name": "email", "label": "Email", "type": "text", "required": true },
{ "name": "phone", "label": "Phone", "type": "text", "required": false },
{ "name": "photo_url", "label": "Photo URL", "type": "text", "required": false }
]
}'Note the returned id_definition — say 240.
2. Create the "Assignment" definition
curl -X POST 'https://core.shopimind.com/v1/custom-data-definitions' \
-H 'spm-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"name": "Attribution",
"description": "Account manager assignment for a contact",
"unique_keys": ["contact_id"],
"fields": [
{ "name": "contact_id", "label": "Contact", "type": "number", "required": true },
{ "name": "responsable_id", "label": "Manager", "type": "text", "required": true },
{ "name": "assigned_at", "label": "Assigned at", "type": "date", "required": false }
],
"relationships": [
{ "sourceField": "contact_id", "targetSchemaType": "system", "targetSchema": "contacts", "targetField": "id_contact" },
{ "sourceField": "responsable_id", "targetSchemaType": "custom", "targetSchema": "240", "targetField": "responsable_id" }
]
}'Returned id_definition: 241.
3. Push the manager catalog
On each hire, departure or update from your CRM/HR side:
curl -X POST 'https://core.shopimind.com/v1/custom-data-records/240' \
-H 'spm-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '[
{
"responsable_id": "COM-001",
"first_name": "Alice",
"last_name": "Durand",
"email": "alice.durand@myshop.com",
"phone": "+33 1 23 45 67 89",
"photo_url": "https://myshop.com/team/alice.jpg"
},
{
"responsable_id": "COM-002",
"first_name": "John",
"last_name": "Martin",
"email": "john.martin@myshop.com",
"phone": "+33 4 56 78 90 12",
"photo_url": "https://myshop.com/team/john.jpg"
}
]'The upsert is on responsable_id (uniqueness key). Each manager will then be referenced by their responsable_id value (e.g. COM-001 for Alice, COM-002 for John) in the assignments.
4. Push the assignments
The API accepts three identifiers to designate the target contact: id_contact, email, or id_customer (your shop-side customer ID). No need to fetch the ShopiMind id_contact before writing — the server resolves the target automatically.
By id_customer — typical of a sync from your CRM or ERP that already holds the shop's customer identifier:
curl -X POST 'https://core.shopimind.com/v1/custom-data-records/241' \
-H 'spm-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '[
{
"contact_id": { "by": "id_customer", "value": "CUST-A4521" },
"responsable_id": "COM-001",
"assigned_at": "2024-03-15"
},
{
"contact_id": { "by": "id_customer", "value": "CUST-A4522" },
"responsable_id": "COM-001",
"assigned_at": "2025-09-20"
},
{
"contact_id": { "by": "id_customer", "value": "CUST-A4523" },
"responsable_id": "COM-002",
"assigned_at": "2025-11-08"
}
]'By email — useful for a trigger based on an email export or a CSV import:
curl -X POST 'https://core.shopimind.com/v1/custom-data-records/241' \
-H 'spm-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '[
{
"contact_id": { "by": "email", "value": "marie.dupont@example.com" },
"responsable_id": "COM-001",
"assigned_at": "2024-03-15"
}
]'Mix identifiers within the same batch
You can combine all three formats (id_contact, email, id_customer) in the same call. See Reference a contact for the resolution rules.
5. Use the assignments on the ShopiMind side
Segment by manager
In the segment editor, build a dynamic segment with the criterion:
Custom data →
Attribution.responsable_idequalsCOM-001(Alice)
The segment refreshes automatically as you push or update assignments. It's immediately usable in a bulk campaign targeting Alice's portfolio, in a scenario filter, or as a trigger.
Personalize message content
In an email or SMS, you can dynamically inject the data of the manager attached to the contact:
Hi {var=contact.first_name},
(your content)
Your dedicated advisor is here to help:
{var=Attribution.responsable.first_name} {var=Attribution.responsable.last_name}
📞 {var=Attribution.responsable.phone}
✉️ {var=Attribution.responsable.email}ShopiMind resolves the relation chain (Contact → Assignment → Account manager) on the fly. No conditional logic in the template — each contact receives a personalized message with their manager's details.
Going further
Mass reassignment
A manager leaves? Fetch their portfolio via listCustomDataRecords (filter responsable_id = X), then bulk-upsert toward their replacement — the uniqueness key on contact_id ensures existing assignments are updated, not duplicated:
curl -X POST 'https://core.shopimind.com/v1/custom-data-records/241' \
-H 'spm-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '[
{ "contact_id": { "by": "id_customer", "value": "CUST-A4521" }, "responsable_id": "COM-005", "assigned_at": "2026-05-08" },
{ "contact_id": { "by": "id_customer", "value": "CUST-A4522" }, "responsable_id": "COM-005", "assigned_at": "2026-05-08" }
]'All segments follow automatically.
Unassign a customer
To remove a contact's manager, delete the corresponding assignment row via deleteCustomDataRecord. The contact will no longer appear in any portfolio segment until a new assignment is pushed.
Recap
| Step | Endpoint | When |
|---|---|---|
| Create Account manager definition | createCustomDataDefinition | Once |
| Create Assignment definition (with 2 relations) | createCustomDataDefinition | Once |
| Sync managers | saveCustomDataRecords | On each hire/departure/update |
| Sync assignments | saveCustomDataRecords | On each CRM update |
| Unassign a contact | deleteCustomDataRecord | Ad-hoc |