Skip to main content
POST
/
public
/
v1
/
contacts
Python
import requests

url = 'https://api.minimo.it/public/v1/contacts'
headers = {'Authorization': 'Bearer {{BEARER_TOKEN}}', 'Content-Type': 'application/json'}
data = {
    'email': '{{email}}',
    'customFields': {
        '{{customKey1}}': '{{customValue1}}',
        '{{customKey2}}': '{{customValue2}}',
        '{{customKey3}}': '{{customValue3}}'
    },
    'marketingConsent': {
        'email': True,
        'whatsapp': False
    }
}
response = requests.post(url, json=data, headers=headers)
print(response.json())
[
  {
    "contactId": "<string>"
  }
]
This endpoint performs an upsert: it first tries to match by email, then falls back to phone if no email match is found. If no match is found, a new contact is created.

How Matching Works

The endpoint matches contacts in this order:
1

Match by email

If email is provided, searches for an existing contact with the same email in your company.
2

Match by phone

If no email match is found and phone is provided, searches by phone number.
3

Create new

If no match is found, creates a new contact.
Need to update a contact’s email? Prefer Update by ID for a deterministic update. Upsert only avoids creating a new record if a phone number is also provided and matches an existing contact.

Custom Fields

Store additional data using the customFields object. Fields are flexible key-value pairs:
{
  "email": "customer@example.com",
  "customFields": {
    "company": "Acme Corp",
    "plan": "enterprise",
    "signup_date": "2025-11-13"
  }
}
When updating an existing contact, custom fields are deep merged — only the fields you include are changed, existing fields are preserved. Control channel-specific marketing consent when creating or updating a contact:
{
  "email": "customer@example.com",
  "marketingConsent": {
    "email": true,
    "whatsapp": false
  }
}
FieldTypeDescription
emailbooleanEmail marketing opt-in (true) or opt-out (false)
whatsappbooleanWhatsApp marketing opt-in (true) or opt-out (false)
Both fields are optional. Omitting a channel leaves its current consent status unchanged. Setting true opts the contact in, false opts them out.

Phone Numbers

For WhatsApp messaging, include a phone number in E.164 format:
{
  "email": "customer@example.com",
  "phone": "+393391234567"
}
Format requirements:
  • Include country code (e.g., +39 for Italy, +1 for US)
  • No spaces, dashes, or parentheses
  • Example: +12025551234 (US), +393391234567 (Italy)
Invalid phone numbers will cause WhatsApp message sending to fail.

Common Errors

ErrorCauseSolution
validation_errorInvalid email formatCheck email address format
invalid_phone_numberPhone not in E.164 formatAdd country code, remove spaces
rate_limit_exceededToo many requestsImplement rate limiting, use batching
unauthorizedInvalid API keyVerify API key in Authorization header

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

email
string
required

Email address of the contact

phone
string

Phone number of the contact

customFields
object

Custom fields specific to the contact

Channel-specific marketing consent preferences

Response

Successful response

contactId
string
Example:

"12345"