How to Make Requests to the VoiceStudio Backend API: A Complete Guide to the TypeScript Client
You can interact with the VoiceStudio backend API by importing helper functions from frontend/src/api/client.ts, which handle base URL resolution, automatic authentication header injection, transport retries, and structured error parsing.
VoiceStudio ships with a lightweight, well-encapsulated client library designed for reliable communication between the frontend and backend services. This guide demonstrates how to make requests to the VoiceStudio backend API using the TypeScript utilities implemented in the repository.
Base URL Resolution
Before executing any request, the client determines the correct backend endpoint through the _resolveApiBase function in frontend/src/api/client.ts. This resolver respects a hierarchy of configuration sources: user-defined overrides take precedence, followed by Tauri webview defaults, development server settings, and finally falling back to the page’s current origin.
The resolved base URL is exported as the constant API and can be inspected or extended using the apiUrl(path?) helper. This ensures that whether you are running in a desktop webview, a local development environment, or a deployed production build, requests automatically target the correct backend instance.
Authentication and Security Headers
The client handles four distinct authentication scenarios transparently based on the request context:
-
Same-origin sessions: When the frontend and backend share an origin, the browser automatically transmits HttpOnly cookies containing the session identifier. No manual header management is required.
-
Cross-origin bearer tokens: For cross-origin requests, the client retrieves a short-lived token from
sessionStorageusinggetAdminSession(defined infrontend/src/api/authSession.ts) and injects it as anAuthorization: Bearer <token>header. -
PIN-based LAN access: When connecting via LAN-share QR codes, the client adds the PIN as the
X‑OmniVoice‑Pinheader to authenticate local network requests. -
CSRF protection: Same-origin requests receive an additional
X‑VoiceStudio‑CSRFheader to prevent cross-site request forgery attacks.
Core Request Methods
The frontend/src/api/client.ts module exports four primary utilities that form the request pipeline:
-
apiFetch(path, opts): The foundational method that builds absolute URLs viaapiUrl(path), attaches security headers, executes the nativefetch, and implements transport-retry logic coupled with backend-lifecycle probing. Non-2xx responses trigger anApiErrorcontaining detailed failure metadata. -
apiJson<T>(path, opts): A convenience wrapper aroundapiFetchthat automatically parses the response body as JSON and returns a typed Promise. -
apiPost<T>(path, body?, opts): Configures the request method toPOST, serializes JSON bodies (or passesFormDataobjects directly), and delegates toapiJsonfor response handling. -
apiDelete(path, opts): Executes aDELETErequest throughapiFetchwithout expecting a response body.
Practical Code Examples
Retrieve Data with Automatic JSON Parsing
Use apiJson for typed GET requests to endpoints like /archetypes:
import { apiJson } from '@/api/client.ts';
async function loadArchetypes() {
const archetypes = await apiJson<{ id: string; name: string }[]>('/archetypes');
console.log(archetypes);
}
loadArchetypes();
Submit Multipart Form Data
Upload files or submit complex payloads using apiPost, which handles both JSON and FormData encoding:
import { apiPost } from '@/api/client.ts';
async function startTranscribe(file: File) {
const form = new FormData();
form.append('audio', file);
const result = await apiPost<{ taskId: string }>('/tasks/transcribe', form);
console.log('Task started:', result.taskId);
}
Cancel Operations with DELETE Requests
Remove resources using the apiDelete shortcut:
import { apiDelete } from '@/api/client.ts';
async function cancelTask(taskId: string) {
await apiDelete(`/tasks/${taskId}`);
console.log('Cancelled', taskId);
}
Implement Request Timeouts and Abort Signals
For long-running operations, pass custom fetch options through apiFetch to leverage AbortController:
import { apiFetch } from '@/api/client.ts';
async function fetchWithTimeout() {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
try {
const resp = await apiFetch('/system/info', { signal: controller.signal });
const info = await resp.json();
console.log(info);
} finally {
clearTimeout(timeout);
}
}
Error Handling and Transport Reliability
When the backend returns a non-2xx status code, apiFetch throws an ApiError instance containing the HTTP status, error message, and response metadata. This allows applications to distinguish between network failures, authentication errors, and validation issues.
The client also implements sophisticated crash-forensics and backend-lifecycle probing through utilities in frontend/src/utils/backendContact.ts and frontend/src/utils/remoteBackendProbe.ts. These modules monitor backend availability and automatically retry transient failures, ensuring robust connectivity across unstable network conditions.
Summary
- Import request helpers from
frontend/src/api/client.tsto interact with the VoiceStudio backend API using consistent, typed methods. - The client automatically resolves the correct base URL via
_resolveApiBaseand supports multiple authentication mechanisms including HttpOnly cookies, bearer tokens, and PIN headers. - Use
apiJsonfor GET requests,apiPostfor creating resources, andapiDeletefor removal operations. - All methods implement transport retries and detailed error reporting through the
ApiErrorclass.
Frequently Asked Questions
How does VoiceStudio handle authentication for cross-origin API requests?
For cross-origin requests, the client retrieves a temporary bearer token from sessionStorage using the getAdminSession function and attaches it as an Authorization: Bearer <token> header. This mechanism is defined in frontend/src/api/authSession.ts and allows secure API access when the frontend and backend are served from different origins.
What happens when the VoiceStudio backend is temporarily unreachable?
The apiFetch function implements transport-retry logic that probes backend lifecycle status using utilities from frontend/src/utils/remoteBackendProbe.ts. If the initial request fails due to network instability, the client automatically retries before surfacing a permanent failure, reducing the impact of transient connectivity issues.
Can I use the VoiceStudio API client outside of the main application?
Yes, the utilities exported from frontend/src/api/client.ts are standard TypeScript modules with no framework dependencies. You can import apiJson, apiPost, or apiFetch into Node.js scripts, testing utilities, or external applications to interact with the VoiceStudio backend API, provided you handle the API base URL configuration and authentication headers appropriately.
How does the client protect against CSRF attacks?
Same-origin requests automatically receive an X‑VoiceStudio‑CSRF header containing a validation token. This header is inspected by the backend to ensure the request originated from an authenticated VoiceStudio frontend session, preventing malicious sites from performing actions on behalf of logged-in users.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →