Does Everyone‑Can‑Use‑English Have an API? Complete Guide to the VTP
Yes. The Everyone‑Can‑Use‑English project provides a public HTTP API versioned under /api/v1/ that powers both its desktop client (the Enjoy app) and web portal. All API traffic is routed through a Cloudflare worker entry point to a backend service called VTP, with authentication handled via bearer tokens stored in the application's settings module.
The API is fully implemented in the open‑source codebase at ZuodaoTech/everyone-can-use-english. Whether you're building integrations, automating workflows, or extending the platform's speech‑processing capabilities, you can interact with the service programmatically using the built‑in TypeScript client or direct HTTP calls.
How the API Architecture Works
The request flow originates from the Cloudflare worker entry point at entry/index.js. This worker inspects the incoming pathname and routes traffic accordingly:
- Portal‑static assets (
/portal-assets,/portal-static) are forwarded to the portal service. - All other requests—including every API call—are forwarded to VTP.
// entry/index.js — routing logic
if (pathname === '/' || pathname.startsWith('/portal-assets') || pathname.startsWith('/portal-static')) {
return forwardToPortal(request, env);
} else {
return forwardToVtp(request, env); // ← API traffic lands here
}
This architecture means the Everyone‑Can‑Use‑English API is always available at the same domain as the application, with the worker handling SSL termination and load balancing transparently.
Core API Client Implementation
The official TypeScript client wraps all HTTP operations, handles authentication headers automatically, and provides typed responses. The implementation lives in two key files:
enjoy/src/api/client.ts— Core client class with methods for each endpoint, error handling, and JSON parsing.enjoy/src/api/index.ts— Re‑exports the singletonapiClientfor convenient imports throughout the Electron application.
The client retrieves the bearer token from enjoy/src/main/settings.ts, which persists authentication data between sessions. Non‑2xx responses are converted into thrown ApiError objects containing status, message, and optional details fields.
Everyone‑Can‑Use‑English API Endpoints
All endpoints share the base path /api/v1/ and require authentication via the Authorization: Bearer <token> header.
| Feature | Endpoint | Method | Description |
|---|---|---|---|
| User profile | /api/v1/users/:id |
GET |
Retrieve current user settings and preferences. |
| Upload recording | /api/v1/recordings |
POST |
Submit audio files as multipart/form-data for processing. |
| Get transcription | /api/v1/recordings/:id/transcription |
GET |
Fetch automatic transcription of a previously uploaded recording. |
| Speech metadata | /api/v1/speeches/:id |
GET / PATCH / DELETE |
CRUD operations for speech segments and metadata. |
| Dictionary data | /api/v1/dictionaries/:lang |
GET |
Access language‑specific IPA tables and custom glossary entries. |
Using the Everyone‑Can‑Use‑English API: Code Examples
Fetch the Current User Profile
import { apiClient } from '@/api';
apiClient.getUserProfile()
.then(profile => {
console.log('User profile:', profile);
})
.catch(err => {
console.error('Failed to load profile:', err);
});
The getUserProfile() method performs a GET request to /api/v1/users/me (or equivalent) and returns a typed UserProfile object.
Upload an Audio Recording
import { apiClient } from '@/api';
const form = new FormData();
form.append('file', file); // File or Blob from <input type="file">
apiClient.uploadRecording(form)
.then(resp => {
console.log('Recording ID:', resp.id);
})
.catch(err => console.error('Upload failed:', err));
The uploadRecording() method sends multipart/form-data to /api/v1/recordings and returns a response containing the generated recording identifier.
Retrieve a Transcription
import { apiClient } from '@/api';
async function fetchTranscription(recordingId: string) {
try {
const transcription = await apiClient.getTranscription(recordingId);
console.log('Transcription text:', transcription.text);
} catch (e) {
console.error('Error fetching transcription:', e);
}
}
Transcriptions are generated asynchronously. This endpoint returns the completed result or status information if processing is still pending.
Update Speech Metadata
import { apiClient } from '@/api';
apiClient.updateSpeech('speech123', {
title: 'New Title',
language: 'en-US',
})
.then(updated => console.log('Updated speech:', updated))
.catch(err => console.error('Update error:', err));
The updateSpeech() method performs a PATCH request to /api/v1/speeches/:id, allowing partial updates to speech segment properties.
Authentication and Settings
The API client automatically attaches authentication headers by reading from the settings module at enjoy/src/main/settings.ts. This module persists the bearer token using Electron's secure storage mechanisms.
For environments requiring proxy configuration, enjoy/src/main/proxy-agent.ts configures the underlying fetch implementation to route through corporate or regional proxies.
Summary
-
The Everyone‑Can‑Use‑English API is public and versioned under
/api/v1/, with all traffic routed through theentry/index.jsCloudflare worker to the VTP backend. -
Use the official TypeScript client exported from
enjoy/src/api/index.tsfor convenient, typed access to all endpoints—authentication and error handling are built‑in. -
Key capabilities include user management, audio recording upload, automatic transcription retrieval, speech metadata CRUD, and dictionary data access.
-
Authentication requires a bearer token stored in
enjoy/src/main/settings.ts; the client handles header injection automatically.
Frequently Asked Questions
Is the Everyone‑Can‑Use‑English API officially documented?
No formal OpenAPI specification is published. The authoritative reference is the source code itself—specifically enjoy/src/api/client.ts, which contains method signatures, endpoint paths, and request/response types. Server‑side route definitions can be inferred from the VTP backend routing logic.
Can I use the API without the Enjoy desktop app?
Yes. While the apiClient is designed for the Electron application, the underlying HTTP endpoints accept standard requests with a valid bearer token. You can authenticate through the web portal, extract your token from browser storage, and make direct fetch or curl calls to https://<domain>/api/v1/.
How are API errors handled?
The client converts all non‑2xx HTTP responses into ApiError exceptions with status, message, and optional details properties. Implement try/catch blocks around client calls to handle authentication failures, rate limits, and validation errors.
What audio formats does the upload endpoint accept?
The analysis shows multipart form uploads but does not specify exact codec requirements. Based on typical speech‑processing pipelines, WAV and MP3 are commonly supported; verify by inspecting the recording validation logic in the VTP backend or testing with your preferred format.
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 →