Introduction

The Events endpoint returns information about the C42 Events related to the authorized user. The response includes the general details and also describes the relation between the requestor and the event.

GET /events/

GET /v2/events

Authorization

Server side API Token or Authentication Action Token

Query Parameters

Name Type Description
ids array specific id's of events
service_ids array id's of services
calendar_ids array id's of calendars, events are related to all
event_types array one or more Event Types
geo_circles array one or more Geo Circles
length int length in meters of event types arrive_by, depart_from and route
order_by string parameter to order on: "sync_token", "due", "distance"
sync_token int Sync Token
order_asc boolean Whether to order in ascending or descending order (default: true)

Allowed operators

Name Type Description
calendar_ids__or array id's of calendars, events are related to ANY
length__lt int Less than length
length__gt int Greater than length

Generic parameters

Name Type Description
offset int offset inside entire set of results (default: 0)
page int amount of results to return per page (default: 10)

Implementation notes

  • when requesting multiple specific events, the response will not be equally ordered
  • Whatever filter is set, the endpoint will only returns events the requestor has access to
  • Order by distance is only allowed when exactly one geo_circle is passed along

Response

Status-Code: 200 OK
{
  "meta_data": {
    "count": 8,
    "sync_token": 23924166,
    "offset": 0
  },
  "data": [
    {
      "id": "32319dc9589464246699ecd6e5300458_14430973869068",
      "event_type": "normal",
      "creator": {},
      "created": "2015-09-24T12:23:06.906807Z",
      "modified": "2015-09-24T12:23:06.906811Z",
      "invitation": {},
      "calendar_ids": [],
      "start": "2015-09-24T00:00:00.000000Z",
      "end": "2018-06-20T00:00:00.000000Z",
      "start_timezone": "Europe/Amsterdam",
      "end_timezone": "Europe/Amsterdam",
      "all_day": true,
      "title": "HOME",
      "description": null,
      "color": null,
      "icon": null,
      "logo": null,
      "source_url": null,
      "time_buffer": null,
      "start_location": {
        "id": "265d7fe5ce987387bc9e77d64600c71e05dc015b",
        "text": "Lloydstraat 138, 3024, Rotterdam",
        "address": "Lloydstraat 138",
        "postcode": "3024",
        "city": "Rotterdam",
        "geo": {
          "latitude": 51.9030818,
          "longitude": 4.4605326
        },
        "labels": []
      },
      "end_location": null,
      "recurrence": false,
      "recurrence_parent": null,
      "sync_token": 23924087,
      "length": null,
      "is_suggestion": null,
      "due": null,
      "state": null,
      "is_invitation": false,
      "rsvp_status": "attending",
      "permission": "subscribed_write",
      "previous_permission": null
    },
   ...
  ]
}

Fields describing the general event

Name Description
id Specifies the unique id that identifies the event
event_type Specifies the event type, e.g. todo or route
is_suggestion Specifies whether the event is autogenerated by the system, so it is a suggestion based on the preferences of he user
creator Person object that created that event
modified Date of the last modification
start Specifies the start Datetime
end Specifies the end Datetime
start_timezone Specifies the Timezone of the start time
end_timezone Specifies the Timezone of the end time
all_day Specifies whether the event is an all day event this should have a true as a value
due Specifies the Due Datetime
state Specifies the internal state of the Event
title Specifies the title
description Specifies the description
color Specifies the color, this color should be in hsla format
icon Specifies the url where to reach the event icon
logo Specifies the url where to reach the event image
source_url Specifies the Url source of the event (If the event is imported from an external service (ics) this attribute ontains the URL where to reach the event information from the source)
start_location Specifies the Location where the event starts
end_location Specifies the Location where the event ends
recurrence Specifies whether the event is a recurrence event
recurrence_parent Specifies the ID of the related recurrence event
related_event Specifies the list of events ID's related to this event
sync_token Specifies the sync token
time_buffer Defines the temporal relation between trips and their related event in seconds. Used when event has event_type rrive_by or depart_from and event has a defined related_event.
trip Specifies all the Trip data for trip. (Present when event_type equals arrive_by, depart_from or route)
length Specifies the length of the trip in meters (Present when event_type equals arrive_by, depart_from or route)

