Contact us to receive your API Key and start experimenting today: info@meekan.com

Getting Started

Welcome to Meekan!

This documentation describes the REST API provided for Meekan’s Scheduling Engine. The API covers the kinds of actions Meekan is capable of:

  • Connecting users with accounts (Calendars) and identifiers, by registerting accounts.
  • Assisting finding the best times for a meeting, through our FreeBusy service and Slot Suggestion.
  • Handling the life-cycle of a meeting, by creating polls, collecting responses, notifying state, and creating the events through the calendar provider.

SDK’s

Authentication and User Model

  • Requests to the API must be sent with an HTTP Authorization Header: Authorization: Meekan API_KEY where the API_KEY is your given personal API key.

  • All authenticated requests must include a session cookie received by proving ownership of a calendar (below)

Glossary

User is an entity that has at least one verified Account used to connect to Meekan. An Account is a calendar on a given provider that Meekan’s engine has permissions to read and modify. A User can have one or more Accounts connected to it (For example, a user with a work and personal calendars from Google). An Account could be connected by many users (For example, a conference-room shared by several people in the office). However, an account could be the main account of only one user.

Log in

Meekan supports logging in by:

  • Google Calendar - Using OAuth2
  • iCloud - Using session cookies
  • Exchange - Using server details and password.

The REST API has documentation for the Google\Google Apps Calendar for now. Information about iCloud and Exchange is coming along.

In order to start using Meekan’s API, you are required to authenticate. Use a browser window (Preferably at Incognito mode or similar), and navigate to Google Login. After allowing access, the browser will navigate to current user details. Persist the session cookie for later use. From now on, using the API Key and the session cookie, you can perform operations on Meekan engine as the connected user.

If you navigate to Google Login with an active session cookie, and login with another account, the new account will be added to the currently connected user.

If you’ve lost your session cookie, you may login again in the same method with the main account. The other accounts will be already connected.

Create Event

Now we can create a meeting.

Example: POST /rest/meetings

With body parameters (full list can be found here): { account_id: "text, THE_USER_ACCOUNT_ID, a user may have more than one connected account [can be fetched from /rest/auth]", meeting_name: "text, The title of the meeting", duration: "int, Time of the meeting in minutes - e.g. 60", e_inv[]: "List of email addresses - ["example@meekan.com", "example@gmail.com", ...]", opt[]: "List of UNIX timestamps for suggested meeting times at UTC timezone - ['1405612800', '1405699200', ...]" }

After this request a two optional meeting will created on the user calendar, and a poll will be sent to the invitees by email. Full details about the options can be seen at the documentation for creating a meeting or updating a meeting.

Get freebusy

Example of get freebusy

FreeBusy allows you to receive the busy times of a known Meekan account.

GET /rest/accounts/:USER_ACCOUNT_ID_TO_FETCH/freebusy?min_date=1405612800&max_date=1405699200

And we will get the next response: { data: { [ {'start': 1405616400, 'end': 1405620000}, {'start': 1405684800, 'end': 1405686600} ] } }

GET /social_login/google_oauth2 Login to meekan - google

This method will login to Meekan using google_oauth2

Response

{ data: { user_id: "5629499534213120", accounts: [ { id: "4785074604081152", identifier: "example@meekan.com", type: "GOOGLE_CALENDAR", name: "John Example" }, { ... } ], primary_email: "example@meekan.com", name: "John Example" }, error_code: 0 }

Google Login

For errors responses, see the response status codes documentation.

GET /rest/auth Get user auth details

This method will return all auth details for user.

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..

Response

{ data: { user_id: "5629499534213120", accounts: [ { id: "4785074604081152", identifier: "example@meekan.com", type: "GOOGLE_CALENDAR", name: "John Example" }, { ... } ], primary_email: "example@meekan.com", name: "John Example" }, error_code: 0 }

Request

Response

For errors responses, see the response status codes documentation.

PUT /rest/meetings/:id Update a meeting

This method allows to update specific meeting. The effect of the parameters is the same as in creating a meeting

Request

  • :id is the id of the meeting to update
  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..
  • The body can’t be empty and must include at least the account_id.
  • All relevant fields must be included, missing values may be overwritten.

Example

{ e_inv[]: emails of invitees (list) k_inv[]: keys of invitees (list) opt[]: list of optional times for the meeting (list of timestamps) duration: the time of the meeting in minutes (int) time_slots_desc: description of the time slot (string) timezone: The time zone (UTC if the default) (string) meeting_name: The name of the meeting (string) repeat_interval: 0 - not repeating 1 - daily, 7 - weekly 14 - every other week 31 - monthly 365 - yearly account_id: The id of the account of the meeting (string) calendar_id: The id of the calender of the meeting inside the account (string) - optional location_desc: description of the location (string) location_address: The location address (string) location_latlong: The Latitude and Longitude of the location ("32.085300,34.781768") reminder_minutes_before: how much time before the meeting to remind (int) reminder_method: how to remind the user (the default is popup) }

