Skip to content

Latest commit

 

History

History
703 lines (492 loc) · 17.6 KB

JSON-API.md

File metadata and controls

703 lines (492 loc) · 17.6 KB

ESN sabre/dav JSON API

The ESN Frontend for SabreDAV adds a JSON REST api for common operations from the web frontend. All methods that return content will use the application/json or application/hal+json format.

Resources

iTip processing request object

Allows Sabre to process iTip messages.

{
  "method": "REQUEST",
  "sender": "a@b.com",
  "recipient": "c@d.com",
  "uid": "the iTip UID",
  "recurrence-id": "the iTip RECURRENCE-ID, if any",
  "sequence": "0",
  "dtstamp": "the iTip DTSTAMP",
  "ical": "raw UTF-8 ical string"
}

time range query object

Make a time range query on one or more calendars. The calendar scope may be specified either as the complete relative url, the relative url excluding the sabre/dav base uri. The calendar scope may or may not have the .json suffix appended.

{
    "scope": { "calendars": [ "/path/to/calendar", ... ] },
    "match": {
        "start": "19700101T010101",
        "end": "20160101T010101"
    }
}

UID query object

Used to query an event by its UID.

{
    "uid": "the event UID"
}

dav:root

A calendar root collection, which contains the calendar homes.

{
    "_links": { "self": { "href": "/calendars.json" } },
    "_embedded": { "dav:home": [ <dav:home resources>... ] }
}

dav:home

A collection containing calendars.

{
    "_links": { "self": { "href": "/calendars/{calendarHomeId}.json" } },
    "_embedded": { "dav:calendar": [ <dav:calendar resources>... ] }
}

dav:calendar

Describes the properties of a caldav calendar. The list of items is optional and may be omitted on some requests.

{
    "_links": { "self": { "href": "/path/to/calendar.json" } },
    "_embedded": { "dav:item": [ <dav:item resources>... ] },
    "dav:name": "events",
    "caldav:description": null,
    "calendarserver:ctag": "http://sabre.io/ns/sync/122",
    "apple:color": "#FD8208FF",
    "apple:order": "1"
}

dav:addressbook

Describes the properties of a carddav address book.

{
    "_links": { "self": { "href": "/path/to/book.json" } },
    "_embedded": { "dav:item": [ <dav:item resources>... ] },
    "dav:syncToken": "sync-token"
}

dav:item

This may be a calendar item or an address book card. The format used is jCal or jCard, respectively.

POST /query.json

Queries one or more calendars for events. The dav:calendar resources will include their items.

Request JSON Object:

A time range query object, which must define a scope of calendars to be queried.

Status Codes:

  • 200 OK: Query has succeeded and results are returned
  • 400 Bad Request: Missing keys in the request object

Response:

{
  "_links": { "self": { "href": "/query.json" } },
  "_embedded": { "dav:calendar": [ <dav:calendar resources>... ] }
}

REPORT /calendars/{calendarHomeId}/{calendarId}.json

Query a specific calendar for events.

Request JSON Object:

A time range query object. The scope object within the query is not used for this request, instead the specific calendar is queried.

{
    "match": {
      "start": "20160606T000000",
      "end": "20160613T000000"
    }
}

Status Codes:

  • 200 OK: Query has succeeded and results are returned
  • 400 Bad Request: Missing keys in the request object

Response:

A dav:calendar resource, with the dav:item expanded.

REPORT /calendars/{calendarHomeId}

Query all calendars of the given home for an event with a given UID.

Request JSON Object:

A UID query object.

{
    "uid": "the event UID"
}

Status Codes:

  • 200 OK: Query has succeeded and results are returned
  • 400 Bad Request: Missing keys in the request object
  • 404 Not Found: No event with the given UID found

Response:

A dav:calendar resource, with the dav:item expanded.

POST /calendars/{userId}/events

Query events by exact, case-sensitive UID across selected calendar sources.

POST /calendars/{userId}/events?teamCalendars=true
Content-Type: application/json

{"uid":"xyz"}

Source selectors accept true or false (default: false):

  • ownCalendar: the home user's calendars.
  • teamCalendars: team calendars.
  • publicSubscriptions: subscribed public calendars.
  • sharedCalendars: calendars delegated by other users.
  • resourceCalendars: resource calendars.

