Documentation menu

Contacts API

Manage your email contacts programmatically with the Contacts API.

List Contacts

Retrieve a paginated list of all contacts.

Endpoint

GET /api/contacts

Query Parameters

ParameterTypeDescriptionDefault
pageintegerPage number1
limitintegerItems per page (max: 100)20
statusstringFilter by status: subscribed, unsubscribedall
tagsstringFilter by tags (comma-separated)-
searchstringSearch by email, name-
sortstringSort field (prefix with - for desc)-created_at

Example Request

curl -X GET "https://api.postbeagle.com/api/contacts?page=1&limit=20&status=subscribed" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Example Response

{
  "success": true,
  "data": [
    {
      "id": "contact_123",
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Doe",
      "status": "subscribed",
      "tags": ["customer", "premium"],
      "custom_fields": {
        "company": "Acme Inc"
      },
      "created_at": "2025-01-15T10:30:00Z",
      "updated_at": "2025-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 150,
    "pages": 8
  }
}

Get Contact

Retrieve details for a specific contact.

Endpoint

GET /api/contacts/:id

Example Request

curl -X GET "https://api.postbeagle.com/api/contacts/contact_123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Example Response

{
  "success": true,
  "data": {
    "id": "contact_123",
    "email": "[email protected]",
    "first_name": "John",
    "last_name": "Doe",
    "status": "subscribed",
    "tags": ["customer", "premium"],
    "custom_fields": {
      "company": "Acme Inc",
      "phone": "+1234567890"
    },
    "lists": ["list_456", "list_789"],
    "engagement": {
      "campaigns_received": 25,
      "campaigns_opened": 18,
      "campaigns_clicked": 12,
      "last_opened": "2025-01-20T15:45:00Z"
    },
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-20T15:45:00Z"
  }
}

Create Contact

Add a new contact to your audience.

Endpoint

POST /api/contacts

Request Body

FieldTypeRequiredDescription
emailstringYesContact email address
first_namestringNoFirst name
last_namestringNoLast name
statusstringNosubscribed or unsubscribed (default: subscribed)
tagsarrayNoArray of tag strings
custom_fieldsobjectNoCustom field key-value pairs
listsarrayNoArray of list IDs
update_onlybooleanNoOnly update a contact that already exists; never create one. With no such contact, the response is 200 with "data": null and "skipped": "contact_not_found"

If a contact with the email already exists, its tags and custom fields are merged with the ones you send.

Example Request

curl -X POST "https://api.postbeagle.com/api/contacts" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "first_name": "Jane",
    "last_name": "Smith",
    "status": "subscribed",
    "tags": ["prospect"],
    "custom_fields": {
      "company": "Tech Corp",
      "role": "Manager"
    }
  }'

Example Response

{
  "success": true,
  "data": {
    "id": "contact_456",
    "email": "[email protected]",
    "first_name": "Jane",
    "last_name": "Smith",
    "status": "subscribed",
    "tags": ["prospect"],
    "custom_fields": {
      "company": "Tech Corp",
      "role": "Manager"
    },
    "created_at": "2025-01-22T09:15:00Z",
    "updated_at": "2025-01-22T09:15:00Z"
  }
}

Update Contact

Update an existing contact's information.

Endpoint

PUT /api/contacts/:id

Request Body

All fields are optional. Only include fields you want to update.

curl -X PUT "https://api.postbeagle.com/api/contacts/contact_456" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Jane Marie",
    "tags": ["prospect", "qualified"],
    "custom_fields": {
      "role": "Senior Manager"
    }
  }'

Example Response

{
  "success": true,
  "data": {
    "id": "contact_456",
    "email": "[email protected]",
    "first_name": "Jane Marie",
    "last_name": "Smith",
    "status": "subscribed",
    "tags": ["prospect", "qualified"],
    "custom_fields": {
      "company": "Tech Corp",
      "role": "Senior Manager"
    },
    "updated_at": "2025-01-22T10:30:00Z"
  }
}

Delete Contact

Permanently delete a contact.

Endpoint

DELETE /api/contacts/:id

Example Request

curl -X DELETE "https://api.postbeagle.com/api/contacts/contact_456" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Example Response

{
  "success": true,
  "message": "Contact deleted successfully"
}

Import Contacts

Import multiple contacts in a single request.

Endpoint

POST /api/contacts/import

Request Body

FieldTypeRequiredDescription
contactsarrayYesArray of contact objects
update_existingbooleanNoUpdate contacts if email exists (default: false)
list_idstringNoAdd all imported contacts to this list

Example Request

curl -X POST "https://api.postbeagle.com/api/contacts/import" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "email": "[email protected]",
        "first_name": "Alice",
        "last_name": "Johnson"
      },
      {
        "email": "[email protected]",
        "first_name": "Bob",
        "last_name": "Williams"
      }
    ],
    "update_existing": true,
    "list_id": "list_789"
  }'

Example Response

{
  "success": true,
  "data": {
    "imported": 2,
    "updated": 0,
    "failed": 0,
    "errors": []
  }
}

Subscribe/Unsubscribe

Change a contact's subscription status.

Subscribe

POST /api/contacts/:id/subscribe

Unsubscribe

POST /api/contacts/:id/unsubscribe

Example Request

curl -X POST "https://api.postbeagle.com/api/contacts/contact_123/subscribe" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Example Response

{
  "success": true,
  "data": {
    "id": "contact_123",
    "email": "[email protected]",
    "status": "subscribed",
    "updated_at": "2025-01-22T11:00:00Z"
  }
}

Error Responses

400 Bad Request - Invalid Email

{
  "success": false,
  "error": {
    "code": "INVALID_EMAIL",
    "message": "The email address is invalid",
    "field": "email"
  }
}

409 Conflict - Duplicate Email

{
  "success": false,
  "error": {
    "code": "DUPLICATE_EMAIL",
    "message": "A contact with this email already exists",
    "field": "email"
  }
}

404 Not Found - Contact Not Found

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Contact not found"
  }
}

Code Examples

JavaScript

// Create a new contact
async function createContact(email, firstName, lastName) {
  const response = await fetch('https://api.postbeagle.com/api/contacts', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      email,
      first_name: firstName,
      last_name: lastName,
      status: 'subscribed'
    })
  });
  
  return await response.json();
}

// Update a contact
async function updateContact(contactId, updates) {
  const response = await fetch(`https://api.postbeagle.com/api/contacts/${contactId}`, {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(updates)
  });
  
  return await response.json();
}

Python

import requests

# Create a new contact
def create_contact(email, first_name, last_name):
    url = 'https://api.postbeagle.com/api/contacts'
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    data = {
        'email': email,
        'first_name': first_name,
        'last_name': last_name,
        'status': 'subscribed'
    }
    
    response = requests.post(url, json=data, headers=headers)
    return response.json()

# List contacts
def list_contacts(page=1, limit=20):
    url = f'https://api.postbeagle.com/api/contacts?page={page}&limit={limit}'
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    
    response = requests.get(url, headers=headers)
    return response.json()

Best Practices

  1. Email Validation: Always validate email addresses before creating contacts
  2. Batch Imports: Use the import endpoint for adding multiple contacts
  3. Error Handling: Handle duplicate email errors gracefully
  4. Rate Limiting: Respect rate limits when importing large lists
  5. GDPR Compliance: Honor unsubscribe requests immediately
  6. Custom Fields: Use custom fields for additional contact data
  7. Tagging: Use tags for easy segmentation and filtering

Next Steps