# Contacts
NOTE
The URI for the API endpoint is often the same for multiple endpoints, the difference being in HTTP methods.
# List Contacts
GET https://api.wolfeo.me/v1/contacts
Returns a paginated list of all contacts in your account, ordered by most recent first.
# Example Request
curl --request GET "https://api.wolfeo.me/v1/contacts?period=last30days&per_page=25" \
--header "Authorization: Bearer YOUR_API_KEY"
# Parameters
| Parameter | Type | Description |
|---|---|---|
| period | string | Time range to filter by (see possible values below) |
| range | string | Custom date range — only used when period=between |
| page | integer | Page number (default: 1) |
| per_page | integer | Results per page — max 100 (default: 50) |
# Possible values for period
| Value | Description |
|---|---|
all | All contacts ever created |
today | Contacts created today |
yesterday | Contacts created yesterday |
last7days | Contacts created in the last 7 days |
last30days | Contacts created in the last 30 days |
between | Custom date range (requires range) |
# Format for range
2023-06-01to2023-06-29
# Sample Return
{
"success": true,
"data": [
{
"id": 1,
"email": "john@doe.ie",
"first_name": "John",
"last_name": "Doe",
"email_marketing": true,
"GDPR": false,
"created_at": "2024-01-01T09:00:00.000000Z"
}
],
"meta": {
"current_page": 1,
"last_page": 21,
"per_page": 50,
"total": 1038
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| INVALID_PERIOD | 400 | Invalid period or missing range |
# Retrieve Contact
GET https://api.wolfeo.me/v1/contact
# Example Request
curl --request GET "https://api.wolfeo.me/v1/contact?contact_id=1" \
--header "Authorization: Bearer YOUR_API_KEY"
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | int | A contact's ID |
** at least one of these parameters must be passed
# Sample Return
{
"success": true,
"data": {
"id": 1,
"email": "john@ted.com",
"first_name": "John",
"last_name": "Doe",
"email_marketing": false,
"GDPR": false,
"tags": [59],
"sequences": [61, 70, 72, 41],
"custom_fields": [
{ "label": "Company", "value": "Wolfeo Ltd" },
{ "label": "Plan", "value": "Pro" }
],
"subscriptions": [
{
"id": 12,
"status": "active",
"amount": 49.00,
"currency": "EUR",
"payment_source": "stripe",
"rate": "monthly",
"trial": false,
"rebill_date": "2024-08-01 00:00:00",
"payments_left": "unlimited",
"created_at": "2024-01-01 09:00:00"
}
]
}
}
TIP
tags and sequences are arrays of IDs. subscriptions is an empty array [] if the contact has no active subscription. custom_fields is an empty array [] if no values have been set.
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | No contact found for given parameters |
# Create Contact
POST https://api.wolfeo.me/v1/contact
# Example Request
curl --request POST "https://api.wolfeo.me/v1/contact" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"email": "john@doe.ie", "first_name": "John"}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email* | string | Contact's email address |
| first_name | string | Contact's first name |
| last_name | string | Contact's last/second name |
| email_marketing | boolean | Whether the contact has opted in to email marketing |
| gdpr | boolean | Whether the contact has given GDPR consent |
| tag_ids | string | Comma-separated list of tag IDs to apply. Example: 123,53434,2503 |
| sequence_ids | string | Comma-separated list of sequence IDs to subscribe to. Example: 61,70 |
* denotes a required parameter
# Sample Return
HTTP 201 Created
{
"success": true,
"data": {
"contact_id": 79
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| CONTACT_EXISTS | 409 | A contact with this email already exists in your account |
| VALIDATION_ERROR | 422 | email is missing or invalid; see error.details |
| VALIDATION_ERROR | 400 | tag_ids or sequence_ids list is incorrectly formatted (no details field) |
# Update Contact
PUT https://api.wolfeo.me/v1/contact
Upsert behaviour
This endpoint creates the contact if they don't exist yet. Pass email to look up an existing contact; if none is found, a new one is created with that email and the provided fields.
# Example Request
curl --request PUT "https://api.wolfeo.me/v1/contact" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"email": "john@doe.ie", "first_name": "John"}'
Only the fields you include are updated.
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email* | string | Contact's email address (used to look up the contact) |
| first_name | string | Contact's first name |
| last_name | string | Contact's last/second name |
| email_marketing | boolean | Whether the contact has opted in to email marketing |
| gdpr | boolean | Whether the contact has given GDPR consent |
| tag_ids | string | Comma-separated list of tag IDs to apply. Example: 123,53434,2503 |
| sequence_ids | string | Comma-separated list of sequence IDs to subscribe to. Example: 61,70 |
* denotes a required parameter
# Sample Return
{
"success": true,
"data": {
"contact_id": 79
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| VALIDATION_ERROR | 422 | email is missing or invalid; see error.details |
| VALIDATION_ERROR | 400 | tag_ids or sequence_ids list is incorrectly formatted (no details field) |
# Delete Contact
DELETE https://api.wolfeo.me/v1/contact
Contacts with orders or transactions
If the contact has associated orders or transactions, they cannot be fully deleted — their financial records must be preserved. Instead, they are automatically opted out of all email marketing and unsubscribed from all sequences. The response will reflect this with "deleted": false and a reason.
# Example Request
curl --request DELETE "https://api.wolfeo.me/v1/contact" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"contact_id": 1}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | int | A contact's ID |
** at least one of these parameters must be passed
# Sample Return — contact fully deleted
{
"success": true,
"data": {
"deleted": true
}
}
# Sample Return — contact has orders/transactions
{
"success": true,
"data": {
"deleted": false,
"reason": "Contact has associated orders or transactions and cannot be fully deleted. They have been opted out of email marketing and all sequences instead."
}
}
TIP
In both cases success is true — the request was handled correctly. Always check data.deleted to know whether the record was removed or only opted out.
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | No contact found for given parameters |
# Retrieve Contact Count
GET https://api.wolfeo.me/v1/contact-count
Returns the number of contacts created in your account over a given time range.
# Example Request
curl --request GET "https://api.wolfeo.me/v1/contact-count?period=last30days" \
--header "Authorization: Bearer YOUR_API_KEY"
# Parameters
| Parameter | Type | Description |
|---|---|---|
| period* | string | Time range to filter by (see possible values below) |
| range | string | Custom date range — only used when period=between |
* denotes a required parameter
# Possible values for period
| Value | Description |
|---|---|
all | All contacts ever created |
today | Contacts created today |
yesterday | Contacts created yesterday |
last7days | Contacts created in the last 7 days |
last30days | Contacts created in the last 30 days |
between | Custom date range (requires range) |
# Format for range
Pass two dates separated by to:
2023-06-01to2023-06-29
# Example URLs
https://api.wolfeo.me/v1/contact-count?period=all
https://api.wolfeo.me/v1/contact-count?period=today
https://api.wolfeo.me/v1/contact-count?period=last7days
https://api.wolfeo.me/v1/contact-count?period=between&range=2023-06-01to2023-06-29
# Sample Return
{
"success": true,
"data": {
"count": 906
}
}
# Add Tag to Contact
POST https://api.wolfeo.me/v1/contact-tag
# Example Request
curl --request POST "https://api.wolfeo.me/v1/contact-tag" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"contact_id": 1, "tag_id": 59}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | int | A contact's ID |
| tag_id* | int | The tag ID to apply |
** at least one of these parameters must be passed — * denotes required
# Sample Return
{
"success": true,
"data": {
"contact_id": 1,
"tag_id": 59
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | Contact or tag not found |
# Remove Tag from Contact
DELETE https://api.wolfeo.me/v1/contact-tag
# Example Request
curl --request DELETE "https://api.wolfeo.me/v1/contact-tag" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"contact_id": 1, "tag_id": 59}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | int | A contact's ID |
| tag_id* | int | The tag ID to remove |
** at least one of these parameters must be passed — * denotes required
# Sample Return
{
"success": true,
"data": {
"contact_id": 1,
"tag_id": 59
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | Contact or tag not found |
# Subscribe Contact to Sequence
POST https://api.wolfeo.me/v1/contact-sequence
# Example Request
curl --request POST "https://api.wolfeo.me/v1/contact-sequence" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"contact_id": 1, "sequence_id": 61}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | int | A contact's ID |
| sequence_id* | int | The sequence ID to subscribe to |
** at least one of these parameters must be passed — * denotes required
# Sample Return
{
"success": true,
"data": {
"contact_id": 1,
"sequence_id": 61
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | Contact or sequence not found |
# Unsubscribe Contact from Sequence
DELETE https://api.wolfeo.me/v1/contact-sequence
# Example Request
curl --request DELETE "https://api.wolfeo.me/v1/contact-sequence" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"contact_id": 1, "sequence_id": 61}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | int | A contact's ID |
| sequence_id* | int | The sequence ID to unsubscribe from |
** at least one of these parameters must be passed — * denotes required
# Sample Return
{
"success": true,
"data": {
"contact_id": 1,
"sequence_id": 61
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | Contact or sequence not found |
# Unsubscribe Contact from All Marketing
POST https://api.wolfeo.me/v1/contact-unsubscribe
Opts a contact out of all email marketing and removes them from all active sequences.
# Example Request
curl --request POST "https://api.wolfeo.me/v1/contact-unsubscribe" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"contact_id": 1}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | int | A contact's ID |
** at least one of these parameters must be passed
# Sample Return
{
"success": true,
"data": {
"contact_id": 1
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | No contact found for given parameters |
# Bulk Tag Contacts
POST https://api.wolfeo.me/v1/contacts-bulk-tag
Applies a tag to multiple contacts in a single call. Accepts up to 500 contact IDs. Contacts not belonging to your account are silently skipped.
# Example Request
curl --request POST "https://api.wolfeo.me/v1/contacts-bulk-tag" \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{"tag_id": 59, "contact_ids": [1, 2, 3, 4]}'
# Parameters
| Parameter | Type | Description |
|---|---|---|
| tag_id* | integer | The tag to apply |
| contact_ids* | array | Array of contact IDs — max 500 |
* denotes a required parameter
# Sample Return
{
"success": true,
"data": {
"tag_id": 59,
"queued": 4,
"skipped": 0
}
}
TIP
queued is the number of valid contacts the tag job was dispatched for. skipped is the count of IDs that did not match a contact in your account.
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | Tag not found, or no valid contacts found |
# Retrieve Contact Stats
GET https://api.wolfeo.me/v1/contact-stats
Returns email engagement statistics for a contact. Stats are read from Redis in real time.
# Example Request
curl --request GET "https://api.wolfeo.me/v1/contact-stats?contact_id=1" \
--header "Authorization: Bearer YOUR_API_KEY"
# Parameters
| Parameter | Type | Description |
|---|---|---|
| email** | string | A contact's email address |
| contact_id** | integer | A contact's ID |
** at least one of these parameters must be passed
# Sample Return
{
"success": true,
"data": {
"contact_id": 1,
"emails_sent": 12,
"emails_opened": 8,
"emails_clicked": 3,
"open_rate": 66.7,
"click_rate": 25.0
}
}
# Possible Errors
| Code | HTTP | Description |
|---|---|---|
| NOT_FOUND | 404 | No contact found for given parameters |