TypeScript

Build a typed StateSet Voice client.

Generate TypeScript types from the public OpenAPI contract, wrap fetch with runtime credentials, and keep contract changes reviewed in CI.

Install and generate types

Use the public spec for tenant runtime integrations. Generate the admin spec only inside internal systems that are allowed to hold admin credentials.

npm install --save-dev openapi-typescript

npx openapi-typescript https://voice.stateset.app/api-docs/public.json \
  -o src/generated/stateset-voice-public.d.ts

Runtime client wrapper

import type { paths } from "./generated/stateset-voice-public";

type MakeCallBody =
  paths["/api/v1/make-call"]["post"]["requestBody"]["content"]["application/json"];
type MakeCallResponse =
  paths["/api/v1/make-call"]["post"]["responses"]["200"]["content"]["application/json"];

export class StateSetVoiceClient {
  constructor(
    private readonly apiKey: string,
    private readonly baseUrl = "https://voice.stateset.app"
  ) {}

  async makeCall(body: MakeCallBody): Promise {
    const response = await fetch(`${this.baseUrl}/api/v1/make-call`, {
      method: "POST",
      headers: {
        authorization: `Bearer ${this.apiKey}`,
        "content-type": "application/json"
      },
      body: JSON.stringify(body)
    });

    if (!response.ok) {
      const requestId = response.headers.get("x-request-id");
      throw new Error(`StateSet Voice ${response.status} request_id=${requestId ?? "unknown"}`);
    }

    return response.json() as Promise;
  }
}

Error handling policy

StatusClient behaviorNotes
400Do not retryFix validation, phone number, route, or payload shape.
401/403Do not retry blindlyRotate or scope credentials before retrying.
429Retry with backoffHonor Retry-After where present.
500/502/503Retry safe operationsUse jitter and protect outbound calls from duplication.

Contract drift check

curl -sS https://voice.stateset.app/api-docs/public.json \
  -o api-contracts/stateset-voice-public.json

npx openapi-typescript api-contracts/stateset-voice-public.json \
  -o src/generated/stateset-voice-public.d.ts

git diff --exit-code api-contracts src/generated