This document will show you some examples on how to use our REST API. The code snippets will be in PHP. If you are using a different language, these examples should still give you a pretty good hint on how to use our REST API and the Oauth interface.

REST in General

Our latest API is a RESTful one, since REST calls are pretty straight forward. Initiliaze your REST Library, append the access token (or do a login and use that token instead) and you are ready to query the API. Check Our full REST API documentaion because it contains everything you need to know and also you can test your queries there.

We also wrote a PHP REST library which most of the the examples here will be based on. You can download our REST library including some examples here.

You need to know this!

The REST API basicly works like every HTTP browser. You want to access a resource f.e. "/groups" and you want to GET all the available groups. Except that REST utilizes the other methods like POST, PUT and DELETE aswell. GET will obviously read from resources, POST will create new resources, PUT updates resources and DELETE will of course delete resources. For a detailed list of available resources and methods, have a look at our REST API documentaion.


Before we can start sending queries, we need to authenticate with the REST API. We will be using the OAuth Baerer method for authenticating.

$rest = new CR\tools\rest("");

//skip this part if you have an OAuth access token
$token = $rest->post('/login',

$rest->setAuthMode("bearer", $token);

GET (retrieve)

To retrieve a resource, like all your available groups, simply run this:

$data = $rest->get("/groups");

Some resources have additional filters/options. /mailings for example has filters to specify what kind of mailings you want (all/finished/draft/waiting)

$data = $rest->get("/mailings", array("type"=>"draft") );

POST (create new and special functions)

Creating a new resource like f.e. a group, follows the same principle. All you need to do is adding the required parameters.

$data = $rest->post("/groups", array("name"=>"my new REST group") );

PUT (update)

Updating a resource requires you to know the resource ID, but follows the same style as a POST.

$data = $rest->put("/groups/1234", array("name"=>"my updated REST group") );


Deleting just requires the resource ID

$data = $rest->delete("/groups/1234");

Error handling

In case of errors, you will receive a http error code and the apropiate error description. In this example we tried to access a report which does not exist.

$data = $rest->get("/report/4321");

  "error": {
    "code": 404,
    "message": "Not Found"


The CleverReach® data structure might be a bit confusing at first, so we are going to explain some basics here.

During the usage of the REST API you will encounter these main resources.


While every resource is accessable on its own, some of these resources may be nested within each other because they can have multiple points of origin.

/receivers f.e. can be a standalone resource, returning you information about an email address.
/groups/receivers on the other hand returns only the receiver inside this group and way more data like subscription dates, group bound attributes events and more.

/attributes Returns a list of all global attributes (not bound to any group)
/groups/{group_id}/attributes returns all attributes bound to this group and
groups/{group_id}/receivers/{pool_id}/attributes returns all attributes assigned to this user INCLUDING their current values.
However, if you just use groups/{group_id}/receivers/{pool_id}, you will get the attributes of the user anyway embeded inside the returned structure.

Example REST Calls

Initialization - Create what you need!

Once you plugin is beeing initialized, its best to create the necessary group (or let the user select it) and attributes in advance. Usualy its best to just create global attributes which can be accessed no matter what group you are currently using. Also only create attributes the user realy needs since the number of attributes are limited.

Imagine a User withe the Email "" with the firstname "Bruce". It should not matter what group (list) he is in, his name will always be "Bruce". Therefor creating a global attribute "Firstname" makes sense.

$rest->post("/attributes", array("name"=>"salutation", "type"=>"gender"));
$rest->post("/attributes", array("name"=>"firstname", "type"=>"text"));
$rest->post("/attributes", array("name"=>"lastname", "type"=>"text"));
$rest->post("/attributes", array("name"=>"address", "type"=>"text"));
$rest->post("/attributes", array("name"=>"city", "type"=>"text"));
$rest->post("/attributes", array("name"=>"zip", "type"=>"text"));
$rest->post("/attributes", array("name"=>"country", "type"=>"text"));
$rest->post("/attributes", array("name"=>"birthday", "type"=>"date"));

If you are writing software for f.e. Multishop solutions, you might want to switch to group bound attributes because the multiple firstnames might interfere with each other.

$rest->post("/groups/{$groupid}/attributes", array("name"=>"firstname", "type"=>"text"));
$rest->post("/groups/{$groupid}/attributes", array("name"=>"lastname", "type"=>"text"));

Syncronize/import receivers

After your setup process, its best to do an initial import. This should be done in stacks and not one by one. While you can import each user one by one, you shouldnt, because this way you will be dealing with way more overhead then necessary.

Here for example, we are passing to the REST API once a stack reaches 1000.

$receivers = array();
$rows = mysql_query("select id, email, firstname, lastname, gender, registration_date from user");

foreach ($rows as $row) {
	$orders = array();
	$order_rows = mysql_query("select * from orders where user_id={$row->id}");
	foreach ($order_rows as $order_row) {
		$orders[] = array(
			"order_id"   => $order_row->order_id,      //required
			"product_id" => $order_row->product_id,    //optional
			"product"    => $order_row->product_name,  //required
			"price"      => $order_row->single_price,  //optional
			"currency"   => "EUR",                     //optional
			"amount"     => $order_row->order_ammount, //optional
			"mailing_id" => $order_row->mailing_id,    //optional
			"source"     => ""          //optional

	$receivers[] = array(
		"email"			=> $row->email,
		"registered"		=> strtotime($row->registration_date),
		"activated"		=> strtotime($row->registration_date),
		"source"		=> "Batcave Computer",
		"global_attributes"	=> array(
			"firstname" => $row->firstname,
			"lastname" =>  $row->lastname,
			"gender" =>    $row->gender
		"orders" => $orders


	if( count($receivers) > 1000) {
		$rest->post("/groups/{$target_group_id}/receivers", $receivers);
		$receivers = array();
$rest->post("/groups/{$target_group_id}/receivers", $receivers);

Order injection vs. import (post setup)

Since data still needs to be synchronized after the initial import, there are 2 methods you can use. You can either run the original import as a cronjob, or you can do a live order injection. We actualy prefer the live order injection which is basicly nothing more like reduced version of the Import.
Please make sure that you are using some sort of try and catch methods, otherwhise you might break your shops order process if the API cant be reached and any other error occurs.

try {
	$receiver = array(
		"email"      => "",
		"registered" => time(),	//current date
		"activated"  => time(),
		"source"     => "Batcave Computer",
		"global_attributes" => array(
			"firstname" => "Bruce",
			"lastname"  => "Wayne",
			"gender"    => "male"
		"orders" => array(
				"order_id" => "xyz12345",                //required
				"product_id" => "SN12345678",            //optional
				"product" => "Batman - The Movie (DVD)", //required
				"price" => 9.99,                         //optional
				"currency" => "EUR",                     //optional
				"amount" => 1,                           //optional
				"mailing_id" => "8765432",               //optional
				"source" => "Batshop"                    //optional
				"order_id" => "xyz12345",                //required
				"product" => "Batman - The Musical (CD)" //required


	$batman = $rest->post("/groups/{$gotham_group->id}/receivers", $receiver);
} catch (\Exception $e){
	system_log("error syncing order");


To send a DOI Email, you have to first create the customer. Please note the that the field "activated" is set to ZERO which means he will not be active and can't receive any newsletters until he is activated. After creation we will tell the REST API to sent him a specific form to activate his account.

$new_user = array(
	"email"      => "",
	"registered" => time(),  //current date
	"activated"  => 0,       //NOT active, will be set by DOI
	"source"     => "Batcave Computer",
	"attributes" => array(
		"firstname" => "Bruce",
		"lastname"  => "Wayne",
		"gender"    => "male"

if( $success = $rest->post("/groups/{$target_group_id}/receivers", $new_user) ) {
	$rest->post("/forms/{$form_id}/send/activate", array(
		"email"   => $new_user["email"],
		"doidata" => array(
			"user_ip"    => $_SERVER["REMOTE_ADDR"],
			"referer"    => $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"],
			"user_agent" => $_SERVER["HTTP_USER_AGENT"]

Our OAuth implementation follows the 2.0 Specification. For a detailed OAuth explanation please have a look at this introduction to OAuth.
The main approach of OAuth is to get a REST API Token in order to be able to control the users account by using the REST API.

How to work with OAuth in CleverReach®:

  1. Go to Account > Extras > REST API and create an OAuth app inside of CleverReach®.
    Note the Client ID and the Client Secret the app contains!
  2. Create a callback page to be called after OAuth process has finished.
    Place that file on a server to be refereed to as the redirect_uri.
  3. Redirect the user to our OAuth service (see example code)
    The user will grant you access by logging in to CleverReach®.
    After the OAuth process finished, the redirect_uri is called.
  4. The redirect_uri - your callback page - is called with a code.
    Immediately trade this code in for an access token (see example code).
    Please note, that the code is valid only a few seconds!
This way, all your users can provide you with a token using one OAuth app.
It is really easy. Give it a try!

Example OAuth process

We will handle both, the callback page and the page to start from in one php file. Note the if to differ the output.
The example is well documented, though to try you do not need to read all the comments. Just fill the variables and go...

Download the example here

// This file contains both:
//   1. A simulation of your page/plugin/service to start the OAuth
//   2. The callback page to be called after OAuth finished
// Make sure to place this file freely accessible on a server!

// At first some very important variables:

// Values from your OAuth app. You create ONE for a page/plugin/service.
$clientid     = "#Place OAuth clientID here#";
$clientsecret = "#Place OAuth client secret here#";

// This is the url of your callback page, to be called after OAuth finished.
// In this case it is this file - wherever you put it on your server.
$redirect_uri = "#The URL of this file#";

// The official CleverReach URLs, no need to change those.
$auth_url  = "";
$token_url = "";

// As the callback page is called by our OAuth service with a code, we use that parameter to differ between the two pages.

if (!$_GET["code"]) {  // If there is no code, this page was propably opened in a browser normally

  // This is a simulation of YOUR page/plugin/service.
  echo "<h1>My fancy web service</h1>";
  echo "<h2>Please let me access your CleverReach® account, user!</h2>";

  // The link will redirect the user to our OAuth service.
  // As the redirect_uri is used as a url parameter, we have to encode it accordingly.
  $redir = urlencode($redirect_uri);
  echo "<a href=\"{$auth_url}?client_id={$clientid}&grant=basic&response_type=code&redirect_uri={$redir}\">OK, connect now!</a>";

} else {  // If there is a code, it must be a callback from OAuth

  // No time to loose! Quickly trade the code for a Token, before it gets invalid.
  // We need to send some data in a POST request for that.

  // Preparing post data:

  // your secret data to make sure, it is you
  $fields["client_id"] = $clientid;
  $fields["client_secret"] = $clientsecret;

  // This must be the same as the previous redirect uri
  $fields["redirect_uri"] = $redirect_uri;

  // This is the actual trade. We tell OAuth what we want and provide the code.
  $fields["grant_type"] = "authorization_code";
  $fields["code"] = $_GET["code"];

  // We use curl to make the request
  $curl = curl_init();
  curl_setopt($curl,CURLOPT_URL, $token_url);
  curl_setopt($curl,CURLOPT_POST, sizeof($fields));
  curl_setopt($curl,CURLOPT_POSTFIELDS, $fields);
  curl_setopt($curl,CURLOPT_RETURNTRANSFER, true);
  $result = curl_exec($curl);
  curl_close ($curl);

  echo "<h1>My fancy web service</h1>";
  echo "<h2>This is the result of the OAuth process:</h2>";

  // The final $result contains the access_token and some other information besides.
  // For you to see it, we dump it out here.

  // Make sure to store the access_token in order to control the users REST API!