Lucid Meetings is a fully hosted solution to manage everything you need to run excellent meetings. We provide a REST API built on pragmatic RESTful design principles.

Introduction

#

Our API uses resource-oriented URLs that leverage built in features of HTTP, like authentication, verbs and response codes. All request and response bodies are JSON encoded, including error responses. Any off-the-shelf HTTP client can be used to communicate with the API.

We believe an API is a user interface for a developer - accordingly, we've made sure our API can be easily explored from the browser!

Changes

#

This is a versionless API. Advance notification of breaking changes will be available in this document and will be sent by email to our developer mailing list. Please contact us at support@lucidmeetings.com to connect with the team.

Authentication

#

This API is authenticated using an application-defined, user-specific API token over HTTPS. Any requests over plain HTTP will fail.

The API tokens can be either Read-Only or Read/Write. A Read-Only token restricts the API caller to the GET, HEAD, and OPTIONS methods. The Read-Write tokens are "full access" tokens that allow the API caller to modify data on behalf of the user.

$ curl -H x-api-key:12345678 https://site.lucidmeetings.com/lucid/api/v1/meetings

All requests are associated with a specific user in Lucid Meetings and permissions are limited to that user's capabilities.

How to Create an API Access Token

  1. Sign in to Lucid Meetings
  2. Click the Account link at the top of the page to access your personal account
  3. Click the Authorize applications button to authorize a new application
  4. Click the Create token button for either the read or read/write token option
  5. Enter the name of your application as the token name ( highly recommended )
  6. Click the Save token button to store your new token
  7. Click the Show API Token link to view or copy your token

Requests

#

The base URL of the API is https://site.lucidmeetings.com/lucid/api/v1 where site should be replaced with your site subdomain. For Lucid Meetings on-demand customers, the base URL is https://meet.lucidmeetings.com/lucid/api/v1 .

JSON Bodies

All POST, PUT, and PATCH requests are JSON encoded and must have have content type of application/json , or the API will return a 415 Unsupported Media Type status code.

$ curl -H x-api-key:X https://site.lucidmeetings.com/lucid/api/v1/meetings/123 \
    -X PATCH \
    -H 'Content-Type: application/json' \
    -d '{"name":"Weekly Staff Meeting"}'

HTTP Verbs

We use standard HTTP verbs to indicate intent of a request:

  • OPTIONS - To retrieve the set of allowable verbs for the resource and requestor
  • HEAD - To retrieve the HTTP headers for a resource or a collection of resources
  • GET - To retrieve a resource or a collection of resources
  • POST - To create a resource
  • PATCH - To modify a resource
  • PUT - To set a resource
  • DELETE - To delete a resource

PATCH Support For Incremental Updates

The Lucid Meetings API supports both PATCH and PUT methods for updating its resources. The PATCH method performs partial updates via instructions that indicate which fields should be modified. For Lucid Meetings resources, all instructions are implicitly "REPLACE", with the field names and replacement values represented as key : value pairs.

{ "email" : "new.email@example.org" }

Limited HTTP Clients

If you are using an HTTP client that doesn't support PUT, PATCH or DELETE requests, send a POST request with an X-HTTP-Method-Override header specifying the desired verb.

$ curl -H x-api-key:X https://site.lucidmeetings.com/lucid/api/v1/meetings/123 \
    -X POST \
    -H "X-HTTP-Method-Override: DELETE"

Responses

#

All response bodies are JSON encoded.

A single resource is represented as a JSON object:

{
  "field1": "value",
  "field2": true,
  "field3": []
}

A collection of resources is represented as a JSON array of objects:

[
  {
    "field1": "value",
    "field2": true,
    "field3": []
  },
  {
    "field1": "another value",
    "field2": false,
    "field3": []
  }
]

Timestamps are in UTC and formatted as ISO 8601.

Unset fields will be represented as a null instead of not being present. If the field is an array, it will be represented as an empty array - ie [] .

HTTP Status Codes

We use HTTP status codes to indicate success or failure of a request.

