The Wayback Machine - https://web.archive.org/web/20160617170552/https://dev.twitter.com/ads/analytics/version-0-analytics

Analytics (Ads API Version 0)

Note: This guide applies to version 0 of the Ads API, which has been deprecated. See our updated Analytics overview for the most current information.

We provide a family of methods for retrieving detailed statistics on the performance of your campaigns. These methods allow you to retrieve both summary and time series data. We have documented some general best practices for consuming our analytics that we recommend all developers read.

Analytics Implementation Details

Billed versus Estimates

billed_charge_local_micro provides a real-time view into the estimated cost of a campaign. After three days, the official billed result will be available with the billed_charge_local_micro and billed_engagements metrics.

All billing stats are generally final within 3 days of the event (~99%), however we do process some spam filtering for up to 14 days from the date of the event.

Please note that spend metrics are not available for dates before 2013-10-10.

Timelines

As soon as stats are available, you are able to retrieve them. The feedback on stats is real-time. These early results are estimates, the stats are finalized after 24 hours, except for spend metrics. Keep in mind that the API rate limit window is 1 minute long, and too-frequent requests against the stats API endpoints will trigger the rate limit. Partners should detect rate limiting and wait for rate limit windows to reset before retrying queries that were throttled.

Data Returned in Time Series

Data is returned for each metric in a time series based on your request of either HOUR (recommended), DAY or TOTAL granularity. That time series could include null values for periods in the series in which Twitter did not collect data for this metric (usually for segmentated data) or for which that metric was invalid for this entity.

Rate Limiting (cost-based)

Analytics utilize a cost-based rate limiting model for all endpoints, similar to our WRITE-based rate limiting. All rate limit windows for analytics are 1-minute windows, rather than 15-minutes. For cost based limiting, we return 5 headers that partners should utilize when measuring the remaining cost and how to respond when rate limited with a HTTP 429 response.

The headers returned for analytics endpoints are:

  • X-Cost-Rate-Limit-Limit: The total cost limit shared across all analytics endpoints, per window, per advertiser.
  • X-Cost-Rate-Limit-Remaining: The cost limit remaining for this window.
  • X-Cost-Rate-Limit-Reset: The time (epoch) that this window will reset. Note that this could be different from the existing X-Rate-Limit-Reset timestamp, but they should generally be consistent.
  • X-Request-Cost: The cost of the request being returned.

Overly Complex Queries

Queries with a time range that is expected to take a significant amount of time to generate will be rejected with a HTTP 400 Bad Request error of the REQUEST_TOO_COMPLEX variety, with a message of This request is too expensive to compute, try a smaller time range.

{
  "errors": [
    {
      "code": "REQUEST_TOO_COMPLEX",
      "message": "This request is too expensive to compute, try a smaller time range"
    }
  ],
  "request": {
    "params": {
    }
  }
}

Specifying Time Ranges

Each of the stats endpoints has a start_time and end_time parameter which can be set to delineate a time range for the stats being requested. start_time must be aligned to the granularity value being requested.

  • TOTAL: start_time can be any value.
  • DAY: start_time must be midnight in the timezone of the account, relative to UTC. For example, if the timezone of the account is America/Los_Angeles during Pacific Time, then the start_date for June 16, 2013 must look like: 2013-06-16T07:00:00Z. It would also be acceptable to specify the timestamp as midnight with the correct offset, for example, 2013-06-16T00:00:00-07:00
  • HOUR: start_time must be an hour without minutes specified, in the timezone of the account relative to UTC. For example, if the timezone of the account is America/Los_Angeles during Pacific Time, then the start_date for 4:00pm, June 16, 2013 must look like: 2013-06-16T23:00:00Z (or equally acceptable, 2013-06-16T16:00:00-07:00.)

end_time, if unspecified, will default to the current time. Currently, end_time is not validated for a particular alignment as per start_time. When dealing with granularity DAY, any end_time that is between start_time+00:00:01 to start_time+24:00:00 will return one day of stats. Any end_time that is between start_time+24:00:01 to start_time+48:00:00 will return two days of stats. And so on. Likewise for granularity HOUR, on a per-hour basis.

Segmentation Reporting

Segmentation reporting allows the retrieval of metrics broken out by the values of a given targeting type. More details on segmentation options can be found at Metrics and Segmentation in Analytics.

Segmentation queries are subject to the same time limits (formerly complexity) as normal reporting. We suggest querying on a shorter time period if you encounter repeated 503 errors.

Example request:

$ twurl -H ads-api.twitter.com "/0/stats/accounts/4cury/campaigns/svth?granularity=DAY&start_time=2013-07-07T07:00:00Z&end_time=2013-07-12T07:00:00Z&metrics=promoted_tweet_timeline_impressions&segmentation_type=GENDER"

{
    "data": [
        {
            "end_time": "2013-07-12T07:00:00Z",
            "granularity": "DAY",
            "promoted_tweet_timeline_impressions": [
                0,
                0,
                1712,
                40,
                0
            ],
            "segment": {
                "name": "Male",
                "segmentation_type": "GENDER",
                "segmentation_value": "m"
            },
            "start_time": "2013-07-07T07:00:00Z"
        },
        {
            "end_time": "2013-07-12T07:00:00Z",
            "granularity": "DAY",
            "promoted_tweet_timeline_impressions": [
                0,
                0,
                2021,
                45,
                0
            ],
            "segment": {
                "name": "Female",
                "segmentation_type": "GENDER",
                "segmentation_value": "f"
            },
            "start_time": "2013-07-07T07:00:00Z"
        }
    ],
    "data_type": "campaign_stats",
    "request": {
        "params": {
            "account_id": "4cury",
            "campaign_id": "svth",
            "end_time": "2013-07-12T07:00:00Z",
            "granularity": "DAY",
            "metrics": [
                "promoted_tweet_timeline_impressions"
            ],
            "segmentation_type": "GENDER",
            "start_time": "2013-07-07T07:00:00Z"
        }
    },
    "segmentation_type": "GENDER"
}