Signing in a user ties them to their feedback items. Gleap stores a unique user ID and optional meta information such as their email and name on the contact.
Sign in your users
Sign your users in with an identity token: a short JWT that your backend signs for the logged-in user. Gleap checks the token once and answers with a session grant that the SDK sends with every later request. Everything in the token is signed: the user ID, the email, the name, the company and any attribute you add, such as stripeCustomerId.
Create an identity key in Settings → Security → Customer identity → Identity keys. Keep its secret on your server.
After login, your backend signs a token for the user with that key.
Your app passes the token to
setUserJwtafter login and on every app start.Once a token from your backend checks out, click Turn on next to Turn on signed sessions in Settings → Security → Customer identity, then confirm with Turn on. Creating a key alone doesn't protect any fields or change how Gleap treats your users.
Sign the token on your backend, for example in Node.js:
// npm install jsonwebtoken
const jwt = require("jsonwebtoken");
const token = jwt.sign(
{
userId: String(user.id),
email: user.email,
name: user.name,
company: { id: user.companyId, name: user.companyName },
},
process.env.GLEAP_IDENTITY_SECRET,
{ algorithm: "HS256", keyid: process.env.GLEAP_IDENTITY_KEY_ID, expiresIn: "30m" }
);Sign the token on your backend lists every claim and shows PHP, Python, Ruby, C# and Go. Return the token to your app, for example in the login response or from an endpoint such as /api/gleap-token.
Then sign the user in from your app:
import { Gleap } from "capacitor-gleap-plugin";
await Gleap.setUserJwt({ token });
// Optional: fetch a fresh token for renewal
Gleap.setUserJwtProvider(async () => {
const response = await fetch("https://api.example.com/gleap-token", {
headers: { Authorization: `Bearer ${accessToken}` },
});
const { token } = await response.json();
return token;
});setUserJwt takes an options object: { token }, not the bare token. The token names the user and carries the contact data, so you don't need a separate identify call. setUserJwt and setUserJwtProvider need 19.4.0 or newer. setUserJwtProvider is optional: the SDK calls it for a fresh token when the session grant is about to run out or a token was refused as expired. From 19.5.0 the provider also restores the signed session after an app restart when no grant is held. We still recommend calling setUserJwt on every app start.
Calling setUserJwt again with a token for the same user and data sends nothing new: the SDK keeps the session grant and only signs in again when the claims change or the grant has run out. The session grant lasts as long as Signed login lasts (7 days by default); the token's exp (for example 30 minutes) only gates the sign-in.
When the grant runs out and no fresh token arrives, the user stays identified but unsigned in your iOS and Android app until the next setUserJwt or provider token, and sees their last 14 days of conversations. In a web build (JavaScript SDK 19.7.0 or newer), the signed session ends instead and the user continues as a visitor until setUserJwt signs them in again. Set setUserJwtProvider so the SDK renews the grant in time.
Call Gleap.clearIdentity() on logout and before you sign in another user. await Gleap.setSessionDuration({ milliseconds: ms }) shortens the signed session; the project's maximum applies.
Moving from an older integration? See Upgrade to identity tokens.
Identify without a token
Gleap.identify() without a token still works, but the contact is unsigned: anyone could claim that user ID. The widget then shows only conversations from the last 14 days, protected fields keep their values, and Gleap refuses the call on platforms (web, iOS, Android) where you turned on Require a signature.
Gleap.identify({
userId: "19283",
name: "Franz",
email: "[email protected]",
phone: "+1 (902) 123123",
value: 199.95,
avatar: "https://.../avatar.png",
customData: {
plan: "Pro plan",
company: "ACME inc.",
},
});Protected conversation files
With Protect new files in Settings → Security → Conversation files (Authenticated conversation files), conversation files can only be opened by agents and by the signed-in customer the conversation belongs to. The SDK (19.4.0 or newer) supports it without extra setup, as long as your app signs the customer in with setUserJwt (see above) on every app start.
A signed-in session gets a short-lived file access token (15 minutes). The SDK keeps it in memory only, hands it to the widget and renews it automatically while the app is in use. clearIdentity revokes it. Guests and unsigned contacts see "Sign in to view" instead of the file.
Open emailed file links
Email replies link attachments to the first of your App URLs without a *, with a gleapFile query parameter. If that URL opens your app (for example as a universal link or App Link), pass the URL that opened the app to Gleap. Once the customer is signed in with setUserJwt, the SDK opens the file's conversation if the customer may see it. The link alone grants no access.
For example with the @capacitor/app plugin:
import { App } from "@capacitor/app";
import { Gleap } from "capacitor-gleap-plugin";
// Link that launched the app.
const launchUrl = await App.getLaunchUrl();
if (launchUrl?.url) {
await Gleap.openProtectedFileFromUrl({ url: launchUrl.url });
}
// Links received while the app is running.
App.addListener("appUrlOpen", ({ url }) => {
Gleap.openProtectedFileFromUrl({ url });
});openProtectedFileFromUrl resolves to { opened: boolean }: opened is true if the link carries a Gleap file reference, false otherwise, so you can hand other links to your own routing. On web it always resolves to { opened: false }; the JavaScript SDK handles ?gleapFile= on page load. Keep the parameter through your app's login flow.
Update contact properties
Use Gleap.updateContact() when contact details change during use, for example when a user subscribes to a new plan or changes their data. It updates the contact in real time. It can't change protected fields: put values you rely on into the token.
Gleap.updateContact({
value: 199.95,
plan: "Pro plan",
});The updateContact method takes in the same contact parameters as the identify method. Partial updates are possible.
Gleap.updateContact({
name: "Franz",
email: "[email protected]",
phone: "+1 (902) 123123",
value: 199.95,
plan: "Pro plan",
avatar: "https://.../avatar.png",
companyId: "12398958484",
companyName: "ACME inc.",
customData: {
key1: "awesome",
key2: true,
},
});Clear the identity on logout
We recommend to clear the identity once the user logs out. Clearing the identity will automatically detach the current session and create a new guest session. It also drops the session grant on this device.
Gleap.clearIdentity();Get the identification status of a user
With the following method, you can get the status of the current user identity.
Gleap.isUserIdentified();Get the current user identity
With the following method, you can get the current user identity.
Gleap.getIdentity();
