Akiles API Reference

Akiles API

API Endpoint
https://api.akiles.app/v2
Contact: support@akiles.app
Version: 2.0

Changelog

Version 2.0

Released July 2020

New features

  • Members can now have multiple email addresses.
  • Members can now have multiple magic links.
  • A member can have email addresses and magic links at the same time.
  • A member can now be associated to multiple groups, with each association having its own start and end date/times.

Having multiple email addresses is useful for hotel room reserves where you have multiple guests in the same room. Now you can create the reserve as a single member that grants access to all guests.

Per-group start/end times is useful for room reservations: the same member can have multiple reservations for different rooms at different times, and he'll only be able to enter each room during the allowed time.

API changes

  • Removed member fields: type, email, member_group_ids
  • Removed endpoints /members/{member_id}/magic_link
  • Added endpoints /members/{member_id}/emails
  • Added endpoints /members/{member_id}/magic_links
  • Added endpoints /members/{member_id}/group_associations

Version 1.0

Initial API release

Versioning

The major version is indicated in the URL. For example https://api.akiles.app/v2 vs https://api.akiles.app/v2. The minor version is not indicated anywhere, since minor versions only do backwards-compatible changes. A client designed for API version v2.0 should work unmodified on version v2.1, provided it follows the compatibility policy outlined below.

We will release new minor versions with only backwards-compatible changes. We consider the following changes backwards-compatible:

  • Adding new endpoints.
  • Adding new HTTP methods to existing endpoints.
  • Adding new optional fields to request objects.
  • Adding new fields to response objects.
  • Adding new possible values to enum fields.
  • Relaxing request validation rules. For example, a field couldn't be null before and now it can.

Keep these in mind when developing your integration. For example, when parsing API responses, ignore unknown received fields instead of erroring.

Ocasionally, when backwards-incompatible changes are necessary for the healthy evolution of the platform, we will also release new major API versions. In this case, the previous major version will be supported for at least 6 months after the launch of the new major version.

Integration examples

There are many ways of integrating Akiles into your existing platform or service. There are two main categories:

-Sync integration (non whitelabel): The user end user will login with the Akiles app or website (magic link, without downloading any app). You can still customize and change all the related paramenters such as membership validity, permissions, sites, etc. The integration consists in syncing your existing objects (users, reservations) with Akiles so user creation and management can be fully automatic.

-Whitelabel integration: The end user will be able to access the diferent spaces through a custom experience in your app or website. You can implement any logic that will end up opening a door. This integration has extra cost and is only available with the whitelabel feature. If you plan to publish your integration and make it available to all Akiles customers, we suggest you to use the non whitelabel option.

Sync integration (non whitelabel)

In this kind of integration, the user will use the Akiles app and environment to interact with your spaces. The idea behind this integration is directly creating or editing other Akiles objects from your backend as needed. You will be able to create, edit and delete members or any other object or parameter based on your business logic.

The end user will have to login once the required member is created using any of the valid login methods. You will have to use the already flexible Akiles permission system to implement your logic.

This kind of integration is recommended for Property Management Systems, Booking systems, etc.

Example flow:

  1. You get a new reservation. Just gather all the relevant details.
  2. Perform a member create API call. Remember to store the returned member_id in your database
POST https://api.akiles.app/v2/members
Content-Type: application/json;charset=UTF-8

{
  "name": "John Doe",
}
  1. Based on the reservation or booking parameters, associate a group to the recently created member. The group will determine which set of spaces the guest will have access. Do a group association create API request.
POST https://api.akiles.app/v2/members/{member_id}/group_associations
Content-Type: application/json;charset=UTF-8

{
  "member_group_id": "mg_3merk33gt1692dk2p2m1",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
}
  1. Choose a login method for the user and send an invite. For temporary applications we recommend using the magic link rather than the email. Do a magic link create API request.
POST https://api.akiles.app/v2/members/{member_id}/magic_links
Content-Type: application/json;charset=UTF-8

{}
  1. Reveal the link. Warning: Remember that the link is able to grant access to your space. You should protect it and distribute it using a secure channel. In order to reveal the link do a magic link reveal API request.
POST https://api.akiles.app/v2/members/{member_id}/magic_links/{member_magic_link_id}/reveal
Content-Type: application/json;charset=UTF-8

{}
  1. Send the link to the final user or display it somewhere.

Whitelabel integration

For this kind of integration the user will directly interact with the gadgets, going through a custom experience. You will be responsible for implementing a proper UX/UI and or equivalent business logic.

As an example, the final user will typically login in your platform. You will have to implement all the permissions and conditions before granting the user access to the gadget. Finally, if theese conditions are met, your backend will call the gadget action endpoint in order to perform the action. You will prevously need to call gadget list endpoint in order to get the ids.

Example flow:

  1. The end user logs in into your app or website
  2. Your platform checks against your backend or database if the end user meets certain requirements before accessing the action button (have a valid reservation, plan, account, etc...)
  3. The user clicks the action button. Your backend does the gadget action API call with the gadget id of the gadget related to the space you want the action to happen
POST https://api.akiles.app/v2/gadgets/{gadget_id}
Content-Type: application/json;charset=UTF-8

{
  "id": "open",
  "name": "Open"
}
  1. Handle response or error

Authentication types

There are two ways to authenticate to the API: API keys and OAuth.

Use API keys if you're developing integrations that you will only use with your own Akiles organization. This is the easiest and simplest way to get started, and the security benefits of OAuth don't apply to you anyway.

Use OAuth if you want other people to use your integration. The most common use case is if you are developing a SaaS and want your customers to be able to enable your integration with their own Akiles organizations.

