Skip to content
Indiana
Dashboard
Docs
Browse docs / Customers and sessions

Customers and sessions

Create and update Customers, issue Customer Tokens, and handle Guests and claims after login.

API v1Updated

Create or find a Customer

Use the verified user ID from your system as externalUserId. Calling again with the same ID returns the same Customer (created: false) and leaves its profile unchanged.

customer.tsTypeScript
import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); async function main() {  const { customer, created } = await indiana.getOrCreateCustomer({    externalUserId: "user-42",  });  console.log(customer.id, created);} main().catch((error) => {  console.error(error);  process.exitCode = 1;});

Update a Customer

Send only the fields to change. Generate and save a requestId per update; retrying with the same value never applies the change twice.

customer.tsTypeScript
import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); export async function syncProfile(input: {  verifiedUserId: string;  requestId: string; // persisted before the first attempt  plan: string;}) {  const { customer, changed } = await indiana.updateCustomer({    lookup: { type: "externalUserId", value: input.verifiedUserId },    requestId: input.requestId,    patch: {      attributes: { plan: input.plan },      tagChanges: { add: ["beta"], remove: [] },    },  });  return { customerId: customer.id, changed };}

Call Indiana from the browser

  • After your backend verifies the login, call createCustomerSession to issue a Customer Token.
  • The browser calls identify(token); later requests act as that Customer.
  • On sign-out or account switch, the browser calls reset() and your backend calls revokeCustomerSessions.
server/session.tsTypeScript
import { createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); // Call only after your own login check succeeds.export async function issueCustomerToken(verifiedUserId: string) {  const { customer } = await indiana.getOrCreateCustomer({    externalUserId: verifiedUserId,  });  const { customerToken, expiresAt } = await indiana.createCustomerSession(customer.id);  return { customerToken, expiresAt };}
  • Register your website origin under SDK integration → Allowed website origins in Console.
  • The issuing Key needs sessions:create plus the scopes the browser uses, such as entitlements:read.
  • Tokens renew while in use, up to 30 days; after expiry, sign the user in again.

Support signed-out users

Generate a guestToken for the visitor, keep it in an HttpOnly cookie and exchange it for a Customer Token. After login, call claimGuestCustomer to bind it to the account.

guest.tsTypeScript
import { createGuestToken, createIndianaServer } from "@tinkerlandai/indiana-sdk/server"; const indiana = createIndianaServer({  baseUrl: process.env.INDIANA_API_URL!,  apiKey: process.env.INDIANA_API_KEY!,  scope: { projectId: process.env.INDIANA_PROJECT_ID!, environment: "sandbox" },}); // 1. First visit: create the guest token once and keep it in an HttpOnly cookie.export async function startGuest(savedGuestToken?: string) {  const guestToken = savedGuestToken ?? createGuestToken();  await indiana.createGuestCustomer({ guestToken });  const session = await indiana.resumeGuestSession({ guestToken });  return { guestToken, customerToken: session.customerToken };} // 2. After your own login succeeds: bind the guest to the verified account.export async function claimGuest(input: {  guestToken: string;  verifiedUserId: string;  requestId: string;}) {  const { customer, switched } = await indiana.claimGuestCustomer({    guestToken: input.guestToken,    externalUserId: input.verifiedUserId,    requestId: input.requestId,  });  const { customerToken } = await indiana.createCustomerSession(customer.id);  return { customerToken, switched };}

Related operations

Customers, Guests and Sessions (10)
createCustomer, getCustomer, listCustomers, updateCustomer, createSession, renewSession, revokeSessions, createGuestCustomer, resumeGuestSession, claimGuestCustomer

Related: Paths, credentials and scopes in All operations