Generic API Request Considerations

All API calls operate on sessions, with the only exception of the GET /api/session call that is used to create a session in the first place. The session id can be provided by the client in an Authorization: Bearer <sid> header, as a URL parameter sid, or as a cookie named sid. Note that sessions and their ids are only known in the context of a specific, single server, as returned on session creation.

Unless otherwise noted, all API commands require not only a valid session, but also a successful user authentication on this session, as performed with the POST /api/session call.

API Responses

The server will always answer with HTTP code 200 OK to all API URL requests that are supposed to deliver JSON response messages. The JSON response itself carries the information whether the API call was successful or some error has occurred.

The general layout of a JSON response looks like the following:

{
    "status": "ok"|"no-session"|"wrong-syntax"|"missing-element"|"fail"|...,
    "message": "a short text about what went wrong"
}

The status element is always present and carries information about the success of the API call, or a reason why the call was not successful. There are some generic status strings that can occur in possibly all of the API calls. Some API calls define additional, situation-specific strings. The generic status strings are:

Status Description
ok The API call was successfully executed and no error has occurred
no-session The request did not include a valid session id, or it contained an invalid or expired id
no-auth The session id included in the request is not authenticated with a valid user or partner
wrong-origin The API call was made from a wrong origin (i.e., the Origin header in the HTTP request does not match the Origin header of the session creation request)
wrong-syntax Some element in the request does not match the required element syntax format (e.g., the value of a field was too long or included invalid characters)
missing-element Some mandatory element is missing from the request
fail A generic failure has occurred. This is usually an unexpected event, more specific status codes are used for specific failure conditions. Note that for any failure condition, partial execution of the API call may have occurred.

If an individual API call specifies additional, specific status strings, they are documented there.

The message element might be present in a status “non-ok” condition and contains a short description of the generic failure. This is primarily useful for debugging and logging purposes.

Every API response includes the general response layout described in this section, the status and message fields are not shown in the descriptions of the specific API calls.

Localization

cospace uses very little server-side localization, mostly for texts in e-mails and sounds in the phone features. The language parameter or field to some of the API calls specifies the desired language. Supported languages in this version of the API are:

Language identifier Description
de German
en English

Authentication for file downloads

The session ID (sid) is the central authentication token that grants access to all API requests once the session is authenticated. However, sometimes a limited access only to certain objects is needed; and an application that obtained a session ID may not want to share the session ID with some other process only to enable that process to access a specific object. For this reason, cospace implements a restricted authentication method for file downloads, the so-called “download id” (did).

Certain API calls (usually those API calls that access file-level data of some objects) accept the did as a means of authentication in addition to the possibility of using the session ID. If authentication with did is requested, two URL parameters need to be present for the respective API call:

  • did – this parameter carries the did of the session.
  • dkey – this parameter, called the download key, contains a hashed combination of the requested object UUID and the sid (session ID).

The dkey is calculated as follows:

dkey = Base64_URL_Safe(MD5(string(object UUID), string(sid)))

That is the (lowercase) version of the object UUID’s string representation (ASCII/UTF-8) is concatenated with the session ID and then hashed with an MD5 hash function. The binary (!) result of the MD5 hash is encoded with the base64url method as defined in RFC 4648 section 5.

On the use of UUIDs

The system makes extensive use of Universally Unique Identifiers (UUIDs) to identify objects, metadata, parameters and state on the platform. All UUIDs used by the platform are time-based UUIDs (Version 1 according to RFC 4122). If clients need to sort objects or data identified by UUIDs by time, they can exploit this feature and implemented the sorting based on the intrinsic timestamps of these UUIDs. In cases where no explicit timestamp for the object exists, the intrinsic timestamp can also serve as an information about the creation time of the respective object.

However, clients must never rely on the fact that a specific server seems to have a specific clock sequence or node identifier, as these might change any time in a distributed system (for newly created UUIDs).

API Call Reference (User API)

/api/session

GET /api/session

Requests a new session with the system or confirms an existing session.

Query Parameters:
 
  • language

    optional: language identifier

    used to localize server-side messages before the session is authenticated.

    defaults to de if not given

Response body example

{
    "sid": "boajw93bawjckbja2ZdbfdGa84Afib",
    "did": "iaEia83AviaDia943faobpEPRkva98",
    "server": "https://api43.service.de:1234",
    "partner": "mypartner",
    "auth": false,
    "next_event": 0
}
Status:
  • resource-throttle: The server did not create a session because of excessive resource usage. A new call to this API might be considered at a later time.
  • wrong-session: The request contained an sid parameter that does not map to a known session on the server.

The HTTP response to this API call will set two HTTP cookies, sid and server, with exactly the same contents as returned in the JSON response message.

Further API calls that reference the newly created session can only be made towards the server specified in the server field, as the session state is only maintained on this server.

If the request to this API call contains an Authorization header, a sid cookie or URL parameter, the server will try to re-use the given session. If the session cannot be re-used, a wrong-session status is returned and the sid and server cookies will be deleted.

The auth response field will be false in the case of a newly created session (because no user is yet authenticated with this session), but may have a value of true if an existing, already authenticated session was re-used.

The did field is the download id of this session that can be used on certain API GET requests to obtain file contents. For more information on file download authentication, see Authentication for file downloads.

The partner field in the response will only be present if the authenticated user belongs to a partner.

The next_event response field indicates the id of the next, not-yet-received event. It might be used as the next parameter of the GET /api/event call to ensure that only new events are received.

POST /api/session

Authenticate a user with or without an existing session.

Request body example 1 (user authentication)

{
    "username": "johndoe47",
    "password": "secret12345"
}

- or-

{
    "email": "john@doe.com",
    "password": "secret12345"
}

Request body example 2 (partner authentication)

{
    "partner": "mypartner",
    "key": "dOajks83AF39ua08uaSDFas"
}

Request body example 3 (partner proxy authentication)

{
    "partner": "mypartner",
    "key": "dOajks83AF39ua08uaSDFas",
    "user": "52c53e36-65be-11e4-bf4a-201a06c768e1"
}
JSON Parameters:
 
  • username

    ^[a-zA-Z0-9]{2,20}$

    only for user authentication

  • email

    <user@domain>

    only for user authentication

  • password

    ^.{5,50}$

    only for user authentication

  • partner

    ^[a-zA-Z0-9]{2,20}$

    only for partner authentication

  • key

    ^.{5,50}$

    only for partner authentication

  • user

    UUID

    only for partner proxy authentication

Response body example 1 (user authentication)

{
    "partner": "mypartner"
}

Response body example 2 (user authentication without session)

{
    "sid": "boajw93bawjckbja2ZdbfdGa84Afib",
    "did": "iaEia83AviaDia943faobpEPRkva98",
    "server": "https://api43.service.de:1234",
    "partner": "mypartner",
    "auth": true,
    "next_event": 0
}

Response body example 3 (partner authentication)

{}

Response body example 4 (partner proxy authentication)

{}
Status:
  • wrong-credentials: username and/or password is wrong/unknown
  • already-auth: the session is already authenticated
  • wrong-user: the given user does not exist or does not belong to the partner

If this API call was successful (i.e. a valid password and the correct username or email is given), the session is authenticated and ready to accept API calls that require an authenticated session.

The partner field in the response will only be present if the authenticated user belongs to a partner.

If user authentication is used, this API may be called without a session to reduce the number of required requests to create an authenticated session.

If the user field is given in a partner authentication, this signals a partner proxy authentication for the specific user. Using this feature, a partner can create an authenticated user session for the specific user.

DELETE /api/session

Closes a session and invalidates the session id.

Response body example

{}

After closing the session, the session id is deleted on the server and can not be used for any further requests. The HTTP response will also invalidate the sid cookie.

This command does require a valid session, but not necessarily a user authentication with that session.

/api/signup

GET /api/signup/captcha/(xxx).png

Retrieves a captcha picture associated with the given sign-up process.

Response body example

The captcha picture in PNG format on success, or HTTP 404 without
response body on failure.

Each time called, this API replaces the server-side captcha with a new one.

This command does require a valid session, but not necessarily a user authentication with that session.

POST /api/signup/verification

Requests verification for the sign-up procedure via E-mail in case of sign-up with captcha or via the HTTP response in case of sign-up with hardware code, or initiates partner-controlled sign-up procedure.

Request body example 1 (user sign-up)

{
    "captcha": "soLuTiOn",
    "email": "john@doe.com"
}

Request body example 2 (partner-controlled sign-up)

{
    "info": {
        "some": ["thing", 4711]
    }
}

Request body example 3 (sign-up with hardware code)

{
    "hardware-code": "ABCDE-FGHIJ-KLMNI-OPQRS",
    "email": "john@doe.com"
}
JSON Parameters:
 
  • captcha

    ^[a-zA-Z0-9]{1,20}$

    The captcha solution for the captcha that was previously requested with GET /api/signup/captcha/(xxx).png

    (not required when this operation is done on a partner session or when a sign-up with hardware-code is performed)

  • email

    user@domain

    The e-mail address to be verified

    (not required when this operation is done on a partner session)

  • info

    ^.{1,10000}$

    Informational metadata that will later be returned on the corresponding GET /api/signup/verification/(verification) call. Can be any valid JSON data type.

  • hardware-code

    ^.{10,50}$

    the sensor device access code, which is the key to the physical device.

    (in this case, the captcha field is not required)

Response body example 1 (user sign-up)

{}

Response body example 2 (partner-controlled sign-up)

{
    "verification": "dijaDia8Aiofjb9aaobasdfDF",
    "uuid": "dfc3e9c4-4e81-11e1-9fe3-0024e8f90cc0",
    "info": {
        "some": ["thing", 4711]
    }
}

Response body example 3 (sign-up with hardware code)

{
    "verification": "dijaDia8Aiofjb9aaobasdfDF"
}
Status:
  • wrong-captcha: The captcha solution is wrong, or no captcha was previously requested
  • email-failure: The verification e-mail could not be sent out
  • already-exist: The e-mail address matches an existing user record (and thus cannot be used)
  • wrong-code: The hardware code is invalid.
  • exceeded-limit: The use of this hardware code for verification process has reached the maximum permitted count of 5 verifications. This hardware code cannot be used anymore for sign-up.

This API generates a verification key and sends it to the E-mail address in case of a sign-up with captcha, or sends it in the HTTP response in case of a sign-up with hardware code or a partner-controlled sign-up.

This command does require a valid session, but not necessarily a user authentication with that session for the user-style sign-up. In this case, a call to this API will reset the server-side captcha, no matter whether the response is successful or not. That means, that if the client needs to re-try this API call, a new captcha must be requested and solved before a second try can be made.

For a partner-controlled sign-up, the call will return the verification key and a uuid. If a user account is later created with this verification key, the user will be assigned this uuid.

GET /api/signup/verification/(verification)

Request information for the given E-Mail verification key

Response body example 1 (user sign-up)

{
    "email": "john@doe.com"
}

Response body example 2 (partner-controlled sign-up)

{
    "partner": "mypartner",
    "uuid": "dfc3e9c4-4e81-11e1-9fe3-0024e8f90cc0"
}
Status:
  • unknown-verification: The given verification key is unknown

This command does require a valid session, but not necessarily a user or partner authentication with that session.

DELETE /api/signup/verification/(verification)

Deletes a verification key.

Response body example

{}
Status:
  • unknown-verification: The given verification key is unknown

This command does require a valid session, but not necessarily a user or partner authentication with that session.

POST /api/signup/user

Creates a new user account within the system.

Request body example

{
    "username": "johndoe47",
    "firstname": "John",
    "lastname": "Doe",
    "display_name": "Johnny Doe",
    "country_code": "+49",
    "password": "secret12345",
    "language": "de",
    "newsletter": true,
    "verification": "dijaDia8Aiofjb9aaobasdfDF"
}
JSON Parameters:
 
  • email

    user@domain

    required if the verification key is from a partner-controlled sign-up and does not already include an e-mail address

  • username^[a-zA-Z0-9]{2,20}$
  • firstname^.{1,50}$
  • lastname^.{1,50}$
  • display_name

    ^.{1,100}$

    optional; the full username as it should be displayed within an application (default is “firstname lastname”)

  • country_code

    ^\+[0-9]{1,3}$

    optional; the country code of the user. (default is “+49” for Germany)

  • password^.{5,50}$
  • language – optional; a valid language identifier
  • newsletter

    true|false

    optional; true if the user wants to receive the newsletter, false if not. Default true.

  • verification

    ^[a-zA-Z0-9]{1,50}$

    the verification key (received by e-mail or partner-controlled sign-up)

Response body example

{}
Status:
  • duplicate-username: the selected username is already taken
  • unknown-verification: the verification key is unknown
  • already-exist: The e-mail address matches an existing user record

The client must provide a valid verification key (E-Mail verification procedure or partner-controlled sign-up). On success, a new user is created within the system and the E-Mail verification key is deleted.

The country_code field is used to enable clients to display a correct phone number. If no country_code field is given, the default value “+49” for Germany will be used.

If no language field is given, the user is created using the language of the session.

If the response indicates success, the session is automatically authenticated with the newly created user, i.e. the client can immediately issue all API commands that require an authenticated session.

This command does require a valid session without a user authentication.

/api/password

POST /api/password/recovery

Request E-Mail password recovery procedure (password recovery code).

Request body example

{
    "username": "johndoe47",
    "captcha": "soLuTiOn"
}

- or-

{
    "email": "john@doe.com",
    "captcha": "soLuTiOn"
}
JSON Parameters:
 
  • username^[a-zA-Z0-9]{2,20}$
  • email

    user@domain

    alternatively to the username: the email address of the user

  • captcha

    ^[a-zA-Z0-9]{1,20}$

    the captcha solution for the captcha that was previously requested with GET /api/signup/captcha/(xxx).png

Response body example

{}
Status:
  • wrong-captcha: The captcha solution is wrong, or no captcha was previously requested
  • wrong-username: The given username or email does not exist
  • email-failure: The verification e-mail could not be sent out

This API generates an e-mail with a password recovery code and sends it to the e-mail address stored in the user’s profile.

This command does require a valid session, but not necessarily a user authentication with that session.

A call to this API will reset the server-side captcha, no matter whether the response is successful or not. That means, the if the client needs to re-try this API call, a new captcha must be requested and solved before a second try can be made.

POST /api/password

Resets a user’s password using a valid password recovery code.

Request body example

{
    "username": "johndoe47",
    "code": "iausDia8sdfasjb9aaobasdfDF",
    "password": "newpass"
}

- or-

{
    "email": "john@doe.com",
    "code": "iausDia8sdfasjb9aaobasdfDF",
    "password": "newpass"
}
JSON Parameters:
 
  • username^[a-zA-Z0-9]{2,20}$
  • email

    user@domain

    alternatively to the username: the email address of the user

  • code

    ^[a-zA-Z0-9]{1,50}$

    the password recovery code (received by e-mail)

  • password

    ^.{5,50}$

    the new password

Response body example

{
    "partner": "mypartner"
}
Status:
  • wrong-username: The given username or email does not exist or the password recovery code is invalid for this username

The client must provide a valid password recovery code (E-Mail password recovery procedure). On success, the password of the given user is overwritten with password and the E-Mail password recovery code is deleted.

The user account can be identified either by specifiying the username, or the email of the user.

If the response indicates success, the session is automatically authenticated with the user, i.e. the client can immediately issue all API commands that require an authenticated session.

The partner field in the response will only be present if the user belongs to a partner.

This command does require a valid session without a user authentication.

/api/language

GET /api/language

Get the list of languages

Response body example

{
    "language": [
        "en",
        "de"
    ]
}

This call will return all the languages supported by the API. It does not require a session.

/api/user

GET /api/user

Get user-related information of current session’s user

Response body example

{
    "user": {
        "uuid": "1de7257a-4f34-11e0-ab6e-0024e8f90cc0",
        "username": "johndoe47",
        "firstname": "John",
        "lastname": "Doe",
        "display_name": "Johnny Doe",
        "birthday": "1970-12-24",
        "email": "john@doe.com",
        "language": "de",
        "newsletter": true,
        "partner": "somepartner",
        "zip_code": "10557",
        "town": "Berlin",
        "street": "Willy-Brandt-Stra\u00dfe",
        "house_number": "15",
        "country": "de",
        "country_code": "+49",
        "area_code": "30",
        "validation": "ok",
        "tag_all": "56697e6e-4f36-11e0-be81-0024e8f90cc0",
        "tag_unread": "56961546-4f36-11e0-9449-0024e8f90cc0",
        "tag_inbox": "56b8e300-4f36-11e0-873b-0024e8f90cc0",
        "tag_outbox": "56ddc9fe-4f36-11e0-a94b-0024e8f90cc0",
        "tag_trash": "5700ebe6-4f36-11e0-859a-0024e8f90cc0",
        "tag_shared": "5726c410-4f36-11e0-a8c1-0024e8f90cc0",
        "share_read": "9638badc-ab55-11e2-a825-0024e8f90cc0",
        "share_write": "a192a9e2-ab55-11e2-b215-0024e8f90cc0",
        "share_propagate": "a8c7aadc-ab55-11e2-a55f-0024e8f90cc0",
        "contact": "b02a5f0c-9268-11e0-84f8-0024e8f90cc0",
        "feature": {
            "pack": [
                "20GB+",
                "COSPACE-BOX"
            ],
            "quota": {
                "volume": 25000,
                "fax": 50
            },
            "used": {
                "volume": 452,
                "fax": 13
            },
            "feature": {
                "fax_noad": true,
                "call_unrestricted": true,
                "box_enable": true,
                "dialplan_enable": true,
                "control_phone": true
            }
        },
        "fax_ident": "+49 221 9999999",
        "fax_header": "John Doe, Inc.",
        "picture": true,
        "usergroup": "Controlling"
    }
}

The partner field will only be present if this user was created with a partner-controlled sign-up.

The feature section lists the feature configuration for the current user, that is, all of the additional feature packs that this user has, the resulting quota for volume (in MB) and fax (pages per month). The used subsection lists the actually used values (in case of fax, for the current month). The feature subsection lists boolean feature variables.

The area_code, birthday, zip_code, town, street, house_number, country, fax_ident and fax_header fields will only be present if they were set with POST /api/user.

The validation field can be set to incomplete, checking, missmatch, baddocument, fail or ok.

  • incomplete address information not set with POST /api/user or no idcard set with POST /api/user/idcard.
  • checking the address information are complete and in validation process
  • missmatch the address information miss match to the idcard.
  • baddocument the document dosen’t match the requirements.
  • fail the document is unreadable.
  • ok the address information match to the idcard.

The share_xxx fields contain the user’s personal share tags. These auto-generated tags can be used by other users to share objects with this user on a personal basis (i.e., without using manually created tags).

The usergroup field will only be present if the user was added to a usergroup by the corresponding partner.

The picture flag will have a value of true if the user has a profile picture.

POST /api/user

Modify user-related information of current session’s user

Request body example

