Skip to main content

Introduction

server_cluster

Welcome to the Carium API, which uses REST and JSON:API to support a wide range of functionality. While most endpoints return JSON-encoded responses, attachments can be retrieved directly. Any exceptions are noted for that specific endpoint. The API uses standard HTTP response codes, authentication, and verbs. All calls must be made over HTTPS.

The root of all API calls is https://api.carium.com. Most API endpoints are versioned, and you should always use the latest version available.

Authentication

Users must authenticate with /identity/v1/login/ to access the Carium API. Access to APIs are then granted by passing your access-token in the request as a Bearer token in the authorization header.

Example call with auth

curl -X 'GET' \
'https://api.carium.com/caredb/v1/journal-entries/' \
-H 'accept: application/vnd.api+json' \
-H 'authorization: Bearer <<access-token>>'

Most endpoints in the Carium API require the user to be authenticated. Unless otherwise noted, assume the access token should be passed in the header.

Error Handling

Carium uses standard HTTP response codes to indicate success or failure of a request. Additionally, some responses include custom error information to allow the caller to resolve the error programmatically or provide a better user experience.

Formats

Some data types returned by the API can not be natively represented in JSON. These types are returned as strings in a specified format -- represented as {"type": "string", "format": "<format>"}. The following types will be frequently returned or taken as input:

  1. date - A date represented as a string in the format YYYY-MM-DD.
  2. datetime - A date and time represented as a string in the format YYYY-MM-DD hh:mm:ss. This is in UTC unless otherwise noted. For input, one may also specify the value as an RFC-3339 timestamp. However, responses will always be in the format YYYY-MM-DD hh:mm:ss.
  3. email - An email address that follows the RFC-2822 format
  4. phonenumberE164 - A phone-number represented as a string in the E.164 format.
  5. uuid - A universally unique identifier represented as a string in the UUID format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. Unless otherwise noted, these may be parsed by clients into a native UUID type and stored as a 128-bit integer.

Paging

Carium supports paging for many of the endpoints. When paging is supported, two optional properties:

PropertyDefaultDescription
page[limit]variesThe maximum number of records returned per page
page[offset]0The starting index of the returned records

Additionally, the top-level 'meta' object contains paging information:

PropertyDescription
page[offset]The starting index of the returned records
page[limit]The maximum number of records returned per page
page[total]The total number of records that match the criteria

Rate Limits

Requests are metered per-user and a usage quota is enforced. If no authentication information is provided, requests are metered per-IP address.

Clients may view rate limit quota consumption by reading the X-Ratelimit-* headers:

HeaderTypeDescription
X-Ratelimit-LimitintRate limit quota.
X-Ratelimit-UsedintUsed quota in the current time bucket.
X-Ratelimit-RemainingintRemaining quota used in current time bucket.
X-Ratelimit-ResetintUnix timestamp when fresh quota will be available. UTC.

Clients exceeding rate limit quotas will be throttled with HTTP 429 Too Many Requests. The response will include Retry-After advisement. Clients should defer additional requests until the time specified to avoid further throttling.

Rate limit quota increases may be requested by contacting support.

Conventions

Standards

Additional Requirements

