Sudden Error 403


#1

Our tool got the following response suddenly starting Sept. 21st (JST) this week.

code: 403
reason: Forbidden
message: unexpected response: #<HTTP::Message::Headers:0x007faf602e1910 @http_version=“1.1”, body_size=0, chunked=false, request_method=“GET”, request_uri=#<Addressable::URI:0x3fd7b0170ff8 URI:https://ads-api.twitter.com/0/accounts/50r4ht/campaigns>, request_query={“count”=>200, “with_deleted”=>“true”}, request_absolute_uri=nil, status_code=403, reason_phrase=“Forbidden”, body_type=nil, @body_charset=nil, body_date=nil, body_encoding=#Encoding:UTF-8, is_request=false, header_item=[[“content-disposition”, “attachment; filename=json.json”], [“content-length”, “97”], [“content-type”, “application/json;charset=utf-8”], [“date”, “Fri, 23 Sep 2016 02:52:57 GMT”], [“server”, “tsa_a”], [“set-cookie”, “guest_id=v1%3A147459917717163294; Domain=.twitter.com; Path=/; Expires=Sun, 23-Sep-2018 02:52:57 UTC”], [“strict-transport-security”, “max-age=631138519”], [“x-access-level”, “read-write”], [“x-connection-hash”, “4e3b58bb02823508936773618b9c6f2f”], [“x-content-type-options”, “nosniff”], [“x-frame-options”, “SAMEORIGIN”], [“x-rate-limit-limit”, “2000”], [“x-rate-limit-remaining”, “1996”], [“x-rate-limit-reset”, “1474600064”], [“x-response-time”, “9”], [“x-transaction”, “005e462a00920593”], [“x-xss-protection”, “1; mode=block”]], dumped=false>

We understand that this error is issued when denying update limits, but is there anyway to tell which of the limits is causing this? If the limit is time-based, how long before it is lifted?

Thanks & looking forward to hearing back.


#2

@nityan: What endpoint are you trying to reach? Could you please provide the request and response bodies, preferably using twurl?


#3

endpoint:
https://ads-api.twitter.com/0/accounts/50r4ht/campaigns

API request:
GET https://ads-api.twitter.com/0/accounts/:account_id
GET https://ads-api.twitter.com/0/accounts/:account_id/campaigns

response:
#<HTTP::Message::Headers:0x007faf602e1910 @http_version=“1.1”, body_size=0, chunked=false, request_method=“GET”, request_uri=#, request_query={“count”=>200, “with_deleted”=>“true”}, request_absolute_uri=nil, status_code=403, reason_phrase=“Forbidden”, body_type=nil, @body_charset=nil, body_date=nil, body_encoding=#, is_request=false, header_item=[[“content-disposition”, “attachment; filename=json.json”], [“content-length”, “97”], [“content-type”, “application/json;charset=utf-8”], [“date”, “Fri, 23 Sep 2016 02:52:57 GMT”], [“server”, “tsa_a”], [“set-cookie”, “guest_id=v1%3A147459917717163294; Domain=.twitter.com; Path=/; Expires=Sun, 23-Sep-2018 02:52:57 UTC”], [“strict-transport-security”, “max-age=631138519”], [“x-access-level”, “read-write”], [“x-connection-hash”, “4e3b58bb02823508936773618b9c6f2f”], [“x-content-type-options”, “nosniff”], [“x-frame-options”, “SAMEORIGIN”], [“x-rate-limit-limit”, “2000”], [“x-rate-limit-remaining”, “1996”], [“x-rate-limit-reset”, “1474600064”], [“x-response-time”, “9”], [“x-transaction”, “005e462a00920593”], [“x-xss-protection”, “1; mode=block”]], dumped=false>


#4

Hey @nityan,

