Contacts
The people your organization talks to: details, lifecycle stage, tags, channel identities, consent and notes. A contact can have several identities (their WhatsApp, their Instagram, their email) and all of them point to the same record.
List contacts
GET/contacts
The organization's contacts, paginated and with filters: tab (tab), stage, owner (ownerId, or none for those without one), source, channel, tag, free-text search (q) or recent activity (days). Besides data and meta it includes tabs (how many are in each tab) and summary (the dashboard header figures).
Scopes: contacts:read
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
page | query | number | default: 1 · 1 – … |
pageSize | query | number | default: 20 · 1 – 100 |
tab | query | string | all · leads · in_progress · customers · inactive · no_consent |
lifecycleStageId | query | uuid | |
ownerId | query | string | ^(none|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$ |
source | query | string | OTHER · MANUAL · IMPORT · WHATSAPP_INBOUND · CAMPAIGN · WEBSITE_FORM · REFERRAL |
channelType | query | string | WHATSAPP · INSTAGRAM · MESSENGER · FACEBOOK · TELEGRAM · TIKTOK · WEBCHAT · EMAIL · SMS · WECHAT · VOICE |
tag | query | string | 0–60 characters |
q | query | string | 0–120 characters |
search | query | string | 0–120 characters |
days | query | number | 7 · 30 · 90 |
ids | query | uuid[] | ≤ 500 |
curl "https://micuenta.whatsmarketing.es/api/v1/contacts?page=1&pageSize=20" \
-H "Authorization: Bearer $WM_API_KEY"const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts?page=1&pageSize=20', {
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
},
});
const data = await res.json();import os, requests
r = requests.get(
"https://micuenta.whatsmarketing.es/api/v1/contacts?page=1&pageSize=20",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts?page=1&pageSize=20');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);{
"data": [
{
"id": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"fullName": "Laura Pérez",
"primaryPhone": "+34612345678",
"primaryEmail": "laura@ejemplo.com",
"company": "Clínica Sol",
"country": "ES",
"source": "WEBSITE_FORM",
"lifecycleStageId": "9c2a1f00-2b3c-4d5e-8f90-1a2b3c4d5e6f",
"lifecycleStage": {
"id": "9c2a1f00-2b3c-4d5e-8f90-1a2b3c4d5e6f",
"name": "Lead nuevo",
"order": 1
},
"ownerId": null,
"owner": null,
"optedOut": false,
"consent": {
"given": true,
"at": "2026-10-14T10:20:00.000Z",
"how": "WEBSITE_FORM"
},
"tags": [
"web"
],
"identities": [
{
"id": "6d7e8f90-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
"channelType": "WHATSAPP",
"externalId": "34612345678"
}
],
"lastConversation": null,
"createdAt": "2026-10-14T10:20:05.000Z",
"updatedAt": "2026-10-14T10:20:05.000Z"
}
],
"meta": {
"page": 1,
"pageSize": 20,
"total": 1,
"totalPages": 1
},
"tabs": {
"all": 1,
"leads": 1,
"in_progress": 0,
"customers": 0,
"inactive": 0,
"no_consent": 0
},
"summary": {
"days": 30,
"total": 1,
"newInPeriod": 1,
"withConsent": 1,
"withoutConsent": 0,
"consentPct": 100,
"leadsNew": 1,
"leadsInProgress": 0,
"customers": 0,
"customersNewInPeriod": 0,
"tags": [
"web"
]
}
}Create a contact
POST/contacts
Creates the record. The phone goes in international format with prefix (+34…). If a contact with that phone already exists, it responds 409 CONTACT_PHONE_EXISTS with the existing contactId. consent records when and how the person consented to receive messages; note leaves a first internal note.
Scopes: contacts:write
Request body CreateContact
| Name | Type | Values |
|---|---|---|
fullName | string | 0–160 characters |
primaryPhone | string | 0–32 characters |
primaryEmail | ||
company | string | 0–160 characters |
country | string | 0–2 characters |
source | string | OTHER · MANUAL · IMPORT · WHATSAPP_INBOUND · CAMPAIGN · WEBSITE_FORM · REFERRAL |
lifecycleStageId | uuid | |
ownerId | uuid | |
optedOut | boolean | |
consent | Consent | |
tags | string[] | ≤ 50 |
note | string | 0–4000 characters |
Common errors
- 409
CONTACT_PHONE_EXISTSA contact with that phone already exists; the response includescontactIdandfullName.
curl -X POST "https://micuenta.whatsmarketing.es/api/v1/contacts" \
-H "Authorization: Bearer $WM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fullName": "Laura Pérez",
"primaryPhone": "+34612345678",
"primaryEmail": "laura@ejemplo.com",
"company": "Clínica Sol",
"country": "ES",
"source": "WEBSITE_FORM",
"tags": [
"web"
],
"consent": {
"given": true,
"at": "2026-10-14T10:20:00.000Z",
"how": "WEBSITE_FORM"
}
}'const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"fullName": "Laura Pérez",
"primaryPhone": "+34612345678",
"primaryEmail": "laura@ejemplo.com",
"company": "Clínica Sol",
"country": "ES",
"source": "WEBSITE_FORM",
"tags": [
"web"
],
"consent": {
"given": true,
"at": "2026-10-14T10:20:00.000Z",
"how": "WEBSITE_FORM"
}
}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://micuenta.whatsmarketing.es/api/v1/contacts",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
json={
"fullName": "Laura Pérez",
"primaryPhone": "+34612345678",
"primaryEmail": "laura@ejemplo.com",
"company": "Clínica Sol",
"country": "ES",
"source": "WEBSITE_FORM",
"tags": [
"web"
],
"consent": {
"given": True,
"at": "2026-10-14T10:20:00.000Z",
"how": "WEBSITE_FORM"
}
},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'fullName' => 'Laura Pérez',
'primaryPhone' => '+34612345678',
'primaryEmail' => 'laura@ejemplo.com',
'company' => 'Clínica Sol',
'country' => 'ES',
'source' => 'WEBSITE_FORM',
'tags' => [
'web'
],
'consent' => [
'given' => true,
'at' => '2026-10-14T10:20:00.000Z',
'how' => 'WEBSITE_FORM'
]
]),
]);
$data = json_decode(curl_exec($ch), true);{
"id": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"organizationId": "f0e1d2c3-b4a5-4968-8776-655443322110",
"fullName": "Laura Pérez",
"primaryPhone": "+34612345678",
"primaryEmail": "laura@ejemplo.com",
"company": "Clínica Sol",
"country": "ES",
"source": "WEBSITE_FORM",
"lifecycleStageId": null,
"lifecycleStage": null,
"ownerId": null,
"owner": null,
"optedOut": false,
"consent": {
"given": true,
"at": "2026-10-14T10:20:00.000Z",
"how": "WEBSITE_FORM"
},
"tags": [
"web"
],
"identities": [
{
"id": "6d7e8f90-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
"channelType": "WHATSAPP",
"externalId": "34612345678"
}
],
"createdAt": "2026-10-14T10:20:05.000Z",
"updatedAt": "2026-10-14T10:20:05.000Z"
}Bulk update contacts
POST/contacts/bulk
Up to 500 contacts per call: change the stage, add tags (up to 20) or reassign the owner (ownerId: null removes it). At least one of the three. skipped are the ids that don't belong to your organization.
Scopes: contacts:write
Request body BulkContacts
| Name | Type | Values |
|---|---|---|
ids required | uuid[] | ≤ 500 |
lifecycleStageId | uuid | |
addTags | string[] | ≤ 20 |
ownerId | uuid |
curl -X POST "https://micuenta.whatsmarketing.es/api/v1/contacts/bulk" \
-H "Authorization: Bearer $WM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b"
],
"addTags": [
"evento-madrid"
],
"lifecycleStageId": "9c2a1f00-2b3c-4d5e-8f90-1a2b3c4d5e6f"
}'const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/bulk', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"ids": [
"0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b"
],
"addTags": [
"evento-madrid"
],
"lifecycleStageId": "9c2a1f00-2b3c-4d5e-8f90-1a2b3c4d5e6f"
}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://micuenta.whatsmarketing.es/api/v1/contacts/bulk",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
json={
"ids": [
"0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b"
],
"addTags": [
"evento-madrid"
],
"lifecycleStageId": "9c2a1f00-2b3c-4d5e-8f90-1a2b3c4d5e6f"
},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/bulk');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'ids' => [
'0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e',
'4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b'
],
'addTags' => [
'evento-madrid'
],
'lifecycleStageId' => '9c2a1f00-2b3c-4d5e-8f90-1a2b3c4d5e6f'
]),
]);
$data = json_decode(curl_exec($ch), true);{
"updated": 2,
"skipped": 0
}Get a contact
GET/contacts/{id}
The full record: channel identities, consent, tags, owner, stage and open deals.
Scopes: contacts:read
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
id required | path | string |
curl "https://micuenta.whatsmarketing.es/api/v1/contacts/{id}" \
-H "Authorization: Bearer $WM_API_KEY"const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}', {
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
},
});
const data = await res.json();import os, requests
r = requests.get(
"https://micuenta.whatsmarketing.es/api/v1/contacts/{id}",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);{
"id": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"organizationId": "f0e1d2c3-b4a5-4968-8776-655443322110",
"fullName": "Laura Pérez",
"primaryPhone": "+34612345678",
"primaryEmail": "laura@ejemplo.com",
"company": "Clínica Sol",
"country": "ES",
"source": "WEBSITE_FORM",
"lifecycleStageId": null,
"lifecycleStage": null,
"ownerId": null,
"owner": null,
"optedOut": false,
"consent": {
"given": true,
"at": "2026-10-14T10:20:00.000Z",
"how": "WEBSITE_FORM"
},
"tags": [
"web"
],
"identities": [
{
"id": "6d7e8f90-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
"channelType": "WHATSAPP",
"externalId": "34612345678"
}
],
"createdAt": "2026-10-14T10:20:05.000Z",
"updatedAt": "2026-10-14T10:20:05.000Z"
}Update a contact
PATCH/contacts/{id}
All fields are optional; only what you send changes. Changing the phone to one that another contact already has responds 409 CONTACT_PHONE_EXISTS. Responds with the updated record.
Scopes: contacts:write
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
id required | path | string |
Request body UpdateContact
| Name | Type | Values |
|---|---|---|
fullName | string | 0–160 characters |
primaryPhone | string | 0–32 characters |
primaryEmail | ||
company | string | 0–160 characters |
country | string | 0–2 characters |
source | string | OTHER · MANUAL · IMPORT · WHATSAPP_INBOUND · CAMPAIGN · WEBSITE_FORM · REFERRAL |
lifecycleStageId | uuid | |
ownerId | uuid | |
optedOut | boolean | |
consent | Consent | |
tags | string[] | ≤ 50 |
curl -X PATCH "https://micuenta.whatsmarketing.es/api/v1/contacts/{id}" \
-H "Authorization: Bearer $WM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"company": "Clínica Sol Fuengirola",
"tags": [
"web",
"cliente"
],
"lifecycleStageId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
}'const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"company": "Clínica Sol Fuengirola",
"tags": [
"web",
"cliente"
],
"lifecycleStageId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
}),
});
const data = await res.json();import os, requests
r = requests.patch(
"https://micuenta.whatsmarketing.es/api/v1/contacts/{id}",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
json={
"company": "Clínica Sol Fuengirola",
"tags": [
"web",
"cliente"
],
"lifecycleStageId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'company' => 'Clínica Sol Fuengirola',
'tags' => [
'web',
'cliente'
],
'lifecycleStageId' => 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d'
]),
]);
$data = json_decode(curl_exec($ch), true);{
"id": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"organizationId": "f0e1d2c3-b4a5-4968-8776-655443322110",
"fullName": "Laura Pérez",
"primaryPhone": "+34612345678",
"primaryEmail": "laura@ejemplo.com",
"company": "Clínica Sol",
"country": "ES",
"source": "WEBSITE_FORM",
"lifecycleStageId": null,
"lifecycleStage": null,
"ownerId": null,
"owner": null,
"optedOut": false,
"consent": {
"given": true,
"at": "2026-10-14T10:20:00.000Z",
"how": "WEBSITE_FORM"
},
"tags": [
"web"
],
"identities": [
{
"id": "6d7e8f90-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
"channelType": "WHATSAPP",
"externalId": "34612345678"
}
],
"createdAt": "2026-10-14T10:20:05.000Z",
"updatedAt": "2026-10-14T10:20:05.000Z"
}Delete a contact
DELETE/contacts/{id}
Only if the contact has no conversations, campaigns or deals; if it does, it responds 409 CONTACT_HAS_HISTORY and it's better to withdraw their consent (optedOut: true) instead of deleting. Notes and identities are deleted along with it.
Scopes: contacts:write
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
id required | path | string |
Common errors
- 409
CONTACT_HAS_HISTORYThe contact has history: it isn't deleted so that reports keep adding up.
curl -X DELETE "https://micuenta.whatsmarketing.es/api/v1/contacts/{id}" \
-H "Authorization: Bearer $WM_API_KEY"const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
},
});
const data = await res.json();import os, requests
r = requests.delete(
"https://micuenta.whatsmarketing.es/api/v1/contacts/{id}",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);{
"deleted": true
}Contact timeline
GET/contacts/{id}/timeline
Conversations, campaigns received, notes, stage changes, consent and creation, in reverse chronological order. type filters by conversations, campaigns or notes; each entry carries its type.
Scopes: contacts:read
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
id required | path | string | |
page | query | number | default: 1 · 1 – … |
pageSize | query | number | default: 20 · 1 – 100 |
type | query | string | all · conversations · campaigns · notes |
curl "https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/timeline?page=1&pageSize=20" \
-H "Authorization: Bearer $WM_API_KEY"const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/timeline?page=1&pageSize=20', {
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
},
});
const data = await res.json();import os, requests
r = requests.get(
"https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/timeline?page=1&pageSize=20",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/timeline?page=1&pageSize=20');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);{
"data": [
{
"id": "7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
"type": "campaign",
"at": "2026-10-10T08:00:00.000Z",
"campaign": {
"id": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
"name": "Octubre: promo"
},
"status": "DELIVERED",
"sentAt": "2026-10-10T08:00:02.000Z",
"deliveredAt": "2026-10-10T08:00:05.000Z",
"readAt": null,
"failedAt": null,
"errorMessage": null
},
{
"id": "8d9e0f1a-2b3c-4d4e-9f5a-6b7c8d9e0f1a",
"type": "note",
"at": "2026-10-09T17:12:00.000Z",
"author": "Ana Gómez",
"body": "Pidió presupuesto por teléfono"
},
{
"id": "9e0f1a2b-3c4d-4e5f-8a6b-7c8d9e0f1a2b",
"type": "stage",
"at": "2026-10-09T17:00:00.000Z",
"by": "Ana Gómez",
"from": "Lead nuevo",
"to": "En proceso",
"bulk": false
},
{
"id": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"type": "created",
"at": "2026-10-01T09:00:00.000Z",
"source": "WEBSITE_FORM"
}
],
"meta": {
"page": 1,
"pageSize": 20,
"total": 4,
"totalPages": 1
}
}Add a channel identity
POST/contacts/{id}/identities
Links another channel to the same record: channelType is the channel type (WHATSAPP, INSTAGRAM, MESSENGER, EMAIL…) and externalId the contact's identifier on that channel (phone without + for WhatsApp, username for Instagram, address for email). If that identity already belongs to another contact, it responds 409.
Scopes: contacts:write
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
id required | path | string |
Request body AddIdentity
| Name | Type | Values |
|---|---|---|
channelType required | string | WHATSAPP · INSTAGRAM · MESSENGER · FACEBOOK · TELEGRAM · TIKTOK · WEBCHAT · EMAIL · SMS · WECHAT · VOICE |
externalId required | string |
curl -X POST "https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/identities" \
-H "Authorization: Bearer $WM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channelType": "INSTAGRAM",
"externalId": "laura.perez"
}'const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/identities', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"channelType": "INSTAGRAM",
"externalId": "laura.perez"
}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/identities",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
json={
"channelType": "INSTAGRAM",
"externalId": "laura.perez"
},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/identities');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'channelType' => 'INSTAGRAM',
'externalId' => 'laura.perez'
]),
]);
$data = json_decode(curl_exec($ch), true);{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"contactId": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"channelId": "5f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c",
"channel": {
"id": "5f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c",
"type": "INSTAGRAM"
},
"externalId": "laura.perez"
}List contact notes
GET/contacts/{id}/notes
Internal team notes, from newest to oldest, with author and date.
Scopes: contacts:read
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
id required | path | string | |
page | query | number | default: 1 · 1 – … |
pageSize | query | number | default: 20 · 1 – 100 |
curl "https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes?page=1&pageSize=20" \
-H "Authorization: Bearer $WM_API_KEY"const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes?page=1&pageSize=20', {
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
},
});
const data = await res.json();import os, requests
r = requests.get(
"https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes?page=1&pageSize=20",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes?page=1&pageSize=20');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
],
]);
$data = json_decode(curl_exec($ch), true);{
"data": [
{
"id": "8d9e0f1a-2b3c-4d4e-9f5a-6b7c8d9e0f1a",
"contactId": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"authorId": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
"author": {
"id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
"fullName": "Ana Gómez"
},
"body": "Pidió presupuesto por teléfono",
"createdAt": "2026-10-09T17:12:00.000Z"
}
],
"meta": {
"page": 1,
"pageSize": 20,
"total": 1,
"totalPages": 1
}
}Add a note
POST/contacts/{id}/notes
The note is attributed to the user who created the API key.
Scopes: contacts:write
Parameters
| Name | Where | Type | Values |
|---|---|---|---|
id required | path | string |
Request body CreateContactNote
| Name | Type | Values |
|---|---|---|
body required | string | 1–… characters |
curl -X POST "https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes" \
-H "Authorization: Bearer $WM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Llamada hecha: le interesa el plan Pyme."
}'const res = await fetch('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WM_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"body": "Llamada hecha: le interesa el plan Pyme."
}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes",
headers={"Authorization": f"Bearer {os.environ['WM_API_KEY']}"},
json={
"body": "Llamada hecha: le interesa el plan Pyme."
},
timeout=30,
)
r.raise_for_status()
data = r.json()<?php
$ch = curl_init('https://micuenta.whatsmarketing.es/api/v1/contacts/{id}/notes');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('WM_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'body' => 'Llamada hecha: le interesa el plan Pyme.'
]),
]);
$data = json_decode(curl_exec($ch), true);{
"id": "4c5d6e7f-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
"contactId": "0b1c2d3e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
"authorId": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
"author": {
"id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
"fullName": "Ana Gómez"
},
"body": "Llamada hecha: le interesa el plan Pyme.",
"createdAt": "2026-10-14T11:00:00.000Z"
}Schemas
Consent
| Name | Type | Values |
|---|---|---|
given required | boolean | |
at | string | |
how | string | OTHER · WEBSITE_FORM · PHONE · WHATSAPP_REPLY · CONTRACT |