API Specification

The fine prints about the Wiraya API

Updated over a week ago

The API aims to allow our clients to build technical integrations where their systems communicate directly with the Wiraya platform in order to use Wiraya Activation Intelligence.

If you're missing some feature or have any questions, please let us know!

Syntax and interoperability

The API is structured as a RESTful endpoint, meaning that the URL encodes the resource and the HTTP method defines the action.

As an API primarily intended for data ingress, there’s no implementation for DELETE operations.

The Content-Type of the requests to the API is defined to be application/json with the UTF-8 character set. The JSON standard (RFC4627) defines how certain primitive types such as strings, integers, floats, objects, and arrays are to be encoded, but complex types such as datetime has no literal syntax provided. To that end, this specification defines that in communicating with the WAI API, dates are to be encoded according to the ISO 8601 standard: “2016-04-11T09:11:43Z” or “2016-04-11T09:11:43.573921Z”. Note that the trailing “Z” is the ISO8601 designation for UTC.

Rate Limiting

In order to ensure stable system performance and fair access for all API clients to shared resources, Wiraya may impose usage restrictions in the form of rate limits.

Such rate limits may vary between endpoints and will be applied at our discretion. As much as possible, any rate limit will be set as to not cause undue restrictions for any reasonable, supported use case. 

If your application hits a rate limit, you will see a response with http code 429. Hold back and retry at a later time.
The 429 response does include the Retry-After header which specifies the number of seconds remaining until new requests are accepted. See the example below:

HTTP/1.1 429 Too Many Requests
Date: Wed, 26 Apr 2017 08:28:52 GMT
Retry-After: 17

Encryption

The API utilises HTTPS to securely transport data across the internet. TLS 1.2 or later is required. Only HTTPS is allowed, it is not possible to access the API using unsecured HTTP calls.

Authentication

Each call to the WAI API needs to be secured with a token. It is acquired by calling the single endpoint that does not require such a token, and passing your API Key to it. Returned is a response that holds the token and its expiration date. Any future calls to the API needs to have this token passed in a header, exemplified later.

HTTP Request

POST https://api.wiraya.ai/auth/Token/apikey HTTP/1.1
Content-Type: application/json; charset=utf-8

JSON

{
  "key":"YOUR API KEY"
}

HTTP Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

{
  "authenticated": true,
  "token": "TOKEN",
  "tokenExpires": "2017-04-26T08:25:42.0418136Z"
}

Extract TOKEN from the response payload above and place it in an "Authorization: Bearer " header for future calls. Observe the token expiration time! For long running processes, implement a provision for renewal of the token before it has expired.

Contacts

This entity represents an individual, an end user to communicate with at some point. Each contact stores the information that is relevant on an individual level such as phone number, gender, age, location as well as interests and any other metadata applicable. Providing this information helps WAI to draw behavioral conclusions based on this data.

Send a contact

In the URL, "12345" represents your contact id. You will refer back to it when additional data such as events and metrics are posted to that contact. Let it be an identifier of the customer that is not resolvable to an individual by a 3rd party.
In the "personal" section, put user information (PII) that needs to be cleared at end of project (e.g. data privacy laws).
In the "general" section, put user information that is generic enough to not identify a specific individual. The fields below are provided as examples. The document is adaptable to your specific data by adding fields within the personal and general section.

HTTP Request

PUT https://api.wiraya.ai/api/Contact/[contactID] HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "personal":
  {
    "phoneNumber":"46704134561",
    "givenName": "John",
    "surName": "Doe",
    "title": "Mr",
    "gender": "Male",
    "birthDate": "1980-01-01"
  },
  "general":
  {
    "city": "Testershire",
    "county": "Dorset",
    "country": "UK",
    "timeOfRegistration": "2018-03-30T16:43:11Z",
    "postCode": "DT11 0PS",
    "accountStatus": "active",
    "forgotPasswdTimes": 7,
    "latestClientDetailUpdate": "2018-04-11T11:21:43Z",
    "nrLogins": 6,
    "latestLogin": "2018-05-07T19:22:11Z"
  }
}

HTTP Response

HTTP/1.1 200 OK
Date: Wed, 26 Apr 2017 08:28:52 GMT

JSON

{
  "id": ["49593967912456823050646721704338680985139835900719529986"],
  "error": false,
  "failures": {}
}

Update a contact

When a user triggers an action that updates the information above, simply send in the entire contact again with the same ID.

Connect a user to a campaign

To make contact 12345 member of a specified campaign - for instance a (re-)activation campaign. Specify a value for "iteration" that changes by the frequency you allow the user to take part in the campaign. For example, if you allow a user to be added to the campaign once per month, set it to the current month (e.g. "2017-09"). In other words, the request is processed only if the combination of ContactId+Campaign+Iteration is unique.

HTTP Request

POST https://api.wiraya.ai/api/Contact/12345/campaigns HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "campaign": "foo",
  "iteration": "2017-09"
}

HTTP Response

HTTP/1.1 200 OK
Date: Wed, 26 Apr 2017 08:28:52 GMT

JSON

{
  "id": "49593967912456823050646721995340423950396846801279778818"
}

Events

Real-time or scheduled, post events (Login, Payments, Conversion events, Opt-outs, etc...) that have occurred for an individual. Events occur at a distinct point in time, as opposed to metrics that are collected over a time period and reported over the metrics API.

See naming conventions for more details and naming standards.

HTTP Request

POST https://api.wiraya.ai/api/Contact/12345/events HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "at": "2017-01-02T03:04:05Z",
  "name": "conversion"
}