Only sources in the requested home that the caller can read are searched. Event privacy rules apply.

  • 200: _embedded["dav:item"] contains events with their source hrefs and full event data; empty when no match or no sources are selected.
  • 400: invalid selectors or body (only a non-empty string uid is supported).
  • 415: Content-Type is not application/json.

POST /calendars/{calendarHomeId}/{calendarId}.json

Define sharees (add or remove) on a particular calendar.

Request JSON Object:

{
    "share": {
      "set": [
        {
          "dav:href": "mailto:joe@example.org",
          "common-name": "Joe Shmoe",
          "summary": "something",
          "dav:read-write": true
        }
      ],
      "remove": [
        {
          "dav:href": "mailto:jane@example.org"
        }
      ]
    }
}

Status Codes:

  • 200 OK: Query has succeeded
  • 400 Bad Request: Missing keys in the request object

GET /calendars.json

List all calendar homes and calendars in the calendar root.

Status Codes:

  • 200 OK: Query has succeeded and results are returned

Response:

A dav:root resource, expanded down to all dav:calendar resouces.

GET /calendars/{calendarHomeId}.json

List all calendars in the calendar home.

Query Parameters:

  • sharedPublic: List only personal calendar that have public_right
  • personal: include only personal calendars in the result list (can be combined with sharedPublicSubscription and sharedDelegationStatus)
  • sharedPublicSubscription: include only subscritions to public calendars from the result list (can be combined with personal and sharedDelegationStatus)
  • sharedDelegationStatus: include only shared calendars with the given invite status (accepted or noresponse) (can be combined with personal and sharedPublicSubscription)

Status Codes:

  • 200 OK: Query has succeeded and results are returned

Response:

A dav:home resource, containing all dav:calendar resources in it.

GET /calendars/{calendarHomeId}/{calendarId}.json

Return information about a calendar

Status Codes:

  • 200 OK: Query has succeeded and results are returned

Response:

A dav:calendar resources.

POST /calendars/{calendarHomeId}.json

Create a calendar in the specified calendar home.

Request JSON Object:

A dav:calendar object, with an additional member "id" which specifies the id to be used in the calendar url.

Status Codes:

  • 201 Created: The calendar has been created
  • 400 Bad Request: Missing keys in the request object

GET /addressbooks/{addressbookHomeId}.json

List address books in the addressbookHome that the current principal can read.

Query Parameters:

  • public: To include public address books.
  • personal: To include personal address books.
  • subscribed: To include subscribed address books.
  • shared: To list only shared address books.
  • shareOwner: To list only shared address books from shareOwner's Id.
  • inviteStatus: To list only shared address books having matching invite status.

Status Codes:

  • 200 OK: Query has succeeded and results are returned
  • 404 NOT FOUND: addressbookHomeId is not correct

Response:

{
    "_links":{"self":{"href":"/addressbooks/55f811e843f181db51af9a67.json"}},
    "_embedded":{
        "dav:calendar":
        [
            {"_links":{"self":{"href":"/addressbooks/55f811e843f181db51af9a67/readonly01.json"}},"dav:name":"","carddav:description":"","dav:acl":["dav:read"],"type":"social"}
        ]
    }
}

GET /contacts/{userId}.json

List contacts across the user's own, delegated and subscribed address books. The optional domainMember=true and domainContacts=true parameters include domain address books.

Query Parameters: sort=fn|email (default fn), order=asc|desc (default asc), limit (1–1000, default 50), after (the next cursor from the previous page), delegate, share, domainMember, and domainContacts.

Status Codes: 200 on success, 400 for invalid sort, order or pagination, 403 when a non-technical user requests another user's contacts, 404 for an unknown user.

The response embeds dav:item contacts. Each item's self link points to its original address book; the listing's self link points to /contacts/{userId}.json. A non-final page also has a next cursor to pass as after. Keep the same sort and order on subsequent pages; changing either requires restarting without after. A cursor issued before order was supported is accepted only for asc.

Example: GET /contacts/{userId}.json?sort=fn&order=desc&limit=50 lists contacts by full name in descending order, with _id descending to break equal-name ties.

