Skip to main content

Feeding your ACTITO Profile tables

Introduction#

If you want to create and update your profiles in your ACTITO database directly via API, this case is made for you.


You will learn here the basis to automate your data flows.

While understanding of the ACTITO concepts is sufficient to set up your data flows, you can read the full documentation on ACTITO Profile tables to dive into profiles management.



Let's consider a practical case:

  • When a client registers on your website, you want to immediately create their profile in ACTITO.
  • Stating you use an opt-in management page in your website, you want the modification on subscriptions/unsubscriptions to be pushed to ACTITO immediately.
  • Twice a day, you import a list of new profiles acquired from partner agencies.
  • Should a profile delete their account in your system, you want to remove their information from your ACTITO database

Step by Step#

  1. Create or update a single profile
  2. Update a single profile subscriptions
  3. Delete a single profile
  4. Launch a bulk profile import and check its result
Prerequisites
  • Make sure the profile table exists in your licence and that you know the entity which it belongs to (check with your marketeer).
  • Check that the structure of that profile table contains all the fields necessary for the data you wish to provide.
  • We assume that you have checked out the Quick Start guide, so we guess that you know how to make some curl calls with the sample JSONs of the steps below.

Step 1. Create or update a single profile#

Real-time one by one API calls should be used when the data is to be present in ACTITO and used as soon as it is present in your system (for example to trigger a scenario, send a welcome e-mail etc.).


You can make that happen by using the operation:

POST /entity/MyEntity/table/MyWebsiteProfiles/profile?allowUpdate=true

This operation will create a new profile or update an existing one by using the data you provide within the call.

These data are profile attributes values, subscriptions, segmentations and data collection information. All that fields will define the full information of the profile.

Hereby follows an example of a representative JSON:

{  "attributes": [    {      "name": "lastName",      "value": "Smith"    },    {      "name": "firstName",      "value": "John"    },    {      "name": "birthDate",      "value": "26/05/1967"    },    {      "name": "sex",      "value": "M"    },    {      "name": "motherLanguage",      "value": "EN"    },    {      "name": "emailAddress",      "value": "john.smith@actito.com"    },    {      "name": "addressLocality",      "value": "Los Angeles"    },    {      "name": "addressCountry",      "value": "US"    },    {      "name": "gsmNumber",      "value": "1223344556"    },    {      "name": "customerId",      "value": 34567    },    {      "name": "nbChildren",      "value": 2    }  ],  "dataCollectionInformation": {    "date": "10/09/2019",    "source": "TEST",    "way": "website registering"  },  "subscriptions": [    {      "name": "Newsletter",      "subscribe": "true"    },    {      "name": "Promotions",      "subscribe": "false"    }  ],  "segmentations": [    {      "belongs": "true",      "segmentation": {        "name": "ClientType",        "category": "Gold"      }    },    {      "belongs": "true",      "segmentation": {        "name": "isActive",        "category": "Member"      }    }  ]}

In this example, ACTITO will try to match an existing profile in table "MyWebsiteProfiles" regarding the unique key customerId which is the unique identifier of the clients in your system. If it exists, ACTITO will update it by replacing existing data with the provided. If not, ACTITO will create a new profile.

As everything is OK, you receive a 200 OK http response with the following JSON response body that contains the profileId of the created/matched profile :

{  "profileId": 1147690}
Behaviour in case of multiple unique keys in the database

This operation can be used both for Create and Update operations. For Updates, the "allowUpdate" parameter must set as true. In this case, the link with the existing profile will be based on a key attribute.

