Provides an API client to connect to XQueue Maileon's REST API and (de-)serializes all API functions and data for easier use in PHP projects.
Maileon's REST API documentation can be found here.
For runnable examples and integration tests see the maileon-php-api-client-examples repository.
The API client requires PHP >= 7.4 with libxml and libcurl.
Additionally, all requests use an SSL encrypted API endpoint. To enable SSL support in CURL, please follow these steps:
- Download the official SSL cert bundle by CURL from https://curl.haxx.se/ca/cacert.pem
- Save the bundle to a directory that can be accessed by your PHP installation
- Add the following entry to your php.ini (remember to change the path to where you put the cert bundle):
curl.cainfo="your-path-to-the-bundle/cacert.pem"
You can add this library to your project using Composer:
composer require xqueue/maileon-api-client
All services accept a configuration array as their constructor argument. The following keys are supported:
| Key | Required | Default | Description |
|---|---|---|---|
API_KEY |
yes | — | Your Maileon REST API key |
BASE_URI |
no | https://api.maileon.com/1.0 |
Override the API base URL (e.g. for staging) |
DEBUG |
no | false |
Print cURL session logs and response details. Do not enable in production — output may contain sensitive data |
THROW_EXCEPTION |
no | true |
Throw a MaileonAPIException on connection errors or 5xx responses. When false, those calls return null instead |
TIMEOUT |
no | 5 |
cURL connect and total timeout in seconds |
PROXY_HOST |
no | — | Proxy hostname or IP |
PROXY_PORT |
no | 80 |
Proxy port |
$service = new ContactsService([
'API_KEY' => 'Your API key',
'TIMEOUT' => 10,
'THROW_EXCEPTION' => false,
]);The API client divides the features of Maileon's REST API into specific consumable services. Each service provides all functions of its specific category.
The following services are available:
-
Contacts Read, subscribe, edit, unsubscribe or delete contacts. Functions for individual contacts or bulk requests if required.
-
Blacklists Manage your blacklists.
-
Contact filters Segment your address pool by filter rules.
-
Targetgroups Manage distribution lists to specify who gets which mailing.
-
Reports Get all KPI information about your mailings and general reportings about your contact pool.
-
Mailings Manage and control your mailings.
-
Transactions Manage transaction endpoints (events) or send new transactions to trigger sendouts or Marketing Automation programs.
-
Marketing Automations Start your predefined Marketing Automation programs.
-
Accounts Configure specific account features.
-
Medias Manage mailing templates.
-
Webhooks Manage automatic data distributions to notify external systems of specific events.
-
Data Extensions Create, update, and delete data extensions (custom tables). Import, query, and bulk-delete records using all five import modes: INSERT, UPDATE, UPSERT, INSERT_IGNORE_DUPLICATES, DELETE.
-
Mailing Blacklists Create and manage named blacklists that suppress specific addresses from mailings. Add or retrieve blacklist expressions (patterns) per list.
-
Ping Verify connectivity and API key validity by sending test GET, PUT, POST, or DELETE requests to the API.
Every service method returns a MaileonAPIResult object. Use the following methods to inspect it:
| Method | Return type | Description |
|---|---|---|
isSuccess() |
bool |
true if the HTTP status code is 2xx |
isClientError() |
bool |
true if the HTTP status code is 4xx |
getStatusCode() |
int |
The raw HTTP status code |
getResult() |
mixed |
The deserialized response payload (typed object, array, or raw string depending on endpoint) |
getResultXML() |
SimpleXMLElement|null |
The response body parsed as XML, or null if the response was not XML |
getBodyData() |
string|null |
The raw response body string |
getResponseHeader(string $header) |
string|null |
A single response header value by name (case-insensitive) |
getResponseHeaders() |
array |
All response headers as an associative array |
The x-pages response header is used by paginated endpoints to indicate the total number of available pages.
When THROW_EXCEPTION is true (default), connection errors and 5xx responses throw a MaileonAPIException. When it is false, those calls return null — check for null before calling any method on the result.
$response = $service->someMethod();
if ($response === null || !$response->isSuccess()) {
// handle error — getResultXML()->message often contains the API error description
$message = $response?->getResultXML()?->message ?? 'Unknown error';
throw new RuntimeException((string) $message);
}
$data = $response->getResult();- Request basic contact data identified by their email address:
<?php
use de\xqueue\maileon\api\client\contacts\ContactsService;
require __DIR__ . '/vendor/autoload.php';
$contactsService = new ContactsService([
'API_KEY' => 'Your API key',
]);
$contact = $contactsService->getContactByEmail('[email protected]')->getResult();
/**
* The contact object stores all information you requested.
*
* Identifiers (Maileon ID, Maileon external id and email address), marketing permission
* level, creation date and last update date are always included if they are set in Maileon.
*
* ID: $contact->id
* Email: $contact->email
* Permission: $contact->permission->getType()
*/- Request a contact identified by its email address including their first name and a predefined custom field and also check for a valid response:
<?php
use de\xqueue\maileon\api\client\contacts\ContactsService;
use de\xqueue\maileon\api\client\contacts\StandardContactField;
require __DIR__ . '/vendor/autoload.php';
$contactsService = new ContactsService([
'API_KEY' => 'Your API key',
]);
$getContact = $contactsService->getContactByEmail(
email:'[email protected]',
standard_fields:[
StandardContactField::$FIRSTNAME,
StandardContactField::$LASTNAME,
],
custom_fields:[
'My custom field in Maileon',
]
);
if (!$getContact->isSuccess()) {
die($getContact->getResultXML()->message);
}
$contact = $getContact->getResult();
/**
* The contact object stores all information you requested.
*
* Identifiers (Maileon ID, Maileon external id and email address), marketing permission
* level, creation date and last update date are always included if they are set in Maileon.
*
* ID: $contact->id
* Email: $contact->email
* Permission: $contact->permission->getType()
* First name: $contact->standard_fields[StandardContactField::$FIRSTNAME];
* Custom field: $contact->custom_fields['My custom field in Maileon'];
*/- Create a contact in Maileon
<?php
use de\xqueue\maileon\api\client\contacts\ContactsService;
use de\xqueue\maileon\api\client\contacts\Contact;
use de\xqueue\maileon\api\client\contacts\Permission;
use de\xqueue\maileon\api\client\contacts\Preference;
use de\xqueue\maileon\api\client\contacts\StandardContactField;
use de\xqueue\maileon\api\client\contacts\SynchronizationMode;
require __DIR__ . '/vendor/autoload.php';
$contactsService = new ContactsService([
'API_KEY' => 'Your API key',
]);
$contact = new Contact(
email:'[email protected]',
standard_fields:[
StandardContactField::$FIRSTNAME => 'Foo',
StandardContactField::$LASTNAME => 'Bar',
],
custom_fields:[
'My custom field in Maileon' => 'A value corresponding to the field type',
],
);
$creation = $contactsService->createContact(
contact:$contact,
syncMode:SynchronizationMode::$IGNORE,
src:'An optional source of the contact creation',
subscriptionPage:'An additional source of the contact creation',
doi:true,
doiPlus:true, // Enable single user tracking with the DOI process
doiMailingKey:'A key to identify the DOI mailing',
);
if (!$creation->isSuccess()) {
die($creation->getResultXML()->message);
}- Synchronize a larger list of contacts in bulk
<?php
use de\xqueue\maileon\api\client\contacts\ContactsService;
use de\xqueue\maileon\api\client\contacts\Contacts;
use de\xqueue\maileon\api\client\contacts\Contact;
use de\xqueue\maileon\api\client\contacts\Permission;
use de\xqueue\maileon\api\client\contacts\SynchronizationMode;
use de\xqueue\maileon\api\client\contacts\StandardContactField;
require __DIR__ . '/vendor/autoload.php';
$contactsService = new ContactsService([
'API_KEY' => 'Your API key',
]);
$contactList = new Contacts();
for ($i=1; $i<=10000; $i++) {
$contactList->addContact(
new Contact(
email:"foo-{$i}@bar.com",
standard_fields:[
StandardContactField::$FIRSTNAME => 'Foo',
StandardContactField::$LASTNAME => 'Bar',
],
custom_fields:[
'My custom field in Maileon' => 'A value corresponding to the field type',
],
)
);
}
$response = $contactsService->synchronizeContacts(
contacts:$contactList,
syncMode:SynchronizationMode::$IGNORE,
useExternalId:false,
ignoreInvalidContacts:true,
reimportUnsubscribedContacts:false,
overridePermission:false,
updateOnly:false,
);
// The response contains some statistics and, if ignore_invalid_contacts is set
// to true, information about possibly failed contact creations, see
// https://maileon.com/support/synchronize-contacts/#articleTOC_3- Print all unsubscriptions:
<?php
use de\xqueue\maileon\api\client\reports\ReportsService;
require __DIR__ . '/vendor/autoload.php';
$contactsService = new ReportsService([
'API_KEY' => 'Your API key',
]);
$index = 1;
do {
$getUnsubscribers = $contactsService->getUnsubscribers(
pageIndex:$index++,
pageSize:1000
);
foreach ($getUnsubscribers->getResult() as $unsubscriber) {
printf('%s unsubscribed in mailing %u at %s'.PHP_EOL,
$unsubscriber->contact->email,
$unsubscriber->mailingId,
$unsubscriber->timestamp
);
}
} while($getUnsubscribers->getResponseHeader('x-pages') >= $index);- Get KPI data for a specific mailing:
<?php
use de\xqueue\maileon\api\client\reports\ReportsService;
require __DIR__ . '/vendor/autoload.php';
$reportsService = new ReportsService([
'API_KEY' => 'Your API key',
]);
$mailingId = 123;
$recipients = $reportsService->getRecipientsCount(mailingIds:[$mailingId])->getResult();
$opens = $reportsService->getOpensCount(mailingIds:[$mailingId])->getResult();
$clicks = $reportsService->getClicksCount(mailingIds:[$mailingId])->getResult();
$unsubscribers = $reportsService->getUnsubscribersCount(mailingIds:[$mailingId])->getResult();
$conversions = $reportsService->getConversionsCount(mailingIds:[$mailingId])->getResult();- Create a new mailing, add custom HTML content, attach a target group and send it immediately:
<?php
use de\xqueue\maileon\api\client\mailings\MailingsService;
require __DIR__ . '/vendor/autoload.php';
$mailingsService = new MailingsService([
'API_KEY' => 'Your API key',
]);
$mailingId = $mailingsService->createMailing(
name:'My campaign name',
subject:'Hi [CONTACT|FIRSTNAME]! We got some news for you!'
)->getResult();
$mailingsService->setSender($mailingId, '[email protected]');
$mailingsService->setSenderAlias($mailingId, 'Maileon news team');
$mailingsService->setHTMLContent(
mailingId:$mailingId,
html:'<html>...</html>',
doImageGrabbing:true,
doLinkTracking:true
);
$mailingsService->setTargetGroupId($mailingId, 123);
$mailingsService->sendMailingNow($mailingId);- Create a new data extension with two fields:
<?php
use de\xqueue\maileon\api\client\dataextensions\DataExtension;
use de\xqueue\maileon\api\client\dataextensions\DataExtensionField;
use de\xqueue\maileon\api\client\dataextensions\DataExtensionsService;
use de\xqueue\maileon\api\client\dataextensions\FieldDataType;
use de\xqueue\maileon\api\client\dataextensions\RetentionPolicy;
require __DIR__ . '/vendor/autoload.php';
$service = new DataExtensionsService(['API_KEY' => 'Your API key']);
$emailField = new DataExtensionField();
$emailField->name = 'email';
$emailField->data_type = FieldDataType::STRING;
$emailField->nullable = false;
$emailField->unique_identifier = true;
$valueField = new DataExtensionField();
$valueField->name = 'score';
$valueField->data_type = FieldDataType::INTEGER;
$valueField->nullable = true;
$extension = new DataExtension();
$extension->name = 'My custom table';
$extension->retention_policy = RetentionPolicy::NONE;
$extension->fields = [$emailField, $valueField];
$response = $service->createDataExtension($extension);
$extensionId = $response->getResult(); // numeric ID of the new extension- Import records using UPSERT (insert new rows, update existing ones by unique key):
<?php
use de\xqueue\maileon\api\client\dataextensions\DataExtensionsService;
require __DIR__ . '/vendor/autoload.php';
$service = new DataExtensionsService(['API_KEY' => 'Your API key']);
$extensionId = 123;
$records = [
['email' => '[email protected]', 'score' => '42'],
['email' => '[email protected]', 'score' => '17'],
];
$service->synchronizeRecords($extensionId, $records, 'UPSERT');
// Other import options: INSERT, UPDATE, INSERT_IGNORE_DUPLICATES, DELETE- Read all records page by page:
<?php
use de\xqueue\maileon\api\client\dataextensions\DataExtensionsService;
require __DIR__ . '/vendor/autoload.php';
$service = new DataExtensionsService(['API_KEY' => 'Your API key']);
$extensionId = 123;
$pageIndex = 1;
$pageSize = 100;
do {
$response = $service->getDataExtensionRecords($extensionId, $pageIndex, $pageSize);
foreach ($response->getResult() as $record) {
// $record->values is a field-name => value map
echo $record->values['email'] . PHP_EOL;
}
$pageIndex++;
} while ((int)$response->getResponseHeader('x-pages') >= $pageIndex);- Delete all records from a data extension:
<?php
use de\xqueue\maileon\api\client\dataextensions\DataExtensionsService;
require __DIR__ . '/vendor/autoload.php';
$service = new DataExtensionsService(['API_KEY' => 'Your API key']);
$extensionId = 123;
$service->deleteAllRecords($extensionId);- Send a new transaction including product information as an order confirmation:
<?php
use de\xqueue\maileon\api\client\transactions\ContactReference;
use de\xqueue\maileon\api\client\transactions\Transaction;
use de\xqueue\maileon\api\client\transactions\TransactionsService;
require __DIR__ . '/vendor/autoload.php';
$transactionsService = new TransactionsService([
'API_KEY' => 'Your API key',
]);
$transaction = new Transaction(
typeName:'My event to trigger',
contact:new ContactReference(
email:'[email protected]'
),
content:[
'foo' => 'bar',
'items' => [
[
'name' => 'foo',
'quantity' => 2,
'price' => 27.99
],
[
'name' => 'bar',
'quantity' => 1,
'price' => 16.49
],
],
]
);
$transactionsService->createTransactions([$transaction]);