@hiveship/sdk
v0.4.0
Published
TypeScript SDK for the Hiveship REST API — auto-generated types over a curated typed client
Maintainers
Readme
@hiveship/sdk
Typed TypeScript client for the Hiveship REST API. Auto-generated from the canonical OpenAPI document — every endpoint, request body, and response shape this SDK exposes matches the production API exactly. Drift between client and server is impossible by construction.
Built on openapi-fetch — ~3 KB runtime, zero dependencies beyond fetch.
Installation
npm install @hiveship/sdkRequires Node.js 20 or later. Also runs in Cloudflare Workers, Deno, Bun, and modern browsers — anywhere a global fetch is available.
Quick start
import { HiveshipClient } from '@hiveship/sdk';
const hiveship = new HiveshipClient({
token: process.env.HIVESHIP_TOKEN, // your personal access token (from workspace settings → API Tokens)
});
const { data, error } = await hiveship.client.GET(
'/workspaces/{workspaceId}/projects/{projectId}/issues',
{
params: {
path: { workspaceId: 'cmpxxx', projectId: 'cmqxxx' },
query: { limit: 20 },
},
},
);
if (error) {
console.error('API error', error);
process.exit(1);
}
console.log(data.items.map((issue) => `${issue.projectPrefix}-${issue.number}: ${issue.title}`));Path strings are checked at compile time. A typo (/workspacs/...) or a removed endpoint surfaces as a TypeScript error before runtime; data and error are narrowed by the OpenAPI response schemas.
Authentication
The SDK takes a single token — a string or a TokenSource factory (see "Token rotation" below). The same field accepts both PAT and agent bearer formats:
| Token type | Prefix | Use case |
| ------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Personal Access Token | hsp_ | Most third-party integrations. Per-token scopes + rate limits. Generate from workspace settings → API Tokens. See docs/api/tokens. |
| Agent bearer token | hsa_ | Agent-side tooling. Capability tier (READ / SESSION / WORKSPACE) bound to the agent record. See docs/agents. |
Public endpoints (/health, /health/ready) work without a token.
Token rotation. Two flavours, pick whichever matches your credential lifecycle:
// 1. Static token (the common case — env var, doesn't change while the process runs):
const sdk = new HiveshipClient({ token: process.env.HIVESHIP_TOKEN });
// 2. Replace at runtime — useful when the operator rotates the PAT:
sdk.setToken(freshToken);
// 3. Factory — invoked per request, supports async credential stores
// (1Password CLI, AWS Secrets Manager, `gcloud auth print-access-token`):
const sdk = new HiveshipClient({
token: async () => await secretManager.get('hiveship_pat'),
});setToken(undefined) clears auth (subsequent requests are anonymous). The factory returning undefined or '' does the same — defensive against a ?? '' bug inside the credential read.
Configuration
new HiveshipClient({
token?: TokenSource; // string OR () => string | undefined | Promise<...>. Empty string throws.
baseUrl?: string; // Resolution: explicit > HIVESHIP_API_URL env var > public default
fetch?: Fetch; // Custom fetch (instrumented / mocked / polyfilled)
});baseUrl should NOT include a trailing slash.
Self-hosted deployments
If you're running Hiveship on your own infrastructure, set HIVESHIP_API_URL once at deploy time:
export HIVESHIP_API_URL=https://hiveship.acme-corp.internal/apiEvery new HiveshipClient({ token }) then routes correctly without touching the constructor surface. Explicit baseUrl still wins over the env var if you need per-call overrides.
Why this matters: without setting either the env var or baseUrl, the SDK defaults to https://hiveship.app/api (the public hosted Hiveship). A self-hosted PAT sent to the hosted host gets a 401 — but the token still traverses a third-party server over the wire. Set HIVESHIP_API_URL to keep credentials inside your perimeter.
Error handling
openapi-fetch returns { data, error, response }. Non-2xx responses surface on error — there's no thrown exception to catch:
const { data, error, response } = await hiveship.client.POST(
'/workspaces/{workspaceId}/projects/{projectId}/issues',
{
params: { path: { workspaceId, projectId } },
body: { title: 'New issue', delegateType: 'HUMAN' },
},
);
if (error) {
// `error` is typed from the API's documented error responses.
// `response.status` gives the HTTP code.
if (response.status === 403) console.log('Forbidden — check your scopes');
else if (response.status === 422) console.log('Validation failed', error);
else console.log('Unexpected error', error);
return;
}
// `data` is typed from the documented 200/201 response shape.
console.log(`Created issue ${data.projectPrefix}-${data.number}`);The API returns one of two error envelopes:
- Zod/custom:
{ success: false, error: { code, message, details? } } - NestJS default:
{ message, error, statusCode }
Both are visible on error — branch on response.status for the HTTP code and inspect error's shape for human-readable detail.
Type re-exports
import type { paths, components, operations } from '@hiveship/sdk';
// Pull a specific route's response type:
type IssueListResponse =
paths['/workspaces/{workspaceId}/projects/{projectId}/issues']['get']['responses']['200']['content']['application/json'];Use these to write strongly-typed wrappers around client.GET / client.POST etc. in your own integration code.
Resources
- API reference: hiveship.app/api/docs — Swagger UI with try-it-out
- OpenAPI spec: hiveship.app/api/openapi.json — machine-readable
- Public docs hub: hiveship.app/docs/api
- SDK docs: hiveship.app/docs/api/sdk
- Issues: github.com/SorcRR/HiveShip/issues
Versioning
@hiveship/sdk follows semver. The version number tracks SDK-side breaking changes — surface additions on the API (new endpoints, new optional fields) ship as MINOR releases since they don't break existing consumers; renames or removals ship as MAJOR. The CHANGELOG lists every release.
API additions don't always force an SDK release. The SDK only re-publishes when the maintainer runs npm run sync-spec and pushes a new release tag.
License
MIT — see LICENSE.