If the JSON object contains more than one key (for instance, a customerId and a unique e-mail address), the following rules will be applied to find the matching profile:

  1. For each value of unique attribute found in the file, the program will search for the matching profile
  2. If all the non-unique field values match the same profile, the profile is updated
  3. If two or more field values match different profiles, a conflict is generated and the update is not applied (you'll receive a 409 Conflict http response)
  4. If no matching profile can be found, the system will create a new one

Step 2. Update a single profile subscriptions#

As an existing profile modifies his opt-in preferences on your website (personal space), you also want this modification to be immediately pushed to ACTITO.


To update an existing profile, you may use the operation:

PUT /entity/MyEntity/table/MyWebsiteProfiles/profile/1147690

In that example, we will update a profile that exists in "MyWebsiteProfiles" with the profileId equal to 1147690.

In that a case, the JSON body to provide in the request should only contain information that has to be updated. Unmentioned attributes in the body will be left unchanged in the profile.

In our use case, wishing only to update the opt-in preferences of our profile, the following JSON only references the subscriptions to modify and the GDPR compliance information dataCollectionInformation:

{  "subscriptions": [    {      "name": "Newsletter",      "subscribe": "false"    },    {      "name": "Promotions",      "subscribe": "true"    }  ],  "dataCollectionInformation": {    "source": "WebsitePersonalSpace",    "date": "2019-09-10 10:10:00",    "way": "A way"  }}

As everything is OK, you receive a 200 OK http response with the following JSON response body that contains the profileId of the updated profile:

{  "profileId": 1147690}

Note that you can also impact a single subscription or segmentation for an existing profile by using those operations:


Subscribe the profile to subscription ***Newsletter***:

POST /entity/MyEntity/table/MyWebsiteProfiles/profile/1147690/subscription/Newsletter


Unsubscribe the profile of subscription ***Newsletter***:

DELETE /entity/MyEntity/table/MyWebsiteProfiles/profile/1147690/subscription/Newsletter

When using those two methods, you should provide always provide the data collection information (GDPR compliance) as the JSON body of your requests:

{  "source": "WebsitePersonalSpace",  "date": "2019-09-10 10:10:00",  "way": "A way"}

Step 3. Delete a single profile#

If a profile requests the deletion of their account from your website, you should also delete it in ACTITO, as keeping their information is not GDPR compliant.


You can delete a profile through the operation:

DELETE /entity/MyEntity/table/MyWebsiteProfiles/profile/1147690

If no profile has been found for the provided profileId, you'll receive a 404 NOT FOUND http response.

If the profile has been found and deletion was OK, then you'll receive a 200 OK http response.

Use DELETE with caution...

Though deleting a profile through the ACTITO APIs is possible, please note that such a deletion has consequences. We therefore invite you to read the Deleting a profile page before automating such an action.


Step 4. Launch a bulk profile import and check its result#

Launch an import#

As one by one operations are not the most efficient way to push a huge volume of data, ACTITO Integration Framework provides an asynchronous data import API that takes in charge flat files upload and load into your Profile tables. Bulk API calls should be preferred for daily/weekly/monthly flows that don't require immediate result or real-time based marketing action triggering.


In addition to new customers who register on your website, you also acquire new profiles through the means of partners agencies (lead generation during an exihibition, a commercial fair etc. for instance).
As they provide you daily with a list of new prospects, a daily bulk call is therefore the best way to import those profiles into ACTITO.


You can therefore use the operation:

POST /entity/MyEntity/table/MyProspectsProfiles/import

This call will require you to post a flat CSV file. We kindly encourage you to compress it (ZIP and GZIP are supported) to optimize data transfer. In case of a ZIP file, it should contain a single CSV file.
In our example, the data are to be loaded in your MyProspectsProfiles profile table.

The CSV file format must fit with following rules:

  • The file must be a valid CSV
  • The file first line contains column headers
  • Every header matches the technical name of a field of the profile table (a field can be an attribute, a subscription or a segmentation) or a custom mapping should be provided (check how below).
  • Technical names are case sensitive
  • Subscriptions will be matched by using the following pattern: subscriptions#xxxx where xxxx is the name of the subscription.
  • Segmentations will be matched by using the following pattern: S_xxxx where xxxx is the name of the segmentation.

    To fit with your CSV generation tool or program (if not exactly what Actito takes in charge by default) and to specify the data loading parameters (mode, csv columns to attributes mapping, e-mail report recipients), you can optionnaly provide an `application/json` file with those custom settings.

    Both files are to be provided as body parts of the POST call with `multipart/form-data` content type.

    Example of POST call with both zipped file and json parameters:
curl -X POST "https://api.actito.com/v4/entity/MyEntity/table/MyProspectsProfiles/import" \     -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI0IiwiaWF0IjoxNTg2ODY1MjE1LCJpc3MiOiJhY3RpdG8iLCJleHAiOjE1ODY4NjYxMTUsImxpY2VuY2VJZCI6MTI3NDAsImFjY291bnRJZCI6MTIsInBvbCI6Im1haW5Qb2xpY3lBcGkiLCJzdWIiOiI2ZWY3YjZmYS0wYTc1LTQ1YTYtYmE5My1iZGY5MmUyZjg3NDAifQ.umizXm0TueN6jRkMCaz9AnQP30qNxud5XIxnZiPzz24L8Aon7WKeJ8_49xcjsTe_v13nv4AI9991Mw_k9bvQffT__eikkv9UMmZ22wvQr5UxCH5Y-NkxFRctEGLjmkEdFFe2EuOkF1GjsIetPrJgY-_L6bpoa3G0o69IWavBIFowQtw_q0FOPaZ_JtBLiDiFH59IM5s4-8S-QAhGkGgjOhTzqBTyDBGj8cqnhvr9eFwgoxGSAZ1QLGU5yTRyIJm8Uaq97M5UhKn98ixK4oQhQvVKwW9MDgGyf0jLFLEFO7l9kyFON34OsxiTyK58U_OFJzehgxqRokBE3wXWo9rKEA"  \     -H "Accept: application/json" \   -H "Content-Type: multipart/form-data" \   -F "inputFile=@/yourfolder/profiles.zip;type=application/zip" \   -F "parameters={\"mode\" : \"CREATE_ONLY\", \"encoding\" : \"UTF-8\", \"format\" : { \"separator\" : \";\", \"endOfLine\" : \"\r\n\", \"enclosing\" : \"\\\"\", \"escaping\" : \"\\\"\" }, \"reportRecipients\" : [ \"john.smith@actito.com\", \"jane.smith@actito.com\" ], \"attributesMapping\" : [ { \"headerColumn\" : \"AdresseEmail\", \"attributeName\" : \"emailAddress\" } ] };type=application/json"
Multi-value attributes

Former multi-value attributes are not supported by bulk synchronizations

When posting a new bulk import request, if everything is OK, you should receive a JSON response containing the technical id of the created import:

{  "id": 123456789,  "name": ""}

Checking the result#

As bulk imports are asynchronous the API also allows you to check your import's status and potential error causes.

Import status#

The following operation provides you with the status of an existing import. An import status should be RUNNING or FINISHED.


GET /entity/MyEntity/import/123456789

Detailed result#

When an import is FINISHED, you can retrieve a detailed result to check how the parsing and loading procees went.

A successful import will return a result like this:

{  "entityId": 1,  "tableId": "1",  "synchroId": 123456789,  "mode": "CREATE_UPDATE",  "startExecution": "2019-10-10 20:00:00",  "endExecution": "2019-10-10 21:00:00",  "withErrorFile": true,  "withErrors": false,  "errors": [],  "executionResult": {    "rowsRead": 100,    "rowsInError": 10,    "rowsWritten": 90  }}

Though the import creation API would directly return bad request errors when providing wrong import parameters, some errors should be only detected while processing the file to load.

In that case, when FINISHED, a failed import result would contain the list of global errors that happened (linked to the global processing of the file such as a corrupted ZIP file or a CSV format problem etc.). The returned result should then look like this :

{  "entityId": 1,  "tableId": "1",  "synchroId": 123456789,  "mode": "CREATE_UPDATE",  "startExecution": "2019-10-10 20:00:00",  "endExecution": "2019-10-10 21:00:00",  "withErrorFile": false,  "withErrors": true,  "errors": [    {      "path": "",      "errorCode": "",      "description": "",      "isGlobal": "",      "idPath": "",      "id": "",      "parameters": {        "": ""      }    }  ]}

However, even if input file and import parameters are all correct, you can always have some processing errors regarding the data validation in ACTITO.

Retrieving the detailed errors file#

When the import result states that an error file is available, you can retrieve it by using the following operation:


GET /entity/MyEntity/import/123456789/errors

This call will return a compressed ZIP file containing a single CSV file that contains all the lines of the import input file for which an error was raised by ACTITO.
A line in this error file contains the same data than the corresponding line in the input file, but with two more columns containing the error code, and the error reason of the error.
An error shall be raised when a column linked to mandatory attribute is empty, when a value in a column is not compatible with the definition of the attribute the column is linked to etc.


You are done!

You are now used to feeding the ACTITO profile tables of your licence.