Skip to main content

TypeScript SDK

The @slog-ai/sdk package provides a typed client for the Slog API with a fluent query builder.

Installation

npm install @slog-ai/sdk

Setup

import { SlogSdk, op } from "@slog-ai/sdk"

const slog = SlogSdk({ apiKey: "sl_abc.secret...", baseUrl: "..." }); // baseUrl optional
apiKey is required. baseUrl defaults to the Slog cloud endpoint.

Authentication

Current user

const me = await slog.me();

CRUD Operations

await slog.tasks.create({ title: "New feature", priority: "HIGH", teamId: "team_01jq..." });

await slog.tasks.update("PLAT-123", { title: "New feature", priority: "HIGH" });

await slog.tasks.delete(task.id);
Required fields for create: title, teamId. For update, all fields are optional — only the provided fields are changed.

Querying

Queries are lazy: they execute only when awaited.

Filtering

Chain multiple .where() calls; all conditions are combined with AND.
const tasks = await slog.tasks
  .where({ status: "TODO" })
  .where({ teamId: "123" })
  .where({ title: op.contains("foo") })
  .select({ id: true, title: true, assignee: { name: true } })
  .order({ priority: "desc" })

Field selection

Pass an object or a list of field name strings.
// Object form — supports nested relations
const tasks = await slog.tasks.select({ id: true, title: true, assignee: { name: true } })

// Array form
const tasks = await slog.tasks.select("id", "title")

Sorting

const tasks = await slog.tasks.order({ priority: "desc" })

Pagination

const page1 = await slog.tasks.limit(20).select("id", "title")
// page1.pagination.nextCursor
Pass nextCursor to fetch the next page:
const page2 = await slog.tasks.limit(20).select("id", "title").cursor(page1.pagination.nextCursor)
nextCursor is null when there are no more pages.

Filter Operators

import { op } from "@slog-ai/sdk"
OperatorDescriptionExample
op.contains(v)Case-insensitive substringwhere({ title: op.contains("auth") })
op.startsWith(v)Case-insensitive prefixwhere({ title: op.startsWith("Q2") })
op.gt(v)Greater thanwhere({ createdAt: op.gt("2025-05-23") })
op.gte(v)Greater than or equalwhere({ createdAt: op.gte("2025-05-23") })
op.lt(v)Less thanwhere({ dueDate: op.lt("2026-01-01") })
op.lte(v)Less than or equalwhere({ dueDate: op.lte("2026-01-01") })
op.oneOf(arr)Match any value in listwhere({ labels: op.oneOf(["red", "green"]) })
op.present()Field is not nullwhere({ assignee: op.present() })
Examples:
const tasks = await slog.tasks
  .select("id", "title")
  .where({ createdAt: op.gt("2025-05-23") })
  .where({ labels: op.oneOf(["red", "green"]) })
  .where({ assignee: op.present() })

Get a Single Record

Use the convenience singular methods — they accept either a UUID or a short reference.
const task = await slog.task("PLAT-123")
const project = await slog.project("proj_01jq...")


Agents

Create an AI agent user. The response includes the agent’s profile and a ready-to-use API key (shown only once).
const result = await slog.agents.create({ name: "My Agent" });
// result.agent.id, result.agent.apiKey
Only human users may create agents. The agent is added to the current workspace with the MEMBER role.

API Keys

List, create, and delete API keys for the current user and their owned agents.
// List keys (raw key value never returned — only prefix)
const { api_keys } = await slog.apiKeys.list();

// Create a key
const { key, ...meta } = await slog.apiKeys.create({ name: "CI/CD key" });
// key is the full raw value — store it now, not shown again

// Create with expiry
await slog.apiKeys.create({ name: "Temp key", expiresAt: "2027-01-01T00:00:00.000Z" });

// Delete a key
await slog.apiKeys.delete("apik_01jq...");

Fields

Manage workspace-scoped custom field definitions. Built-in fields are included automatically in list responses with isBuiltIn: true.
// List all field definitions (built-ins first, then custom)
const { fields } = await slog.fields.list();

// Filter to a specific resource type
const taskFields = await slog.fields
  .where({ recordType: "task" })

// Get a single field definition
const field = await slog.field("fdef_01jq...");

// Create a custom field (requires ADMIN or OWNER workspace role)
await slog.fields.create({
  key: "sprint_points",
  name: "Sprint Points",
  type: "number",
  recordTypes: ["task"],
});

// Create a select field with choices
await slog.fields.create({
  key: "quarter",
  name: "Quarter",
  type: "select",
  metadata: { choices: ["Q1", "Q2", "Q3", "Q4"] },
  recordTypes: ["task", "project"],
});

// Update a field (key and type are immutable)
await slog.fields.update("fdef_01jq...", { name: "Story Points" });

// Delete a field
await slog.fields.delete("fdef_01jq...");

Other Resources

The same query API is available on all resource collections.
slog.teams.where(...)
slog.projects.where(...)
slog.milestones.where(...)
slog.fields.where(...)