Fields describing the relation between the event and the requestor

Name Description
is_invitation Specifies whether the event is an invitation.
invitation Specifies meta information about the invitation: Invitation object
rsvp_status Specifies the string that defines the RSVP status of the user at this event.
calendar_ids Specifies the list of calendar ID's that requestor has this event in
permission Specifies the string that defines the Permission that the user have over this event. This is an user related attribute
previous_permission Specifies the previous Permission that the user had over this event. This is an user related attribute

Examples

Using ordering: Get events belonging to a certain calendar within a certain geographic range, orderder by distance:

GET: /events/?calendar_ids=[abc123]&geo_circles=[(52.28297176 5.27424839 5000)]&order_by=distance

Using operators: Get trips longer than 15km, that are in either calendar 'abc1' or calendar 'abc2'

GET: /events/?event_types=[arrive_by,depart_from]&length__gt=15000&calendar_ids__or=[abc1,abc2]

Synchronisation: Get events that changed since last retrieval

GET: /events/?sync_token=128973981273

GET /events/{event_id}/

GET: /v2/events/{event_id}/

Authorization

Server side API Token or Authentication Action Token

Query Parameters

Name Type Description
event_id string Unique identifier representing a specific event

Response

Status-Code: 200 OK
{
  "meta_data": {
    "count": 1,
    "sync_token": 23924166,
    "offset": 0
  },
  "data": [
    {
      "id": "32319dc9589464246699ecd6e5300458_14430973869068",
      "event_type": "normal",
      "creator": {},
      "created": "2015-09-24T12:23:06.906807Z",
      "modified": "2015-09-24T12:23:06.906811Z",
      "invitation": {},
      "calendar_ids": [],
      "start": "2015-09-24T00:00:00.000000Z",
      "end": "2018-06-20T00:00:00.000000Z",
      "start_timezone": "Europe/Amsterdam",
      "end_timezone": "Europe/Amsterdam",
      "all_day": true,
      "title": "HOME",
      "description": null,
      "color": null,
      "icon": null,
      "logo": null,
      "source_url": null,
      "time_buffer": null,
      "start_location": {
        "id": "265d7fe5ce987387bc9e77d64600c71e05dc015b",
        "text": "Lloydstraat 138, 3024, Rotterdam",
        "address": "Lloydstraat 138",
        "postcode": "3024",
        "city": "Rotterdam",
        "geo": {
          "latitude": 51.9030818,
          "longitude": 4.4605326
        },
        "labels": []
      },
      "end_location": null,
      "recurrence": false,
      "recurrence_parent": null,
      "sync_token": 23924087,
      "length": null,
      "is_suggestion": null,
      "due": null,
      "state": null,
      "is_invitation": false,
      "rsvp_status": "attending",
      "permission": "subscribed_write",
      "previous_permission": null
    },
   ...
  ]
}

Fields describing the general event

Same as GET: /v2/events/

Fields describing the relation between the event and the requestor

Same as GET: /v2/events/


POST /events/

POST: /v2/events/

Authorization

Server side API Token or Authentication Action Token

Post Parameters

