API Version 3

You're seeing the newest version of System of Record API. Looking for the old one? Click here.

In order to use this version of the API, please add the value "application/vnd.fa.v3" to the Accept header of the request.

Endpoint and Authentication

Please refer to the API overview section to get the API endpoint, query format and authentication process

Retrieve Attribute Values

Retrieve Customer Attribute Values

This API returns all the Customer Attribute values of the given Customer Profile, for a specific System of Record. It concerns both custom and SDK SORs. Please note that this API is not adapted to massive retrieving that should rather use exports API.

GET /api/attribute_values?sor_id=sor_id&customer_id=c_id&customer_type=type&with_validity_dates

Query parameter

Property Type Description Default
sor_id string The identifier of the Custom or SDK System of Record to fetch the results from. required
customer_id string Customer id to retrieve the profile.
If your customer id is an e-mail, for instance, don't forget to encode both the @ and . signs in the URL to ensure the APIs receive the full parameter, e.g. me@gmail.com becomes me%40gmail%2Ecom.
required
customer_type string Filter by the type of customer_id, user_id or device_id. If the sor_id param does not correspond to a Custom SOR, and the customer_type is device_id, the API returns instead the attributes for the last user that used the device provided. required
with_validity_dates boolean Request the values with the latest dates they became valid, or without these.
If this value is true, the format of the response will be adapted. For set attributes, the date corresponds to the last update made globally to the set.
false

Response

Without requesting dates ( with_validity_dates=false ):

Status: 200 OK

{
  "success": true,
  "result":
    {
      "customer_id": "maximillian",
      "customer_id_type": "user_id",
      "attribute_values": {
        "first_name": "maximillian",
        "last_name": "weber",
        "contract_type": "Premium",
        "client_type": null,
        "hobbies": [],
        "favorite_team": "France",
        "languages": ["French", "English"],
        "city": null,
        "region": null,
      }
    }
}

With the validity dates ( with_validity_dates=true ):

Status: 200 OK

{
  "success": true,
  "result":
    {
      "customer_id": "maximillian",
      "customer_id_type": "user_id",
      "attribute_values": {
        "first_name": {
          "value": "maximillian",
          "since": "2017-10-25T23:48:46:299Z"
        },
        "last_name": {
          "value": "weber",
          "since": "2017-10-25T23:48:46:299Z"
        },
        "contract_type": {
          "value": "Premium",
          "since": "2017-11-13T06:55:21:437Z"
        },
        "client_type": {
          "value": null,
          "since": null
        },
        "hobbies": {
          "value": [],
          "since": null,
        },
        "languages": {
          "value": ["French", "English"],
          "since": "2017-12-05T11:34:51:701Z",
        },
        "city": {
          "value": null,
          "since": null
        },
        "region": {
          "value": null,
          "since": null
        },
      }
    }
}

Export Customer Profiles

This API exports a batch of customer profiles along with the associated attributes values.

GET /api/customer_profiles/export?sor_identifiers=sor_identifiers&customer_id_type=customer_id_type&attribute_keys=attribute_keys&updated_since=updated_since

!!! Using updated_since query parameter is recommended to speed up the processing time. By using this parameter, the API returns only the list of attribute values that changed since the specified date. The other filters and pagination are also used to limit the amount of profiles for each request.

Query parameters

Property Type Description Default
customer_id_type string Filter by the type of customer id, options: user_id, device_id -
customer_ids string List of customer IDs, separated by commas, used to filter the customer profiles returned in the API output -
sor_identifiers string List of SOR identifiers separated by commas, used to define the Systems of Records to return for each profile in the output -
attribute_keys string List of attribute keys separated by commas, used to filter the SOR keys to return for each profile in the API output: only SORs containing a key matching this parameter will be returned, and only this key will be listed -
page integer The page number to fetch. This number must be a positive integer greater then or equal to 1 1
num_per_page integer The maximal number of profiles per page. This number must be a positive integer greater than or equal to 1 and lower than or equal to 10000 2000
updated_since datetime If provided, returns only the list of profiles for which there were attribute changes since this date. Attributes that were removed before this date are not returned. If the attribute was removed after the date and there has been other changes to this attribute after the date, the property removed is marked as true. For set attributes, returns the current state of the set if the set suffered any modifications since the date. -
Example
system_of_record_identifier;customer_attribute_identifier;customer_attribute_key;customer_attribute_value;customer_id_type;customer_id
SOR-SDK_2a116e0767a7dc76e85a5ef85434d92b;FACA_lEDOA5CbP5YzFKcM;team;team1;device_id;3f976ddac73f7d80
SOR-SDK_2a116e0767a7dc76e85a5ef85434d92b;FACA_lEDOA5CbP5YzFKcM;team;team2;user_id;user1