sort=email uses the preferred email (TYPE=PREF in vCard 3, lowest PREF in vCard 4), falling back to the first email; equal preferences keep the first email. Missing emails sort first for asc, last for desc. Existing cards require email_sort to be populated before enabling email sorting.

POST /addressbooks/{addressbookHomeId}.json

Create an address book in the specified addressbook home.

Request JSON Object:

A dav:addressbook object, with an additional member "id" which specifies the id to be used in the address book's url and "privilege" which determines the address book's privilege

{
    "id": "ID",
    "dav:name" :"NAME",
    "carddav:description": "DESCRIPTION",
    "dav:acl": ["dav:read", "dav:write"],
    "type": "social"
}

Status Codes:

  • 201 Created: New address book has been created
  • 400 Bad Request: Missing keys in the request object

GET /addressbooks/{addressbookHomeId}/{addressbookId}.json

List all contacts in the address book.

Status Codes:

  • 200 OK: Query has succeeded and results are returned

Query Parameters:

  • offset: List offset for the contacts returned
  • limit: The number of contacts to be returned
  • sort: The column to sort by, e.g. "fn"
  • modifiedBefore: Timestamp in seconds, to list contacts modified before a specificed time
  • after: The next cursor of the previous page, see below
  • order: asc (default) or desc, only applied to cursor pagination, see below

Response:

A dav:addressbook resource, with items expanded. The resource may also contain a next link, if the offset/limit query parameters are used.

Cursor pagination: with after, or with sort=fn|email and neither offset, search nor modifiedBefore, contacts are sorted by full name or preferred email (ignoring case and accents) and paginated like GET /contacts/{userId}.json: limit is 1–1000 (default 50), sort=fn|email and order=asc|desc (default asc) must stay the same on subsequent pages, and a non-final page has a next cursor to pass as after instead of a next link. after cannot be used with offset, search or modifiedBefore: such requests, and invalid cursors, sort, order or limit, get a 400.

order only applies to cursor pagination: it is ignored, and not validated, when the request is not cursor paginated, e.g. with offset or without sort=fn|email: sort then sorts in ascending order.

REPORT /addressbooks/{addressbookHomeId}/{addressbookId}.json

Synchronize an address book using a sync-token. This is the JSON equivalent of the WebDAV XML sync-collection REPORT and returns the contacts that were created, updated or deleted since the given sync-token.

Request JSON Object:

{
    "sync-token": "http://sabre.io/ns/sync/{token}"
}

The sync-token may be omitted or set to an empty string for the initial sync, in which case all current contacts are returned. Both the bare numeric form ("123") and the URL form ("http://sabre.io/ns/sync/123") are accepted.

Status Codes:

  • 207 Multi-Status: Sync succeeded and the response body lists the changes
  • 400 Bad Request: The sync-token is invalid or unsupported

Response:

A multistatus resource. Created/updated contacts have status 200, deleted contacts have status 404. The new sync-token is returned for the next sync.

{
    "_links": { "self": { "href": "/addressbooks/{addressbookHomeId}/{addressbookId}.json" } },
    "_embedded": {
        "dav:item": [
            { "_links": { "self": { "href": "/addressbooks/{...}/card1.vcf" } }, "status": 200 },
            { "_links": { "self": { "href": "/addressbooks/{...}/gone.vcf" } }, "status": 404 }
        ]
    },
    "sync-token": "http://sabre.io/ns/sync/124"
}

The same {DAV:}read permissions as other JSON REPORT requests are enforced.

POST /addressbooks/{addressbookHomeId}/{addressbookId}.json

Publish an address book

Request JSON Object:

A dav:publish-addressbook object, with a privilege value that can be either {DAV:}read or {DAV:}write

{
    "dav:publish-addressbook": {
      "privilege": "{DAV:}read"
    }
}

Status Codes:

  • 204 No Content: Address book is published
  • 400 Bad Request: Invalid privilege
  • 403 Forbidden: Princial user does not have {DAV:}share privilege

Unpublish an address book

Request JSON Object:

A dav:unpublish-addressbook object.

{
    "dav:unpublish-addressbook": true
}

Status Codes:

  • 204 No Content: Address book is unpublished
  • 403 Forbidden: Princial user does not have {DAV:}share privilege

Share an address book

