# @workast/sdk

> Workast SDK for JavaScript in the browser and Node.js

Latest version **3.5.0** (published 2026-09-16) · MIT license · 0 weekly downloads

## Install

```sh
npm install @workast/sdk
pnpm add @workast/sdk
yarn add @workast/sdk
bun add @workast/sdk
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 3.5.0 |
| Published | 2026-09-16 |
| First published | 2019-12-05 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18 |
| Dependencies | 0 |
| Unpacked size | 2 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2 |
| Author | Workast |
| Maintainers | guillegette |
| Keywords | workast, project management, api |

## Links

- npm: https://www.npmjs.com/package/@workast/sdk
- Repository: https://github.com/workast/sdk
- Homepage: https://github.com/workast/sdk#readme
- Issues: https://github.com/workast/sdk/issues
- npm.io page: https://npm.io/package/@workast/sdk

## Recent versions

- 3.5.0 (latest) — 2026-09-16
- 3.4.0 — 2026-09-15
- 3.3.0 — 2026-09-08
- 3.2.0 — 2026-09-03
- 3.1.0 — 2026-08-20
- 3.0.0 — 2026-08-16
- 2.3.0 — 2020-08-27
- 2.2.0 — 2020-08-04
- 2.1.1 — 2020-07-29
- 2.1.0 — 2020-07-27
- 2.0.0 — 2020-05-18
- 1.3.1 — 2020-05-07
- 1.3.0 — 2020-05-05
- 1.2.0 — 2020-03-02
- 1.1.0 — 2019-12-26
- … 5 more at https://npm.io/package/@workast/sdk/versions

## README

# @workast/sdk

[![npm version](https://img.shields.io/npm/v/@workast/sdk.svg)](https://www.npmjs.com/package/@workast/sdk)
[![CI](https://github.com/workast/sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/workast/sdk/actions/workflows/ci.yml)

TypeScript library for the [Workast API](https://developers.workast.com/). Works in Node.js 18+ and in browsers.

## Installation

```sh
npm install @workast/sdk
```

## Usage

Create a token in Workast under **Preferences → API**. Secret API keys are server-only — passing `apiKey` in a browser throws.

```ts
import { Workast } from '@workast/sdk';

const workast = new Workast({ apiKey: process.env.WORKAST_API_KEY });
// shorthand: new Workast(process.env.WORKAST_API_KEY)

const task = await workast.tasks.create(listId, { text: 'Ship SDK' });
await workast.tasks.complete(task.id);
const page = await workast.tasks.list({
  predicates: [{ type: 'status', attribute: 'status', comparison: 'eq', value: 'pending' }],
});
```

Browser / user session:

```ts
const workast = new Workast({ token: sessionToken });
// or
const workast = new Workast({ getToken: () => auth.getAccessToken() });
```

### Configuration

| Option | Description |
| --- | --- |
| `apiKey` | Secret API token. Server-only. |
| `token` | User or session token. Allowed in browsers. |
| `getToken` | Function that returns a token (sync or async). |
| `baseUrl` | API host. Defaults to `https://api.workast.com`. |
| `headers` | Extra headers (for example `W-USER-ID`, `W-TEAM-ID`). `Authorization` is set by the client. |
| `fetch` | Custom `fetch` implementation. |
| `timeout` | Request timeout in milliseconds. Defaults to `30000`. `0` disables the timeout. |

`withHeaders(h)` returns a cloned client. `setHeaders(h)` updates the current one.

```ts
const workast = new Workast({
  apiKey: process.env.WORKAST_API_KEY,
  headers: { 'W-USER-ID': userId },
});

await workast.withHeaders({ 'W-USER-ID': otherUserId }).tasks.create(listId, { text: 'Hi' });
workast.setHeaders({ 'W-TEAM-ID': teamId });
```

### Errors

Failed requests throw a subclass of `ApiError`:

| Status | Error |
| --- | --- |
| 400 | `ValidationError` |
| 401 | `AuthenticationError` |
| 403 | `PermissionError` |
| 404 | `NotFoundError` |
| other | `ApiError` |