If the "at field is set it will be parsed as UTC. If it's not possible to parse as UTC, the time will be parsed and the timezone will be UTC. If the time is not possible to be parsed, or if the "at" field is not set at all, it will be set to the current time UTC.

Metrics

This endpoint accepts metrics for an individual. Metrics, as opposed to events, are aggregated values over a time period. Metrics have a period and a period starts in addition to the value that is reported for that period.

As an example, monthly metrics would be reported as:

HTTP Request

POST https://api.wiraya.ai/api/Contact/12345/metrics HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "received": "2017-02-10T01:00:00Z",
  "periodStart": "2017-02-01T01:00:00Z",
  "periodEnd": "2017-03-01T01:00:00Z",
  "metrics":
  [
    {
      "name": "electricity",
      "value": 492,
      "unit": "kWh"
    },
    {
      "name": "water",
      "value": 4.32,
      "unit": "kbm"
    }
  ]
}

HTTP Response

HTTP/1.1 200 OK
Date: Wed, 26 Apr 2017 08:28:52 GMT

JSON

{
  "id": "49593967912456823050646722334603694560489470978150105090"
}

Bulk operations

These endpoints allow the transmissions of multiple contacts and/or events in a single call. This increases throughput because more data is transmitted in each round trip to the API.

However, keep the total Content-Length below 1 MB and the item count below or equal to 500.

Contact bulk

Here's an example showing how to put multiple contacts in a single request:

HTTP Request

PUT https://api.wiraya.ai/api/Contact/_bulk HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "12345":
  {
    "personal":
    {
      "givenName": "John",
      "surName": "Doe",
      "phoneNumber": "999123123"
    },
    "general": {}
  },
  "12346":
  {
    "personal":
    {
      "givenName": "Jane",
      "surName": "Doe",
      "phoneNumber": "999456456"
    },
    "general": {}
  }
}

HTTP Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

{
  "id":
  [
    "49584134327499146337076065330038012842683545324179423234",
    "49584134327499146337076065330047684249240462357577072642"
  ]
}

Campaign bulk

Here's an example showing how to join multiple contacts to campaigns using a single request:

HTTP Request

POST https://api.wiraya.ai/api/Contact/campaigns/_bulk HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "12345":
  {
    "campaign": "activation"
  },
  "12346":
  {
    "campaign": "reactivation"
  }
}

HTTP Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

{
  "id":
  [
    "49584134327499146337076065330038012842683545324179423234",
    "4958413432749 9146337076065330047684249240462357577072642"
  ]
}

Events bulk

Here's an example showing how to post events for multiple contacts in a single request:

HTTP Request

POST https://api.wiraya.ai/api/Contact/events/_bulk HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "12345":
  [
    {
      "name": "conversion",
      "at": "2017-01-02T03:04:05Z"
    },
    {
      "name": "optout",
      "at": "2017-01-02T03:05:05Z"
    }
  ],
  "12346":
  [
    {  
      "name": "conversion",
      "at": "2017-01-02T04:04:05Z"
    }
  ]
}

HTTP Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

{
  "id":
  [
    "49592484688466421086197143861218373048866107935558729730",
    "49592484688466421086197143861219581974685722564733435906"
  ],
  "error": false,
  "failures": {}
}

Metrics bulk

Here's an example showing how to post metrics for multiple contacts in a single request:

HTTP Request

POST https://api.wiraya.ai/api/Contact/metrics/_bulk HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

JSON

{
  "12345":
  [
    {
      "metrics":
      [
        {
          "name": "electricity",
          "unit": "kWh",
          "value": 492
        },
        {
          "name": "water",
          "unit": "kbm",
          "value": 4.32
        }
      ],
      "periodStart": "2017-02-01T01:00:00Z",
      "periodEnd": "2017-03-01T01:00:00Z",
      "received": "2017-02-10T01:00:00Z"
    },
  ],
  "12346":
  [
    {
      "metrics":
      [
        {
          "name": "electricity",
          "unit": "kWh",
          "value": 633
        },
        {
          "name": "water",
          "unit": "kbm",
          "value": 8.21
        }
      ],
      "periodStart": "2017-02-01T01:00:00Z",
      "periodEnd": "2017-03-01T01:00:00Z"
      "received": "2017-02-10T01:00:00Z"
    }
  ]
}

HTTP Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

{
  "id":
  [
    "49584134327499146337076065330038012842683545324179423234",
    "49584134327499146337076065330047684249240462357577072642"
  ]
}

Error handling

Normally errors are identified by an error HTTP status code, such as this:

HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

{
  "bulkItemLimitExceeded": true
}

Occasionally, a bulk request is partially successful. A typical partial success response is:

HTTP Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

{
  "id":    
  [
    "49584134327499146337076065330038012842683545324179423234",
    null
  ]
  "error": true,
  "failures":
  {
    "12345":
    {
      "retry": true
    }
  }
}

Campaigns listing

Retrieves a listing of campaigns available for your account

HTTP Request

GET https://api.wiraya.ai/api/Campaign/campaigns HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

HTTP Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 26 Apr 2017 08:20:47 GMT

JSON

[
{
"id": "campaignid",
"description": "Description 1",
"enabled": true
},
{
"id": "campaign2id",
"description": "Description 2",
"enabled": true
}
]

Optionally the query string parameter filterEnabled can be included as per below. When true, the returned list only includes enabled campaigns, the behavior is otherwise unchanged.

HTTP Request

GET https://api.wiraya.ai/api/Campaign/campaigns?filterEnabled=true HTTP/1.1
Authorization: Bearer [YOUR TOKEN]
Content-Type: application/json

What's Next

Please follow our Naming Conventions or go directly to the API Reference.

Did this answer your question?