Success codes:

  • 200 OK - Request succeeded. Response included
  • 201 Created - Resource created. URL to new resource in Location header
  • 204 No Content - Request succeeded, but no response body

Error codes:

  • 400 Bad Request - Could not parse request
  • 401 Unauthorized - No authentication credentials provided or authentication failed
  • 403 Forbidden - Authenticated user does not have access
  • 404 Not Found - Resource not found
  • 405 Method Not Allowed - The requested HTTP method is not implemented or not allowed
  • 410 Gone - The requested resource is no longer available
  • 415 Unsupported Media Type - POST/PUT/PATCH request occurred without a application/json content type
  • 422 Unprocessable Entry - A request to modify or create a resource failed due to a validation error
  • 429 Too Many Requests - Request rejected due to rate limiting
  • 500, 501, 502, 503, etc - An internal server error occured

Errors

All 400 series errors (400, 401, 403, etc) will be returned with a JSON object in the body and a application/json content type.

{
   "message": "Not Found"
}

500 series error codes (500, 501, 502, etc) do not return JSON bodies.

Validation Errors

In case of validation errors on a POST/PUT/PATCH request, a 422 Unprocessable Entry status code will be returned. The JSON response body will include an array of error messages.

{
  "message": "Validation Failed",
  "errors": {
    "resource": "rooms",
    "field": "embed",
    "code": "invalid_value"
  }
}

Rate Limiting

#

The API is rate limited to 100 credits per minute for a single user. A request is typically worth 1 credit. However, embedding can increase the the amount of required credits for a request. All responses include headers describing the current rate limit status:

X-Rate-Limit-Limit: 100
X-Rate-Limit-Remaining: 98
X-Rate-Limit-Used: 2
X-Rate-Limit-Reset: 20
  • X-Rate-Limit-Limit - Total credit for current period
  • X-Rate-Limit-Remaining - Remaining credit for current period
  • X-Rate-Limit-Used - Number of credits used for this request
  • X-Rate-Limit-Reset - Number of seconds until the the credit count resets

If the rate limit is hit, the API will return a 429 Too Many Requests status code. In this situation, your application should not send any further requests until Rate-Limit-Reset seconds have elapsed.

Field Types

#

Most resource fields are typed as basic types, such as plain text , html , email address , enum , integer , boolean , etc. In addition to these basic types, the Lucid Meetings API presents some data as timestamps or tuples that include both the raw value and a more readily usable or display-ready value. This is essentially a light form of embedding.

Plain Text

Input fields identified as plain text are filtered to remove HTML tags during POST, PATCH, and PUT operations. Examples of plain text fields in the Lucid Meetings model include member name, company, title, etc.

HTML

Input fields identified as HTML are filtered via HTMLPurifier to remove unsupported HTML tags and attributes. The current set of tags corresponds to the Lucid Meetings CKEditor (WYSIWYG) configuration: <p>, <b>, <strong>, <s>, <strike>, <del>, <i>, <em>, <span>, <ul>, <ol>, <li>, <br>, <div>. Invalid markup is removed and/or corrected. Examples of HTML fields in the Lucid Meetings model include the description fields for action items and notes.

Timestamps

Internally, the application stores all dates and times as Unix timestamps, deferring conversion to the user's local timezone and language as a matter of the user interface. For programmer convenience, we present timestamps as a tuple containing both the Unix timestamp (value) and an ISO 8601 date/time represenation. The ISO 8601 format is a bit more user friendly and is compatible with a variety of API client usage scenarios.

{
  "create_ts": {
    "value": 1464124304,
    "iso_8601": "2016-05-24T21:11:44Z",
    "pretty": {
      "time": "5:11 PM",
      "date": "24 May 2016",
      "timezone": "New York"
    }
  }
}

The API can use either format when processing dates and times, though internally we always convert the ISO 8601 values to Unix timestamps via strtotime (or equivalent). The strtotime() conversion also accepts Relative Formats, such as "today", "tomorrow", "next week", etc.

Tuples