Name Type Description
event_type string Specifies the event type, e.g. todo or route
is_suggestion boolean Specifies whether the event is autogenerated by the system, so it is a suggestion based on the preferences of he user
start string Specifies the start Datetime
end string Specifies the end Datetime
start_timezone string Specifies the Timezone of the start time
end_timezone string Specifies the Timezone of the end time
all_day boolean Specifies whether the event is an all day event this should have a true as a value
due string Specifies the Due Datetime
title string Specifies the title
description string Specifies the description
color string Specifies the color, this color should be in hsla format
icon string Specifies the url where to reach the event icon
logo string Specifies the url where to reach the event image
source_url string Specifies the Url source of the event (If the event is imported from an external service (ics) this attribute ontains the URL where to reach the event information from the source)
start_location object Specifies the Location where the event starts
end_location object Specifies the Location where the event ends
related_event string Specifies the list of events ID's related to this event
time_buffer int Defines the temporal relation between trips and their related event in seconds. Used when event has event_type arrive_by or depart_from and event has a defined related_event.
rsvp_status string Specifies the string that defines the RSVP status of the user at this event.
calendar_ids array Specifies the list of calendar ID's that requestor has this event in

Implementation notes

  • Created events WILL contain a new generated id
  • Created events WILL be extended with the following attributes and their default values
    • sync_token, event_type, permission, created, modified & creator
  • Created events COULD be enriched to contain more specific location data
    • Geocoding: The posted event contains one or more locations without geo-position. The geo-position COULD be added based on location text, city, address and postcode.
    • Reverse geocoding: The posted event contains one or more locations with only geo-positions. Location text, city, address and postcode COULD be added.

Response

Status-Code: 200 OK
{
  "meta_data": {
    "count": 1,
    "sync_token": 23924166,
    "offset": 0
  },
  "data": [
    {
      "id": "32319dc9589464246699ecd6e5300458_14430973869068",
      "event_type": "normal",
      "creator": {},
      "created": "2015-09-24T12:23:06.906807Z",
      "modified": "2015-09-24T12:23:06.906811Z",
      "invitation": {},
      "calendar_ids": [],
      "start": "2015-09-24T00:00:00.000000Z",
      "end": "2018-06-20T00:00:00.000000Z",
      "start_timezone": "Europe/Amsterdam",
      "end_timezone": "Europe/Amsterdam",
      "all_day": true,
      "title": "HOME",
      "description": null,
      "color": null,
      "icon": null,
      "logo": null,
      "source_url": null,
      "time_buffer": null,
      "start_location": {
        "id": "265d7fe5ce987387bc9e77d64600c71e05dc015b",
        "text": "Lloydstraat 138, 3024, Rotterdam",
        "address": "Lloydstraat 138",
        "postcode": "3024",
        "city": "Rotterdam",
        "geo": {
          "latitude": 51.9030818,
          "longitude": 4.4605326
        },
        "labels": []
      },
      "end_location": null,
      "recurrence": false,
      "recurrence_parent": null,
      "sync_token": 23924087,
      "length": null,
      "is_suggestion": null,
      "due": null,
      "state": null,
      "is_invitation": false,
      "rsvp_status": "attending",
      "permission": "subscribed_write",
      "previous_permission": null
    },
   ...
  ]
}

Error Response

@todo

Examples

Most minimal creation in the form of a todo

The most minimal event consists of todo, as it doesn't requires start, end, start_timezone or end_timezone to be set. This example shows clearly which fields are being defaulted and which are being send back empty.

    // postdata
    {
        "event_type": "todo"
    }
# Response (including automatically generated and defaulting fields)
    {
        "data": [
            {
              # ORIGINAL FIELD
                "event_type": "todo",
              # AUTOMATICALLY GENERATED FIELDS
                "id": "897dsah8789had897had873b4",
                "created": "2015-02-12T15:19:21:00.000000Z",
                "modified": "2015-02-12T15:19:21:00.000000Z",
                "sync_token": 142,
                "creator": {
                    "id": "987jbkhjasd7563ghjva78",
                    "first_name": "Your",
                    "last_name": "Name"
                },
              # AUTOMATICALLY DEFAULTING FIELDS
                "permission": "subscribed_write",
                "calendar_ids": [],
              # EMPTY FIELDS
                "previous_permission": null,
                "is_suggestion": null,
                "is_invitation": null,
                "invitation": null,
                "rsvp_status": null,
                "start": null,
                "end": null,
                "start_timezone": null,
                "end_timezone": null,
                "due": null,
                "all_day": null,
                "title": null,
                "description": null,
                "color": null,
                "logo": null,
                "source_url": null,
                "start_location": null,
                "end_location": null,
                "recurrence": null,
                "recurrence_parent": null,
                "related_event": null,
                "trip": null,
                "length": null
            }
        ],
        "meta_data": {
            "sync_token": 142
        }
    }

