Search API Connector Documentation


Import Facebook Ad Data to Google Sheets

In this guide, we’ll walk through how to pull Facebook ad data from the Facebook Marketing Insights API directly into Google Sheets, using the API Connector add-on for Google Sheets.

There are 2 ways to connect to the Facebook Ads API:

  • Preset “Connect” button (OAuth) premium
  • Personal access token. Please check the appendix for detailed instructions to retrieve your token.


Before You Begin

Click here to install the API Connector add-on from the Google Marketplace.

Part 1: Connect to the Facebook Ads API

To begin, we’ll initiate the connection to the Facebook Ads API.

  1. Open up Google Sheets and click Add-ons > API Connector > Manage Connections.
  2. In the list of available connections, find Facebook Ads and click Connect.
  3. You will be directed to Facebook and asked to approve the connection. Click Done.
  4. You’ll then be returned to your Google Sheet, and can verify that your Facebook Ads connection is active in the Connections screen.

Part 2: Create a Facebook API Request URL

For our first request, let’s get some basic data about your Facebook ads account.

  • API root:
  • Endpoint: /v12.0/act_YOUR_ACCOUNT_ID/insights (Get your account ID as described here)

Putting it together, we get the full API Request URL:

Just substitute in your own account ID. (If you use the preset Facebook Ads connection, API Connector will automatically route requests to the most recent version when the version changes.)

Part 3: Pull Facebook API Ad Data into Sheets

Now let’s enter that URL into API Connector and import our first set of data.

  1. Back in the Create Request interface, enter the Request URL we just created above.

  2. Under OAuth, choose Facebook Ads from the dropdown menu. You should see a badge saying “Connected”.
  3. We don’t need any headers so just leave that section blank.
  4. Create a new tab and click ‘Set current’ to use that tab as your data destination.
  5. Name your request and click Run. A moment later you should see summary ad stats populate your Google Sheet. By default, without additional parameters the FB Advertising API will return impression and spend data for the last 30 days.

Part 4: More Example API URLs

Facebook’s API is large and complex, with many different endpoints. The cool thing about querying the API directly is that you can get ANY of the data they provide, but it can require a little digging to get exactly what you want. Here are some resources:


  • The example APIs below. Check out the examples first to get an idea how it works.
  • Mixed Analytics’ handy Facebook URL builder. This is the easiest way to create your request URLs.
  • While in the add-on, you can also query API Connector’s API Library (just search for “Facebook Ads”) to easily pull up many sample URLs.
  • If you want to get more technical, this blog article contains additional examples and information about the API.
  • And, of course, Facebook’s official documentation.


  • Key metrics (reach, impressions, clicks, CPC, and spend) for the past 30 days:,impressions,clicks,cpc,spend

  • Key metrics for the past 30 days, broken down by age and gender:,impressions,clicks,cpc,spend&breakdowns=["age","gender"]
    fb-ads-img26The documentation contains a list of available breakdown dimensions and breakdown combinations.
  • Key metrics for the past 30 days, for each day:,impressions,clicks,cpc,spend&time_increment=1
    fb-ads-img20The time_increment parameter lets you choose how to slice up the results. Options include time_increment=monthly, time_increment=all_days, or time_increment={any number from 1-90}.
  • Key metrics for a specific time period, for each day:,impressions,clicks,cpc,spend&time_increment=1&time_range={"since":"2020-08-01","until":"2020-08-31"}
    If you prefer to use a variable time period, you can either use Facebook’s date_preset parameter, or reference cells containing dynamic dates in your API request URL.
  • Key metrics for a specific time period, for each day and campaign name:,reach,impressions,clicks,cpc,spend&time_increment=1&time_range={"since":"2020-08-01","until":"2020-08-31"}&level=campaign

  • Key metrics for the past 7 days, for each day and by account name, campaign ID, campaign name, adset ID, adset name, ad ID, ad name, and account currency:,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,account_currency,reach,impressions,clicks,cpc,spend&time_increment=1&level=ad&date_preset=last_7d
    The date_preset parameter lets you choose your reporting period. Options include date_preset=today, yesterday, this_month, last_month, etc. A full list is available in the documentation. It will be ignored if the time_range parameter is used.

  • Key metrics for the past 30 days, including conversions/actions (see more about getting conversion data in part 5). May 2021 update: the &use_unified_attribution_setting=true parameter has been added to account for iOS14-related attribution changes (info).,reach,impressions,clicks,cpc,spend&use_unified_attribution_setting=true

    Note: this request was run in “compact” mode to make it easier to read the list of actions. The “single row” report style would display each action in its own column.

  • Ad status (active, paused, deleted, etc):,id,ad_review_feedback,effective_status,updated_time&limit=1000
    Note: this final “Ad status” request pulls from the FB Ads API rather than the FB Insights API. The FB Ads API uses a different URL structure, and requires UNIX timestamp filters, e.g.,id,ad_review_feedback,effective_status,updated_time&limit=1000&filtering=[{'field':'updated_time','operator':'GREATER_THAN','value':'1616025600'}, {'field':'updated_time','operator':'LESS_THAN','value':'1629590400'}] or,id,effective_status&filtering=[{field: "effective_status",operator: "IN",value: ['ACTIVE']}]&limit=1000

Part 5: Understanding Conversion / Action Data

Facebook’s API treats conversions as a type of “action”, and you retrieve them by including fields=actions in your query, as shown in the conversions URL example above. Actions will automatically be returned with their action count (the number of times the action occurred). If you would like to also retrieve the value of an action, e.g. a purchase value, you need to also request the action_values field like this: fields=actions,action_values.

The response isn’t that convenient as Facebook will return ALL of the actions they’ve tracked on your site or app, along with the action count. This is an abbreviated list of the actions tracked by Facebook (Source:

  • offsite_conversion.custom.: Custom Conversions defined by the advertiser
  • offsite_conversion.fb_pixel_add_payment_info: Adds Payment Info
  • offsite_conversion.fb_pixel_add_to_cart: Adds To Cart
  • offsite_conversion.fb_pixel_add_to_wishlist: Adds To Wishlist
  • offsite_conversion.fb_pixel_complete_registration: Completed Registration
  • offsite_conversion.fb_pixel_custom: Custom pixel events defined by the advertiser
  • offsite_conversion.fb_pixel_initiate_checkout: Initiates Checkout
  • offsite_conversion.fb_pixel_lead: Leads
  • offsite_conversion.fb_pixel_purchase: Purchases
  • offsite_conversion.fb_pixel_search: Searches
  • offsite_conversion.fb_pixel_view_content: Views Content
  • onsite_conversion.flow_complete: On-Facebook Workflow Completions
  • onsite_conversion.messaging_block: Blocked Messaging Conversations
  • onsite_conversion.messaging_conversation_started_7d: Messaging Conversations Started
  • onsite_conversion.messaging_first_reply: New Messaging Conversations
  • onsite_conversion.post_save: Post Saves
  • onsite_conversion.purchase: On-Facebook Purchases
  • outbound_click: Outbound Clicks
  • photo_view: Page Photo Views
  • post: Post Shares
  • post_reaction: Post Reactions
  • rsvp: Event Responses
  • video_view: 3-Second Video Views

This means that when you run your “fields=actions” request, the Facebook API may return a lot of data about conversions you’re not interested in. Therefore, you will usually want to include some type of filtering. The next section has information on that.

Part 6: Handle Filtering

If you want to filter for specific actions, e.g. purchases, you can do so with the ‘filtering’ parameter, like this:,reach,impressions,clicks,cpc,spend&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]

If you’re using the IN operator, you can include multiple conditions like this:

&filtering=[{field: "action_type",operator:"IN", "value":["offsite_conversion.fb_pixel_purchase","offsite_conversion.fb_pixel_add_to_cart"]}]

To combine multiple filters for different fields, e.g. both a specific campaign and a specific action type, include them in the “filtering” array as a comma separated list. Facebook’s documentation isn’t very clear on this point, but it seems campaign names and ID filters need to be evaluated as a string rather than in an array, like this:

&filtering=[{field: "",operator:"CONTAIN", value: '123456789'},{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]

To filter for custom conversions, open up FB Business Manager, click Events Manager, then click Custom Conversions in the lefthand sidebar. You’ll see a list of custom conversions and their IDs. Substitute in that ID, like offsite_conversion.custom.398028550584411 instead of offsite_conversion.fb_pixel_purchase.

Part 7: Sort Data

Facebook allows sorting of data using the sort parameter. You enter the field name you’d like to sort on, and then append “_ascending” or “_descending” to specify the sort order (the default sort order is ascending). For example, to sort data in descending order of spend amount, you would append the following to your URL:


If you’re sorting on actions, you would sort by action type using the syntax sort=["actions:<action_type>"]. For example, to sort data in ascending order of cart adds, you would append the following to your URL:


Part 8: Set Column Order

The Facebook API doesn’t return fields at all when they don’t contain any data. So to make sure your columns line up between pulls, please open the Field Editor and select the fields you’d like to show in your sheet. This will ensure that your data stays fixed in place.

For actions, it’s a bit more complicated as Facebook’s API lists each conversion under the “actions” field. Therefore, if you’re requesting multiple conversions at once, you’ll probably need to do one of the following:

  • split actions into separate requests, or
  • use Sheets functions like VLOOKUP and QUERY to extract just the actions you want, or
  • restructure the data with a snippet of JMESPath (paid feature). The following JMESPath would create a report with the following fields fixed in place: campaign_id, campaign_name, unique_clicks, spend, cart_adds, purchases, date_start, date_stop
data[*]. {campaign_id:campaign_id, campaign_name:campaign_name, unique_clicks:unique_clicks, spend:spend, cart_adds:actions[?action_type=='offsite_conversion.fb_pixel_add_to_cart'].value|[0], purchases:actions[?action_type=='offsite_conversion.fb_pixel_purchase'].value|[0], date_start:date_start, date_stop:date_stop}

Part 9: Handle Pagination

  1. By default Facebook limits the number of results in a single response (usually to 25 records) as described here. To get more records, you can add the ‘limit’ parameter to the end of your URL, like this:,impressions,clicks,cpc,spend&limit=1000

  2. There seems to be an undocumented limit of 5000, so if you need more records after that, you can loop through them using pagination handling (paid feature).
    • API URL: enter your request URL as usual, making sure to include limit=5000
    • Pagination type: cursor
    • Next token parameter: after
    • Next token field: paging.cursors.after
    • Number of pages: enter the number of pages you’d like to fetch


Part 10: API Request URL Builder (NEW)

This is a convenient tool for easily building Facebook API request URLs as shown below. Just select your dates and parameters.

Once you’ve constructed your URL, you can copy and paste it into API Connector’s request URL input field. Here’s the link: Facebook API Request Builder

Part 11 [Business Plan]: Get the Facebook Ads Report Pack

Note: this report pack makes use of JMESPath filters and API Connector’s Facebook Ads OAuth2 connection, so you’ll need a paid Business account with API Connector for it to work (or install API Connector for a free trial).

The Facebook Ads report pack is a pack of pre-built report templates to get you started. All you need to do is enter your own Facebook account ID to populate the reports with your own data. The report pack includes the following:

  • Overview: A summary overview of key metrics
  • Campaign Data: A report showing all your campaigns, with key metrics including impressions, frequency, clicks, spend, purchases, etc.
  • Monthly Data: A report showing a summary of key metrics broken out by month
  • Device Data: clicks and impressions by device
  • Demographic: clicks and impressions by age and gender

Here is the link (click File > Make a Copy to get your own copy).

Appendix: Connect with a Facebook API User Access Token

This section is provided as an alternative to the method described above. Instead of clicking Facebook Ads in the Connections manager, you will retrieve and refresh your token yourself every 2 months.
  1. Begin by navigating to, and click My Apps.
  2. Click Add a New App.
  3. Facebook will ask you who is using your app. Choose “Manage integrations for your business” and click Next.
  4. Now choose an app type of Business and click Next.
  5. Finally, enter your app details. You can name your app anything as long as it doesn’t include terms related to Facebook. Click Create App.
  6. You’ll be directed into your Developer dashboard. Under the heading “Add Products to Your App”, scroll down to Marketing API and click Set Up.fb-ads-img5
  7. On the left sidebar, you’ll now see Marketing API listed under Products. Click Tools.
  8. This will produce a screen where you can select your token permissions. All the example API requests in this article use the “ads_read” permission, which allows you to read ads reports from the Ads Insights API for ad accounts you own or have been granted access to by the ad account owner. Click Get Token.fb-ads-img7
  9. You’ll now see your access token. Copy it down and keep it safe as they won’t show it again. Congrats, you can now access the Facebook Advertising API!
  10. Now that you have your token, you can use it by appending access_token=YOUR_ACCESS_TOKEN to any API URL, e.g.,cpc,spend&access_token=YOUR_ACCESS_TOKEN. Since you’re manually including a token, leave OAuth2 authentication set to None.
This access token will expire in 2 months. Once it expires, go back to your Developer Dashboard, select your app, click Tools, and get a new token. Repeat this process each time your token expires. To view the status and expiration date of a token, you can paste it into Facebook’s Access Token Debugger tool.

Previous Import Etsy Data to Google Sheets
Next Import Facebook Leads to Google Sheets

209 thoughts on “Import Facebook Ad Data to Google Sheets”

  1. Great article! I’m looking to add lead events from the pixel in mine, and I’ve found the documentation for it (action_type and offsite_conversion.fb_pixle_lead) but I don’t know how to add this to what I have so far:{account ID}/insights?date_preset=yesterday&level=ad&fields=campaign_name,adset_name,ad_name,reach,impressions,spend,inline_link_clicks,inline_link_click_ctr,cost_per_inline_link_click&access_token={access token}

    • It should be the same pattern as the example above that filters for purchases. Something like this:{account ID}insights?date_preset=yesterday&level=ad&fields=campaign_name,adset_name,ad_name,reach,impressions,spend,inline_link_clicks,inline_link_click_ctr,cost_per_inline_link_click,actions&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_lead']}]&access_token={access token}

  2. Is there a way how to get the daily breakout of performance and show the corresponding day for the data in each row? Right now I have:{account}/insights?time_range={"since":"2020-03-01","until":"2020-03-31"}&level=ad&fields=account_name,campaign_name,adset_name,ad_name,account_id,campaign_id,adset_id,ad_id,reach,impressions,spend,inline_link_clicks,inline_link_click_ctr,cost_per_inline_link_click,actions&filtering=[{field: "action_type",operator:"IN", value: ["lead"]}]&access_token={access token}

    This above request is working however, I am not able to pull in the specific date of each row (ad performance for a specific day within the time range), I only have date_start, date_stop (the first and last days of the whole time period).


  3. Hi, Thanks for the tutorial, very nice! Have a few questions that you might have time to answer… First of I have:,account_name,campaign_name,adset_name,ad_name,account_currency,impressions,reach,conversions,clicks,conversion_values,ctr,cpc,cpm,cpp,cost_per_conversion,spend,social_spend&access_token=

    However, I don´t get the fields Conversions, Conversion_values, cost_per_conversion to display any value. Any idea?

    Secondly, the data from the following fields looks very wierd. Have tried to work with different formats but it still doesn’t make sense. Any idea?

    data » ctr data » cpc data » cpm data » cpp data » spend
    8307.28.00 10121.09.00 11354.04.00 10961.36.00 138.25.00


    • conversions isn’t a field like impressions and clicks etc. Simple fields are listed in the documentation as “string” or “numeric string” etc, while conversions is followed by a link to “list-AdsActionStats“. If you click that link you’ll find information on pulling in conversions. (you can see some examples above in the section on filtering for specific actions.)

      I’m not sure about your weird cpc/cpm data, in my own tests those fields come through fine. What does the data look like when you’re logged into FB Ads Manager? If it’s OK there, I’d check if it’s related to the locale of your spreadsheet, since that can affect how commas and periods get processed. You can change your locale by navigating to File > Spreadsheet Settings > Locale. Try setting it to United States and see if that helps.

  4. Great article! Would it be unwise to use this to pull in info from two different fb users? I’m thinking it might not be a good idea to show facebook a link between the two separate users/accounts so they don’t suspect something fishy is going on? Could they know two APIs are linked to the same Google sheet??

    • I don’t really have any idea what Facebook is looking at, or if they even can tell that the API is being pulled from a Google Sheet, but I would be very surprised if this is an issue. Many agencies & companies work with multiple brands and accounts, so it’s totally normal to bring data from separate FB accounts into the same sheet.

  5. This is amazing! Thanks so much – do you know if it is possible to pull in multiple actions and also action values? I’m looking to pull in Link Clicks, ViewContent, AddToCart, InitiateCheckout and Purchases, along with Purchase Value.

    Also – is there a limit to the size of the request coming back that can be handled? I’ve tried using the date range last year to date (split by day) and this works at the overall level, but when I try and break this down by campaign as well I get an “unknown error” and not sure if this is due to the size of the request that’s coming back (I’m not using any pagination, just setting the limit to a super high value so I get all the info in one sheet).

    • Sure, you can get multiple actions just by leaving off the filter condition, like this:
      I suggest switching to the compact report style, it makes the output a bit easier to read.

      If you want purchase value, you’d include the field action_values, e.g. &fields=actions,action_values.

      Facebook does have limits on the size of the request, but I don’t think that’s the case here since the API usually returns a useful error message when their limits are hit. I just searched online for information about the “unknown” error, and found some related bug reports and some people saying it’s related to including the “likes” field in your requests. You can check as well, but you may need to just experiment with your request parameters until you get a working response.

  6. Ana I need your helpppp Please
    I want to have a sheet for every single campaign on fb ads, but i can’t because it writes me all the campaigns in a single sheet. Secondly I really need the conversions number and conversion cost but i really can’t add them. Thank you very very much for this work.,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,account_currency, impressions,reach,clicks,ctr,cpc,cpm,cpp,spend,social_spend&access_token=XXXXXXXX

    • Here I am! 😀 If you want to get campaign data into individual sheets, you should create multiple requests, each one filtering for the campaign ID. Like this:,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,account_currency,actions&access_token=XXXXXXXX&filtering=[{field: "",operator:"IN", value: ['23842750602790045']},{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]
      You can get all your campaign IDs by first running the above request without the filtering parameter.
      The “actions” field shows all conversions. The example above shows the actions field filtered for just purchase conversions.

      • Thank you very much ana. I’m sorry but I just can’t create the code that shows me the conversions (in a cell) and the conversions cost (in another cell). In fact if i use “access” it gives all the results in one cell and I can’t analyse them with sheets’ formula. (really sorry but I am not a developer… I think you understand it ahaha)

      • Ah ok, I included all the metrics/breakdowns from the URL in your question, but if you just want a simple cost + conversions by campaign, then you can use something like this instead:,campaign_name,spend,actions&access_token=YOUR_TOKEN&filtering=[{field: "",operator:"IN", value: ['23842750602790045']},{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]
        When I run that, it produces a simple report with just campaign ID, campaign name, spend, conversions, and date. Can you please check if that works better for you?

    • Hi, thank you for reading my site. I’m afraid I’m not sure what you mean by URL parameter, do you mean the parameters that go on the end of your ad URLs? I don’t know if FB provides that, the only thing I see related to URLs is the action_destination breakdown, which they describe as “The destination where people go after clicking on your ad.” You can pull that field like this:

      • Yes sorry for the confusion. I mean the url parameters that go at the end of your website link when someone clicks your ad. They are called “url_tags” as referenced here

        Note I keep getting “No Breakdown” when I try your code above. When I replaced action_destination with action_device I get a HTTP ResponseCode 500 (internal error) which is weird because, unless I read the docs wrong, that is another option I can use for action_breakdowns. Any ideas? 🙂

      • I tested based on that documentation and this successfully pulled in the url parameters, can you please try it and see if it gets what you’re looking for?

        I’m not sure about your “no breakdown” error, I just retested and that request URL still worked for me.

  7. Hello dear Ana, Tahnk you so much of this Topic that helped me so much !
    I’m wondering if you have any idea about the API Url to use to generate a report that includes the spending per day per campaign?
    Also, I’d like to know if there is a way to automate for a daily update and keep the previous data stored (yesterday’s for example)

    Thanks you in advance

    • You can choose your metrics from the fields listed in the documentation. If you’re looking for information on tracking specific actions on your site like purchases, you can include something like,cost_per_action_type&access_token=TOKEN. (add a filter or switch to compact mode to make it easier to read)

  8. Hi Ana and great site! I’ve been playing around the API Connector and it’s been working great but when I tried to add any information about ad sets, ad ids, etc, it seems to completely ignore it. Much appreciated!,clicks,adset_id,adset_name,ad_id,ad_name,spend&time_increment=1&access_token=

    • Also Ana, what I would really like to track are results and it seems like offsite_conversion is specifically what I need but there seems to be a custom number attached to each event. Not sure if that can be had. link_click would be helpful in place of offsite_conversion if that’s not available. Cheers!

      • That sounds like a custom conversion. One of the example URLs is a request for “offsite_conversion.fb_pixel_purchase” (number of purchases), and the only number returned is the number of purchases. Is that what you’re looking for?

    • Thank you! Your request is missing the parameter &level=ad, so that’s why it won’t work. You’ll need to include that parameter if you’re pulling ad-level metrics like ad ID and name.

  9. Thanks Ana! I thought all of my offsite conversions had custom numbers but there are actually only two types: offsite_conversion.custom.2384461294947489 or offsite_conversion.custom.410251349618741. So the question is, can the API Connector show me my daily count of offsite conversions? Thanks again!

    • Yep, you need to add the time_increment=1 parameter.
      So the whole thing would be like this:[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]&access_token=token&time_increment=1

  10. Hello Ana, I have joined the family for a week now, so far has been so great! Thanks!
    However, there’s one thing about this Facebook api bugs me. The time zone is always in GT-8 time zone, and I’m in Auckland (GT+12), how can I convert the time(data » date_start) and date to my local time?


    • Hi James! I’m glad you like API Connector 🙂 It’s rather hidden, but Facebook’s documentation says “We report ad insights data in the ad account’s timezone.” Therefore, please check the timezone your ad account is set to. You should be able to view that at this URL:
      The default is GMT-8 (Pacific time), so this is probably the reason you’re seeing that time zone from the API. If you have admin access to the FB Ads account, you can change that value to your local time.

  11. Hi, how much would it cost for you to set this up for me? We’re currently considering Supermetrics / / Integromat as a software stack but we’re looking to avoid these software applications completely by pulling the data directly from Facebook’s API. Please email me with a quote if you can help, thank you very much!

  12. Hi Ana,

    Thank you so much for this documentation! It really helps.

    I just have one thing to raise: Is this realtime data that gets displayed on Sheets or is there an auto update? If so, how often does the update happen?

    Thank you so much again!

    • Hi Alex! Thank you for the comment, I’m glad you like the article.
      The data is up to date at the moment you pull it, and you can run the request manually at any time to get newly refreshed data. Alternately you can set up scheduling (paid feature) to run the requests automatically on a schedule. Please let me know if that answers your question.

  13. hi there, I followed your guide and the integration was super cool and worked fine for the last couple months. Today, however, I keep getting server error 400 when I send a new API. What could that be?

    • Hi there, a 400 error generally means there’s an error with how you’ve entered the request (info). Since the error just started, it’s likely related to an expired token. If you click ‘show response’ in the footer of API Connector, you should be able to see the exact error message from Facebook.

  14. Hi Anna,

    thanks so much for the detailed explanation. I have one issue, which I can’t solve with google.
    The format of numbers is very weird.

    CTR in FB-ads-manager is 5,76%. In Google Sheets it’s 5.781.521
    Costs in FB-ads-manager is 78,37€. In Google Sheets it’s 78.37

    Language of sheets is german.
    I already tried to change the format, but nothing helped.

    Do you know the solution to this?


    • Someone above had this issue too. I’m not sure but I think it’s related to the locale of the sheet. Can you please try changing it to the United States to see if it helps? The setting is located under File > Spreadsheet Settings > Locale.

      • Oh, no worries, I didn’t expect you to have seen it. And that commenter never responded to say if it worked or not, so I wasn’t sure, haha. Thank you for coming back with an update!

  15. Hi Ana,

    I only need specific regions which got conversions for this month. I tried; but it is not working for me.

    Please check the below URL:['28d_click','28d_view']&action_report_time=conversion&date_preset=this_month&fields=actions,action_values&time_increment=1&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]&level=campaign&access_token=XX

      • Hi Ana,

        I am trying to add region field in the URL so that I can get revenue details regionwise.

        E.g. when I am using this tag – time_range={"since":"2020-07-01","until":"2020-07-01"}&action_attribution_windows=['28d_click','28d_view']&action_report_time=conversion&fields=campaign_name,actions,action_values&time_increment=1&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]&level=campaign

        I only get information about orders and its value; but I also information about from Which region I got that order.

        Please help.

      • Your new URL above seems to have some problem unrelated to region, it gives me an error. But assuming you have a working request URL, you add “region” as a breakdown element, like this: &breakdowns=["region"]. For reference, multiple breakdowns would be added to the array, e.g. &breakdowns=["age","gender"].

  16. Hi Ana,

    I’m trying to get the following columns to populate:

    Spend, Link Clicks, Impressions, Add to Carts, Checkouts Initiated, Purchases, and Purchase Conversion Value for 1 day click, 7 day click, 28 day click, and 1 day view windows on the ad level by day for the past 7 days. This is the URL I have so far, and it is not working (just says unknown error occurred). Could you help troubleshoot?*****/insights?action_attribution_windows=['28d_click','1d_view','1d_click','7d_click']&action_report_time=conversion&date_preset=last_7d&time_increment=1&level=ad&fields=campaign_name,adset_name,ad_name,impressions,inline_link_clicks,spend,actions&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase','offsite_conversion.fb_pixel_add_to_cart','initiate_checkout']}]&access_token=******&limit=5000

    • The problem seems to be that your request can’t be broken down to such a granular level. It works when I replace level=ad with level=campaign, can you please try that?

  17. Hi Ana,

    I tried this 2 weeks ago and was getting each campaign in a separate row, however now it’s not working and I am only getting all ads data in one single row which is no good. Here’s my query without the identifiers:,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,reach,impressions,outbound_clicks,cost_per_outbound_click,outbound_clicks_ctr,actions,spend&access_token=REMOVED&sort=["campaign_name_ascending"]&limit=1000

    Thank you!

    • Hey Amy, it sounds like you may have inadvertently switched your report style back to the default single-row style.
      Under Output Settings, please click Output options > Report style: compact to see if that resolves the issue.

  18. Hi Ana,

    This is really a great article, which can make Facebook Ads numbers appear on Google Sheet, and it really helped me a lot in my work. I have a question about connecting accounts, can I extract campaign’s data of all accounts in the my Facebook Business Manager through one API request? I hope that campaign spending of all accounts in one Business Manager can be presented on the same sheet. The request URL in this article seems to be designed for a single Ads account using. Was wondering whether you can help me to adjust the requested URL?

    Thank you very much!

    • Thanks, Murphy, I appreciate the nice comment! Unfortunately you can’t pull data from multiple accounts at the same time, as the Facebook API only allows for a single account ID. You would need to duplicate your requests, substitute in different account IDs for each request, and then aggregate them together into a single sheet (you should be able to do that using Sheets functions like VLOOKUP() and QUERY() ).

      • Hi Ana, thanks a lot for this great tutorial. In that particular case – pulling data from multiple ad accounts – will it be necessary to generate one access token for each request, every 2-3 months, or only one access token is needed for my App?

      • Hi Patrice, you only need one access token. It’s tied to the user, so it will provide access to all the accounts that the user — you — has access to.

  19. Hi Ana,

    Thanks for the post. Really helpful.

    I am looking to pull inlcude paused campaigns in my data pull. Do you have an idea on how I can acheive this?

    • Nice, I’m glad it’s helpful 🙂 All campaign types including paused campaigns should be included by default, at least I don’t see anything in the docs indicating that they’re not. Are you seeing something different?

  20. I’ve been looking for something like this product for *soooooooo long*
    I’m sooo happy. really.

    and this tutorial is amazing. and it’s working.

    what can I say? You got yourself a loyal customer.
    keep rockin’

    • Oh, this is a really nice comment, thank you! I’m interested to know whether you were looking for a tool to get FB data specifically, or just for an API connection tool in general.. sent you a message 🙂

  21. hi – super excited about this add on but when I import my FB ad data (append it) it randomly puts it into different columns, making it unusable as an automatic tool for syncing reports (also, because the numbers aren’t distinct I don’t know what order it’s putting the columns in!)

    Any idea why this is happening to me?

    • Hey Rob, this happens because the FB API doesn’t return fields when they contain only null values. So if one of your fields contains data one day, but not the second day, Facebook won’t include it at all on day 2, which shifts around the order of columns.

      To address this, you can limit your requests to pull just the fields that always contain data, you can use a Sheets formula to pull in data to a second sheet with fixed column headers, and/or you can use JMESPath filtering to lock response fields into certain columns regardless of the underlying API response. You can see more detail about this issue here:

  22. From the Facebook Marketing API, how could you get the exact attribute an ad is charging for? in cost_per_action_type it sends me a list, but I don’t know exactly why they are charging me.

    I would appreciate a help with this problem.

    • I’m not totally sure I understand your question, the response should contain each action type and its value. Can you use filtering to get the action types you’re looking for, like this? &filtering=[{field: "action_type",operator:"IN", value: ['mobile_app_install']}]

    • Conversion actions like installs are shown under the “actions” field, so you need to add “actions” to your list of fields and include a filter for the action you’re interested in (if you’re not sure of the action name, then first pull all the actions and add your filter after). The question above this one has an example of that.

      • Thanks for your prompt reply…..

        this is my code:*******/insights?date_preset=this_month&time_increment=1&level=ad&fields=campaign_name,adset_name,ad_name, impressions,reach,clicks,ctr,cpc,cpm,cpp,spend&fields=actions&filtering=[{field: "action_type",operator:"IN", value: ['mobile_app_install']}]&access_token=**************

        it’s not showing the all value filed.

      • That looks all right to me. Facebook doesn’t display null values, could that be the issue? Feel free to share your sheet if you’d like me to take a look (email support at

  23. Hey Ana ! Thanks for the great tutorial.
    I just want to know if I can access Leads of my Facebook ads through this method or not ?
    Is there any way to automate leads from Facebook Ads to Google sheets without using third party integrations like Zapier etc ?

  24. Nice Article, Ana!

    But i am getting the below error.

    {“error”:{“message”:”Invalid OAuth access token.”,”type”:”OAuthException”,”code”:190,”fbtrace_id”:”AsnC2jHPNAav8JXp_7090vx”}}

    Can you pls help me in understanding this?

  25. Hi Ana, I’m really so happy to read this article. It really helps me so much to start get data from Facebook optimize fee in this time.
    Special that your example URL. But when I tried to add more fields is Error or not get data.
    Can you show me how to mix 2 this example:,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,account_currency,impressions,reach,clicks,ctr,cpc,cpm,cpp,spend,social_spend&access_token=YOUR_ACCESS_TOKEN

    And[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]&access_token=YOUR_ACCESS_TOKEN

    Because I wanna get important field as ad_id, ad_name, spend, Post Comments, Messaging Conversation Started, Cost per Messaging Conversation Started, Messaging Replies. Please help me with an example ♥. Thank you, Ana

    • Hi Phuc, you should be able substitute in the specific action type you’re interested in. All possible action types are listed here. So I think it would look like this:,ad_name,spend,actions&level=ad&access_token=YOUR_ACCESS_TOKEN&filtering=[{field: "action_type",operator:"IN", value: ["onsite_conversion.messaging_conversation_started_7d","onsite_conversion.messaging_first_reply","post_reaction"]}]

  26. Hi Ana,

    Great tutorial.

    Everything is working fine, but when i use it for a live campaign the api is not giving the live stats and seems to be only updating once a day?

    I see this when i open ads manager and see different results there than from the api

    Any way around this

      • Hi Henrik, in my own tests the data has always matched, and I’m not aware of any delay between the API and FB Ads Manager. Maybe you’ve found a bug on Facebook’s end, but I’d also double-check that you’ve set your request up with the same exact conditions (metrics, time, attribution window) as your report in FB Ads Manager. In this Stack Overflow post you can see someone else with the same issue you’re having, and they resolved it by changing their attribution windows.

  27. Hi Ana,

    Thank you for this insightful documentation! This really helped with my weekly reporting for the company i work at.

    However, i have trouble to get my conversion data into sheets. We have 3 different custom conversions. I used the template from this blog and tried to change the conversion type, but it doesnt show the right conversions.Right now it only shows purchases, but we don’t use this goal.

    Could you please help me out? Every other metric comes out fine, i only have problems with the conversions. Thanks in advance and i hope to hear from you soon!


    • Hi Jael, you should be able to substitute in the conversion you’re interested in. The entire request would then be something like this:,impressions,reach,clicks,spend,actions&level=campaign&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.YOUR_CONVERSION']}]&access_token=YOUR_ACCESS_TOKEN

      • Hi Ana,

        Thanks for the fast and extensive response! The thing i dont understand is what to fill in at ‘offsite_conversion.YOUR_CONVERSION. Should i replace ‘YOUR_CONVERSION’ with the custom conversion id? Or should it be the name of the conversion? For example the name of the conversion is ‘Registration bootcamp’.

        Thanks again, i hope my explenation is clear!

        – Jael

      • You should replace it with your custom conversion ID. To find your ID, you can open up FB Business Manager, click Events Manager, then click Custom Conversions in the lefthand sidebar. You’ll see a list of custom conversions and their IDs. So then you would substitute in that value, like offsite_conversion.custom.398028550584411

        If you don’t have immediate access to FB Ads Manager, an alternate method is to run this request:'Tokens'!B1+++
        It will return a list of all your conversions and custom conversion IDs, but it won’t include their name. Still, it could work if you only have one or two custom conversions and are able to identify them.

      • Hi Ana,

        Thank you so much, it worked :D. This is amazing. I used the custom conversion id from FB Business manager.

        I have one more question, we have a total of 3 custom conversions, how should the request look like if i want to include all 3 of them?

        Thanks again!

        – Jael

      • woohoo, I’m glad it worked! So, you have two options here:
        1) Run them separately. I think this might be best because the output can get complicated when you’re looking at multiple conversions in a single response.
        2) Run them together. In that case your query would look like this:
        &filtering=[{field: "action_type",operator:"IN", "value":["offsite_conversion.custom.398028550584411","offsite_conversion.custom.123456789","offsite_conversion.custom.987654321"]}]

        You can try the second one and see what you think, and if the output is too complicated try the first one 🙂

  28. Hey,

    This API request I have created starting of this month after running smoothly now it’s throwing error –
    Request failed: The server responded with an error (500) show response
    {“error”:{“code”:1,”message”:”Please reduce the amount of data you’re asking for, then retry your request”}}

    Is there any data limitation I should know about?

    • This error message comes from Facebook itself. FB doesn’t seem to provide any documentation on it, but based on some comments here, their limits aren’t based on specific numbers, but rather on how many resources it takes to get the data. You can reduce the amount of data you’re asking for by using the limit parameter or using date parameters like since and until.

  29. When we create the token manually and copy it for use in the API Connector, where exactly do we put it in the API Connector? I’ve tried a few things and they haven’t worked.

    • Once you have your token, you can use it by appending it to any API URL, like

    • Thanks, I’m glad you like the article. You would just need to run your query twice, once for a 3 day period and once for a 7 day period, like this:
      3 days:,adset_name,spend,actions&level=ad&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]&date_preset=last_3d
      7 days:,adset_name,spend,actions&level=ad&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]&date_preset=last_7d

      That will pull in the raw data to your sheet, and you can then reconfigure it however you like to make it match your desired dashboard output.

      • Hi Ana, Thanks for your reply. But I want to display my conversion column. I use the below URL but display an error.,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,actions&access_token=XXXX&filtering=[{field: "",operator:"IN", value: ['Conversion ID']},{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]


      • Hi Fieza, what does your error message say? That usually identifies the issue.
        Also I don’t see any “level” parameter in your URL. If you’re breaking out data by adset name, you will need to include level=ad.

      • Thanks Anna.

        How I can display my conversion column? I using this request.,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,actions&access_token=XXXX&filtering=[{field: "",operator:"IN", value: ['Conversion ID']},{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']}]

        Is my request wrong? It display “Request processed, no records found”. I’m sure my account and conversion id are right.

      • Hmm, maybe Facebook doesn’t accept an array filter for campaign name. Also your request URL is missing the “level=ad” parameter. Can you please try the following instead, substituting in your campaign ID where it says 1234567? Let me know if this works better.,account_name,campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,actions&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_purchase']},{field: "",operator:"CONTAIN", value: '1234567'}]&level=ad&access_token=XXXX

  30. Hey there,

    Very good article, thank you for making it. I am trying to create an API URL for my Google Sheet reports, but need very specific requirements to get the Facebook data I need. Since my developer skills are not great I was wondering if I might be able to get help with creating a URL with the following requirements:

    – Impressions, Link Clicks, Add To Cart, Initiate Checkout, Purchases, Revenue, Amount Spent, Attribution, 28 Days Click, 7 Day View

    Date Range
    – Lifetime (Broken down by Mon to Sun), Basically being able to see each week’s performance over the lifetime period

    Is this something can be possible to create?

    • Thank you, I’m glad you like the article! You don’t need any developer skills for this, but since your requirements are rather specific and complex, you need to be comfortable reading API documentation to construct your queries. Otherwise, I suggest picking a different tool that doesn’t require working with the API directly (if you search the Google Marketplace for “Facebook” you can find a few).

      With that said, something like this should work to pull in the raw data for your query.,clicks,spend,actions,action_values&filtering=[{field: "action_type",operator:"IN", value: ['offsite_conversion.fb_pixel_add_to_cart','offsite_conversion.fb_pixel_initiate_checkout','offsite_conversion.fb_pixel_purchase']}]&action_attribution_windows=["7d_view","28d_click"]&date_preset=lifetime&time_increment=7&limit=5000

      • Hey Ana,

        Thank you that is exactly what I was looking for!

        The data currently pulls from Friday to Thursday for the 7 day period within the lifetime range. In order to get it to do Mon to Sun would I need to run the request on a certain day of the week? or is there a way to filter the code to make it pull Mon to Sun each time?

      • Good question… I could be wrong, but I don’t see anywhere to specify the week start date when you’re pulling for date_preset=lifetime. If you used the since and until parameters you could choose the day of week you wanted to start on, but only 90 days of data can be pulled when using since and until. So it’s probably easiest to just wait and run this request on a certain day of the week. Alternatively, you could pull it for all days (time_increment=1 instead of time_increment=7) and do your weekly aggregation yourself.

  31. Hi Ana,

    Thank you very much for the article, but I stumble on a problem, can you please point me where i did wrong? By the way, I am not a coder, so it would be very helpful if you explain it in simple terms. Thank you so much 🙂

    I try to add “yesterday” date to the fields, and i use this URL{yesterday},spend,reach,impressions,click

    • Hi Adya, thanks for the message. Date presets aren’t added into the “fields” parameter. Please try the following instead:,reach,impressions,clicks

  32. When I added a JMES Path it accurately organized the data in the correct columns. Except for ‘Spend’, that value is coming back as a blank cell.

    I added a Screenshot and additional info below to help you with answering my question. Thank you in advance for your help with this!


    API URL Path:,frequency,inline_link_clicks,spend

    JMESPath: data[].
    [*] | [0].value,date_start:date_start,date_stop:date_stop}

    • Hi Blake! You don’t need the | [0].value piece of this, that’s only for when you’re adding actions (since actions get returned as an array). Please try this instead and let me know if the results come through as expected.

  33. Hello there!

    2 quick questions:

    Is there a way to add the page name in which the campaigns are set? Cause with 1 Ad Account I have 2 different pages linked in which I’m doing campaigns, so it would be good to know from which pages are the results coming.

    Also, can we see the locations (cities) for the results shown? Cause 1 campaign is set for different locations (one location for each Ad group) and I can’t see which cities are the ones that work better in each campaign.

    • Hey Vaiana, sorry, I’m not sure about adding in a page name, I thought FB ads are just running on Facebook in general, not a specific page. So I think you’ll need to consult their docs for info on that. For location, you would add a breakdown, but I don’t see any way to break it down by city. The closest I see is region, like,impressions,clicks,cpc,spend&breakdowns=["region"].
      You can see more info about breakdowns here:

  34. Hi there,

    I’m trying to export the time of day (viewer’s time zone) as a breakdown but without success. Can you please let me know how to do that?

    • Hi Francesco, please try this:["hourly_stats_aggregated_by_audience_time_zone"]

  35. Hi Ana, I need to extract the spend from every day ever since the ad account has been created, and it should be updated once a day moving forward. And unfortunately, I am stuck.

    • You should be able to get historical data with a query like this:
      Going forward you can just switch your date_preset value to ‘yesterday’ and run it each day.

    • Hi Milica! It is possible, but since Facebook is giving you the “Please reduce the amount of data you’re asking for” error message, you’ll need to split up your request into smaller bits.
      There are several ways you could do this, here is one way you can try:
      Request 1:{"since":"2019-01-01","until":"2020-01-01"}&fields=spend&time_increment=1&limit=500
      Request 2:{"since":"2020-01-01","until":"2021-01-01"}&fields=spend&time_increment=1&limit=500
      (and so on)

      Another method would be to set the limit to something smaller (e.g. limit=500) and then set up pagination handling as described in the article.
      Can you please try and see how it goes?

    • You can add a filter to the end of your URL like this:
      &filtering=[{field: "",operator:"CONTAIN", value: 'your_campaign'}]
      Substitute in your own campaign name where it says your_campaign.

      • Their documentation is very unclear about this, but in my own tests I can only get the CONTAIN operator to work on campaigns. So I think you can only do this if you find a string that both of your campaigns contain. You can also test out some other operators like STARTS_WITH as shown here (all operators are listed under the entry for ‘filtering’).

  36. Hi, I’m Facebook Ads Marketer. I have a question:

    Can I get Data Bill Payment account or invoice payment?

    Because now I used “Sum amount spend” but it not good for charge fee with customer. I wanna get data payment in bill transaction to know exactly Facebook charge fee me and notify customers when the deposit is almost exhausted.

    • Hi there, this page shows how to get invoices from the Facebook API. It says you would send a URL like this:

      However it’s not that easy, since the page also says your account needs a finance role and your connection requires business_management scope, which is not provided by API Connector’s built-in Facebook Ads connection. So you would need to create your own app at, and then add the permissions needed for the invoices endpoint. Hope that helps point you in the right direction.

  37. Hi Ana,

    your API still uses version 8.0 as far as I know.
    I just received a mail from facebook that apps using version 8.0 are not supported after May 2021.
    Do you have any plans to upgrade to version 9.0 or 10.0?

    Thanks for the API! It helps me a lot 🙂


    • Yeah, if your client has provided your account with access to their FB Ads account, you can access their data via FB Ads Manager or the API.

  38. Hello,
    Could you help, please?
    I am pulling data using … &time_increment=1&date_preset=last_7d.
    Today is 03/30. But I am only getting data for the period 03/23 – 03/26. And no data for 03/27 – 03/30

    I have tried … &time_increment=1&time_range={“since”:”2021-03-24″,”until”:”2021-03-30″}
    The same problem – only getting data for the period 03/24 – 03/27. And no data for 03/28 – 03/30

    What could be the problem?

    • I don’t see anything wrong with your request URL (at least the part you’ve shared) so if you aren’t getting data it’s because there is no data matching the conditions of your query. Can you please double check that you’re seeing data for that date range in the FB Ads Manager interface? If so then make sure you haven’t added any filters to your API request URL that would exclude data for those days, e.g. campaign name filters, device filters, action filters etc. It’s also possible that it’s related to attribution since default attribution via the API doesn’t automatically match what you’ve set in FB Ads Manager. If you’ve set an attribution window in FB Ads Manager you would need to explicitly set it in your request URL with a parameter like &action_attribution_windows=['1d_click','1d_view']

      • Thanks for the reply. It still does not work for some reason.

        1) There is data in the FB Ads Manager interface for sure.
        2) I have cut my request to a very simple one, just to be sure that there are no filters.ХХХХХХ/insights?fields=campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,reach,impressions,clicks,inline_link_clicks,cpc,spend&level=ad&time_increment=1&date_preset=last_7d

        3) I have also tried adding attribution window to the requestХХХХХХ/insights?fields=campaign_id,campaign_name,adset_id,adset_name,ad_id,ad_name,reach,impressions,clicks,inline_link_clicks,cpc,spend&level=ad&action_attribution_windows=['7d_click','1d_view']&time_increment=1&date_preset=last_7d

        with ['7d_click','1d_view'] that’s what I have in my campaigns

        If I use … &date_preset=last_3d, it correctly pulls data for the last 3 days

      • Well that’s pretty weird then, if it shows up when you do a last_3d date preset. Maybe it’s just getting cut off by Facebook’s 25 row limit. Can you please add &limit=1000 to the end of your URL and see if it makes a difference?

  39. Hi Ana!

    Thanks for such a helpful resource. I was wondering if you could tell me why I can’t get my date period to extend beyond 30 days. I am using the below script, and no matter what I put into date_preset I can’t get more than 30 days of data.,account_name,campaign_id,actions,reach,impressions,clicks,cpc,spend&filtering=[{field: "action_type",operator:"IN", "value":["offsite_conversion.fb_pixel_purchase","offsite_conversion.fb_pixel_add_to_cart"]}]&time_increment=1&level=campaign&limit=5000

    Thank you!

    • Hi Peter, thanks for the message and sorry you’re having trouble with your request. However, I just tested your request URL and it retrieved the past 90 days of data as expected. Therefore, I don’t think there’s any issue with the request itself, and I’m thinking about what else could be the problem. Do you have more than 5000 rows of data by any chance? Or any JMESPath filter on your request? Do you see more than 90 days of data in FB Ads Manager?

      • Strange…I don’t have more than 500 rows of data, and I do have more than 90 days of data in ads manager. I will look into any JMESPAth filters I may have on my request.

      • Can you also try removing the filtering part of your request to see if that makes a difference? Basically, try to simplify and isolate what could be producing the problem.

Leave a Comment

Table of Contents