On top of JSON API spec, Carium API adds additional requirements that are necessary, which includes:

  • Path should be in the form of /<appname>/<version>/<resources>/.

    Examples:

    • /myapp/v1/tests/
    • /yourapp/v3/tickets/
  • Resource object identification should be plural.

    Examples:

    • http://site.app.carium.com/identity/v1/users/
    • http://site.app.carium.com/identity/v1/groups/
  • For action that doesn’t fall within POST/GET/PATCH/DELETE, Carium API supports custom methods that follows the resource specific id (JSON API currently doesn't specify how it should be done). The custom-method must be in a verb form.

    Examples:

    • http://abc.com/identity/v1/tests/1/reset/
    • http://abc.com/identity/v1/tests/11-22-33-44/reset/
  • Carium API doesn't support global action directly on top of the resources (example: /identity/api/v1/tests/reset) to avoid ambiguity.

  • Carium API enforces trailing slash at the end of the path. If the client calls the endpoint without trailing slash, the server will redirect them to the correct one.

Request Parameters

Depending on the HTTP method, Carium API can pass request parameters to the API server using query-string and content/body.

Even though RFC-7231 section 4.3 provides a lot of flexibility on which method to use, to standardize the API implementation, Carium uses:

  • Query String, only for GET and DELETE
  • Content/Body for other methods (PATCH, POST, PUT)

Carium API uses Query String for GET/DELETE to maintain compatibility with other existing implementations (as explained in the RFC). Note that Query String has size-limit (around 4KB, depending on the browser and the web server).

If the API requires larger parameter size, Carium will use other method (for example POST).

Naming

Carium API follows the JSON API restrictions for member names. However, since JSON API doesn’t explicitly mention the naming style for attributes and to keep consistencies, all Carium APIs use Kebab Case, which aligns well with the JavaScript convention.

This style applies to:

  • Query parameters
  • JSON attribute names, both request and response
  • URL path
{
"meta": {
"page[offset]": 0,
"page[limit]": 100
}
}

Filtering

Reference: https://jsonapi.org/format/#fetching-filtering https://jsonapi.org/format/1.1/#query-parameters

  • filter[field]: The value type is based on the field's value

The filter[field] is used for exact match (case insensitive, due to database limitation).

In the case where it’s necessary additional operator comparison (for example gt, lt, contains), extend the filter by adding -<operator.

Example:

filter[name]=abc is searching for all objects with name exactly abc

filter[type]=xyz is searching for all objects with type exactly xyz

filter[name][contains]=abc is searching for all objects that has abc in the name

filter[count][gt]=10 is searching for all objects with count more than 10

filter[date][gte]=2021-09-23 is searching for all objects with date equal to or after 2021-09-23

Valid operators: gt, gte, lt, lte, contains

Datetime filtering:

Although it’s possible to use an option such as filter[datetime][gte]=2021-09-23 00:00:00, Carium API adopted a flexible cmp- formula.  The parameter template is <operator>-<datetime> where operator can be one of >, <, >=, <=.  The equivalent filter in the cmp- style would be:

filter[cmp-datetime]=>=2021-09-23 00:00:00

AND vs OR

AND operations are accomplished by including multiple & separated filter statements.  In the case where the same filter can be repeated this is seen as an array type option. E.g.:

filter[cmp-start-at]=>=2021-09-23 00:00:00&filter[cmp-start-at]=<2021-09-24 00:00:00

OR operations can be accomplished for a single filter with comma separated values.

Specifically this can be applied for complex datetime filtering to allow for null values:

filter[cmp-datetime]=>=2021-09-23 00:00:00,null

Note on field vs filter[field] parameter name:

field is used for a required field. For example, when a client calls list API, it’s often required to pass an organization filter. In this case, the parameter should be organization-id.

Nullable

There are some conflicts in regards to specify if an argument is nullable or not. This case is useful when the API allows a user to reset a certain attribute, while enforcing the formatter on that argument.

For example: specifying a phone attribute with e164 format, but also allow an empty value to nullify/reset this attribute.

While Swagger OpenAPI 3.0 supports the Nullable type, OpenAPI 3.1 drops that support in favor of json-schema compatible oneOf flavor.

The preferred nullable definition would be:

"expire-time": {
"oneOf": {
{"type": "null"},
{"type": "string", "format": "datetime"},
}
}

Sorting

Reference: https://jsonapi.org/format/#fetching-sorting

  • sort: Array(String(enum=[]), min_items=1)

Different than the spec, sort uses array structure to indicate multiple sort fields. For example: service1/v1/objects?sort=field1&sort=field2

Error

Reference: https://jsonapi.org/format/#errors

Example:

{
"errors": [
{
"status": "400",
"detail": "User is not in confirmed state",
"code": "UserDisabledError",
"meta": { "key": "value" }
}
]
}

meta attribute is optional.

Status Code

  • 200: Default return value for GET and PUT when operation was successful.
  • 201: Used for POST when operation was successful.
  • 202: Used for POST, PUT, DELETE, when operation was pending and result isn’t yet available.
  • 204: Used for DELETE when there is no content to return.
  • 400: Common response for user error. Ideally, user should be able to change their request parameters to fix this error.
  • 403: Error response for access denied.
  • 404: Error response for resource not found.
  • 500: Internal server error. This is the default error when the server finds an unhandled exception. The client shouldn’t see this error.

Philosophies

In general at HTTP interfaces between applications the Carium API follows the robustness principle to ensure loose coupling between the Carium applications.