Creating a simple event into a calendar

This example shows a regular usecase, where an event is created in one of the accessible calendars, together with a title and a description.

  • The event_type will default to normal
  • normal events require start and end to be set
  • These dates require their timezones to be set with start_timezone and end_timezone
    // postdata
    {
        "calendar_ids": ["42b42b42b42b42b42b42b42b42b42b42b42b42b4"],
        "start": "2015-02-12T15:00:00:00.000000Z",
        "start_timezone": "Europe/Amsterdam",
        "end": "2015-02-12T15:30:00:00.000000Z",
        "end_timezone": "Europe/Amsterdam",
        "title": "Nice title",
        "description": "A nice description",
    }
# Response, including automatically generated and defaulting fields
    {
        "data": [
            {
              # ORIGINAL FIELDS
                "id": "897dsah8789had897had873b4",
                "calendar_ids": ["42b42b42b42b42b42b42b42b42b42b42b42b42b4"],
                "start": "2015-02-12T15:00:00:00.000000Z",
                "start_timezone": "Europe/Amsterdam",
                "end": "2015-02-12T15:30:00:00.000000Z",
                "end_timezone": "Europe/Amsterdam",
                "title": "Nice title",
                "description": "A nice description",
              # AUTOMATICALLY DEFAULTING FIELDS
                "event_type": "normal",
                "permission": "subscribed_write",
              # EMPTY FIELDS
                "previous_permission": null,
                "is_suggestion": null,
                "is_invitation": null,
                "invitation": null,
                "rsvp_status": null,
                "all_day": null,
                "color": null,
                "logo": null,
                "source_url": null,
                "start_location": null,
                "end_location": null,
                "recurrence": null,
                "recurrence_parent": null,
                "related_event": null,
                "trip": null,
                "length": null
            }
        ],
        "meta_data" : {
            "sync_token": 143
        }
    }

Special case: Event creation with location id

Prefered way of posting locations in events.

    // postdata (partial)
    {
        ...
        "start_location": {
            "id": "789ash9d87a98sdh7987ads",
        }
        ...
    }
# Response (partial), including id & extended location information
    {
        "data": [
            {
              ...
                "start_location": {
                    "id": "789ash9d87a98sdh7987ads",
                    "text": "Dorpstraat 1, 2600 AE",
                    "address": "Dorpstraat 1",
                    "postcode": "2600 AE",
                    "city": "Delft",
                    "geo": {
                        "latitude": 52.001,
                        "longitude": 4.3065
                    }
                }
              ...
            }
        ],
        "meta_data" : {
            ...
        }
    }

Event creation with automatic geocoding

The server will try to perform geocoding when an event is posted that contains a location (either start_location or end_location) that has no geo object. This missing latitude, longitude will then automatically be filled in based on the text, or based on the city, address, postcode fields.

    // postdata (partial)
    {
        ...
        "start_location": {
            "text": "Dorpstraat 1, 2600 AE",
        }
        ...
    }
# Response (partial), including id & enriched location
    {
        "data": [
            {
              ...
                "start_location": {
                    "text": "Dorpstraat 1, 2600 AE",
                    "address": "Dorpstraat 1",
                    "postcode": "2600 AE",
                    "city": "Delft",
                    "geo": {
                        "latitude": 52.001,
                        "longitude": 4.3065
                    }
                }
              ...
            }
        ],
        "meta_data" : {
            ...
        }
    }

Event creation with automatic reverse geocoding

