Personal Business

API Reference

Authentication

API key authentication flow

The NoLang API uses API key authentication. Include the following header in every request.

Authorization: Bearer YOUR_API_KEY

Managing API keys

  • Generation In the sidebar, open “NoLang API” → “API Key Management” and click “New API Key”
  • Permission An API key has the same permissions as your user account
  • Deletion Delete keys promptly once you no longer use them

Security best practices

  1. Store it in an environment variable Avoid hard-coding it
  2. HTTPS only All API traffic goes over HTTPS
  3. Rotate your keys regularly
Shell
# Enter the key without echoing it
read -rsp "Enter your NoLang API key: " NOLANG_API_KEY && echo
# Call the API with the variable
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer $NOLANG_API_KEY" \
-F "video_setting_id=$VIDEO_SETTING_ID" \
-F "text=Hello, this is a test of the NoLang API."
# Clear the variable when you are done, just in case
unset NOLANG_API_KEY

Common specifications

Base URL and version

  • Production: https://api.no-lang.com/v1
  • Versioning: The URL path includes the version (currently v1)

Request format

Authorization: Bearer YOUR_API_KEY
Content-Type: multipart/form-data # For file uploads
Content-Type: application/json # For JSON requests

List endpoints use the following query parameters.

  • page Page number (starts at 1)
  • Fixed at 50 items per page
Shell
curl "https://api.no-lang.com/v1/videos/?page=2" \
-H "Authorization: Bearer YOUR_API_KEY"

Rate limits and concurrency limits

Endpoint Limit When exceeded
POST /videos/generate/
POST /videos/{video_id}/conversions/
Up to 2 requests per 10 seconds 429 error
Other endpoints Up to 5 requests per 10 seconds (1 per 2 seconds) 429 error
  • Video generation: up to 2 videos can be generated in parallel per user account. Exceeding this returns a 503 error.
  • Video conversion is subject to the same concurrency limit as video generation. Exceeding it returns a 503 error.
  • Note: The limit applies per user account, not per API key. Issuing multiple API keys does not increase the number of concurrent generations.

Error handling

JSON
{
"error_code": "ERROR_CODE",
"error": "Detailed error description"
}
  • 5xx errors: Retry up to 3 times with exponential backoff
  • 503 error: Wait until server load decreases (recommended: 30 seconds to 1 minute)
  • 429 error: Wait until the rate limit resets
  • Other: No retry needed

Endpoint

POST /videos/generate/

Requests generation of a new video.

  • Permission: API key authentication required
  • Rate Limit: Up to 2 requests per 10 seconds
  • Content-Type: multipart/form-data
Name Type Personal Plan Business Plan Required Description
Supported formats Size Supported formats Size
video_setting_id string (UUID) Required ID of the video setting to use
text string Conditional Text for video generation (required in generate-from-question/instruction mode)
pdf_file file .pdf 100MB .pdf 180MB Conditional PDF file (required in generate-from-documents mode)
pptx_file file .pptx 100MB .pptx 180MB Conditional PPTX file (required in generate-from-documents mode)
audio_file file .mp3, .wav, .m4a, .aac 50MB .mp3, .wav, .m4a, .aac 180MB Conditional Audio file (required in generate-from-audio mode)
video_file file .mp4 50MB .mp4, .mov, .webm 180MB Conditional Video file (required in generate-from-video mode)
image_files list of file .png, .jpg, .jpeg, .webp 10MB x 10 .png, .jpg, .jpeg, .webp 10MB x 10 Optional List of image files (can be specified in generate-from-question/instruction mode)
JSON
{
"video_id": "550e8400-e29b-41d4-a716-446655440000"
}
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "video_setting_id=YOUR_VIDEO_SETTING_ID" \
-F "text=What is machine learning? Please explain it briefly"
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "video_setting_id=YOUR_VIDEO_SETTING_ID" \
-F "text=NoLang is a service developed by Mavericks, Inc. that generates videos in real time."
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "video_setting_id=YOUR_VIDEO_SETTING_ID" \
-F "pdf_file=@company_presentation.pdf"
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "video_setting_id=YOUR_VIDEO_SETTING_ID" \
-F "pptx_file=@annual_report.pptx"
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "video_setting_id=YOUR_VIDEO_SETTING_ID" \
-F "text=Analyze this company's strengths and weaknesses in comparison with its competitors" \
-F "pdf_file=@company_report_2024.pdf"
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "video_setting_id=YOUR_VIDEO_SETTING_ID" \
-F "audio_file=@lecture_recording.mp3"
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/generate/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "video_setting_id=YOUR_VIDEO_SETTING_ID" \
-F "video_file=@original_video.mp4"

