Klaus Jensen


Have been dealing with Snapchat API for the past few days, and boy is that a terrible API to work with…

When querying the Campaign stats endpoint and want to get stats on a day level, you need to specify start_date and end_date. That makes sense. It also specifies dateĀ format should follow ISO 8601. That is the only sane date format in the world, so great!

I could take you through my frustrating journey of trial and error, talk about how stupid the date handling is, but let’s skip that part and get straight to the solution.

Use ISO 8601 date/time format INCLUDING time zone information (and url encode your values)

That format looks like this, with date, time and timezone.


You need to URL encode it though, or else…


The time zone information HAS TO MATCH the time zone of the ad account, NOT the zone you are in!

How do you find that information?

SnapcHAt Business Interface

Using the Snapchat business interface, go to:

Settings > Ad Accounts > Select Ad Account

Using API

List all organizations for an account:

List all ad accounts for an organization:{organization_id}/adaccounts

Convert that timezone value to a UTC offset.

Whether you get it from API or interface, you need to take that timezone string and look it up somewhere to get the UTC offset (-08:00 in this case).

But wait, what about Daylight Saving Time?

Be aware that Daylight Saving Time (needs to die in a fire, but that’s for another day/rant) WILL affect the current UTC offset!

Failure to account for DST and the effect on UTC offsets will get you this lovely error:

‘Unsupported Stats Query: Timeseries queries with DAY granularity must have a start time that is the start of day (00:00:00) for the account’s timezone. This account’s timezone is: America/Los_Angeles’

If your snapchat account is set to “America/Los_Angeles”, and you want to query data for January 1st, your date parameter should look like this:


That is because on January 1st , the UTC offset in Los Angeles is -08:00.

However, if you want to query on April 1st, Daylist Saving Time is now in effect in LA, so the UTC offset is now -07:00!

So your date parameter should now look like this:



Requires that you already have a project configured with web client credentials.

In order to get the user to consent (which gives is a code we will later exchange for an access token), we need to hand the user a URL.

What is not so documented here is, that you really want to prompt for consent (in case the user has already authenticated once) and you want to ask for access_type=offline

Hand the url to the user.


This gives you a user code, which we will now exchange for access _token + refresh_token using this:

This gives us a response like this:

    "access_token": "ya29.GluuBvGQ-238S6Y0Dq-FYrgDddddddddddddddddddddFA_iB3iv85_hklCaqT3v9lhwgW-lAVvrWaLJUSOxnkBhCjjBhTZz06qWHsDyOJonaZd",
    "expires_in": 3600,
    "refresh_token": "1/xCT3kKuccccccccccccccccccccccccS158hrpVM",
    "scope": "",
    "token_type": "Bearer"

Voila – we now have an access token and a refresh token!