The server will try to perform reverse geocoding when an event is posted that contains a location (either start_location or end_location) that has a geo object, but misses one of the fields for text, address, postcode or city. These missing fields will then automatically be filled in.

    // postdata (partial)
    {
        ...
        "start_location": {
            "geo": {
                "latitude": 52.001,
                "longitude": 4.3065
            }
        }
        ...
    }
# Response (partial), including id & enriched location
    {
        "data": [
            {
              ...
                "start_location": {
                    "text": "Dorpstraat 1, 2600 AE",
                    "address": "Dorpstraat 1",
                    "postcode": "2600 AE",
                    "city": "Delft",
                    "geo": {
                        "latitude": 52.001,
                        "longitude": 4.3065
                    }
                }
              ...
            }
        ],
        "meta_data" : {
            ...
        }
    }

PATCH /events/{event_id}/

PATCH /v2/events/{event_id}/

Authorization

Server side API Token or Authentication Action Token

Patch Parameters

Name Type Description
event_type string Specifies the event type, e.g. todo or route
is_suggestion boolean Specifies whether the event is autogenerated by the system, so it is a suggestion based on the preferences of he user
start string Specifies the start Datetime
end string Specifies the end Datetime
start_timezone string Specifies the Timezone of the start time
end_timezone string Specifies the Timezone of the end time
all_day boolean Specifies whether the event is an all day event this should have a true as a value
due string Specifies the Due Datetime
title string Specifies the title
description string Specifies the description
color string Specifies the color, this color should be in hsla format
icon string Specifies the url where to reach the event icon
logo string Specifies the url where to reach the event image
source_url string Specifies the Url source of the event (If the event is imported from an external service (ics) this attribute ontains the URL where to reach the event information from the source)
start_location object Specifies the Location where the event starts
end_location object Specifies the Location where the event ends
related_event string Specifies the list of events ID's related to this event
time_buffer int Defines the temporal relation between trips and their related event in seconds. Used when event has event_type arrive_by or depart_from and event has a defined related_event.
rsvp_status string Specifies the string that defines the RSVP status of the user at this event.
calendar_ids array Specifies the list of calendar ID's that requestor has this event in

Implementation notes

  • start & end:
    • start should always be before end
  • start, end & event_type:
    • When the event type is normal, start and end should always both be set
  • start, end and all_day:
    • When all_day is set to true, the start and end should only contain the date and no time, e.g. 2015-02-12T00:00:00:00.000000Z
  • start & start_timezone:
    • When start is set, start_timezone also always needs to be set. This holds true even if you are setting start_time to null (for todo events).
  • end & end_timezone:
    • When end is set, end_timezone also always needs to be set. This holds true even if you are setting start_time to null (for todo events).
  • event_type & related_event_id:
    • When the event type is not arrive_by or depart_from, related event can't be set
  • rsvp_status & calendar_ids:
    • When you want to change your rsvp on a read-only event or add a read-only event to one of your calendars, make sure to pas ONLY one or both of these fields. Anythng else mentioned in the payload will result in a 'forbidden' error message.

Response

Status-Code: 200 OK
{
  "meta_data": {
    "count": 1,
    "sync_token": 23924166,
    "offset": 0
  },
  "data": [
    {
      "id": "32319dc9589464246699ecd6e5300458_14430973869068",
      "event_type": "normal",
      "creator": {},
      "created": "2015-09-24T12:23:06.906807Z",
      "modified": "2015-09-24T12:23:06.906811Z",
      "invitation": {},
      "calendar_ids": [],
      "start": "2015-09-24T00:00:00.000000Z",
      "end": "2018-06-20T00:00:00.000000Z",
      "start_timezone": "Europe/Amsterdam",
      "end_timezone": "Europe/Amsterdam",
      "all_day": true,
      "title": "HOME",
      "description": null,
      "color": null,
      "icon": null,
      "logo": null,
      "source_url": null,
      "time_buffer": null,
      "start_location": {
        "id": "265d7fe5ce987387bc9e77d64600c71e05dc015b",
        "text": "Lloydstraat 138, 3024, Rotterdam",
        "address": "Lloydstraat 138",
        "postcode": "3024",
        "city": "Rotterdam",
        "geo": {
          "latitude": 51.9030818,
          "longitude": 4.4605326
        },
        "labels": []
      },
      "end_location": null,
      "recurrence": false,
      "recurrence_parent": null,
      "sync_token": 23924087,
      "length": null,
      "is_suggestion": null,
      "due": null,
      "state": null,
      "is_invitation": false,
      "rsvp_status": "attending",
      "permission": "subscribed_write",
      "previous_permission": null
    },
   ...
  ]
}