Feed Customer Attributes

FollowAnalytics Ruby gem

We provide a ruby gem to help you modify values for profiles stored in FollowAnalytics.

Define attribute types

To avoid having incoherence in the attribute values it's preferable to define attribute types before starting the feeding.

Limit of attribute values

For both feeding and import APIs, there is a limit of 1000 values for attributes of type SET and each element of the set must be a string of at most 256 characters, if these limits are exceeded the request will be rejected.

Feed Customer Attributes with values

Feeding a Customer Profile with values can be done either from the SDK or from other external systems. This chapter does not cover the SDK functionality, but focuses on external systems.

This API is adapted to small data sets

If you intend to send large data sets on a regular basis, please use the batch CSV imports documented below.

POST https://sor.follow-apps.com/api/attribute_values

Body parameters

It takes a JSON object containing the following keys:

Property Type Description Default
sor string The System of Record identifier required
api_key string The API Key associated to this SOR required
customer_attribute_values array of objects An array of customer_attribute_value object (called CAV below to simplify reading) required
CAV[attribute_key] string The Attribute key. required
CAV[attribute_value] string The value of this attribute for this Customer. Possible values are listed below. required
CAV[customer_id] string The customer identifier required
CAV[action_type] string Used to ADD or REMOVE a specific value to/from the attribute. You can also use DEL to empty the set or UPSERT to replace all set values at once. required for SET type, for the other types it's not required, when it's not speicified it simply adds the value

Possible attribute values:

Value Type Description
Test string Limit of 256 Unicode characters
10 number Limit: 2**63 - 1
-1420.2 number Limit: -(2**63 - 1)
true boolean
false boolean
2016-12-22 date
2016-12-22T13:02:53Z datetime
null any Removes the value

Here is the description of the possible action types:

action_type For attributes of type set For scalar attribute values (other than set type)
ADD adds the provided element to the set replaces the attribute value by the provided one
REMOVE removes the provided element from the set ignored, it's considered as an UPSERT
DEL deletes ALL the elements of the set removes the current attribute value regardless of the provided attribute_value
UPSERT replaces the whole content of the set with new values. The new values should be provided in the parameter value, separated by ;: "value":"one;2;three;etc...". If a set value contains itself a semicolon ; it's recommended to use an ADD request for each value. For example to add value1; and value2, it's recommended to use 2 ADD requests, one for value1; and another one for value2 replaces the attribute value by the provided one

Example

{
    "sor": "SOR_XXXX",
    "api_key": "XXXXXXXX",
    "customer_attribute_values": [
        {
            "customer_id" : "098713490",
            "attribute_key" : "contract_type",
            "attribute_value" : "Premium"
        },
        {
            "customer_id" : "098713490",
            "attribute_key" : "hobbies",
            "attribute_value" : "Sport",
            "action_type" : "ADD"
        },
        {
            "customer_id" : "098713490",
            "attribute_key" : "hobbies",
            "attribute_value" : "Reading",
            "action_type" : "REMOVE"
        },
        {
            "customer_id" : "098713490",
            "attribute_key" : "hobbies",
            "attribute_value" : "Reading;Hiking;Singing",
            "action_type" : "UPSERT"
        },
        {
            "customer_id" : "098713491",
            "attribute_key" : "fav_team",
            "attribute_value" : "France"
        },
        {
            "customer_id" : "098713492",
            "attribute_key" : "fav_team",
            "attribute_value" : "Italy"
        }
    ]
}

In the example above contract_type and fav_team are attributes of type String.hobbies is an attribute of type SET.

The request body above will imply the following:

Response

The response will return the request_id that will allow to track the progress of the request.

Status: 200 OK

{
    "success" : true,
    "result": {
        "requestId": "1522771731812-vl9cUtxfZtMl"
    },
    "errorMessage": null,
    "errorCode": 0
}

Import attribute values from CSV

For large attribute data sets and recurrent imports, it's recommended to send CSV files with attribute values to Followanalytics through the following API. All CSV files must use UTF-8 encoding and it's preferable to compress them as gzip files.

Use the common end-point

