API and Data Management

Last updated: March 5th, 2019

The Schema

A profile needs a schema for validation and allowing UI (and the rest of the platform) to know which fields are available, their type etc.
Let’s assume we would only like to store the following information on profiles: email, name and interests and transactions made.

Json schema draft 04 representation:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "profiles",
  "description": "Profile Schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "ID"
    },
    "firstname": {
      "type": "string",
      "description": "Firstname"
    },
    "lastname": {
      "type": "string",
      "description": "Lastname"
    },
    "email": {
      "type": "string",
      "description": "Email"
    },
    "interests": {
      "type": "object",
      "properties": {
        "biking": {
          "type": "string",
          "description": "Biking"
        },
        "tennis": {
          "type": "string",
          "description": "Tennis"
        }
      }
    },
    "transactions": {
      "type": "array",
      "description": "transactions",
      "items": {
        "type": "object",
        "title": "Transactions",
        "properties": {
          "id": {
            "type": "string",
            "description": "id"
          },
          "TransactionId": {
            "type": "string",
            "description": "TransactionId"
          },
          "TransactionDate": {
            "type": "string",
            "format": "date-time",
            "description": "TransactionDate"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "TransactionItems": {
            "type": "array",
            "description": "TransactionItems",
            "items": {
              "type": "object",
              "title": "TransactionItems",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "price": {
                  "type": "number"
                },
                "currency": {
                  "type": "string"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "updatedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

Authentication

All API requests require an authorization token, which can be retrieved using the login service.
A token expires after 6 hours

Login
POST /login HTTP/1.1
Host: api.flowstack.com Content-Type: application/json
{"username":"rune@flowstack.com","password":"secretpassword"}

Login result
{"token": "<TOKEN>"}

Getting profiles


Retrieving list of profiles
GET /v1/profiles
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>

Result
{
"pagesCount": 1,
"items": [ {profileobj},
{profileobj},.. ],
"total": 12, "page": 1, "limit": 15
}

Possible options set as parametres
limit
Max number of profiles returned. Default is 15

page
If number of profiles exceeds the number of profiles returned, page can be used to retrieve result outside first page. Default is 1

identifier
E.g. retrieve profiles matching “email equals ​rune@flowstack.com​”: ?identifier={“email”:”​rune@flowstack.com​”}

withPermissions
Retrieves profile and adds permissions as an attribute to profile object. Permissions are read only, and can not be set/removed using /profiles/profiles. Service for setting permissions on profile is described later in this document.

segql Retrieves profiles matching specified segql

segmentId
Retrieves profiles in specified segment

omit_subcollections
If omit_subcollections is set to 1, only top level properties of profile is retrieved.


Retrieving specific profile
GET /v1/profiles/4c5af400-b61f-11e7-a352-cd08a6c5d7e0
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>

Result
{
"company": null,
"createdAt": "2018-01-15T08:36:53+00:00", "customerSince": null,
"email": "rune@flowstack.com", "firstname": "Rune",
"id": "3cf40120-f9cf-11e7-9f0f-976af719886b", "lastname": "Viem",
"updatedAt": "2018-01-15T08:50:35+00:00", "orders": [
{
"createdAt": "2018-01-15T08:44:14+00:00", "id": "43b8ae60-f9d0-11e7-b7a8-6d47e15f2f2c", "orderdate": "2018-01-14 09:41:00+01:00", "updatedAt": "2018-01-15T08:50:35+00:00", "products": []
} ]
}

Creating or updating profiles


Profiles POST

POST is used for creating new entity or doing partial update of existing entity

Creating new profile
POST /v1/profiles HTTP/1.1
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>

{
    "firstname": "John",
    "lastname": "Doe",
    "email": "johndoe@flowstack.com"
}

Result
{
    "id": "0212c940-ff58-11e7-b4c4-1b53acbcad21"
}

Partial update
POST /v1/profiles/0212c940-ff58-11e7-b4c4-1b53acbcad21 HTTP/1.1
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>
{
    "firstname": "Johnny"
}

Result
{
    "company": null,
    "createdAt": "2018-01-22T09:38:31+00:00",
    "email": "johndoe@flowstack.com",
    "firstname": "Johnny",
    "id": "0212c940-ff58-11e7-b4c4-1b53acbcad21",
    "lastname": "Doe",
    "updatedAt": "2018-01-22T09:38:31+00:00",
    "transactions": []
}

Full update (WARNING: REPLACE)
PUT /v1/profiles/0212c940-ff58-11e7-b4c4-1b53acbcad21 HTTP/1.1
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>

{
    "firstname": "Johnny"
}


Result
{
    "company": null,
    "createdAt": "2018-01-22T09:42:54+00:00",
    "customerSince": null,
    "email": null,
    "firstname": "Johnny",
    "id": "0212c940-ff58-11e7-b4c4-1b53acbcad21",
    "lastname": null,
    "updatedAt": "2018-01-22T09:42:54+00:00",
    "transactions": []
}

As you see in the result, all attributes are reset unless specified in the body of the PUT.


Deleting profiles

DELETE /v1/profiles/0212c940-ff58-11e7-b4c4-1b53acbcad21 HTTP/1.1
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>


Returns empty response body. Status is 204 No Content

Sub entities

Creating “order” on specified profile
POST /v1/profiles/6142a7e0-ff59-11e7-b4c4-1b53acbcad21/orders HTTP/1.1
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>

{
    "orderdate": "2018-01-22T10:48:20+01:00"
}


Result
{
    "createdAt": "2018-01-22T09:51:05+00:00",
    "id": "c39a48d0-ff59-11e7-9eae-d330f583334d",
    "orderdate": "2018-01-22T10:48:20+01:00",
    "updatedAt": "2018-01-22T09:51:05+00:00",
    "products": []
}


Updating or deleting specific order is done using POST or DELETE on full path to specific subentity E.g.


POST /v1/profiles/6142a7e0-ff59-11e7-b4c4-1b53acbcad21/orders/c39 a48d0-ff59-11e7-9eae-d330f583334d HTTP/1.1

Profiles permissions

Set permissions for profile
POST /v1/profiles:permissions/6142a7e0-ff59-11e7-b4c4-1b53acbcad21 HTTP/1.1
Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>
{"792":true}


Result
{
    "792":true
}

Visitor to profile relation

Relate website visitor to profile

Visitor id: 747089024 (retrieved via fs get_visitor_id)
Profile id: dca17f534d95c0006801f535209f1c1317111fa5

POST /v1/visitors/747089024/e5ce3871446f1146f3ec9ee4fcfb2b02 HTTP/1.1 Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>


Returns 200 if successful (no body)

This service should never be called from browser. Web page should never allow script kiddies to change profile/visitor relations.

Retrieving Content Snippets

Retrieving snippets
GET /v1/contents HTTP/1.1 Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>

Response
{
    "items": [
        {
            "_key": "f698453c-d948-470c-9399-43b9baef429e",
            "id": "f698453c-d948-470c-9399-43b9baef429e",
            "name": "",
            "type": "",
            "content": "
{{#eq profile.profile.ecomcategory \"sports\"}}
\"\"

Flat 50% Discount If Your Name Is {{profile.profile.firstname}}

Hot Offer In Sports Category Today Only

{{/eq}}{{#eq profile.profile.ecomcategory \"fashion\"}}
\"\"

Our Latest Fashion Editorials

Special Offer If Your Name Is {{profile.profile.firstname}}

{{/eq}}
\"\"

End Of Season Sale

Good Deals On Electronics This Week Only

", "fallback": "
\"\"

Flat 50% Discount

Hot Offer In Sports Category Today Only

\"\"

Our Latest Fashion Editorials

cupidatat non proident

\"\"

End Of Season Sale

Good Deals On Electronics This Week Only

", "createdAt": "2019-03-18T10:24:19Z", "updatedAt": "2019-03-18T10:24:19Z" } ], "limit": 25, "page": 1, "pagesCount": 1, "total": 1 }
Retrieving specific snippet
GET /v1/contents/<SNIPPET ID> HTTP/1.1 Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>

Creating Content Snippets

Snippets are objects containg a content property and a fallback property.

Snippets can be rendered frontend side with the jstool.
If a profile is assigned to the visitor, the snippets content property is rendered with the profiles data.
If no profile is assigned, the fallback will be output.

Creating new snippet
POST /v1/contents HTTP/1.1 Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>
{
  "content": "<YOUR CONTENT WHICH CAN CONTAIN HANDLEBARS CODE>",
  "fallback": "<YOUR FALLBACK CONTENT>"
}

Updating specific snippet
POST /v1/contents/<SNIPPET ID> HTTP/1.1 Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>
{
  "content": "<YOUR CONTENT WHICH CAN CONTAIN HANDLEBARS CODE>",
  "fallback": "<YOUR FALLBACK CONTENT>"
}

Deleting Content Snippets

Delete specific snippet
DELETE /v1/contents/<SNIPPET ID>
HTTP/1.1 Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>
                            

Email sendout

Create email sendout
POST /v1/sendouts
HTTP/1.1 Host: api.flowstack.com
Content-Type: application/json
Authentication: <TOKEN>
{
  "name":"", // Sendout name - defaults to name of Email message
  "emailId":"", // Id of email message
  "segmentId":"", // Id of segment, which email will be sent to (recipients)
  "onceOnly":, // Remove recipients from sendout who already received email
  "removeDuplicates": // Remove duplicate recipients,
  "duplicatePath":"", // Property used as duplicate identifier (typically "email")
  "duplicateUse":"", // If duplicates use "newest" or "oldest" profile (based on createdAt) 
  "sendType":"", // Use "now" or "later" depending on whether you want to sendout immediately or at a later time
  "sendAt":"", // Time to sendout (e.g. "2019-05-16T08:00:00.435Z")
  "subject":"", // Email subject
  "fromName":"", // Name of sender
  "fromEmail":"", // Sender email
  "emailPath":"", // Property containing email address (typically "email")
  "emailType":"", // Type of message (marketing or transactional)
  "permissionIds":[] // If marketing message, recipients need at least one of permissions provided. Marketing message will not be sent, if no permission(s) provided
}