Response

Sends back a details about the remote events created.

Status: 200 { meeting_id: "csiebq26o9l0rdibndsfk23" remote_id: { remote_id: "csiebq26o9l0rdibbvc5peloso", start: 1404282883, duration: 60 } }

Meeting not found: Status: 500

Unauthorized access: Status: 403

Request

($1) meeting_id
account_id
calendar_id
meeting_name
duration
location_desc
location_address
location_latlong
time_slots_desc
notes
timezone
reminder_minutes_before
reminder_method
repeat_interval
e_inv (+)
k_inv (+)
opt (+)
slot (+)

Response

For errors responses, see the response status codes documentation.

PUT /rest/meetings/:meeting_id/poll/:voter_id Update vote for meeting

Updates a poll response

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..
  • meeting_id = the meeting id
  • voter_id = the voter id

GET Params: { vote_token = "The vote token" }

POST Params: { resp_type = "Response type - RESPONSE_NOT_YET/RESPONSE_CUSTOM/..", preferred = "List of preffered time (or empty) - [101054365, 101054366, 101054367]" }

RESPONSE_NOT_YET = 0 RESPONSE_CUSTOM = 1 RESPONSE_ALWAYS = 2 RESPONSE_WHEN_AVAILABLE = 3 RESPONSE_NO = 4 RESPONSE_MAYBE = 5

Response

Status: 200 OK

Request

($1) meeting_id
($2) voter_id
vote_token
resp_type
preferred (+)

Response

For errors responses, see the response status codes documentation.

POST /rest/meetings Create Meeting

This method creates a new meeting for the user.

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..
  • The body can’t be empty and must include at least the account_id attribute.
  • For opt:
    • If no values - The meeting is saved as a draft, with no created events
    • If one value - The meeting is created on the calendar in the account provider, and invitations are sent out.
    • If more than one value - The optional times are added to the calendar in the account provider, without sending invitations. The invitees will receive a poll by email or push notification, with options to vote for.

Example

{ meeting_name: The name of the meeting (string) e_inv[]: emails of invitees (list) k_inv[]: keys of invitees (list) duration: the time of the meeting in minutes (int) opt[]: list of options to the meeting (list of timestamps) time_slots_desc: description of the time slot (string) timezone: The time zone (UTC if the default) (string) location_desc: description of the location (string) location_address: The location address (string) location_latlong: The Latitude and Longitude of the location ("32.085300,34.781768") reminder_minutes_before: how much time before the meeting to remind (int) reminder_method: how to remind the user (the default is popup) repeat_interval: 0 - not repeating 1 - daily, 7 - weekly 14 - every other week 31 - monthly 365 - yearly account_id: The id of the account of the meeting (string) calendar_id: The id of the calender of the meeting (string) - optional }

Response

If succeeds, returns the created elements. - meeting_id: String, Meekan Identifier of the meeting - remote_id: IDs and start times on the events created on the calendar provider.

Status: 200 Created { meeting_id: "984562915582" remote_id: { remote_id: "csiebq26o9l0rdibbvc5peloso", start: 1404282883, duration: 60 } }

Request

account_id
calendar_id
meeting_name
duration
location_desc
location_address
location_latlong
time_slots_desc
notes
timezone
reminder_minutes_before
reminder_method
repeat_interval
e_inv[] (+)
k_inv[] (+)
slot[] (+)
opt[] (+)

Response

For errors responses, see the response status codes documentation.

GET /rest/slots Get slots

Return list of available slots for a meeting from all the invitees by page number.

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..

The frames parameter indicates times that suggested slots should be returned in. It is agnostic to timezones and user preferences, therefore the client should generate the relevant frames based on user preferences.

GET Params: { invitees[]: "the Meekan account id of the invitees (list) - not email or other identifiers", duration: "the duration of the meeting in minutes (int)", organizer_account_id: "the account id of the organizer (int)", page: "the page of the results to return (int), optional", frames[]: "The time frames in which slots should be suggested (list of strings ("start:end") example - ["140003040:145403200",...]" }

Response

List of available slots from all the invitees by page number sorted by rank

Status: 200 OK { [{start: 'long, UNIX timestamp, the suggested time slot, e.g. 140003040', not_available: "list of Meekan Account IDs that are not available the meeting if starts at *start*, ["126572762", "12310976216"]", rank: 'int, the rank of this timeslot, higher is better - 3001' }, ...] }

Request

duration
organizer_account_id
page
frames[] (+)
invitees[] (+)

Response

For errors responses, see the response status codes documentation.

GET /rest/meetings Get meetings

Return a list of meeting for the given user, updated since last request

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..

Response

Sends back a json with collection of meetings.

