Forecast API - Documentation

 Content

Table of Contents

In order to use the Forecast API, your Salesforce Org needs to have API usage activated through having an API usage License. 

We also recommend you to automate the OAuth access to avoid authorization issues: 1.6 How to authenticate / authorize ADvendio Gateway for the use of our Third Party System integrations? - Authorize ADvendio message / OAuth#Setup:

The Forecast API function is implemented as Apex class and is exposed as REST web service by using Salesforce standard functionality (see Apex Developer Guide for more information). For general information about the Forecast API feature, see 4.4 Availability Forecast.

1. REST web service

1.1. URL

https://<my-domain-name>.my.salesforce.com/services/apexrest/ADvendio/ADvendio__Campaign_Item__c/CheckAvailability/

https://<my-domain-name>.my.salesforce.com/services/apexrest/ADvendio/ADvendio__Campaign_Item__c/JobUpdates/


1.2. Method

PATCH

1.3. URL Params

-

1.4. Data Params

A JSON object with the attribute campaignItems, containing a JSON serialized list of Campaign Items.

Example: { "campaignItems":[{<Campaign Item>}, ...]}

See /wiki/spaces/AD/pages/852000769 for detailed information about the internal data structure of the Campaign Item.

1.5. Success Response

Code: 200

Content: A JSON serialized list of the Campaign Items from the request body, but now with updated availability and status fields.

Example: [{<Campaign Item>}, ...]

1.6. Error Response

See Salesforce Apex REST Documentation

1.7. Logic

The CheckAvailability web service function returns the availabilities for all Campaign Items not connected to an Ad Server and starts the availability check for the Campaign Items that are connected to an Ad Server. If an availability check job was started the job information will be saved to the field ADvendio__MostRecentGatewayJobInformation__c. The returned Campaign Item can now be used to get the job results by using the JobUpdates function.


The following fields are updated by the CheckAvailability or JobUpdates function.

Campaign Item FieldData formatNote
ADvendio__AvailabilityRunning__cNumber

Campaign Item start time < NOW()

AND

Already submitted to the Ad Server

ADvendio__ReservedImpressionsRunning__cNumber
ADvendio__MatchedImpressionsRunning__cNumber
ADvendio__Availability__cNumber

Campaign Item start time > NOW()

OR

Not yet submitted to the Ad Server

ADvendio__ReservedImpressionsPlanned__cNumber
ADvendio__MatchedImpressionsPlanned__cNumber
ADvendio__Share_of_Voice__cPercent100 * Matched / BookingQuantity
ADvendio__LastAvailabilityForecast__cDate/TimeNOW()
ADvendio__MostRecentGatewayJobInformation__c

JSON String:

{"jobId":123456,
  "campaignItemId":"a0Y000000000001EAA"
  "status":{
    "progress":1,
    "message":"Finish Job",
    "status":2,
    "start":"2019-09-02T07:34:37.000+0000",
    "operation":"Forecast",
    "orgId":"00D1x0000008bZ9EAI"
}}

If an Ad Server is connected the availability will be asynchonously checked by the Ad Server Gateway.

This field is used to store information about the asynchronous job.

campaignItemId: If there is no Campaign Item id, we need an identifier to map back the results, so a fake id is automatically generated.

progress: A value between 0 and 1 to show the progress of the job. Starts with 0 and is finished when it reatches 1.

message: Message about the job status

status: Queued = 0, In progress = 1, completed = 2, failed = 3

start: The the time stamp when the job was started.

operation: For Check Availability always "Forecast".

orgId: The Salesforce org id.

ADvendio__SelectedContent__r.ADvendio__Availability__c

JSON:

{ "version":1,
  "availabilityPerTime": {
    "2020-01-01":123,
    "2020-02-01":565
  }
}

If there is Content linked to the Campaign Item at it is no AdServer connected, the availability will be checked per content per time frame. Time frames are days for CPD, weeks for CPW, months for CPMo, years for CPY and the Campaign Item run time for Fixed Price billing category.

version: A version number for the JSON format in case we need to change it.

availabilityPerTime: Map of the first date of a time frame to the availability number for that time frame.

1.8. Examples

1.8.1. Get a Session-ID

Get a Session ID
curl -v https://login.salesforce.com/services/oauth2/token -d "grant_type=password" -d "client_id=<CLIENT_ID>" -d "client_secret=<CLIENT_SECRET>" -d "username=<USER_NAME>" -d "password=<PASSWORD+TOKEN>" -H 'X-PrettyPrint:1'

Connected App

