Partner Managed Funding Instruments (PMFI)
The onboarding flow configures an ads.twitter.com account for the Twitter account, which can be managed by the partner through the Ads API, and whose advertising spend is billed to the partner.
Partner Initial Set-up
The process to initially set-up a new PMFI Ads API partner takes up to 3-weeks from exchange of required information. The following must be shared with your technical contacts at Twitter, as well as the Twitter contact managing the integration with the partner in order to get the process started:
- The partner must share their PGP/GPG public key. A shared secret key needs to be exchanged between the Ads API partner and Twitter. This will be used to verify data during the onboarding flow.
- The
app_id
orconsumer_secret
for the Twitter app that will be used for Ads API access. You can view and edit your existing Twitter apps via the app dashboard if you are logged into your Twitter account on developer.twitter.com. If you need to create a Twitter app, you will need to have an approved developer account. Twitter allows one app for production+sandbox and one optional app for sandbox-only access. The Twitter app must be created on a corporate, partner-controlled Twitter handle.
Advertiser Onboarding Flow
The advertiser onboarding flow occurs via a web browser in the following way:
- The user starts the onboarding flow on the partner’s website and enters the handle they want to onboard.
- The partner redirects the user to a URL on ads.twitter.com with a signed payload. This payload contains the partner’s API
app_id
, the Twitteruser_id
of the Twitter handle which is to be onboarded and a callback URL and other fields documented below. - The user is asked to sign into ads.twitter.com using the standard twitter.com login page.
- Once the user is logged in, the onboarding process is initiated. This step includes ad review, account validation and other checks.
- When all onboarding tasks are completed, the user is redirected to the callback URL that was provided by the Ads API partner, with a payload that indicates success or failure. This includes the 3-legged authorization process.
Onboarding redirect payload
URL for redirect:
https://ads.twitter.com/link_managed_account
The redirect URL will be called with the following parameters:
Name | Type | Description |
---|---|---|
callback_url | URL encoded string | user will be redirected to this url after the account link process completes, regardless of outcome. See the partner redirect url section for protocol details |
client_app_id | integer | Twitter API client app id, used to identify the managing partner |
promotable_user_id | integer | Twitter user_id of the @handle whose promotions are to be managed by the managing partner. Used to make sure it is the same as the user who logs into ads.twitter.com to complete the linking process |
fi_description | URL encoded String (max 255 characters) | funding instrument name. This will be displayed in the description field in the API when the funding instrument is retrieved. If a funding_instrument description is given, the existing funding_instrument will be paused, and a new managed partner funding instrument will be set up. (if one exists with the same name, nothing will happen) |
timezone | String, in Area/Location format | This will be the timezone used to determine the day to which daily budgets apply, and in which charges will be aggregated |
currency | ISO 4217 Currency Code | Currency that will be used to enter bids, and in which charges will be billed |
country | ISO 3166-1 alpha 2 Country Code | Billing Country for the account |
signature | URL encoded, base64 encoded binary code, as explained below | signature that combines a shared secret and the other parameters to verify authenticity of the call, as well as validity of the parameters. |
Callback URL payload
The base redirect URL is provided using the callback_url parameter on the account link request (see above). The parameters added by ads.twitter.com are:
Name | Type | Description |
---|---|---|
status | string |
|
account_id | URL encoded string | Twitter ads account id of the linked account |
funding_instrument_id | URL encoded string | ID of the active partner managed funding instrument |
signature | URL encoded, base64 encoded binary code, as explained below | Base64 encoded HMAC-SHA1 signature that combines a shared secret and the other parameters to verify authenticity of the call, as well as validity of the parameters. To make sure the callback url is only valid for the Twitter user_id that the account link process was intended for, the twitter user_id is to be appended to the shared secret (using &) when signing the request. |
To make sure the callback URL is only valid for the Twitter user_id
that the account link process was intended for, the Twitter user_id
is to be appended to the shared secret (using &) when signing the request.
Signing the request and callback URLs
In order to ensure that the requests to /link_managed_account
and the callback url are valid, the requests need to be signed at the source and verified by the recipient before the recipient takes action on them. Signing the request with a secret that is shared between Twitter and the managing partner ensures that each party only accepts requests sent by the authorized counterpart.
The signature generation algorithm is similar to the one used in OAuth.
Create a signature base string as follows:
- Convert the HTTP Method to uppercase and set the base string equal to this value.
- Append the ‘&’ character to the base string.
- Percent encode the URL (without parameters) and append it to the base string.
- Append the ‘&’ character to the base string.
- Append the percent encoded query string, which is built as follows:
- Percent encode every key and value that will be signed.
- Sort the list of parameters alphabetically by key.
- For each key/value pair (and with primary_promotable_user_id for the partner redirect url):
- Append the percent encoded key to the query string.
- Append the ‘=’ character to the base string.
- Append the percent encoded value to the query string.
- Separate the percent encoded key=value pairs with the ‘&’ character.
- Use the HMAC-SHA1 algorithm, using the previously exchanged shared secret, as the key, and the base string as the value to generate the signature.
- Base64 encode the output of Step 2, drop the trailing newline character percent encode the signature generated in Step 3 and add it to the url in a signature parameter
Signing examples
Signing a link account request
Url to sign, assuming a GET request:
https://ads.twitter.com/link_managed_account?callback_url=https%3A%2F%2Fmanagingpartner.com%2Flink_account_callback&client_app_id=12345&fi_description=some%20name&promotable_user_id=1
This url has the following parameters:
callback_url = https://managingpartner.com/link_account_callback client_app_id = 12345 fi_description = some name promotable_user_id = 1
The base string consisting of http method and url without parameters, steps a - d, looks like:
GET https://ads.twitter.com/link_managed_account
The query string, produced by the substeps of e, looks like:
callback_url=https://managingpartner.com/link_account_callback&client_app_id=12345&fi_description=some name&promotable_user_id=1
Note that the key-value pairs are sorted by key name.
The percent encoded query string looks like:
callback_url%3Dhttps%253A%252F%252Fmanagingpartner.com%252Flink_account_callback%26client_app_id%3D12345%26fi_description%3Dsome%2520name%26promotable_user_id%3D1
The complete base string, combining steps a - d and e:
GET https://ads.twitter.com/link_managed_account&callback_url%3Dhttps%253A%252F%252Fmanagingpartner.com%252Flink_account_callback%26client_app_id%3D12345%26fi_description%3Dsome%2520name%26promotable_user_id%3D1
Using the hmac-sha1 algorithm we will sign this with the word “secret” as the key. The result is Base64 encoded, and presented without the final “\n” (steps 2 and 3): KBxQMMSpKRrtg9aw3qxK4fTXvUc=
This signature is then added (percent encoded) to the end of the original url in the signature parameter (step 4):
https://ads.twitter.com/link_managed_account?callback_url=https%3A%2F%2Fmanagingpartner.com%2Flink_account_callback&client_app_id=12345&fi_description=some%20name&promotable_user_id=1&signature=KBxQMMSpKRrtg9aw3qxK4fTXvUc%3D
Signing a partner redirect url (account link request callback) The URL to sign, assuming a GET request:
https://managingpartner.com/link_account_callback?status=OK&account_id=ABC&funding_instrument_id=DEF
This url has the following parameters:
account_id
= ABC
, funding_instrument_id
= DEF
and status
= OK
The base string consisting of http method and url without parameters, steps a - d, looks like:
GET https%3A%2F%2Fmanagingpartner.com%2Flink_account_callback&``
The query string, produced by the substeps of e, looks like:
account_id=ABC&funding_instrument_id=DEF&status=OK
The percent encoded query string looks like:
account_id%3DABC%26funding_instrument_id%3DDEF%26status%3DOK
The complete base string, combining steps a - d and e:
GET https%3A%2F%2Fmanagingpartner.com%2Flink_account_callback&account_id%3DABC%26funding_instrument_id%3DDEF%26status%3DOK
Using the hmac-sha1 algorithm we will sign this with the word “secret” and the twitter user id for which the original link request was made, 1 (promotable_user_id
= 1 from above) as the key, “secret&1”.
The result is Base64 encoded, and presented without the final “\n” (steps 2 and 3): jDSHDkHJIFXpPLVxtA3a9d4bPjM=
This signature is then added (percent encoded) to the end of the original url in the signature parameter (step 4):
https://managingpartner.com/link_account_callback?&status=OK&account_id=ABC&funding_instrument_id=DEF&signature=jDSHDkHJIFXpPLVxtA3a9d4bPjM%3D
Shared Key use / renewal
The signing algorithm should have the ability to repeat itself with multiple keys. This will allow multiple shared keys to be used, and enables cycling shared keys on a periodic basis.
partner_managed_funding_instrument creation
If the fi_description parameter is given, and no existing partner_managed_funding_instrument with the same name exists in the account, a new partner_managed_funding_instrument will be created, and all existing partner_managed_funding_instruments will be paused.
If a partner_managed_funding_instrument with the same name exists, no new one will be created.
Repeated on-boarding flow calls / token refresh
The on-boarding flow can be repeated in case the API access token was lost. The on-boarding flow implementation will require the user is logged in. If the user matches the promotable_user_id, and the associated ads account is found, and everything looks good, the user will be redirected back to the callback url, and the partner can initiate the OAuth flow to obtain an access token.
Non-redirectable error flow
If the account link url is invoked with invalid parameters, the user will be shown a page similar to the one shown in the OAuth flow when invalid or expired parameters are given.
Ongoing updates to the PMFI
Once the advertiser has been onboarded, the funding instrument can be managed using the PUT accounts/:account_id/funding_instruments/:funding_instrument_id endpoint by only the partner who manages it.