GET /videos/

Retrieves a list of the videos you have generated.

  • Permission: API key authentication required
  • Rate Limit: Up to 5 requests per 10 seconds
Name Type Required Description
page integer Optional Page number (default: 1)
JSON
{
"results": [
{
"video_id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2024-01-15T09:30:00Z",
"prompt": "Explain the evolution of AI in 5 minutes."
},
{
"video_id": "660e8400-e29b-41d4-a716-446655440001",
"created_at": "2024-01-15T08:20:00Z",
"prompt": "Marketing strategy basics"
}
],
"has_next": false,
"total_count": 5,
"page": 1,
"items_per_page": 50
}

GET /videos/{video_id}/

Retrieves the generation status and download URL of a specific video.

  • Permission: API key authentication required
  • Rate Limit: Up to 5 requests per 10 seconds
Name Type Required Description
video_id string (UUID) Required Video ID
  • running — Generating
  • completed — Generation complete (available for download)
  • failed — Generation failed
  • expired — Expired
{
"video_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"download_url": "",
"copyright": []
}
{
"video_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"download_url": "https://s3.no-lang.com/asset/example.mp4?X-Amz-Algorithm=...",
"copyright": [...]
}
  • completed Only videos in this status can be downloaded
  • download_url is a temporary presigned URL (it expires)

GET /videos/{video_id}/conversions/

Retrieves whether a specific video supports language and aspect ratio conversion, along with the list of values you can specify as the conversion target.

  • Permission: API key authentication required
  • Rate Limit: Up to 5 requests per 10 seconds
Name Type Required Description
video_id string (UUID) Required ID of the source video. You can specify only videos you own
  • is_convertible — Whether this video supports conversion. false when there is no generated video data or when the video includes a real avatar
  • current_language — Current language of the source video
  • available_languages — List of language codes you can specify as the conversion target (varies by video)
  • current_aspect_ratio — Current aspect ratio of the source video
  • available_aspect_ratios — List of aspect ratios you can specify as the conversion target (always all 7 for convertible videos)
JSON
{
"is_convertible": true,
"current_language": "ja",
"available_languages": ["ja", "en"],
"current_aspect_ratio": "16:9",
"available_aspect_ratios": ["16:9", "9:16", "4:3", "1:1", "4:5", "2:3", "21:9"]
}

POST /videos/{video_id}/conversions/

Asynchronously generates a new video by converting an existing video into another language or aspect ratio. The source video is left unchanged. Poll the new video_id returned in the response with GET /videos/{video_id}/ and confirm completion in the same way as for video generation.

  • Permission: API key authentication required
  • Rate Limit: Up to 2 requests per 10 seconds
  • Content-Type: application/json
Name Type Required Description
language string Conditional Language code after conversion. At least one of this and aspect_ratio must be specified. The same value as the source video cannot be specified
aspect_ratio string Conditional Aspect ratio after conversion. At least one of this and language must be specified. The same value as the source video cannot be specified

16:9 9:16 4:3 1:1 4:5 2:3 21:9

  • Japanese ja
  • English en
  • Chinese (Simplified) zh-Hans
  • Chinese (Traditional) zh-Hant
  • Korean ko
  • Spanish es
  • French fr
  • German de
  • Italian it
  • Portuguese pt
  • Russian ru
  • Hindi hi
  • Bengali bn
  • Indonesian id
  • Thai th
  • Vietnamese vi
  • Tagalog tl
  • Malay ms
  • Burmese my
  • Nepali ne
  • Mongolian mn
  • Turkish tr
  • Swedish sv
  • Danish da
  • Finnish fi
  • Polish pl
  • Czech cs
  • Slovak sk
  • Dutch nl
  • Romanian ro
  • Croatian hr
  • Bulgarian bg
  • Ukrainian uk
  • Greek el
JSON
{
"video_id": "550e8400-e29b-41d4-a716-446655440000"
}
  • video_id is the ID of the new video created by the conversion (different from the source video ID)