Get CLIENT_ID and CLIENT_SECRET from any connected app or create a new app in your org: App Manager -> New Connected App

Enable Enable OAuth Settings to see the consumer key (CLIENT_ID) and Consumer Secret (CLIENT_SECRET)

1.8.2. Minimal request

A simple request for a Campaign Item connected to an Ad Server (Google Ad Manager, other Ad Server may need additional information).

Call Check Availability web service
curl https://<my-domain-name>.my.salesforce.com/services/apexrest/ADvendio/ADvendio__Campaign_Item__c/CheckAvailability/ -H 'Authorization: Bearer <SESSION_ID>' -H "Content-Type: application/json" -H 'X-PrettyPrint:1' -d @requestBody.txt --request PATCH

For CheckAvailability the following fields are required per Campaign Item: ADvendio__from_Date__c, ADvendio__until_Date__c, ADvendio__Ad_Price__c

requestBody.txt
{
	"campaignItems":[
		{
			"ADvendio__from_Date__c" : "2019-12-01",
			"ADvendio__until_Date__c" : "2019-12-31",
			"ADvendio__Ad_Price__c" : "a0HA000000LYVkQMAX"
		}
	]
}
Response
[ 
	{
		"attributes" : {
			"type" : "ADvendio__Campaign_Item__c",
		},
		"ADvendio__from_Date__c" : "2019-12-01",
		"ADvendio__until_Date__c" : "2019-12-31",
		"ADvendio__MostRecentGatewayJobInformation__c" : "{\"jobId\":440596,\"campaignItemId\":\"a0Y000000000001EAA\"}",
		"ADvendio__Ad_Price__c" : "a0HA000000LYVkQMAX",
		"Id" : null
	}
]

Second call to get the job results some time later:

Call Job Updates web service
curl https://<my-domain-name>.my.salesforce.com/services/apexrest/ADvendio/ADvendio__Campaign_Item__c/JobUpdates/ -H 'Authorization: Bearer <SESSION_ID>' -H "Content-Type: application/json" -H 'X-PrettyPrint:1' -d @requestBody1.txt --request PATCH

For the JobUpdates request the field ADvendio__MostRecentGatewayJobInformation__c is required. This contains the jobId and dummy campaignItemId to map the results back to each Campaign Item.

requestBody1.txt
{
	"campaignItems":[
		{
			"ADvendio__MostRecentGatewayJobInformation__c" : "{\"jobId\":440596,\"campaignItemId\":\"a0Y000000000001EAA\"}"
		}
	]
}
Response
[ {
  "attributes" : {
    "type" : "ADvendio__Campaign_Item__c"
  },
  "ADvendio__MatchedImpressionsPlanned__c" : 156,
  "ADvendio__ReservedImpressionsPlanned__c" : 1,
  "ADvendio__MostRecentGatewayJobInformation__c" : "{\"errors\":[{\"message\":null}],\"jobId\":440596,\"campaignItemId\":\"a0Y000000000001EAA\",\"status\":{\"jobId\":440596,\"orgId\":\"00DA0000000clAiMAI\",\"operation\":\"Forecast\",\"start\":\"2019-10-17T13:38:29.000+0000\",\"end\":\"2019-10-17T13:38:38.000+0000\",\"status\":2,\"message\":\"Finish Job\",\"progress\":1}}",
  "ADvendio__Share_of_Voice__c" : 15600,
  "ADvendio__Availability__c" : 112
} ]

1.8.3. Request with some targeting

A request for a Campaign Item connected to an Ad Server including some targeting information. To simplify this, we're using Targeting Sets, which contain all Targeting Criteria. You will need to create those in advance in Salesforce. See 3.5.8 Create and Manage Targeting Sets for more information on that.

