Layer Overview

Layer is a platform for integrating rich, engaging messaging experiences directly into your products and applications. We provide developers with APIs, SDKs, and UI toolkits that enable the rapid development of user experiences on par with leading consumer messengers such as iMessage and Facebook Messenger. The platform is delivered as a service with fully managed infrastructure.

Layer provides you with:

  • Direct Messaging and Group Conversations with up to 25 participants
  • Multi-part Messages combining text, rich media content (up to 2GB per part), and application data
  • Granular delivery and read receipts for each Conversation participant
  • Typing Indicators
  • Integrated support for mobile push notifications via APNS and FCM
  • User and Bot Identity profile management
  • A flexible querying interface for searching and retrieving data
  • Blocking and suspension of users
  • Robust connection management and offline support
  • Rich server-side integrations via the Server API and Webhooks
  • An elegant, high-level client programming environment
  • Rapid development of consumer class user experiences via the UI toolkits on mobile and web

Technical Concepts Overview

Layer provides hosted infrastructure and services that allow developers to easily integrate messaging into native and web apps. Layer is designed for asynchronous, person-to-person messaging, along with APIs for bot integrations. Layer is fully managed and HIPAA-compliant, and powers a wide range of products across both person-to-person and business-to-consumer use cases.

There are four core concepts you should understand:

1. Production vs staging apps

When you first sign up for Layer, you’ll have a staging app, and a staging app ID, which looks like this: layer:///apps/staging/749d6ae6-22b5-11e6-9940-40bc000045d0. Paid accounts get access to a production app and a corresponding production app ID.

Common mistake

The staging or production portion of the app ID is for developer convenience and is ignored by our SDKs. Typically the UUID portion of staging and production IDs only differ in a few characters and may look the same at first glance. Using the wrong ID is a common source of missing content, authentication issues, and incorrect push notification behavior.

Staging apps are meant to be used while you are building your project, but should not be used in production apps with real users. Staging apps provide access to all Layer features, but come with a few technical limitations:

  • They are not covered by our platform SLA. We make no guarantees about uptime or data integrity for service apps.
  • We may disable staging apps from accessing Layer servers if we observe excessive usage or usage patterns that match those of a production app.
  • We may introduce limits on the number of users or message volume for staging apps in the future.

Production apps are covered by our platform SLA and do not have any usage limitations.


Conversations and messages created on staging apps cannot be accessed from production apps. The opposite is also true.

2. User management & Identity provider

Layer does not handle user management. This means that you do not have to import or migrate existing users, and users don’t have to register with Layer itself. It also means that we cannot provide lists of users or limit actions to certain users (also known as “user permissions”).

Instead, this functionality should be handled by the rest of your app and server. In particular, you should have a server that contains a database of all your users and provides a way for app users to login, often via a password or session token. Most apps already have a database and server for user management.

Sample Identity Provider implementations are available on GitHub which generate an Identity Token, which gets passed to Layer to authenticate the user and optionally provide profile information. Every Layer app must have an identity provider to handle authentication.

User IDs

During the authentication process, you provide Layer with a unique ID for each user. Often, this is the primary ID for the same user in your database. We only require that they be unique for every user in your app, and stable, meaning that they can never change.


Email addresses are a bad choice for user IDs because users may change their email address. It also unnecessarily exposes private information.

You use your user ID for every Layer operation — adding or removing users from conversations, configuring push notifications, etc.


We create an Identity object for every user ID registered with Layer. At a minimum, each Identity object has a user_id field. During the authentication process, you can optionally provide additional profile details, such as name, email, and a URL for a profile picture (“avatar”). This makes it easy for apps to display a name and photo for message senders.

However, an Identity is not the same thing as a user:

  • Identities don’t have to correspond to actual users. For example, you could create a “Admin” identity that is associated with messages broadcasted from your backend.
  • Identities do not include any built-in concepts of roles or permissions (although you could implement this via identity metadata).

Identities also contain status information about a user, such as whether that user is online and available.

3. Conversations, Channels, messages, and message parts

Layer Conversations and Channels contain a set of participants and an unlimited number of messages.

Each message is sent by a specific user, and can contain an unlimited number of message parts, and typically indicates if the current user has read the Message.

Message parts hold the actual contents of a message. They are comprised of a MIME type and body; the body can be up to 2 KB in size. Larger payloads should be first uploaded to an external hosting service, such as AWS S3 or Google Cloud Storage; the URL of the uploaded file is sent instead. Our SDKs automatically handle this; if you are using the REST APIs, you will have to handle this yourself.

The MIME type tells your app how to display the contents of the message part. For example, if the message part contains a URL, a MIME type of text/plain might cause your app to display the URL as text, as if one user had sent a link to another. However, if the MIME type is image/jpeg, your app might display the image specified by the URL rather than the URL itself.


Message parts cannot be edited once they’ve been sent. However, a common pattern is to send a URL in a message part, and load the latest data available at the URL before displaying the rest of the message in your app.

Conversations and Channels differ in two ways:

  1. Conversations can have at most 25 participants, whereas Channels can have up to 250 participants
  2. Conversation Messages track who has received and who has read each message, while Channel Messages do not track any received or read state.


Channels are only supported by applications built using the Layer Web SDK or Client APIs, and are not currently available on Mobile SDKs.

4. Sync & querying

The WebSDK is a wrapper around the RESTful Client API. The iOS and Android SDKs are different.

The mobile SDKs synchronize all the conversations the authenticated user is a participant in, along with Identity information for each conversation participant and a configurable number of messages in each conversation. This data is downloaded to a SQLite database on disk, and happens in the background.


Because sync happens in the background, new data may not be immediately available. The SDKs provide methods that notify you when a particular conversation or message has finished syncing to the device.

Syncing all data to a local SQLite database allows users to access all their conversations and messages, even while offline. In addition, if messages are sent while offline, we will save them in the local database, and send them to our server the next time the device establishes a network connection.

Querying is the primary way to get Layer data on mobile. For example, you can display all conversations by issuing a query for all conversations. To display the messages in a conversation, use a query for messages that are part of that conversation.


Queries are a wrapper around SQL and operate over the local database. They will not return data that has not yet had time to sync. Queries do not load any data from the server, and will never return results that the authenticated user doesn’t have access to (such as conversations the authenticated user is not a part of).

Install SDK