Skip to main content

TypeScript SDK

Status: not published yet. @nexspace/sdk is generated by Stainless from the merged OpenAPI spec and stainless.config.yml; the first release has not landed on npm. The hand-written package under packages/sdk-typescript/ is a deprecated, private: true stopgap and is not the package documented here — it exports different symbols and will be deleted. Everything below describes the generated client. Track tools/stainless/README.md for the release.

Installation

Quick Start

Configuration

NEXSPACE is the environment prefix for generated options, so apiKey falls back to NEXSPACE_API_KEY when you omit it.
There is no version client option. NexSpace-Version is a per-request header (see Pinning an API version), not a constructor argument — a client-level default would silently pin every caller in your process to one date.

Resources

The generated resources mirror stainless.config.yml. Path parameters are positional; query and body fields go in the params object.

Facilities

update needs facilities:write. create is guarded by role, not scope — authorize(ROLES.SUPER_ADMIN) against the key owner’s role — so it only succeeds for a key owned by a super admin.

Staff

GET /api/staff accepts exactly four filters — facilityId, specialty, isActive, and search (name or email). There is no query field and no limit.

Staff credentials

Credentials hang off a staff member, as the staff.credentials subresource:
Each credential carries status — one of active, expiring, expired, pending, rejected — so filter client-side on that plus expirationDate to find what is lapsing. There is no server-side “expiring credentials” REST endpoint; the MCP verb listExpiringCredentials covers that shape over MCP.

Shifts

status accepts open, assigned, in_progress, completed, or cancelled. shifts.unassign and shifts.delete are generated too.

Agent runs

Requires the agents:run scope. A second concurrent start for the same agent returns 409 AGENT_BUSY. agents.listRuns, agents.cancelRun, and agents.listRunApprovals round out the resource. The SSE progress stream (GET /api/agents/{id}/runs/{runId}/stream) is not generated — consume it with the CLI or raw HTTP. See Agent runs.

Approvals

Two gates, not one: the credential needs agents:approve and must own the run that raised the approval — and because that makes every decision a self-approval, the credential’s bound user must also hold the ai.approve_actions RBAC permission. Without it you get 403 SELF_APPROVAL_FORBIDDEN.

Everything else

Client-level calls

whoami() returns the identity the presented credential authenticates as — the fastest way to confirm a key is live and bound to the user you expect.
No apiKeys resource is generated. /api/api-keys* rejects every API-key-authenticated request with 403 FORBIDDEN (“API keys cannot be managed with an API key — sign in to the dashboard”) before the handler runs, so the methods would be guaranteed-dead code. Mint and rotate keys in the dashboard under Settings → API Keys.No mcp resource either. MCP is spoken over JSON-RPC by MCP clients, and the SDK is pinned to https://api.nexspace365.com, where every /mcp path answers 403 MCP_HOST_NOT_ALLOWED. Point an MCP client at https://mcp.nexspace365.com instead.

Pinning an API version

Send NexSpace-Version as a per-request header. Omit it and you get the latest version.
2026-07-24 is the current latest. Discover the catalog with client.apiVersions(), and see Versioning.

Error Handling

The generated client throws an APIError hierarchy, one class per HTTP status family:
Every NexSpace error body has the same envelope, so err.error is:
Quote requestId when you email admin@nexspace365.com. See Errors for the full code list.

Idempotency

Mutations are not given an automatic key. Pass one yourself with the idempotencyKey request option, which sends the Idempotency-Key header:
Replaying the same key with the same body within 24 hours replays the original response; the same key with a different body returns 409 Conflict. See Idempotency.