Real-Time Audience API endpoint gives invalid format exception


#1

I’m trying to submit a membership update to real-time audience API endpoint as described in https://dev.twitter.com/ads/audiences/ta-realtime-integration-guide

and always receive this error message “The JSON string format is invalid”, regardless the data sent.

The twurl command used:

twurl -X POST -H “https://ads-api.twitter.com” /1/tailored_audience_memberships --file “group_membership.txt”

The contents of the group_membership.txt file:

[
{
“operation_type”:“Update”,
“params”:{
“membership_type”: “LIST_MEMBERSHIP”,
“advertiser_account_id”:“realID”,
“user_identifier”:“D99E433E9ADA02FB15085BC1DC29EDAA1962C926F187819AA0BBA01E5F1AE54A”,
“user_identifier_type”:“TWITTER_ID”,
“audience_names”:“Membership test”,
“effective_at”:“2016-12-21T00:00:00Z”,
“expires_at”:“2016-12-22T00:00:00Z”
}
}
]

Tried it with --file-field “data”, but no luck.

Please advise how to fix it.


#2

Hey @Andrey

Have you tried using the Content-Type: application/json header when calling this endpoint, as mentioned here ?

Let us know if you’re still seeing issues after using the header.

Thanks!


#3

Hi!

I tried this:

twurl -X POST -H “https://ads-api.twitter.com” /1/tailored_audience_memberships -A “Content-Type: application/json” --file “group_membership.txt”

but still get the same error:

{“errors”:[{“code”:“INVALID”,“message”:“The JSON string format is invalid”}],“operation_errors”:[],“request”:[]}


POST tailored_audience_memberships AND GOT ERROR
#4

Hey @Andrey

Thank you for bringing this up! It looks like this may be an issue with twurl itself and the way it’s reading the file. I was able to send the same JSON data, to the tailored_audience_memeberships endpoint, like so:

twurl_ads -t  -X POST --header 'Content-Type: application/json'  --data '[{"operation_type":"Update","params":{"membership_type": "LIST_MEMBERSHIP","advertiser_account_id":"realID","user_identifier":"D99E433E9ADA02FB15085BC1DC29EDAA1962C926F187819AA0BBA01E5F1AE54A","user_identifier_type":"TWITTER_ID","audience_names":"Membership test","effective_at":"2016-12-21T00:00:00Z","expires_at":"2016-12-22T00:00:00Z"}}]' "/1/tailored_audience_memberships" | jq .
{
  "data_type": "tailored_audience_membership",
  "data": [
    {
      "success_count": 1
    }
  ],
  "request": [
    {
      "total_count": 1
    }
  ]
}

Can you confirm if this works for you?

Thanks!


#5

Yes, passing JSON to a command line works.

Thanks!


#6

Awesome! Please consider marking this thread as resolved!


#7

I’m getting the same issue. Trying to use Python requests oauthlib. I’ve poured over the documentation and can’t find anything. I’ve tried hashing with uppercase

Also, the documented ‘https://ads-api.twitter.com/2/tailored_audience_memberships’ endpoint doesn’t respond.

raw='[{"operation_type":"Update","params":{"membership_type":"LIST_MEMBERSHIP","user_identifier_type":"HANDLE","user_identifier":"b05cfd1f12d82e6cdc18457b6373ba01713b62f02677d3cc49943e735eae7d57","advertiser_account_id":"myid","audience_names":"test"}}]'

res = requests.post('https://ads-api.twitter.com/1/tailored_audience_memberships', headers={'Content-Type': 'application/json'}, auth=OAuth1(...), json=raw)

Any suggestions what I might be doing wrong?


#8

Hey @chet

Thank you for bringing this to our attention. This is currently an issue on our end and we’re actively working towards a resolution. In the meantime, as a potential workaround I would recommend using the same endpoint on v1, i.e.,

/1/tailored_audience_memberships instead of /2/tailored_audience_memberships. We’ll be sure to make an update once we know more.

Thanks!


#9

@imit8me thank you that makes sense–however I’m still getting the “JSON string format is invalid” from the 1.0 endpoint as I documented.

In your experience is there a common point of confusion with the documentation? As you can see from my code sample I’m posting with the content type added as suggested and getting the same issue.


#10

Actually I think I got it. Thanks for the help, and I’ll swap to the 2.0 endpoint when it’s ready.


#11

Hey @chet

Great to hear you were able to resolve the problem. Can you post your solution here in case other folks have the same issue?

Thanks!


#12

The data/json parameters in the requests library were confusing me I think since sometimes it tries to form-encode. Best to let it handle the json serialization. This works for me:

post_data=[{"operation_type":"Update","params":{"membership_type":"LIST_MEMBERSHIP","user_identifier_type":"HANDLE","user_identifier":"b05cfd1f12d82e6cdc18457b6373ba01713b62f02677d3cc49943e735eae7d57","advertiser_account_id":"myid","audience_names":"test"}}]

res = requests.post('https://ads-api.twitter.com/1/tailored_audience_memberships', headers={'Content-Type': 'application/json'}, auth=OAuth1(...), json=post_data)