{
    "firstname": "John",
    "lastname": "Doe",
    "display_name": "Johnny Doe",
    "birthday": "1970-12-24",
    "zip_code": "10557",
    "town": "Berlin",
    "street": "Willy-Brandt-Stra\u00dfe",
    "house_number": "15",
    "country": "de",
    "country_code": "+49",
    "password": "newpass",
    "old_password": "oldpass",
    "pin": "1234",
    "language": "de",
    "newsletter": false,
    "email": "johnsnewmail@foobar.de",
    "fax_ident": "+49 221 9999999",
    "fax_header": "John Doe, Inc."
}
JSON Parameters:
 
  • firstname

    ^.{1,50}$

    optional

  • lastname

    ^.{1,50}$

    optional

  • display_name

    ^.{1,100}$

    optional; the user name as it should display within an application

  • birthday

    ^[\d]{4}-[\d]{2}-[\d]{2}$

    optional; the user’s birthday, format YYYY-MM-DD, if present, zip_code, town, street, house_number and country must also be present

  • zip_code

    ^.{1,50}$

    optional; if present, birthday, town, street, house_number and country must also be present

  • town

    ^.{1,50}$

    optional; if present, birthday, zip_code, street, house_number and country must also be present

  • street

    ^.{1,50}$

    optional; if present, birthday, zip_code, town, house_number and country must also be present

  • house_number

    ^.{1,50}$

    optional; if present, birthday, zip_code, town, street and country must also be present

  • country

    ^[a-z]{2}$

    optional; ISO country code; if present, birthday, zip_code, town, street and house_number must also be present

  • country_code

    ^\+[0-9]{1,3}$

    optional; the country code of the user

  • password

    ^.{5,50}$

    optional; a new password for this user

  • old_password

    ^.{5,50}$

    optional; must be present if password is present

  • pin

    ^[0-9]{4}$

    optional; a new phone PIN for this user

  • language – optional; a valid language identifier
  • email

    user@domain

    optional; a new e-mail address (first step)

  • newsletter

    true|false

    optional; true if the user wants to receive the newsletter

  • code

    ^[a-zA-Z0-9]{1,50}$

    optional; the e-mail verification code (second step)

  • fax_ident

    ^[\+ 0-9]{0,20}$

    optional; the default fax transmitting station ID (TSI)

  • fax_header

    ^.{0,40}$

    optional; the default fax header line

Response body example

{}
Status:
  • wrong-password: The old_password is wrong
  • already-exist: The e-mail address matches an existing user record
  • email-failure: The e-mail could not be sent out
  • address-incomplete: Missing parameter birthday, zip_code, town, street, house_number or country
  • address-wrong: The combination of the given address-parameters zip_code, town, street, house_number and country are incorrect, too imprecise or unknown to the system
  • address-forbidden: The new address is correct, but is located at a different area code than the current address. Please release all phone numbers associated with your current area code and retry.
  • unsupported-country: The country given is not supported by the system
  • too-young: The given age (birthday field) is too young

To change the user’s e-mail address, a two-step process is needed. First, this API call is used to with the email field to indicate the new e-mail address. The system will send a verification e-mail to the new address including a verification code. The client can then issue this API call a second time and provide the verification code in the code field to confirm and save the new e-mail address. Thus, a single call to this API must not include both the email and code fields.

In order to set location data for a user, all 6 parameters birthday, zip_code, town, street, house_number and country must be given. These parameters will be verified and the corresponding area_code will be set. If the user already has location data inserted, the new data will only be accepted if the new address is correct and has the same area code or there a no phone numbers associated with the old area code.

POST /api/user/delete

Requests permanent deletion of a user account.

Request body example

{
    "username": "johndoe47",
    "password": "secret12345"
}

- or-

{
    "email": "john@doe.com",
    "password": "secret12345"
}

Response body example

{}
Status:
  • wrong-user: The given username does not match the session’s user or the user is controlled by a partner
  • wrong-credentials: The given password is wrong

The deletion of a user account is a permanent action and cannot be undone.

To delete the user account, the username and password need to be repeated in this call (i.e., the given username must match the session’s user name).

On successful completion, this call will invalidate the current user session.

POST /api/user/idcard

Set the current session user’s idcard for identification process.

Request body

The request body contains binary data in PDF format.

Response body example

{}
Status:
  • too-large: The contents are too large to be handled by the system
  • malformed-file: The content is malformed.

The data in the request body should be given as a binary format PDF.

GET /api/user/(user-uuid)

Get basic information about a user

Response body example

{
    "user": {
        "username": "johndoe47",
        "firstname": "John",
        "lastname": "Doe",
        "display_name": "Johnny Doe",
        "deleted": true,
        "picture": true,
        "share_read": "9638badc-ab55-11e2-a825-0024e8f90cc0",
        "share_write": "a192a9e2-ab55-11e2-b215-0024e8f90cc0",
        "share_propagate": "a8c7aadc-ab55-11e2-a55f-0024e8f90cc0"
    }
}
Status:
  • wrong-user: The given user-uuid does not exist

This call is typically used to get information about another user of the system, whose UUID is known because it shows up in some other object.

If the deleted field is present, this indicates that the user is no longer active in the system.

The share_xxx fields will contain the personal sharing tags of the other user. These fields will only be present if the current user is linked with this user.

The picture flag will have a value of true if the user has a profile picture.

GET /api/user/metadata

Get the metadata information for the current session’s user.

Query Parameters:
 
  • keys – optional: a comma-separated list of metadata keys to get information for
  • domain – optional: a domain to retrieve metadata for all keys under this domain

Response body example

{
    "metadata": {
        "org.mydomain.phone": "+492216698000",
        "org.mydomain.room": "B3"
    }
}

Within the metadata section, the requested metadata information of the user is given in form of a JSON object.

Without any URL parameters, the call will retrieve all metadata keys for current session’s user. If they keys parameter is given, only the metadata elements for the given keys are returned. If the domain parameter is given, all metadata elements for keys under this domain (not including the domain as a key itself) are returned. That is, if domain is com.mycompany, keys like com.mycompany.application1.element1 and com.mycompany.entity2 will be returned, but not the key com.mycompany.

POST /api/user/metadata

Modify or delete metadata information associated with the current session’s user.

Query Parameters:
 
  • noevent – optional: if present, don’t generate a user_metadata event (see below)
  • nostore – optional: if present, don’t store the metadata permanently (see below)

Request body example

{
    "update": {
        "com.otherdomain.client.nice": true,
        "com.otherdomain.client.timestamp": 1324899645
    },
    "delete": [
        "com.otherdomain.client.something"
    ]
}
JSON Parameters:
 
  • key^[a-z0-9]{2,50}(\\.[a-z0-9]{2,50}){1,10}$
  • value – any valid JSON type, maximum length: 100KB

Response body example

{}
Status:
  • too-large: At least metadata value is too big (100 KB maximum size limit).

The metadata keys listed in the update section are updated in the database (or added if they don not currently exist).

The metadata keys listed in the delete section are deleted from the database.

To avoid conflicts between different applications that might otherwise use the same metadata keys, metadata keys must have the form of a reverse Internet domain, possibly extended with customer-chose domain elements. Applications are encouraged to use officially registered domains for the first part of their metadata key, like com.mycompany.application1.element1.

By default, the modification of the user’s metadata will generate a user_metadata event that is sent towards all sessions currently active for the user. This behavior can be suppressed by including the noevent parameter in the request URL.

If the request URL includes the nostore parameter, the given metadata will not be stored to the database (i.e. the contents can not be retrieved with GET /api/user/metadata afterwards). This is useful if the desired behavior is to create the user_metadata event only.

/api/user/picture

POST /api/user/picture

Set the current session user’s profile picture.

Request body

The request body contains binary picture data in JPEG or PNG format.

Response body example

{}
Status:
  • too-large: The picture data is too large to be handled
  • malformed-file: The picture data is malformed / cannot be decoded

The picture data in the request body should be given as a binary format JPEG or PNG image. The actual format is automatically determined by the system. The profile picture of the user should be square, the optimal resolution is 384x384 picture, larger resolutions are possible but will be down-scaled on the server side. The maximum acceptable picture resolution is 1500x1500 pixels.

DELETE /api/user/picture

Deletes the current session user’s profile picture.

Response body example

{}
GET /api/user/(user-id)/picture/(size)/(xxx).jpg

Get a user’s profile picture

Response body example

The picture contents as a binary JPEG file.

The user-id portion of the call might have one of the following forms:

  • a UUID of an arbitrary user of the system.
  • the string “self” to get the profile picture of the current session’s user.
  • the string “default” to get the default profile picture for users that don’t have a profile picture.

If a UUID is given in user-id and the user is not found, an HTTP 404 error will be returned.

If a UUID is given in user-id and the specified user does not have a profile picture, a temporary HTTP redirection (status code 302) will be returned pointing to the location of the default profile picture.

The size selector within the URI is used to select the resolution of the picture returned by the call. The following resolutions are available:

  • small 48x48 pixels
  • medium 96x96 pixels
  • large 192x192 pixels
  • huge 384x384 pixels

The xxx portion of the URI is an arbitrary file name to be chosen by the client.

/api/user/invitation

GET /api/user/invitation

Get user’s invitations

Response body example

{
    "invitation": {
        "dlJdod9df2jAoemnvao4u9a": {
            "description": "CeBIT 2011, Stand 42",
            "expire": 1300217017,
            "one-time": false
        },
        "Dfvp9audpd93dtAadvdDvsD": {
            "description": "Einladung f\u00fcr Hans M\u00fcller",
            "one-time": true
        }
    },
    "out": [
        "56697e6e-4f36-11e0-be81-0024e8f90cc0"
    ],
    "in": [
        "11697e6e-4f36-11e0-be81-0024e8f90cc0"
    ]
}

Invitations listed within the invitation element are keyed by the invitation’s identifier string. The expire field specifies the expiration date of the invitation (seconds-since-epoch, only present if an expiration date exists), and one-time specifies whether the invitation will immediately expire on usage (if true).

The out section lists outstanding requests that were made by the current user, i.e. the listed UUIDs are those of the invited users.

The in section lists requests that were made by other users to invite the current user, i.e. the listed UUIDs are those of users that originated an invitation towards the current user.

POST /api/user/invitation

Modify user’s invitations

Request body example

{
    "create": [
        {
            "description": "Grillen am See",
            "expire": 2281283821,
            "one-time": true
        },
        {
            "description": "Please get in touch with me",
            "expire": 2381283821,
            "one-time": false
        }
    ],
    "update": {
        "doOsie8dOmdos9732Jdkfos": {
            "description": "Changed description",
            "one-time": true
        },
        "Dfvp9audpd93dtAadvdDvsD": {
            "expire": 2381283821,
            "one-time": false
        }
    },
    "delete": [
        "dlJdod9df2jAoemnvao4u9a"
    ],
    "invite": [
        "56697e6e-4f36-11e0-be81-0024e8f90cc0"
    ],
    "refuse": [
        "11697e6e-4f36-11e0-be81-0024e8f90cc0"
    ]
}
JSON Parameters:
 
  • description^.{,100}$
  • expire32-bit integer
  • one-timetrue|false

Response body example

{
    "create": [
        "dfijaijADFVLIaosjd34342",
        "aFbouajfASDERGa49ja94wd"
    ]
}
Status:
  • wrong-invitation: An invitation in the update or delete or refuse section does not exist.
  • access-denied: An invitation in the update or delete section is not owned by the current user.
  • wrong-user: A user listed in the invite section does not exist or is deleted.
  • already-link: A link already exists towards a user listed in the invite section.
  • already-invited: An invitation to or from a user listed in the invite section already exists.

The invitations in the create section of the request are added to the user’s invitation data. These refer to so-called external invitations, i.e. persons that are not yet users of the system. For these invitations, description and one-time are mandatory fields, expire is optional.

Data in the update section of the request body is modified in the current user’s invitation data, all fields are optional (only the fields given are modified).

The invitations in the delete section are deleted from the user’s invitation data.

The invite section lists UUIDs of other users to be invited via so-called internal invitations.

An internal invitation can be deleted by both the initiator and the recipient of the invitation by listing the other party’s UUID in the refuse section.

The create section of the response lists the identifier strings of the newly created external invitations.

GET /api/invitation/(invitation)

Get information about (usually other user’s) external invitation invitation

Response body example

{
    "description": "Please get in touch with me",
    "user": {
        "username": "johndoe47",
        "firstname": "John",
        "lastname": "Doe",
        "display_name": "Johnny Doe"
    }
}
Status:
  • wrong-invitation: The given invitation identifier is wrong/unknown

This API call is used to “pre-view” an invitation received from another user, identified by its invitation identifier string invitation. The response reveals the description of the invitation and the name of the user that issued the invitation.

To actually confirm the invitation and to create a user link, use POST /api/user/link.

/api/phone

GET /api/phone

Get a list of (system-managed) phone numbers associated with current user

Response body example

{
    "phone": {
        "+492216698712": {
            "announcement": {
                "uuid": "1de7257a-4f34-11e0-ab6e-0024e8f90cc0",
                "description": "John's personal announcement"
            },
            "dialplan_enable": false,
            "call_enable": false,
            "fax_enable": true,
            "recording_enable": true,
            "play_announcement_only": false,
            "conference_enable": true,
            "notification_email": true,
            "notification_attachment": true,
            "on_hold_music": null
        },
        "+492211110004": {
            "dialplan_enable": true,
            "call_enable": false,
            "fax_enable": false,
            "recording_enable": false,
            "play_announcement_only": false,
            "conference_enable": false,
            "notification_email": true,
            "notification_attachment": false,
            "partner": "mypartner",
            "on_hold_music": null
        },
        "+492118888888": {
            "dialplan_enable": false,
            "call_enable": false,
            "fax_enable": true,
            "recording_enable": true,
            "play_announcement_only": false,
            "conference_enable": true,
            "notification_email": false,
            "notification_attachment": false,
            "unlock_code": "7649"
            "on_hold_music": null
        },
        "+492118888899": {
            "dialplan_enable": false,
            "call_enable": false,
            "fax_enable": false,
            "recording_enable": false,
            "play_announcement_only": false,
            "conference_enable": false,
            "notification_email": false,
            "notification_attachment": false,
            "ivr": "ce19884c-8fed-11e2-93fe-0024e8f90cc2"
            "on_hold_music": null
        },
        "+492118888999": {
            "dialplan": "215a5977-7835-47ed-8795-e9da0540074c",
            "dialplan_enable": false,
            "call_enable": false,
            "fax_enable": false,
            "recording_enable": false,
            "play_announcement_only": false,
            "conference_enable": false,
            "notification_email": false,
            "notification_attachment": false,
            "notification_email": false,
            "notification_attachment": false,
            "on_hold_music": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
        }
    }
}

The phone section lists the phone numbers associated with the current session’s user.

The announcement element exists if an associated announcement is present.

The partner element exists if the phone number is controlled by the partner.

The ivr field points to an “Interactive Voice Response API” object that is associated with this phone number.

If an unlock_code field is present, it signals that the corresponding number is reserved, but still inactive. It must be unlocked by calling the number and entering the unlock_code (DTMF).

The on_hold_music field is either null or the UUID of an announcement that should be used as the On-Hold-Music for this number.

POST /api/phone

Modify current user’s phone configuration

Request body example

{
    "create": true,
    "update": {
        "+492216698712": {
            "announcement": "1de7257a-4f34-11e0-ab6e-0024e8f90cc0",
            "conference_enable": false,
            "notification_email": true,
            "notification_attachment": true
        },
        "+491796548354": {
            "announcement": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
            "dialplan_enable": false,
            "call_enable": false,
            "fax_enable": true,
            "recording_enable": true,
            "play_announcement_only": true,
            "conference_enable": false,
            "notification_attachment": false,
            "ivr": "ce19884c-8fed-11e2-93fe-0024e8f90cc2"
        },
        "+492118888899": {
            "dialplan": "215a5977-7835-47ed-8795-e9da0540074c",
            "notification_email": false,
            "notification_attachment": false
            "on_hold_music": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1"
        }
    },
    "delete": [
        "+492211110004",
        "+492211110006"
    ]
}
JSON Parameters:
 
  • phonenumber^\\+[0-9]{3,20}$
  • ivr

    UUID | null

    • UUID - associate this IVR to the phone
    • null - remove the IVR field from the phone

Response body example

{
    "+492118888888": {
        "unlock_code": "7649"
    }
}
Status:
  • pool-depleted: There was a request to create a new phone number, but there are no more numbers available in the user’s area code
  • address-missing: There was a request to create a new phone number, but there were no verified address information entered (POST /api/user & POST /api/user/idcard) .
  • phone-limit: There was a request to create a new phone number, but the maximum amount of numbers for this users has been reached.
  • wrong-phone: The phone number referenced in the update section does not belong to the user.
  • wrong-announcement: The given announcement does not exist or is not accessible by the current user
  • wrong-dialplan: The given dialplan does not exist or is not accessible by the current user
  • concurrent-access: There is another request to create a new phone number running in parallel
  • phone-forbidden: This user has no rights to create new phone numbers

A new number is added to the user’s list of system-maintained phone numbers and will be automatically chosen from a internal pool of available phone numbers for the users area_code if create is true. Numbers can only be requested after a valid address is entered with POST /api/user. The returned number is reserved for the user but inactive. In order to activate the number, it must be called and the unlock_code must be entered via DTMF.

The phone numbers in the update section of the request body are modified in the current user’s phone data. If no announcement is given in this section, an existing announcement binding is deleted.

The phone numbers in the delete section are deleted from the user’s phone data.

The dialplan_enable, call_enable, fax_enable, conference_enable and recording_enable elements in the create and update sections are all optional (dialplan_enable and call_enable default to false, all other switches default to true).

Any combination of the *_enable switches is possible; however dialplan_enable takes priority, i.e. if dialplan_enable is true, the setting of call_enable, fax_enable, conference_enable and recording_enable is ignored for that number. The call API (call_enable) will only work if call_enable is the only switch that is true.

The dialplan field enables the “Dialplan v2” feature for this number. Setting the field to null will disable the feature, setting it to the UUID of a “Dialplan v2” object will enable it. This field has priority over all other phone flags. See POST /api/dialplan/v2 for further information.

The ivr is activated only if call_enable and dialplan_enable are disabled.

The play_announcement_only field is optional and defaults to false. If set to true, the system will not record a voice message after the announcement has been played in voice recorder mode.

The notification_email and notification_attachment elements in the create and update sections are optional (default false).

For a given user, only one request to create a new phone number might be running in parallel. If multiple requests are issued at the same time, some will return a concurrent-access status.

The on_hold_music field should be either null or the UUID of an announcement that will be used as the On-Hold-Music for this number.

/api/tag

GET /api/tag

Get list of tags associated with current user

Response body example

{
    "tag": {
        "1de7257a-4f34-11e0-ab6e-0024e8f90cc0": {
            "owner": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
            "label": "private",
            "foreign_use": true,
            "policy": {
                "1de7257a-4f34-11e0-ab6e-0024e8f90cc1": 4,
                "1d333333-4f34-11e0-ab6e-0024e8f90cc1": 2,
                "1d444444-4f34-11e0-ab6e-0024e8f90cc1": 3
            }
        },
        "1de1227a-4f34-11e0-ab6e-0024e8f90cc1": {
            "owner": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
            "label": "Q-loud Team",
            "foreign_use": false,
            "policy": {
                "1de7257a-4f34-11e0-ab6e-0024e8f90cc1": 4,
                "1d333333-4f34-11e0-ab6e-0024e8f90cc1": 1,
                "1d444444-4f34-11e0-ab6e-0024e8f90cc1": 1
            }
        }
    }
}

The tag section lists all tags that are visible for the current session’s user. This includes tags that are owned by the user and tags from other user’s where the current user has some sort of access privileges. The result does not include the user’s system tags and the user’s share tags.

POST /api/tag

Create a new tag for the current user.

Request body example

{
    "label": "Project X",
    "foreign_use": true,
    "policy": {
        "1de1227a-4f34-11e0-ab6e-0024e8f90cc1": 1,
        "1d333333-4f34-11e0-ab6e-0024e8f90cc1": 2,
        "1d444444-4f34-11e0-ab6e-0024e8f90cc1": 3
    }
}
JSON Parameters:
 
  • label

    ^.{1,50}$

    Text label of this tag

Response body example

{
    "uuid": "1de7257a-4f34-11e0-ab6e-0024e8f90cc0"
}
Status:
  • wrong-user: One of the given user UUIDs is unknown or has no link with the current user