This uses the regular, common end-point given in the API overview page, contrary to the JSON upload of attributes which is done through a specific one.

POST /api/attribute_values/batch_import

Query parameter

Property Type Description Default
file_url string URL to the CSV file, gzipped or not required unless uploaded as part of request
sor_id string The System of Record identifier required
api_key string The API Key associated to this SOR required
request_headers map Key-values to use as headers in the call to the file URL, if necessary. Useful for Authentication, e.g. { "Authorization": "abcd", "x-ms-blob-type": "def", ...} -
skip_email boolean Indicates if FA should send an email to notify about the status of the import false

You can also upload the file directly as if part of a web form. The key for the file must be file.

Response

Processing is done asynchronously, including the download of your file. When you call the API, a job ID is returned if all parameters are valid.

Use this job ID in communicating with us if you have an issue with your jobs.

Status: 200 OK

{
    "success": true,
    "result": {
        "jid": "c98de272c6e42d93e7d2b969",
        "import_id": "import_id_1"
    }
}

CSV file content

It's recommended to use gzip compressed files to increase the performance. The CSV file itself must be encoded with UTF-8 and have the following header:

user_id,attribute_key,value,action_type

The key must match an existing attribute of the right type

This API will ignore values for keys not found for the provided SOR identifier. The action_type accepts the 'ADD', 'REMOVE', 'DEL', and 'UPSERT' actions, with 'UPSERT' being the default if the column is empty.

Set values

Each line for a Set attribute is considered as the new full state of the Set. In other words, for a given user and given Set attribute, any list of values provided replaces all current values.

Values for a given user and set are put on the same line, separated by semi-colons. For instance, a CSV line where we set value1 and value2 as the two new and only values of the Set identified by the key my_set is as follows:

abcd,my_set,value1;value2,UPSERT
Example

The following CSV file:

user_id,attribute_key,value,action_type
abcd,my_set,value1;value2,UPSERT
abcd,my_set,value3;value4
efgh,my_set,value2,REMOVE
xyzw,my_set,,DEL
xyzw,my_set,value1,ADD
efgh,my_number,1234,

Hosted at https://path.to/my/file.csv, you would send it as follows:

{
    "file_url": "https://path.to/my/file.csv",
    "sor_id": "SOR_767yUpsMJoTWi0mz",
    "api_key": "XXXXXXXX"
}

CSV attributes import generation

Generate a CSV template that can be used for the batch CSV import API.

GET /api/attribute_values/template

Query parameter
Property Type Description Default
sor_id string The identifier of a System of Record required
api_key string The API Key associated to the System of Record required

Monitoring of CSV imports

You can verify the status of your recent imports. The import job ids and the details of import errors are available for one week.

GET /api/attribute_values/import_jobs

Query parameter

There are no parameters for this query.

Response

The query returns the list of import jobs for the currently logged in user.

Status: 200 OK

{
    "success": true,
    "result": {
        "import_id_1": "2019-01-02 11:12:13",
        "import_id_2": "2019-02-03 11:12:13",
        "import_id_3": "2019-03-03 11:12:13"
    }
}

GET /api/attribute_values/import_errors?import_id=import_id

Query parameter
Property Type Description Default
import_id string The identifier of the import required
Response

The query returns the list of import jobs for the currently logged in user or, in alternative, for a specific customer.

Status: 200 OK

{
    "success": true,
    "result": {
        "attribute_errors": [
            {
                "import_id": "import_id_1",
                "error_type": "empty_key",
                "customer_id": "Bob",
                "key": "age",
                "date": "2019-01-02T11:12:13",
                "message": "attributeKey is empty",
                "raw": "{\n\"sor\":\"SOR_XXXX\",\n\"api_key\":\"XXXXXXXX\",\n\"customer_attribute_values\": [\n{\n\"customer_id\" :\"098713490\",\n\"attribute_key\" :\"contract_type\",\n\"attribute_value\" :\"Premium\"\n}\n]\n}",
                "sor": "SOR_XXX",
                "source": "AttributeCleaner",
            }
        ]
    }
}

error_type can be a technical error :

Or a content error :

Systems of Records

List of SORs

GET /api/system_of_records?type=type

This call lists all the Systems Of Records available for your entity.

There are two types of systems of records (key type):

If the param type is invalid, no system of records are returned.

Query parameter

Property Type Description Default
type string Filter results by type. Can be app and custom. -

Response

Status: 200 OK