Call Check Availability web service
curl https://<my-domain-name>.my.salesforce.com/services/apexrest/ADvendio/ADvendio__Campaign_Item__c/CheckAvailability/ -H 'Authorization: Bearer <SESSION_ID>' -H "Content-Type: application/json" -H 'X-PrettyPrint:1' -d @requestBody.txt --request PATCH
requestBody.txt
{
	"campaignItems":[
		{
			"ADvendio__from_Date__c" : "2019-12-01",
			"ADvendio__until_Date__c" : "2019-12-31",
			"ADvendio__Ad_Price__c" : "a1CB0000002lK6RMAU",
			"ADvendio__FrequencyCapping__c":"2 per 1 campaign",
			"ADvendio__AdServerTargeting__c" : "{\"Geography\":{\"valL\":[{\"valS\":\"a14B0000001bZaoIAE\",\"type\":\"Id\"}],\"type\":\"List\",\"logic\":\"&&\"}}",
			"ADvendio__Media_Campaign__r" : {
				"ADvendio__Account__c" : "001A000001R6HDqIAN"
			},
			"ADvendio__SelectedTargetingSets__r":{"records":[
				{"ADvendio__TargetingSet__c":"a2f2K000000orLNQAY"}
			]}
		}
	]
}
Response
[ 
	{
		"attributes" : {
			"type" : "ADvendio__Campaign_Item__c",
			"url" : "/services/data/v46.0/sobjects/ADvendio__Campaign_Item__c/a0l1j000000ayRJAAY"
		},
		"ADvendio__from_Date__c" : "2019-12-01",
		"ADvendio__until_Date__c" : "2019-12-31",
		"ADvendio__MostRecentGatewayJobInformation__c" : "{\"jobId\":434663,\"campaignItemId\":\"a0Y000000000001EAA\"}",
		"ADvendio__Ad_Price__c" : "a1CB0000002lK6RMAU",
		"ADvendio__Media_Campaign__r" : {
			"attributes" : {
				"type" : "ADvendio__MediaCampaign__c"
			},
			"ADvendio__Account__c" : "001A000001R6HDqIAN"
		},
		"Id" : null,
		"ADvendio__FrequencyCapping__c" : "2 per 1 campaign",
		"ADvendio__AdServerTargeting__c" : "{\"Geography\":{\"valL\":[{\"valS\":\"a14B0000001bZaoIAE\",\"type\":\"Id\"}],\"type\":\"List\",\"logic\":\"&&\"}}",
		"ADvendio__SelectedTargetingSets__r" : {
		    "totalSize" : 0,
		    "done" : false,
		    "records" : [ {
		      "attributes" : {
		        "type" : "ADvendio__SelectedTargetingSet__c"
		      },
		      "ADvendio__TargetingSet__c" : "a2f2K000000orLhQAI"
		    }]
		}
	}
]

Second call to get the job results some time later:

Call Job Updates web service
curl https://<my-domain-name>.my.salesforce.com/services/apexrest/ADvendio/ADvendio__Campaign_Item__c/JobUpdates/ -H 'Authorization: Bearer <SESSION_ID>' -H "Content-Type: application/json" -H 'X-PrettyPrint:1' -d @requestBody1.txt --request PATCH
requestBody1.txt
{
	"campaignItems":[
		{
			"attributes" : {
    			"type" : "ADvendio__Campaign_Item__c",
    			"url" : "/services/data/v46.0/sobjects/ADvendio__Campaign_Item__c/a0l1j000000ayRJAAY"
  			},
			"ADvendio__from_Date__c" : "2019-12-01",
			"ADvendio__until_Date__c" : "2019-12-31",
			"ADvendio__MostRecentGatewayJobInformation__c" : "{\"jobId\":434663,\"campaignItemId\":\"a0Y000000000001EAA\"}",
			"ADvendio__Ad_Price__c" : "a1CB0000002lK6RMAU",
			"ADvendio__Media_Campaign__r" : {
				"attributes" : {
					"type" : "ADvendio__MediaCampaign__c"
				},
				"ADvendio__Account__c" : "001A000001R6HDqIAN"
			},
			"Id" : null,
			"ADvendio__FrequencyCapping__c" : "2 per 1 campaign",
			"ADvendio__AdServerTargeting__c" : "{\"Geography\":{\"valL\":[{\"valS\":\"a14B0000001bZaoIAE\",\"type\":\"Id\"}],\"type\":\"List\",\"logic\":\"&&\"}}",
			"ADvendio__SelectedTargetingSets__r" : {
			    "totalSize" : 0,
			    "done" : false,
			    "records" : [ {
			      "attributes" : {
			        "type" : "ADvendio__SelectedTargetingSet__c"
			      },
			      "ADvendio__TargetingSet__c" : "a2f2K000000orLNQAY"
			    } ]
			}
		}
	]
}
Response
[
 {
  "attributes" : {
    "type" : "ADvendio__Campaign_Item__c",
    "url" : "/services/data/v46.0/sobjects/ADvendio__Campaign_Item__c/a0l1j000000ayRJAAY"
  },
  "ADvendio__MatchedImpressionsPlanned__c" : 24,
  "ADvendio__from_Date__c" : "2019-12-01",
  "ADvendio__until_Date__c" : "2019-12-31",
  "ADvendio__ReservedImpressionsPlanned__c" : 1,
  "ADvendio__MostRecentGatewayJobInformation__c" : "{\"errors\":[{\"message\":null}],\"jobId\":434663,\"campaignItemId\":\"a0Y000000000001EAA\",\"status\":{\"jobId\":434663,\"orgId\":\"00DB0000000IE6XMAW\",\"operation\":\"Forecast\",\"start\":\"2019-10-10T14:50:26.000+0000\",\"end\":\"2019-10-10T14:50:32.000+0000\",\"status\":2,\"message\":\"Finish Job\",\"progress\":1}}",
  "ADvendio__Ad_Price__c" : "a1CB0000002lK6RMAU",
"ADvendio__Media_Campaign__r" : {
	"attributes" : {
	  "type" : "ADvendio__MediaCampaign__c"
	},
	"ADvendio__Account__c" : "001A000001R6HDqIAN"
  },
  "Id" : null,
  "ADvendio__FrequencyCapping__c" : "2 per 1 campaign",
  "ADvendio__Share_of_Voice__c" : 2400,
  "ADvendio__AdServerTargeting__c" : "{\"Geography\":{\"valL\":[{\"valS\":\"a14B0000001bZaoIAE\",\"type\":\"Id\"}],\"type\":\"List\",\"logic\":\"&&\"}}",
  "ADvendio__SelectedTargetingSets__r" : {
    "totalSize" : 0,
    "done" : false,
    "records" : [ {
      "attributes" : {
        "type" : "ADvendio__SelectedTargetingSet__c"
      },
      "ADvendio__TargetingSet__c" : "a2f2K000000orLNQAY"
    } ]
  },
  "ADvendio__Availability__c" : 16
 }
]



