NAV
shell C#

Introduction

You’ll use the Unwaffle API to send us information about what your users are doing so that we can run our Machine Learning magic on it.

The API itself is quite simple, consisting of only a few endpoints to send us information about your Participants and the things they do.

We have Client Libraries available for download in C#, Java, Ruby, Javascript, and a few other languages, which should be enough to get you up and running straight away.

Basic Concepts

Projects

You’ll probably only have one Project that you care about, and that will be “Live Data For My Business”.

Have two businesses? OK, sure, you can use a separate project for that. Have two Battlin’ Business Units within your Division of your MegaCorp? Go ahead and split off projects for them too. The important distinction is that a Project is a self-contained pile of data, users, predictions, and everything else that Unwaffle does. Nothing leaks out of a Project, and there’s no way to get a cross-project report. So again, you probably just want one.

There’s no CreateProject API endpoint, because it’s not something you’ll do often. In fact, you got one for free when you signed up, so go ahead and just rename that one on the website and you’ll be good to go.

If you do need to add extra projects, you can do that on the website as well.

Credentials

Credentials are sets of per-project access keys that you’ll use to send API requests.

You can add as many Credential sets as you like from your Account Dashboard, and you can invalidate old ones that you no longer need.

Participants

{
    "ParticipantIdentifier": "1234",
    "ParticipantUsername": "sclark",
    "ParticipantFullName": "Stewart Clark",
    "ParticipantEmail": "[email protected]",
    "ParticipantPhotoUrl": "https://placekitten.com/200/200",
    "ParticipantStatus": "Trial",
    "ParticipantSignupDate": "2016-03-01T00:00:00"
}

Participants are your users, your customers. They’re the people using your site, but since we’re doing Big Data and Machine Learning and such, they get a fancy, mathematician-approved name.

Chances are you have a lot of information about your Participants, and you can give us as much or as little of it as you like. At a minimum, we’ll need a unique ParticipantIdentifier for each one. Generally, the ParticipantIdentifier will be your internal integer or guid UserID from your database. You can use usernames or email addresses if you prefer, but we provide separate fields for those things, so it makes more sense to use the one thing you’re already storing that’s guaranteed to be unique.

You can give us as much information as you like about a given Participant via the API, but again the only thing we need to see is the ParticipantIdentifier. You can fill in missing information about a Participant during subsequent API calls (by simply adding more fields), or by viewing and editing them directly via the Participant List screen. You can also Bulk Import Participants to quickly pull in records from your database.

Participant Status Codes

Code Description
Trial (default) This Participant is currently on a Trial.
Subscribed This Participant is currently subscribed to your product.
Cancelled This Participant has cancelled and not yet re-subscribed.
Expired This Participant has allowed his Trial to lapse.

We recommend not imporing existing (Subscribed, Cancelled or Expired) Participants into your Project unless you have detailed Action history for them, as missing or partial data can confuse the prediction engine.

Labels

{
    "ShortCode": "ViewSummaryReport",
    "LabelName": "Viewed Summary Report",
    "LabelDescription": "User viewed his weekly summary report.",
    "LabelType": "Info"
}

Labels are used to describe the things your Participants do. When paired with a Participant and (optionally) a date, it is used to note an Action that we can use to do our thing. They should include a unique ShortCode that we can use to look them up at our end, but may also include a human-readable LabelName and LabelDescription as well as LabelType information for classification in your reports.

You can (and should) create as many Labels as you like, since you never know which seemingly innocuous things your users do can turn out to be significant.
There are a few specific labels that you absolutely need to report, as our prediction engine relies on them for classification. These include TrialStart, Purchase and Cancel. TrialEnd is handy as well, but we can infer them from the Trial Duration setting of your Project. In addition to these, we have a short list of Stock Labels that we recommend you implement for reporting.

Stock Labels

ShortCode Description
TrialStart (Important) The Participant has started a new Trial. This should be among the first Labels we see for a Participant, and will mark him as Trial.
Purchase (Important) The Participant has upgraded to a paid subscription. We will mark this user as Subscribed when we see this.
Cancel (Important) The Participant has cancelled his paid subscription or trial. We will mark this user as Cancelled when we see this.
TrialExpired The Participant has allowed his trial to lapse. We will mark this user as Expired when we see this.
Renew The Participant has renewed his subscription. We will ensure that this user is marked as Subscribed when we see this, though you should also send a Purchase Action if he is renewing an expired or cancelled subscription.
CardExpired The Participant has had his account cancelled due to an expired card. We will mark this user as Cancelled when we see this.
CardUpdated The Participant has updated his credit card information. We will ensure that this user is marked as Subscribed when we see this, though you should also send a Purchase Action if he was previously cancelled for non-payment.
Login The Participant has logged in to his account on your website.
Logout The Participant has logged out of his account on your website.
ResetPassword The Participant has reset his password.

