Developer Documention

API Overview

The Preact Events API is a single endpoint used to log events. Events will, at a minimum, send a person object and an event object. Read more in the Parameters section.

Base API URL: https://api.preact.io/api/v2/events

Authentication

Authentication is done over HTTPS using Basic Auth with your API credentials. Your Project Code will be your username and your API Secret will be the password. Your API keys are located on the API Settings page of your Preact dashboard.

All API calls must be made over HTTPS, otherwise they will fail.

Versioning

The current stable API version is v2.

As we work on new features, we try very hard to make things backwards compatible so that we minimize change for you. In the event we make breaking changes, we will bump the version number when it's released.

Parameters

Parameter Name Value Description
Required parameters
person object The person object contains the personal information of the user. For example, the user's name, email and the unix timestamp of the account creation date. For more information, see the Person Object section.
event object The event object contains information about the event being logged. For example, the event name, note, associated revenue, timestamp, etc. For more information, see the Event Object section.

These are both required in order to accept the event. You can send your POST request via Form or JSON format to our /api/v2/events endpoint.

If you're submitting via JSON make sure to include proper header information. For instance, with curl:

curl -H 'Content-Type: application/json' -H 'Accept: application/json'

The minimum required params to track an event are as follows:

{
    "person": {
        "email": "cgooley@preact.com",
        "name": "Christopher Gooley",
        "created_at": 1367259292.74
    },
    "event": {
        "name": "viewed:item",
        "target_id": "sku_1234"
    }
}

Curl Example

curl --user 'project_code:api_secret' \
  -H 'Content-Type: application/json' \
  -X POST -d '{"person":{"email":"cgooley@preact.com","name":"Christopher Gooley"},
  "event":{"name":"viewed:item", "target_id":"sku_1234"}}' \
  https://api.preact.io/api/v2/event
curl -s -k https://api.preact.io/api/v2/events \
  --user 'project_code:api_secret' \
  -F person[email]='cgooley@preact.com'\
  -F person[name]='Christopher Gooley' \
  -F person[created_at]=1367259292.74 \
  -F event[name]='viewed:item'\
  -F event[target_id]='sku_1234'

Person Object

Field Name Value Description
Required fields
email string The email field is the email address off the user (will be the unique id).
Strongly suggested fields
name string The name field is the name of the user.
created_at float The created_at field is a unix timestamp (in secs or ms) of user registration.
uid string The uid field is the internal user id for this user in your application.
Optional fields
twitter_id string The twitter_id field is this user's twitter id.
facebook_id string The facebook_id field is this user's facebook id.
stripe_id string The stripe_id field is this user's stripe id.
properties object The properties field is an object with custom information about the user. For more information, see the Additional Parameters section.
  {
      "person": {
          "email": "cgooley@preact.com",
          "name": "Christopher Gooley",
          "created_at": 1367259292.74,
          "uid": "cgooley"
      }
  }
person[email] = "cgooley@preact.com"
person[name] = "Christopher Gooley"
person[created_at] = 1367259292.74
person[uid] = "cgooley"

Event Object

Field Name Value Description
Required fields
name string The name field is the indentifying name of the event. See the Logging Basics for more information about event names.
Required fields for Preact B2B customers
account object The object field is an object containing the id and name of the account associated with the action. For more information, see the Accounts section.
Optional fields
timestamp float The timestamp field is a unix timestamp (in secs or ms).
revenue int The revenue field is the event's associated revenue in cents (995 = $9.95 USD).
note string The note field is a human-readable description.
target_id string The target_id field is your app's internal id for the target of this action.
extras object The extras field is an object that contains extra information about the event. For more information see the Additional Parameters section.
  {
      "event": {
          "name": "purchased:item",
          "timestamp": 1367259292.74,
          "revenue": 995,
          "note": "Turnstone Desk"
      }
  }
event[name] = "purchased:item"
event[timestamp] = 1367259292.74
event[revenue] = 995
event[note] = "Turnstone Desk"

Logging Basics

Events should be named with simple verb/object pairs and must not include any whitespace.

We find that there are a small number of distinct events that practically every app will need to use. You should set these up first, and then you can get fancy and add more custom events. Some of these will also have special meaning in our analysis:

Account Events
  • registered
  • upgraded
  • downgraded
  • deleted-account
  • purchased:item
User Events
  • logged-in
  • logged-out
  • forgot-password
  • changed-password
  • updated-profile
App Events
  • created:document
  • uploaded:media
  • deleted:workspace
  • modified:dashboard
  • viewed:dashboard

Tenses
Event names should generally be past tense: uploaded, deleted, created, registered, logged-in, viewed. Event item names (if provided) should be singular: image, profile, media, person. We'll convert singular items to plural when necessary for readability.

Accounts

If you are a Preact B2B customer, you must also log the account id and name for each event.

This will activate Account Health monitoring and provide additional analysis at the account level. Because many systems will allow a single user account to interact with multiple "accounts", you will pass account info at the Event level, rather than the Person level. This allows us to track account health while separating distinct behaviors between these multi-account users.

You can add account info by simply adding "account": {"id":"828492", "name": "Bitium"} to the existing event object. For instance, if you are using a direct HTTP POST via curl or your language's built-in library, you would do something like this:

curl --user 'project_code:api_secret' \
  -H 'Content-Type: application/json' \
  -X POST -d '{"person":{"email":"cgooley@preact.com","name":"Christopher Gooley",
  "created_at":1367259292.74},"event":{"name":"purchased:item","note":"Preact shirt",
  "revenue":1999,"account": {"id":"828492", "name": "Bitium"}}}' \
  https://api.preact.io/api/v2/events

By adding those two final field parameters (account id and account name) above), Preact will associate this event with that account (creating a new account if necessary) and will properly aggregate analysis.

Note: If your users sometimes perform actions outside the context of an account (such as the initial login or a password reset) you can simply omit the account parameters and we will only attach those actions to the person directly.

Additional Parameters

Preact has a number of additional parameters that should be passed when appropriate for the event.

Some of them are treated as special properties and Preact will do interesting things with them. For instance, on any event that represents revenue (a checkout, succesful billing, etc) you must pass the revenue parameter so that Preact can build up the revenue-to-date value for each person.

Person
{
    "person": {
        "email": "cgooley@preact.com",
        "name": "Christopher Gooley",
        "created_at": 1367259292.74,
        "uid": "cgooley",
        "twitter_id": "gooley",
        "facebook_id": "12805383",
        "stripe_id": "cus_1123f3f5",
        # nested special "properties" of the person
        "properties": {
            "subscription_level_name": "Platinum",
            "subscription_level": 5,
            "is_paying": true
        }
    }
}

Custom Person Properties can include arbitrary additional "properties" for any person. These are additive and will build out the profile of the person over time.

...

"properties": {
    "subscription_level_name": "Platinum",
    "subscription_level": 5,
    "is_paying": true,
    "favorite_color": "red",
    "birthday": "1984-02-03"
}
...
Event
{
    "event": {
        "name": "purchased:item",
        "timestamp": 1367259292.74,
        "revenue": 99500,
        "note": "Turnstone Desk",
        "target_id": "sku_2345",
        "link_url": "http://blah/2345",
        "thumb_url": "http://blah/2345.jpg",
        "account": {
            "id": "828492",
            "name": "Bitium"
        },
        # certain event extras have meaning and are populated by the offical JS library
        # you may pass these if you are using server-side logging and have them handy
        "extras": {
            "_ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWeb...",
            "_page_title": "Turnstone :: Tables",
            "_ip": "216.24.174.102",
            "_referer": "http://google.com?q=awesome+desks",
            "_url": "http://myturnstone.com/products/tables"
        }
    }
}

Custom Event Extras can include arbitrary additional "extras" for any event. These will be available within the sidebar view for review. Good ideas for extras would be additional information useful to support or account managers (such as error messages, or other extra information).

...

"extras": {
    "_ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWeb...",
    "_page_title": "Turnstone :: Tables",
    "_ip": "216.24.174.102",
    "_referer": "http://google.com?q=awesome+desks",
    "_url": "http://myturnstone.com/products/tables",
    "category": "desks",
    "color": "titanium"
}
...

Note: If you're using the Javascript API library, the extras field preceded by an '_' are automatically generated for you. However, if you're using any of the server side API libraries, you'll have to provide this data. Specifically, if you're looking to have geolocation information on your users, please populate the '_ip' field.

Code Samples