Status: 200 OK { meetings:[ { remote_id: { remote_id: "csiebq26o9l0rdibbvc5peloso", start: 1404282883, duration: 60 }, timezone: "UTC", repeat_interval: 0, start_time: 1404282883, last_update: 1404283142.993, id: "5348024557502464", organizer_user: "5629499534213120", votes: { }, options: [ 1404282883 ], duration: 60, is_deleted: false, time_desc: "", name: "", invitees: [ ], reminder_method: "popup", organizer: "4785074604081152", location_desc: "Home", organizer_email: "organizer@meekan.com", location_address: "New York" }, { .... } ] "more" : False }

Request

last_timestamp

Response

For errors responses, see the response status codes documentation.

GET /rest/meetings/:meeting_id/poll/:account_id/adjacent-events Get adjacent events

Return adjacent events to the time slots options

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..
  • meeting_id = the meeting id
  • voter_id = the voter id

GET Params: { vote_token = "The vote token" }

Response

The adjacent events to the meeting

Status: 200 OK { 1402395500: '[["", ""], ["No Meetings", ""], ["No Meetings", ""], ["", ""]]', 1402392132: '[["", ""], ["No Meetings", ""], ["No Meetings", ""], ["", ""]]' }

Request

($1) meeting_id
($2) account_id

Response

For errors responses, see the response status codes documentation.

GET /rest/meetings/:meeting_id/poll/:voter_id Get voter details for meeting

Return the latest vote details the user has for the poll for this meeting

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..
  • meeting_id = the meeting id
  • voter_id = the voter id

GET Params: { vote_token = "The vote token" }

Response

The latest vote details the user has for the poll for this meeting

Status: 200 OK { meeting: '{ title:"meeting title", organizer_name:"organizer name", organizer_email: "organizer@gmail.com", duration: 90, loc_name: "location name" loc_address: "location address 123, City", loc_latlon: "5.0,5.1", options:[101054365, 101054366, 101054367]}', user_vote:'{type: "1",times: "[1, 0, 1]"}', votes:'[{User Name: "[0,0,1]"}]' }

votes - Interpolation based on the RESPONSE and preferred values: For each timestamp:

RESPONSE_NOT_YET = 0 RESPONSE_CUSTOM = 1 RESPONSE_ALWAYS = 2 RESPONSE_WHEN_AVAILABLE = 3 RESPONSE_NO = 4 RESPONSE_MAYBE = 5

Request

($1) meeting_id
($2) voter_id
vote_token

Response

For errors responses, see the response status codes documentation.

GET /rest/accounts Get ids to accounts

Return a dictionary between identifier to id.

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..

{ q[]: identifiers of account (list) }

Response

Status: 200 OK { example@meekan.com: "4785074604081152" }

Request

q[] (+)

Response

For errors responses, see the response status codes documentation.

GET /rest/accounts/:id/freebusy Get freebusy

Return a list of freebusy for an account between the given dates. If a user has multiple accounts (Work, Personal) they are all queried for free-busy, to ensure best joined data. If an account is connected by multiple users, only FreeBusy from this account is retrieved - This ensures that shared calendars (Such as a meeting-room) will not leak personal information.

Request

  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..
  • id = the account id to fetch freebusy from

GET Params: { id = "the account id of the auth user " min_date = "Start searching from this date (timestamp, long)" max_date = "Searching until this date (timestamp, long), max_date must be after than min_date, but not more 3 months later" }

Response

Returns a list of freebusy for account between the dates. The returned times are the times in which the user is indicated busy. Results may be cached on the server but usually refreshed once meetings are organized or after a short duration. Returned list is usually sorted based on start time, and contain no overlaps.

Status: 200 OK { data: {[{'start': 1404381600, 'end': 1404385200}, ... ]} }

Request

($1) account_id
min_date
max_date

Response

For errors responses, see the response status codes documentation.

DELETE /rest/meetings:id Delete a meeting

This will delete the specific meeting

Request

  • :id is the id of the meeting to delete
  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..
  • The body is omitted.

Response

If the deleted succeed: Status: 200

Meeting was not found: Status: 404

Failed deleting meeting: Status: 500

Request

($1) meeting_id

Response

For errors responses, see the response status codes documentation.

POST /social_login/:provide_name/delete Delete auth

Removing auth from our data store

Request

  • :provider_name the provider to delete (exchange/icloud/google_oauth2)
  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..

For errors responses, see the response status codes documentation.

DELETE /rest/accounts:id Delete account

Removing account from our data store

Request

  • :id is the id of the account to delete
  • Must provide a valid API key in the “Authorization” header
  • The cookie must include a valid session..

Response

Status: 200 OK

Request

($1) account_id

Response

For errors responses, see the response status codes documentation.

Response status codes

Success

Successes differ from errors in that their body may not be a simple response object with a code and a message. The headers however are consistent across all calls:

  • GET, PUT, DELETE POST returns 200 OK on success

Error

Error responses are simply returning standard HTTP error codes along with some additional information:

  • The error code is sent back as a status header,
  • The body includes an object describing both the code and message (for debugging and/or display purposes),

For a call with an invalid authentication token for example: { code: 500, message: 'inactive account' }

{ code: 404, message: 'account does not exist' }

{ code: 403, message: 'incorrect vote token' }