From your latest response it looks like you’re trying to access our deprecated v0 endpoints (note the **/0/**accounts)

Can you try calling the equivalent v1 endpoints and let us know if you’re still experiencing the same issue?

Thanks!


#5

Hi @imit8me,

We just tried replacing it with the v1 equivalents, but we’re still receiving the same error.
(Our Ads API is also upgraded to v1).

By the way, the Twitter docs state that v0 deprecated on June 30th, but our requests were working fine until just last week. Can you think of any other cause?

Thanks!


#6

Hi,

Can you post specific example of the call getting the same error?

In general we expect to see that error for any /0/ paths because of changes made to wind down traffic made to v0 - although we announced June 30 we had been giving some extra time for partners.

You may continue to see error for POST because of having an Analytics Only solution - I want to confirm if that’s what you are seeing now.

Thanks,

John


#7

Hi,

Endpoint:
https://ads-api.twitter.com/1/accounts/18ce53vxdp2/

Not sure if this is related, but we were bumped up to Standard Access around the same time we starting receiving error 403.

Also, could you please elaborate on what you mean by an “Analytics Only solution”? First time I am hearing the term.

Thanks again!


#8

One of the access types to Ads API is that you can only pull stats and cannot do campaign management (Basically POST to create and edit campaigns and creative).

I wouldn’t expect to see you get an error to that endpoint - could you please capture a trace of the exact HTTP call being made or use twurl to repro and paste output? (The latter is usually preferred because it helps us narrow down the issue very quickly)


#9

Thanks for clarifying. I believe you’re referring to the read-only and read/write difference, correct?

Hope this is more uselful:

HTTP::Message::Headers:0x007ff9755de078 http_version=“1.1”, body_size=0, chunked=false, request_method=“GET”, request_uri=#<Addressable::URI:0x3ffcbaaef398 URI:https://ads-api.twitter.com/1/accounts/18ce53vxdp2/>, request_query={}, request_absolute_uri=nil, status_code=403, reason_phrase=“Forbidden”, body_type=nil, body_charset=nil, body_date=nil, body_encoding=#Encoding:UTF-8, is_request=false, header_item=[[“content-disposition”, “attachment; filename=json.json”], [“content-length”, “103”], [“content-type”, “application/json;charset=utf-8”], [“date”, “Tue, 27 Sep 2016 04:48:16 GMT”], [“server”, “tsa_m”], [“set-cookie”, “guest_id=v1%3A147495169692960398; Domain=.twitter.com; Path=/; Expires=Thu, 27-Sep-2018 04:48:16 UTC”], [“strict-transport-security”, “max-age=631138519”], [“x-access-level”, “read-write”], [“x-api-version”, “1.0”], [“x-connection-hash”, “7079003aa94bbf038c2682c8022d6e61”], [“x-content-type-options”, “nosniff”], [“x-frame-options”, “SAMEORIGIN”], [“x-rate-limit-limit”, “2000”], [“x-rate-limit-remaining”, “1999”], [“x-rate-limit-reset”, “1474952596”], [“x-response-time”, “119”], [“x-runtime”, “0.010425”], [“x-transaction”, “0013b2a900bc2372”], [“x-xss-protection”, “1; mode=block”]], dumped=false

The “@” marks have been omitted due to the forum message limit.

thanks again!


#10

Yes that’s read-only vs read-write I was mentioning.

Hi sorry it’s still a little difficult to determine the API call being made, although I see it’s a GET this error could happen because the wrong path is being specified.

You can try to repro the API calls you are trying to do in code via twurl - https://github.com/twitter/twurl

This makes it clearer to us like:
twurl -X GET -H “ads-api.twitter.com” “/1/accounts//”

If you are using either Ruby or Python, you can also try using the official SDKs as you should be able to set them up quickly and test hitting the API from within even an interactive prompt.

My assumption is that you may be hitting a 403 related to retrieving stats, and I want to narrow that down, if you are hitting it for other endpoints too we definitely want to know ASAP.

Thanks,

John


#11

Just some additional info from our side.

We originally applied for read-only access, but due to a previous bug that prevented us from making calling calls, we temporarily set access to “read + write” in the Ads API app permissions tab to adjust for this.

We still have it set to “read + write”- could this be influencing anything?


#12

We tried reproducing it with your recommendations. Please take a look.

Request:
twurl -X GET -H “ads-api.twitter.com” “/1/accounts//”

Response:
{“request”:{“params”:{}},“data”:[{“name”:“ATARA\u5408\u540C\u4F1A\u793E - Yahoo! Japan”,“timezone”:“Asia/Tokyo”,“timezone_switch_at”:“2015-04-19T15:00:00Z”,“id”:“18ce53v5amm”,“created_at”:“2014-02-11T22:00:38Z”,“salt”:“c28f97909dc10a1ab97d7d1b2466ea04”,“updated_at”:“2016-06-17T10:04:25Z”,“approval_status”:“ACCEPTED”,“deleted”:false}],“data_type”:“account”,“total_count”:1,“next_cursor”:null}


#13

That’s actually a successful response - there may be a problem with your code hitting a certain path, could you please investigate which calls are failing and compare to what you see from twurl?

To post a job to analytics from twurl it’s something like:
Mimic example call from https://dev.twitter.com/ads/reference/1/post/stats/jobs/accounts/%3Aaccount_id

twurl -H ads-api.twitter.com "/1/stats/jobs/accounts/98spr" -X POST -d "entity_ids=43gk6&entity=CAMPAIGN&end_time=2016-02-01T17:00:00Z&granularity=HOUR&metric_groups=BILLING&placement=ALL_ON_TWITTER&start_time=2016-02-01T15:00:00Z&segmentation_type=GENDER"

To get the data from this job you must ping the job_id on separate endpoint https://dev.twitter.com/ads/reference/1/get/stats/jobs/accounts/%3Aaccount_id and then download a gz file and uncompress it - so it probably would be clear if you had developed this functionality. We mainly want to ensure that you are calling /1/stats/jobs/accounts because you would get 403 forbidden if you are calling /0/stats/jobs/accounts here.

Thanks,

John


#15

Hey, just an update from our side - we identified an issue where POST to the jobs analytics endpoint was being incorrectly denied with 403 Forbidden for read-only App IDs. The fix for this should be released within the next day or two.


#16

We expect these issues to be fixed now, so it gets noticed quickly please go ahead and post a new thread if any sort of 403 is still happening for you.


#17