The below code samples give a few examples of logging events. For a more in-depth explanation, see the documentation for the API Libraries.

You can hit our API end-point with basic http calls. If we don't have an official library for your language, please let us know. If you build one we'll link to your Github repo.

A User Registered

JSON format
curl --user 'project_code:api_secret' \
  -H 'Content-Type: application/json' \
  -X POST -d '{"person":{"email":"cgooley@preact.com","name":"Christopher Gooley",
  "uid":"cgooley","created_at":1367259292},"event":{"name":"registered"}}' \
  https://api.preact.io/api/v2/events
Form format
curl -s -k https://api.preact.io/api/v2/events \
  --user 'project_code:api_secret' \
  -F person[name]='Christopher Gooley' \
  -F person[email]='gooley@preact.com'\
  -F person[uid]='cgooley'\
  -F person[created_at]=1367259292\
  -F event[name]='registered'

A User Upgraded Their Account

JSON format
curl --user 'project_code:api_secret' \
  -H 'Content-Type: application/json' \
  -X POST -d '{"person":{"email":"cgooley@preact.com","name":"Christopher Gooley",
  "uid":"cgooley","created_at":1367259292,"properties":{"is_paying":true,
  "subscription_level":2,"subscription_level_name":"Pro"}},"event":{"name":"upgraded"}}' \
  https://api.preact.io/api/v2/events
Form format
curl -s -k https://api/react.io/api/v2/events \
  --user 'project_code:api_secret' \
  -F person[name]='Christopher Gooley' \
  -F person[email]='gooley@preact.com'\
  -F person[uid]='cgooley'\
  -F person[created_at]=1367259292\
  -F person[properties][is_paying]='1'\
  -F person[properties][subscription_level]='2'\
  -F person[properties][subscription_level_name]='Pro'\
  -F event[name]='upgraded'

A User Purchased An Item

JSON format
curl --user 'project_code:api_secret' \
  -H 'Content-Type: application/json' \
  -X POST -d '{"person":{"email":"cgooley@preact.com","name":"Christopher Gooley",
  "uid":"cgooley","created_at":1367259292},"event":{"name":"purchased:item",
  "note":"Georgia Tech Hoodie","revenue":3995,"extras":{"color":"blue",
  "size":"L"}}}' \
  https://api.preact.io/api/v2/events
Form format
curl -s -k https://api.preact.io/api/v2/events \
  --user 'project_code:api_secret' \
  -F person[name]='Christopher Gooley' \
  -F person[email]='gooley@preact.com'\
  -F person[uid]='cgooley'\
  -F person[created_at]=1367259292\
  -F event[name]='purchased:item' \
  -F event[note]='Georgia Tech Hoodie' \
  -F event[revenue]=3995 \
  -F event[extras][color]='blue' \
  -F event[extras][size]='L'

All of these samples assume you've configured the API library with your Project Code and API Secret. They also assume you are using the Preact gem. As such, the first parameter is the Person hash and the second parameter is the Event hash in the log_event function.

For more information about integrating with Preact using Ruby, see the Ruby API Library documentation.

A User Registered


Preact.log_event(
  { :email       => "gooley@preact.com",
    :name        => "Christopher Gooley",
    :created_at  => 1367259292,
    :uid         => "gooley"
  }, {
    :name        => "registered"
  })

A User Upgraded Their Account


Preact.log_event(
  { :email       => "gooley@preact.com",
    :name        => "Christopher Gooley",
    :created_at  => 1367259292,
    :uid         => "gooley",
    :properties  => {
      :is_paying                => true,
      :subscription_level       => 2,
      :subscription_level_name  => "Pro"
    }
  }, {
    :name        => "upgraded",
  })

A User Purchased An Item


Preact.log_event(
  { :email       => "gooley@preact.com",
    :name        => "Christopher Gooley",
    :created_at  => 1367259292,
    :uid         => "gooley"
  }, {
    :name        => "purchased:item",
    :note        => "Georgia Tech Hoodie",
    :revenue     => 3995,
    :extras      => {
      :color     => "blue",
      :size      => "L"
    }
  })

All of these samples assume you've configured the API library with your Project Code and API Secret. Using the Javascript API Library, you only have to set the person data once, but we'll set it in each example below for completeness.

