Google Calendar API v3 Access Not Configured

sea_monster picture sea_monster · Nov 17, 2014 · Viewed 23.3k times · Source

I'm trying to get a list of events from a client's public calendar using v3 of Google's API. I entered the Calendar ID into the API Explorer, and I'm getting a positive result:

https://www.googleapis.com/calendar/v3/calendars/rpsj44u6koirtq5hehkt21qs6k%40group.calendar.google.com/events?key={YOUR_API_KEY}`

=> [List of events here, as expected]

To create an API key, I created a project in the Google Developer Console, created a Public API access key (APIs & auth > Credentials), and replaced {YOUR_API_KEY} above with my actual key. I made sure that the Calendar API was turned on (APIs & auth > APIs). When I paste this URL in the browser, I get this error response:

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "accessNotConfigured",
    "message": "Access Not Configured. The API is not enabled for your project, or there is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your configuration.",
    "extendedHelp": "https://console.developers.google.com"
   }
  ],
  "code": 403,
  "message": "Access Not Configured. The API is not enabled for your project, or there is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your configuration."
 }
}

All the responses I've seen say that you need to make sure the Google Calendar API is turned on, and it definitely is (also, it's turned on by default). What am I missing here?

Answer

gwg picture gwg · Jan 18, 2015

Using Google's Calendar API frustrated me for a couple of hours, and I want to document an overly complete (beyond the scope of this question) answer from a few sources for anyone else who may be having difficulty.

First, if you're like me, you got the public address from your calendar's settings: enter image description here

For my public calendar, that XML link was this; but the data was messy and, I think, represented an older version of the API. After searching around a bit, I found the correct URL structure for the v3 API: https://www.googleapis.com/calendar/v3/calendars/dl9fj86o2ohe7o823s7jar920s%40group.calendar.google.com/events?key={API_KEY}.

But like this question, I was getting an error. Do the following:

1. Create a project

Do that by going to the Google Developer Console and clicking Create Project. I was confused by this because my application is entirely front-end, and I didn't think I needed Google Developer project. I was wrong; I needed a project to perform the next steps.

2. Create an API key for your project

After creating the project, click on the project name and navigate to APIs & auth > Credentials. Under "Public API access", click Create new key > {KEY_TYPE} > Create; in my case {KEY_TYPE} was Browser key since I have an entirely front-end application. Skip filling in referers for now. This should create you an API key that you insert into the URL above (where it says {API_KEY}.

3. Add referers

If you've made it this far, you should see the error OP was talking about. The reason you get this error is that even though the calendar is public, Google only allows requests from specified domains. So I could publish my calendar's ID and even my API key, and another developer would not be able to access my calendar programmatically without me allowing that.

To resolve this, click Edit allowed referers—under APIs & auth > Credentials—and add (1) the name of the domain that will be making the request to the API and (2) if you're developing locally http://localhost:{PORT}/*. Make sure you add the wildcard at the end.

4. Make an HTTP request from an allowed domain

After all of this configuration, you'll still get an error if you just paste the URL into your browser. This is because the request has to come from one of the domains you just allowed. Just make the request from whatever application you're building. In my case, the JavaScript (jQuery) looks like this:

$.ajax({
    type: 'GET',
    url: {MY_URL},
    success: function(data) {
        // Throw a debugger statement in here,
        // and you should be able to inspect your data.
    }
});