Additionally, OAuth is required to get your application/integration listed in the Applications tab in the Akiles admin panel. Listing your application will make it discoverable to all Akiles customers.

API key authentication

API keys are static keys that can be used to make calls to the Akiles API.

To create an API key, login to the Akiles admin panel, and go to API -> API keys and create one. For security, you will only be able to see the full value of the API key once, when creating it.

To use the API key, include an Authorization: Bearer header with it:

Authorization: Bearer ak_3pbzqfe...

All API keys have full read-write permissions, equivalent to organization administrators. All the actions performed with the API key are attributed to it in the events.

OAuth authentication

OAuth authentication uses the standard RFC-6479 OAuth 2.0 protocol. It allows your app to interactively request access to customers' Akiles organizations and obtain access tokens for them. This makes the experience smoother and more secure, since the customer doesn't have to manually copy and paste a sensitive API key.

This section is not intended to be a full explanation on how OAuth works, just a quick reference to get started. For more info, consult online documentation about OAuth.

Client ID and Client Secret

Your OAuth application needs a Client ID and a Client Secret to operate.

  • The Client ID is considered public, it is OK to expose it to frontends (and is in fact necessary to do so).
  • The Client Secret must be maintained confidential since it is used to obtain access tokens. Always use it from your server, never send it or expose it to your frontend.

To obtain your application's Client ID and Secret, contact support.

Token types

  • Access token: used to make API calls, expires 1 hour after issuance.
  • Refresh token: used to obtain new access tokens when they expire.

There are multiple types of Access and Refresh tokens depending on how they've been obtained

  • Session access/refresh token: This token is associated to an organization and a particular user's session. They get revoked in these cases:
    • The user logs out
    • The user's session expires due to inactivity
    • The user is removed as an admin from the organization
    • The application is deauthorized from the organization
  • Organization access/refresh token: This token is only associated to an organization. They get revoked in these cases:
    • The application is deauthorized from the organization

When doing the authorization flow you will receive session access/refresh tokens. If you need persistent access to the organization (e.g. after the user logs out), you can do so by requesting the offline scope, and exchanging the session token for organization access/refresh tokens (see below).

Authorization flow

  1. Generate a cryptographically-secure random string state and store it somewhere you can access it later (e.g. a cookie)
  2. Start the flow by redirecting the user to the following URL:
https://auth.akiles.app/oauth2/auth?client_id=CLIENT_ID_HERE>&redirect_uri=https://your-app.example.com/redirect&response_type=code&scope=full_read_write&state=STATE_HERE
  1. The Akiles authorization server will prompt the user to choose a user account and organization.
  2. The Akiles authorization server will ask the user to authorize your requested scopes.
  3. The user gets redirected to your redirect_uri:
https://your-app.example.com/redirect?code=CODE_HERE&scope=full_read_write&state=STATE_HERE
  1. Check the state you have received matches the original state you stored. If it doesn't, abort. This is necessary to protect against CSRF / session poisoning attacks.
  2. Exchange the authorization code for the access and refresh tokens.
POST https://auth.akiles.app/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
client_id=CLIENT_ID_HERE
client_secret=CLIENT_SECRET_HERE
code=CODE_HERE
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
  "access_token": "ACCESS_TOKEN_HERE",
  "expires_in": 3599,
  "refresh_token": "REFRESH_TOKEN_HERE",
  "scope": "full_read_write",
  "token_type": "bearer"
}
  1. You're done! Save the access token and refresh token.

You can now use the access token to make API calls on behalf of the user's organization. The access token expires in 1 hour. You can obtain new, fresh access tokens with the refresh token.

Refresh token flow

POST https://auth.akiles.app/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
client_id=CLIENT_ID_HERE
client_secret=CLIENT_SECRET_HERE
refresh_token=REFRESH_TOKEN_HERE
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
  "access_token": "NEW_ACCESS_TOKEN_HERE",
  "expires_in": 3599,
  "refresh_token": "NEW_REFRESH_TOKEN_HERE",
  "scope": "full_read_write offline",
  "token_type": "bearer"
}

Store both the new access and refresh tokens. The old refresh token, once used, is no longer guaranteed to keep working forever.

Token exchange flow

If you want to exchange a session acess token for an organization access token (see "Token types" above), do the following request:

POST https://auth.akiles.app/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=token_exchange
exchange_to=organization
client_id=CLIENT_ID_HERE
client_secret=CLIENT_SECRET_HERE
refresh_token=SESSION_REFRESH_TOKEN_HERE
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
  "access_token": "ORGANIZATION_ACCESS_TOKEN_HERE",
  "expires_in": 3599,
  "refresh_token": "ORGANIZATION_REFRESH_TOKEN_HERE",
  "scope": "full_read_write offline",
  "token_type": "bearer"
}

Store the new access and refresh tokens. Note that unlike a normal refresh, a token exchange does not "use up" the original refresh token. You may store both session and organization tokens, and keep using and refreshing both independently.

Scopes

  • full_read_write: read-write access to all the objects. Same as a regular API key, or an administrator user.
  • full_read_only: read-only access to all the objects.
  • offline: allows offline access. You need this to obtain refresh tokens, and to exchange session tokens for organization tokens.

Webhooks

Webhook objects are scoped to your OAuth application. That is, webhooks created with API keys or manually from the admin panel won't be visible to you, and webhooks you create won't be visible to API keys or in the admin panel.

All your application's webhooks in an organization will be deleted when your app gets deauthorized.

You must create/edit/delete webhooks with an organization access token, not with a session access token.

Even if you have read-only access, you can still create/edit/delete webhooks. This allows you to receive real-time updates in an application that only needs to read data from the Akiles organization.