For more information about integrating with Preact using Javascript, see the Javascript API Library documentation.

A User Registered


_lnq.push(["_setPersonData", {
  email: "gooley@preact.com",
  name: "Christopher Gooley",
  created_at: 1367259292,
  uid: "gooley"
}]);

_lnq.push(["_logEvent", "registered"]);

A User Upgraded Their Account


_lnq.push(["_setPersonData", {
  email: "gooley@preact.com",
  name: "Christopher Gooley",
  created_at: 1367259292,
  uid: "gooley",
  properties: {
    is_paying: true,
    subscription_level: 2,
    subscription_level_name: "Pro"
  }
}]);

_lnq.push(["_logEvent", "upgraded"]);

A User Purchased An Item


_lnq.push(["_setPersonData", {
  email: "gooley@preact.com",
  name: "Christopher Gooley",
  created_at: 1367259292,
  uid: "gooley"
}]);

var event = {
  name: "purchased:item",
  note: "Georgia Tech Hoodie",
  revenue: 3995,
  extras: {
    color: "blue",
    size: "L"
  }
};

_lnq.push(["_logEvent", event]);

All of these samples assume you've configured the API library with your Project Code and API Secret.

For more information about integrating with Preact using PHP, see the PHP API Library documentation.

A User Registered


$eventdata = Array(
  'person[name]'       => 'Christopher Gooley',
  'person[email]'      => 'gooley@preact.com',
  'person[created_at]' => '1367259292',
  'person[uid]'        => 'gooley',

  'event[name]'        => 'registered'
);

LessNeglect::log_event($eventdata);

A User Upgraded Their Account


$eventdata = Array(
  'person[name]'                                => 'Christopher Gooley',
  'person[email]'                               => 'gooley@preact.com',
  'person[created_at]'                          => '1367259292',
  'person[uid]'                                 => 'gooley',
  'person[properties][is_paying]'               => true,
  'person[properties][subscription_level]'      => 2,
  'person[properties][subscription_level_name]' => 'Pro',

  'event[name]'                                 => 'upgraded'
);

LessNeglect::log_event($eventdata);

A User Purchased An Item


$eventdata = Array(
  'person[name]'         => 'Christopher Gooley',
  'person[email]'        => 'gooley@preact.com',
  'person[created_at]'   => '1367259292',
  'person[uid]'          => 'gooley',

  'event[name]'          => 'purchased:item',
  'event[note]'          => 'Georgia Tech Hoodie',
  'event[revenue]'       => 3995,
  'event[extras][color]' => 'blue',
  'event[extras][size]'  => 'L'
);

LessNeglect::log_event($eventdata);

All of these samples assume you've configured the API library with your Project Code and API Secret.

For more information about integrating with Preact using Objective-C, see the Objective-C API Library documentation.

A User Registered


Person *person = [[Person alloc] init];
person.name = @"Christopher Gooley";
person.email = @"gooley@preact.com";
person.created_at = @"1367259292";
person.uid = @"gooley";

Event *event = [[Event alloc] init];
event.name = @"registered";
event.person = person;

[con createActionEvent:event success:^(NSDictionary *response) {
  NSLog(@"Success!");
} error:^(NSError *error) {
  NSLog(@"Error.");
}];

A User Upgraded Their Account


Person *person = [[Person alloc] init];
person.name = @"Christopher Gooley";
person.email = @"gooley@preact.com";
person.created_at = @"1367259292";
person.uid = @"cgooley";
person.is_paying = YES;
person.account_level = @"2";
person.account_level_name = @"Pro";

Event *event = [[Event alloc] init];
event.name = @"upgraded";
event.person = person;

[con createActionEvent:event success:^(NSDictionary *response) {
  NSLog(@"Success!");
} error:^(NSError *error) {
  NSLog(@"Error.");
}];

A User Purchased An Item


Person *person = [[Person alloc] init];
person.name = @"Christopher Gooley";
person.email = @"gooley@preact.com";
person.created_at = @"1367259292";
person.uid = @"gooley";

Event *event = [[Event alloc] init];
event.name = @"purchased:item";
event.note = @"Georgia Tech Hoodie";
event.person = person;

[con createActionEvent:event success:^(NSDictionary *response) {
  NSLog(@"Success!");
} error:^(NSError *error) {
  NSLog(@"Error.");
}];

