You are on page 1of 12

 

Objective 
The Basics 
API Protocol 
Access Tokens 
Domain 
Request Rate limiter 
Public facing Apis 
API Versioning 
Secure Transfer 
Size of GET requests 
Response format type 
Batch Requests 
Receiving Error Codes 
API Debug Mode 
Account Creation and Payment Gateway 
Managing Audiences (Facebook Link) 
Retrieve a custom audience segment 
Build an Audience 
Updating an audience segment 
Opting out Users 
Deleting audience segment 
Ads Management 
Create a campaign : 
Verify campaign creation 
Limitations of Campaign 
Reporting Campaign stats 
Create Adgroup 
Create Creative 
Create Ad 
Launch your Ad 
APIs Signature InMobi (Demand Service) 
Create Campaign API: 
2: required Model.RequestContext) 
Update Campaign API: 
CampaignModel.CampaignDetail updateCampaign(1: required 
CampaignModel.UpdateCampaignRequest, 
2: required Model.RequestContext) 
Read Campaign API: 
Delete Campaign API: 
Design Consideration Block Diagram 
Stacks Involved 
Campaign API frontend [New Stack Component] 
Campaign API backend [New Stack Component] 
Demand Service 
Cron/Adpool/UMP 
Brand Job for audience management 
User/Citrus Leaf 
Assumptions & Considerations 
 

Owner  Rajat  

Reviewer  Sunder, Ankur 

PRD  PRD 

Objective 
To onboard Resellers who are integrated with Facebook, Twitter etc and are looking for new partners with 
API integrations. 

The Basics 

API Protocol 
The InMobi APIs will be HTTPS based, so that it will work with any language that has an HTTP library, such 
as cURL, urllib, etc.  

Access Tokens 
The APIs will require the use of access tokens. Access tokens are random strings that will provide temporary 
secure access to InMobi campaign APIs. ​ [How the access token will be created? Check authentication servie 
used by kensho] 
 
The access token will have further permissions level 
● ads_read:​  Will provide access to pull reporting information only.  
● ads_management​  Will provide access to both read and update the ads in an account. 

Domain 
All the requests will be passed to the API at api.inmobi.com ​
[other domain?] 

Request Rate limiter 
Support for rate limiting the incoming requests from a particular account/token. 
Public facing Apis 

Public facing Name  Public facing API 

Campaign  /campaigns 

Ad group  /adgroups 

Ad  /ads 

Creative  /creatives 

API Versioning 
The APIs will be versioned. The version will be prepend to the start of the request path. eg.  
GET api.inmobi.com/v1.0/{request­path} 

Secure Transfer 
This enables data to be transferred over a secure connection. 

Size of GET requests 
The request can end up being larger if number of query parameters increase. [Max size of url?] 

Response format type 
The response will be in json format. 

Batch Requests 
Single GET request that retrieves multiple campaigns/adgroups etc by using the ?ids endpoint with the object 
IDS of the campaigns/adgroups. Eg. 
GET api.inmobi.com/v1.0/campaigns?ids=campaignId1,campaignId2 
And this would return something like this: 

