← All documentationContents ↓

API Reference: Session Tokens

Create and manage short-lived, scoped session tokens (s360_sess_*) for browsers, AI agents, and partner access.

Overview

Session tokens are short-lived, scoped credentials that you mint from your server using an API key. They are designed for client-side use, AI agents, and temporary partner access — scenarios where exposing a long-lived API key would be a security risk. Every session token value starts with s360_sess_; its identifier (returned as id) starts with sess_.

Key Concepts

  • Short-lived — Maximum lifetime is 24 hours (1440 minutes); the default is 60 minutes. Tokens cannot be renewed; mint a new one when they expire.
  • Scoped — Each token carries a subset of the creator's feature permissions plus a set of API scopes. Scopes default to read-only: schema:read and records:read.
  • Inherited ceiling — A token can never exceed the permissions or scopes of the API key (or user) that created it. If you omit featurePermissions, the token inherits all of the creator's feature permissions — pass an explicit subset for least privilege.
  • Never admin — Session tokens never carry sysadmin or team-admin status, and full data access is only retained when the creator has it and DATA_FULL_ACCESS is included in the token's feature permissions.

Endpoints

MethodPathPurpose
POST/v1/session-tokensCreate a session token (value returned once).
GET/v1/session-tokens/{sessionTokenId}Get token metadata (never the token value).
DELETE/v1/session-tokens/{sessionTokenId}Revoke a token before its natural expiry.

Create a Session Token

Generate a scoped session token from your server using an API key, then send the token to your client. The request body accepts expiresInMinutes (1–1440, default 60), featurePermissions, oauthScopes, and free-form metadata.

TypeScript SDK

const session = await s360.sessionTokens.create({
  expiresInMinutes: 60,
  featurePermissions: ['DATA_RECORD_LOGS'], // subset of the caller's permissions
  oauthScopes: ['schema:read', 'records:read'],
});

// session.data.token is the s360_sess_... value to send to the client (returned once).
// session.data.id is the sess_... identifier for later inspection/revocation.
console.log(`Token: ${session.data.token}`);
console.log(`Expires at: ${session.data.expiresAt}`);

cURL

curl -s -X POST "https://api.simply360.app/v1/session-tokens" \
  -H "Authorization: Bearer $S360_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "expiresInMinutes": 60,
    "oauthScopes": ["schema:read", "records:read"]
  }'

Valid oauthScopes values are schema:read, records:read, records:write, websites:read, websites:write, conversations:read, conversations:write, files:write, wizards:run, and admin:read. Unknown scopes are rejected with 400 INVALID_OAUTH_SCOPES; requested scopes the creator does not hold are silently dropped. Request write scopes only for the capability the token needs: records:write for record mutation and files:write for the quarantined file-upload flow.

Using a Session Token

Use a session token in the same way as an API key — pass it in the Authorization: Bearer header.

// In a browser or other client environment
import { Simply360 } from '@simply360/sdk';

const s360 = new Simply360({
  apiKey: tokenFromServer, // s360_sess_...
});

// Operations are limited to the token's scope
const records = await s360.dataRecords.list({ dataCollectionSimplyId: 'XXXX-XXXX-XXXX' });
curl -s "https://api.simply360.app/v1/data-records?dataCollectionSimplyId=XXXX-XXXX-XXXX" \
  -H "Authorization: Bearer s360_sess_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Inspect a Session Token

Fetch metadata for a token you minted — useful for checking whether it has expired and which permissions it carries. The token value itself is never returned.

curl -s "https://api.simply360.app/v1/session-tokens/sess_1f2e3d4c5b6a7890" \
  -H "Authorization: Bearer $S360_API_KEY"
{
  "data": {
    "id": "sess_1f2e3d4c5b6a7890",
    "expiresAt": "2026-07-07T15:00:00.000Z",
    "expired": false,
    "featurePermissions": ["DATA_RECORD_LOGS"],
    "oauthScopes": ["schema:read", "records:read"],
    "metadata": null,
    "createdAt": "2026-07-07T14:00:00.000Z"
  }
}

Revoke a Session Token

Use revoke when you need to immediately invalidate a token before its natural expiry. Pass the sess_... identifier (not the token value).

await s360.sessionTokens.revoke('sess_1f2e3d4c5b6a7890');
curl -s -X DELETE "https://api.simply360.app/v1/session-tokens/sess_1f2e3d4c5b6a7890" \
  -H "Authorization: Bearer $S360_API_KEY"

Use Cases

  • Browser proxying — Issue a short-lived, read-only token to a single-page app so it can fetch data directly without exposing your API key.
  • AI agents — Give an LLM-driven workflow tightly scoped credentials it cannot exceed, even if its prompt is compromised.
  • Third-party access — Grant a partner temporary, scoped access without giving them a permanent API key.
  • Mobile apps — Pair a backend authentication step with on-device session tokens that expire automatically.

Usage Notes

  • Tokens cannot have broader feature permissions or scopes than the credential used to create them — requested extras are dropped.
  • Omitting featurePermissions inherits every feature permission the creator holds. Always pass an explicit subset for client-facing tokens.
  • Tokens default to schema:read and records:read. Include records:write explicitly for write-capable clients.
  • Expired or revoked tokens return 401 UNAUTHENTICATED. Your client should handle this by requesting a new token from your server.
  • Maximum lifetime is 1440 minutes (24 hours). Shorter durations are recommended for better security.
  • There is no list endpoint — store the id returned at creation if you need to inspect or revoke tokens later.