Share an address book to a list of users each with a specific privilege

Request JSON Object:

A dav:share-resource object with an array dav:sharee contains delegation objects:

  • dav:href: email of user whom is delegated to the source address book.
  • dav:share-access: privilege code of delegated user in the source address book.

Privilege codes:

  • Read only: 2
  • Read/Write: 3
  • Read/Write and Administration: 5
  • No access for sharee: 4
{
    "dav:share-resource": {
      "dav:sharee": [{
        "dav:href": "mailto:user1@example.org",
        "dav:share-access": 3
      }, {
        "dav:href": "mailto:user2@example.org",
        "dav:share-access": 5
      }]
    }
}

Status Codes:

  • 204 No Content
  • 403 Forbidden: Princial user does not have {DAV:}share privilege

Accept address book sharing invitation

Set the sharing invitation of an address book to accepted.

Request JSON Object:

A dav:invite-reply object contains these properties:

  • dav:invite-accepted: must be true to set invitation accepted.
  • dav:slug: (optional) to set the display name of the new shared address book.
{
    "dav:invite-reply": {
      "dav:invite-accepted": true,
      "dav:slug": "My new address book"
    }
}

Status Codes:

  • 204 No Content: Invitation is accepted.

PROPFIND /addressbooks/{addressbookHomeId}/{addressbookId}.json

List all properties of the address book.

Status Codes:

  • 200 OK: Query has succeeded and results are returned

Request JSON Object:

An object with an array member "property" which specifies list of property of the address book.

Response:

A json resource containing the values of all requested properties

{
  "{urn:ietf:params:xml:ns:carddav}addressbook-description": "description",
  "{DAV:}acl": ['dav:read', 'dav:write'],
  "{http://open-paas.org/contacts}type": "social"
}

DELETE /addressbooks/{addressbookHomeId}/{addressbookId}.json

Delete an address book.

Status Codes:

  • 204 No Content: Successfully deleted an address book.
  • 403 Forbidden: The address book is protected which can not be deleted by default

Request JSON Object:

None.

PROPFIND /calendars/{calendarHomeId}/{calendarHomeId}.json

List asked properties about a calendar. For the moment only 'cs:invite' and 'acl' properties are supported Status Codes:

  • 200 OK: Query has succeeded and results are returned

Request JSON Object:

An object with an array member "prop" which specifies list of wanted property of the calendar.

{
  "prop": [
    "cs:invite",
    "acl"
   ]
}

Response:

A json resource containing the values of all requested properties

{
  "invite": [
    {
      "href": "principals/users/54b64eadf6d7d8e41d263e0f"
      ...
    }
  ]
  "acl": [
    {
      "privilege": "{DAV:}share"
      "principal": "principals/users/54b64eadf6d7d8e41d263e0f"
      "protected": 1
    },
    ...
  ]
}

ACL /calendars/{calendarHomeId}/{calendarId}

Sets the public access privilege on a calendar.

Request JSON Object:

{
  "public_right": "{DAV:}read" //any supported DAV acl privilege for a calendar
}

Status Codes:

  • 200 Ok
  • 400 Bad Request: Request payload is badly formatted
  • 404 Not Found: Calendar has not been found
  • 412 Precondition Failed: Privilege in the payload is not supported

Response:

[
  {
    "privilege": "{DAV:}read",
    "principal": "principals/users/54b64eadf6d7d8e41d263e0f"
  },
  {
    "privilege": "{DAV:}read",
    "principal": "{DAV:}authenticated"
  },
  ...
]

ITIP /calendars/{calendarHomeId}

Requests that Sabre processes a iTip message.

Request JSON Object:

An iTip processing request object. All keys in the request object except method (defaults to REQUEST) and sequence (defaults to 0) are required.

{
  "method": "REQUEST",
  "sender": "a@b.com",
  "recipient": "c@d.com",
  "uid": "the iTip UID",
  "recurrence-id": "the iTip RECURRENCE-ID, if any",
  "sequence": "0",
  "dtstamp": "the iTip DTSTAMP",
  "ical": "raw UTF-8 ical string"
}

Status Codes:

  • 204 No Content: Query has succeeded
  • 400 Bad Request: Missing keys in the request object

Response:

None.