error_code HTTP Condition
CONVERT_TARGET_REQUIRED 400 Neither language nor aspect_ratio is specified
INVALID_LANGUAGE 400 language is set to a value that is not a supported language code
INVALID_ASPECT_RATIO 400 aspect_ratio is set to an unsupported value
LANGUAGE_NOT_SUPPORTED_BY_VOICES 400 The language you specified is not included in the available_languages of the source video
CONVERT_NO_CHANGE 400 Every value you specified is identical to the source video (nothing changes)
SOURCE_VIDEO_NOT_CONVERTIBLE 400 The source video does not support conversion (is_convertible is false)
UNSUPPORTED_HEAVY_AVATAR 400 The source video contains a real avatar
NOT_FOUND 404 video_id does not exist, or the video is not one you own
INSUFFICIENT_CREDIT 429 / 403 Insufficient credit balance (429), or a plan below Standard / Premium (403)
SIMULTANEOUS_GENERATE_LIMIT 503 The concurrency limit shared with video generation was exceeded
UNKNOWN_ERROR 500 Internal server error
  • If authentication fails, a 401 / 403 error is returned separately from the errors above
Terminal window
curl https://api.no-lang.com/v1/videos/YOUR_VIDEO_ID/conversions/ \
-H "Authorization: Bearer YOUR_API_KEY"
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/YOUR_VIDEO_ID/conversions/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"language": "en"}'
Terminal window
curl -X POST https://api.no-lang.com/v1/videos/YOUR_VIDEO_ID/conversions/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"aspect_ratio": "9:16"}'

GET /video-settings/

Retrieves a list of available video settings.

  • Permission: API key authentication required
  • Rate Limit: Up to 5 requests per 10 seconds
JSON
{
"results": [
{
"video_setting_id": "123e4567-e89b-12d3-a456-426614174000",
"updated_at": "2024-01-15T10:00:00Z",
"created_at": "2024-01-10T10:00:00Z",
"title": "Educational content settings",
"request_fields": ["text"]
},
{
"video_setting_id": "223e4567-e89b-12d3-a456-426614174001",
"updated_at": "2024-01-14T09:00:00Z",
"created_at": "2024-01-09T09:00:00Z",
"title": "Presentation conversion settings",
"request_fields": ["pdf_file"]
}
],
"has_next": false,
"total_count": 5,
"page": 1,
"items_per_page": 50
}

Sample code