In the policy section, a mapping of other users UUIDs to access privileges is defined.

The policy levels are:

  • 1 (read): user has read access to objects tagged with this tag
  • 2 (write): user has read and write access to objects tagged with this tag
  • 3 (propagate): user has read and write access to objects tagged with this tag, and may re-tag the object, possibly granting access rights to other users
  • 4 (owner): user is the owner of that tag, and has full permissions on any object carrying the tag (in respect to the object, this is equivalent to policy level 3)

The API call returns the UUID of the created tag.

GET /api/tag/(uuid)

Get information for tag uuid

Response body example

{
    "owner": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
    "label": "Project X",
    "foreign_use": true,
    "policy": {
        "1de1227a-4f34-11e0-ab6e-0024e8f90cc1": 1,
        "1d333333-4f34-11e0-ab6e-0024e8f90cc1": 2,
        "1d444444-4f34-11e0-ab6e-0024e8f90cc1": 3
    }
}
Status:
  • wrong-tag: The given UUID does not match to a tag accessible by the current user

This API cannot be used to request detail information for one of the user’s system tags or share tags (because label, foreign_use and policy do not make sense in the context of those tags).

POST /api/tag/(uuid)

Modify tag uuid

Request body example

{
    "label": "Project X",
    "foreign_use": false,
    "policy": {
        "update": {
            "1de1227a-4f34-11e0-ab6e-0024e8f90cc1": 3,
            "1d333333-4f34-11e0-ab6e-0024e8f90cc1": 2
        },
        "delete": [
            "1d444444-4f34-11e0-ab6e-0024e8f90cc1"
        ]
    }
}
JSON Parameters:
 
  • label

    ^.{1,50}$

    Text label of this tag

Response body example

{}
Status:
  • wrong-tag: The given UUID does not match to a tag accessible by the current user
  • wrong-user: One of the given user UUIDs is unknown or has no link with the current user
  • access-denied: The user is not the owner of the specified tag

All fields in the request body are optional to allow a subset of fields to be updated. Users listed in the update section are added to or modified in the policy list of this tag, users listed in the delete section are deleted from the policy list.

System tags and share tags cannot be modified using this API call.

DELETE /api/tag/(uuid)

Delete tag uuid

Response body example

{}
Status:
  • wrong-tag: The given UUID does not match to a tag accessible by the current user
  • access-denied: The user is not the owner of the specified tag

System tags and share tags cannot be deleted using this API call.

GET /api/tag/(uuid)/object

Get objects tagged with the tag <uuid>

Query Parameters:
 
  • filter – optional: one of {fax, recording, announcement, contact, conference, volume, box, ipquality, presentation, sensor, xobject}
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start

    optional: the UUID of the first object to return, exclusive, i.e. the object with an exact match UUID is not returned.

    If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.

  • order

    optional: If set to asc (default), objects are returned in time ascending order (i.e. starting with from or start and ending with stop).

    If set to desc, objects are returned in time descending order (i.e. starting with to or start and ending with from).

  • count – optional, default 10: limits the number of returned objects (valid range: 1...500)
  • tag – optional, a comma-separated list of additional tag UUIDs that also need to be present on the objects that this query will return. This effectively forms a logical AND query for objects with multiple tags.
  • search – optional, a search string containing words that must be present in the content of the objects this query will return. This feature is used to implement a full-text search within tags.

Response body example

{
    "object": {
        "550e8400-e29b-41d4-a716-446655440000": {
            "type": "recording",
            "owner": "550e8400-e29b-41d4-a716-446655440000",
            "time": 24532354234,
            "tag": [
                "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
                "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
            ],
            "description": "Ein Anruf von Herrn Mueller",
            "from": "+492421848484",
            "to": "+492216698123"
        },
        "550e8421-e29b-41d4-a716-446655440001": {
            "type": "fax",
            "owner": "550e8400-e29b-41d4-a716-446655440000",
            "time": 21232145273,
            "tag": [
                "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0",
                "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
                "97d3a606-a961-11e0-9a43-0024e8f90cc0"
            ],
            "description": "Versicherungsvertrag Hausrat",
            "page_count": 12
        },
        "12322321-e29b-41d4-a716-446655440001": {
            "type": "contact",
            "owner": "550e8400-e29b-41d4-a716-446655440000",
            "time": 22634544573,
            "tag": [
                "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0"
            ],
            "firstname": "Dirk",
            "lastname": "Mueller"
        },
        "6546565-e29b-41d4-a716-446655440001": {
            "type": "announcement",
            "owner": "550e8400-e29b-41d4-a716-446655440000",
            "time": 22436234323,
            "tag": [
                "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
                "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0",
                "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
                "97d3a606-a961-11e0-9a43-0024e8f90cc0",
                "9e7c3b80-a961-11e0-b40e-0024e8f90cc0"
            ],
            "description": "Meine Standardansage"
        },
        "c1497ba2-926c-11e0-973a-0024e8f90cc0": {
            "type": "conference",
            "owner": "550e8400-e29b-41d4-a716-446655440000",
            "time": 22436292746,
            "tag": [
                "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
                "97d3a606-a961-11e0-9a43-0024e8f90cc0",
                "9e7c3b80-a961-11e0-b40e-0024e8f90cc0"
            ],
            "description": "Unser t\u00e4gliches Kaffeekr\u00e4nzchen",
            "active": true,
            "pin": "4711"
        }
    }
}
Status:
  • wrong-tag: The given UUID does not match to tag accessible by the current user

/api/trash

DELETE /api/trash

Purge the trash. All objects in the trash will be permanently deleted.

Response body example

{}

/api/object

POST /api/object/(uuid)/tag

Modify tag attachments of object uuid

Request body example

{
    "add": [
        "3da40b94-591b-11e0-9d92-0024e8f90cc0",
        "43bd397e-591b-11e0-a47e-0024e8f90cc0"
    ],
    "delete": [
        "4d4f6606-591b-11e0-81f3-0024e8f90cc0",
        "53190e02-591b-11e0-be0c-0024e8f90cc0"
    ]
}

Response body example

{}
Status:
  • wrong-object: The given UUID does not match to an object accessible by the current user
  • wrong-tag: One of the given UUIDs does not match a tag accessible by the current user
  • access-denied: The user does not have sufficient privileges on the object (not the owner and no propagate rights, or the object is in trash and the request operation does something else than remove the trash tag)
  • already-tag: A tag listed in the add section is already attached to the object
  • no-tag: A tag listed in the delete section is not attached to the object

Tags listed in the add section are attached to the object, those listed in the delete section are detached from it.

If an object has the trash tag, then the only valid tag modification is the deletion of the trash tag. This operation effectively “undeletes” the object.

GET /api/object/(uuid)/comment

Get comments of object uuid

Query Parameters:
 
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start – optional: the UUID of the first object to return, exclusive, i.e. the comment with an exact match UUID is not returned. If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.
  • order – optional: If set to asc (default), objects are returned in time ascending order (i.e. starting with from or start and endin If set to desc, objects are returned in time descending order (i.e. starting with to or start and ending with from).
  • count – optional, default 10: limits the number of returned objects (valid range: 1...500)

Response body example

{
    "comment": {
        "36b7bbf4-591c-11e0-a7e3-0024e8f90cc0": {
            "owner": "550e8400-e29b-41d4-a716-446655440000",
            "time": 2598392983,
            "text": "This is a comment"
        },
        "54512f9c-591c-11e0-8085-0024e8f90cc0": {
            "owner": "550e8400-e29b-41d4-a716-446655440000",
            "time": 2498234333,
            "text": "Another comment"
        }
    }
}
Status:
  • wrong-object: The given UUID does not match to an object accessible by the current user

Comments in the comment section are keyed by their UUID and appear ordered with ascending creating time.

POST /api/object/(uuid)/comment

Create a comment for the object uuid

Request body example

{
    "text": "This is just another comment"
}
JSON Parameters:
 
  • text^.{1,1000}$

Response body example

{
    "uuid": "550e8400-e29b-41d4-a716-446655440001"
}
Status:
  • wrong-object: The given UUID does not match to an object accessible by the current user

The call returns the UUID of the created comment.

POST /api/comment/(uuid)

Modify the comment uuid

Request body example

{
    "text": "This is just another comment"
}
JSON Parameters:
 
  • text^.{1,1000}$

Response body example

{}
Status:
  • wrong-comment: The given UUID does not match to a comment accessible by the current user
  • access-denied: The user is not the owner of the specified comment
DELETE /api/comment/(uuid)

Delete the comment <uuid>

Response body example

{}
Status:
  • wrong-comment: The given UUID does not match to a comment accessible by the current user
  • access-denied: The user is neither the owner of the specified comment nor the owner of the object that this comment refers to

Get all objects that are linked to object (uuid)

Response body example

{
    "link": {
        "6546565-e29b-41d4-a716-446655440001": {
            "type": "announcement"
        },
        "c1497ba2-926c-11e0-973a-0024e8f90cc0": {
            "type": "conference"
        }
    }
}
Status:
  • wrong-object: The given <uuid> does not match to an object accessible by the current user

The result will only contain objects that the current user has at least read access for.

POST /api/object/(uuid)/link/(other-uuid)

Create a connection between object uuid and object other-uuid

Request body example

{}

Response body example

{}
Status:
  • wrong-object: At least one of the given uuid or other-uuid do not match to an object accessible by the current user
  • access-denied: The user does not have sufficient privileges on at least one of the given objects uuid and other-uuid (at least write privileges are required)

To create a link between to objects, write privileges are needed on both objects.

Delete the connection between object uuid and object other-uuid

Response body example

{}
Status:
  • wrong-object: The given uuid or other-uuid does not match to an object accessible by the current user
  • access-denied: The user does not have sufficient privileges on object uuid (at least write privileges are required)
GET /api/object/(uuid)/metadata

Get the metadata information for object uuid.

Query Parameters:
 
  • keys – optional: a comma-separated list of metadata keys to get information for
  • domain – optional: a domain to retrieve metadata for all keys under this domain

Response body example

{
    "metadata": {
        "org.mydomain.firstapp.floor": "basement",
        "org.mydomain.firstapp.room": "conference room",
        "com.otherdomain.client.nice": null,
        "com.otherdomain.client.phonelist": [
            "+492216698000",
            "+492216698999"
        ],
        "com.otherdomain.client.timestamp": 1324898273,
        "com.otherdomain.client.triggers": {
            "this": true,
            "that": false
        }
    }
}
Status:
  • wrong-object: The given UUID does not match an object accessible to the current user

Within the metadata section, the requested metadata information of the object is given in form of a JSON object.

Without any URL parameters, the call will retrieve all metadata keys for the specified object. If the keys parameter is given, only the metadata elements for the given keys are returned. If the domain parameter is given, all metadata elements for keys under this domain (not including the domain as a key itself) are returned. That is, if domain is com.mycompany, keys like com.mycompany.application1.element1 and com.mycompany.entity2 will be returned, but not the key com.mycompany.

POST /api/object/(uuid)/metadata

Modify or delete metadata information associated with the object uuid.

Query Parameters:
 
  • noevent – optional: if present, don’t generate an object_metadata event (see below)
  • nostore – optional: if present, don’t store the metadata permanently (see below)

Request body example

{
    "update": {
        "com.otherdomain.client.nice": true,
        "com.otherdomain.client.timestamp": 1324899645
    },
    "delete": [
        "com.otherdomain.client.something"
    ]
}
JSON Parameters:
 
  • key^[a-z0-9]{2,50}(\\.[a-z0-9]{2,50}){1,10}$
  • value – any valid JSON type, maximum length: 100KB

Response body example

{}
Status:
  • too-large: At least metadata value is too big (100 KB maximum size limit)
  • wrong-object: The given UUID does not match an object accessible to the current user
  • access-denied: The user does not have sufficient privileges on the object (at least write privileges are required)

The metadata keys listed in the update section are updated in the database (or added if they don not currently exist).

The metadata keys listed in the delete section are delete from the database.

To avoid conflicts between different applications that might otherwise use the same metadata keys, metadata keys must have the form of a reverse Internet domain, possibly extended with customer-chose domain elements. Applications are encouraged to use officially registered domains for the first part of their metadata key, like com.mycompany.application1.element1.

By default, the modification of the object’s metadata will generate a object_metadata event that is sent towards all users that have access to the object. This behavior can be suppressed by including the noevent parameter in the request URL.

If the request URL includes the nostore parameter, the given metadata will not be stored to the database (i.e. the contents can not be retrieved with GET /api/object/(uuid)/metadata afterwards). This is useful if the desired behavior is to create the object_metadata event only.

/api/fax

POST /api/fax

Create a new fax object

Request body example

{
    "description": "A description text"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this fax

Response body example

{
    "uuid": "ca9a612c-591d-11e0-a7c8-0024e8f90cc0"
}

The UUID of the new fax is returned.

GET /api/fax/(uuid)

Get information about fax uuid

Response body example

{
    "fax": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145273,
        "description": "Versicherungsvertrag Hausrat",
        "page_count": 12,
        "x_res": 203,
        "y_res": 98,
        "status": "ok",
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ],
        "report": {
            "7b149600-5921-11e0-b85f-0024e8f90cc0": {
                "incoming": true,
                "from": "+492216689711",
                "to": "+492216689712",
                "time_start": 2128383234,
                "time_end": 2128384351,
                "status": "ok",
                "sip_status_code": 200,
                "fax_error_code": 0
            },
            "882b6418-5921-11e0-bb15-0024e8f90cc0": {
                "incoming": false,
                "from": "+492216689712",
                "to": "+4925328372322",
                "time_start": 2128383234,
                "status": "transmit"
            }
        }
    }
}
Status:
  • wrong-fax: The given UUID does not match a fax accessible by the current user

The status field in the fax section can have the following values:

  • record: Fax is being received. No contents are present yet.
  • ok: Fax contents available
  • convert: Fax is being converted (upload). No contents are present yet.
  • empty: Fax has no contents available
  • fail: Fax or fax upload has failed, no contents available

The page_count, x_res and y_res fields will not show if the fax doesn’t (yet) have a content. In the report section, the following status fields are possible:

  • dial: The destination is dialled (outgoing fax only)
  • transmit: The fax is transmitting
  • ok: The fax was transmitted successfully
  • fail: Fax transmission failed
  • cancel: Fax transmission was cancelled by the user (outgoing fax only)
  • busy: Fax transmission failed because opposite site is busy (outgoing fax only)
  • error: Fax cannot be delivered because of an internal error

The sip_status_code field is optional and, if present, delivers information about the status of the underlying telephone call. Likewise, the fax_error_code, if present, gives detailed information about the T.38 fax transaction.

Depending on the status, the time_end field in the report section may or may not be present.

The report section is keyed by the fax report UUID and ordered by time.

POST /api/fax/(uuid)

Modify fax uuid

Request body example