Actions

An Action is a combination of all the things described above, along with a date, that tells us that something has happened that you’d like us to note down.

At the very least, we’ll need to receive a ParticipantIdentifier and a ShortCode describing who did what. We’ll assume it happened “now” if you don’t tell us any more than that.

Calling the API

Unwaffle expects to receive a HTTPS POST with Basic Authentication Headers containing a valid set of Credentials, and an action description as the POST content.

The Action Description can be either a Transport Object or a list of Comma/Tab Separated Variables.

Authentication

Unwaffle expects API requests to come in the form of a HTTPS POST with Basic Authentication Headers set, with the Username field containing the PublicKey from a valid Credential set, and the Password field containg the SecretKey.

It is possible to configure a Project such that it can accept API requests using only the PublicKey (which is useful if you have a need to run the API in a browser). If that is the case, the Password/SecretKey field may be omitted from Basic Authentication.

We’ll infer who you are and which Project you’re talking about from the Credentials you send.

Transport Objects

The minimum Transport Object for specifying an action:
{
  "Label": {
    "ShortCode": "Login"
  },
  "Participant": {
    "ParticipantIdentifier": "1234"
  }
}
A full Transport Object:
{
  "Label": {
    "ShortCode": "Login",
    "LabelName": "Login",
    "LabelDescription": "User logged in.",
    "LabelType": "Info"
  },
  "Participant": {
    "ParticipantIdentifier": "1234",
    "ParticipantUsername": "sclark",
    "ParticipantFullName": "Stewart Clark",
    "ParticipantEmail": "[email protected]",
    "ParticipantPhotoUrl": "https://placekitten.com/200/200",
    "ParticipantStatus": "Trial",
    "ParticipantSignupDate": "2016-03-01T00:00:00"
  },
  "Action": {
    "ActionDate": "2016-04-15T10:28:16",
    "ActionNote": "from homepage"
  }
}

The most common way to send information to the API will be via Transport Objects. These are simple JSON serialized objects containing a Label, Participant and Action.

At the right, you’ll see a couple examples of Transport Objects for specifying an action.

Notice that in practice, you can omit everything apart from the ShortCode and ParticipantIdentifier fields, and can skip the Action section entirely. If no ActionDate is given, we’ll use the current date & time. If we see a new Participant or Label, we’ll add records for them with default values for any missing fields.

You can fill in information on existing Participants and Labels if you like, and we’ll update their records. In practice, though, it’s more likely that you’ll import Participant data in CSV or TSV format.

CSV & TSV

A quick shorthand way of adding lots of records quickly without having to fiddle with curly braces is to format them into Comma or Tab Separated Variables and simply post them to the API. You could probably build your API Client to use only this format, but then you would risk being ridiculed by 19 year old junior devs for your oldskool behavior, so use caution.

Here are lists of parameters for the various API endpoints. Order is important, and optional fields are shown with [brackets]. One record per line, with no column headers, please.

Participant

ParticipantIdentifier, [ParticipantUsername], [ParticipantFullName], [ParticipantEmail], [ParticipantSignupDate], [ParticipantPhotoUrl], [ParticipantStatus]

Label

ShortCode, [LabelName], [LabelType], [LabelDescription]

Action

ParticipantIdentifier, ShortCode, [Date], [Description]

Client Endpoints

AddAction

curl "https://api.unwaffle.com/v1/addaction" \
    -u pub_YOUR_PUBLIC_KEY:pvt_YOUR_SECRET_KEY \
    -H "Content-Type: application/json" \
    -d {                                \
        "Label": {                      \
        "ShortCode": "Login"            \
        },                              \
        "Participant": {                \
        "ParticipantIdentifier": "1234" \
        }                               \
    }


curl "https://api.unwaffle.com/v1/addaction" \
    -u pub_YOUR_PUBLIC_KEY:pvt_YOUR_SECRET_KEY \
    -H "Content-Type: text/csv" \
    -d Login, 1234


// TODO: Move this out to a function somewhere public!
var client = new UnwaffleClient("pub_YOUR_PUBLIC_KEY", "pvt_YOUR_SECRET_KEY");
var config = new ActionConfig
{
    Label = new Label { ShortCode = "MovedSpinner" },
    Participant = new Participant { ParticipantIdentifier = _userID.ToString() }
};