Error Responses

@todo

Examples

Using PATCH to subscribe to calendars or unsubscribe from calendars

Say event_42 is both in calendar_id1 & calendar_id2 the following PATCH operation can be performed to add new_calendar_id3 and new_calendar_id4 to it:

  {
    calendar_ids : [calendar_id1, calendar_id2, new_calendar_id3, new_calendar_id4]
   }

Similarly, the following PATCH operation will remove it from all calendars but calendar_id1:

    {
        calendar_ids : [calendar_id1, calendar_id3, calendar_id4]
    }

Using PATCH to remove the location of an event

It is possible to 'clean' the location field of an event setting it to null

...
"time_buffer": null,
"start_location": null,
"end_location": null,
...

Example Use Cases

How to: perform synchronization of data

For synchronization the following query parameters are important to understand:

name Type Descriptions
sync_token integer the sync_token value to filter above (default: 0)
order_by string parameter to order on
order_asc boolean whether to order in ascending or descending order (default: true)
limit integer number of items per page (default: 10)

In order to not miss any items during synchronization it is vital to:

  • Make sure to set the sync_token to be equal to the sync_token of the last received item
    • Upon start of the synchronization this sync_token be equal to 0
  • Make sure to set order_by to sync_token
  • Make sure to keep order_asc set to true
  • Make sure to pick a reasonable limit, or keep the default value of 10

The following example will show how to use these parameters together and perform a stable synchronization process.

Synchronization of a small set of items

Imagine you would like to synchronize the following set of items:

Item ID Sync token
A 2123
B 3634
C 3855
D 4546
E 5546

1) Initial synchronization call

As upon the start of the synchronization process we don't know how high the sync_token of the different items are, we just send along a sync_token of 0 and request the first page. Note that:

  • in order to keep things simple to understand, we use a small set of items and also use a very low pagination size.
  • we don't send along order_by_asc=true as this is the default value
GET: /items/?sync_token=0&order_by=sync_token&limit=2

The response will contain:

  • Item A (with sync_token 2123)
  • Item B (with sync_token 3634)

2) Subsequent synchronization calls

As we now know that the last item we got has sync_token 3634, we can pass this along in the next call and retrieve the next set.

GET: /items/?sync_token=3634&order_by=sync_token&limit=2

The response will contain:

  • Item C (with sync_token 3855)
  • Item D (with sync_token 4546)

3) Final request

The pagination can continu, until no items are left anymore. This is indicated by the fact that the amount of returned items is less than the limit set in the query parameters.

GET: /items/?sync_token=4546&order_by=sync_token&limit=2

The response will contain:

  • Item E (with sync_token 5546)

Only one item is retrieved, indicating that the synchronization process is done. Note that in order to further optimize the synchronization process, the client can also choose to now save the token as stated in the meta_data of the response. This token will indicate the last possible sync_token within C42 and can be used to start the next synchronization process.

Note about updates to items during synchronization

If an item is updated during pagination, it will move to the last page again (as it will receive the highest sync token), ensuring that no items will be missed

If for instance in the example above Item C is updated, the sync token of the Item C will become a number higher then 5546, and will show up on the last page.