I am trying to extract ad wise spend data including metrics like impression,clicks and fields like campaign id, campaign name, ad group id, ad group name, tweet id in a single report every day. Reference below

As per the documentation i don’t find there is a straight forward solution to fetch these data unlike other ad platforms (Adwords, FB, Quora).

I am using python twitter_ads library to achieve this. below are the sample code which generates required metrics. however i couldn’t find the way to fetch other fields like campaign id/name, adgroup id/name through PromotedTweet ids.

    from twitter_ads.client import Client
    from twitter_ads.enum import METRIC_GROUP, GRANULARITY, PLACEMENT
    from twitter_ads.creative import PromotedTweet

    client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
    account = client.accounts(ACCOUNT_ID)
    metric_groups = [METRIC_GROUP.BILLING, METRIC_GROUP.ENGAGEMENT, METRIC_GROUP.WEB_CONVERSION]
    granularity = GRANULARITY.DAY

    start = datetime.strptime('2018-01-24', '%Y-%m-%d')
    end = datetime.strptime('2018-01-25', '%Y-%m-%d')

    active_entities = PromotedTweet.active_entities(account, start, end)

    for i in range(0, len(active_entities), 20):
        ids = []
        for itm in active_entities[i:i + 20]:
            ids.append(itm['entity_id'])

        queued_job = PromotedTweet.queue_async_stats_job(
            account, ids, metric_groups, granularity=granularity, start_time=start, end_time=end)
        job_id = queued_job['id']
        time.sleep(15)
        async_stats_job_result = PromotedTweet.async_stats_job_result(account, [job_id])
        async_data = PromotedTweet.async_stats_job_data(account, async_stats_job_result['url'])
        for itm in async_data['data']:
            print('tweet_id: ', itm['id'])
            for x in itm['id_data']:
                print('impressions:', x['metrics']['impressions'])
                print('spend:', x['metrics']['billed_charge_local_micro'])
                print('clicks:', x['metrics']['clicks'])

I guess if i take top down approach campaign->adgroups->promotedtweet->cost data this can be achievable. However how can i get other data like campaign name, ad group name form this call?
Moreover multiple request for this simple report will definitely hits the API limitation for large account so what’s the ideal way to fetch this report?

Hello @rsganesh,

however i couldn’t find the way to fetch other fields like campaign id/name, adgroup id/name through PromotedTweet ids.

There’s a way to fetch parent entity’s metadata from promoted_tweet id.
For instance, you can pass up to 200 promoted_tweet ids to GET accounts/:account_id/promoted_tweets
endpoint, then you will get their associated parent ids (line_item_id in this case).

so you loop over the response and collect ids then you can pass up to 200 line_item ids to GET accounts/:account_id/line_items endpoint, then again, you will get the metadata of each line_item_id as well as its associated parent ids (campaign_id in this case).

the same thing as above, you can pass up to 200 campaign ids to GET accounts/:account_id/campaigns endpoint, then you will get the metadata of each campaign_id.

That is, you can fetch parent entity metadata with 3 calls as long as returned ids from active entities endpoint are less than 200. And if you can deduplicate ids when you loop over the response then you probably could handle more large response with the same rule.

I understand your concern around rate-limit but with the above solution, what do you think? (or what changes/features could help your situation if that doesn’t help?)

1 Like

Hello @jrsyo,

Thanks for your quick response!

The “line_item_id” that’s what i wanted, naming convention entirely confused/missed.

Your solution on fetching associated meta data by sending 200 entity ids are perfectly fine for limited records like few 100s/1000s.

This would be over kill in case if i fetch data for 90 days in a larger ad account, i wonder how many requests should be made to derive the final expected outcome as every 200 promoted_tweets i should call /line_items and /campaigns endpoints to store it in memory to look up the reference data after fetching metrics with batch of 20 promoted tweets call for each placements. Eventually this become multiple multi level inner calls for every batch.

Or i would first fetch and store the associated entities in some temporary database to look up the data.

These process definitely expensive. Instead ideal solution would be providing report endpoint to download (csv or json) data.

@rsganesh Thanks for your feedback.
We do not have a plan to create additional report endpoint but happy to hear your use case. I understand our Ads Manager UI supports generating excel format report data that includes parent entity’s metadata and you’re trying to achieve something similar to this using the Ads API.

As you originally mentioned “in a single report every day” I thought my solution would work.

Or i would first fetch and store the associated entities in some temporary database to look up the data.
These process definitely expensive.

I like this idea though. It’s better to fetch metadata before making async call in this scenario.
Let’s say, first, you fetch data via the Active Entities endpoint and got 1000 promoted_tweet IDs.
That means you need 5 calls (200 ids * 5 calls) to /promoted_tweets endpoint to get associated line_item_id. But after this operation, the number of line_item_id should be small (~100 ids, for instance) as one line_item_id contains multiple promoted_tweet, usually.

So in this case, you just need 2 additional calls to /line_items and /campaigns endpoint to fetch all the necessary metadata then you can have all information on memory or DB whatever you prefer.

That is, this solution shouldn’t be so expensive, I think.
For instance, I created this PoC that is implemented above: fetching metadata (campaign/line_item) from promoted_tweet_ids · GitHub

Best,
Shohei

2 Likes

Thank you!