Admin API batch option

This document shows how to batch multiple Admin API endpoint calls

This document is intended to support batching Admin API calls.

Definition

A way of sending multiple API requests at the same time. For instance if you want to update a factor and its 2 variations, normally you have to do 3 requests. Each requests the validates who you are and runs through the rate limiting code. With the multiple endpoint it counts as a single request, we validate and get your permissions for the site, then on each sub request we check to see if you can access that specific object. Less redundant work, means a faster API. The only down side is all the work is being done serially on the server.

You can mix and match methods in a multiple call. So you can PUT to a factor, POST a new variation, DELETE an old variation, and GET a different variation.

Variables

When creating objects, often you need to reference another object’s ID. For instance to create a variation you need a factor’s ID. Which means if you want to create a factor with 2 variations, you would first have to create the factor, get the response, then create the variations. With variables for the multiple API endpoint, you can say create a factor, store its ID in a variable, then in the sub requests use that variable.

The variable must be for a top level value. Variables can not access sub values (can not set a variable on a factor’s match condition).

Variable names must start and end with a colon, and can only contain alphanumeric and underscores.

m/^:[A-Z0-9_]+:$/i

To apply variables, a sub API call will be converted to json, a search and replace is called for each variable, then the json is converted back to a perl object.  By doing this the variable can be used in any part of the sub API call.

Endpoint URL

All requests go to /site/{site-id}/multiple/

Methods

The method to the multiple endpoint itself doesn’t matter.  POST/PUT/GET/DELETE all call the same sub.  The only reason I didn’t restrict it to one, is I can see a user wanting to use a POST, if all the sub queries are POSTs, or a PUT if all the sub queries are PUTs.

Format

The format for a multiple, is a hash with a key called “multiple” with an array for the value.

Errors

The API will loop through the array (in order), executing each sub call.  If a call fails, the API will stop at that call, and not run the remaining calls.

Response

The response will be a hash with 2 keys.  “summary” a hash of what work was done and “response” which is the response for each API call.

Example API Call

This will create a factor with 2 variations.  The variable :factor1ID: will get the ID column of the results of the factor POST.  Then the following calls we will replace :factor1ID: with the ID of the factor that was created.

{
    "multiple": [
        {
            "URL" : "/API/site/1/factor",
            "Method" : "POST",
            "Data" : {
                "Name": "Test Factor",
                "type": "Regular"        
            },
            "SetVariables": {
                ":factor1ID:": "ID"
            }
        
        },
        {
            "URL" : "/API/site/1/factor/:factor1ID:/variation",
            "Method" : "POST",
            "Data" : {
                "Name": "Variation 1"        
            }
        },
        {
            "URL" : "/API/site/1/factor/:factor1ID:/variation",
            "Method" : "POST",
            "Data" : {
                "Name": "Variation 2"    
            }
        }
    ]
}

Example response

(truncated a bit)

{
  "summary": {
    "PROCESSED": 3,
    "POST": 3
  },
  "response": [
    {
      "method": "POST",
      "url": "/API/site/1/factor",
      "result": {
        "DefaultNewVisitRating": 0,
        "IsVisuallyEdited": false,
        ...
        "ID": 3868,
        "Status": "Active"
      }
    },
    {
      "method": "POST",
      "url": "/API/site/1/factor/3868/variation",
      "result": {
        "Status": "Active",
        "ID": 14777,
        ...
        "IsControlVariation": false,
        "DisableWhenCookieConflict": false
      },
      "originalUrl": "/API/site/1/factor/:factor1ID:/variation"
    },
    {
      "originalUrl": "/API/site/1/factor/:factor1ID:/variation",
      "result": {
        "OriginCookieValue": null,
        "StartDate": "Never",
        "ParentFactorID": null,
        ....
        "UrlForPreview": null
      },
      "url": "/API/site/1/factor/3868/variation",
      "method": "POST"
    }
  ]
}

Note: in the response from the variations you only see originalUrl, when the url in the request had a variable. 

Example Campaign

{
   "multiple":[
      {
         "URL":"/api/site/1/factor",
         "Method":"POST",
         "Data":{
            "name":"test 1",
            "type":"Regular",
            "matchconditions":[
               {
                  "type":"Url",
                  "urlcriterion":"Origin(?#contains)"
               }
            ],
            "newbuildflowcampaignid":"-1"
         },
         "SetVariables":{
            ":factor1ID:":"ID",
            ":ControlVariationID:":"ControlVariationID"
         }
      },
      {
         "URL":"/api/site/1/factor/:factor1ID:/variation/:ControlVariationID:",
         "Method":"PUT",
         "Data":{
            "name":"Template"
         }
      },
      {
         "URL":"/api/site/1/factor/:factor1ID:/variation",
         "Method":"POST",
         "Data":{
            "iscontrolvariation":false,
            "name":"Variation 1",
            "modificationregexsearch":"x",
            "modificationregexreplace":"y"
         },
         "SetVariables":{
            ":variation1ID:":"ID"
         }
      },
      {
         "URL":"/api/site/1/campaign",
         "Method":"POST",
         "Data":{
            "control":null,
            "name":"test via multiple 4",
            "newbuildflow":true,
            "setname":"Non-Overlay",
            "optimizationmetric":"H",
            "criticalresponsepointid":3,
            "userasmtcriteria":[
               {
                  "ID":28,
                  "Action":"EXCLUDE"
               },
               {
                  "ID":30,
                  "Action":"EXCLUDE"
               },
               {
                  "ID":32,
                  "Action":"EXCLUDE"
               }
            ],
            "responsepoints":[
               14406,
               11085,
               11090,
               14164,
               14420,
               14683,
               14671,
               14680,
               14684,
               14426,
               3
            ],
            "campaignset":1
         },
         "SetVariables":{
            ":campaign1ID:":"ID",
            ":ControlVariationGroupID:":"ControlVariationGroupID"
         }
      },
      {
         "URL":"/api/site/1/campaign/:campaign1ID:/variationgroup/:ControlVariationGroupID:",
         "Method":"PUT",
         "Data":{
            "name":"Original",
            "variations":[
               {
                  "id":":ControlVariationID:",
                  "applysearchandreplace":true
               }
            ],
            "control":true
         }
      },
      {
         "URL":"/api/site/1/campaign/:campaign1ID:/variationgroup",
         "Method":"POST",
         "Data":{
            "name":"Variation Group 1",
            "variations":[
               {
                  "id":":variation1ID:",
                  "applysearchandreplace":true
               }
            ]
         }
      }
   ]
}