1.8.4. Request for non adserver Campaign Items with Content

A request for a Campaign Item not connected to an Ad Server with selected Content. This will start the Exclusivity Check process inside of ADvendio instead of the Check Availability against the AdServer Gateway.

Call Check Availability web service
curl https://<my-domain-name>.my.salesforce.com/services/apexrest/ADvendio/ADvendio__Campaign_Item__c/CheckAvailability/ -H 'Authorization: Bearer <SESSION_ID>' -H "Content-Type: application/json" -H 'X-PrettyPrint:1' -d @requestBody.txt --request PATCH
requestBody.txt
{
    "campaignItems":[
        {
            "ADvendio__from_Date__c" : "2019-12-01",
            "ADvendio__until_Date__c" : "2019-12-31",
            "ADvendio__Ad_Price__c" : "a1CB0000002lK6RMAU",
            "ADvendio__SelectedContent__r": {
                "records": [
                    {
                        "attributes": {
                            "type": "ADvendio__SelectedContent__c"
                        },
                        "ADvendio__Content__r": {
                            "attributes": {
                                "type": "ADvendio__Content__c"
                            },
                            "Id": "a2f2K000000orLNQAY",
                            "ADvendio__ConstantQuantity__c": "Quantity",
                            "ADvendio__MaximumApplicability__c": 1,
                            "ADvendio__MaximumApplicabilityUnit__c": "Day"
                        }
                    }
                ],
                "done": true
            }
        }
    ]
}
Response
[
 {
  "attributes" : {
    "type" : "ADvendio__Campaign_Item__c",
    "url" : "/services/data/v46.0/sobjects/ADvendio__Campaign_Item__c/a0l1j000000ayRJAAY"
  },
  "ADvendio__from_Date__c" : "2019-12-01",
  "ADvendio__until_Date__c" : "2019-12-31",
  "ADvendio__Ad_Price__c" : "a1CB0000002lK6RMAU",
  "ADvendio__SelectedContent__r" : {
    "totalSize" : 1,
    "done" : false,
    "records" : [ {
      "attributes" : {
        "type" : "ADvendio__SelectedContent__c"
      },
      "ADvendio__Content__c" : "a2f2K000000orLNQAY"
      "ADvendio__Availability__c" : {
		"version":1,
		"availabilityPerTime" : {
		  "2019-12-01" : 16
		}
	  }
    } ]
  },
  "ADvendio__Availability__c" : 16
 }
]

1.8.5. Request for non adserver Campaign Items with Content (Inventory Forecast)

A request for a Campaign Item not connected to an Ad Server with selected Content. This will start the Exclusivity Check process inside of ADvendio instead of the Check Availability against the AdServer Gateway.