nolang_api.py
import os
import time
import requests
from typing import Optional
class NoLangAPI:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.no-lang.com/v1"
self.headers = {"Authorization": f"Bearer {api_key}"}
def generate_video_from_text(self, video_setting_id: str, text: str) -> dict:
"""Generate a video from text"""
url = f"{self.base_url}/videos/generate/"
data = {
"video_setting_id": video_setting_id,
"text": text
}
response = requests.post(url, headers=self.headers, data=data)
response.raise_for_status()
return response.json()
def generate_video_from_pdf(self, video_setting_id: str, pdf_path: str) -> dict:
"""Generate a video from a PDF"""
url = f"{self.base_url}/videos/generate/"
data = {"video_setting_id": video_setting_id}
files = {"pdf_file": open(pdf_path, "rb")}
response = requests.post(url, headers=self.headers, data=data, files=files)
response.raise_for_status()
return response.json()
def get_video_status(self, video_id: str) -> dict:
"""Retrieve the status of a video"""
url = f"{self.base_url}/videos/{video_id}/"
response = requests.get(url, headers=self.headers)
response.raise_for_status()
return response.json()
def get_convert_options(self, video_id: str) -> dict:
"""Retrieve whether a video can be converted and the values you can convert it to"""
url = f"{self.base_url}/videos/{video_id}/conversions/"
response = requests.get(url, headers=self.headers)
response.raise_for_status()
return response.json()
def convert_video(
self,
video_id: str,
language: Optional[str] = None,
aspect_ratio: Optional[str] = None,
) -> dict:
"""Generate a new video by converting an existing video to another language or aspect ratio"""
url = f"{self.base_url}/videos/{video_id}/conversions/"
payload = {}
if language:
payload["language"] = language
if aspect_ratio:
payload["aspect_ratio"] = aspect_ratio
response = requests.post(url, headers=self.headers, json=payload)
response.raise_for_status()
return response.json()
def wait_for_completion(self, video_id: str, timeout: int = 600) -> Optional[str]:
"""Wait for video generation to finish and return the download URL"""
start_time = time.time()
while time.time() - start_time < timeout:
status_data = self.get_video_status(video_id)
if status_data["status"] == "completed":
return status_data["download_url"]
elif status_data["status"] == "failed":
raise Exception("Video generation failed")
time.sleep(10) # Poll every 10 seconds
raise TimeoutError("Video generation timed out")
# Example usage
api = NoLangAPI(os.environ["NOLANG_API_KEY"])
# Generate a video from text
result = api.generate_video_from_text(
video_setting_id="123e4567-e89b-12d3-a456-426614174000",
text="Let's learn the basics of Python programming"
)
print(f"Video ID: {result['video_id']}")
# Wait for completion and download
download_url = api.wait_for_completion(result['video_id'])
print(f"Download URL: {download_url}")
# Convert the generated video to English + vertical (9:16)
options = api.get_convert_options(result['video_id'])
if options["is_convertible"] and "en" in options["available_languages"]:
converted = api.convert_video(result['video_id'], language="en", aspect_ratio="9:16")
converted_url = api.wait_for_completion(converted['video_id'])
print(f"Converted URL: {converted_url}")
nolang_api.js
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
class NoLangAPI {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.no-lang.com/v1';
this.headers = { 'Authorization': `Bearer ${apiKey}` };
}
async generateVideoFromText(videoSettingId, text) {
const formData = new FormData();
formData.append('video_setting_id', videoSettingId);
formData.append('text', text);
const response = await axios.post(
`${this.baseUrl}/videos/generate/`,
formData,
{
headers: {
...this.headers,
...formData.getHeaders()
}
}
);
return response.data;
}
async generateVideoFromPDF(videoSettingId, pdfPath) {
const formData = new FormData();
formData.append('video_setting_id', videoSettingId);
formData.append('pdf_file', fs.createReadStream(pdfPath));
const response = await axios.post(
`${this.baseUrl}/videos/generate/`,
formData,
{
headers: {
...this.headers,
...formData.getHeaders()
}
}
);
return response.data;
}
async getVideoStatus(videoId) {
const response = await axios.get(
`${this.baseUrl}/videos/${videoId}/`,
{ headers: this.headers }
);
return response.data;
}
async getConvertOptions(videoId) {
const response = await axios.get(
`${this.baseUrl}/videos/${videoId}/conversions/`,
{ headers: this.headers }
);
return response.data;
}
async convertVideo(videoId, { language, aspectRatio } = {}) {
const payload = {};
if (language) payload.language = language;
if (aspectRatio) payload.aspect_ratio = aspectRatio;
const response = await axios.post(
`${this.baseUrl}/videos/${videoId}/conversions/`,
payload,
{
headers: {
...this.headers,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
async waitForCompletion(videoId, timeout = 600000) {
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const status = await this.getVideoStatus(videoId);
if (status.status === 'completed') {
return status.download_url;
} else if (status.status === 'failed') {
throw new Error('Video generation failed');
}
// Wait 10 seconds
await new Promise(resolve => setTimeout(resolve, 10000));
}
throw new Error('Video generation timed out');
}
}
// Example usage
(async () => {
const api = new NoLangAPI(process.env.NOLANG_API_KEY);
try {
// Generate a video from text
const result = await api.generateVideoFromText(
'123e4567-e89b-12d3-a456-426614174000',
"Explain asynchronous processing in JavaScript"
);
console.log(`Video ID: ${result.video_id}`);
// Wait for completion
const downloadUrl = await api.waitForCompletion(result.video_id);
console.log(`Download URL: ${downloadUrl}`);
// Convert the generated video to English + vertical (9:16)
const options = await api.getConvertOptions(result.video_id);
if (options.is_convertible && options.available_languages.includes('en')) {
const converted = await api.convertVideo(result.video_id, {
language: 'en',
aspectRatio: '9:16'
});
const convertedUrl = await api.waitForCompletion(converted.video_id);
console.log(`Converted URL: ${convertedUrl}`);
}
} catch (error) {
console.error('Error:', error.message);
}
})();

Troubleshooting

Issue Cause Solution
401 Unauthorized Invalid API key Check the API key, or regenerate it
429 Too Many Requests Rate limit exceeded Wait until the rate limit resets, then retry
Video generation is slow Peak load period Run it during off-peak hours
File upload error File size exceeded Reduce the file size
403 error on video conversion The video conversion API is not available on the Free plan Upgrade to the Standard / Premium plan
LANGUAGE_NOT_SUPPORTED_BY_VOICES error A speaker in the source video does not support the specified language Choose from available_languages in GET /videos/{video_id}/conversions/
CONVERT_NO_CHANGE error The same language and aspect ratio as the source video are specified Specify a value different from the source video
API Reference