When the API body is `{ error: { name, message } }` and `name` is `TeamDeactivatedError`, `UserDeactivatedError`, `UserSuspendedError`, or `TeamSuspendedError`, the SDK throws `AccountError` instead. `AccountError` extends `ApiError`. It has `reason` (the API `name`) and `message` (the API `message`).

```ts
import { AccountError } from '@workast/sdk';

try {
  await workast.tasks.retrieve(taskId);
} catch (err) {
  if (err instanceof AccountError) {
    console.log(err.reason, err.message, err.status);
  }
}
```

`TimeoutError` has no HTTP status. It is thrown when the request exceeds `timeout`.

```ts
import { NotFoundError } from '@workast/sdk';

try {
  await workast.tasks.retrieve(taskId);
} catch (err) {
  if (err instanceof NotFoundError) {
    console.log(err.status, err.body);
  }
}
```

## Resources

`tasks` · `lists` · `fields` · `users` · `searches` · `tags` · `notes` · `notifications` · `meetings` · `calendar.events` · `workflows` · `reactions` · `attachments` · `tokens`

Methods use `create` / `retrieve` / `update` / `list` / `del`, plus domain verbs like `complete` and `assign`. Path ids first, body second, request options last. Types match the [API reference](https://developers.workast.com/).

## Testing

`@workast/sdk/mock` stubs SDK methods on any `Workast` instance (including one your app already constructed). No real HTTP while a mock is active. It also exports `examples`: Public API response fixtures (`examples.task`, `examples.list`, `examples.userResource`, …) generated from the spec. Spread them in `.resolves()` and override the fields your test cares about.

```ts
import { Workast } from '@workast/sdk';
import { examples, mockWorkast } from '@workast/sdk/mock';

const workast = new Workast({ apiKey: process.env.WORKAST_API_KEY });

async function createShipTask() {
  return workast.tasks.create(examples.list.id, { text: examples.task.text });
}

const mock = mockWorkast();
mock.tasks.create.on(examples.list.id, { text: examples.task.text }).resolves({
  ...examples.task,
  text: 'Ship from my test',
});

const created = await createShipTask();

expect(created.text).toBe('Ship from my test');
expect(mock.calls()).toEqual([
  { method: 'tasks.create', args: [examples.list.id, { text: examples.task.text }] },
]);
```

```ts
mock.users.me.on().resolves({ ...examples.userResource, name: 'Ada Lovelace' });
```

`.on(...args)` is a prefix: extra trailing options on the real call still match. Nested objects match regardless of key order. Pass a function for a loose match (`true` → match):

```ts
mock.tasks.create.on(examples.list.id, (body) => body.text === examples.task.text).resolves({
  ...examples.task,
});
```

Queue errors with `.rejects()`. `errors.*` are the same classes the client throws:

```ts
import { AuthenticationError } from '@workast/sdk';
import { errors } from '@workast/sdk/mock';

mock.users.me.on().rejects(errors.unauthorized);
await expect(workast.users.me()).rejects.toBeInstanceOf(AuthenticationError);
```

| Helper | Meaning |
| --- | --- |
| `mock.calls()` | Every SDK call while this mock is active (`{ method, args }`). |
| `mock.pending()` | Interceptors that were not used. |
| `interceptor.wasCalled()` | Whether that `.resolves()` / `.rejects()` fired. |
| `mock.reset()` | Clear queue and calls. Stay intercepting. |
| `mock.restore()` | Unpatch. Later SDK calls hit the real API. |

One mock per test, or one shared mock and `reset()` between tests:

```ts
const mock = mockWorkast();

afterEach(() => mock.reset());
afterAll(() => mock.restore());
```

`mockWorkast()` last-wins: a second call replaces the active queue. Unmatched SDK methods throw and list pending interceptors.

## Upgrading from v2

v3 is a rewrite. The v2 positional constructor, `apiCall`, and generated resource helpers are gone. A string argument is now a secret `apiKey` (server-only), not a session token.

```ts
// v2
const workast = new Workast(process.env.WORKAST_TOKEN);

// v3
const workast = new Workast({ apiKey: process.env.WORKAST_API_KEY });
```

What shipped in each version is on [Releases](https://github.com/workast/sdk/releases).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). To report a vulnerability, see [SECURITY.md](SECURITY.md).

## License

MIT

---
_Source: https://npm.io/package/@workast/sdk · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