{
    "success": true,
    "result": [    
        {
            "name": "SOR for app XYZ",
            "identifier": "SOR-SDK_your.package.name",
            "type": "app",
            "api_keys": [
                "FH7nIacl4f"
            ],
            "attributes_count": 0,
            "disabled": false,
            "customer_attributes": []
        },                   
        {
            "name": "Custom SOR",
            "identifier": "SOR_rldYf1ypGTfvKjl-",
            "type": "custom",
            "api_keys": [
                "2ypbGlj7g0SHOe"
            ],
            "attributes_count": 2,
            "disabled": true,
            "customer_attributes": [
                {
                    "identifier": "FACA__eTzcrLpnuJq",
                    "key": "key1",
                    "label": "label_name1",
                    "value_type": "String",
                    "disabled": false
                },
                {
                    "identifier": "FACA_t7NiJiYd_kGj",
                    "key": "key2",
                    "label": "label_name1",
                    "value_type": "Number",
                    "disabled": false
                }
              ]
          }
       ]
   }

View SOR

GET /api/system_of_records/sor_identifier

Gets information about a single System of Records. This is more detailed than the list because it contains information about the attributes as well.

Query parameter

Property Type Description Default
sor_identifier string The System of Records identifier to view required

Response

Status: 200 OK

{
    "success": true,
    "result":{
        "name": "Custom SOR",
        "identifier": "SOR_rldYf1ypGTfvKjl-",
        "type": "custom",
        "api_keys": [
            "2ypbGlj7g0SHOe"
        ],
        "attributes_count": 2,
        "disabled": true,
        "customer_attributes": [
            {
                "identifier": "FACA__eTzcrLpnuJq",
                "key": "key1",
                "label": "label_name1",
                "value_type": "String",
                "disabled": false
            },
            {
                "identifier": "FACA_t7NiJiYd_kGj",
                "key": "key2",
                "label": "label_name1",
                "value_type": "Number",
                "disabled": false
            }
          ]
        }
    }

Create, Update, Delete SOR

Create

Creates a custom SoR, with a name.

Please note that SDK-based Systems of Records are created automatically, so there is no need to create on manually.

POST /api/system_of_records

Body parameter

Property Type Description Default
name string Name of the new SOR required

Example

{
    "name": "My Custom SoR"
}

Response

Status: 200 OK

{
    "success": true,
    "result": {
        "name": "My Custom SoR",
        "identifier": "SOR_767yUpsMJoTWi0mz",
        "type": "custom",
        "api_keys": [
            "tBqL8qvvAhfyAQ"
        ],
        "attributes_count": 0,
        "disabled": false
    }
}

Update

Modifies a System of Records.

Only custom system of records can be modified.

PUT /api/system_of_records/sor_identifier

Query parameter

Property Type Description Default
sor_identifier string The System of Records identifier required

Body parameter

Property Type Description Default
name string New name for the SOR required

Example

{
    "name": "My Custom SoR"
}

Response

Status: 200 OK

{
    "success": true,
    "result": {
        "name": "My Custom SoR",
        "identifier": "SOR_767yUpsMJoTWi0mz",
        "type": "custom",
        "api_keys": [
            "tBqL8qvvAhfyAQ"
        ],
        "attributes_count": 0,
        "disabled": false
    }
}

Delete

Deletes a System of Records.

Please note that this is not very useful for live SDK-based Systems of Records, as the entry will automatically be regenereted upon next call. In that case, disabling the System of Records is advised.

Also, please note that only custom system of records can be deleted.

DELETE /api/system_of_records/sor_identifier

Query parameter

Property Type Description Default
sor_identifier string Identifier for the SOR to delete required

Response

Status: 200 OK

{
    "success": true
}

Disable & Enable SOR

Disable

Disables a System of Records. Trying to disable an already disabled system of record will result in an API error.

PUT /api/system_of_records/sor_identifier/disable

Query parameter

Property Type Description Default
sor_identifier string Identifier of the SOR to disable required

Response

Status: 200 OK

{
    "success": true
}

Enable

Enables a System of Records. Trying to enable an already enabled system of record will result in an API error.

PUT /api/system_of_records/sor_identifier/enable

Query parameter

Property Type Description Default
sor_identifier string Identifier of the SOR to enable required

Response

Status: 200 OK

{
    "success": true
}

Customer Attributes

This section covers the definition of the attributes onto SORs: key, type, and so on.

View Customer Attribute

GET /api/customer_attributes/ca_identifier

Gets information about a single customer attribute.

