The CityGrid Budget API allows publishers to discover the advertisers with budget available to them in the network and check the available remaining budget of a particular advertiser. Publishers who wish to check budgets must use this API so their quality score is unaffected by too many queries without subsequent clicks or user actions.
As of September 2016 a new version of the Budget API, called v4, has been introduced. There are three major changes compared to the previous v2 version:
The budget API allows publishers to discover what advertisers have budget available at a particular moment in time by making accessible a report, generated on demand of the advertisers and budgets available.
http://stream.api.citygridmedia.com/ads/budget/v4/discover |
The following query string parameters are used with the Budget API endpoint:
Parameter | Description | Required | Valid Values | Examples |
---|---|---|---|---|
publisher | The publisher code that identifies you. This parameter is required so that we can reflect the accurate budget. | Yes | Contact your account manager for your publisher code. | acme |
format | The desired format for the result. Default is xml. | No | json, xml | xml |
We use streaming instead of pagination for the response given that the result could be quite large. The response is a streaming-octet content type, which is a file with the result in XML or JSON based on the format specified in the request.
Xsd schema available at:
http://stream.api.citygridmedia.com/ads/budget/v4/discover/schema?publisher=<publisher_code> |
The table below describes the content of the response file. We also included an example of how to write a client to retrieve the response file using this method
Element | Parent Element | Attributes | Description |
---|---|---|---|
ads |
|
| Top level container of advertisement elements |
ad | ads |
| Advertisement data |
ppe | ad | Price per event | |
budget_allocation_id | ad | Budget allocation id | |
call_duration_seconds_minimum | ad | (Nullable) Minimum call duration for a phone call to be eligible for billing | |
dedupe_period | ad | (Nullable) period for which calls from a same caller number on the same advertiser will be deduped | |
dedupe_unit | ad | (Nullable) unit of the dedupe period, for eg. days, hours, months etc. | |
remaining_budget | ad | Budget available | |
day_parting_settings | ad | (Nullable) Day parting settings for this ad and day (apply to all listings in the ad) if any specified by the advertiser | |
windows | day_parting_settings | List of day parting windows | |
window | windows | A window of time within which the budget is available | |
start_time | window | The start time of the day parting window (formatted using xml native "time" format) | |
end_time | window | The end time of the day parting window (formatted using xml native "time" format) | |
listings | ad | The group of businesses sharing the same budget | |
listing | listings | Data of a business location | |
listing_id | listing |
| The ID to uniquely identify CityGrid's businesses |
listing_name | listing | The name of the business | |
reference_id | listing | The ID to uniquely identify provider to which listing belongs to | |
in_day_parting | listing | Boolean that indicates weather or not the advertiser accepts connections at the current time of the day | |
remaining_budget_override | listing | (Nullable) Budget available for this listing if different from remaining_budget | |
phone_number | listing | (Nullable) phone number for the advertiser listing | |
categories | listing |
| List of categories associated to this advertiser |
category | categories | primary= true if the category is primary for this business | Category associated to this advertiser |
markets | listing |
| List of markets associated to this advertiser |
market | markets |
| Market associated to this advertiser |
neighborhoods | listing |
| List of neighborhoods associated to this advertiser |
neighborhood | neighborhoods |
| Neighborhood associated to this advertiser |
cities | listing | List of cities associated to this advertiser | |
city | cities | City associated to this advertiser | |
postal_codes | listing | List of postal codes associated to this advertiser | |
postal_code | postal_codes | Postal code associated to this advertiser | |
day_parting_settings_overrides | listing | (Nullable) Day parting settings that apply for this particular listing if different from day_parting_settings |
Parameter | Description | Required | Valid Values |
---|---|---|---|
Content-Type | Return format | Yes | application/octet-stream |
In the case of an XML, the file downloaded will look like the following:
<ads> <ad> <ppe>1.0</ppe> <remaining_budget>31.0</remaining_budget> <budget_allocation_id>111</budget_allocation_id> <call_duration_seconds_minimum>30</call_duration_seconds_minimum> <dedupe_period>1</dedupe_period> <dedupe_unit>days</dedupe_unit> <listings> <listing> <listing_id>1111</listing_id> <listing_name>XYZ Inc</listing_name> <reference_id>1</reference_id> <in_day_parting>true</in_day_parting> <phone_number>8008001111</phone_number> <categories> <category>Overnight Shipping</category> <category>Commercial Shipping</category> </categories> <markets> <market>Cape Coral-Fort Myers, FL</market> <market>Naples-Marco Island, FL</market> </markets> <neighborhoods> <neighborhood>North Naples</neighborhood> <neighborhood>Urban Estates</neighborhood> </neighborhoods> <cities> <city>Los Angeles</city> <city>San Diego</city> </cities> <postal_codes> <postal_code>99999</postal_code> <postal_code>11111</postal_code> </postal_codes> </listing> <listing> <listing_id>3333</listing_id> <listing_name>abc Inc</listing_name> <reference_id>1</reference_id> <in_day_parting>true</in_day_parting> <phone_number>8008003333</phone_number> <categories> <category primary="true">Attorneys</category> <category>Wrongful Death Attorneys</category> </categories> <markets> <market>West Palm Beach-Boca Raton-Boynton Beach, FL</market> <market>Ocala, FL</market> </markets> <neighborhoods> <neighborhood>Water Catchment Area</neighborhood> <neighborhood>Golden Lakes</neighborhood> </neighborhoods> <cities/> <postal_codes/> </listing> </listings> </ad> <ad> <ppe>2.0</ppe> <remaining_budget>32.0</remaining_budget> <budget_allocation_id>222</budget_allocation_id> <call_duration_seconds_minimum>8</call_duration_seconds_minimum> <listings> <listing> <listing_id>2222</listing_id> <listing_name>stores Inc</listing_name> <reference_id>1</reference_id> <in_day_parting>false</in_day_parting> <phone_number>8008002222</phone_number> <categories> <category>Overnight Shipping</category> <category>Commercial Shipping</category> </categories> <markets> <market>Cape Coral-Fort Myers, FL</market> <market>Naples-Marco Island, FL</market> </markets> <neighborhoods> <neighborhood>North Naples</neighborhood> <neighborhood>Urban Estates</neighborhood> </neighborhoods> <cities/> <postal_codes/> </listing> <listing> <listing_id>4444</listing_id> <listing_name>ZZZ Inc</listing_name> <reference_id>1</reference_id> <in_day_parting>true</in_day_parting> <phone_number>8008004444</phone_number> <categories> <category primary="true">Attorneys</category> <category>Wrongful Death Attorneys</category> </categories> <markets> <market>West Palm Beach-Boca Raton-Boynton Beach, FL</market> <market>Ocala, FL</market> </markets> <neighborhoods> <neighborhood>Water Catchment Area</neighborhood> <neighborhood>Golden Lakes</neighborhood> </neighborhoods> <cities> <city>Los Angeles</city> <city>San Diego</city> </cities> <postal_codes> <postal_code>99999</postal_code> <postal_code>11111</postal_code> </postal_codes> </listing> </listings> </ad> </ads> |
<ads> <ad> <ppe>0.2</ppe> <remaining_budget>3.0311</remaining_budget> <budget_allocation_id>16369425</budget_allocation_id> <call_duration_seconds_minimum>8</call_duration_seconds_minimum> <listings> <listing> <listing_id>838628150</listing_id> <listing_name>Mojo's Seafood & Chicken</listing_name> <reference_id>7</reference_id> <in_day_parting>true</in_day_parting> <remaining_budget_override>1.005</remaining_budget_override> <phone_number>8008008150</phone_number> <categories> <category>Catering</category> <category>Health Food</category> <category>Home Meal Delivery</category> <category>Restaurants</category> <category primary="true">Seafood Markets</category> </categories> <markets/> <neighborhoods/> <postal_codes> <postal_code>36542</postal_code> </postal_codes> <cities> <city>Gulf Shores</city> </cities> </listing> </listings> </ad> </ads> |
<ads> <ad> <ppe>0.2</ppe> <remaining_budget>3.0311</remaining_budget> <budget_allocation_id>16369425</budget_allocation_id> <call_duration_seconds_minimum>8</call_duration_seconds_minimum> <day_parting_settings> <windows> <window> <start_time>09:00:00.000-07:00</start_time> <end_time>18:00:00.000-07:00</end_time> </window> </windows> </day_parting_settings> <listings> <listing> <listing_id>838628150</listing_id> <listing_name>Mojo's Seafood & Chicken</listing_name> <reference_id>7</reference_id> <in_day_parting>true</in_day_parting> <remaining_budget_override>1.005</remaining_budget_override> <phone_number>8008008150</phone_number> <categories> <category>Catering</category> <category>Health Food</category> <category>Home Meal Delivery</category> <category>Restaurants</category> <category primary="true">Seafood Markets</category> </categories> <markets/> <neighborhoods/> <postal_codes> <postal_code>36542</postal_code> </postal_codes> <cities> <city>Gulf Shores</city> </cities> </listing> </listings> </ad> </ads> |
<ads> <ad> <ppe>0.2</ppe> <remaining_budget>3.0311</remaining_budget> <budget_allocation_id>16369425</budget_allocation_id> <call_duration_seconds_minimum>8</call_duration_seconds_minimum> <day_parting_settings> <windows> <window> <start_time>09:00:00.000-07:00</start_time> <end_time>18:00:00.000-07:00</end_time> </window> </windows> </day_parting_settings> <listings> <listing> <listing_id>838628150</listing_id> <listing_name>Mojo's Seafood & Chicken</listing_name> <reference_id>7</reference_id> <in_day_parting>false</in_day_parting> <phone_number>8008008150</phone_number> <categories> <category>Catering</category> <category>Health Food</category> <category>Home Meal Delivery</category> <category>Restaurants</category> <category primary="true">Seafood Markets</category> </categories> <markets/> <neighborhoods/> <postal_codes> <postal_code>36542</postal_code> </postal_codes> <cities> <city>Gulf Shores</city> </cities> <day_parting_settings_override> <windows> <window> <start_time>08:00:00.000-07:00</start_time> <end_time>14:00:00.000-07:00</end_time> </window> </windows> </day_parting_settings_override> </listing> </listings> </ad> </ads> |
Accessing this API requires keeping a persistent HTTP connection open. This involves thinking about your client application differently than if you are using a REST API. In other words, use this API as a separate process independent of user requests.
To connect to the Discovery API, form an HTTP request and download the response file. You must keep the connection open while you are downloading the file. This may be different for every language or framework.
We provide a simple client example to open a connection and download the response file (using Apache HttpClient):
String endpoint = " http://stream.api.citygridmedia.com/ads/budget/v4/discover?publisher=test&format=xml"; HttpGet httpGet = new HttpGet(endpoint); HttpClient client = new DefaultHttpClient(); HttpContext context = new BasicHttpContext(); HttpResponse getResponse = client.execute(httpGet, context); if (getResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { int size = -1; OutputStream os = new FileOutputStream("result.xml"); InputStream is = getResponse.getEntity().getContent(); byte[] buffer = new byte[4096]; while ((size = is.read(buffer)) != -1) { os.write(buffer, 0, size); } os.flush(); os.close(); client.getConnectionManager().shutdown(); } |
We will maintain the connection open until you close it but in some cases we may close your connection:
We are not enforcing hard limits on this version of the API, but we ask that you don’t try to connect to this API over 5 times per day.
The budget API also allows publishers to check what is the advertisers' budget available to them based on their traffic quality.
The following endpoint is used with HTTPS GET:
https://api.citygridmedia.com/ads/budget/v4/where |
The following query string parameters are used with the Budget API endpoint:
Parameter | Description | Required | Valid Values | Examples |
---|---|---|---|---|
publisher | The publisher code that identifies you. This parameter is required so that we can reflect the accurate budget. | Yes | Contact your account manager for your publisher code. | acme |
what | What a user is searching for. For multi-word searches, simply put a space between the words. | Yes | A URL-Encoded string value | pizza |
where | The geographic location, generally a zip code or city-state pair. | Yes | A zip code, city-state pair, or street address. Spaces are optional following the comma between a city and state. | 91011 |
rpp | The maximum number of results to return. The default value is 10. Values over 100 will be clamped to 10. | No | Integers in the range 1 through 100. | 3 |
format | The desired format for the results. Default value xml | No | json, xml | xml |
includeOutsideDayParting | This parameter decides if listings that are at the moment not available because of day parting are included in the response. Default is false | No | true, false | false |
The following endpoint is used with HTTPS GET:
https://api.citygridmedia.com/ads/budget/v4/latlon |
The following query string parameters are used with the Budget API endpoint:
Parameter | Description | Required | Valid Values | Examples |
---|---|---|---|---|
publisher | The publisher code that identifies you. This parameter is required so that we can reflect the accurate budget. | Yes | Contact your account manager for your publisher code. | acme |
lat | Latitude of the center of a circle for a geographic search. | Yes | A decimal between -90 and 90. | 37.65056 |
lon | Longitude of the center of a circle for a geographic search. | Yes | A decimal between -180 and 180. | -119.03639 |
radius | Radius of a circle search, in miles. Defaults to 5. If radius is larger than 25, it will be clamped to 25. | No | An integer between 1 and 25, inclusive. | 2 |
rpp | The maximum number of results to return. The default value is 10. Values over 100 will be clamped to 10. | No | Integers in the range 1 through 100. | 8 |
format | The desired format for the results. Default is xml. | No | json, xml | xml |
includeOutsideDayParting | This parameter decides if listings that are at the moment not available because of day parting are included in the response. Default is false | No | true, false | false |
The following endpoint is used with HTTPS POST or GET:
https://api.citygridmedia.com/ads/budget/v4/detail |
The following query string parameters are used with the Budget API endpoint:
Parameter | Description | Required | Valid Values | Examples |
---|---|---|---|---|
rpp | The maximum number of results to return. The default value is 10. Values over 100 will be clamped to 10. | No | Integers in the range 1 through 100. | 3 |
publisher | The publisher code that identifies you. This parameter is required so that we can reflect the accurate budget. | Yes | Contact your account manager for your publisher code. | acme |
ids | A comma separated string of CityGrid listing ids | Yes |
| 45654239,41783749,32636885 |
format | The desired format for the results. Default is xml. | No | json, xml | xml |
Header Values for POST Requests
Header | Description | Required | Valid Values |
---|---|---|---|
Content-Type | Media type of the request body, if any | yes | application/json |
Usage | URL |
---|---|
Return listings with budget for restaurants in 90069 | https://api.citygridmedia.com/ads/budget/v4/where?publisher=test&what=restaurants&where=90069 |
Return listings with budget for restaurants within 5 miles of the specified lat/lon location | |
Return the budget information for the specified Places | https://api.citygridmedia.com/ads/budget/v4/detail?publisher=test&ids=45654239,41783749,32636885 |
The Budget API results can be returned in both XML or JSON format.
The following table describes the return elements:
Element | Parent Element | Attributes | Description |
---|---|---|---|
ads |
|
| Root element |
ad | ads |
| Advertisement data |
net_ppe | ad |
| Price per event |
reference_id | ad | The ID to uniquely identify provider to which listing belongs to | |
budget_remaining | ad | Budget available | |
budget_allocation_id | ad | Budget allocation id available | |
call_duration_seconds_minimum | ad | (Nullable) Minimum call duration for a phone call to be eligible for billing | |
dedupe_period | ad | (Nullable) period for which calls from a same caller number on the same advertiser will be deduped | |
dedupe_unit | ad | (Nullable) unit of the dedupe period, for eg. days, hours, months etc. | |
day_parting_settings | ad | (Nullable) Day parting settings for this ad and day (apply to all listings in the ad) if any specified by the advertiser | |
windows | day_parting_settings | List of day parting windows | |
window | windows | A window of time within which the budget is available | |
start_time | window | The start time of the day parting window (formatted using xml native "time" format) | |
end_time | window | The end time of the day parting window (formatted using xml native "time" format) | |
listings | ad | The group of businesses that shares the budget available | |
listing | listings | Data for a given location | |
listing_id | listing |
| The ID to uniquely identify CityGrid's businesses |
in_day_parting | listing | Boolean that indicates weather or not the advertiser accepts connections at the current time of the day | |
remaining_budget_override | listing | (Nullable) Budget available for this listing if different from remaining_budget | |
phone_number | listing | (Nullable) phone number for the advertiser listing | |
day_parting_settings_overrideslisting | listing | (Nullable) Day parting settings that apply for this particular listing if different from day_parting_settings |
The following is an example of an XML response:
<ads> <ad> <reference_id>1</reference_id> <net_ppe>0.17728867898596223</net_ppe> <budget_remaining>97.49548319047202</budget_remaining> <budget_allocation_id>11111</budget_allocation_id> <call_duration_seconds_minimum>30</call_duration_seconds_minimum> <dedupe_period>1</dedupe_period> <dedupe_unit>days</dedupe_unit> <listings> <listing> <listing_id>4740459</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008000459</phone_number> </listing> <listing> <listing_id>174934</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008004934</phone_number> </listing> </listings> </ad> <ad> <reference_id>1</reference_id> <net_ppe>1.5468694912910876</net_ppe> <budget_remaining>96.36092528669207</budget_remaining> <budget_allocation_id>22222</budget_allocation_id> <call_duration_seconds_minimum>8</call_duration_seconds_minimum> <listings> <listing> <listing_id>609752</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008009752</phone_number> </listing> </listings> </ad> <ad> <reference_id>1</reference_id> <net_ppe>0.9577210507033189</net_ppe> <budget_remaining>95.46137700585184</budget_remaining> <budget_allocation_id>33333</budget_allocation_id> <call_duration_seconds_minimum>8</call_duration_seconds_minimum> <listings> <listing> <listing_id>4743772</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008003772</phone_number> </listing> </listings> </ad> </ads> |
<ads> <ad> <reference_id>1</reference_id> <net_ppe>0.17728867898596223</net_ppe> <budget_remaining>97.49548319047202</budget_remaining> <budget_allocation_id>11111</budget_allocation_id> <call_duration_seconds_minimum>30</call_duration_seconds_minimum> <dedupe_period>1</dedupe_period> <dedupe_unit>days</dedupe_unit> <listings> <listing> <listing_id>4740459</listing_id> <in_day_parting>true</in_day_parting> <budget_remaining_override>17.49548319047202</budget_remaining_override> <phone_number>8008000459</phone_number> </listing> <listing> <listing_id>174934</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008004934</phone_number> </listing> </listings> </ad> </ads> |
<ads> <ad> <reference_id>1</reference_id> <net_ppe>0.17728867898596223</net_ppe> <budget_remaining>97.49548319047202</budget_remaining> <budget_allocation_id>11111</budget_allocation_id> <call_duration_seconds_minimum>30</call_duration_seconds_minimum> <dedupe_period>1</dedupe_period> <dedupe_unit>days</dedupe_unit> <day_parting_settings> <windows> <window> <start_time>09:00:00.000-07:00</start_time> <end_time>18:00:00.000-07:00</end_time> </window> </windows> </day_parting_settings> <listings> <listing> <listing_id>4740459</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008000459</phone_number> </listing> <listing> <listing_id>174934</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008004934</phone_number> </listing> </listings> </ad> </ads> |
<ads> <ad> <reference_id>1</reference_id> <net_ppe>0.17728867898596223</net_ppe> <budget_remaining>97.49548319047202</budget_remaining> <budget_allocation_id>11111</budget_allocation_id> <call_duration_seconds_minimum>30</call_duration_seconds_minimum> <dedupe_period>1</dedupe_period> <dedupe_unit>days</dedupe_unit> <day_parting_settings> <windows> <window> <start_time>09:00:00.000-07:00</start_time> <end_time>18:00:00.000-07:00</end_time> </window> </windows> </day_parting_settings> <listings> <listing> <listing_id>4740459</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008000459</phone_number> </listing> <listing> <listing_id>174934</listing_id> <in_day_parting>true</in_day_parting> <phone_number>8008004934</phone_number> <day_parting_settings_override> <windows> <window> <start_time>06:00:00.000-07:00</start_time> <end_time>14:00:00.000-07:00</end_time> </window> </windows> </day_parting_settings_override> </listing> </listings> </ad> </ads> |