client.AddAction(config);

This endpoint sends us an action to be analyzed. It’s probably the only API Endpoint you’ll ever use directly.

HTTP Request

POST https://api.unwaffle.com/v1/AddAction

Unwaffle expects to receive a HTTP POST with Basic Authentication Headers containing a valid set of Credentials as described above, and an action description as the POST content.

AddParticipant

curl "https://api.unwaffle.com/v1/addparticipant" \
    -u pub_YOUR_PUBLIC_KEY:pvt_YOUR_SECRET_KEY \
    -H "Content-Type: application/json" \
    -d  {                                                           \
        "ParticipantIdentifier": "1234",                            \
        "ParticipantUsername": "sclark",                            \
        "ParticipantFullName": "Stewart Clark",                     \
        "ParticipantEmail": "[email protected]",                   \
        "ParticipantPhotoUrl": "https://placekitten.com/200/200",   \
        "ParticipantStatus": "Trial",                               \
        "ParticipantSignupDate": "2016-03-01T00:00:00"              \
        }


curl "https://api.unwaffle.com/v1/addparticipant" \
    -u pub_YOUR_PUBLIC_KEY:pvt_YOUR_SECRET_KEY \
    -H "Content-Type: text/csv" \
    -d 1234,sclark,Stewart Clark,[email protected]


var client = new UnwaffleClient("pub_YOUR_PUBLIC_KEY", "pvt_YOUR_SECRET_KEY");
var participant = new Participant {
{
    ParticipantIdentifier = _user.UserID.ToString(),
    ParticipantUsername = _user.Username,
    ParticipantEmail = _user.Email,
    ParticipantFullName = _user.DisplayName,
};

client.AddParticipant(participant);

This endpoint sends information about a Participant. You’ll likely only use it to flesh out information about Participants that you’ve reported to us previously just by their ParticipantIdentifier. Any fields we receive in this call will be used to overwrite information in an existing record. And, of course, a new record will be created if you send a ParticipantIdentifier that we haven’t yet seen for this Project.

HTTP Request

POST https://api.unwaffle.com/v1/AddParticipant

Unwaffle expects to receive a HTTP POST with Basic Authentication Headers containing a valid set of Credentials as described above, and an action description as the POST content.

AddLabel

curl "https://api.unwaffle.com/v1/addlabel" \
    -u pub_YOUR_PUBLIC_KEY:pvt_YOUR_SECRET_KEY \
    -H "Content-Type: application/json" \
    -d {                                \
        "ShortCode": "KilledBear",      \
        "LabelName": "Killed a bear",   \
        "LabelDescription": "User totally killed a bear. It was awesome.", \
        "LabelType": "Info"             \
    }


curl "https://api.unwaffle.com/v1/addlabel" \
    -u pub_YOUR_PUBLIC_KEY:pvt_YOUR_SECRET_KEY \
    -H "Content-Type: text/csv" \
    -d KilledBear, Killed a bear, Seriously I was right there.


var client = new UnwaffleClient("pub_YOUR_PUBLIC_KEY", "pvt_YOUR_SECRET_KEY");
var label = new Label { 
        ShortCode = "KilledBear",
        LabelName = "Killed a bear",
        LabelDescription = "I couldn't watch.",
        LabelType = "Info"
    };

client.AddLabel(config);

This endpoint sends information about a Label. You’ll likely only use it to flesh out information about Labels that you’ve reported to us previously just by their ShortCode. Any fields we receive in this call will be used to overwrite information in an existing record. And, of course, a new record will be created if you send a ShortCode that we haven’t yet seen for this Project.

HTTP Request

POST https://api.unwaffle.com/v1/AddLabel

Unwaffle expects to receive a HTTP POST with Basic Authentication Headers containing a valid set of Credentials as described above, and an action description as the POST content.

Errors

The Unwaffle API returns a status of -1 for any failed call, along with a short description of what went wrong. As in:

-1 invalid credentials

Client Libraries

We have API Client Libraries available for several programming languages and frameworks:

Swagger Specification

We have created a Swagger specification for the Unwaffle API that you can use to generate API Clients for a few dozen technologies (most of the libraries above were generated this way).

If you don’t see your language listed above, you can generate one yourself using the Unwaffle API in the Swagger Editor. Look for “Generate Client” in the top nav.

Here are the raw .json and .yaml files for that Swagger API spec, in case you need them: