Docs

Client API reference

The complete normalized client surface. Provider adapters implement transport and mapping; WorkClient adds validation, plans, revisions, warning acknowledgement, and idempotency.

createWorkClient

function createWorkClient(options: {
  adapter: WorkAdapter;
  idempotencyStore?: IdempotencyStore;
  now?: () => Date;
}): WorkClient;

adapter is required. The default idempotency store is process-local memory. now exists for deterministic testing and should normally be omitted.

Read methods

get(id, options?)

get(id: string, options?: { signal?: AbortSignal }): Promise<WorkItem>

Returns one normalized item or throws WorkNotFoundError. IDs are adapter-native: a GitHub issue number, GitLab issue IID, Linear ID or identifier, Jira key, or Azure work-item ID.

list(input?, options?)

list(input?: {
  project?: string; assignee?: string;
  state?: WorkItemState | WorkItemState[];
  labels?: string[]; query?: string;
  limit?: number; cursor?: string;
}, options?: { signal?: AbortSignal }): Promise<WorkPage<WorkItem>>

Returns an opaque provider cursor. Never construct or parse cursors; pass nextCursor back unchanged.

assignee takes the writable user reference that the provider exposes as WorkUser.id: a GitHub login, a numeric GitLab user ID, a Linear user ID, a Jira account ID, or an Azure DevOps identity.

Prepare methods

  • prepareCreate(input) — Plan a new item without writing it.
  • prepareUpdate(id, input, options?) — Read current state and calculate a changed-field diff.
  • prepareComment(id, input, options?) — Read the target and plan a comment.

Create plans do not have an expected revision. Update and comment plans capture the current item and opaque revision.

Fields set to undefined are treated as absent: they never appear in input or changes, and an update that contains only undefined fields is rejected with WorkValidationError.

commit(change, options?)

commit<TChange extends PreparedWorkChange>(
  change: TChange,
  options?: {
    idempotencyKey?: string;
    acceptWarnings?: boolean;
    signal?: AbortSignal;
  },
): Promise<CommitResultFor<TChange>>

Commit validates provider identity, fingerprint integrity, warning acknowledgement, idempotency state, and revision before calling the adapter. The receipt follows the prepared action: create plans return CreateCommitResult, updates return UpdateCommitResult, and comments return CommentCommitResult with a required comment.

typed-receipt.ts
const change = await work.prepareComment("ENG-42", {
  body: "Validated in staging.",
});

const receipt = await work.commit(change);
receipt.action;       // "comment"
receipt.comment.body; // string, not optional

If a mutation starts and the provider outcome becomes uncertain, Work SDK stores an ambiguous state and throws WorkAmbiguousCommitError. Reconcile the provider result before another write; never blind-retry that key.

Core types

TypePurpose
WorkItemNormalized item plus provider state name, opaque revision, URL, and optional raw payload.
WorkCommentNormalized body, author, timestamps, and raw payload.
PreparedWorkChangeSerializable, fingerprinted plan for one create, update, or comment.
CommitResultDiscriminated union of create, update, and comment receipts with replay flag and commit time.
CommitResultFor<T>Maps a prepared change type to its exact action-specific receipt.
WorkPage<T>Items plus an optional opaque next cursor.
WorkWarningStructured provider limitation or lossy/ambiguous mapping notice.

Capabilities

work.capabilities is an immutable snapshot. Inspect it when building tools or UIs so unsupported actions are absent rather than offered and rejected later.

if (work.capabilities.parentLinks) {
  tools.push(updateParentTool(work));
}

if (!work.capabilities.multipleAssignees) {
  schema.assigneeIds = z.array(z.string()).max(1);
}

switch (work.capabilities.concurrency.update) {
  case "atomic":     // provider rejects races in the write itself
  case "preflight":  // SDK re-reads, but a small race window remains
  case "none":
}

optimisticConcurrency remains as a deprecated compatibility Boolean. New code should use the action-specific concurrency object.

IdempotencyStore

interface IdempotencyStore {
  acquire(key: string, intentFingerprint: string): MaybePromise<
    | { status: "acquired"; leaseId: string }
    | { status: "completed"; result: CommitResult }
    | { status: "in-flight" | "ambiguous" | "conflict" }
  >;
  complete(key: string, leaseId: string, result: CommitResult): MaybePromise<void>;
  abandon(key: string, leaseId: string, outcome: "retryable" | "ambiguous"): MaybePromise<void>;
}

The client prefixes keys with the provider. acquire must be atomic across every worker using the store; use a transaction, compare-and-swap, unique insert, or conditional put. A durable get followed by set is not sufficient.

  • completed — Replay the stored receipt without a provider call.
  • in-flight — Throw WorkInFlightError; another worker owns the claim.
  • ambiguous — Throw WorkAmbiguousCommitError; reconcile before retrying.
NextErrors →Handle authentication, rate limits, conflicts, validation, and provider failures.

On this page