Teamup API Overview
This API allows programmatic access to calendars hosted by Teamup.
The API endpoints described here are the only ones we currently officially support and intend on maintaining backwards compatible. As such if you use any other URL you have to understand you are doing so at your own risk.
If the API endpoints described here are not sufficient for your requirements, please get in touch with us and we will be happy to discuss further integration points.
Usage of the API is included in the subscription plans offered for Teamup. There is no additional fee. We only ask you to register your application by requesting an API key for free. This provides us with a means to contact you, should the need arise to do so.
General API Guidelines
- API access MUST be done over TLS/SSL via https://api.teamup.com/
- All API requests must include an API key in a request header
- Strings in requests and responses MUST be using the UTF-8 character set
- Successful responses will have status codes in the 200-299 range
- Client errors will have status codes in the 400-499 range
- Server errors will have status codes in the 500-599 range
- Placeholders in URL examples are indicated by curly braces, e.g.
{eventId}
- API responses are in JSON using the
application/json
content type
Please also take a look at the API Usage Best Practices.
Querying the Teamup API
API Key
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/events');
print $result->getStatusCode();
// "200"
print $result->getHeader('content-type');
// 'application/json'
print $result->getBody();
// {"events":[ ... ]}
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events" \
-H "Teamup-Token: API_KEY"
Every request to the API must include an API key in a request header.
We ask you to register your application by requesting an API key for free. This provides us with a means to inform you about changes to the API or contact you, should the need arise to do so.
Calendar Key
Almost all API requests require a calendar key as part of the request URL. For example, to read a list of events the following API request is used:
GET /{calendarKey}/events
{calendarKey}
addresses a specific calendar. One calendar can have many calendar keys and each
calendar key has associated permissions, for example read-only, modify or administration. For each
API endpoint you find the needed permission in the documentation of that endpoint.
Calendar keys are managed using the Web-based calendar settings application. Look for the Sharing tab.
API Clients
The API can be queried using any HTTP client. Our documentation provides PHP and cURL examples. The PHP examples use the Guzzle library (version 6). You can install it in your project using Composer by running:
composer require 'guzzlehttp/guzzle:^6.0'
Testing your API key
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/check-access');
print $result->getStatusCode();
// "200"
curl "https://api.teamup.com/check-access" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"access": "ok"
}
This endpoint lets you check if your API key is valid and you are submitting it as expected.
HTTP Request
GET /check-access
Querying password-protected calendars
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => [
'Teamup-Token' => 'API_KEY',
'Teamup-Password' => 'demopassword'
]);
$result = $client->get('https://api.teamup.com/kscb1caefc73e9f0a8/events');
print $result->getStatusCode();
// "200"
print $result->getHeader('content-type');
// 'application/json'
print $result->getBody();
// {"events":[ ... ]}
curl "https://api.teamup.com/kscb1caefc73e9f0a8/subcalendars" \
-H 'Teamup-Token: API_KEY' -H 'Teamup-Password: demopassword'
For password-protected calendars, you must send a custom Teamup-Password
header that has the
password as value.
Querying the API using cURL on Windows
If you use the cURL samples in Windows's cmd.exe, and want to POST JSON data, you
will have to escape the JSON text. For example use curl ... -d "{""json"": ""data""}"
with all the double quotes appearing twice within the string. On Linux or using cygwin
cURL builds this is not an issue as you can quote using single quotes ('
) to avoid
having to escape the double quotes.
The other thing to take into account is that by default your cURL might not come with
an SSL CABundle, which prevents it from making secure connections to us, and it will
warn you about a self-signed certificate. The solution is to download a
CA bundle and save it next to curl.exe, with the
file name curl-ca-bundle.crt
(don't forget to change the extension from .pem). This
will give cURL the knowledge about root certificate authorities, which will allow it
to validate our SSL certificate against it. You should ideally keep this file updated
reasonably often to make sure any revoked certificates are removed and new ones added.
Querying the API via JavaScript / CORS
Example:
// Creates a CORS request in a cross-browser manner
function createCORSRequest(method, url) {
var apiKey = 'API_KEY';
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari/IE10+.
xhr.open(method, url, true);
xhr.setRequestHeader('Teamup-Token', apiKey);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE8/IE9.
xhr = new XDomainRequest();
// XDomainRequest does not support querying HTTPS from HTTP pages
if (window.location.protocol === 'http:') {
url = url.replace('https://', 'http://');
}
if (-1 === ['GET', 'POST'].indexOf(method)) {
alert('XDomainRequest only supports GET and POST methods');
return;
}
if (-1 === url.indexOf('?')) {
url += '?_teamup_token=' + apiKey;
} else {
url += '&_teamup_token=' + apiKey;
}
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
// Sends the actual CORS request.
function makeCorsRequest(url, successCallback, errorCallback) {
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function (xhr) {
if (xhr.target.status < 400) {
if (successCallback) successCallback(xhr.target);
} else if (errorCallback) {
errorCallback(xhr.target);
}
};
xhr.onerror = function (xhr) {
if (errorCallback) {
errorCallback(xhr.target);
}
};
xhr.send();
}
// Send a GET request for all events in a date range
makeCorsRequest(
'https://api.teamup.com/ks73ad7816e7a61b3a/events?startDate=2015-06-01&endDate=2015-06-05',
function(xhr) {
var data = JSON.parse(xhr.responseText);
alert('Successfully Received: ' + JSON.stringify(data));
},
function(xhr) {
var data = JSON.parse(xhr.responseText);
alert('Request failed with code '+ xhr.status +': ' + JSON.stringify(data));
}
);
The Teamup API supports Cross-Origin Resource Sharing requests. This is the preferred way and is widely supported across all browsers.
If you do ajax requests with jQuery for example it will use CORS by default and everything should work out of the box. If you wish to do it with pure JS you can use the code snippet on the right to make it work across browsers.
Note that IE8 and IE9 only support XDomainRequest and not the full CORS specification. If you need to support those versions, be mindful of the following limitations:
- You can only use the GET and POST method
- If your site is hosted on http and not https, you must query our API using http as well
- You can not set custom headers, this means that the key has to be passed using a
_teamup_token
query parameter, e.g.?_teamup_token=API_KEY
The code above takes care of most of these for you but supporting IE8/9 will still restrict your
usage. To use the full API you can write a simple server-side script to proxy your requests to the
Teamup API via your server and then use regular XMLHttpRequest
calls.
Date and Time Formats
All parameters and properties of type date and/or time follow the ISO-8601 standard on date and time formats.
Example | Description |
---|---|
2015-01-31 |
Date only |
2015-01-31T10:00:00 |
Date and time, default timezone |
2015-01-31T10:00:00Z |
Date and time, timezone UTC |
2015-01-31T10:00:00-05:00 |
Date and time, timezone -05:00 |
Default Timezone
If timezone is not specified, then the default timezone is assumed. The default timezone is:
- The timezone defined by the tz query parameter or
- The calendar's default timezone as specified in the calendar's configuration
Global Query Parameters
The following query parameters are available for all API end points:
Parameter | Type | Default | Description |
---|---|---|---|
tz | string | Calendar timezone | The request timezone. Supported timezones include: UTC , America/New_York and equivalent (see TZ database timezones for a full list). Note that this parameter is only respected by the server if the calendar is configured to allow users changing the timezone. See Settings -> Date & Time of your calendar. |
lang | string | Calendar language | The language to use in responses. Currently supported values are en, en_GB, fr, de, es, hu. |
Configuration
Read Configuration
Example:
<?php
$client = new GuzzleHttp\Client(['headers': {'Teamup-Token': 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/configuration');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/configuration" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"configuration": {
"general_settings": {
"admin_email": "support@teamup.com",
"language": "en",
"control_panel_default_state": "visible",
"onetomany_enabled": false,
"user_signup_enabled": true,
"icsfeeds_enabled": true,
"about": "<p>This is a demo calendar.</p>",
"about_enabled": true,
"about_title": "About"
},
"calendar_views": {
"default_view": "W",
"show_day_view": true,
"show_week_view": true,
"show_multiday_view": false,
"show_multiweek_view": true,
"show_month_view": true,
"show_agenda_view": false,
"show_list_view": true,
"show_scheduler_view": true,
"show_year_view": true,
"week_hide_weekend": false,
"multiweek_number_of_weeks": 8,
"multiday_number_of_days": 3,
"agenda_date_range": "3months",
"agenda_show_details": false,
"list_date_range": "3months",
"list_group_by": "month",
"list_show_details": false,
"year_number_of_months": 12
},
"date_time": {
"tz_dynamic": false,
"tz": "Europe/Berlin",
"tz_show": false,
"date_locale": "en",
"use_24h_times": false,
"time_range_start": 6,
"time_range_end": 24,
"start_date_type": "current",
"start_date": "2016-01-01",
"start_date_pattern": "y1",
"week_start": 1,
"scroll_start_hour": 7
},
"identity": {
"title": "API Demo Calendar",
"customize": false,
"show_custom_logo": true,
"logo_uri": "//teamup.com/app/customlogo/key/ksa87cfc0bcd81ad77",
"header_background_color": "#D0DEF0",
"header_font_color": "#444444"
},
"link": {
"name": "Administrator",
"key": "ksa87cfc0bcd81ad77",
"id": 1351743
},
"features": {
"calendar_limit": 50,
"history": 120,
"daily_agenda": true,
"passwords": true,
"file_storage": 10737418240,
"refresh_param": true,
"file_upload": true,
"notification_for_past": true,
"import_feed_frequency": [
43200,
10080,
720,
240,
60
]
},
"fields": {
"definitions": [
{
"id": "builtin_who",
"name": "",
"type": "builtin_who",
"type_data": {
"min": 0
},
"active": true,
"hidden": false,
"creation_dt": "2017-11-01T12:28:51+00:00",
"update_dt": null
},
{
"id": "builtin_location",
"name": "",
"type": "builtin_location",
"type_data": {
"min": 0
},
"active": true,
"hidden": false,
"creation_dt": "2017-11-01T12:28:51+00:00",
"update_dt": null
},
{
"id": "builtin_notes",
"name": "",
"type": "builtin_notes",
"type_data": {
"min": 0
},
"active": true,
"hidden": false,
"creation_dt": "2017-11-01T12:28:51+00:00",
"update_dt": null
},
{
"id": "builtin_signup",
"name": "",
"type": "builtin_signup",
"type_data": {},
"active": true,
"hidden": false,
"creation_dt": "2017-11-01T12:28:51+00:00",
"update_dt": null
},
{
"id": "builtin_comments",
"name": "",
"type": "builtin_comments",
"type_data": {},
"active": true,
"hidden": false,
"creation_dt": "2017-11-01T12:28:51+00:00",
"update_dt": null
}
]
}
}
}
This endpoint can be used to retrieve the configuration of a calendar.
HTTP Request
GET /{calendarKey}/configuration
{calendarKey}
: Calendar key with read-only, modify or administration permission.- Response: On success, returns the calendar configuration as a JSON-encoded hierarchy. The returned data structure is organized similarly to calendar settings application. We recommend to consult the settings application to learn about the meaning of the different settings.
Events
Event Data Structure
The following table documents the attributes of a calendar event. Please note that some event attributes are read-only while others are update-only. Read-only attributes are returned in server responses but do not need to be submitted in requests. Update-only attributes need to be submitted in requests but are not returned in server responses. The notes below the table give more details.
Name | Type | Default | Description |
---|---|---|---|
id | string | generated | Event id |
remote_id* | string/null | null |
Unique id of event in a third party system, (optional) |
series_id | int/null | generated | (read-only) Id of recurring event series to which this event belongs (recurring events only) |
subcalendar_ids | array of int | - | A list of ids of sub-calendars to which event is assigned |
subcalendar_id* | int | - | (DEPRECATED) Id of sub-calendar to which event is assigned |
start_dt | date | - | Event start date in ISO-8601 format |
end_dt | date | - | Event end date in ISO-8601 format |
all_day | bool | - | Whether the event spans all day or not |
title | string | "" |
Event title, 0 to 255 characters |
who | string | "" |
Event attendee information, 0 to 255 characters |
location | string | "" |
Event location, 0 to 255 characters |
notes* | string | "" |
Event notes, 0 to 65535 characters |
rrule* | string | "" |
Recurrence rule (recurring events only) |
redit* | string | - | (update-only) The edit mode when updating recurring events (recurring events only) |
ristart_dt* | date | generated | The recurrence instance start date (recurring events only) |
rsstart_dt* | date | generated | (read-only) The start date of the recurring series of events to which this event instance belongs (recurring events only) |
tz* | string/null | request tz | Timezone for which the recurrence rule is evaluated (recurring events only) |
version* | string | generated | The event version |
readonly* | bool | generated | (read-only) Whether the event can be modified |
duration | int | generated | (read-only) Event duration in minutes. Only returned if fetching changes. |
signup_enabled | bool | false | Whether event signup is enabled or not. This field is currently not part of the public API. Please ignore. |
signup_deadline | date | - | Signup deadline in ISO-8601 format. This field is currently not part of the public API. Please ignore. |
signup_visibility | bool | false | Whether the list of signups is public or not. This field is currently not part of the public API. Please ignore. |
signup_limit | int | 0 | The maximum number of allowed signups (0 = an unlimited number). This field is currently not part of the public API. Please ignore. |
comments_enabled | bool | false | Whether event comments are enabled or not. This field is currently not part of the public API. Please ignore. |
comments_visibility | string | "all-users" |
Whether event comments are available to all users or not. This field is currently not part of the public API. Please ignore. |
custom* | JSON object | - | The values of custom event fields. This field is currently not part of the public API. Please ignore. |
creation_dt | date | generated | (read-only) Event creation date in ISO-8601 format |
update_dt | date/null | generated | (read-only) Event last update date in ISO-8601 format |
delete_dt | date/null | generated | (read-only) Date when an event was deleted in ISO-8601 format. This field is only present if the event has been deleted. |
Notes
- remote_id: This field is optional and can be used to track a relationship between events that are synced from your local calendar to Teamup.
- rrule: Recurrence rules follow the iCal RRULE specifications, see also RRULE examples. Please note that only a sub-set of recurrence rules as defined by the standard are supported. We suggest to use the web client of Teamup Calendar to explore what rules are supported.
- notes: Can contain basic HTML tags or Markdown.
- redit:
Must be one of "
all
", "single
" or "future
". - ristart: Omit it during creation, but when editing events this MUST be sent back unmodified to the server for correct recurring events date calculations.
- version: Should be omitted when creating events, but when editing events this MUST be sent back unmodified to the server for conflict-detection.
Get Events Collection
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/events?startDate=2017-08-01&endDate=2017-08-31');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events?startDate=2017-08-01&endDate=2017-08-01" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"events": [
{
"id": "123",
"remote_id": null,
"series_id": null,
"subcalendar_id": [730624],
"subcalendar_id": 730624,
"start_dt": "2015-06-17T06:00:00-0400",
"end_dt": "2015-06-17T07:00:00-0400",
"all_day": false,
"title": "Demo Event",
"who": "",
"location": "",
"notes": "",
"rrule": "",
"ristart_dt": null,
"rsstart_dt": null,
"tz": null,
"version": "556db1f949aa6",
"readonly": false,
"creation_dt": "2015-06-02T13:39:05+0000",
"update_dt": null,
}
],
"timestamp": 1502628855
}
Retrieve a list of events for a specified date range. This endpoint can be used to periodically synchronize a calendar client with the calendar server.
HTTP Request
GET /{calendarKey}/events
{calendarKey}
: Calendar key with at least read permission- Response: On success, returns an array of JSON-encoded event objects.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
startDate | date | today | Optional. The start of the date range to list events from, in YYYY-MM-DD format |
endDate | date | today +1 day | Optional. The end of the date range to list events from (inclusive), in YYYY-MM-DD format |
format | string | html |
Optional. Can be used to request the format of the event notes in the response. Supported values are html , markdown or both (array). To request both formats, use this syntax: ?format[]=html&format[]=markdown . |
subcalendarId[] | Integer | Optional. Use this parameter to restrict the response to selected sub-calendars. This parameter can be applied multiple times to the URL. Eg. &subcalendarId[]=1234&subcalendarId[]=6789 . |
Notes
- Recurring events: For recurring events, the recurrence rule is evaluated and all event instances that fall between the given start and end date are returned.
Get Event
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/events/11449078');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events/11449078" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"event": {
"id": "11449078",
"subcalendar_id": 893615,
"start_dt": "2015-06-01T00:00:00+0000",
"end_dt": "2015-06-01T23:59:00+0000",
"all_day": true,
"rrule": "",
"title": "Demo Event 1 - All Day",
"who": "",
"location": "",
"notes": "",
"version": "55817b2954ae4",
"ristart_dt": null,
"creation_dt": "2015-06-17T13:50:33+0000",
"update_dt": null,
"readonly": false
}
}
This endpoint retrieves a single event.
HTTP Request
GET /{calendarKey}/events/{eventId}
{calendarKey}
: Calendar key with read permission{eventId}
: Id of event to be retrieved- Response: On success, returns a JSON-encoded event object.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
format | string | html |
Can be used to request the format of the event notes in the response. Supported values are html , markdown or both (array). To request both formats, use this syntax: ?format[]=html&format[]=markdown . |
Get Event in iCalendar Format
Example:
See shell example
curl "https://teamup.com/ks73ad7816e7a61b3a/events/130178881.ics" \
Expected response:
200 OK
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Teamup Calendar//Teamup//DE
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
SUMMARY:Meeting with Mr. Martens
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
LOCATION:Conf. Room 3
DTSTAMP:20170812T214339Z
UID:evt130178881@teamup.com
DTSTART;TZID=UTC:20170810T070000Z
DTEND;TZID=UTC:20170810T100000Z
TZID:UTC
DESCRIPTION:Please prepare coffee and snacks.\n\n\n---\nEvent exported from Teamup, www.teamup.com
END:VEVENT
END:VCALENDAR
This endpoint retrieves a specific event and returns it in iCalendar format (content type text/calendar
).
Important: This request must be addressed at the teamup.com
host (not the api.teamup.com
host) and does not require an API key.
This allows the request to be used with a web browser. Most web browsers are configured to open a calendar
application when receiving a response of type text/calendar
. This can be used to easily export an event to a
third-party calendar program.
HTTP Request
GET /{calendarKey}/events/{eventId}.ics
{calendarKey}
: Calendar key with read permission{eventId}
: Id of event to be retrieved- Response: On success, returns an event in iCalendar format.
Create Event
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->post('https://api.teamup.com/ks73ad7816e7a61b3a/events', [
'json' => [
"subcalendar_id" => 730624,
"start_dt" => "2015-06-17T06:00:00-0400",
"end_dt" => "2015-06-17T07:00:00-0400",
"all_day" => false,
"rrule" => "",
"title" => "Demo Event",
"who" => "",
"location" => "",
"notes" => "",
]
]);
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events" -XPOST \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json' \
--data '{
"subcalendar_id": 730624,
"start_dt": "2015-06-17T06:00:00-0400",
"end_dt": "2015-06-17T07:00:00-0400",
"all_day": false,
"rrule": "",
"title": "Demo Event",
"who": "",
"location": "",
"notes": ""
}'
Expected response:
201 Created
Location: /{calendarKey}/events/{eventId}
{
"event": {
"id": "123",
"subcalendar_id": 730624,
"start_dt": "2015-06-17T06:00:00-0400",
"end_dt": "2015-06-17T07:00:00-0400",
"all_day": false,
"rrule": "",
"title": "Demo Event",
"who": "",
"location": "",
"notes": "",
"version": "556db1f949aa6",
"ristart_dt": null,
"creation_dt": "2015-06-02T13:39:05+0000",
"update_dt": null,
"readonly": false
},
"undo_id": "30b0c87f725228a57dce"
}
This API endpoint can be used to create a new calendar event.
HTTP Request
POST /{calendarKey}/events
{calendarKey}
: Calendar key with modify permission- Request body: The request body must contain an JSON-encoded event object.
- Response: On success, the newly created event is returned as a JSON-encoded event object.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
format | string | html |
Used to specify the format of the event notes in the request. Supported values are html , markdown . |
inputFormat | string | html |
By default, the event notes in the request are expected to be html formatted. If this is not the case, this parameter can be used to declare the format. Supported values are html and markdown . |
Update Event
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->put('https://api.teamup.com/ks73ad7816e7a61b3a/events/123', [
'json' => [
"id" => "123",
"subcalendar_id" => 730624,
"start_dt" => "2015-06-17T06:00:00-0400",
"end_dt" => "2015-06-17T07:00:00-0400",
"all_day" => false,
"rrule" => "",
"title" => "New Title",
"who" => "",
"location" => "",
"notes" => "",
"version" => "556db1f949aa6",
"redit" => null,
"ristart_dt" => null,
]
]);
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events/123" -XPUT \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json' \
--data '{
"id": "123",
"subcalendar_id": 730624,
"start_dt": "2015-06-17T06:00:00-0400",
"end_dt": "2015-06-17T07:00:00-0400",
"all_day": false,
"rrule": "",
"title": "New Title",
"who": "",
"location": "",
"notes": "",
"version": "556db1f949aa6",
"redit": null,
"ristart_dt": null
}'
Expected response:
200 OK
{
"event": {
"id": "123",
"subcalendar_id": 730624,
"start_dt": "2015-06-17T06:00:00-0400",
"end_dt": "2015-06-17T07:00:00-0400",
"all_day": false,
"rrule": "",
"title": "New Title",
"who": "",
"location": "",
"notes": "",
"version": "556dd350bf702",
"ristart_dt": null,
"creation_dt": "2015-06-02T13:39:05+0000",
"update_dt": null,
"readonly": false
},
"undo_id": "30b0c87f725228a57dce"
}
This API endpoint can be used to update an existing event.
HTTP Request
PUT /{calendarKey}/events/{eventId}
{calendarKey}
: Calendar key with modify permission{eventId}
: Id of event to be retrieved- Request body: The request body must contain an JSON-encoded event object.
- Response: On success, the updated event is returned as a JSON-encoded event object.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
format | string | html |
Used to specify the format of the event notes in the request. Supported values are html , markdown . |
inputFormat | string | html |
By default, the event notes in the request are expected to be html formatted. If this is not the case, this parameter can be used to declare the format. Supported values are html and markdown . |
Note on version conflicts
The event attribute version
represents the version of an event. This attribute is updated
by the server whenever an event is changed. It implements a soft-locking mechanism to
prevent multiple users from overwriting each others' changes. A request to update an
event is only accepted if the given version
is equal to the latest value of this
attribute in the calendar database.
If an event carries an old version, then an update request is rejected with the error
id: event_validation_conflict
. In that case, before the event can be updated it must
be read from the server in order to obtain the latest version. Any modifications should
then be applied to it again before doing a new update.
Note on recurring events
When updating a recurring event, event attribute redit
can be used to specify how the update will be applied.
Supported value are:
all
(default) : Update is applied to all instances of the recurring event.single
: Update is applied only to the event instance addressed by{eventId}
.future
: Update is applied to the event instance addressed by{eventId}
and all future instances.
Delete Event
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->delete('https://api.teamup.com/ks73ad7816e7a61b3a/events/123?version=556db1f949aa6&redit=all');
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events/123?version=556db1f949aa6&redit=all" -XDELETE \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"undo_id": "ec37cfb1a7c1bbd43a0c"
}
This endpoint lets you delete an event.
HTTP Request
DELETE /{calendarKey}/events/{eventId}
{calendarKey}
: Calendar key with modify permission{eventId}
: Id of event to be deleted- Response: On success, returns HTTP status 200 and a JSON body with an undo id. See example. This undo id can be used to undo the delete.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
version | string | - | Required. The version of the event. This string must be read from an uptodate event records. |
redit | string | single |
Optional. Edit mode for recurring events. See notes below. |
Note on recurring events
When deleting a recurring event, event attribute redit
can be used to specify how the delete operations will be applied.
Supported value are:
all
(default) : All instances of the recurring event are deleted.single
: Only the event instance addressed by{eventId}
is deleted.future
: Only the event instance addressed by{eventId}
and all later event instances are deleted.
Get Events Changed
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/events?modifiedSince=1501545600');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events?modifiedSince=1501545600" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"events": [
{
"id": "130178881",
"series_id": null,
"remote_id": null,
"subcalendar_id": 893615,
"subcalendar_ids": [
893615
],
"start_dt": "2017-08-10T09:00:00+02:00",
"end_dt": "2017-08-10T12:00:00+02:00",
"all_day": false,
"rrule": "",
"title": "Meeting with Mr. Martens",
"who": "",
"location": "Conf. Room 3",
"notes": "<p>Please prepare coffee and snacks.</p>",
"version": "598f62832520e",
"ristart_dt": null,
"rsstart_dt": null,
"creation_dt": "2017-08-12T20:18:11+00:00",
"update_dt": null,
"delete_dt": null,
"readonly": true,
"tz": null,
"duration": 180
}
],
"timestamp": 1502628855
}
Retrieve a list of events that changed recently.
HTTP Request
GET /{calendarKey}/events
{calendarKey}
: Calendar key with at least read permission- Response: On success, returns an array of JSON-encoded event objects. Notice that the response also contains a property "timestamp" representing the server time as of which all changes are included in the response. It is recommended to use this timestamp in the next request for changes as the value of the modifiedSince parameter. This will ensure that never a change is missed.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
modifiedSince | UNIX timestamp | - | Required. All events that were created, updated or deleted after this time will be returned. |
format | string | html |
Optional. Can be used to request the format of the event notes in the response. Supported values are html , markdown or both (array). To request both formats, use this syntax: ?format[]=html&format[]=markdown . |
Notes
- Deleted Events: The response includes deleted events. Deleted events can be recognized by attribute "delete_dt" having a non-null value.
- Date Range: It is currently not possible to restrict the changes to a calendar date range.
- Repeating Events: For repeating events, the reply contains only the master event with the repeating rule but does not return each repeating event instance. Attribute end_dt represents the end of the entire repeating series. The duration of one event instance is returned in attribute duration. If repeating instances are needed, the API endpoint Get Events Collection must be used to fetch events.
- Changes are tracked for 30 days: The value of the modifiedSince parameter can be at most 30 days in the past.
Search Events
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/events?query=Martens&startDate=2017-08-01&endDate=2017-08-31&subcalendarId[]=36062666');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events?query=Martens&startDate=2017-08-01&endDate=2017-08-31&subcalendarId[]=36062666" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"events": [
{
"id": "130178881",
"series_id": null,
"remote_id": null,
"subcalendar_id": 893615,
"subcalendar_ids": [
893615
],
"start_dt": "2017-08-10T09:00:00+02:00",
"end_dt": "2017-08-10T12:00:00+02:00",
"all_day": false,
"rrule": "",
"title": "Meeting with Mr. Martens",
"who": "",
"location": "Conf. Room 3",
"notes": "<p>Please prepare coffee and snacks.</p>",
"version": "598f62832520e",
"ristart_dt": null,
"rsstart_dt": null,
"creation_dt": "2017-08-12T20:18:11+00:00",
"update_dt": null,
"delete_dt": null,
"readonly": true,
"tz": null
}
],
"timestamp": 1502628855
}
Searches for events using a query string.
HTTP Request
GET /{calendarKey}/events
{calendarKey}
: Calendar key with at least read permission- Response: On success, returns an array of JSON-encoded event objects.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
query | string | - | Required. Query string used to search for events. See the Search Guide for supported query syntax and features. |
startDate | date | today | Optional. The start of the date range to search for events, in YYYY-MM-DD format. |
endDate | date | today +1 day | Optional. The end of the date range to search for events, in YYYY-MM-DD format. |
format | string | html |
Optional. Can be used to request the format of the event notes in the response. Supported values are html , markdown or both (array). To request both formats, use this syntax: ?format[]=html&format[]=markdown . |
subcalendarId[] | Integer | Optional. Use this parameter to restrict the response to selected sub-calendars. This parameter can be applied multiple times to the URL. Eg. &subcalendarId[]=1234&subcalendarId[]=6789 . |
Notes
- Recurring events: For recurring events, the recurrence rule is evaluated and all event instances that fall between the given start and end date are returned.
Get Event History
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/events/11449078/history');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events/11449078/history" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"created":{
"by":"Administrator",
"datetime":"2017-12-18T08:36:34-05:00"
},
"updates":[
{
"by":"Administrator",
"datetime":"2017-12-21T09:00:47-05:00"
}
]
}
Read the change history of an event. This includes the creation date, the link used to create the event, the last modification date and the link used to modify the event.
HTTP Request
GET /{calendarKey}/events/{eventId}/history
{calendarKey}
: Calendar key with read permission{eventId}
: Id of event- Response: On success, returns a JSON-encoded object containing the event history. See example.
Query Parameters
None
Get Auxiliary Information
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/events/11449078/aux');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/events/11449078/aux" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"history":{
"created":{
"by":"Administrator",
"datetime":"2017-12-18T08:36:34-05:00"
},
"updates":[
{
"by":"Administrator",
"datetime":"2017-12-21T09:00:47-05:00"
}
]
},
"signups":[
{
"id":35081,
"event_id":151921276,
"name":"Mark",
"email":"mark@teamup.com",
"email_hash":"eb88aebd18089396d068a498a66dd7fe",
"creation_dt":"2017-12-21T09:00:41-05:00",
"update_dt":null,"image":"https:\/\/www.gravatar.com\/avatar\/eb88aebd18089396d068a498a66dd7fe?s=30\u0026d=identicon\u0026d=blank"
},
{...}
],
"comments":[
{
"id":"2587",
"event_id":"151921276",
"name":"Peter",
"email":"peter@teamup.com",
"email_hash":"885b6e0fd1498af73319bf3f94411ee3",
"message":"\u003Cp\u003EHi Mark, I need a beamer for my presentation. Thanks\u003C\/p\u003E",
"creation_dt":"2017-12-21T14:02:34+00:00",
"update_dt":null,
"updater":""
},
{...}
]
}
Read auxiliary event information. This includes the event change history, events comments and event signups.
HTTP Request
GET /{calendarKey}/events/{eventId}/aux
{calendarKey}
: Calendar key with read permission{eventId}
: Id of event. If it is a recurring event, this must address a specific instance to see comments on that instance.- Response: On success, returns a JSON-encoded object containing event history, event comments and event signups. See example.
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
format | string | html |
Used to specify the format of the event comments in the request. Supported values are html , markdown . |
inputFormat | string | html |
By default, the event comments in the request are expected to be html formatted. If this is not the case, this parameter can be used to declare the format. Supported values are html and markdown . |
Sub-Calendars
A calendar has one to many sub-calendars. Sub-calendars represent categories of events. Events are always associated with at least one sub-calendar. Each sub-calendar has a color assigned which is used to visualize the sub-calendar and events assigned to it in the user interfaces.
Sub-Calendar Data Structure
A sub-calendar object has the following attributes:
Parameter | Type | Default | Description |
---|---|---|---|
id | int | generated | (read-only) Sub-calendar id |
name | string | - | Sub-calendar name, 1 to 100 characters. Sub-calendar names must be unique. |
active | bool | true |
Whether the sub-calendar is enabled or not |
color | int/string | 17 |
Color id. An integer between 1 and 48 from the list of predefined colors. Use of custom colors (e.g. #ABCD12 ) is not in use yet but might be eventually so you should handle them to be future-proof. |
overlap | bool | true |
Whether the sub-calendar can have multiple events overlapping each other |
readonly | bool | generated | (read-only) Whether the sub-calendar can be written to. This is a calculated attribute. Its value depends on the permission of the calendar key used for the request. |
creation_dt | date | generated | (read-only) Event creation date |
update_dt | date/null | generated | (read-only) Event last update date |
remote_id* | string/null | null |
(optional) Unique id of sub-calendar in a third party system. Up to 255 characters. |
Notes
- remote_id: This field is optional and can be used to track a relationship between sub-calendar records in Teamup and a third party system.
Get Sub-Calendar Collection
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars');
print $result->getBody();
curl "http://api.teamup.com/ks73ad7816e7a61b3a/subcalendars" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"subcalendars": [
{
"id": 730624,
"name": "Calendar 1",
"active": true,
"color": 19,
"overlap": true,
"creation_dt": "2015-04-29T09:50:28+00:00",
"update_dt": "2015-04-29T09:52:00+00:00",
"readonly": false
},
{
"id": 730625,
"name": "Calendar 2",
"active": true,
"color": 3,
"overlap": true,
"creation_dt": "2015-04-29T09:50:29+00:00",
"update_dt": "2015-04-29T09:52:02+00:00",
"readonly": true
}
]
}
This endpoint returns a list of all sub-calendars for the addressed calendar.
HTTP Request
GET /{calendarKey}/subcalendars
{calendarKey}
: Calendar key with read permission- Response: On success, returns an array of JSON-encoded sub-calendar objects.
Query Parameters
None
Get Sub-Calendar
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars/893615');
print $result->getBody();
curl "https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars/893615" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"subcalendar": {
"id": 893615,
"name": "Frank",
"active": true,
"color": 6,
"overlap": true,
"type": 0,
"attributes": [],
"creation_dt": "2015-06-01T13:51:39+00:00",
"update_dt": "2017-08-12T20:14:24+00:00",
"readonly": false
}
}
This endpoint retrieves a specific sub-calendar.
HTTP Request
GET /{calendarKey}/subcalendars/{subCalendarId}
{calendarKey}
: Calendar key with modify permission{subCalendarId}
: Id of sub-calendar to be retrieved- Response: On success, returns a JSON-encoded sub-calendar object.
Query Parameters
None
Create Sub-Calendar
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->post('https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars', [
'json' => [
"name" => "Melissa",
"active" => true,
"color" => 7,
"overlap" => true
]
]);
curl "https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars" \
-XPOST \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json' \
--data '{
"name": "Melissa",
"active": true,
"color": 7,
"overlap": true
}'
Expected response:
201 Created
Location: /ks73ad7816e7a61b3a/subcalendars/3619812
{
"subcalendar": {
"id": 3619812,
"name": "Melissa",
"active": true,
"color": 7,
"overlap": true,
"type": 0,
"attributes": [],
"creation_dt": "2017-08-16T09:06:09+00:00",
"update_dt": null,
"readonly": false
}
}
This API endpoint can be used to create a new sub-calendar.
HTTP Request
POST /{calendarKey}/subcalendars
{calendarKey}
: Calendar key with modify permission- Request body: The request body must contain an JSON-encoded sub-calendar object.
- Response: On success, the newly created sub-calendar is returned as a JSON-encoded sub-calendar object.
Query Parameters
None
Update Sub-Calendar
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->put('https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars/3619812', [
'json' => [
"id" => "3619812",
"name" => "Melissa Jane",
"active" => true,
"color" => 9,
"overlap" => true
]
]);
curl "https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars/3619812" \
-XPUT \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json' \
--data '{
"id": "3619812",
"name": "Melissa Jane",
"active": true,
"color": 9,
"overlap": true
}'
Expected response:
200 OK
{
"subcalendar": {
"id": 3619812,
"name": "Melissa Jane",
"active": true,
"color": 9,
"overlap": true,
"type": 0,
"attributes": [],
"creation_dt": "2017-08-16T09:06:09+00:00",
"update_dt": "2017-08-16T09:54:13+00:00",
"readonly": false
}
}
This API endpoint can be used to update an existing sub-calendar.
HTTP Request
PUT /{calendarKey}/subcalendars/{subCalendarId}
{calendarKey}
: Calendar key with modify permission{subCalendarId}
: Id of sub-calendar to be updated- Request body: The request body must contain an JSON-encoded sub-calendar object.
- Response: On success, the updated event is returned as a JSON-encoded sub-calendar object.
Query Parameters
None
Delete Sub-Calendar
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->delete('https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars/3619812');
curl "https://api.teamup.com/ks73ad7816e7a61b3a/subcalendars/3619812" \
-XDELETE \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json'
Expected response:
204 No Content
This endpoint lets you delete a sub-calendar.
HTTP Request
DELETE /{calendarKey}/subcalendars/{subCalendarId}
{calendarKey}
: Calendar key with modify permission{subCalendarId}
: Id of sub-calendar to be deleted- Request body: None
- Response: On success, returns an empty response with HTTP status 204.
Access Keys
Access keys provide access to the calendar. They are strings of 18 characters and can be used as part of a Web URL to load the calendar into a web browser. For example:
https://teamup.com/ks73ad7816e7a61b3a
Each access key has associated permissions that determine which sub-calendars are accessible and what operations can be performed on them.
Access Key Data Structure
A access key has the following attributes:
Parameter | Type | Default | Description |
---|---|---|---|
id | int | generated | (read-only) Access key id |
name | string | - | Access key name, 1 to 50 characters. Name must be unique. |
key | string | generated | Access key string, e.g. ks73ad7816e7a61b3a. This is a generated value that cannot be changed. |
active | bool | true |
Whether the access key is active or not |
admin | bool | false |
Flag indicating if the key has administrator permission and therefore can manipulate the calendar settings. |
share_type* | string | all_subcalendars |
Defines the sharing model used for this access key. See notes below. |
role* | string | Defines the permission the access key has on sub-calendars. See notes below. | |
subcalendar_permissions* | array | [] | An array of pairs of sub-calendar identifier and permission. See notes below. |
require_password | bool | false |
Indicates if a password is required when using this access key. |
has_password | bool | false |
Indicates if a password has been set for this access key. |
creation_dt | date | generated | (read-only) Creation date |
update_dt | date/null | generated | (read-only) Last update date |
Notes
share_type: Defines the sharing model configured for the access key. The sharing model defines how permissions for sub-calendars are defined. Two models are supported. A value of all_subcalendars means that the access key has the same permission for all sub-calendars. In this case the permission is defined in attribute role. A value of selected_subcalendars means that the access key has different permissions for different sub-calendars. In this case the permission for each sub-calendar is defined in array attribute subcalendar_permissions.
role: If attribute share_type is set to all_subcalendars, then this attribute defines the common permission the access key has for all the sub-calendars. For an overview of supported permission, see below.
subcalendar_permissions: If attribute share_type is set to selected_subcalendars, then this attribute defines the individual permissions this access key has for each sub-calendars. The value of this attribute is an array of key/value pairs. The key is the id of a sub-calendar, the value is the permission this access key has for that sub-calendar. Please see Create Access Key for an example. For an overview of supported permission, see below.
Supported Permissions: The following permission values are supported:
- admin
- modify
- modify_from_same_link
- add_only
- read_only
- modify_from_same_link_without_details
- add_only_without_details
- read_only_without_details
- no_access
For more details about each permission, visit the Settings -> Sharing section of your calendar.
Get Access Key Collection
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/keys');
print $result->getBody();
curl "http://api.teamup.com/ks73ad7816e7a61b3a/keys" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"keys": [
{
"id": 1351743,
"name": "Administrator",
"key": "ksa8fc0bedfd81ad77",
"active": true,
"admin": true,
"share_type": "all_subcalendars",
"role": "admin",
"subcalendar_permissions": [],
"require_password": false,
"has_password": false,
"email": null,
"user_id": null,
"creation_dt": "2015-06-01T13:51:39+00:00",
"update_dt": null
}, {
"id": 1351768,
"name": "Authenticated",
"key": "kscb1caezduce9f0a8",
"active": true,
"admin": false,
"share_type": "all_subcalendars",
"role": "modify_from_same_link",
"subcalendar_permissions": [],
"require_password": true,
"has_password": true,
"email": null,
"user_id": null,
"creation_dt": "2015-06-01T13:58:13+00:00",
"update_dt": "2015-06-01T13:58:40+00:00"
},{
"id": 4739545,
"name": "Linda",
"key": "ksa2wavezv53er56dg",
"active": true,
"admin": false,
"share_type": "selected_subcalendars",
"role": "mixed",
"subcalendar_permissions": {
"893615": "no_access",
"893616": "modify",
"3606264": "read_only",
"3606266": "add_only",
"3607516": "no_access",
"3620740": "read_only"
},
"require_password": false,
"has_password": false,
"email": null,
"user_id": null,
"creation_dt": "2017-08-27T17:41:40+00:00",
"update_dt": "2017-09-03T12:07:54+00:00"
}
]
}
This endpoint returns a list of all access keys for the calendar.
HTTP Request
GET /{calendarKey}/keys
{calendarKey}
: Calendar key with administration permission- Response: On success, returns an array of JSON-encoded access key objects.
Query Parameters
None
Get Access Key
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->get('https://api.teamup.com/ks73ad7816e7a61b3a/key/4788218');
curl "https://api.teamup.com/ks73ad7816e7a61b3a/key/4788218" \
-H 'Teamup-Token: API_KEY'
Expected response:
200 OK
{
"key": {
"id": 47788218,
"name": "Michelle",
"key": "ksxok7didijdgywijb",
"active": true,
"admin": false,
"share_type": "all_subcalendars",
"role": "read_only",
"subcalendar_permissions": [],
"require_password": false,
"has_password": false,
"creation_dt": "2017-09-04T06:42:38+00:00",
"update_dt": null
}
}
This API endpoint can be used to retrieve an access key.
HTTP Request
GET /{calendarKey}/keys/{keyId}
{calendarKey}
: Calendar key with administrator permission{keyId}
: Id of access key to be retrieved- Response: On success, the key is returned as a JSON-encoded access key object.
Query Parameters
None
Create Access Key
Example 1: Create a new access key with the same permission for all sub-calendars.
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->post('https://api.teamup.com/ks73ad7816e7a61b3a/keys', [
'json' => [
"name" => "Michelle",
"active" => true,
"admin" => false,
"require_password" => false,
"password" => "",
"share_type" => "all_subcalendars",
"role" => "read_only"
]
]);
curl "https://api.teamup.com/ks73ad7816e7a61b3a/keys" \
-XPOST \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json' \
--data '{
"name": "Michelle",
"active": true,
"admin": false,
"require_password": false,
"password": "",
"share_type":"all_subcalendars",
"role":"read_only"
}'
Expected response:
201 Created
Location: /ksxok7didijdgywijb/keys/47788218
{
"key": {
"id": 47788218,
"name": "Michelle",
"key": "ksxok7didijdgywijb",
"active": true,
"admin": false,
"share_type": "all_subcalendars",
"role": "read_only",
"subcalendar_permissions": [],
"require_password": false,
"has_password": false,
"creation_dt": "2017-09-04T06:42:38+00:00",
"update_dt": null
}
}
Example 2: Create a new access key with different permissions for different sub-calendars.
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->post('https://api.teamup.com/ks73ad7816e7a61b3a/keys', [
'json' => [
"name" => "Michelle",
"active" => true,
"admin" => false,
"require_password" => false,
"password" => "",
"share_type" => "selected_subcalendars",
"subcalendar_permissions": [
"893615" => "no_access",
"893616" => "read_only",
"3606264" => "add_only",
"3606266" => "read_only_without_details",
"3607516" => "modify",
"3620740" => "modify_from_same_link"
]
]
]);
curl "https://api.teamup.com/ks73ad7816e7a61b3a/keys" \
-XPOST \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json' \
--data '{
"name": "Michelle",
"active": true,
"admin": false,
"require_password": false,
"password": "",
"share_type":"selected_subcalendars",
"subcalendar_permissions": {
"893615": "no_access",
"893616": "read_only",
"3606264": "add_only",
"3606266": "read_only_without_details",
"3607516": "modify",
"3620740": "modify_from_same_link"
}
}'
Expected response:
201 Created
Location: /ks93k3juz54rd6faf6/keys/4778606
{
"key": {
"id": 4778606,
"name": "Michelle",
"key": "ks93k3juz54rd6faf6",
"active": true,
"admin": false,
"share_type": "selected_subcalendars",
"role": "mixed",
"subcalendar_permissions": {
"893615": "no_access",
"893616": "modify",
"3606264": "add_only",
"3606266": "no_access",
"3607516": "read_only",
"3620740": "no_access"
},
"require_password": false,
"has_password": false,
"creation_dt": "2017-09-04T05:42:18+00:00",
"update_dt": null
}
}
This API endpoint can be used to create a new access key.
HTTP Request
POST /{calendarKey}/keys
{calendarKey}
: Calendar key with administrator permission- Request body: The request body must contain an JSON-encoded access key object.
- Response: On success, the newly created access key is returned as a JSON-encoded access key object.
Query Parameters
None
Update Access Key
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->put('https://api.teamup.com/ks73ad7816e7a61b3a/keys/4709149', [
'json' => [
"id" => 4709149,
"name" => "Michelle",
"active" => true,
"admin" => false,
"require_password" => false,
"password" => "",
"share_type" => "all_subcalendars",
"role" => "read_only"
]
]);
curl "https://api.teamup.com/ks73a35htdd7a61b3a/keys/4709149" \
-XPUT \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json' \
--data '{
"id": 4709149,
"name": "Michelle",
"active": true,
"admin": false,
"require_password": false,
"password": "",
"share_type": "all_subcalendars",
"role": "read_only"
}'
Expected response:
200 OK
{
"key": {
"id": 4709149,
"name": "Michelle",
"key": "ks3zf99udzd6dzd6vd",
"active": true,
"admin": false,
"share_type": "all_subcalendars",
"role": "read_only",
"subcalendar_permissions": [],
"require_password": false,
"has_password": false,
"creation_dt": "2017-08-21T20:52:03+00:00",
"update_dt": "2017-09-04T13:14:39+00:00"
}
}
This API endpoint can be used to update an existing access key.
HTTP Request
PUT /{calendarKey}/keys/{keyId}
{calendarKey}
: Calendar key with administration permission{keyId}
: Id of access key to be updated- Request body: The request body must contain an JSON-encoded access key object.
- Response: On success, the updated access key is returned as a JSON-encoded access key object.
Query Parameters
None
Delete Access Key
Example:
<?php
$client = new GuzzleHttp\Client(['headers' => ['Teamup-Token' => 'API_KEY']]);
$result = $client->delete('https://api.teamup.com/ks73ad7816e7a61b3a/keys/47463537');
curl "https://api.teamup.com/ks73ad7816e7a61b3a/keys/47463537" \
-XDELETE \
-H 'Teamup-Token: API_KEY' \
-H 'Content-type:application/json'
Expected response:
204 No Content
This endpoint can be used to delete an access key.
HTTP Request
DELETE /{calendarKey}/keys/{keyId}
{calendarKey}
: Calendar key with administrator permission{keyId}
: Id of access key to be deleted- Request body: None
- Response: On success, returns an empty response with HTTP status 204.
Colors
The following table lists all colors supported for sub-calendars and custom field options.
Color ID | Hex | Color ID | Hex |
---|---|---|---|
33 | #553711 |
20 | #133897 |
34 | #724f22 |
19 | #2951b9 |
35 | #9c6013 |
18 | #4770d8 |
5 | #ca7609 |
17 | #668CB3 |
6 | #f16c20 |
21 | #1a5173 |
7 | #f58a4b |
22 | #1a699c |
8 | #d2b53b |
23 | #0080a6 |
36 | #f6c811 |
24 | #4aaace |
3 | #a01a1a |
28 | #176413 |
37 | #ce1212 |
27 | #2d850e |
2 | #cf2424 |
26 | #5a8121 |
1 | #f2665b |
25 | #88b347 |
38 | #b20d47 |
29 | #0f4c30 |
39 | #d8135a |
30 | #386651 |
40 | #e81f78 |
31 | #00855b |
41 | #f5699a |
32 | #4fb5a1 |
12 | #7a0f60 |
42 | #5c1c1c |
11 | #9d3283 |
4 | #7e3838 |
10 | #b84e9d |
43 | #a55757 |
9 | #d96fbf |
44 | #c37070 |
13 | #542382 |
45 | #000000 |
14 | #7742a9 |
46 | #383838 |
15 | #8763ca |
47 | #757575 |
16 | #b586e2 |
48 | #a3a3a3 |
Errors
The Teamup API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Invalid request |
401 | Unauthorized -- Accessing a password-protected resource without providing authentication |
403 | Forbidden -- Invalid credentials to access the given resource |
404 | Not Found -- Resource missing, not found or not visible by your request |
405 | Method Not Allowed -- You tried to access a resource with an invalid method (i.e. GET instead of POST ) |
406 | Not Acceptable -- You requested a format that is not json |
415 | Unsupported Media Type -- The server is refusing to service the request because the payload is in a format not supported. Make sure you have the headers Content-Type: application/json and Content-Encoding properly set. |
500 | Internal Server Error -- Application error on our side, we will look into it but feel free to reach out to us with details. |
503 | Service Unavailable -- We are temporarially offline for maintanance. Please try again later. |
Error Response Format
Example generic 400 response
400 Bad Request
{
"error": {
"id": "bad_request",
"title": "Invalid request",
"message": "The request parameters were invalid."
}
}
Example validation error on event creation
400 Bad Request
{
"error": {
"id": "validation_error",
"title": "Invalid event data",
"message": [
"The event title is too long. The maximum length is 255 characters.",
"The value of the <i>Who<\/i> field is too long. The maximum length is 255 characters."
]
}
}
All API errors are returned in the format you can see on the right. The error id
is a constant string
that you can rely on not to change. The title
and message
are translated strings that
can be used to display errors to end users.
The message
can also be an array in case there are multiple errors, for example when creating an
event you may get multiple validation errors, see the second block on the right.
The message
may contain HTML and should be considered safe for XSS purposes, but you can also
safely strip all tags before rendering it.
Error IDs
Here is a list of known error ids our API may return and a short explanation of what they mean.
Error ID | HTTP Status Code | Explanation |
---|---|---|
maintenance_active | 503 | The application is in maintenance mode. |
unexpected_error | 500 | The application experienced an unexpected error. |
auth_required | 401 | Authentication is required to access this calendar key, you must provide a Teamup-Password header. |
no_permission | 403 | You do not have the permissions to do this, you may be using a readonly calendar key for example. |
event_add_only_permission_expired | 400 | If you use an add-only calendar key, events created can not be updated via the API. |
calendar_not_found | 404 | You use an invalid calendar key. |
event_not_found | 404 | The event id was not found. |
field_definition_not_found | 404 | The field id was not found. |
validation_error | 400 | The provided data did not validate. |
event_overlapping | 400 | You tried to create an event conflicting with an existing event on a sub-calendar that does not allow overlap. |
event_validation | 400 | You provided invalid event data when updating or creating an event. See the message key for details. |
event_validation_conflict | 400 | You tried to update or delete an event using an outdated version property because someone else modified it since you last read the event. |
invalid_timezone_identifier | 400 | Invalid timezone identifier provided. |
invalid_api_key | 400 | Invalid API Key provided. |
field_id_reserved | 400 | This is a built-in or reserved field ID, so a field with that ID cannot be directly created or deleted. |
field_id_not_unique | 400 | There is already a field with that ID. |
field_type_reserved | 400 | This is a built-in field type, so a field with that type cannot be directly created. |
field_limit_exceeded | 400 | Creating or enabling this field would make the calendar exceed its subscription plan's limit on the number of custom fields. |
field_choice_limit_exceeded | 400 | Creating or enabling this field would make it exceed its calendar's subscription plan's limit on the number of custom field choices. |
field_choice_removed | 400 | You attempted to update a field definition and omitted a choice definition that was previously present. |
API Usage Best Practices
Scheduled Synchronization
If your API use case requires automatic periodic syncing with Teamup Calendar, it should not sync too frequently and make reasonable use of API calls.
If you do scheduled syncing, you should avoid having it automatically sync at a particular time of the day (for example: on the hour, at midnight, etc).
This might cause our servers to have spikes in traffic at these particular times, which is bad for everyone. It is better to pick a random time offset. For example sync at 13 past instead of 00 on every hour.
Rate Limiting
The API usage is currently unrestricted, but Teamup Calendar reserves the right to impose rate limiting on a per-application basis at a future time if we determine that a poorly designed application is using a disproportionate amount of our resources.