Internally, the application uses integer IDs throughout as either references or as tokens associated with display values for named properties. All named properties are translatable and subject to change in the application interfaces. For programmer convenience, we strive to include both the reference ID and a display value when presenting coded fields.

{
  "meeting_id": 1214,
  "room_id": {
    "value": 74,
    "display": "Engineering Team"
  },
  "template_id": {
    "value": 192,
    "display": "Staff Meeting Template"
  },
  "name": "Weekly staff meeting"
}

When dealing with the field programmatically, we use the ID portion of the tuple. For example, role_id, member_id, organization_id. To reduce API round trips, we also provide the translated (if available) display value for the reference or field constant value. While this breaks with resource presentation simplicity, ready access to the display value has proved to be a useful tradeoff.

Field Filtering

#

All responses from the API can limit fields to only the fields you need. Just pass in a fields query parameter with a comma separated list of fields you need.

For example:

GET /lucid/api/v1/meetings?fields=meeting_id,name

Would have the following response body:

[
  {
    "name": "Weekly staff meeting",
    "meeting_id": 1214
  },
  {
    "name": "Code review meeting",
    "meeting_id": 1212
  }
]

Embedding

#

Many endpoints support embedding related resources to minimize the number of required API round trips.

Embedding is triggered by passing in an embed query parameter, which takes a comma separated list of endpoint types.

GET /lucid/api/v1/rooms/74?fields=room_id,name&embed=managers
{
  "room_id": 74,
  "name": "Engineering Team",
  "managers": [
    {
      "room_member_id": 224,
      "member_id": {
        "value": 75,
        "display": "Sally Johnson"
      }
    },
    {
      "room_member_id": 333,
      "member_id": {
        "value": 157,
        "display": "Carol Jones"
      }
    },
    {
      "room_member_id": 142,
      "member_id": {
        "value": 1,
        "display": "Bob Smith"
      }
    },
    {
      "room_member_id": 276,
      "member_id": {
        "value": 105,
        "display": "Jack Bronson"
      }
    }
  ]
}

Only certain resource types can be embedded from certain endpoints. The endpoint documentation specifies which ones can be embedded.

Counting

#

All endpoints that return a collection provide a count of the total number of results and result pages. The count will be returned in a header X-Total-Count.

GET /lucid/api/v1/meetings
200 OK
X-Total-Count: 302
X-Total-Pages: 31
X-Page-Num: 0
X-Per-Page: 10
Link: <https://site.lucidmeetings.com/lucid/api/v1/meetings?per_page=10page=1&z=>; rel="next" 
[
  ... results ...
]

Note that the count represents the total amount of available results, not the amount returned as part of the current response.

Enveloping

#

If your HTTP client makes it difficult to read status codes or headers, we can package everything neatly into the response body. Just include envelope=true as a request parameter and the API will always return a 200 HTTP status code. The real status, headers and response will be within the body.

GET /lucid/api/v1/members/does-not-exist?envelope=true
200 OK
{
  "status": 404,
  "headers": {
    "X-Rate-Limit-Limit": 200,
    "X-Rate-Limit-Remaining": 150,
    "X-Rate-Limit-Used": 0,
    "X-Rate-Limit-Reset": 25
  },
  "response": {
    "message": "Not Found"
  }
}

Pagination

#

Requests for collections can return between 0 and 100 results, controlled using the per_page and page query parameters. All end points are limited to 10 results by default.

GET /lucid/api/v1/meetings?per_page=15&page=2

Not all endpoints support pagination. If they do, it will be mentioned in their documentation.

Sorting

#

Some endpoints offer result sorting, triggered using the sort query parameter. The value of sort is a comma separated list of fields to sort by. You can specify descending sort by prepending - to a field. Not all fields can be sorted on. The endpoint documentation will list supported sort options.

Unless otherwise specified in the endpoint doucmentation, the default sort for all endpoints is descending order of creation.

To get upcoming scheduled meetings, sorted in descending order of meeting date:

GET /lucid/api/v1/meetings?sort=-start_time