{
    "description": "A description text"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    a short description of this fax

Response body example

{}
Status:
  • wrong-fax: The given UUID does not match a fax accessible by the current user
  • access-denied: The user does not have sufficient privileges on the fax (at least write privileges are required)
DELETE /api/fax/(uuid)

Delete the fax <uuid>

Query Parameters:
 
  • purge – optional: if present, delete this fax permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-fax: The given UUID does not match a fax accessible by the current user
  • access-denied: The user does not have sufficient privileges on the fax (at least write privileges are required)
GET /api/fax/(uuid)/(page)/(xxx).png

Get contents of page page of fax uuid in PNG format

Response body example

The contents of page <page> of the fax in PNG format on success, or
HTTP 404 without response body on failure.

xxx is a file name arbitrarily chosen by the user agent.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the fax uuid. For more information on file download authentication, see Authentication for file downloads.

GET /api/fax/(uuid)/(xxx).pdf

Get contents of fax uuid in PDF format

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The contents of the fax in PDF format on success, or HTTP 404 without
response body on failure.

xxx is a file name arbitrarily chosen by the user agent.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the fax uuid. For more information on file download authentication, see Authentication for file downloads.

POST /api/fax/(uuid)/(xxx).pdf

Post fax uuid contents in PDF format (xxx is an arbitrary name)

Query Parameters:
 
  • orientation – optional: if set to landscape, the contents will be rotated 90 degrees before being rendered into a fax
  • mode – optional: if set to photo, the document will be rastered instead of simply being converted to black and white

Request body

The fax contents in PDF format.

Response body example

{}
Status:
  • wrong-fax: The given UUID does not match a fax accessible by the current user
  • access-denied: The user does not have sufficient privileges on the fax (at least write privileges are required)
  • wrong-state: The contents of this fax cannot be changed, because it is an incoming fax or because it was already transmitted to some destination
  • too-large: The contents are too large to be handled by the system
  • malformed-file: The content is malformed.

xxx is a file name arbitrarily chosen by the user agent. After the contents are received, the PDF file is converted and the contents of the fax are updated.

GET /api/fax/(uuid)/(xxx).tif

Get contents of fax uuid in TIF format

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The contents of the fax in TIF format on success, or HTTP 404 without
response body on failure.

xxx is a file name arbitrarily chosen by the user agent.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the fax uuid. For more information on file download authentication, see Authentication for file downloads.

POST /api/fax/(uuid)/send

Send the fax uuid out to a destination (i.e., queue fax transmission)

Request body example

{
    "from": "+492216698123",
    "to": "+492216698711"
}
JSON Parameters:
 
  • from^\+[0-9]{3,20}$
  • to^\+[0-9]{3,20}$
  • fax_ident

    ^[\+ 0-9]{0,20}$

    Optional; the fax transmitting station ID (TSI)

  • fax_header

    ^.{0,40}$

    Optional; a fax header line printed to the top of the page

Response body example

{
    "uuid": "b2f2a27e-5921-11e0-b923-0024e8f90cc0"
}
Status:
  • wrong-fax: The given UUID does not match a fax accessible by the current user
  • access-denied: The user does not have sufficient privileges on the fax (at least write privileges are required)
  • wrong-phone: The phone number in the from field does not match one of the user’s phone numbers in the system
  • locked-phone: The phone number in the from field has not yet been unlocked
  • quota-exceeded: The send operation would exceed the user’s quota
  • no-content: The fax does not have any content to be sent
  • forbidden-to: Invalid attempt to send to a “expensive” or “premium” number using a “free” user account

The call returns the UUID of the outgoing fax report.

GET /api/fax/(fax-uuid)/report/(report-uuid)/(xxx).pdf

Get a fax sender report in PDF format for the given fax fax-uuid and faxreport report-uuid.

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The contents of the fax report in PDF format on success, or HTTP 404
without response body on failure.

xxx is a file name arbitrarily chosen by the user agent.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the fax report report-uuid. For more information on file download authentication, see Authentication for file downloads.

/api/recording

GET /api/recording/(uuid)

Get information about recording uuid

Response body example

{
    "recording": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145273,
        "description": "Anruf Herr Mueller",
        "from": "+492216689712",
        "to": "+492216689711",
        "status": "ok",
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-recording: The given UUID does not match a recording accessible by the current user

In the recording section, the following status fields are possible:

  • record: The recording is just being recorded (in progress). No contents are present yet.
  • ok: Recording was successful, contents available
  • convert: Recording is being converted (upload). No contents are present yet.
  • empty: Recording was successful, only silence detected, no contents available
  • fail: Recording failed for some reason, no contents available
POST /api/recording/(uuid)

Modify recording uuid

Request body example

{
    "description": "A description text"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    a short description of this recording

Response body example

{}
Status:
  • wrong-recording: The given UUID does not match a recording accessible by the current user
  • access-denied: The user does not have sufficient privileges on the recording (at least write privileges are required)
DELETE /api/recording/(uuid)

Delete recording uuid

Query Parameters:
 
  • purge – optional: if present, delete this recording permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-recording: The given UUID does not match a recording accessible by the current user
  • access-denied: The user does not have sufficient privileges on the recording (at least write privileges are required)
GET /api/recording/(uuid)/(xxx).wav

Get the recording uuid contents in WAV format (xxx is an arbitrary name)

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The recording in WAV format on success, or HTTP 404 without response
body on failure.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the recording uuid. For more information on file download authentication, see Authentication for file downloads.

GET /api/recording/(uuid)/(xxx).ogg

Get the recording uuid contents in Ogg Vorbis format (xxx is an arbitrary name)

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The recording in Ogg Vorbis format on success, or HTTP 404 without
response body on failure.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the recording uuid. For more information on file download authentication, see Authentication for file downloads.

/api/announcement

POST /api/announcement

Create a new announcement object

Request body example

{
    "description": "A description text"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this announcement

Response body example

{
    "uuid": "62f85b4e-5924-11e0-a8ae-0024e8f90cc0"
}

The UUID of the new announcement is returned.

GET /api/announcement/(uuid)

Get information about announcement uuid

Response body example

{
    "announcement": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145273,
        "description": "Meine Standardansage",
        "status": "ok",
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-announcement: The given UUID does not match an announcement accessible by the current user

In the announcement section, the following status fields are possible:

  • record: The announcement is just being recorded (in progress). No contents are present yet.
  • ok: Announcement was successful, contents available
  • convert: Announcement is being converted (upload). No contents are present yet.
  • empty: Announcement was successful, only silence detected, no contents available
  • fail: Announcement failed for some reason, no contents available
POST /api/announcement/(uuid)

Modify announcemet uuid

Request body example

{
    "description": "A description text"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this announcement

Response body example

{}
Status:
  • wrong-announcement: The given UUID does not match an announcement accessible by the current user
  • access-denied: The user does not have sufficient privileges on the announcement (at least write privileges are required)
DELETE /api/announcement/(uuid)

Delete announcement uuid

Query Parameters:
 
  • purge – optional: if present, delete this announcement permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-announcement: The given UUID does not match an announcement accessible by the current user
  • access-denied: The user does not have sufficient privileges on the announcement (at least write privileges are required)
GET /api/announcement/(uuid)/(xxx).wav

Get the announcement uuid contents in WAV format (xxx is an arbitrary name)

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The announcement in WAV format on success, or HTTP 404 without response
body on failure.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the announcement <uuid>. For more information on file download authentication, see Authentication for file downloads.

GET /api/announcement/(uuid)/(xxx).ogg

Get the announcement <uuid> contents in Ogg Vorbis format (<xxx> is an arbitrary name)

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The announcement in Ogg Vorbis format on success, or HTTP 404 without
response body on failure.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the announcement <uuid>. For more information on file download authentication, see Authentication for file downloads.

POST /api/announcement/(uuid)/(xxx).wav

Upload the announcement uuid in WAV format

Request body

The announcement contents in WAV format

Response body example

{}
Status:
  • wrong-announcement: The given UUID does not match an announcement accessible by the current user
  • access-denied: The user does not have sufficient privileges on the announcement (at least write privileges are required)
  • too-large: The contents are too large to be handled by the system
  • malformed-file: The content is malformed.

xxx is a file name arbitrarily chosen by the user agent. After the contents are received, the WAV file is converted and the contents of the announcement is updated.

POST /api/announcement/(uuid)/(xxx).ogg

Upload the announcement uuid in Ogg Vorbis format

Request body

The announcement contents in Ogg Vorbis format

Response body example

{}
Status:
  • wrong-announcement: The given UUID does not match an announcement accessible by the current user
  • access-denied: The user does not have sufficient privileges on the announcement (at least write privileges are required)
  • too-large: The contents are too large to be handled by the system
  • malformed-file: The content is malformed.

xxx is a file name arbitrarily chosen by the user agent. After the contents are received, the Ogg Vorbis file is converted and the contents of the announcement is updated.

POST /api/announcement/(uuid)/text2speech

Upload the announcement uuid in text format.

Request body example

{
    "text": "Hello to Johns mailbox.",
    "locale": "en-GB"
}
JSON Parameters:
 
  • text

    ^.{1,5000}$

    the text of this announcement

  • locale

    ^(de-DE|en-GB|en-US|es-ES|fr-FR|it-IT)$

    optional, default de-DE: the language of text

Response body example

{}
Status:
  • wrong-announcement: The given UUID does not match an announcement accessible by the current user
  • access-denied: The user does not have sufficient privileges on the announcement (at least write privileges are required)

/api/contact

POST /api/contact

Create a new contact object

Request body example

{
    "firstname": "Peter",
    "lastname": "Mueller"
}
JSON Parameters:
 
  • firstname^.{1,50}$`
  • lastname^.{1,50}$`

Response body example

{
    "uuid": "f2e1f97c-592e-11e0-8d4a-0024e8f90cc0"
}

The UUID of the newly created contact object is returned.

GET /api/contact/(uuid)

Get information about contact uuid

Response body example

{
    "contact": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145273,
        "firstname": "Peter",
        "lastname": "Mueller",
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ],
        "entry": {
            "98b62706-9269-11e0-8ef6-0024e8f90cc0": {
                "type": "phone",
                "scope": "business",
                "value": "+492216698100"
            },
            "da084df6-9269-11e0-88e3-0024e8f90cc0": {
                "type": "email",
                "scope": "private",
                "value": "hans@wurst.de"
            },
            "b3dbdf94-9269-11e0-bf32-0024e8f90cc0": {
                "type": "other",
                "scope": "private",
                "key": "Haarfarbe",
                "value": "schwarz"
            }
        }
    }
}
Status:
  • wrong-contact: The given UUID does not match a contact accessible by the current user
POST /api/contact/(uuid)

Modify the contact uuid

Request body example

{
    "firstname": "Peter",
    "lastname": "Mueller",
    "create": [
        {
            "type": "phone",
            "scope": "business",
            "value": "+492216698100"
        }
    ],
    "update": {
        "98b62706-9269-11e0-8ef6-0024e8f90cc0": {
            "type": "phone",
            "value": "+492216698200"
        },
        "b3dbdf94-9269-11e0-bf32-0024e8f90cc0": {
            "type": "other",
            "scope": "private",
            "key": "Strandkorb-Nr.",
            "value": "42a"
        }
    },
    "delete": [
        "da084df6-9269-11e0-88e3-0024e8f90cc0"
    ]
}
JSON Parameters:
 
  • firstname^.{1,50}$
  • lastname^.{1,50}$
  • type^phone|mobile|fax|email|address|other$
  • scope^private|business$
  • key^.{,100}$ (only for type other)
  • value

    ^\\+[0-9]{3,20}$ (type phone, mobile, fax)

    valid email address (type email)

    ^.{,100}$ (type address, other)

Response body example

{
    "create": [
        "04056934-926c-11e0-97ef-0024e8f90cc0"
    ]
}
Status:
  • wrong-contact: The given UUID does not match a contact accessible by the current user
  • access-denied: The user does not have sufficient privileges on the contact (at least write privileges are required)

Newly created entries must have all fields type, scope, key (only for type other) and value.

Modified entries must have at least the fields type, key (only for type other) and value.

The create section of the response lists the member UUIDs for the newly created members (create section of the request).

DELETE /api/contact/(uuid)

Modify the contact uuid

Query Parameters:
 
  • purge – optional: if present, delete this contact permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-contact: The given UUID does not match a contact accessible by the current user
  • access-denied: The user does not have sufficient privileges on the contact (at least write privileges are required)

/api/conference

POST /api/conference

Create a new conference object

Request body example

{
    "description": "Konferenzraum f\u00fcr Team-Besprechung",
    "pin": "4711",
    "active": true,
    "mute_default": true
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this announcement

  • pin

    ^[0-9]{4}$

    The authentication code (PIN) to access the conference

  • active

    true|false

    If true, participants can join the conference

  • mute_default

    true|false

    optional: if true, participants joining the conference are muted by default

Response body example

{
    "uuid": "2d4d09e0-85de-11e0-844e-0024e8f90cc0"
}
Status:
  • duplicate-pin: The PIN is already assigned to another conference object of this user

The UUID of the newly created conference object is returned.

GET /api/conference/(uuid)

Get information about conference uuid

Response body example

{
    "conference": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145373,
        "description": "Konferenzraum f\u00fcr Team-Besprechung",
        "pin": "4711",
        "active": true,
        "mute_default": false,
        "phone": [
            "+492216698000",
            "+493029819232"
        ],
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-conference: The given UUID does not match a conference accessible by the current user
POST /api/conference/(uuid)

Modify the conference uuid

Request body example

{
    "description": "Konferenzraum f\u00fcr Kaffeekr\u00e4nzchen",
    "pin": "4712",
    "active": false,
    "mute_default": false
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    A short description of this conference

  • pin

    ^[0-9]{4}$

    The authentication code (PIN) to access the conference

  • active

    true\|false

    If true, participants can join the conference

  • mute_default

    true\|false

    optional: if true, participants joining the conference are muted by default

Response body example

{}
Status:
  • wrong-conference: The given UUID does not match a conference accessible by the current user
  • access-denied: The user does not have sufficient privileges on the conference (at least write privileges are required)
  • duplicate-pin: The PIN is already assigned to another conference object of this user

All fields in the request are optional.

DELETE /api/conference/(uuid)

Delete conference uuid

Query Parameters:
 
  • purge – optional: if present, delete this conference permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-conference: The given UUID does not match a conference accessible by the current user
  • access-denied: The user does not have sufficient privileges on the conference (at least write privileges are required)
GET /api/conference/(uuid)/event

Subscribe the current session to the event channel of the given conference

Response body example

{
    "busy": true
}
Status:
  • wrong-conference: The given UUID does not match a conference accessible by the current user

This API call will subscribe the current session to the detailed events of the given conference. The events themselves will be delivered by the GET /api/event interface.

If the conference has active participants, the busy field will be true, and the server is supposed to send a conference_status event shortly after receiving this subscription, so that the client can catch up with the current conference state.

If busy is false, then the conference does not have active participants, however the detailed event subscription still takes place, and conference events will start to flow as soon as the first participant enters the conference.

DELETE /api/conference/(uuid)/event

Cancel the subscription of the current session to the event channel of the given conference

Response body example

{}
Status:
  • wrong-conference: The given UUID does not match a conference accessible by the current user

This API call will stop the flow of conference detail events to the current session.

POST /api/conference/(uuid)/member

Modify conference member state

Request body example

{
    "update": {
        "9fe1cc2a-8ab6-11e0-b368-0024e8f90cc0": {
            "user": "2d07f7be-8abc-11e0-8166-0024e8f90cc0",
            "mute": true,
            "deaf": false,
            "volume_in": 1,
            "volume_out": -1
        },
        "b1439c46-8ab6-11e0-acdc-0024e8f90cc0": {
            "mute": false
        }
    },
    "delete": [
        "22731d12-8b6e-11e0-9f8c-0024e8f90cc0",
        "23980df6-8b6e-11e0-b616-0024e8f90cc0"
    ]
}

Response body example

{}
Status:
  • conference-offline: The conference is currently offline, so the action cannot be delivered
  • wrong-conference: The given UUID does not match a conference accessible by the current user
  • access-denied: The user does not have sufficient privileges on the conference (at least write privileges are required)

The update section lists the member UUIDs whose properties are to be modified. All fields within a specific conference member are optional, only those that contain properties to be modified should be present.

The user field is used to associate a conference participant with a system user.

A participant can be muted (i.e., the conference cannot hear what she says) by setting the mute field to true, or made deaf (i.e., she cannot hear the conference) by setting the deaf field to true.

Volume levels for the participant can be set from -4 to 4, whereas 0 is the default level.

The delete section lists the member UUIDs to be kicked from the conference.

/api/volume

POST /api/volume

Create a new volume object

Request body example

{
    "description": "files for project X"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this volume

Response body example

{
    "uuid": "2d4d09e0-85de-11e0-844e-0024e8f90cc0"
}

The UUID of the newly created volume object is returned.

GET /api/volume/(uuid)

Get information about volume uuid

Response body example

{
    "volume": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145373,
        "description": "files for project X",
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
POST /api/volume/(uuid)

Modify volume uuid

Request body example

{
    "description": "files and more for project Y"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    A short description of this volume

Response body example

{}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)

All fields in the request are optional.

DELETE /api/volume/(uuid)

Delete volume uuid

Query Parameters:
 
  • purge – optional: if present, delete this volume permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
POST /api/volume/(uuid)/folder

Create a new folder in volume uuid

Request body example

{
    "name": "temp_files",
    "parent": "2d4d09e0-85de-11e0-844e-0024e8f90cc0",
    "ctime": 21232145273,
    "mtime": 21232145373
}
JSON Parameters:
 
  • name

    valid file name

    The name of the folder

  • parent

    UUID

    The UUID of the parent folder, or, if the folder is to be created at the root level of the volume, the UUID of the volume itself

  • ctime – Optional: the creation time of the folder in seconds-since-epoch, defaults to the current time
  • mtime – Optional: the modification time of the folder in seconds-since-epoch, defaults to the current time

Response body example

{
    "uuid": "8dfb2e5e-45d5-11e1-962b-0024e8f90cc0",
    "commit": "a0801fe0-3632-11e3-9f9f-0024e8f90cc0"
}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
  • wrong-parent: The given parent is not a valid folder in this volume and not the volume itself
  • name-exists: The parent folder already contains a file or folder with the given name

The uuid of the newly created folder is returned.

The commit UUID of the operation is returned in the commit field.

GET /api/volume/(uuid)/folder/(folder-uuid)

Get information about folder folder-uuid in volume uuid. If folder-uuid is the same as uuid, then the information about the volume’s root folder is returned

Response body example

{
    "name": "some_documents",
    "parent": "2d4d09e0-85de-11e0-844e-0024e8f90cc0",
    "ctime": 21232145273,
    "mtime": 21232145373,
    "user": "bc93f42a-45d6-11e1-b856-0024e8f90cc0",
    "content": {
        "637e470a-45db-11e1-bb2e-0024e8f90cc0": {
            "name": "letter.pdf",
            "type": "file",
            "ctime": 20232142212,
            "mtime": 21232145373,
            "user": "bc93f42a-45d6-11e1-b856-0024e8f90cc0",
            "size": 386231,
            "mime_type": "application/pdf",
            "md5": "92f2e0728cd03376ed13a191734cc065"
        },
        "6540c04a-45db-11e1-b771-0024e8f90cc0": {
            "name": "picture.png",
            "type": "file",
            "ctime": 20232142212,
            "mtime": 21232145373,
            "user": "71f79f78-4664-11e1-b5e8-0024e8f90cc0",
            "size": 4982722,
            "mime_type": "image/png",
            "md5": "1ce642b0a3616a60be0dc5651a4abd73"
        },
        "63f0f6b0-45db-11e1-b56b-0024e8f90cc0": {
            "name": "old",
            "type": "folder",
            "ctime": 20232142212,
            "mtime": 21232145373,
            "user": "bc93f42a-45d6-11e1-b856-0024e8f90cc0"
        }
    }
}
Status:
  • wrong-volume: The given uuid does not match a volume accessible by the current user
  • wrong-folder: The given folder-uuid is not a valid folder in this volume

The parent, name, ctime, mtime and user fields in the response body will not be present if the requested folder is the root folder of the volume. For files without content, the size, mime_type, and md5 fields will not be present.

POST /api/volume/(uuid)/folder/(folder-uuid)

Modify folder folder-uuid within volume uuid

Request body example

{
    "name": "temp_files",
    "parent": "2d4d09e0-85de-11e0-844e-0024e8f90cc0",
    "ctime": 21232145273,
    "mtime": 21232145373
}
JSON Parameters:
 
  • name

    valid file name

    The name of the folder

  • parent

    UUID

    The UUID of the parent folder, or, if the folder is to be moved to the root level of the volume, the UUID of the volume itself

  • ctime – The creation time of the folder in seconds-since-epoch
  • mtime – The modification time of the folder in seconds-since-epoch

Response body example

{
    "commit": "a0801fe0-3632-11e3-9f9f-0024e8f90cc0"
}
Status:
  • wrong-volume: The given uuid does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
  • wrong-folder: The given folder-uuid is not a valid folder in this volume
  • wrong-parent: The given parent is not a valid folder in this volume and not the volume itself
  • name-exists: The parent folder already contains a file or folder with the given name

All fields in the request are optional. If the parent field is given, the resulting operation is a move of the folder to a new parent folder. If the name field is given, the resulting operation is a rename of the folder.

In contrast to GET /api/volume/(uuid)/folder/(folder-uuid), this operation is only valid on a sub-folder of the volume, not the volume itself (i.e., folder-uuid must not be equal to uuid).

The commit UUID of the operation is returned in the the commit field.

DELETE /api/volume/(uuid)/folder/(folder-uuid)

Delete folder folder-uuid within volume uuid.

Response body example

{
    "commit": "a0801fe0-3632-11e3-9f9f-0024e8f90cc0"
}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
  • wrong-folder: The given folder-uuid is not a valid folder in this volume and not the UUID of volume itself

This operation recursively deletes all folders and files contained in the given folder.

If folder-uuid is equal to the volume uuid, then all folders and files in the volume are deleted (but not the volume itself).

The commit UUID of the operation is returned in the the commit field.

POST /api/volume/(uuid)/file

Create a new file in volume uuid

Request body example

{
    "name": "picture.png",
    "parent": "2d4d09e0-85de-11e0-844e-0024e8f90cc0",
    "ctime": 21232145273,
    "mtime": 21232145373
}
JSON Parameters:
 
  • name

    valid file name

    The name of the file

  • parent

    UUID

    The UUID of the parent folder, or, if the file is to be created at the root level of the volume, the UUID of the volume itself

  • ctime – Optional: the creation time of the file in seconds-since-epoch, defaults to the current time
  • mtime – Optional: the modification time of the file in seconds-since-epoch, defaults to the current time

Response body example

{
    "uuid": "8dfb2e5e-45d5-11e1-962b-0024e8f90cc0",
    "commit": "a0801fe0-3632-11e3-9f9f-0024e8f90cc0"
}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
  • wrong-parent: The given parent is not a valid folder in this volume and not the volume itself
  • name-exists: The parent folder already contains a file or folder with the given name

The uuid of the newly created file is returned.

The commit UUID of the operation is returned in the the commit field.

GET /api/volume/(uuid)/file/(file-uuid)

Get information about file file-uuid in volume uuid

Response body example

{
    "name": "letter.pdf",
    "parent": "2d4d09e0-85de-11e0-844e-0024e8f90cc0",
    "ctime": 21232145273,
    "mtime": 21232145373,
    "user": "bc93f42a-45d6-11e1-b856-0024e8f90cc0",
    "size": 386231,
    "mime_type": "application/pdf",
    "md5": "92f2e0728cd03376ed13a191734cc065"
}
Status:
  • wrong-volume: The given uuid does not match a volume accessible by the current user
  • wrong-file: The given file-uuid is not a valid file in this volume

For files without content, the size, mime_type, and md5 fields will not be present.

POST /api/volume/(uuid)/file/(file-uuid)

Modify file file-uuid in volume uuid

Request body example

{
    "name": "picture.png",
    "parent": "2d4d09e0-85de-11e0-844e-0024e8f90cc0",
    "ctime": 21232145273,
    "mtime": 21232145373
}
JSON Parameters:
 
  • name

    valid file name

    The name of the file

  • parent

    UUID

    The UUID of the parent folder, or, if the file is to be moved to the root level of the volume, the UUID of the volume itself

  • ctime – The creation time of the file in seconds-since-epoch, defaults to the current time
  • mtime – The modification time of the file in seconds-since-epoch, defaults to the current time

Response body example

{
    "commit": "a0801fe0-3632-11e3-9f9f-0024e8f90cc0"
}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
  • wrong-file: The given file-uuid is not a valid file in this volume
  • wrong-parent: The given parent is not a valid folder in this volume and not the volume itself
  • name-exists: The parent folder already contains a file or folder with the given name

All fields in the request are optional. If the parent field is given, the resulting operation is a move of the file to a new parent folder. If the name field is given, the resulting operation is a rename of the file.

The commit UUID of the operation is returned in the the commit field.

POST /api/volume/(uuid)/file/(file-uuid)/(xxx)

Upload file contents of file file-uuid in volume uuid. xxx is an arbitrary name chosen by the client.

Request body

The file contents

Response body example

{
    "size": 386231,
    "mime_type": "application/pdf",
    "md5": "92f2e0728cd03376ed13a191734cc065",
    "commit": "a0801fe0-3632-11e3-9f9f-0024e8f90cc0"
}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
  • wrong-file: The given file-uuid is not a valid file in this volume
  • quota-exceeded: The upload operation would exceed the user’s quota
  • upload-fail: The upload operation failed

The size, mime_type, and md5 properties of the file will be derived from the content of the upload, stored in the database and returned in the response.

The xxx is an arbitrary name that can be chosen by the client for convenience. It will not change or set the file’s name as defined by this API.

The commit UUID of the operation is returned in the the commit field.

GET /api/volume/(uuid)/file/(file-uuid)/(xxx)

Get file contents of file file-uuid in volume uuid. xxx is an arbitrary name chosen by the client.

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body

The file contents, or a HTTP error status (e.g., 404) if the file does
not exist or is not accessible.

The xxx is an arbitrary name that can be chosen by the client for convenience, for example to select the proposed “download file name” within a browser. It has no influence on which file is selected for download; the file is uniquely addressed by the given file-uuid.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the file’s file-uuid. For more information on file download authentication, see Authentication for file downloads.

GET /api/volume/(uuid)/folder/(folder-uuid)/(xxx)

Get file contents of folder folder-uuid in volume uuid as a compressed ZIP file, i.e. all files and sub-folders of this folder. xxx is an arbitrary name chosen by the client.

Query Parameters:
 
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment. |

Response body

The folder contents as a ZIP file, mime type application/zip, or a HTTP
error status (e.g., 404) if the folder does not exist or is not
accessible.

The xxx is an arbitrary name that can be chosen by the client for convenience, for example to select the proposed “download file name” within a browser (in this case, the extension “.zip” should probably be used to let the user know that the result is actually a ZIP file). It has no influence on which folder is selected for download; the folder is uniquely addressed by the given folder-uuid.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the folder’s folder-uuid. For more information on file download authentication, see Authentication for file downloads.

DELETE /api/volume/(uuid)/file/(file-uuid)

Delete file file-uuid within volume uuid.

Response body example

{
    "commit": "a0801fe0-3632-11e3-9f9f-0024e8f90cc0"
}
Status:
  • wrong-volume: The given UUID does not match a volume accessible by the current user
  • access-denied: The user does not have sufficient privileges on the volume (at least write privileges are required)
  • wrong-file: The given file-uuid is not a valid file in this volume

The commit UUID of the operation is returned in the the commit field.

GET /api/volume/(uuid)/commit

Get commit operations for volume uuid

Query Parameters:
 
  • start – optional: the UUID of the first commit entry to return, exclusive, i.e. the entry with an exact match UUID is not returned.
  • count – optional, default 10: limits the number of returned entries (valid range: 1...500)
  • order – optional: If set to asc (default), commit entries are returned in time ascending order. If set to desc, commit entries are returned in time descending order.

Response body example

{
    "commit": [
        {
            "commit": "383a5354-362f-11e3-837a-0024e8f90cc0",
            "event": "file_new",
            "time": 21232145372,
            "file": "8aaf6000-474f-11e1-b0ba-0024e8f90cc0",
            "volume": "6a8432ec-474f-11e1-8495-0024e8f90cc0",
            "type": "file",
            "name": "letter.pdf",
            "parent": "9e6bde98-474f-11e1-9a62-0024e8f90cc0",
            "ctime": 20232142212,
            "mtime": 21232145372,
            "user": "bc93f42a-45d6-11e1-b856-0024e8f90cc0"
        },
        {
            "commit": "400f9be8-362f-11e3-b868-0024e8f90cc0",
            "event": "file_modify",
            "time": 21232145373,
            "file": "8aaf6000-474f-11e1-b0ba-0024e8f90cc0",
            "volume": "6a8432ec-474f-11e1-8495-0024e8f90cc0",
            "type": "file",
            "parent": "d5edfe04-4750-11e1-be06-0024e8f90cc0",
            "ctime": 20232142212,
            "mtime": 21232145373,
            "user": "bc93f42a-45d6-11e1-b856-0024e8f90cc0",
            "size": 386231,
            "mime_type": "application/pdf",
            "md5": "92f2e0728cd03376ed13a191734cc065"
        },
        {
            "commit": "46bf0e74-362f-11e3-a637-0024e8f90cc0",
            "event": "file_delete",
            "time": 2182782840,
            "file": "8aaf6000-474f-11e1-b0ba-0024e8f90cc0",
            "volume": "6a8432ec-474f-11e1-8495-0024e8f90cc0"
        }
    ]
}
Status:
  • wrong-volume: The given uuid does not match a volume accessible by the current user

The commit log of a volume is the amount of all file events, which are stored in the system and can be retrieved with this call, sorted by time according to the order parameter.

Each file event is marked with a commit entry UUID, which serves for time-ordering and can be used as a key for paging through a large set of commit entries with this command by using the start and count parameters. To get the next batch of commit entries, use the last commit UUID as a start parameter for the next call of this command.

For a detailed description of the entries, refer to the description of the file events in this document (file_new, file_modify, file_delete). Please note that several fields in the file events are optional, for example the name field will only be present in a file_modify event if the file was actually renamed.

/api/box

POST /api/box

Create a new box object and associates the box with a physical device using the device code.

Request body example

{
    "description": "box in office basement",
    "code": "ABCDE-FGHIJ-KLMNI-OPQRS"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this volume

  • code

    ^.{10,50}$

    the device access code, which is the key to the physical device that will be attached to the new box

Response body example

{
    "uuid": "63013ee2-772a-11e1-a9b8-0024e8f90cc0",
    "device": "64215bea-772a-11e1-ae6c-0024e8f90cc0"
}
Status:
  • wrong-code: The given code does not match an available physical device
  • duplicate-box: The device is already linked to an existing box object

The uuid field returns the UUID of the newly created box object. The device field carries the UUID of the device that the box was linked to.

GET /api/box/(uuid)

Get information about box uuid

Response body example

{
    "box": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145273,
        "description": "box in office basement",
        "device": "64215bea-772a-11e1-ae6c-0024e8f90cc0",
        "hw_version": "cospace-box",
        "sw_version": "001",
        "ip_addr": "212.202.35.2",
        "mac_addr": "00:24:e8:f9:0c:c0",
        "online": true,
        "license": {
            "key": "EXAMP-LELIC-ENSEK-EY007",
            "begin_time": 1356998400,
            "expire_time": 1388534399
        },
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-box: The given UUID does not match a box accessible to the current user

The device field carries the UUID of the device associated with the box. The mac_addr field contains the last known MAC address of the associated device, if any. The ip_addr field contains the last known IP address of the device, if any. The online field will have a value of true if the box (aka the associated device) is currently connected to the cloud.

The license section (which will only be present if a license is attached to the box) will contain the license key as well as the license begin and end times (in seconds-since-epoch).

POST /api/box/(uuid)

Modifies box uuid, including the possibility to change the underlying physical device.

Request body example

{
    "description": "new box in office basement",
    "code": "XYZKL-FGHIJ-KLMNI-OPQRS",
    "license": "EXAMP-LELIC-ENSEK-EY007"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this volume

  • code

    ^.{10,50}$

    optional: the device access code, which is the key to the new physical device that will be attached to the new box

  • license

    ^.{10,50}$

    optional: a license key to attach to the box

Response body example

{
    "device": "828bfe1c-772c-11e1-90f0-0024e8f90cc0"
}
Status:
  • wrong-box: The given UUID does not match a box accessible to the current user
  • duplicate-box: The given code is already linked to an existing box object
  • access-denied: The user does not have sufficient privileges on the box (at least write privileges are required)
  • wrong-code: The given code does not match an available physical device
  • wrong-license: The given license key is unknown

The device field carries the UUID of the new device that the box was linked to and is only present if the device association was changed during this request.

Note that once a license key is attached to a box, it cannot be deleted, only be replaced by another license key.

DELETE /api/box/(uuid)

Delete box object uuid

Response body example

{}
Status:
  • wrong-box: The given UUID does not match a box accessible to the current user
  • access-denied: The user does not have sufficient privileges on the box (at least write privileges are required)

The box object is permanently deleted (no trash option) and the association with the physical device is removed.

/api/ipquality

POST /api/ipquality

Create a ipquality object

Request body example

{
    "description": "data center rack #1",
    "source": "736f7e1c-772d-11e1-bc19-0024e8f90cc0",
    "destination": "80334d0e-772d-11e1-b374-0024e8f90cc0",
    "interval": 10,
    "duration": 5,
    "active": true,
    "dscp": 0,
    "ptime": 30,
    "psize": 100
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this object

  • source

    UUID

    optional: the UUID of the box that acts as a source for the quality measurements under this object

  • destination

    UUID

    optional: the UUID of the box that acts as a destination for the quality measurements under this object

  • interval

    ^[0-9]{1,4}$

    the time (in seconds) between the end of a measurement and the start of the next measurement

  • duration

    ^[1-9][0-9]{1,3}$

    the duration of a measurement (in seconds)

  • active

    true|false

    optional: if true, measurements are currently scheduled according to the interval/duration parameters. Defaults to false.

  • dscp

    0..63

    optional: IP DSCP value for the measurement, default 46

  • ptime

    10..1000

    optional: packetization time (packet rate) in ms, default 20

  • psize

    80..2000

    optional: IP packet size, default 200

Response body example

{
    "uuid": "9a955dbc-772e-11e1-ad02-0024e8f90cc0"
}
Status:
  • wrong-box: The given source or destination do not match to accessible box device (at least read access is needed to the respective box object to create a measurement on that box)

The uuid of the newly created ipquality object is returned.

GET /api/ipquality/(uuid)

Get information about ipquality object uuid

Response body example

{
    "ipquality": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145273,
        "description": "data center rack #1",
        "source": {
            "box": "736f7e1c-772d-11e1-bc19-0024e8f90cc0",
            "description": "box in office basement",
            "device": "64215bea-772a-11e1-ae6c-0024e8f90cc0",
            "ip_addr": "212.202.35.2",
            "mac_addr": "00:24:e8:f9:0c:c0",
            "online": true
        },
        "destination": {
            "box": "80334d0e-772d-11e1-b374-0024e8f90cc0",
            "description": "box in the woods",
            "device": "3c445074-abea-11e1-be9e-0024e8f90cc0",
            "ip_addr": "92.192.3.45",
            "mac_addr": "00:c0:e1:12:23:0a"
        },
        "interval": 10,
        "duration": 5,
        "active": true,
        "dscp": 46,
        "ptime": 20,
        "psize": 200,
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-ipquality: The given UUID does not match a ipquality object accessible to the current user

The source and destination sections include information about the source and destination box objects for this ipquality measurement. Their respective description, device UUID, IP address and MAC address will always be included (if they exist), regardless if the user has access to the box or not. The online information will only be included if at least read access to the box is possible for the user, because only in this case a status change might later be recognized in form of a box_online / box_offline event.

POST /api/ipquality/(uuid)

Modify ipquality object uuid

Request body example

{
    "description": "data center rack #2",
    "source": "736f7e1c-772d-11e1-bc19-0024e8f90cc0",
    "destination": "80334d0e-772d-11e1-b374-0024e8f90cc0",
    "interval": 0,
    "duration": 10,
    "active": true,
    "psize": 150
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this object

  • source

    UUID

    optional: the UUID of the box that acts as a source for the quality measurements under this object. To delete the source, this field must be an empty string.

  • destination

    UUID

    optional: the UUID of the box that acts as a destination for the quality measurements under this object. To delete the destination, this field must be an empty string.

  • interval

    ^[0-9]{1,4}$

    optional: the time (in seconds) between the end of a measurement and the start of the next measurement

  • duration

    ^[1-9][0-9]{1,3}$

    optional: the duration of a measurement (in seconds)

  • active

    true|false

    optional: if true, measurements are currently scheduled according to the interval/duration parameters.

  • dscp

    0..63

    optional: IP DSCP value for the measurement, default 46

  • ptime

    10..1000

    optional: packetization time (packet rate) in ms, default 20

  • psize

    80..2000

    optional: IP packet size, default 200

Response body example

{}
Status:
  • wrong-ipquality: The given UUID does not match a ipquality object accessible to the current user
  • access-denied: The user does not have sufficient privileges on the ipquality object (at least write privileges are required)
  • wrong-box: The given source or destination do not match to accessible box device (at least read access is needed to the respective box object to create a measurement on that box)
GET /api/ipquality/(uuid)/result

Get information about ipquality object <uuid>

Parameters:
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start

    optional: the UUID of the first result to return, exclusive, i.e. the result with an exact match UUID is not returned.

    If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.

  • order

    optional: If set to asc (default), objects are returned in time ascending order (i.e. starting with from or start and ending with stop).

    If set to desc, objects are returned in time descending order (i.e. starting with to or start and ending with from).

  • count – optional, default 10: limits the number of returned objects (valid range: 1...1000)

Response body example

{
    "result": {
        "c7c1e972-7747-11e1-85ea-0024e8f90cc0": {
            "time": 2598392983,
            "duration": 10,
            "source": {
                "p_s": 500,
                "p_r": 480,
                "t_n": 475,
                "t_min": 13,
                "t_max": 56,
                "t_sum": 14970,
                "t_sq": 311875,
                "j_n": 465,
                "j_max": 34,
                "j_sum": 2413,
                "j_sq": 11625
            },
            "destination": {
                "p_s": 500,
                "p_r": 480,
                "t_n": 475,
                "t_min": 13,
                "t_max": 56,
                "t_sum": 14970,
                "t_sq": 311875,
                "j_n": 465,
                "j_max": 34,
                "j_sum": 2413,
                "j_sq": 11625
            }
        },
        "d8c42a00-7747-11e1-a938-0024e8f90cc0": {
            "time": 2598392993,
            "duration": 10,
            "source": {
                "p_s": 500,
                "p_r": 480,
                "t_n": 475,
                "t_min": 13,
                "t_max": 56,
                "t_sum": 14970,
                "t_sq": 311875,
                "j_n": 465,
                "j_max": 34,
                "j_sum": 2413,
                "j_sq": 11625,
                "l_n": 20,
                "rfac": 87
            },
            "destination": {
                "p_s": 500,
                "p_r": 480,
                "t_n": 475,
                "t_min": 13,
                "t_max": 56,
                "t_sum": 14970,
                "t_sq": 311875,
                "j_n": 465,
                "j_max": 34,
                "j_sum": 2413,
                "j_sq": 11625,
                "l_n": 18,
                "rfac": 79
            }
        }
    }
}
Status:
  • wrong-ipquality: The given UUID does not match a ipquality object accessible to the current user

Explanation of fields in the source / destination response:

p_s: number of packets sent

p_r: number of packets received

p_e: number of ICMP errors

t_n: number of packets valid for RTT (round-trip time) calculation

t_min: minimum RTT (ms)

t_max: maximum RTT (ms)

t_sum: sum of all RTT values of valid packets (ms)

t_sq: sum of all squared RTT values of valid packets (ms^2)

j_n: number of packets valid for jitter calculation

j_max: maximum jitter (ms)

j_sum: sum of all jitter values of valid packets (ms)

j_sq: sum of all squared jitter value of valid packets (ms^2)

l_n: the number of packet loss sequences

rfac: the R-factor quality assessment of the measurement

Note that the l_n parameter was introduced later and may not be present on older ipquality results. It specifies the number of gaps in the packet sequence, not the number of lost packets. For example, if l_n is 1, it means that all the packet loss happened in one burst error.

The rfac result is optional and will only be present if the parameters of the measurement allow for a quality assessment using the ITU-T E-model (R-factor).

GET /api/ipquality/(uuid)/result/(xxx).csv

Download ipquality results in CSV format

Parameters:
  • from – start time, in seconds-since-epoch (must have from <= to)
  • to – end time, in seconds-since-epoch (must have from <= to)
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

time,duration,src pkts sent,src pkts rcvd,src ICMP errs,src # pkts
RTT,src min RTT,src max RTT,src sum RTT,src square sum RTT,src # pkts
jitter,src max jitter,src sum jitter,src square sum jitter,src # loss
sequences,src r-factor,dst pkts sent,dst pkts rcvd,dst ICMP errs,dst #
pkts RTT,dst min RTT,dst max RTT,dst sum RTT,dst square sum RTT,dst #
pkts jitter,dst max jitter,dst sum jitter,dst square sum jitter,dst #
loss sequences,dst r-factor
1342004417,10,500,500,0,500,0,0,0,0,499,0,0,0,,,500,500,0,499,0,0,0,0,499,0,0,0,,
1342004427,10,500,500,0,500,0,0,0,0,499,0,0,0,,,500,500,0,499,0,0,0,0,499,0,0,0,,
1342004437,10,500,500,0,500,0,0,0,0,499,0,0,0,,,500,500,0,499,0,0,0,0,499,0,0,0,,
1342004447,10,500,500,0,500,0,0,0,0,499,0,0,0,,,500,500,0,499,0,0,0,0,499,0,0,0,,
1342004457,10,500,500,0,500,0,0,0,0,499,0,0,0,,,500,500,0,499,0,0,0,0,499,0,0,0,,
1342004467,10,500,500,0,500,0,0,0,0,499,0,0,0,,,500,500,0,499,0,0,0,0,499,0,0,0,,

This API call allows for downloading of ipquality results in comma-separated-values format. The output is streaming, so very large results can be handled well.

The fields in the CSV output correspond to the fields in the GET /api/ipquality/(uuid)/result call.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the ipquality uuid. For more information on file download authentication, see Authentication for file downloads.

DELETE /api/ipquality/(uuid)

Delete ipquality object uuid

Parameters:
  • purge – optional: if present, delete this object permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-ipquality: The given UUID does not match a ipquality object accessible to the current user
  • access-denied: The user does not have sufficient privileges on the ipquality object (at least write privileges are required)

/api/sip

POST /api/sip

Create a SIP account

Request body example

{
    "password": "sEcReT53a",
    "description": "office phone",
    "domain": "sip.cospace.de"
}
JSON Parameters:
 
  • password

    ^.{5,50}$

    a password for the new account

  • description

    ^.{0,100}$

    optional: a description text for the new account

  • domain

    sip.solucon.com or sip.cospace.de

    optional: the SIP domain that this account is associated with

    SIP accounts created before the 01.01.2016 are created with sip.cospace.de by default. SIP accounts created after that date are using sip.solucon.com instead.

Response body example

{
    "user": "joe_08",
    "domain": "sip.cospace.de"
}
Status:
  • quota-exceeded: The maximum number of SIP accounts for this user is reached
  • wrong-domain: The specified domain is not a valid choice

The user and domain parts of the newly created SIP accounts are returned.

GET /api/sip

Get the user’s SIP accounts

Response body example

{
    "sip": {
        "joe_01": {
            "domain": "sip.solucon.com",
            "password": "sEcReT53a",
            "description": "office phone",
            "contact": "212.202.0.32:5060",
            "expire": 1340107084
        },
        "joe_08": {
            "domain": "sip.cospace.de",
            "password": "sEcReT55a"
        }
    }
}

The contact and expire fields will only be present if there is currently an active registration by a SIP end device for the respective SIP account. contact contains the IP address and port of the registration origin (i.e., usually the IP address and port of the end device), expire contains the absolute time of registration expiration in seconds-since-epoch.

POST /api/sip/(sip-user)

Modify a SIP account

Request body example

{
    "password": "sEcReT54a",
    "description": "PC softphone",
    "domain": "sip.cospace.de"
}
JSON Parameters:
 
  • password

    ^.{5,50}$

    optional: a password for the new account

  • description

    ^.{0,100}$

    optional: a description text for the new account

  • domain

    sip.solucon.com or sip.cospace.de

    optional: the SIP domain that this account is associated with

    SIP accounts created before the 01.01.2016 are created with sip.cospace.de by default. SIP accounts created after that date are using sip.solucon.com instead.

Response body example

{}
Status:
  • wrong-sip: The given SIP user name does not match any of the user’s SIP accounts
  • wrong-domain: The specified domain is not a valid choice
DELETE /api/sip/(sip-user)

Delete a SIP account

Response body example

{}
Status:
  • wrong-sip: The given SIP user / account does not exist
POST /api/sip/(sip-user)/notify

Request the system to send a custom notify message to the given sip-user

Request body example

{
    "event-string": "check-sync;reboot=true",
    "content-type": "application/simple-message-summary"
}
JSON Parameters:
 
  • event-string

    ^.{0,200}$

    the event-string used in the generated notify

  • content-type

    ^.{0,200}$

    the content-type for the generated notify

  • content

    ^.{0,2500}$

    optional: the content set in the generated notify

Response body example

{}
Status:
  • wrong-sip: The given SIP user / account does not exist
  • not-registered: The given SIP user / account is not registered

The user can send custom notify messages to own registered sip accounts e.g. to restart the used device or to reload the current configuration.

GET /api/sip/(sip-user)/blf

Get all active phone number subscriptions for the given sip-user

Response body example

{
    "subscriptions": [
        "492216698711",
        "492216698712"
    ]
}
Status:
  • wrong-sip: The given SIP user / account does not exist
POST /api/sip/(sip-user)/blf

Change the subscriptions of phone numbers for the busy lamp field (blf) feature.

Request body example

{
    "subscribe": [
        "+492216698711",
        "+492216698712"
    ],
    "unsubscribe": [
        "+492216698307"
    ]
}

Response body example

{}
Status:
  • wrong-sip: The given SIP user / account does not exist
  • wrong-phone: At least one phone number does not exist
  • access-denied: The user is not member of an usergroup or at least one owner of the given phone numbers are not in the same usergroup as the user.

The user can subscribe to other users phone numbers and will be notified when these receive calls or are in an active call. The user can also pickup incoming calls from monitored users while they are ringing. In order to use the busy lamp field feature a supported device (SIP-Client) must be used and properly configured.

/api/presentation

POST /api/presentation

Create a new presentation object

Request body example

{
    "description": "Why The Sky Is Black At Nighttime"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this object

Response body example

{
    "uuid": "13e46b2c-13a1-11e2-b0eb-0024e8f90cc0"
}

The uuid of the newly created presentation object is returned.

GET /api/presentation/(uuid)

Get information about presentation object uuid

Response body example

{
    "presentation": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 21232145273,
        "description": "Why The Sky Is Black At Nighttime",
        "page_count": 15,
        "busy": false,
        "status": "ok",
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-presentation: The given UUID does not match a presentation object accessible to the current user

The page_count field returns the number of slides (pages) in this presentation. If no content has been uploaded to the presentation, this field is not present.

The busy field is true if the presentation has been started, i.e. it has active participants.

The status field can have the following values:

  • ok: Presentation content is available
  • convert: Presentation is being converted (upload). No contents are present yet.
  • empty: Presentation has no contents available
  • fail: Presentation or presentation upload has failed, no contents available
POST /api/presentation/(uuid)

Modify presentation object uuid

Request body example

{
    "description": "Why The Sky Is Blue At Daytime"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this object

Response body example

{}
Status:
  • wrong-presentation: The given UUID does not match a presentation object accessible to the current user
  • access-denied: The user does not have sufficient privileges on the presentation object (at least write privileges are required)
GET /api/presentation/(uuid)/(page)/(xxx).png

Get contents of page page of presentation uuid in PNG format

Response body example

The contents of page <page> of the presentation in PNG format on
success, or HTTP 404 without response body on failure.

xxx is a file name arbitrarily chosen by the user agent.

GET /api/presentation/(uuid)/(xxx).pdf

Get original contents of presentation uuid in PDF format

Parameters:
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

The original contents of the presentation in PDF format on success, or
HTTP 404 without response body on failure.

xxx is a file name arbitrarily chosen by the user agent.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the presentation uuid. For more information on file download authentication, see Authentication for file downloads.

POST /api/presentation/(uuid)/(xxx).pdf

Upload presentation uuid contents in PDF format

Request body

The presentation contents in PDF format.

Response body example

{}
Status:
  • wrong-presentation: The given UUID does not match a presentation accessible by the current user
  • access-denied: The user does not have sufficient privileges on the presentation (at least write privileges are required)
  • too-large: The contents are too large to be handled by the system
  • malformed-file: The content is malformed.

xxx is a file name arbitrarily chosen by the user agent.

After the contents are received, the PDF file is converted and the individual pages (slides) of the presentation are stored as images (PNG format). The original content is preserved and can be downloaded later.

DELETE /api/presentation/(uuid)

Delete presentation object uuid

Parameters:
  • purge – optional: if present, delete this object permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-presentation: The given UUID does not match a presentation object accessible to the current user
  • access-denied: The user does not have sufficient privileges on the presentation object (at least write privileges are required)
GET /api/presentation/(uuid)/event

Subscribe the current session to the event channel of the given presentation

Response body example

{
    "busy": true
}
Status:
  • wrong-presentation: The given UUID does not match a presentation accessible by the current user

This API call will subscribe the current session to the detailed events of the given presentation. The events themselves will be delivered by the GET /api/event interface.

If the presentation has active participants, the busy field will be true, and the server is supposed to send a presentation_status event shortly after receiving this subscription, so that the client can catch up with the current presentation state.

If busy is false, then the presentation does not have active participants, however the detailed event subscription still takes place, and presentation events will start to flow as soon as the presentation starts.

DELETE /api/presentation/(uuid)/event

Cancel the subscription of the current session to the event channel of the given presentation

Response body example

{}
Status:
  • wrong-presentation: The given UUID does not match a presentation accessible by the current user

This API call will stop the flow of presentation detail events to the current session.

POST /api/presentation/(uuid)/control

Control the presentation uuid, modify subscription state for participants or control the presentation parameters for the moderator

Request body example

{
    "control": "start"
}

Response body example

{}
Status:
  • wrong-presentation: The given UUID does not match a presentation accessible by the current user
  • illegal-state: The given control parameter does not match the current presentation state or the state of the current user

The following control command parameters are defined:

Start a presentation

{
    "control": "start"
}

This command starts a presentation. The current user will join the presentation as the first member and will take the role of the moderator. If the presentation has already been started, an illegal-state status will be returned.

Stop a presentation

{
    "control": "stop"
}

This command ends a presentation. All members of the presentation leave the presentation. If the presentation has not been started, an illegal-state status will be returned. Only the moderator can stop a presentation.

Join a presentation

{
    "control": "join"
}

With this command, the current user will join the presentation as a listening member. If the presentation has not been started, an illegal-state status will be returned.

Leave a presentation

{
    "control": "leave"
}

With this command, the current user will leave the presentation. If the presentation has not been started, an illegal-state status will be returned.

Member keepalive

{
    "control": "keepalive"
}

A presentation member should send this control after receiving a presentation_keepalive event. The keepalive mechanism is used by the server to continuously ensure the presence of listening members.

Change the presentation moderator

{
    "control": "moderator",
    "moderator": "489fbb76-13a8-11e2-b6aa-0024e8f90cc0"
}

This command changes the moderator of a presentation. If the presentation has not been started, an illegal-state status will be returned. Only users that are currently members of the presentation can be appointed the moderator. The old moderator will stay a member of the presentation.

Switch page

{
    "control": "page",
    "page": 3
}

The current page of the presentation is changed to the given number. If the presentation has not been started, an illegal-state status will be returned. Only the moderator can control the current page.

Move pointer

{
    "control": "pointer",
    "x": 0.47,
    "y": 0.7,
    "visible": true
}

This command changes the pointer properties of the presentation. The x, y and visible fields are all optional. They refer to the pointer position (x, y) with values between 0.0 (left, top) and 1.0 (right, bottom) and control the visibility of the pointer. If the presentation has not been started, an illegal-state status will be returned. Only the moderator can control the pointer.

/api/chat

GET /api/chat

Get information about chats that the user participates in

Parameters:
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start

    optional: the UUID of the first chat to return, exclusive, i.e. the chat with an exact match UUID is not returned.

    If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.

  • order

    optional: if set to asc (default), chats are returned in time ascending order (i.e. starting with from or start and ending with stop).

    If set to desc, chats are returned in time descending order (i.e. starting with to or start and ending with from).

  • count – optional, default 10: limits the number of returned chats (valid range: 1...500)
  • uuid – optional: if set, the chat with the given UUID is returned as a single entry (if it exists and the current user is a member). All other URL parameters are ignored.

Response body example

{
    "chat": {
        "1815eef2-84d3-11e2-8d90-0024e8f90cc0": {
            "description": "some nice chat",
            "create_time": 1362587184,
            "message_head": "fd43561e-84d7-11e2-88d8-0024e8f90cc0",
            "message_read": "68ee6d72-84d3-11e2-a343-0024e8f90cc0",
            "user": [
                "126ad5ae-31a2-11e3-bfaa-0024e8f90cc0",
                "2018470e-31a2-11e3-a05a-0024e8f90cc0"
            ]
        },
        "2c71353c-84d3-11e2-a1d3-0024e8f90cc0": {
            "message_head": "39af0574-84d5-11e2-bf25-0024e8f90cc0",
            "create_time": 1362587000,
            "user": [
                "2018470e-31a2-11e3-a05a-0024e8f90cc0"
            ]
        },
        "3a7354c4-84d5-11e2-a795-0024e8f90cc0": {
            "create_time": 1362534343,
            "user": [
                "126ad5ae-31a2-11e3-bfaa-0024e8f90cc0"
            ]
        }
    }
}

The description field is optional, in fact it might not be set for a majority of chats.

The create_time field denotes the creation time of the chat in seconds-since-epoch.

The message_head UUID points to the newest message in the chat, while the message_read UUID points to the newest message that the current user has marked with POST /api/chat/(uuid)/user. Together, these fields enable a client to detect whether there are new messages in the chat. In addition, they serve to synchronize the “message-read state” between multiple clients. Both fields are optional (no messages might exist in the chat or no message might have been marked yet).

The user section contains all user UUIDs currently participating in the chat, excluding the current session’s user.

POST /api/chat

Create a new chat

Request body example

{}

Response body example

{
    "uuid": "1815eef2-84d3-11e2-8d90-0024e8f90cc0"
}

The newly created chat will have only one participant, the current user.

The call returns the uuid of the newly created chat.

GET /api/chat/(uuid)/user

Get participant information about a specific chat

Response body example

{
    "user": {
        "1de7257a-4f34-11e0-ab6e-0024e8f90cc1": {
            "active": 58,
            "message_read": "68ee6d72-84d3-11e2-a343-0024e8f90cc0"
        },
        "1d333333-4f34-11e0-ab6e-0024e8f90cc1": {
            "active": 35,
            "typing": 20,
            "message_read": "68ee6d72-84d3-11e2-a343-0024e8f90cc0"
        },
        "1d444444-4f34-11e0-ab6e-0024e8f90cc1": {}
    }
}
Status:
  • wrong-chat: The given UUID does not match a chat that the current user participates in

The user section lists all users that participate in the chat. Users are keyed by their user UUID.

Within the individual user’s section, the transient states of the user are listed. The represents the state, and the value is a timeout in seconds that denotes the expire time of this state. For example, if the state is "typing": 20, this means that user is currently typing text, and if no update is received this state will last for the next 20 seconds. It is the responsibility of a client to expire transient states after the given expire time, so in this case the client must set the internal state to “not typing text” after 20 seconds.

Note that all transient states in the user’s section are optional. States that are not listed are supposed to be inactive, i.e. not set.

The following transient states are defined:

  • active states that the user is currently attending the chat, i.e. has an active view of the chat and is most likely to take note of chat contents.
  • typing states that the user is currently typing text.

In addition to the transient states, the user section also lists the message_read field if the corresponding user has read at least one message in the chat.

POST /api/chat/(uuid)/user

Change the current user’s transient chat state or read message pointer

Request body example

{
    "active": 60,
    "typing": 10,
    "message_read": "68ee6d72-84d3-11e2-a343-0024e8f90cc0"
}
JSON Parameters:
 
  • state

    0..60

    optional; the state expire value in seconds, 0 will set the state to inactive immediately

  • message_read

    UUID

    optional; the current message-read pointer for this user

Response body example

{}
Status:
  • wrong-chat: The given UUID does not match a chat that the current user participates in
  • wrong-message: The given message_read does not match a message within the chat

All fields in this request are optional.

With this call, the user can set her own transient states expire values. For a description about transient states, see GET /api/chat/(uuid)/user.

Note that since only expire values between 0 and 60 seconds are allowed, clients are forced to regularly refresh longer lasting states such as active. This mechanism is used to ensure the detection of dead clients.

In addition to the transient states, the message_read pointer for the session’s use can also be set with this call.

GET /api/chat/(uuid)/message

Get chat messages

Parameters:
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start

    optional: the UUID of the first message to return, exclusive, i.e. the message with an exact match UUID is not returned.

    If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.

  • order

    optional: If set to asc (default), messages are returned in time ascending order (i.e. starting with from or start and ending with stop).

    If set to desc, messages are returned in time descending order (i.e. starting with to or start and ending with from).

  • count – optional, default 10: limits the number of returned messages (valid range: 1...500)

Response body example

{
    "message": {
        "c2c35df8-84dd-11e2-933d-0024e8f90cc0": {
            "user": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
            "time": 1362407297,
            "type": "add",
            "member": "fd43561e-84d7-11e2-88d8-0024e8f90cc0"
        },
        "c1aa1566-84d7-11e2-a7a8-0024e8f90cc0": {
            "user": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
            "time": 1362407297,
            "type": "text",
            "text": "what's for lunch today?"
        },
        "ee01a430-84d7-11e2-bab2-0024e8f90cc0": {
            "user": "1d333333-4f34-11e0-ab6e-0024e8f90cc1",
            "time": 1362407293,
            "type": "image"
        },
        "f901a430-84d7-11e2-bab2-0024e8f90cc0": {
            "user": "1d333333-4f34-11e0-ab6e-0024e8f90cc1",
            "time": 1362407297,
            "type": "text",
            "text": "chicken wings \u2013 again :-("
        },
        "fa01a430-84d7-11e2-bab2-0024e8f90cc0": {
            "user": "1d333333-4f34-11e0-ab6e-0024e8f90cc1",
            "time": 1362407293,
            "type": "audio"
        },
        "fd43561e-84d7-11e2-88d8-0024e8f90cc0": {
            "user": "1d444444-4f34-11e0-ab6e-0024e8f90cc1",
            "time": 1362407297,
            "type": "leave"
        }
    }
}
Status:
  • wrong-chat: The given UUID does not match a chat that the current user participates in

The returned chat messages are keyed by the message UUID.

Within the message section, the user field specifies the user who performed the action. For a description of the message types, see POST /api/chat/(uuid)/message.

POST /api/chat/(uuid)/message

Post a chat message or action

Request body example

{
    "type": "text",
    "text": "what's for lunch today?"
}

- or -

{
    "type": "add",
    "member": "1d444444-4f34-11e0-ab6e-0024e8f90cc1"
}
JSON Parameters:
 
  • text

    ^.{1,500}$

    the message text (for type text)

  • description

    ^.{,100}$

    the new chat description (for type description)

  • member

    UUID

    the user UUID of the new member (for type add)

Response body example

{
    "uuid": "c1aa1566-84d7-11e2-a7a8-0024e8f90cc0"
}
Status:
  • wrong-chat: The given UUID does not match a chat that the current user participates in
  • wrong-user: Only for type add: the given member is unknown or has no link with the current user
  • already-member: Only for type add: the given member is already a member of this chat

The following message types are defined:

  • text is a simple text message. The content is delivered in the field text.
  • add adds a new member to the chat. The member field holds the UUID of the new member.
  • leave is used to exit the chat.
  • description is used to change the description of the chat. The new description is delivered in the field description.

The call will return the UUID of the newly created chat message.

POST /api/chat/(uuid)/message/image

Post a chat message with type image

Request body example

Binary encoded image data in JPEG or PNG format

Response body example

{
    "uuid": "c1aa1566-84d7-11e2-a7a8-0024e8f90cc0"
}
Status:
  • wrong-chat: The given UUID does not match a chat that the current user participates in
  • too-large: The image data is too large to be handled
  • malformed-file: The image data is malformed or cannot be handled

This request will create a chat message with type image. The image data is passed as raw image data (format JPEG or PNG) in the request body.

The maximum image size is 10MB and the maximum acceptable dimension is 5000 x 5000 pixels.

The system will down-scale images to a maximum dimension (x- or y-dimension) of 2000 pixels (the large version of the image) and an additional version with a maximum dimension of 500 pixels (the small version of the image). Down-scaling will keep the aspect ration of the image; images smaller than the target dimension will not be up-scaled.

The call will return the UUID of the newly created chat message.

POST /api/chat/(uuid)/message/audio

Post a chat message with type audio

Request body example

Binary encoded audio data in AAC format

Response body example

{
    "uuid": "c1aa1566-84d7-11e2-a7a8-0024e8f90cc0"
}
Status:
  • wrong-chat: The given UUID does not match a chat that the current user participates in
  • too-large: The audio data is too large to be handled
  • malformed-file: The audio data is malformed or cannot be handled

This request will create a chat message with type audio. The audio data is passed in AAC encoded form (MP4 or M4A container).

The maximum encoded audio size is 10MB.

The call will return the UUID of the newly created chat message.

GET /api/chat/(uuid)/message/(message-uuid)/image/(small|large)/(xxx).jpg

Get the contents of a chat message with type image

Response body example

Binary encoded image data in JPEG format, or an HTTP error without
response body on failure.

The size selector within the URL is used to select either the small (maximum dimension 500 pixels) or the large version of the image (maximum dimension of 2000 pixels).

The xxx portion of the URI is an arbitrarily chosen file name by the client.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the message-uuid. For more information on file download authentication, see Authentication for file downloads.

GET /api/chat/(uuid)/message/(message-uuid)/audio/(xxx).(mp4|m4a)

Get the contents of a chat message with type audio

Parameters:
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

Binary encoded image data in AAC format, MP4/M4A container, or an HTTP
error without response body on failure.

The xxx portion of the URI is an arbitrarily chosen file name by the client.

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the message-uuid. For more information on file download authentication, see Authentication for file downloads.

/api/call

GET /api/call

Get details of the current user’s controlled calls within the call API.

Parameters:
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start

    optional: the UUID of the first call to return, exclusive, i.e. the call with an exact match UUID is not returned.

    If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.

  • order

    optional: if set to asc (default), calls are returned in time ascending order (i.e. starting with from or start and ending with stop).

    If set to desc, calls are returned in time descending order (i.e. starting with to or start and ending with from).

  • count – optional, default 10: limits the number of returned calls (valid range: 1...500)
  • uuid – optional: if set, the call with the given UUID is returned as a single entry (if it exists and is owned by the current user. Any other URL parameters are ignored.
  • state – optional: if set to active (default), only active, i.e. ongoing calls will be returned. If set to hangup, historic calls that are already finished will be searched.

Response body example

{
    "call": {
        "2b3b70ce-8677-11e2-a7c1-0024e8f90cc0": {
            "incoming": false,
            "to": "+492216695777",
            "from": "+492216695888",
            "clip": "+492216695000",
            "clir": false,
            "status": "answered",
            "create_time": 1362587184,
            "answer_time": 1362587197,
            "current_control_id": "ivr-second-state",
            "last_control_id": "ivr-first-stage",
            "record_on": false
        },
        "ecbe6758-867a-11e2-a415-0024e8f90cc0": {
            "incoming": true,
            "to": "+492216695888",
            "from": "anonymous",
            "clir": true,
            "status": "ringing",
            "create_time": 1362587213,
            "last_control_id": "let-it-ring",
            "record_on": false
        },
        "ecc434b6-867b-11e2-a32f-0024e8f90cc0": {
            "incoming": true,
            "to": "+492216695888",
            "from": "+498001234567",
            "clir": false,
            "status": "answered",
            "create_time": 1362587213,
            "answer_time": 1362587215,
            "current_control_id": "play-some-stuff",
            "last_control_id": "hook-off",
            "record_on": false,
            "bridge": "1a4d67c2-867c-11e2-aadc-0024e8f90cc0"
        },
        "4644f1d4-867b-11e2-96ed-0024e8f90cc0": {
            "incoming": true,
            "to": "+492216695888",
            "from": "+492216695777",
            "clir": false,
            "status": "hangup",
            "create_time": 1362587350,
            "answer_time": 1362587358,
            "hangup_time": 1362587599,
            "last_control_id": "arrivederci",
            "record_on": false,
            "recording": "ba65e460-867b-11e2-9c3b-0024e8f90cc0",
            "hangup_cause": 16
        }
    }
}

Calls are listed in the call section with the call UUID as the key.

If incoming is true, the call direction is incoming (from the PSTN towards cospace), if false, the direction is from cospace towards the PSTN.

The to field specifies the called phone number (B-party).

The from field specifies the caller’s phone number (A-party).

The clip field is only present if a different, user-signaled caller phone number is associated with the call.

The clir field signals if the presentation of the caller’s phone number is restricted (CLIR feature).

The status field can have one of the following call states:

  • init – only for outgoing calls, the call logic is initialized
  • calling – the call is ongoing and has not received any confirmation or progress yet
  • progress – the call received a confirmation and is progressing
  • ringing – the call is progressing and has ringing indication
  • answered – the call has been answered, media is established
  • hangup – the call has ended

The hangup_cause field is only present if the call status is hangup. It carries the Q.850 termination cause code.

If record_on is true, call media is currently being recorded. If the recording process is finished and the media has been imported into the system, the recording field will show up and carry the UUID of a new recording object that has the media data.

The bridge field is only present if the call is currently bridged with another call. In this case, it carries the UUID of the other call leg.

The create_time field denotes the time of call creation (seconds-since-epoch).

The answer_time field denotes the time of answering (only present if the call was answered).

The hangup_time field denotes the time of call hangup (only present if the call has ended).

If a call control is currently executing on the call, the current_control_id field will carry the user-provided id of this call control.

If at least one call control has finished executing on the call, the last_control_id field will carry the user-provided id of the last call control that was finished.

GET /api/call/event

Subscribe the current session to the call API events

Response body example

{}

This API call will subscribe the current session to the flow of call events which are part of the call API.

DELETE /api/call/event

Cancel the subscription of the current session to the call API events

Response body example

{}

This API call will stop the flow of call API events to the current session.

POST /api/call/dial

Create an outgoing call within the call API

Request body example

{
    "to": "+492216698123",
    "from": "+492216698007",
    "clip": "+4980098989898",
    "clir": false
}
JSON Parameters:
 
  • to

    ^\+[0-9]{3,20}$

    the destination phone number

  • from

    ^\+[0-9]{3,20}$

    the calling phone number, must be one of the current user’s phone numbers

  • clip

    ^\+[0-9]{3,20}$

    optional; an arbitrary phone number for display (CLIP – calling line identification presentation feature)

  • clir

    true|false

    optional, default false; if true, presentation of the calling number is restricted (CLIR feature)

Response body example

{
    "uuid": "2b3b70ce-8677-11e2-a7c1-0024e8f90cc0"
}
Status:
  • wrong-phone: The given from number does not match any of the user’s phone numbers
POST /api/call/(uuid)/control

Execute one or more actions on the call uuid via the call API

Request body example

{
    "queue": "append",
    "controls": [
        {
            "control": "ring"
        },
        {
            "control": "silence",
            "duration": 1000
        },
        {
            "id": "hook-off",
            "control": "answer"
        }
    ]
}
JSON Parameters:
 
  • queue

    append|clear|break

    optional; controls the behavior of the server-side control queue. If append (default), the listed controls are appended to the control queue and are executed after the controls that are already in the queue.

    If set to clear, the server-side queue is cleared and replaced with the given controls.

    break will behave like clear but in addition to clearing the server queue, it will also interrupt the currently running control on the server.

  • id

    ^.{,100}$

    optional; an arbitrary, user-supplied identification string that will be referenced in the call state and events to identify the currently running control.

  • control

    (see below)

    a control action to execute on the call. For detailed description of available controls, see below.

Response body example

{}
Status:
  • illegal-state: the given control parameter does not match the current call state. For example, a call that is already answered will not accept a ring control.
  • wrong-call: the given call uuid is unknown
  • wrong-object: only for control play: the given announcement or recording UUID is invalid

The following call control actions:

Start ringing

{
    "control": "ring"
}

This control will let the call start ringing, which is only possible in incoming calls. The caller will typically hear a network-generated ring-tone in this state.

Signal call progress

{
    "control": "progress"
}

This control will signal call progress on an incoming call. This will establish one-way media flow, so that it is possible to play audio to the call.

Answer the call

{
    "control": "answer"
}

This control will answer the call and establish two-way media flow. This is only possible on incoming calls.

End the call

{
    "control": "hangup",
    "hangup_cause": 16
}

This control will end the call. The optional hangup_cause field can be supplied to specify the ITU-T Q.850 call termination cause. It defaults to 16 (“normal call clearing”).

Bridge two calls

{
    "control": "bridge",
    "call": "0cde3f60-8683-11e2-99bd-0024e8f90cc0",
    "hangup_both": true
}

This control will connect the call with another call, specified by the UUID in the call field. This b-leg call must also be controlled by the same user’s call API.

The optional hangup_both field controls how the other call leg behaves in case a call leg is hung up. If false, then the bridge will terminate but the other channel will stay alive. If true (default value if the field is not given) the other channel will automatically be hung up.

Un-bridge two calls

{
    "control": "split"
}

This control will end the bridge between two calls. To perform this operation, the call must have been previously bridged with another call using the bridge control.

Sleep on a call without audio

{
    "control": "sleep",
    "duration": 1000
}

This control will wait for the specified number of milliseconds (duration field, allowed values between 1 and 3600000). During the sleep, no audio will be played to the call. The primary use is when a call is status where it is not accepting audio (i.e., incoming calls with status calling or outgoing calls that are not yet answered). To pause within an answered call, the use of the silence control is recommended.

This control can be interrupted with the queue break option.

Sleep on a call playing silence

{
    "control": "silence",
    "duration": 1000
}

This control will play silence to the call for the specified number of milliseconds (duration field, allowed values between 1 and 3600000).

This control can be interrupted with the queue break option.

Play a tone one a call

{
    "control": "tone",
    "duration": 1000,
    "frequency": 440,
    "interval": 4000,
    "loop": 10
}

This control will play a tone with the specified frequency (in Hz, values between 0 and 40000) for duration milliseconds (values between 1 and 3600000). If the interval field is given, it specifies a period of silence following the tone (in milliseconds, values between 1 and 3600000). If the loop field is given (range 0 to 1000), the tone (and the optional period of silence) is repeated for the specified amount of times, with 0 meaning endless repetitions.

This control can be interrupted with the queue break option.

Play audio on a call

{
    "control": "play",
    "object": "a93d166e-a69c-5a85-8604-4f9faa6620cc"
}

This control will play the audio contents of an announcement or recording object with the specified object UUID to the channel. The given UUID must point to an object of type announcement or recording.

This control can be interrupted with the queue break option.

Start call recording

{
    "control": "record_start",
    "limit": 30
}

This control will start audio recording on the call. The limit field specifies the maximum duration of the recording in seconds (values between 1 and 3600). The process will eventually generate a recording object and deliver its UUID with an call_update event when the recording is finished.

Stop call recording

{
    "control": "record_stop",
    "discard": true
}

This control will stop an ongoing audio recording on the call. If the optional discard field is given and has a value of true, the recording contents will be discarded. Otherwise, a recording object will be created and its UUID will be delivered with a channel_update event.

Enable / Disable DTMF collection on a call

{
    "control": "dtmf_collect",
    "enable": true
}

This control will enable or disable the recognition and delivery of DTMF digits within the call (which is disabled by default). The enable field specifies whether detected DTMF digits should be delivered via call_dtmf events.

Play DTMF digit on a call

{
    "control": "dtmf_send",
    "digits": "*123#",
    "duration": 250
}

This control will play the specified DTMF digits into the call (valid digits are “0”..”9”, “#” and “*”). Instead of the default DTMF digit duration 100 milliseconds, the duration might optionally be specified by duration parameter (in milliseconds, values between 50 and 3600000).

/api/sensor

POST /api/sensor

Create a new sensor object and associates the sensor with a physical sensor device using the sensor device code.

Request body example

{
    "description": "sensor in my garden",
    "code": "ABCDE-FGHIJ-KLMNI-OPQRS"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this sensor

  • code

    ^.{10,50}$

    the sensor device access code, which is the key to the physical device that will be attached to the new sensor

Response body example

{
    "uuid": "63013ee2-772a-11e1-a9b8-0024e8f90cc0",
    "sdevice": "001a45fe"
}
Status:
  • wrong-code: The given code does not match an available physical sensor device
  • duplicate-sensor: The sensor device is already linked to an existing sensor object

The uuid field returns the UUID of the newly created sensor object as a hex encoded string. The sdevice field carries the hardware address of the sensor device that the sensor was linked to.

GET /api/sensor/(uuid)

Get information about sensor uuid

Response body example

{
    "sensor": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 1363333307,
        "description": "sensor in my garden",
        "sdevice": "001a45fe",
        "mbus": {
           "manufacturer" : "AMT",
           "ident_number" : "50026470",
           "version" : "2e",
           "device_type" : "04"
        },
        "model": "cospace-sensor",
        "profile": "room-sensor-thm",
        "recv_interval": 60,
        "send_interval": 10,
        "recv_after_send": true,
        "recv_time": 1363623307,
        "battery_status": 86,
        "mains_power": true,
        "tamper_detect": 1363347807,
        "fault_detect": 1363347820,
        "capabilities": {
            "data": [
                "temperature",
                "motion"
            ],
            "action": [
                "onoff",
                "text"
            ]
        },
        "state": {
            "data": [
                20.5,
                [1, 10, 50]
            ],
            "action": [
                1,
                "Hello, World!"
            ]
        },
        "box": {
            "efd04b02-8fd8-11e2-bf7e-0024e8f90cc0": {
                "time": 1320403260,
                "rssi": -80,
                "lqi": 45
            },
            "f10cb83e-8fd8-11e2-9f7c-0024e8f90cc0": {
                "time": 1320403155,
                "rssi": -38,
                "lqi": 70
            }
        },
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-sensor: The given UUID does not match a sensor accessible to the current user

The sdevice field carries the hardware address of the sensor device associated with the sensor as a hex encoded string. The model field contains the model identification string of the associated sensor device. If the sensor device belongs to a standardized profile class, this is shown in the profile field.

The optional mbus field carries information retrieved from the M-Bus Device Id if the sensor is an M-Bus device. If so, the sensor uses the M-Bus protocol for communication in the local sensor network. The subfield dev_id provides the complete hex string of the M-Bus device id as transported on the wire (or on the ether if the sensor is an wireless M-Bus device). The manufacturer subfield informs about the device manufacturer in the format given by ASCII code of EN 62056-21 (three uppercase letters). The flag association, UK (http://www.dlms.com/) administers these three letter manufacturers ID of EN 62056-21. The ident_number is a fixed fabrication number that runs from 00000000 to 99999999. The subfield version specifies the generation or version of the device and depends on the manufacturer. It can be used to make sure, that within each ‘’version’’ number the ident_number is unique. The subfield field dev_type mirrors the device type of the sensor in hex code format as specified in EN 113757-3.

The recv_interval field is only present if the sensor is supposed to send data in regular time intervals. It specifies the maximum time interval between sensor transmissions in seconds.

The send_interval field is only present if the sensor participates in the beacon protocol. It specifies the maximum beacon interval for the sensor in seconds.

If the recv_after_send field is present, the sensor will receive data only after having transmitted a packet itself. This is typically used in battery powered applications.

The recv_time field contains the timestamp of the last received data from the sensor. It is only present if the sensor has delivered data at least once in its lifetime.

The battery_ok field (type boolean) will be present if the sensor is battery-powered and is capable of signaling a simple “battery ok” (true) or “battery low” (false) condition. If the sensor is capable of reporting detailed battery statistics, the battery_status field will reflect the battery level in percent. The mains_power field might be present if a battery-powered device is currently running on mains power. If the device has the ability to detect a tampering attempt, the tamper_detect field will be present and will show the timestamp of the first detection. Likewise, the presence of the fault_detect field signals a sensor fault condition timestamp.

The box section will list the UUIDs of the box objects that have had contact with the sensor in the last time. Each box will have some meta-information about the connection to the sensor. Possible fields in this section include time (time of the last sensor contact in seconds-since-epoch), rssi (received signal strength indication in dBm) and lqi (link quality indicator, higher value means better signal).

The capabilities section lists the feature attributes of the sensor device.

In the capabilities data subsection, sensor capabilities are displayed as an ordered array of features (thus with an implicit index). The sensor device in the above example has two sensor features, a temperature sensor at index 0 which will yield a temperature in degrees Celsius), and a motion sensor at index 1 which will yield a motion detection duration time in seconds.

In the capabilities action subsection, actor capabilities are displayed as an ordered array of features (thus with an implicit index). The sensor device in the above example has two actor features, a onoff actor at index 0 that can be switched on (1) or off (0) and a text display at index 1.

The following capabilities are defined with their corresponding data format (see GET /api/sensor/(uuid)/data):

  • temperature: A temperature sensor that has a single JSON number value as data, measured in degree Celsius (°C).
  • light: An illuminance sensor (typically an ambient light sensor) that has a single JSON number value as data, measured in lux (lx; 1 lx = 1 lm/m2 = 1 cd sr/m2).
  • humidity: A sensor for relative humidity that has a single JSON number value as data, measured in percent.
  • open: A sensor that monitors the state of an opening such as a door, window, vent or a similar object. The value is a single JSON number that reads 1 if the state is “open”, or 0 if the state is “closed”.
  • open_percent: A sensor that monitors the state of an opening such as a door, window, vent or a similar object. The value is a percentage, expressed as a single JSON number. The reading is 100 for “open” and 0 if the state is “closed”. Numbers in between signal a half-closed half-open condition.
  • motion: A motion detection sensor which has a JSON array containing exactly three JSON numbers as data. The first number represents the initial state of the motion sensor (0 for no motion detect, 1 for motion detect), the second number represents a time interval in seconds for this state. The third number represents a time interval for the opposite state. As an example, the data [1, 3, 5] would mean that the initial state of the sensor was “motion detect”, this state lasted for 3 seconds, and afterwards the sensor remained 5 seconds in the state “no motion detect”. The data [0, 100, 1] means that the sensor did not detect motion for 100 seconds, but then a motion detect happened for 1 second.
  • energy: An energy meter that has a single JSON number value as data, measured in Watt-hours (Wh; 1 Wh = 0.001 kWh = 3600 J [Joule]).
  • voltage: An electrical voltage sensor that has a single JSON number value as data, measured in Volts (V).
  • current: An electrical current sensor that has a single JSON number value as data, measured in Amperes (A).
  • power: An electrical power sensor that has a single JSON number value as data, measured in Watts (W).
  • power_factor: An electrical power factor. Data is a single JSON number in the range -1..1.
  • frequency: A frequency counter. The data is represented as a JSON number, measured in Hz (1 Hertz = 1 cycle per second).
  • onoff: A switch-type sensor that has a single JSON number as a representation. Valid values are 1 (representing the “on” state) and 0 (“off” state).
  • text: A device that has some sort of text display. The representation is a JSON string which holds the text that is to be displayed with a maximum length of 255 characters.
  • button: A button-type sensor that has a single JSON number as a representation. There is only one valid value, 1, which represents that the button was pressed.
  • color_rgb: A color sensor. The data is represented as a JSON array with exactly three JSON numbers, one for each color component: red, green and blue. Values for the individual components range from 0 to 255. As an example, the data [ 255, 255, 0 ] represents a bright yellow.
  • interval: A time interval expressed as a single JSON number, representing the time period in seconds (s).
  • datetime: An absolute point in time, expressed as a single JSON number that holds the seconds elapsed since the epoch of Jan 1st, 1970.
  • dimmer: A dimmer switch in percent, represented by a single JSON number with values between 0 (completely off) and 100 (completely on).
  • distance: A physical distance (length), expressed by a single JSON number, representing the distance in meters (m).
  • mass: A mass, expressed as a single JSON number, representing the mass in kilograms (kg).
  • mass_flow: A flow rate of mass, expressed as a single JSON number, representing the flow in kilograms per second (kg/s).
  • volume: A space volume, expressed as a single JSON number, representing the volume in cubic meters (m3).
  • volume_flow: A flow rate of volume, expressed as a single JSON number, representing the flow in cubic meters per second (m3/s).
  • fuel_use: A mileage (fuel usage), expressed as a single JSON number, representing the value in liters per 100 km (l/100km).
  • velocity: A velocity, expressed as a single JSON number, representing the speed in meters per second (m/s).
  • acceleration: An acceleration, expressed as a single JSON number, representing the speed gain in meters per square second (m/s2).
  • resistance: An electrical resistance, expressed as a single JSON number, representing the resistance in ohms (Ω).
  • pressure: A pressure, expressed as a single JSON number, representing the pressure in Pascal (Pa; 1 Pa = 1 N/m2).
  • force: A force, expressed as a single JSON number, representing the force in Newton (N).
  • torque: A circular force (torque), expressed as a single JSON number, representing the torque in Newton meters (Nm).
  • angle: An angle, expressed as a single JSON number, representing the angle in degrees (°, full circle is 360°).
  • compass: A compass reading, expressed as a single JSON number, in degrees °, clockwise from the north direction (0°) to east (90°), south (180°) and west (270°) back to north (360°).
  • location: A geographical position. The data is represented as a JSON array with exactly two JSON numbers. The first number represents the longitude, the second number the latitude of the position. Both values are in degrees (°) ranging from -180° to 180°.
  • concentration: A concentration (ratio of mixture between two components), expressed as a single JSON number, representing the concentration in parts-per-million (ppm).
  • ph: A pH value, expressed as a single JSON number, representing the pH (no unit, typical values between 1 and 14).
  • radiation: An ionizing radiation dose. The data is expressed as a single JSON number, representing the dose in Sievert (Sv).
  • sound_pressure: A sound pressure, expressed as a single JSON number, representing acoustic pressure in dezibels (dB).
  • level: An otherwise unspecified logarithmic level, expressed as a single JSON number, representing the level in dezibels (dB).
  • alarm: An alarm sensor. The data is expressed as a single JSON number. Valid values are 0 (“no alarm” state) and 1 (“alarm” state).
  • gauge: An otherwise unspecified absolute value, expressed as a single JSON number.
  • counter: An otherwise unspecified counter value, expressed as a single JSON number.
  • load: An load percentage value, expressed as a single JSON number, representing the load in percent (%).
  • cycles: A rotary speed value, expressed as a single JSON number, representing the rotary speed in cycles per second (1/s).
  • binary_8bit: An otherwise unspecified value, expressed as a single JSON integer number with a range between 0 and 255.
  • binary_16bit: An otherwise unspecified value, expressed as a single JSON integer number with a range between 0 and 65535.
  • binary_32bit: An otherwise unspecified value, expressed as a single JSON integer number with a range between 0 and 4294967295.
  • octets: An otherwise unspecified array of octets (binary string), expressed as a single JSON string in Base64 encoding.
  • mbus_raw: A raw M-Bus (long-)frame, expressed as a single JSON string in Base64 encoding. After its end marker, the frame may be padded with 0x00.

The state section contains the most recent up-to-date status of the data and action elements. Its structure matches the capabilities section. While the GET /api/sensor/(uuid)/data and GET /api/sensor/(uuid)/action calls can be used to get the precise time series of sensor data and actions, the state section represents the current state of each of the data and action items. For the data items, this is the last sensor data update which was not null, and the the action items, this is that last action command which was not null.

POST /api/sensor/(uuid)

Modifies sensor uuid, including the possibility to change the underlying physical sensor device.

Request body example

{
    "description": "new sensor in garden",
    "code": "XYZKL-FGHIJ-KLMNI-OPQRS"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this sensor

  • code

    ^.{10,50}$

    optional: the sensor device access code, which is the key to the new physical sensor device that will be attached to the sensor

  • tamper_detect

    ^0$

    optional: if set to the fixed value of 0, a tamper detect condition of the sensor is cleared

  • fault_detect

    ^0$

    optional: if set to the fixed value of 0, a fault condition of the sensor is cleared

Response body example

{
    "sdevice": "014a5fe7"
}
Status:
  • wrong-sensor: The given UUID does not match a sensor accessible to the current user
  • duplicate-sensor: The given code is already linked to an existing sensor object
  • access-denied: The user does not have sufficient privileges on the sensor (at least write privileges are required)
  • wrong-code: The given code does not match an available physical sensor device

The sdevice field carries the hardware address of the new sensor device that the sensor was linked to as a hex encoded string and is only present if the device association was changed during this request.

DELETE /api/sensor/(uuid)

Delete sensor object uuid

Response body example

{}
Status:
  • wrong-sensor: The given UUID does not match a sensor accessible to the current user
  • access-denied: The user does not have sufficient privileges on the sensor (at least write privileges are required)

The sensor object is is permanently deleted (no trash option) and the association with the physical sensor device is removed. All persistent data associated with the sensor is deleted.

GET /api/sensor/(uuid)/data

Get the sensor data for sensor object uuid

Query Parameters:
 
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start

    optional: the start key of the first data object to return, exclusive, i.e. the result with an exact match data key (definition see below) is not returned.

    If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.

  • order

    optional: If set to asc (default), data objects are returned in time ascending order (i.e. starting with from or start and ending with stop).

    If set to desc, data objects are returned in time descending order (i.e. starting with to or start and ending with from).

  • count – optional, default 10: limits the number of returned data objects (valid range: 1...50000)

Response body example

{
    "data": {
        "1363623247000": [
            20.5,
            [1, 10, 50]
        ],
        "1363623307001": [
            null,
            [0, 500, 0]
        ],
        "1363623367000": [
            21,
            null
        ]
    }
}
Status:
  • wrong-sensor: The given UUID does not match a sensor object accessible to the current user

Within the data section, the requested data objects are listed in form of a JSON object.

The key within the data section consists of the data sampling time in seconds-since-epoch, multiplied by 1000, and increased by an arbitrary ID between 0 and 999 to make the number unique. The key should not be interpreted as a time in milliseconds. The time of the data record has only second precision and can be obtained by converting the key to an integer number and dividing the value by 1000.

The value within the data section is a JSON array. The entries in this array represent the data capabilities of the sensor (see GET /api/sensor/(uuid)). The number of entries in each JSON value array must exactly match the amount of data capabilities of the sensor. The type of values within the array depend on the specific data capabilities.

In this example, since the sensor has a temperature sensor at index 0 and a motion sensor at index 1, each data value consists of two entries, the first one being a single JSON number (temperature in °C), the second one an array of motion detection count and detection time. Each entry might be null, to signal that the sensor did not deliver any data for the respective index.

POST /api/sensor/(uuid)/data

Store sensor data for sensor object uuid

Request body example

{
    "data": {
        "1363623247000": [
            20.5,
            [1, 10, 50]
        ],
        "1363623307001": [
            null,
            [0, 500, 0]
        ],
        "1363623367000": [
            21,
            null
        ]
    }
}

Response body example

{}
Status:
  • wrong-sensor: The given UUID does not match a sensor object accessible to the current user
  • access-denied: The user does not have sufficient privileges on the sensor (at least write privileges are required)
  • malformed-encoding: The Content-Encoding is set to gzip but the payload can not be decompressed.

The body of the request might be gzip encoded which must then be indicated by setting the Content-Encoding HTTP header to gzip.

The data in the request body is given in form of a JSON object.

The keys of the JSON object consists of the data sampling time in milliseconds-since-epoch or of the data sampling time in seconds-since-epoch, multiplied by 1000, and increased by an arbitrary ID between 0 and 999 to make the number unique.

The values of the JSON object are JSON arrays. The entries in this array represent the data capabilities of the sensor (see GET /api/sensor/(uuid)). The number of entries in each JSON value array must exactly match the amount of data capabilities of the sensor. The type of values within the array depend on the specific data capabilities.

In this example, since the sensor has a temperature sensor at index 0 and a motion sensor at index 1, each data value consists of two entries, the first one being a single JSON number (temperature in °C), the second one an array of motion detection count and detection time. Each entry might be null, to signal that the sensor did not deliver any data for the respective index.

GET /api/sensor/(uuid)/action

Get the sensor actions for sensor object uuid

Query Parameters:
 
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • start

    optional: the start key of the first action object to return, exclusive, i.e. the result with an exact match action key (definition see below) is not returned.

    If given, overrides the from parameter when asc order is selected or overrides the to parameter when desc order is selected.

  • order

    optional: If set to asc (default), action objects are returned in time ascending order (i.e. starting with from or start and ending with stop).

    If set to desc, action objects are returned in time descending order (i.e. starting with to or start and ending with from).

  • count – optional, default 10: limits the number of returned action objects (valid range: 1...50000)

Response body example

{
    "action": {
        "1363623253000": [
            0,
            "Hello, World!"
        ],
        "1363623378001": [
            1,
            null
        ]
    }
}
Status:
  • wrong-sensor: The given UUID does not match a sensor object accessible to the current user

This call lists the time series of sensor action commands (i.e. actions that were sent to the sensor with the POST /api/sensor/(uuid)/action call)

Within the action section, the requested data objects are listed in form of a JSON object.

The key within the action section consists of the data sampling time in seconds-since-epoch, multiplied by 1000, and increased by an arbitrary ID between 0 and 999 to make the number unique. The key should not be interpreted as a time in milliseconds. The time of the data record has only second precision and can be obtained by converting the key to an integer number and dividing the value by 1000.

The value within the action section is a JSON array. The entries in this array represent the action capabilities of the sensor (see GET /api/sensor/(uuid)). The number of entries in each JSON value array must exactly match the amount of action capabilities of the sensor. The type of values within the array depend on the specific action capabilities.

GET /api/sensor/(uuid)/data/(xxx).csv

Get the sensor data for sensor object uuid in CSV format

Query Parameters:
 
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

time,U/V,U/V,U/V,t/s,I/A,I/A,I/A,t/s
2014-06-04 13:00:00,230,225,233,300,1.2,1.98,1.34,300
2014-06-04 13:05:00,231,223,233,300,1.24,1.98,1.32,300
2014-06-04 13:10:00,230,222,233,300,1.22,1.98,1.34,300
2014-06-04 13:15:00,231,227,233,300,1.21,1.98,1.31,300

This API call allows for downloading of sensor data results in comma-separated-values format. The output is streaming, so very large result sets can be handled.

The fields in the CSV output correspond to the fields in the GET /api/sensor/(uuid)/data call depending on the data capabilities the sensor supports. If a sensor supports a multidimensional capability, the data is flattened in the downloaded CSV format. This means that every dimension of such a capability has its own header field in the CSV file and the corresponding data separated by commas. For more information on supported capabilities please see documentation of API call GET /api/sensor/(uuid).

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the sensor uuid. For more information on file download authentication, see Authentication for file downloads.

GET /api/sensor/(uuid)/action/(xxx).csv

Get the sensor action for sensor object uuid in CSV format

Query Parameters:
 
  • from – optional: start time, in seconds-since-epoch (must have from <= to)
  • to – optional: end time, in seconds-since-epoch (must have from <= to)
  • inline – optional: if present, the response will include an HTTP Content-Disposition header (see RFC 2183) with a value of inline. Otherwise, the content disposition will be attachment.

Response body example

time,state
2014-06-04 13:00:00,0
2014-06-04 13:05:00,1
2014-06-04 13:10:00,1
2014-06-04 13:15:00,0

This API call allows for downloading of sensor action data in comma-separated-values format. The output is streaming, so very large result sets can be handled.

The fields in the CSV output correspond to the fields in the GET /api/sensor/(uuid)/action call depending on the action capabilities the sensor supports. If a sensor supports a multidimensional capability, the data is flattened in the downloaded CSV format. This means that every dimension of such a capability has its own header field in the CSV file and the corresponding data separated by commas. For more information on supported capabilities please see documentation of API call GET /api/sensor/(uuid).

This API is eligible for use with the session’s download id (did). In this case, the object UUID is the sensor uuid. For more information on file download authentication, see Authentication for file downloads.

POST /api/sensor/(uuid)/action

Triggers an action on the sensor uuid.

Request body example

{
    "action": [
        0,
        "Hello, World!"
    ]
}

- or -

{
    "action": [
        1,
        null
    ]
}

Response body example

{
    "action-uuid": "97a1f558-9167-11e2-892a-0024e8f90cc0"
}
Status:
  • wrong-sensor: The given UUID does not match a sensor accessible to the current user
  • sensor-offline: The sensor is currently not visible through any devices, so the action cannot be delivered

The entries in the JSON array action must exactly match the action capabilities of the sensor (see GET /api/sensor/(uuid)). The type of values in the array depend on the specific action capabilities. In the first example, the sensor has an onoff capability at index 0, which is set to the “off” state (value 0) with this call, and a text capability at index 1 which is instructed to display the string “Hello, World!”. In the second example, the onoff-switch is set to “on”, while the text display remains unchanged.

Note that even though the number of elements in the action array must exactly match the number of action capabilities of the given sensor, a value of null might be given for a specific element to signal that no change is desired for this actor.

If the action was successfully queued to the sensor, the call will return an action UUID. A sensor_action event will be delivered to the user after an acknowledgement message has been received by the sensor to confirm that the action was successfully carried out.

GET /api/sensor/(uuid)/event

Subscribe the current session to the event flow of sensor uuid

Query Parameters:
 
  • timeout – optional: expiration timeout of the event flow in seconds. Default: 1 hour (3600 seconds), valid range 1..36000 seconds (10 hours)

Response body example

{}
Status:
  • wrong-sensor: The given UUID does not match a sensor object accessible to the current user

This API call will enable the flow of sensor_data and sensor_action events to the current session for the specified sensor object. The flow of events will automatically stop after the timeout period. If this behavior is not desired, this API call should be called again before expiration to re-new the timeout period.

DELETE /api/sensor/(uuid)/event

Cancel the subscription of the current session to the data events of sensor uuid

Response body example

{}
Status:
  • wrong-sensor: The given UUID does not match a sensor object accessible to the current user

This API call will stop the flow of sensor data events to the current session for the given sensor.

/api/xobject

POST /api/xobject

Create a new object of type xobject.

Request body example

{
    "description": "some custom object"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this xobject

Response body example

{
    "uuid": "be4b6102-e3b6-11e2-b2d6-0024e8f90cc0"
}

The uuid field returns the UUID of the newly created xobject.

The conceptual idea behind xobjects is to support a form of structured object storage in the cospace system that has no semantic representation in the platform itself. By using objects of type xobject, applications can leverage generic cospace features like attaching tags, comments and linking objects, storing metadata and passing events based on metadata without cospace having to understand the meaning of the application itself. In this way, generic use cases can be implemented on top of the cospace framework.

GET /api/xobject/(uuid)

Get information about the xobject uuid

Response body example

{
    "xobject": {
        "owner": "550e8400-e29b-41d4-a716-446655440000",
        "time": 1372839009,
        "description": "some custom object",
        "tag": [
            "ae30e5b0-5c3d-11e0-817e-0024e8f90cc0",
            "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
        ]
    }
}
Status:
  • wrong-xobject: The given UUID does not match a xobject accessible to the current user

This API call is provided mainly to maintain consistency with other object calls. Since objects of type xobject don’t have any real content besides the description field, applications might want to store custom information using metadata (see POST /api/object/(uuid)/metadata).

POST /api/xobject/(uuid)

Modifies xobject uuid

Request body example

{
    "description": "some other custom object"
}
JSON Parameters:
 
  • description

    ^.{0,200}$

    optional: a short description of this xobject

Response body example

{}
Status:
  • wrong-xobject: The given UUID does not match a xobject accessible to the current user
  • access-denied: The user does not have sufficient privileges on the xobject (at least write privileges are required)

Since objects of type xobject do not have any real content besides the description field, applications might want to store custom information using metadata (see POST /api/object/(uuid)/metadata).

DELETE /api/xobject/(uuid)

Delete xobject uuid

Parameters:
  • purge – optional: if present, delete this xobject permanently (do not move to trash)

Response body example

{}
Status:
  • wrong-xobject: The given UUID does not match a xobject accessible to the current user
  • access-denied: The user does not have sufficient privileges on the xobject (at least write privileges are required)

/api/event

GET /api/event

Returns events pending for the session (event system)

Parameters:
  • timeout – optional: a timeout in seconds after which the call returns even if no event was triggered (valid range: 0...300, default: 55)
  • next – optional: The next event that the client wants to see. For subsequent calls to this function, the value of the next field of the response (see below) can be used here (default: 0)

Response body example

{
    "event": [
        {
            "id": 0,
            "event": "object_new",
            "time": 2182782732,
            "object": "52a9fd3c-8aad-11e0-9138-0024e8f90cc0",
            "type": "contact",
            "owner": "1de7257a-4f34-11e0-ab6e-0024e8f90cc1",
            "description": "Hans Mustermann",
            "tag": [
                "be00e8aa-5c3d-11e0-b0cf-0024e8f90cc0"
            ]
        },
        {
            "id": 1,
            "event": "fax_report",
            "time": 2182782758,
            "fax": "94f1bb1a-5931-11e0-8db5-0024e8f90cc0",
            "report": {
                "7b149600-5921-11e0-b85f-0024e8f90cc0": {
                    "incoming": true,
                    "from": "+492216689711",
                    "to": "+492216689712",
                    "time_start": 2128383234,
                    "time_end": 2128384351,
                    "status": "ok"
                }
            }
        }
    ],
    "next": 2
}
JSON Parameters:
 
  • timeout – The specified (or default) timeout has occurred before an event was triggered

Events are ordered by ascending time (seconds-since-epoch). Please see chapter Generic Event JSON Considerations for a detailed description of the events and their JSON representation.

The next field specifies the next event (i.e., the one expected after the events returned with this call). It can be used for subsequent calls in the next URL parameter.

Note that the amount of events that are stored in the server side might be limited. So if events are not requested by a client for a long period of time, old events might be lost. The client can detect this condition by looking at the id fields: since ids are contiguous, a gap in the id fields indicates that events have been dropped on the server side.

POST /api/event/filter

Attaches a filter to the session’s stream of events

Request body example

{
    "op": "or",
    "args": [
        {
            "op": "and",
            "args": [
                {
                    "op": "equal",
                    "key": "owner",
                    "value": "b4e38072-dcd1-11e2-a597-0024e8f90cc0"
                },
                {
                    "op": "rematch",
                    "key": "type",
                    "value": "sensor|box"
                }
            ]
        },
        {
            "op": "filter",
            "key": "object",
            "arg": {
                "op": "equal",
                "key": "owner",
                "value": "b4e38072-dcd1-11e2-a597-0024e8f90cc0"
            }
        }
    ]
}

Response body example

{}

With this API call, the client can attach a filter to the stream of events for the current session, effectively reducing the amount of events delivered to the client via the GET /api/event call. Every event that is received for the current session is matched against the filter, and only if it passes the filter it is queued for delivery to the client. Note that the filter works on a per-session level. A user might have several sessions with different filters. If a new session is created, it does not have a filter associated with it.

A filter consists of the operator (op field) and one or more additional fields specific for the selected operator. The following operators are supported:

  • equal

    Passes the event if it has a field with the name defined in the filter’s key field that exactly matches the content given in the filter’s value field. Any JSON type might be used for the value field, as the type is also part of the matching process.

  • rematch

    Passes the event if it has a field with the name defined in the filter’s key field that is of JSON string type and matches the regular expression given in the filter’s value field.

  • greater

    Passes the event if it has a field with the name defined in the filter’s key field that is of JSON number type and has a value greater than the JSON number in the filter’s value field.

  • lesser

    Passes the event if it has a field with the name defined in the filter’s key field that is of JSON number type and has a value lesser than the JSON number in the filter’s value field.

  • contain

    Passes the event if it has a field with the name defined in the filter’s key field that is of JSON array type and this array contains an element that exactly matches the content given in the filter’s value field. Any JSON type might be used for the value field, as the type is also part of the matching process.

  • filter

    Passes the event if it has a field with the name defined in the filter’s key field that is of JSON object type and this object passes the filter given in the filter’s value field. With this operator, matching of fields that are nested in deeper JSON structures is possible, since the filter in the value field is now applied one level deeper than the original filter.

  • and

    This filter has an additional args field that is an array of JSON objects, each in turn being a new filter that is applied to the event. If all of these new filters match, then the event is passed.

  • or

    This filter has an additional args field that is an array of JSON objects, each in turn being a new filter that is applied to the event. If at least one of these new filters matches, then the event is passed.

  • not

    This filter has an additional arg field of type JSON object, which in turn is a new filter that is applied to the event. The result of this new filter is negated, i.e. the outer filter passes the event if the inner filter would reject it and the other way around.

The filter given in the example above will pass the event via the GET /api/event call if either condition is true:

  • the event has an owner field with value b4e38072-dcd1-11e2-a597-0024e8f90cc0 and the event has a type field with value sensor or box (regular expression match).
  • the event has an object field which in turn is a JSON object that has an owner field with value b4e38072-dcd1-11e2-a597-0024e8f90cc0.

If the event filtering fails because there is an error in the filter syntax that could not be detected when the filter was attached, the event will pass and will be delivered with the GET /api/event call. In this case, a filter_error field will be present in the event so that the filter failure can be detected by the client.

DELETE /api/event/filter

Removes a session filter from the event system

Response body example

{}

This API call will remove a filter previously applied to the session’s event stream.