Query parameter

Property Type Description Default
ca_identifier string The Customer Attribute identifier required

Response

Status: 200 OK

{
    "success": true,
    "result": {
        "identifier": "FACA_eVYy7KP9PZqP_B8w",
        "key": "is_valid",
        "label": "Is valid",
        "value_type": "Boolean",
        "disabled": false,
        "system_of_record_identifier": "SOR-SDK_2a116e0767a7dc76e85a5ef85434d92b"
    }
}

Create, Update, Delete Customer Attribute

Create

Creates a customer attribute, with a custom label and a type.

POST /api/customer_attributes

Body parameter

Property Type Description Default
system_of_record_identifier String The Customer Attribute related SOR required
key String The Customer Attribute key. Cannot contain more than 256 characters. required
label String The Customer Attribute displayed name required
type String The Customer Attribute value type: String, Number, Boolean, Date, DateTime or Set required

Example

{
    "system_of_record_identifier": "SOR-SDK_c7a5a35762fd9e50006fd77215599dfb",
    "key": "My Attr",
    "label": "my_attr",
    "type": "String"
}

Response

Status: 200 OK

{
    "success": true,
    "result": {
        "identifier": "FACA_0OkzOc8",
        "key": "My Attr",
        "label": "my_attr",
        "value_type": "String",
        "disabled": false
    }
}

Modify

Modifies a customer attribute. Only the label of a customer attribute can be changed.

PUT /api/customer_attributes/ca_identifier

Query parameter

Property Type Description Default
ca_identifier string The Customer Attribute identifier required

Body parameter

Property Type Description Default
label String The new label of the customer attribute. Leave it empty if you don't wish to change it required

Example

{
    "label": "Test"
}

Response

Status: 200 OK

{
    "success": true,
    "result": {
        "identifier": "FACA_eVYy7KP9PZqP_B8w",
        "key": "is_valid",
        "label": "Test",
        "value_type": "Boolean",
        "disabled": false
    }
}

Delete

Deletes a customer attribute along with all the values associated to it.

It is not advised to delete attributes from a live System of Records. Because of auto-declaration, the attribute is going to be recreated upon the next receival of a value. If you don't want to receive these values, but you cannot modify the external system, you can disable the attribute instead.

An attribute that is currently being used in the filters of a campaign or segment cannot be deleted.

DELETE /api/customer_attributes/ca_identifier

Query parameter

Property Type Description Default
ca_identifier string The Customer Attribute identifier required

Response

Status: 200 OK

{
    "success": true
}

Disable & Enable Customer Attribute

Disable

By default, all attributes are enabled, but it is possible to disable one. By doing so, all future values sent for this attribute will be refused, until the attribute is enabled again.

Query parameter

Property Type Description Default
ca_identifier string The Customer Attribute identifier required

Response

Status: 200 OK

{
    "success": true
}

Enable

Enables a previously disabled attribute. Enabling an already enabled attribute is a no-op.

PUT /api/customer_attributes/ca_identifier/enable

Query parameter

Property Type Description Default
ca_identifier string The Customer Attribute identifier required

Response

Status: 200 OK

{
    "success": true
}

Attributes removed since a praticular date

GET /api/removed_attributes?since=since?system_of_record_identifier=system_of_record_identifier

Returns all the attributes removed for the given system of record.

Query parameter

Property Type Description Default
system_of_record_identifier string The identifier of a system of record required
since timestamp If provided, only the attributes removed since this date will returned. Must be a valid date string (eg: '2020-01-01'), a timestamp string (eg: '2020-01-01 20:30') or a unix timestamp integer (eg: 1577910000) -

Response

Status: 200 OK

{
    "success":true,
    "result":[
        {
            "id":32500,
            "system_of_record_id":1,
            "key":"attr1",
            "value_type":"Number",
            "label":"attributeTest1",
            "created_at":"2019-09-03T16:01:55.852Z",
            "updated_at":"2020-01-06T11:00:26.082Z",
            "identifier":"FACA_FgzfBvu",
            "removed":true,
            "disabled":false
        },
        {
            "id":33050,
            "system_of_record_id":1,
            "key":"attr2",
            "value_type":"String",
            "label":"attributeTest2",
            "created_at":"2019-09-25T14:52:04.261Z",
            "updated_at":"2019-12-26T16:54:33.275Z",
            "identifier":"FACA_2BmN8T0",
            "removed":true,
            "disabled":false
        }
    ]
}