Skip to content
shuffl

Searches the public product guides only. Nothing from a workspace is read, and questions are not saved.

← All guides

Use the SDK and HTTP API

Install the TypeScript client from npm, select exact permissions and verify reads before writes.

Developers and agent builders

Read as MarkdownAll guides as textAgent documentation index

App links open your signed-in workspace. Check the selected workspace before making changes.

Install the SDK

@shuffl/sdk is an ES module package for Node.js 22 or later and Bun. It installs @shuffl/api-contracts, which types every method’s input and output so your editor and the TypeScript compiler check your calls. The SDK, CLI and contracts share one version.

Call it from your server, script or agent runtime. Browsers can only call from the same origin as your Shuffl deployment, since cross-origin CORS isn’t enabled. To skip the package, use the HTTP API directly.

npm install @shuffl/sdk
# or: bun add @shuffl/sdk, pnpm add @shuffl/sdk

Choose the workspace and permissions

  1. Sign in and select the workspace. Open Settings → API keys → New API key, name the key and choose only the endpoints this integration needs.
  2. For the example below, select knowledge.search. Workspace identity and permission discovery are always readable; everything else needs an explicit grant.
  3. Acknowledge external access, create the token and save the one-time secret in a credential manager. Pass SHUFFL_TOKEN and SHUFFL_BASE_URL in through your environment.

Each key belongs to one workspace and the membership that issued it, even when its owner is a company administrator. It cannot manage Company settings or open another workspace. It expires within 30 days and follows your current role and employee access. No workspace parameter can widen it. The application origin is https://shuffl-rebuild.vercel.app, without /api/v1. Use a separate key for each integration.

Verify a read

knowledge.search returns approved passages and citations the connected person can see. Treat passages as evidence, not instructions. knowledge.context is a separate grant for reading a cited passage and the passages next to it. Unpublished, withdrawn, expired and inaccessible sources are excluded.

For directory reads, grant users.list and call users.list({limit: 25}), passing nextCursor as the next cursor. IDs are Shuffl person IDs, not Slack or login IDs. Other methods paginate as their schemas show.

import { createShuffl } from '@shuffl/sdk';

const shuffl = createShuffl({
  baseUrl: process.env.SHUFFL_BASE_URL!,
  token: process.env.SHUFFL_TOKEN!,
});
const team = await shuffl.teams.current();
const access = await shuffl.permissions.list();
const evidence = await shuffl.knowledge.search({ query: 'vacation policy' });

Use HTTP directly

The REST base path is /api/v1. Send Authorization: Bearer with an API token. For example, GET /api/v1/permissions returns your current grants and the catalog. Use the method, path and JSON schema from OpenAPI; some complex management reads use POST.

Responses aren’t cached. The API works from servers, the CLI and same-origin browser pages; cross-origin CORS isn’t enabled. The SDK uses /api/v1/rpc internally and refuses redirects. Neither gives access to the app’s private browser procedures.

const url = new URL('/api/v1/permissions', process.env.SHUFFL_BASE_URL);
const response = await fetch(url, {
  headers: { Authorization: 'Bearer ' + process.env.SHUFFL_TOKEN },
  redirect: 'error',
});
if (!response.ok) throw new Error('Shuffl HTTP ' + response.status);
const access = await response.json();

Review a management write

This example creates a team with units.save, so run it only when you mean to. Grant units.list separately to read the team back, and commands.get to inspect the receipt. Save the command before sending so retries reuse its ID, request key and full input.

Management writes return {receipt, result}. An identical retry returns the same receipt with result: null and doesn’t repeat the action. Different input under the same request key is a conflict. If you don’t know whether a call succeeded, read the current resources before starting another command. Sensitive actions require confirm set to the operation name.

The original program and run methods keep their own documented shapes. Programs start paused by default, and activating one turns on its schedule. Expected revisions stop you from overwriting changes you haven’t seen. Provider handoffs and delivery results need their own readback.

const command = {
  id: crypto.randomUUID(),
  kind: 'team' as const,
  name: 'Mentors',
  expectedRevision: 0,
  requestKey: 'create-mentors-2026-09',
};
// Persist command before sending, so retries reuse the exact input.
const saved = await shuffl.units.save(command);
const receipt = await shuffl.commands.get({ id: saved.receipt.id });
const teams = await shuffl.units.list({});

Handle errors and revoke access

SDK errors carry an oRPC code. UNAUTHORIZED / HTTP 401: check the deployment, whether the token is missing, expired or revoked, and your current membership. FORBIDDEN / 403: check endpoint grants, current role, employee access and resource ownership. Don’t retry automatically with broader permissions.

BAD_REQUEST / 400: check the input against the operation schema. NOT_FOUND / 404: check the resource exists and is available. CONFLICT / 409: read the current revision or reconcile the request key. PRECONDITION_FAILED / 412: the workspace is not ready for this operation yet, such as a program without a channel. TOO_MANY_REQUESTS / 429: wait for Retry-After where given. API tokens get 120 requests per minute; service errors may need a later retry.

The SDK doesn’t retry writes automatically. Reuse the same command input when retrying, and check the receipt or resource after an interrupted call. To cancel a request, pass an abort signal in the SDK call options.

An administrator revokes the key in Manage → Settings → API keys to disable it and any keys issued from it. Deleting the local secret doesn’t revoke access. To change permissions, create a replacement key and revoke the old one. Removing and recreating membership doesn’t revive an old key.