“campaignId1”: { 
“id”: “101” 
… // Other fileds 
}, 
“campaignId2” : { 
“id” : “102” 
… // Other fields 

Response Code 
Standard HTTP Response code with full description. 
Receiving Error Codes 
The following represents a common error response resulting from a failed API request: 

“error”: { 
“message”: “Message describing the error”, 
“type”: “OAuthException”, 
“code”: 190, 


Full error code taxonomy is available at https://developers.facebook.com/docs/marketing­api/error­reference. 

API Debug Mode 
When debug mode is enabled, InMobi campaign APIs response may contain additional fields, explaining 
possible issues with the request. To enable debug mode, use ‘debug’ query string parameter. 
 
The response may look like this. 

    “data”: [ … ], 
        “__debug__”: { 
            “messages”: [ 
            { 
                “message”: “The adgroup is targeting to invalid country”, 
                “type”: “error” 
            }, 
            { 
                “message”: “The adgroup bid is lower than minimum expected”, 
                “type”: “warning” 
            } 
        ] 
    } 

‘debug’ parameter value can be set to ‘all’ or to a minimal requested severity level. E.g. warning, info etc. 
Debug information will be returned as a JSON object under __debug__ key, that contains messages array. 

Account Creation and Payment Gateway 
Account creation and payment can be done through UI. ​
[Thoughts?] 
 
Managing Audiences ​
(​
Facebook Link​

Retrieve a custom audience segment 
Retrieve individual segment 
curl ​ https://api.inmobi.com/​ v1.0/<AUDIENCE_ID> 
 
Custom Audience​
If you want to fetch a list of all the ​  objects associated with a specific ad account you can use 
an URL like this: 
GET api.inmobi.com/v1.0/<AD_ACCOUNT_ID>/customaudiences 

Build an Audience 
To add people, share data in an encrypted format to maintain privacy. The accepted method for hashing is 
SHA256 or MD5. 
 
To create a custom audience first create a blank audience segment. Once segment is created, add people to it. 
curl \ 
  ​­​
F ​'name=My new Custom Audience'​  \ 
  ​­​
F ​'subtype=AUDIENCE'​  \ 
  ​­​
F ​'description=People who bought from my website'​  \ 
  ​­​
F ​'access_token=<ACCESS_TOKEN>'​  \ 
  ​https://api.inmobi.com/v1.0/​ <​AD_ACCOUNT_ID​>/​
customaudiences 
 
On success, the Custom Audiences API returns a new ​ custom_audience_ID​ . 
 
To add user data to the audience, make a call to ​ {custom_audience_ID}/users​  with your normalized, hashed 
data. For example: 
curl \ 
  ­F 'payload={  
    "schema": "EMAIL_SHA256",  
    "data": [  
      "83b1fe0afe7e25f11db408baf85f5acea6c9381049619b75909bef957373ff83",  
      "24bf0dd10ca4df1cdd5dcd07b503f5468f74cc145d0451517bd9892af0dd5728",  
      "caa0190ae6bf9c6c77cb57a2c249122039a8d687e4ab8c88479c2cbe858dfe82"  
    ]  
  }' \ 
  ­F 'access_token=<ACCESS_TOKEN>' \ 
  ​https://api.inmobi.com/v1.0​ /<CUSTOM_AUDIENCE_ID>/​ users 
 
A successful return result will looks like this: 
Struct { 
    audience_id: numeric string, 
    num_received: int32, 
    num_invalid_entries: int32, 
    invalid_entry_samples: Map { 
    string: string 
    }, 

 
num_invalid_entries​
The ​  indicates a number of users that did not match and are not in the custom audience. 
Question: What should be the lifespan of the users associated to the audience segment? 

Updating an audience segment 
To update the audience name: 
curl \ 
  ​
­​F ​
'name=Updated Name for CA'​  \ 
  ​
­​F ​
'access_token=<ACCESS_TOKEN>'​  \ 
  ​
https://api.inmobi.com/v1.0/​ <​
CUSTOM_AUDIENCE_ID​ > 
 
On success, it will return a boolean value “true”, “false” otherwise 

Opting out Users 
If a user has opted out of being targeted he has to be removed from all custom audiences. To do so a delete 
api call is required. 
curl \ 
  ​ ­​
F ​
'payload={  
    "data": [  
      "83b1fe0afe7e25f11db408baf85f5acea6c9381049619b75909bef957373ff83",  
      "24bf0dd10ca4df1cdd5dcd07b503f5468f74cc145d0451517bd9892af0dd5728",  
      "caa0190ae6bf9c6c77cb57a2c249122039a8d687e4ab8c88479c2cbe858dfe82"  
    ]  
  }'​  \ 
  ​ ­​
F ​
'access_token=<ACCESS_TOKEN>'​  \ 
  ​ https://api.inmobi.com/v1.0/​ <AD_ACCOUNT_ID>/​ usersofanyaudience 
 
On success, it will return a boolean value “true”, “false” otherwise 

Deleting audience segment 
/{custom_audience_id}​
You can delete a Custom Audience by making a DELETE request to ​ . 
 

Ads Management 

Create a campaign ​

A campaign is a grouping of adgroups which are organized by the same business objective. Each campaign has 
an objective that must be valid across the adgroups within that campaign. 
1. Set a tittle 
2. Pause the campaign (don’t billed while testing) 
3. Campaign objective.  
4. Start and End date of the campaign 
5. Campaign budget and lifetime budget 
 
curl \ 
  ­F 'name=My campaign' \ 
  ­F 'status=PAUSED' \ 
  ­F 'objective=​ BRAND_AWARENESS​  \ 
  ­F 'start_time=2016­01­13T00:00:24+0000' \ 
  ­F 'end_time=2016­02­13T00:00:24+0000' \ 
  ­F 'lifetime_budget=10000' \ 
  ­F 'daily_budget=1000' \ 
  ­F 'access_token=<ACCESS_TOKEN>' \ 
  ​
https://api.inmobi.com/v1.0/​ <AD_ACCOUNT_ID>/campaigns 
 
campaignId (numeric string) ​
On success, a new ​ will be returned. 

Verify campaign creation 
curl ​https://api.inmobi.com/​v1.0/<CAMPAIGN_ID> 
 
Return Type 
Struct { 
campaignId​ : numeric string, 
name​: string, 
objective​ : string, 
status​: enum string, 
start_time​ : date string, 
end_time​ : date string, 
lifetime_budget​ : numeric string, 
daily_budget​ : numeric string, 

Limitations of Campaign 
● Maximum number of campaigns per ad account? 
● Maximum number of adgroups in a campaign? 
● Maximum length of campaign name? 

Reporting Campaign stats 
After your ads begin delivering, you can query stats for campaigns. The statistics returned will be unique stats, 
deduped across the adgroups. You can also get reports and statistics for all adgroups in an campaign 
simultaneously. 
curl ​
­​
G \ 
  ​
­​
d ​
'time_range={"since":"2015­12­30","until":"2016­01­06"}'​
 \ 
  ​
­​
d ​
'fields=impressions,unique_clicks,reach'​
 \ 
  ​
­​
d ​
'access_token=<ACCESS_TOKEN>'​
 \ 
https://api.inmobi.com/​
  ​ v1.0/stats/<CAMPAIGN_ID> 

Create Adgroup 
An adgroup is a group of ads that share the same daily or lifetime budget, schedule, billing, optimization, and 
targeting data. Create an adgroup with following definition 
● Name of Adgroup 
● How long your adgroup will run (​ start_time​ end_time​
 / ​ ). 
● Tracking Url 
● How much money you want to spend per day (​ daily_budget​ ). 
● How you want to pay (​ billing_event​ ). 
● What is the bid amount (​ bid_amount​ ). 
● Question: What about other Ad group parameters as mentioned on InMobi UI 
○ call to action 
○ select site 
○ Targeting 
 
curl \ 
  ­F 'campaign_id=<CAMPAIGN_ID>' \ 
  ­F ‘optimization_goal=REACH' \ 
  ­F 'billing_event=IMPRESSIONS' \ 
  ­F 'bid_amount=2' \ 
  ­F 'daily_budget=1000' \ 
  ­F 'targeting={“geo_locations”:{“countries”:[“US”]}}' \ 
  ­F 'start_time=2016­01­13T00:00:24+0000' \ 
  ­F 'end_time=2016­02­13T00:00:24+0000' \ 
  ­F 'status=PAUSED' \ 
  ­F 'access_token=<ACCESS_TOKEN>' \ 
  https://api.inmobi.com/v1.0/<AD_ACCOUNT_ID>/adgroups 
 
On success, a new ​ AdgroupId (numeric string) ​ will be returned. ​[adgroup name, guid, id?] 

Create Creative 
AdCreative​
The information you need to provide in ​  in part depends on the campaign objective. Commonly you 
will define the following attributes: 
 
● Upload one or multiple images (or a video) 
● Set title, description, etc. 
● Link your creative to an ad 
Depending on your objective you will need to provide some advanced fields. By example: If you book an ad for an 
iOS app you need to provide an app store URL. This requirement does evidently not apply if you book an ad for 
website clicks. In our example, using the objective "website clicks", you need to provide a link to your website. 
 
AdImage​
First, create an ​  from an image file. 
curl \ 
  ­F 'filename=@<IMAGE_PATH>' \ 
  ­F 'access_token=<ACCESS_TOKEN>' \ 
  https://​ api.inmobi.com/v1.0/<ADGROUP_ID>/adcreatives 
 
On Success this will return an image hash. Use the image hash to create the ​ AdCreative​ . 
curl \ 
  ­F 'name=Sample Creative' \ 
  ­F 'object_story_spec={  
    "link_data": {  
      "caption": "My caption",  
      "image_hash": "<IMAGE_HASH>",  
      "link": "<URL>",  
      "message": "try it out"  
    },  
  }' \ 
  ­F 'access_token=<ACCESS_TOKEN>' \ 
  ​https://​ api.inmobi.com/v1.0​ /<​ ADGROUP_ID​ >/adcreatives 
 
On success, a new ​ CreativeId (numeric string) ​ will be returned 

Create Ad 
Ad​
With an ​ AdCreative ​
 you link your ​ Adgroup​
and ​  to a new object representing your ad. 
 
curl \ 
  ­F 'name=My Ad' \ 
  ­F 'adgroupId=<AD_GROUP_ID>' \ 
  ­F 'creative={"creative_id":"<CREATIVE_ID>"}' \ 
  ­F 'status=PAUSED' \ 
  ­F 'access_token=<ACCESS_TOKEN>' \ 
  https://​ api.inmobi.com/v1.0/<AD_ACCOUNT_ID>/​ ads 
 

Launch your Ad 
active​
Once you feel comfortable booking ads using the API set the status to ​ . 

PENDING_REVIEW​
The ad will first go through ad review, and will have the status ​  before it finishes review and 
ACTIVE​
reverts back to your selected status of ​ . 
 
APIs Signature InMobi (Demand Service) 

Create Campaign API: 
CampaignModel.CampaignDetail​
 ​
createCampaign​
(​
1:​
 ​
required​
 ​
CampaignModel.Campaign​, 
2:​
 ​
required​
 ​ ) 
Model.RequestContext​

Update Campaign API:  
CampaignModel.CampaignDetail​
 ​
updateCampaign​
(​
1:​
 ​
required​
 ​
CampaignModel.UpdateCampaignRequest​

2:​
 ​
required​
 ​
Model.RequestContext​

Read Campaign API: 
CampaignModel.CampaignDetail​
 ​
getCampaign​
(​
1:​
 ​
string​
 campaignId, 
    ​
2:​
 ​
required​
 ​
Model.RequestContext​
)  

Delete Campaign API: 
CampaignModel.CampaignDetail​
 ​
updateCampaignState​
(​
1:​
 ​
required​
 ​
CampaignModel.UpdateCampaignStateRequest​

     2:​
 ​
required​
 ​ ) 
Model.RequestContext​

Design Consideration Block Diagram 

 
*Green color components are new components 
*Yellow color components require code change. 
*Blue color components require no change 
 

Stacks Involved 

Campaign API frontend [New Stack Component] 
This will expose ​
REST based APIs​ to be called directly by the resellers. The APIs will provide CRUD 
operations for Campaign, Adgroup, Ad and Creative. The APIs are listed in “Ads Management” section of this 
design doc. 

Campaign API backend [New Stack Component] 
This layer will provide the translation of REST exposed interfaces to data model. This will host all the 
business logic and call respective downstream services to store data. For example, it will call Demand 
Service with relevant information to create/update campaigns,adgroups etc. It can also call report DB service 
to get campaign level stats. 

Demand Service 
The current update method requires whole object to be passed again. For example even to update the 
campaign name, whole of campaign object needs to be passed again which will override the existing 
campaign detail to the new detail object just passed. 
This needs to be changed to update and pass only relevant fields rather than whole object. 

Cron/Adpool/UMP 
No Changes 

Brand Job for audience management 
This job will start taking input as reseller supplied user segment mapping and will provide the same as a 
cumulative feed to profile validator job. 

User/Citrus Leaf 
Service to create user segment already exists. No changes are required here. 
 
Profile validator service to upload user segment mapping to citrus leaf will start reading from a new feed also. 
The service will take the audience mapping from brand job and upload that to Citrus leaf. Currently it only 
uploads the matched audience, i.e. users seen on InMobi network. Whatever is the logic of this service will 
be used and no customization will be done for Campaign API. 
 
Assumptions & Considerations 
1. Jointly (with Sunder & Ankur) taking a call to keep campaign api and kensho as two separate 
systems. Campaign/adgroup/ad created through campaign API may or may not be available/modified 
through Kensho and vice versa. 
2. There are many API versions and we are picking the latest API version for our reference. ​ What 
should be the action plan for onboarding resellers using different API versions?  
3. Wherever there is a mismatch between Facebook and InMobi entities definition, we are choosing 
Facebook defined definition so that there is minimum work required to onborad and start resellers. 
One such example is objective. Facebook says “Brand Awareness”, InMobi says “Generate 
Awareness”. 
4. The first version of the APIs will be build for BRAND campaigns only but the design and code 
structure will be kept flexible enough to provide easy extendibility to other business verticals in future. 
5. In case of custom audience creation, profile extractor job takes the user segment mapping and 
upload the same to citrus leaf. Whether it uploads all users or only matched users is agnostic to 
consumer services and will be applied generically across all the implementations. 
6. InMobi currency type is $ while facebook supports multiple currency types. We are expecting that the 
account creation with InMobi and money refill will happen only in $ and reseller will always provide 
bid/budget etc in $ 
7. Jetty vs Tomcat? Based on Internet research we are choosing Jetty. http://sohanb.blogspot.in/ 

You might also like