How to upload tailored audience list?



Edit: I just realized documentation mentions a whitelist. Is there any way to check if my app is whitelisted?

This is the request I tried (taken from here

twurl -t -H /1.1/ton/bucket/ta_partner/ -X POST -A "Content-Type: text/plain" -A "Content-Length: 12" --data ""


opening connection to
starting SSL for
SSL established
<- "POST /1.1/ton/bucket/ta_partner/ HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 14\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: OAuth gem v0.4.7\r\nAuthorization: OAuth oauth_consumer_key=\"***\", oauth_nonce=\"***\", oauth_signature=\"***\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1437406132\", oauth_token=\"***\", oauth_version=\"1.0\"\r\nConnection: close\r\nHost:\r\n\r\n"
<- ""
-> "HTTP/1.1 403 Forbidden\r\n"
-> "connection: close\r\n"
-> "content-length: 0\r\n"
-> "date: Mon, 20 Jul 2015 15:28:54 GMT\r\n"
-> "server: tsa_a\r\n"
-> "set-cookie: guest_id=v1%3A143740613433381487;; Path=/; Expires=Wed, 19-Jul-2017 15:28:54 UTC\r\n"
-> "strict-transport-security: max-age=631138519\r\n"
-> "x-connection-hash: 3a3d8a118a36d5e51a775e02e4b63d78\r\n"
-> "x-rate-limit-limit: 50\r\n"
-> "x-rate-limit-remaining: 49\r\n"
-> "x-rate-limit-reset: 1437407034\r\n"
-> "x-response-time: 9\r\n"
-> "x-tsa-request-body-time: 514\r\n"
-> "\r\n"
reading 0 bytes...
-> ""
read 0 bytes
Conn close

As you can see I received an HTTP 403 error.
Is there a whitelist to use TON API or am I missing something?


@ulsoz you’re close but there are a few issues with the request.

  1. The ta_partner bucket requires that you set an X-TON-Expires header. You can read more about about that here.

From our TON API documentation:


For Tailored Audiences, please use the bucket name ta_partner.

Note that the ta_partner bucket also requires the X-TON-Expires header to be set with an expiration date up to 7 days from the current date (see the ton-upload example script for more detail). For all other TON API buckets, this header is optional however it’s safe and a good practice to pass this header all the time and buckets that do not require it will simply ignore it.

  1. A Content-Type of application/x-www-form-urlencoded is never permitted in the TON API.

You’re setting the Content-Type correctly, but it looks like you’re using an older version of twurl where it was errantly forcing Content-Type to application/x-www-form-urlencoded on all requests. Ensure you’re running twurl v0.9.3 or higher so that you don’t run into this issue.

gem uninstall --force twurl && gem install twurl -v 0.9.3

Once you have those issues corrected, you should be able to do the following:

twurl -t -H /1.1/ton/bucket/ta_partner -X POST -A "Content-Type: text/plain" -A "X-TON-Expires: Sat, 05 Sep 2015 23:01:50 GMT" -A "Content-Length: 12" --data ""

opening connection to
starting SSL for
SSL established
<- "POST /1.1/ton/bucket/ta_partner HTTP/1.1\r\nContent-Type: text/plain\r\nX-Ton-Expires: Sat, 05 Sep 2015 23:01:50 GMT\r\nContent-Length: 12\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: OAuth gem v0.4.7\r\nAuthorization: OAuth oauth_body_hash=\"ZmqMusMfLNliIT45yUqjwqfwUQ0%3D\", oauth_consumer_key=\"OIDntXZULiYrCzSBq23BQ\", oauth_nonce=\"NdZHTLBog4yXkJ7NUDOMHvzSvXEsRCTgKOiPaNyxeIA\", oauth_signature=\"xNPQBV6Pv8JvoK8Wyj%2BnNfvdGLQ%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1440631051\", oauth_token=\"15678855-Q9DtXWXni83LwkqPcUl3dBkhtr9VgHu02nLKueKMI\", oauth_version=\"1.0\"\r\nConnection: close\r\nHost:\r\n\r\n"
<- ""
-> "HTTP/1.1 201 Created\r\n"
-> "connection: close\r\n"
-> "content-length: 0\r\n"
-> "content-type: text/plain\r\n"
-> "date: Wed, 26 Aug 2015 23:17:31 GMT\r\n"
-> "location: /1.1/ton/data/ta_partner/15678855/qpO2_-TSjGA8rXA.txt\r\n"
-> "server: tsa_a\r\n"
-> "set-cookie: guest_id=v1%3A144063105152928411;; Path=/; Expires=Fri, 25-Aug-2017 23:17:31 UTC\r\n"
-> "strict-transport-security: max-age=631138519\r\n"
-> "x-connection-hash: 68aef5ab65b6e2d72d3f9d020322c43e\r\n"
-> "x-rate-limit-limit: 90000\r\n"
-> "x-rate-limit-remaining: 89999\r\n"
-> "x-rate-limit-reset: 1440631951\r\n"
-> "x-response-time: 13\r\n"
-> "x-tsa-request-body-time: 47\r\n"
-> "\r\n"
reading 0 bytes...
-> ""
read 0 bytes
Conn close


In Simple.txt, I put

twurl -t -H /1.1/ton/bucket/ta_partner -X POST -A “Content-Type: text/plain” -A “X-TON-Expires: Sat, 26 Nov 2016 23:01:50 GMT” --file Simple.txt
opening connection to
starting SSL for
SSL established
<- "POST /1.1/ton/bucket/ta_partner HTTP/1.1\r\nContent-Type: multipart/form-data, boundary=“00Twurl129918792308398455lruwT99”\r\nX-Ton-Expires: Sat, 26 Nov 2016 23:01:50 GMT\r\nAccept-Encoding: gzi
p;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: /\r\nUser-Agent: OAuth gem v0.5.1\r\n

-> “HTTP/1.1 400 Bad Request\r\n”
-> “cache-control: no-cache\r\n”
-> “connection: close\r\n”
-> “content-length: 0\r\n”
-> “date: Tue, 22 Nov 2016 07:10:15 GMT\r\n”
-> “server: tsa_b\r\n”

Can someone help to give the correct query?



I go to the file above, and comment out the multipart_body for ‘file’, and also the hard setting ‘request.content_type’, and run below command, seems like OK…

// oauth_client.rb file

def perform_request_from_options(options, &block)
request_class = METHODS.fetch(options.request_method.to_sym)
request =, options.headers)

  if options.upload && options.upload['file'].count > 0
    boundary = "00Twurl" + rand(1000000000000000000).to_s + "lruwT99"
    multipart_body = []
    file_field = options.upload['filefield'] ? options.upload['filefield'] : 'media[]' {|key, value|
      multipart_body << "--#{boundary}\r\n"
      multipart_body << "Content-Disposition: form-data; name=\"#{key}\"\r\n"
      multipart_body << "\r\n"
      multipart_body << value
      multipart_body << "\r\n"
    options.upload['file'].each {|filename|
      #multipart_body << "--#{boundary}\r\n"
      #multipart_body << "Content-Disposition: form-data; name=\"#{file_field}\"; filename=\"#{File.basename(filename)}\"\r\n"
      #multipart_body << "Content-Type: application/octet-stream\r\n"
      #multipart_body << "Content-Transfer-Encoding: base64\r\n" if options.upload['base64']
      #multipart_body << "\r\n"
      # need to read in binary
      file =, "rb")
      if options.upload['base64']
        #enc = Base64.encode64(
        enc = Base64.encode64(
        multipart_body << enc
        #multipart_body <<
        multipart_body <<
    #multipart_body << "\r\n--#{boundary}--\r\n"
    request.body = multipart_body.join
    #request.content_type = "multipart/form-data, boundary=\"#{boundary}\""
  elsif request.content_type &&