Pagination

The API uses cursor-based pagination. All list endpoints return data in reverse chronological order, and have the following common structure:

GET parameters

  • limit: How many items to fetch, between 1 and 100
  • cursor: Value of cursor_next from a previous request. If not given, it will fetch the most recent items.

Response data

  • data: The received items, in a JSON array.
  • has_next: Whether there are more items to fetch.
  • cursor_next: Cursor to fetch the next page of items. Only present if has_next is true.

Metadata

Most API objects allow you to attach your own, arbitrary key-value metadata in the metadata field. You can use it to store references to primary keys of your database, custom states, etc.

Metadata is visible to anyone with admin or API access to your organization. There is a storage limit of 1024 bytes of metadata per object.

metadata

Key-value metadata

string
Example
{
  "key1": "value1",
  "key2": "value2"
}

Organizations

Everything in Akiles APIs belongs to an Organization. An organization represents one Akiles customer and can handle multiple sites, gadgets, etc.. API keys are tied to organizations too, and they give access only to the objects belonging to the organization.

organization

id
string (organization_id)

Unique identifier.

name
string

Name.

is_deleted
boolean

Indicates if the object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "org_3merk33gt1v9ypgfzrp1",
  "name": "SkyCowork",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Get organization

GET /organization
An instance of organization
Response Example (200 OK)
{
  "id": "org_3merk33gt1v9ypgfzrp1",
  "name": "SkyCowork",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit organization

PATCH /organization
metadata
metadata

Key-value metadata

Request Example
{
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of organization
Response Example (200 OK)
{
  "id": "org_3merk33gt1v9ypgfzrp1",
  "name": "SkyCowork",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Sites

A site is a physical place where Akiles gadgets are installed. For example, it can be a building, a floor... Gadgets belong to a particular site.

End users will see one "card" in their app's home screen per site. The site information (email, contact, etc) is displayed in that card.

location

lat
number (float)

Latitude in degrees

lng
number (float)

Longitude

Example
{
  "lat": 41.290485,
  "lng": 2.1829076
}

site_geo

location
location
radius
number

Radius in meters

Example
{
  "location": {
    "lat": 41.290485,
    "lng": 2.1829076
  },
  "radius": 100
}

site_map

location
location
place_id
string

place_id from Google Maps Places API

address
string

Human-readable address

image_url
string

Map image URL, displayed in the site's header in the app.

Example
{
  "location": {
    "lat": 41.290485,
    "lng": 2.1829076
  },
  "place_id": "string",
  "address": "string",
  "image_url": "string"
}

site

id
string (site_id)

site ID

name
string

Site name

organization_id
string (organization_id)

organization ID

geo
site_geo
map
site_map
phone
string

Phone number. Shown in the site info in the app.

email
string

Email. Shown in the site info in the app.

info
string

Free-form extra information. Shown in the site info in the app.

timezone
string (timezone)

Local time zone of the site.

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "site_3merk33gt21kym11een1",
  "name": "string",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "geo": {
    "location": {
      "lat": 41.290485,
      "lng": 2.1829076
    },
    "radius": 100
  },
  "map": {
    "location": {
      "lat": 41.290485,
      "lng": 2.1829076
    },
    "place_id": "string",
    "address": "string",
    "image_url": "string"
  },
  "phone": "string",
  "email": "string",
  "info": "string",
  "timezone": "Europe/Madrid",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

List sites

GET /sites
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

data
site
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "site_3merk33gt21kym11een1",
      "name": "string",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "geo": {
        "location": {
          "lat": 41.290485,
          "lng": 2.1829076
        },
        "radius": 100
      },
      "map": {
        "location": {
          "lat": 41.290485,
          "lng": 2.1829076
        },
        "place_id": "string",
        "address": "string",
        "image_url": "string"
      },
      "phone": "string",
      "email": "string",
      "info": "string",
      "timezone": "Europe/Madrid",
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z",
      "metadata": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Get site

GET /sites/{site_id}
site_id
in path
string (site_id)

site ID

An instance of site
Response Example (200 OK)
{
  "id": "site_3merk33gt21kym11een1",
  "name": "string",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "geo": {
    "location": {
      "lat": 41.290485,
      "lng": 2.1829076
    },
    "radius": 100
  },
  "map": {
    "location": {
      "lat": 41.290485,
      "lng": 2.1829076
    },
    "place_id": "string",
    "address": "string",
    "image_url": "string"
  },
  "phone": "string",
  "email": "string",
  "info": "string",
  "timezone": "Europe/Madrid",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit site

PATCH /sites/{site_id}
site_id
in path
string (site_id)

site ID

metadata
metadata

Key-value metadata

Request Example
{
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of site
Response Example (200 OK)
{
  "id": "site_3merk33gt21kym11een1",
  "name": "string",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "geo": {
    "location": {
      "lat": 41.290485,
      "lng": 2.1829076
    },
    "radius": 100
  },
  "map": {
    "location": {
      "lat": 41.290485,
      "lng": 2.1829076
    },
    "place_id": "string",
    "address": "string",
    "image_url": "string"
  },
  "phone": "string",
  "email": "string",
  "info": "string",
  "timezone": "Europe/Madrid",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Gadgets

A gadget is a "thing that can be controlled" by a physical device. Gadgets can be doors, lights, heating, window blinds...

Gadgets are not "physical devices": some devices can have multiple gadgets (gateway_controllers and controllers). Others can have only one (smart locks, for example).

Gadgets can have multiple actions depending on what they are. For example, a normal door will just have an open action, but a blind can have raise and lower actions, and a light can have on and off actions. Actions are identified by their string ID, and they also have a human-friendly name for display in the UI.

gadget_action

id
string

action ID

name
string

Action user-friendly name

Example
{
  "id": "open",
  "name": "Open"
}

gadget

id
string (gadget_id)

gadget ID

organization_id
string (organization_id)

organization ID

site_id
string (site_id)

site ID

name
string

Gadget name

actions
gadget_action
is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "gad_3merk33gt1hnl6pvbu71",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "site_id": "site_3merk33gt21kym11een1",
  "name": "string",
  "actions": [
    {
      "id": "open",
      "name": "Open"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

List gadgets

GET /gadgets
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

data
gadget
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "gad_3merk33gt1hnl6pvbu71",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "site_id": "site_3merk33gt21kym11een1",
      "name": "string",
      "actions": [
        {
          "id": "open",
          "name": "Open"
        }
      ],
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z",
      "metadata": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Get gadget

GET /gadgets/{gadget_id}
gadget_id
in path
string (gadget_id)

gadget ID

An instance of gadget
Response Example (200 OK)
{
  "id": "gad_3merk33gt1hnl6pvbu71",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "site_id": "site_3merk33gt21kym11een1",
  "name": "string",
  "actions": [
    {
      "id": "open",
      "name": "Open"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit gadget

PATCH /gadgets/{gadget_id}
gadget_id
in path
string (gadget_id)

gadget ID

metadata
metadata

Key-value metadata

Request Example
{
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of gadget
Response Example (200 OK)
{
  "id": "gad_3merk33gt1hnl6pvbu71",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "site_id": "site_3merk33gt21kym11een1",
  "name": "string",
  "actions": [
    {
      "id": "open",
      "name": "Open"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Do gadget action

POST /gadgets/{gadget_id}/actions/{action_id}

This endpoint is only available to Akiles customers that have the whitelabel integration feature which has extra cost. If you want to make your integration public we recommend using the non whitelabel option.

gadget_id
in path
string (gadget_id)

gadget ID

action_id
in path
string

gadget action ID

Request Example
{}
Response Example (200 OK)
{}

Members

member

id
string (member_id)

member ID

organization_id
string (organization_id)

organization ID

name
string

Member name shown in the admin panel. This is for the organization admins to identify the member, it's never shown to the user.

starts_at
string (date-time)

Start date of the member's access. If null, the access is valid immediately.

ends_at
string (date-time)

End date of the member's access. If null, the access is valid forever (ie, until an end date is set or the member is deleted.)

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "mem_3merk33gt7ml3tde71f3",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "John Doe",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

member_email

id
string (member_email_id)

member email ID

organization_id
string (organization_id)

organization ID

member_id
string (member_id)

member ID

email
string (email_address)

Email address

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "me_3rkd7ya2pnjysjqbluj1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "email": "hello@example.com",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

member_pin

id
string (member_pin_id)

member pin ID

organization_id
string (organization_id)

organization ID

member_id
string (member_id)

member ID

length
integer

Pin length

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "mp_3rkd2fmgmmdh1dgkvluh",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "length": 6,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

member_pin_revealed

pin
string

Pin number.

id
string (member_pin_id)

member pin ID

organization_id
string (organization_id)

organization ID

member_id
string (member_id)

member ID

length
integer

Pin length

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "pin": "123456",
  "id": "mp_3rkd2fmgmmdh1dgkvluh",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "length": 6,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

member_group_association

id
string (member_group_association_id)

member group association ID

organization_id
string (organization_id)

organization ID

member_id
string (member_id)

member ID

member_group_id
string (member_group_id)

member_group ID

starts_at
string (date-time)

Start date of the member's access. If null, the access is valid immediately.

ends_at
string (date-time)

End date of the member's access. If null, the access is valid forever (ie, until an end date is set or the member is deleted.)

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "mga_3rkd81x2hc3qluv56pl1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "member_group_id": "mg_3merk33gt1692dk2p2m1",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

List members

GET /members
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

is_deleted
in query
string true, false, any

Filter by deletion status

email
in query
string

Filter by email address

metadata.source
in query
string

Filter by metadata.source

metadata.sourceID
in query
string

Filter by metadata.sourceID

data
member
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "mem_3merk33gt7ml3tde71f3",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "name": "John Doe",
      "starts_at": "2018-03-13T16:56:51.766836837Z",
      "ends_at": "2018-03-13T16:56:51.766836837Z",
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z",
      "metadata": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Create member

POST /members
name
string

Member name shown in the admin panel. This is for the organization admins to identify the member, it's never shown to the user.

starts_at
string (date-time)

Start date of the member's access. If null, the access is valid immediately.

ends_at
string (date-time)

End date of the member's access. If null, the access is valid forever (ie, until an end date is set or the member is deleted.)

metadata
metadata

Key-value metadata

Request Example
{
  "name": "John Doe",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member
Response Example (200 OK)
{
  "id": "mem_3merk33gt7ml3tde71f3",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "John Doe",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Get member

GET /members/{member_id}
member_id
in path
string (member_id)

member ID

An instance of member
Response Example (200 OK)
{
  "id": "mem_3merk33gt7ml3tde71f3",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "John Doe",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit member

PATCH /members/{member_id}
member_id
in path
string (member_id)

member ID

name
string

Member name shown in the admin panel. This is for the organization admins to identify the member, it's never shown to the user.

starts_at
string (date-time)

Start date of the member's access. If null, the access is valid immediately.

ends_at
string (date-time)

End date of the member's access. If null, the access is valid forever (ie, until an end date is set or the member is deleted.)

is_deleted
boolean

True if this object has been deleted.

metadata
metadata

Key-value metadata

Request Example
{
  "name": "John Doe",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member
Response Example (200 OK)
{
  "id": "mem_3merk33gt7ml3tde71f3",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "John Doe",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Delete member

DELETE /members/{member_id}
member_id
in path
string (member_id)

member ID

An instance of member
Response Example (200 OK)
{
  "id": "mem_3merk33gt7ml3tde71f3",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "John Doe",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

List emails

GET /members/{member_id}/emails
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

q
in query
string

Search parameter

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

member_id
in path
string (member_id)

member ID

data
member_email
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "me_3rkd7ya2pnjysjqbluj1",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "member_id": "mem_3merk33gt7ml3tde71f3",
      "email": "hello@example.com",
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z",
      "metadata": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Create email

POST /members/{member_id}/emails
member_id
in path
string (member_id)

member ID

email
string (email)

Email address

metadata
metadata

Key-value metadata

Request Example
{
  "email": "string (email)",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_email
Response Example (200 OK)
{
  "id": "me_3rkd7ya2pnjysjqbluj1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "email": "hello@example.com",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Get email

GET /members/{member_id}/emails/{member_email_id}
member_id
in path
string (member_id)

member ID

member_email_id
in path
string (member_email_id)

member email ID

An instance of member_email
Response Example (200 OK)
{
  "id": "me_3rkd7ya2pnjysjqbluj1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "email": "hello@example.com",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit email

PATCH /members/{member_id}/emails/{member_email_id}
member_id
in path
string (member_id)

member ID

member_email_id
in path
string (member_email_id)

member email ID

metadata
metadata

Key-value metadata

Request Example
{
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_email
Response Example (200 OK)
{
  "id": "me_3rkd7ya2pnjysjqbluj1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "email": "hello@example.com",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Delete email

DELETE /members/{member_id}/emails/{member_email_id}
member_id
in path
string (member_id)

member ID

member_email_id
in path
string (member_email_id)

member email ID

An instance of member_email
Response Example (200 OK)
{
  "id": "me_3rkd7ya2pnjysjqbluj1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "email": "hello@example.com",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

List pins

GET /members/{member_id}/pins
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

member_id
in path
string (member_id)

member ID

data
member_pin
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "mp_3rkd2fmgmmdh1dgkvluh",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "member_id": "mem_3merk33gt7ml3tde71f3",
      "length": 6,
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z",
      "metadata": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Create pin

POST /members/{member_id}/pins
member_id
in path
string (member_id)

member ID

length
integer

Pin length

pin
string

Pin number

metadata
metadata

Key-value metadata

Request Example
{
  "length": "integer",
  "pin": "string",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_pin_revealed
Response Example (200 OK)
{
  "pin": "123456",
  "id": "mp_3rkd2fmgmmdh1dgkvluh",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "length": 6,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Get pin

GET /members/{member_id}/pins/{member_pin_id}
member_id
in path
string (member_id)

member ID

member_pin_id
in path
string (member_pin_id)

member pin ID

An instance of member_pin
Response Example (200 OK)
{
  "id": "mp_3rkd2fmgmmdh1dgkvluh",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "length": 6,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit pin

PATCH /members/{member_id}/pins/{member_pin_id}
member_id
in path
string (member_id)

member ID

member_pin_id
in path
string (member_pin_id)

member pin ID

metadata
metadata

Key-value metadata

Request Example
{
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_pin
Response Example (200 OK)
{
  "id": "mp_3rkd2fmgmmdh1dgkvluh",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "length": 6,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Delete pin

DELETE /members/{member_id}/pins/{member_pin_id}
member_id
in path
string (member_id)

member ID

member_pin_id
in path
string (member_pin_id)

member pin ID

An instance of member_pin
Response Example (200 OK)
{
  "id": "mp_3rkd2fmgmmdh1dgkvluh",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "length": 6,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Reveal pin

POST /members/{member_id}/pins/{member_pin_id}/reveal
member_id
in path
string (member_id)

member ID

member_pin_id
in path
string (member_pin_id)

member pin ID

Request Example
{}
An instance of member_pin_revealed
Response Example (200 OK)
{
  "pin": "123456",
  "id": "mp_3rkd2fmgmmdh1dgkvluh",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "length": 6,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

List group associations

GET /members/{member_id}/group_associations
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

member_id
in path
string (member_id)

member ID

data
member_group_association
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "mga_3rkd81x2hc3qluv56pl1",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "member_id": "mem_3merk33gt7ml3tde71f3",
      "member_group_id": "mg_3merk33gt1692dk2p2m1",
      "starts_at": "2018-03-13T16:56:51.766836837Z",
      "ends_at": "2018-03-13T16:56:51.766836837Z",
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z",
      "metadata": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Create group association

POST /members/{member_id}/group_associations
member_id
in path
string (member_id)

member ID

member_group_id
string (member_group_id)

member_group ID

starts_at
string (date-time)

Start date of the member's access. If null, the access is valid immediately.

ends_at
string (date-time)

End date of the member's access. If null, the access is valid forever (ie, until an end date is set or the member is deleted.)

metadata
metadata

Key-value metadata

Request Example
{
  "member_group_id": "mg_3merk33gt1692dk2p2m1",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_group_association
Response Example (200 OK)
{
  "id": "mga_3rkd81x2hc3qluv56pl1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "member_group_id": "mg_3merk33gt1692dk2p2m1",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Get group association

GET /members/{member_id}/group_associations/{member_group_association_id}
member_id
in path
string (member_id)

member ID

member_group_association_id
in path
string (member_group_association_id)

member group association ID

An instance of member_group_association
Response Example (200 OK)
{
  "id": "mga_3rkd81x2hc3qluv56pl1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "member_group_id": "mg_3merk33gt1692dk2p2m1",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit group association

PATCH /members/{member_id}/group_associations/{member_group_association_id}
member_id
in path
string (member_id)

member ID

member_group_association_id
in path
string (member_group_association_id)

member group association ID

starts_at
string (date-time)

Start date of the member's access. If null, the access is valid immediately.

ends_at
string (date-time)

End date of the member's access. If null, the access is valid forever (ie, until an end date is set or the member is deleted.)

metadata
metadata

Key-value metadata

Request Example
{
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_group_association
Response Example (200 OK)
{
  "id": "mga_3rkd81x2hc3qluv56pl1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "member_group_id": "mg_3merk33gt1692dk2p2m1",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Delete group association

DELETE /members/{member_id}/group_associations/{member_group_association_id}
member_id
in path
string (member_id)

member ID

member_group_association_id
in path
string (member_group_association_id)

member group association ID

An instance of member_group_association
Response Example (200 OK)
{
  "id": "mga_3rkd81x2hc3qluv56pl1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "member_id": "mem_3merk33gt7ml3tde71f3",
  "member_group_id": "mg_3merk33gt1692dk2p2m1",
  "starts_at": "2018-03-13T16:56:51.766836837Z",
  "ends_at": "2018-03-13T16:56:51.766836837Z",
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Member groups

member_group

id
string (member_group_id)

member_group ID

organization_id
string (organization_id)

organization ID

name
string

Group name

permissions
member_group_permission_rule

Permission rules granted to members of this group. A member can have multiple groups, and the permissions are the union of all the groups. Access is granted if at least one rule matches.

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

metadata
metadata

Key-value metadata

Example
{
  "id": "mg_3merk33gt1692dk2p2m1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "string",
  "permissions": [
    {
      "site_id": "site_3merk33gt21kym11een1",
      "gadget_id": "gad_3merk33gt1hnl6pvbu71",
      "action_id": "string",
      "schedule_id": "sch_3merk33gt21kyz1f3z1",
      "presence": "string"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

member_group_permission_rule

Rule granting permissions to a member group. Examples:

  • {} matches all gadgets in all sites
  • {"site_id": "site_3merk33gt21kym11een1"} matches all gadgets in that site.
  • {"gadget_id": "gad_3merk33gt1hnl6pvbu71"} matches that gadget only.

It is not allowed to set site_id and gadget_id at the same time.

site_id
string (site_id)

Site ID. If set, the rule only matches gadgets in this site.

gadget_id
string (gadget_id)

Gadget ID. If set, the rule only matches this gadget.

action_id
string

Action ID. If set, the rule only matches this particular action within the gadget.

Only one action can be chosen. If you want to allow multiple actions in the same gadget, create one permission rule for each action.

If you set this, gadget_id must be set. That is, it's not possible to have a permission rule like "All gadgets in site X, but only action Y".

schedule_id
string (schedule_id)

Schedule ID. If set, the rule only matches if the current time is within the schedule.

presence
string none, gps

Presence check performed.

  • none: no presence check is done, the user can perform gadget actions using the Akiles app remotely, from anywhere in the world.
  • gps: the user must be within the site's GPS radius to perform gadget actions.

Actions via PINs, cards and Bluetooth are always allowed and not affected by this setting.

Example
{
  "site_id": "site_3merk33gt21kym11een1",
  "gadget_id": "gad_3merk33gt1hnl6pvbu71",
  "action_id": "string",
  "schedule_id": "sch_3merk33gt21kyz1f3z1",
  "presence": "string"
}

List member groups

GET /member_groups
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

q
in query
string

Search parameter

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

data
member_group
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "mg_3merk33gt1692dk2p2m1",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "name": "string",
      "permissions": [
        {
          "site_id": "site_3merk33gt21kym11een1",
          "gadget_id": "gad_3merk33gt1hnl6pvbu71",
          "action_id": "string",
          "schedule_id": "sch_3merk33gt21kyz1f3z1",
          "presence": "string"
        }
      ],
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z",
      "metadata": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Create member group

POST /member_groups
name
string

Group name

permissions
member_group_permission_rule

Permission rules granted to members of this group. A member can have multiple groups, and the permissions are the union of all the groups. Access is granted if at least one rule matches.

metadata
metadata

Key-value metadata

Request Example
{
  "name": "string",
  "permissions": [
    {
      "site_id": "site_3merk33gt21kym11een1",
      "gadget_id": "gad_3merk33gt1hnl6pvbu71",
      "action_id": "string",
      "schedule_id": "sch_3merk33gt21kyz1f3z1",
      "presence": "string"
    }
  ],
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_group
Response Example (200 OK)
{
  "id": "mg_3merk33gt1692dk2p2m1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "string",
  "permissions": [
    {
      "site_id": "site_3merk33gt21kym11een1",
      "gadget_id": "gad_3merk33gt1hnl6pvbu71",
      "action_id": "string",
      "schedule_id": "sch_3merk33gt21kyz1f3z1",
      "presence": "string"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Get member group

GET /member_groups/{member_group_id}
member_group_id
in path
string (member_group_id)

member_group ID

An instance of member_group
Response Example (200 OK)
{
  "id": "mg_3merk33gt1692dk2p2m1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "string",
  "permissions": [
    {
      "site_id": "site_3merk33gt21kym11een1",
      "gadget_id": "gad_3merk33gt1hnl6pvbu71",
      "action_id": "string",
      "schedule_id": "sch_3merk33gt21kyz1f3z1",
      "presence": "string"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Edit member group

PATCH /member_groups/{member_group_id}
member_group_id
in path
string (member_group_id)

member_group ID

name
string

Group name

permissions
member_group_permission_rule

Permission rules granted to members of this group. A member can have multiple groups, and the permissions are the union of all the groups. Access is granted if at least one rule matches.

metadata
metadata

Key-value metadata

Request Example
{
  "name": "string",
  "permissions": [
    {
      "site_id": "site_3merk33gt21kym11een1",
      "gadget_id": "gad_3merk33gt1hnl6pvbu71",
      "action_id": "string",
      "schedule_id": "sch_3merk33gt21kyz1f3z1",
      "presence": "string"
    }
  ],
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}
An instance of member_group
Response Example (200 OK)
{
  "id": "mg_3merk33gt1692dk2p2m1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "string",
  "permissions": [
    {
      "site_id": "site_3merk33gt21kym11een1",
      "gadget_id": "gad_3merk33gt1hnl6pvbu71",
      "action_id": "string",
      "schedule_id": "sch_3merk33gt21kyz1f3z1",
      "presence": "string"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Delete member group

DELETE /member_groups/{member_group_id}
member_group_id
in path
string (member_group_id)

member_group ID

An instance of member_group
Response Example (200 OK)
{
  "id": "mg_3merk33gt1692dk2p2m1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "name": "string",
  "permissions": [
    {
      "site_id": "site_3merk33gt21kym11een1",
      "gadget_id": "gad_3merk33gt1hnl6pvbu71",
      "action_id": "string",
      "schedule_id": "sch_3merk33gt21kyz1f3z1",
      "presence": "string"
    }
  ],
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z",
  "metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Events

event

id
string (event_id)

event ID

organization_id
string (organization_id)

organization ID

subject
object
verb
string create, edit, delete, use
object
object
created_at
string (date-time)

Creation time for this object.

Example
{
  "id": "evt_3merk33gt21kym11een1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "subject": {
    "type": "member",
    "member_id": "mem_3merk33gt7ml3tde71f3",
    "user_id": "usr_3merk33gt13y99aqtze1",
    "user_session_id": "sess_3merk33gt13y99aqtze1",
    "api_key_id": "ak_3merk33gt21kym11een1",
    "admin_id": "adm_3merk33gt7ml3ltq5bg1",
    "user_agent": "string (user_agent)",
    "ip_address": "100.64.0.32"
  },
  "verb": "use",
  "object": {
    "type": "gadget_action",
    "admin_id": "adm_3merk33gt7ml3ltq5bg1",
    "api_key_id": "ak_3merk33gt21kym11een1",
    "device_id": "dev_3merk33gt3l525ryhcmh",
    "gadget_id": "gad_3merk33gt1hnl6pvbu71",
    "link_id": "lnk_3merk33gt345nu3dnkmh",
    "member_id": "mem_3merk33gt7ml3tde71f3",
    "member_group_id": "mg_3merk33gt1692dk2p2m1",
    "member_invitation_id": "mi_3merk33gt7fsymkn47q1",
    "site_id": "site_3merk33gt21kym11een1",
    "gadget_action_id": "open"
  },
  "created_at": "2018-03-13T16:56:51.766836837Z"
}

List events

GET /events
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

data
event
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "evt_3merk33gt21kym11een1",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "subject": {
        "type": "member",
        "member_id": "mem_3merk33gt7ml3tde71f3",
        "user_id": "usr_3merk33gt13y99aqtze1",
        "user_session_id": "sess_3merk33gt13y99aqtze1",
        "api_key_id": "ak_3merk33gt21kym11een1",
        "admin_id": "adm_3merk33gt7ml3ltq5bg1",
        "user_agent": "string (user_agent)",
        "ip_address": "100.64.0.32"
      },
      "verb": "use",
      "object": {
        "type": "gadget_action",
        "admin_id": "adm_3merk33gt7ml3ltq5bg1",
        "api_key_id": "ak_3merk33gt21kym11een1",
        "device_id": "dev_3merk33gt3l525ryhcmh",
        "gadget_id": "gad_3merk33gt1hnl6pvbu71",
        "link_id": "lnk_3merk33gt345nu3dnkmh",
        "member_id": "mem_3merk33gt7ml3tde71f3",
        "member_group_id": "mg_3merk33gt1692dk2p2m1",
        "member_invitation_id": "mi_3merk33gt7fsymkn47q1",
        "site_id": "site_3merk33gt21kym11een1",
        "gadget_action_id": "open"
      },
      "created_at": "2018-03-13T16:56:51.766836837Z"
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Get event

GET /events/{event_id}
event_id
in path
string (event_id)

event ID

An instance of event
Response Example (200 OK)
{
  "id": "evt_3merk33gt21kym11een1",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "subject": {
    "type": "member",
    "member_id": "mem_3merk33gt7ml3tde71f3",
    "user_id": "usr_3merk33gt13y99aqtze1",
    "user_session_id": "sess_3merk33gt13y99aqtze1",
    "api_key_id": "ak_3merk33gt21kym11een1",
    "admin_id": "adm_3merk33gt7ml3ltq5bg1",
    "user_agent": "string (user_agent)",
    "ip_address": "100.64.0.32"
  },
  "verb": "use",
  "object": {
    "type": "gadget_action",
    "admin_id": "adm_3merk33gt7ml3ltq5bg1",
    "api_key_id": "ak_3merk33gt21kym11een1",
    "device_id": "dev_3merk33gt3l525ryhcmh",
    "gadget_id": "gad_3merk33gt1hnl6pvbu71",
    "link_id": "lnk_3merk33gt345nu3dnkmh",
    "member_id": "mem_3merk33gt7ml3tde71f3",
    "member_group_id": "mg_3merk33gt1692dk2p2m1",
    "member_invitation_id": "mi_3merk33gt7fsymkn47q1",
    "site_id": "site_3merk33gt21kym11een1",
    "gadget_action_id": "open"
  },
  "created_at": "2018-03-13T16:56:51.766836837Z"
}

Webhooks

webhook_filter_rule

object_type
string gadget, gadget_action, member, member_group, organization, site

Object type of the event.

verb
string create, edit, delete, use

Action verb of the event. If null, matches all verbs.

Example
{
  "object_type": "gadget_action",
  "verb": "use"
}

webhook

id
string (webhook_id)

webhook ID

organization_id
string (organization_id)

organization ID

filter
webhook_filter_rule

Array of event filter rules. An event will be sent to this webhook if it matches at least one rule. If it matches multiple rules, it will only be sent once. If it matches multiple webhook objects, it will be sent once per webhook to its respective URL.

url
string

URL the events are sent to.

secret
string

Secret used to sign webhooks. Visible only in the response for the creation API call.

is_enabled
boolean

True if this webhook is enabled. When false, no webhooks are sent.

is_deleted
boolean

True if this object has been deleted.

created_at
string (date-time)

Creation time for this object.

Example
{
  "id": "string (webhook_id)",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "filter": [
    {
      "object_type": "gadget_action",
      "verb": "use"
    }
  ],
  "url": "https://example.com/hook",
  "secret": "47f455202923a84cdf8d046e4e1a45b54d6355569e211b388abf389d322db2e4",
  "is_enabled": false,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z"
}

List webhooks

GET /webhooks
cursor
in query
string

Cursor value obtained from a previous request to the same endpoint. If not present, the first page of results is returned.

limit
in query
integer

Items per page.

sort
in query
string

Sort order. Field name, followed by :asc or :desc. Defaults to id:desc. In most models, IDs are assigned in increasing order in time, so sorting by id is equivalent to sorting by created_at. Depending on the model, sorting on some fields might not be supported.

data
webhook
has_next
boolean
cursor_next
string (cursor)
Response Example (200 OK)
{
  "data": [
    {
      "id": "string (webhook_id)",
      "organization_id": "org_3merk33gt1v9ypgfzrp1",
      "filter": [
        {
          "object_type": "gadget_action",
          "verb": "use"
        }
      ],
      "url": "https://example.com/hook",
      "secret": "47f455202923a84cdf8d046e4e1a45b54d6355569e211b388abf389d322db2e4",
      "is_enabled": false,
      "is_deleted": false,
      "created_at": "2018-03-13T16:56:51.766836837Z"
    }
  ],
  "has_next": true,
  "cursor_next": "i9vmCnOgONT2AjUMCn1K1N5cJg=="
}

Create webhook

POST /webhooks
filter
object[]

Array of event filter rules. An event will be sent to this webhook if it matches at least one rule. Null in verb matches all verbs.

url
string

URL the events are sent to.

is_enabled
boolean

True if this webhook is enabled. When false, no webhooks are sent.

Request Example
{
  "filter": [
    [
      {
        "object_type": "gadget_action"
      }
    ]
  ],
  "url": "https://example.com/hook",
  "is_enabled": false
}
An instance of webhook
Response Example (200 OK)
{
  "id": "string (webhook_id)",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "filter": [
    {
      "object_type": "gadget_action",
      "verb": "use"
    }
  ],
  "url": "https://example.com/hook",
  "secret": "47f455202923a84cdf8d046e4e1a45b54d6355569e211b388abf389d322db2e4",
  "is_enabled": false,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z"
}

Get webhook

GET /webhooks/{webhook_id}
webhook_id
in path
string (webhook_id)

webhook ID

An instance of webhook
Response Example (200 OK)
{
  "id": "string (webhook_id)",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "filter": [
    {
      "object_type": "gadget_action",
      "verb": "use"
    }
  ],
  "url": "https://example.com/hook",
  "secret": "47f455202923a84cdf8d046e4e1a45b54d6355569e211b388abf389d322db2e4",
  "is_enabled": false,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z"
}

Edit webhook

PATCH /webhooks/{webhook_id}
webhook_id
in path
string (webhook_id)

webhook ID

filter
object[]

Array of event filter rules. An event will be sent to this webhook if it matches at least one rule. Null in object_type or verb matches all.

url
string

URL the events are sent to.

is_enabled
boolean

True if this webhook is enabled. When false, no webhooks are sent.

Request Example
{
  "filter": [
    [
      {
        "object_type": "gadget_action"
      }
    ]
  ],
  "url": "https://example.com/hook",
  "is_enabled": false
}
An instance of webhook
Response Example (200 OK)
{
  "id": "string (webhook_id)",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "filter": [
    {
      "object_type": "gadget_action",
      "verb": "use"
    }
  ],
  "url": "https://example.com/hook",
  "secret": "47f455202923a84cdf8d046e4e1a45b54d6355569e211b388abf389d322db2e4",
  "is_enabled": false,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z"
}

Delete webhook

DELETE /webhooks/{webhook_id}
webhook_id
in path
string (webhook_id)

webhook ID

An instance of webhook
Response Example (200 OK)
{
  "id": "string (webhook_id)",
  "organization_id": "org_3merk33gt1v9ypgfzrp1",
  "filter": [
    {
      "object_type": "gadget_action",
      "verb": "use"
    }
  ],
  "url": "https://example.com/hook",
  "secret": "47f455202923a84cdf8d046e4e1a45b54d6355569e211b388abf389d322db2e4",
  "is_enabled": false,
  "is_deleted": false,
  "created_at": "2018-03-13T16:56:51.766836837Z"
}