requestBody.txt
{
  "campaignItems": [
    {
      "ADvendio__from_Date__c": "2022-11-09",
      "ADvendio__until_Date__c": "2022-11-15",
      "ADvendio__Quantity__c": "2",
      "ADvendio__Frequency__c": "1",
      "ADvendio__RequestedContents__c": "1",
      "ADvendio__Ad_Price__c": "a0H2K00000VuuRDUAZ",
      "ADvendio__SelectedContent__r": {
        "records": [
          {
            "attributes": {
              "type": "ADvendio__SelectedContent__c"
            },
            "ADvendio__Content__c": "a0e2K00000fn85fQAA"
            
          }
        ],
        "totalSize": 1,
        "done": true
      }
    }
  ]
}
responseBody
[
    {
        "attributes": {
            "type": "ADvendio__Campaign_Item__c",
            "url": "/services/data/v46.0/sobjects/ADvendio__Campaign_Item__c/a0Y000000000001EAA"
        },
        "ADvendio__ContendingCampaignItems__c": "a0Y2K00000GEyltUAD\na0Y2K00000GEymIUAT",
        "ADvendio__Quantity__c": 2.0,
        "ADvendio__Ad_Price__r": {
            "attributes": {
                "type": "ADvendio__Ad_price__c",
                "url": "/services/data/v46.0/sobjects/ADvendio__Ad_price__c/a0H2K00000VuuRDUAZ"
            },
            "Id": "a0H2K00000VuuRDUAZ",
            "ADvendio__Ad_Spec__c": "a0F2K00000QxD3LUAV",
            "ADvendio__MaximumApplicability__c": 10.0000,
            "ADvendio__MaximumApplicabilityUnit__c": "Week",
            "ADvendio__EffectiveMaximumApplicability__c": 10.0000,
            "ADvendio__EffectiveMaximumApplicabilityUnit__c": "Week",
            "ADvendio__ConstantQuantity__c": "Runtime Campaign Item",
            "ADvendio__Exclusive__c": true,
            "ADvendio__Ad_Spec__r": {
                "attributes": {
                    "type": "ADvendio__Ad_Specs__c",
                    "url": "/services/data/v46.0/sobjects/ADvendio__Ad_Specs__c/a0F2K00000QxD3LUAV"
                },
                "Id": "a0F2K00000QxD3LUAV",
                "ADvendio__Ad_Type__c": "a0G2K00001Uu7qTUAR",
                "RecordTypeId": "012A00000012g4SIAQ",
                "ADvendio__Placement__c": "a1M2K00000EhD7hUAF",
                "ADvendio__Ad_Type__r": {
                    "attributes": {
                        "type": "ADvendio__Ad_Type__c",
                        "url": "/services/data/v46.0/sobjects/ADvendio__Ad_Type__c/a0G2K00001Uu7qTUAR"
                    },
                    "Id": "a0G2K00001Uu7qTUAR"
                }
            }
        },
        "ADvendio__SelectedContent__r": {
            "totalSize": 1,
            "done": true,
            "records": [
                {
                    "attributes": {
                        "type": "ADvendio__SelectedContent__c"
                    },
                    "ADvendio__Content__r": {
                        "attributes": {
                            "type": "ADvendio__Content__c",
                            "url": "/services/data/v46.0/sobjects/ADvendio__Content__c/a0e2K00000fn85fQAA"
                        },
                        "Id": "a0e2K00000fn85fQAA",
                        "Name": "Store 1000",
                        "ADvendio__ConstantQuantity__c": "Runtime Campaign Item",
                        "ADvendio__MaximumApplicability__c": 1.0000,
                        "ADvendio__MaximumApplicabilityUnit__c": "Week"
                    },
                    "ADvendio__Content__c": "a0e2K00000fn85fQAA",
                    "ADvendio__Availability__c": "{\"available\":true}"
                }
            ]
        },
        "ADvendio__LastAvailabilityForecast__c": "2022-10-10T16:11:55.247+0000",
        "ADvendio__from_Date__c": "2022-11-09",
        "ADvendio__Exclusive__c": true,
        "ADvendio__until_Date__c": "2022-11-15",
        "ADvendio__RequestedContents__c": 1.0,
        "ADvendio__Ad_Price__c": "a0H2K00000VuuRDUAZ",
        "ADvendio__Frequency__c": 1.0,
        "Id": "a0Y000000000001EAA",
        "ADvendio__Availability__c": 2.0
    }
]

1.8.6. Usage in Apex

List<ADvendio__Campaign_Item__c> cis = ...
cis = ADvendio.CheckAvailabilityService.checkAvailability(cis);
// there is no real option to wait in APEX, so getting the asynchronous results while running synchronous apex is not really usable
while (ADvendio.JobStatusService.isAJobRunning(cis)) {
   wait some time
   cis = ADvendio.JobStatusService.getStatusAndWriteToCI(cis);
}