All of these samples assume you've configured the API library with your Project Code and API Secret.

For more information about integrating with Preact using C#, see the C# API Library documentation.

A User Registered


DateTime epoch = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);

LessNeglect.LessNeglectApi.Client.CreateActionEvent(
  new LessNeglect.ActionEventCreateRequest() {
    Event = new LessNeglect.ActionEvent() {
      Name = "registered"
    },
    Person = new LessNeglect.Person() {
      Name = "Christopher Gooley",
      Email = "gooley@preact.com",
      CreatedAt = epoch.AddSeconds(1367259292),
      Uid = "gooley"
    }
  }
);

A User Upgraded Their Account


DateTime epoch = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);

LessNeglect.LessNeglectApi.Client.CreateActionEvent(
  new LessNeglect.ActionEventCreateRequest() {
    Event = new LessNeglect.ActionEvent() {
      Name = "upgraded"
    },
    Person = new LessNeglect.Person() {
      Name = "Christopher Gooley",
      Email = "gooley@preact.com",
      CreatedAt = epoch.AddSeconds(1367259292),
      Uid = "gooley",
      Properties = new Dictionary<string, object>() {
        {"is_paying", true},
        {"account_level", 2},
        {"account_level_name", "Pro"}
      }
    }
  }
);

A User Purchased An Item


DateTime epoch = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);

LessNeglect.LessNeglectApi.Client.CreateActionEvent(
  new LessNeglect.ActionEventCreateRequest() {
    Event = new LessNeglect.ActionEvent() {
      Name = "purchased:item",
      Note = "Georgia Tech Hoodie",
      Revenue = 3995,
      Extras = new Dictionary<string, object>() {
        {"color", "blue"},
        {"size", "L"}
      }
    },
    Person = new LessNeglect.Person() {
      Name = "Christopher Gooley",
      Email = "gooley@preact.com",
      CreatedAt = epoch.AddSeconds(1367259292),
      Uid = "gooley"
    }
  }
);

All of these samples assume you've configured the API library with your Project Code and API Secret.

For more information about integrating with Preact using Python, see the Python API Library documentation.

A User Registered


person = {
  "person[name]": "Christopher Gooley",
  "person[email]": "gooley@preact.com",
  "person[created_at]": "1367259292",
  "person[uid]": "cgooley"
}

event = {
  "event[name]": "registered"
}

log_event(dict(person.items() + event.items()))

A User Upgraded Their Account


person = {
  "person[name]": "Christopher Gooley",
  "person[email]": "gooley@preact.com",
  "person[created_at]": "1367259292",
  "person[uid]": "cgooley",
  "person[properties][is_paying]": true,
  "person[properties][subscription_level]": 2,
  "person[properties][subscription_level_name]": "Pro"
}

event = {
  "event[name]": "upgraded"
}

log_event(dict(person.items() + event.items()))

A User Purchased An Item


person = {
  "person[name]": "Christopher Gooley",
  "person[email]": "gooley@preact.com",
  "person[created_at]": "1367259292",
  "person[uid]": "cgooley"
}

event = {
  "event[name]": "purchased:item",
  "event[note]": "Georgia Tech Hoodie",
  "event[revenue]": 3995,
  "event[extras][color]": "blue",
  "event[extras][size]": "L"
}

log_event(dict(person.items() + event.items()))

Tracking Pixel

The tracking pixel is a way to track if a user opened an email that was sent to them. Use the example below as a template to create a tracking pixel of your own.

Field Name Description
Optional fields
c The c field is the Project Code, found here.
pem The pem field is the email of the recipient.
e The e field is name of the event.
Optional fields
acctid The acctid field is account id of the recipient.
n The n field is a note about the event.

Example

<img src="https://api.preact.io/track/ln.gif?c=PROJECTCODE&pem=some@email.com&e=opened:invite-email&acctid=34532&n=invite-campaign-234" />

API Libraries

Official Client Logging Libraries:

We have several helper libraries that the user community has helped us build. We try to keep these as up to date as possible with the stable API version. If you find that a library does not provide everything you need, please feel free to fork the repo and add changes as needed. We are happy to accept pull requests on the changes if it helps push the library forward towards being API feature complete.