Professional Documents
Culture Documents
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/{requestpath}
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/marketingapi/errorreference.
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=20160113T00:00:24+0000' \
F 'end_time=20160213T00: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":"20151230","until":"20160106"}'
\
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=20160113T00:00:24+0000' \
F 'end_time=20160213T00: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/