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
| Status | Client behavior | Notes |
|---|---|---|
400 | Do not retry | Fix validation, phone number, route, or payload shape. |
401/403 | Do not retry blindly | Rotate or scope credentials before retrying. |
429 | Retry with backoff | Honor Retry-After where present. |
500/502/503 | Retry safe operations | Use 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