Discussions

Eloqua REST API to import contacts to segment or shared list

Wayne Chan-Oracle
Wayne Chan-Oracle Posts: 34 Employee
edited Apr 28, 2020 7:03PM in Developer Tools

Hi Experts,

Current Eloqua REST API set does not seem to provide capability to import list of contacts to segment or shared list. The APIs related to segments are to Crete/delete/update or search segments. Are there APIs there to import list of contacts to an existing segment or shared list ??

thanks,

Wayne Chan

Post edited by Unknown User on
Tagged:

Answers

  • Lou Patrick
    Lou Patrick Principal Product Manager, Eloqua APIs & App Developer Framework Portland, ORPosts: 174 Bronze Trophy
    edited Mar 16, 2020 6:13PM

    You can add contacts to a contact list using the Bulk API sync action - Add to contact list.

    Sync actions are parameters that you declare in an import or export definition that specify additional actions Eloqua should take when you import or export data. There is also a sync actions endpoint that allows sync actions to be executed without running a data import or export. We are currently working on updating the sync actions endpoint documentation, if this is the route you'd like to use, let me know, and I'll provide an example.

    You can then add the Contact List to a Segment via API:

    Here is an example of adding an existing Shared List with an id of 69 to an existing Segment with an id of 7:

    PUT /API/REST/1.0/assets/contact/segment/7

    Request Body:

    {

      "id": "7",

      "name": "Segment_Add_Shared_List_Test",

        "elements": [

        {

          "type": "ContactListSegmentElement",

          "list": {

            "type": "ContactList",

            "id": "69",

            "name": "Segment_Shared_List_Test",

            "scope": "global"

          }

        }

      ]

    }

    Response:

    {

      "type": "ContactSegment",

      "currentStatus": "Draft",

      "id": "7",

      "initialId": "7",

      "createdAt": "1473654217",

      "createdBy": "11",

      "depth": "complete",

      "folderId": "312",

      "name": "Segment_Add_Shared_List_Test",

      "permissions": "fullControl",

      "updatedAt": "1473654810",

      "updatedBy": "11",

      "count": "0",

      "elements": [

        {

          "type": "ContactListSegmentElement",

          "id": "8",

          "depth": "complete",

          "count": "0",

          "isIncluded": "false",

          "lastCalculatedAt": "1473654810",

          "list": {

            "type": "ContactList",

            "id": "69",

            "initialId": "69",

            "createdAt": "1473654190",

            "createdBy": "11",

            "depth": "complete",

            "folderId": "48",

            "name": "Segment_Shared_List_Test",

            "permissions": "fullControl",

            "updatedAt": "1473654810",

            "updatedBy": "11",

            "count": "0",

            "dataLookupId": "eae3aa27-a66a-47c9-bf06-7293ba9f884a",

            "scope": "global"

          }

        }

      ],

      "lastCalculatedAt": "1473654220"

    }

  • Wayne Chan-Oracle
    Wayne Chan-Oracle Posts: 34 Employee
    edited Apr 21, 2020 1:56PM

    Hi Lou,

    thanks for your advise using SyncAction to add contact list/shared list to a segment. I'm actually looking for API to add list of contacts in the form of email addresses to a shared list or contact list. I don't seem to find there are any API endpoints for contact/list in Bulk2.0 ?? I was able to do the same to add multiple entries to a custom object using :

    /bulk/2.0/customobjects/{cdo-id}/imports then /bulk/2.0/customobjects/{cdo-id}/data and finally /bulk/2.0/syncs/{sync-id} to bulk load CDO entries. But don't seems to find the equivalent for contact/list e.g. /bulk/2.0/contact/list/{list-id}/imports etc....

    I want to write an interface for our users to upload list of email addresses to a contact list. The reason to use an external interface instead of just letting users to upload email addresses from csv/Excel is I want to precheck those email addresses before uploading them...

    thanks,

    Wayne

  • Lou Patrick
    Lou Patrick Principal Product Manager, Eloqua APIs & App Developer Framework Portland, ORPosts: 174 Bronze Trophy
    edited Apr 21, 2020 6:51PM

    The Add to contact list sync action can be added to a Contact import, export, or sync action definition. For the import or sync action definition, you can set the identifierFieldName to email address.

    Note: Sync actions are a lighter weight operation and are always recommended instead of imports if fields do not need to be updated.

    Here is an example request to create a Contact sync action definition to add Contacts by email address to a shared list with an id of 64:

    POST /api/Bulk/2.0/contacts/syncActions{    "name": "Bulk Sync Action - Shared List - Email",    "fields": {        "Email": "{{Contact.Field(C_EmailAddress)}}"    },    "identifierFieldName": "Email",    "syncActions": [        {            "destination": "{{ContactList[64]}}",            "action": "add"        }    ]}
  • Wayne Chan-Oracle
    Wayne Chan-Oracle Posts: 34 Employee
    edited Apr 22, 2020 6:10PM

    Lou,

    thanks for your advise. I use your example and performed the following syncActions against a contact list from my instance:

    /bulk/2.0/contacts/syncActions

    {

        "name": "Bulk Sync Action - Shared List - Email",

        "fields": {

            "Email": "{{Contact.Field(C_EmailAddress)}}"

        },

        "identifierFieldName": "Email",

        "syncActions": [

            {

                "destination": "{{ContactList[73]}}",  ====> my shared list Id

                "action": "add"

            }

        ]

    }

    I received 200 OK response from Eloqua as follow:

    {

        "items": [],

        "totalResults": 0,

        "limit": 1000,

        "offset": 0,

        "count": 0,

        "hasMore": false

    }

    Am I suppose to get a syncAction ID ?? As I need to perform an import /bulk/2.0/contact/imports/{sync-Id} ?? with JSON data as follow:

    [

    { Email: [email protected]},

    { Email: [email protected]},

    { ... },

    { .... }

    ]

    If no sync-id is returned from syncActions how would subsequent data import call can match up with syncActions setup from before  ??

    Did I miss something from here ??

    thanks,

    Wayne Chan

  • Wayne Chan-Oracle
    Wayne Chan-Oracle Posts: 34 Employee
    edited Apr 22, 2020 7:03PM

    Lou,

    I think I got it perhaps syncActions -> imports/exports ??

    so the api end point should be : /api/bulk/2.0/contacts/imports

    {

      "name": "Email Address Import",

      "fields": {

        "EmailAddress": "{{Contact.Field(C_EmailAddress)}}"

      },

      "identifierFieldName": "EmailAddress",

      "syncActions": [

        {

          "destination": "{{ContactList[73]}}",  <<===== this is my shared list

          "action": "add"

        }

      ]

    }

    but the 200 OK response did not include any sync id uri as indicated in Oracle's Eloqua sync actions help page:

    https://docs.oracle.com/en/cloud/saas/marketing/eloqua-develop/Developers/BulkAPI/Tutorials/import_export_parameters.htm

    Using the example above (exact cut-n-paste except the contactList id , the response from the above example page is:

    { "name": "Email Address Import", "fields": { "EmailAddress": "{{Contact.Field(C_EmailAddress)}}" }, "identifierFieldName": "EmailAddress", "syncActions": [ { "destination": "{{ContactList[31]}}", "action": "add" } ], "isSyncTriggeredOnImport": false, "dataRetentionDuration": "P7D", "isUpdatingMultipleMatchedRecords": false, "uri": "/contacts/imports/3", "createdBy": "API.User", "createdAt": "2018-01-29T14:29:15.2227712Z", "updatedBy": "API.User", "updatedAt": "2018-01-29T14:29:15.2227712Z" }

    which includes import id : /contacts/imports/3 URI. This is the URI I suppose to use in next call /bulk/2.0/contacts/73/imports/3/data.
    But my experience of making the sync action call is different than what it is described in Eloqua page. I include a screen shot of my postman test.

    Screen Shot 2020-04-22 at 3.56.17 PM.png
    Screen Shot 2020-04-22 at 4.02.08 PM.png

    thanks,

    Wayne Chan

  • Lou Patrick
    Lou Patrick Principal Product Manager, Eloqua APIs & App Developer Framework Portland, ORPosts: 174 Bronze Trophy
    edited Apr 23, 2020 1:15PM

    Let's take a step back. Here is the pattern the Bulk API follows, taken from the API call format tutorial:

    Define the import, export, or sync action. The definition describes how Eloqua's fields map to your own. For example, your email field might map to Eloqua's Contact.Field(C_EmailAddress). You can also give the definition a name, so that you can reuse it later, specify how to filter the data, and define any additional actions you want to perform. The import or export definition tells Eloqua what kind of operation to prepare to perform.Move data into the staging area. For imports or sync actions, this means POSTing your data to the staging area; for exports, this means telling Eloqua to move its data into the staging area. The staging area is a middle ground that allows read and write operations to occur asynchronously from the HTTP requests you send.Move the data to its final destination. For imports or sync actions, this means telling Eloqua to sync the data from the staging area into its database; for exports, this involves retrieving the data from the staging area.

    So, to your previous comments:

    • You need to POST to the definition endpoint, not GET, to create the definition
    • After you create the definition, whether it's an import or sync action definition, you need to perform step 2, which is POSTing data to the definition that was created in step 1
    • Lastly, you need to sync the data. Note, on the definition you could set isSyncTriggeredOnImport to "true" to automatically create the sync when POSTing the data

    Note: Sync actions are a lighter weight operation and are always recommended instead of imports if fields do not need to be updated

  • Wayne Chan-Oracle
    Wayne Chan-Oracle Posts: 34 Employee
    edited Apr 24, 2020 3:25PM

    Hi Lou, thanks for your syncActions coaching. I have used bulk/2.0 to upload data to custom object before using the same protocol sequence: define import definition, upload data to staging area, syncs to trigger data move from staging to custom object. I'm trying to do the same but with contact list.

    Using your example with the same request setup I seemed to be able to get 201 response if the contact list is/are those Eloqua prebuilt shared lists e.g. {{ContactList[1]}} from unfiled folder, {{ContactList[22]}} from BP Event Management folder. My contact list with id=73 was in Testing area folder but the same /bulk/2.0/contacts/syncActions POST returns with 400 validation error as below:

    Screen Shot 2020-04-24 at 11.41.46 AM.png

    If I POSTED against {{ContactList[1]}} or {{ContactList[22]}} the return is 201 Created as shown below (output of POST request against {{ContactList[1]}} --> Unfiled folder -> Eloqua Users shared list

    Screen Shot 2020-04-24 at 11.57.15 AM.png

    I then moved my ContactList[73] to Unfiled folder but got same POST error. It seems to me this API endpoint is applicable only to those shared lists prebuilt by Eloqua instance ??

    Can you advise if I have done anything wrong with this test ?? I ran all the POST requests from the Postman session with same JSON body setup. I just change the {ContactList[id]}} number from 1 to 22 then 73 but Eloqua came back with different results when 73 is POSTed.

    Wayne Chan

  • Wayne Chan-Oracle
    Wayne Chan-Oracle Posts: 34 Employee
    edited Apr 24, 2020 3:31PM

    Lou,

    quick update about syncActions API. I created a new shared list : wayne - empty shared list without any data in it. The syncActions API came back with 201 Created. See screen shot below. Does this mean syncActions must act on an empty shared list only ??

    Screen Shot 2020-04-24 at 12.31.25 PM.png

    Wayne Chan

  • Wayne Chan-Oracle
    Wayne Chan-Oracle Posts: 34 Employee
    edited Apr 24, 2020 8:37PM

    Lou,

    I was able to follow this example to successfully add a shared list to a segment. But the added shared list showed as an "exclude" list but not "include" list when I checked the result from Eloqua console login. I manually switched the shared list to "include" to get right the way I wanted. Can you advise what I did wrong with this endpoint call.

    Also I noticed this PUT endpoint call wiped out any filter(s) existed before this call. This seems to be a destructive call as I got one filter on the segment with one contact added when created the test segment for this endpoint call. After this call all but the shared list was the only filter left there.

    thanks,

    wayne

  • Lou Patrick
    Lou Patrick Principal Product Manager, Eloqua APIs & App Developer Framework Portland, ORPosts: 174 Bronze Trophy
    edited Apr 28, 2020 6:53PM

    With the ContactListSegmentElement the isIncluded property needs to be set to "true". If not including the isIncluded property in the create request it will default to "false".

    Here is an example request:

    POST /api/REST/2.0/assets/contact/segment{    "name": "add_shared_list_include",    "elements": [        {            "isIncluded": "true",            "list": {                "type": "ContactList",                "id": "80",                "name": "Test upload"            },            "type": "ContactListSegmentElement"        }    ]}

    The behavior described is correct for the PUT request. PUT is a replace, so you need to include all the elements when making an update.

  • Lou Patrick
    Lou Patrick Principal Product Manager, Eloqua APIs & App Developer Framework Portland, ORPosts: 174 Bronze Trophy
    edited Apr 28, 2020 6:57PM

    You successfully created the definition, that is only 1/3 of the steps required

    After you create the definition, whether it's an import or sync action definition, you need to perform step 2, which is POSTing data to the definition that was created in step 1.

    Lastly, you need to sync the data. Note, on the definition you could set isSyncTriggeredOnImport to "true" to automatically create the sync when POSTing the data.

    I'd strongly recommend reviewing this tutorial that details this flow for imports and sync actions: Import data into Eloqua

  • Lou Patrick
    Lou Patrick Principal Product Manager, Eloqua APIs & App Developer Framework Portland, ORPosts: 174 Bronze Trophy
    edited Apr 28, 2020 7:03PM

    The most likely scenario is that the id is incorrect. You could use this endpoint to retrieve all available shared lists in your instance - Retrieve a list of contact lists.