Use this API to upload new source files, replace outdated ones, track translation progress, and download completed translations.
Whether you’re managing a single file or automating a continuous localization workflow, this API gives you full control over the content you send for translation and how you receive the translations.
API Quick Links
Endpoints
How the PTC API Identifies and Organizes Source Files
The PTC API uses a flexible system based on file tags and file paths. These parameters work together to ensure every file you upload, update, or request is clearly defined and easy to manage.
File Tags
File tags are a flexible way to group and organize source files in translation projects. You can use them like categories to match your workflow needs. For example, file tags can show:
- Version control:
v1.0
,beta
,production
- Feature branches:
user-auth
,dashboard-redesign
- Application context:
mobile-app
,admin-panel
,marketing
- Team ownership:
frontend-team
,content-team
- Workflow state:
approved
,pending-review
,priority-high
File tag names are optional in most API operations. However, every source file always has at least one tag. A default file tag is automatically created and assigned when a project is set up. This default behavior keeps projects organized even in simple setups, while still allowing you to build more advanced tagging structures when needed.
File Tag Name + File Path
Each source file is uniquely identified by the combination of its file tag name and file path.
- If you do not provide a custom file tag when uploading or processing a file, the default tag will be assigned automatically.
- A file’s tag name + path together define its identity. This combination ensures each file is unique within your project, even if different versions or contexts share the same file path.
Query Parameters
When retrieving a specific file, related endpoints can accept query parameters such as:
file_tag_name
– The tag associated with the filefile_path
– The path to the file
These parameters allow you to precisely locate and retrieve the correct files from your project.
List All Source Files in The Project
Lists all the source files in your project, with options to filter, sort, and paginate the results. This is useful when you want to browse your files, check their status, or find specific files based on tag, path, or upload method.
HTTP Request
GET https://app.ptc.wpml.org/api/v1/source_files
Parameters
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
page | integer | No | 1 | The page number for pagination. Must be greater than 0. |
per_page | integer | No | 50 | The number of items per page. Must be greater than 0. |
order_by | string | No | created_at | The field to sort by. Allowed values: id , created_at , updated_at . |
sort | string | No | desc | The direction of sorting. Allowed values: asc , desc . |
file_path | string | No | – | Filters by exact file path. |
upload_origin | string | No | – | Filters by how the file was uploaded. Allowed values include: git , manual , api . |
Responses
Success Response
- Code:
200 OK
- Content Type:
application/json
{
"source_files": [
{
"id": 123,
"file_path": "locales/en.po",
"translation_path": "locales/{{lang}}.po",
"additional_translation_files": ["locales/{{lang}}.mo"],
"status": "completed",
"upload_origin": "git",
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T14:20:00.000Z",
"file_tag": {
"id": 456,
"name": "frontend"
},
"download_url": "https://app.ptc.wpml.org/api/v1/source_files/download_translations?file_path=locale/en.po&file_tag_name=frontend"
}
],
"pagination": {
"page": 1,
"per_page": 50,
"total": 150,
"total_pages": 3,
"has_next_page": true,
"has_previous_page": false
}
}
Response Schema
Source File Object:
Field | Type | Description |
---|---|---|
id | integer | The unique identifier for the source file. |
file_path | string | The path to the source file within the project. |
translation_path | string | The pattern for where translated files should be saved. |
additional_translation_files | array[string] | The paths for any additional output files. |
status | string | The current processing status of the source file. |
upload_origin | string | How the file was uploaded (git , manual , api ). |
created_at | string | An ISO 8601 timestamp indicating when the source file was originally created. |
updated_at | string | An ISO 8601 timestamp indicating when the source file was last updated. |
file_tag | object | Information about the file tag. |
file_tag.id | integer | The file tag identifier. |
file_tag.name | string | The file tag name. |
download_url | string | The URL to download translations for this source file. |
Pagination Object:
Field | Type | Description |
---|---|---|
page | integer | The current page number. |
per_page | integer | The number of items per page. |
total | integer | The total number of source files. |
total_pages | integer | The total number of pages. |
has_next_page | boolean | Whether there is a next page available. |
has_previous_page | boolean | Whether there is a previous page available. |
Error Responses
Unauthorized
- Code:
401 Unauthorized
{
"error": "Unauthorized access. Please provide a valid API token."
}
Forbidden
- Code:
403 Forbidden
{
"error": "Access denied. Insufficient permissions."
}
Invalid Parameters
- Code:
422 Unprocessable Entity
{
"error": "Invalid parameters provided."
}
Example Requests
Basic request:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files" \
-H "Content-Type: application/json"
Filtered request:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files?file_tag_name=frontend&page=1&per_page=25&order_by=updated_at&sort=desc" \
-H "Content-Type: application/json"
Code Examples
const response = await fetch('https://app.ptc.wpml.org/api/v1/source_files?file_tag_name=frontend&page=1&per_page=25', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
console.log(data);
import requests
headers = {
'Content-Type': 'application/json'
}
params = {
'file_tag_name': 'frontend',
'page': 1,
'per_page': 25
}
response = requests.get('https://app.ptc.wpml.org/api/v1/source_files',
headers=headers, params=params)
data = response.json()
print(data)
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://app.ptc.wpml.org/api/v1/source_files?file_tag_name=frontend&page=1&per_page=25',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
$data = json_decode($response, true);
print_r($data);
?>
const axios = require('axios');
const response = await axios.get('https://app.ptc.wpml.org/api/v1/source_files', {
headers: {
'Content-Type': 'application/json'
},
params: {
file_tag_name: 'frontend',
page: 1,
per_page: 25
}
});
console.log(response.data);
Get Translation Strings
Retrieves all translatable strings from a specific source file, along with their existing translations in all target languages.
This endpoint is useful for fetching content that needs to be translated or has already been translated. The source file is identified by file_path
and file_tag_name
.
HTTP Request
GET https://app.ptc.wpml.org/api/v1/source_files/translation_strings
Parameters
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
file_path | string | Yes | – | The path to the source file within the project. |
file_tag_name | string | No | – | The file tag name. If not provided, the project’s default tag is used. |
page | integer | No | 1 | The page number for pagination (used as a cursor). Must be greater than 0. |
q | string | No | – | The search query to filter translation strings by their source text. |
Responses
Success Response
- Code:
200 OK
- Content Type:
application/json
{
"total_strings_count": 1250,
"translation_strings": [
{
"source": "Welcome to our application",
"translations": {
"es": "Bienvenido a nuestra aplicación",
"fr": "Bienvenue dans notre application",
"de": "Willkommen in unserer Anwendung"
}
},
{
"source": "Login",
"translations": {
"es": "Iniciar sesión",
"fr": "Connexion",
"de": "Anmelden"
}
}
],
"cursor": 1
}
Response Schema
Field | Type | Description |
---|---|---|
total_strings_count | integer | The total number of translatable strings in the source file. |
translation_strings | array[object] | The array of translation string objects (paginated, max 500 per page). |
translation_strings[].source | string | The original source text to be translated. |
translation_strings[].translations | object | A hash of translations where the keys are language ISO codes and the values are the translated text. |
cursor | integer | The current page cursor used for pagination. |
Error Responses
Source File Not Found
- Code:
404 Not Found
{
"error": "Source file not found"
}
Unauthorized
- Code:
401 Unauthorized
{
"error": "Unauthorized access. Please provide a valid API token."
}
Forbidden
- Code:
403 Forbidden
{
"error": "Access denied. Insufficient permissions."
}
Invalid Parameters
- Code:
422 Unprocessable Entity
{
"error": "Invalid parameters provided."
}
Example Requests
Basic request:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files/translation_strings?file_path=locales/en.po" \
-H "Content-Type: application/json"
A request with file tag:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files/translation_strings?file_path=locales/en.po&file_tag_name=frontend" \
-H "Content-Type: application/json"
A request with pagination and search:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files/translation_strings?file_path=locales/en.po&file_tag_name=frontend&page=2&q=welcome" \
-H "Content-Type: application/json"
Code Examples
const response = await fetch('https://app.ptc.wpml.org/api/v1/source_files/translation_strings?file_path=locales/en.po&file_tag_name=frontend&page=1&q=login', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
console.log(data);
import requests
headers = {
'Content-Type': 'application/json'
}
params = {
'file_path': 'locales/en.po',
'file_tag_name': 'frontend',
'page': 1,
'q': 'login'
}
response = requests.get('https://app.ptc.wpml.org/api/v1/source_files/translation_strings',
headers=headers, params=params)
data = response.json()
print(data)
<?php
$params = http_build_query([
'file_path' => 'locales/en.po',
'file_tag_name' => 'frontend',
'page' => 1,
'q' => 'login'
]);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.ptc.wpml.org/api/v1/source_files/translation_strings?{$params}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
$data = json_decode($response, true);
print_r($data);
?>
const axios = require('axios');
const response = await axios.get('https://app.ptc.wpml.org/api/v1/source_files/translation_strings', {
headers: {
'Content-Type': 'application/json'
},
params: {
file_path: 'locales/en.po',
file_tag_name: 'frontend',
page: 1,
q: 'login'
}
});
console.log(response.data);
Create the Source File
Registers a new source file in your project so it’s ready for translation.
This endpoint creates the file entry and sets up its translation configuration, but does not attach the actual file content.
After creating the file, you’ll need to use the Process the Source File endpoint to upload the content and start the translation process.
HTTP Request
POST https://app.ptc.wpml.org/api/v1/source_files
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
file_path | string | Yes | The path where the source file should be stored in the project. Must have a supported extension. |
output_file_path | string | Yes | The output path pattern for translated files. Use {{lang}} as a placeholder for the language code. |
translations | array[object] | No | The pre-existing translation files to upload alongside the source file. These files will be stored as provided, and their strings will not be re-translated by PTC. Note that providing existing translations is not recommended, as PTC produces better results when it can use your project’s full context and translate from scratch. |
translations[].target_language_iso | string | Yes | The ISO code of the target language for this translation. You can find the full list of supported languages and their ISO codes in the List All Target Languages endpoint. |
translations[].file | file | Yes | The translation file to upload. |
additional_translation_files | array[object] | No | Additional output file configurations for specific formats. To see which formats support additional output files, refer to the List Supported File Formats endpoint. For unsupported formats, this field will be ignored. |
additional_translation_files[].type | string | Yes | See supported file formats for more details. |
additional_translation_files[].path | string | Yes | The path pattern for the file. |
Responses
Success Response
- Code:
201 Created
- Content Type:
application/json
{
"source_file": {
"id": 123,
"file_path": "src/locales/en.json",
"created_at": "2024-01-15T10:30:00.000Z",
"file_tag": {
"id": 456,
"name": "frontend"
}
}
}
Response Schema
Field | Type | Description |
---|---|---|
source_file.id | integer | The unique identifier for the created source file. |
source_file.file_path | string | The path of the source file within the project. |
source_file.created_at | string | An ISO 8601 timestamp indicating when the source file was originally created. |
source_file.file_tag.id | integer | The file tag identifier. |
source_file.file_tag.name | string | The file tag name. |
Error Responses
Validation Failed
- Code:
422 Unprocessable Entity
{
"success": false,
"error": "Source file creation failed"
}
Unauthorized
- Code:
401 Unauthorized
{
"error": "Unauthorized access. Please provide a valid API token."
}
Forbidden
- Code:
403 Forbidden
{
"error": "Access denied. Insufficient permissions."
}
Example Requests
Basic source file creation:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files" \
-H "Content-Type: multipart/form-data" \
-F "file_path=src/locales/en.json" \
-F "output_file_path=src/locales/{lang}.json" \
-F "file_tag_name=frontend"
Request with callback URL:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files" \
-H "Content-Type: multipart/form-data" \
-F "file_path=src/locales/messages.po" \
-F "output_file_path=locales/{lang}/messages.po" \
-F "callback_url=https://your-app.com/webhooks/translation-complete"
Request with pre-existing translations:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files" \
-H "Content-Type: multipart/form-data" \
-F "file_path=src/messages.json" \
-F "output_file_path=locales/{lang}/messages.json" \
-F "translations[0][target_language_iso]=es" \
-F "translations[0][file]=@spanish_translations.json" \
-F "translations[1][target_language_iso]=fr" \
-F "translations[1][file]=@french_translations.json"
Request with additional output files:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files" \
-H "Content-Type: multipart/form-data" \
-F "file_path=src/messages.po" \
-F "output_file_path=locales/{lang}/messages.po" \
-F "additional_translation_files[mo]=locales/{lang}/messages.mo" \
-F "additional_translation_files[json]=locales/{lang}/messages.json"
Code Examples
const formData = new FormData();
formData.append('file_path', 'src/locales/en.json');
formData.append('output_file_path', 'src/locales/{lang}.json');
formData.append('file_tag_name', 'frontend');
formData.append('callback_url', 'https://your-app.com/webhooks/complete');
const response = await fetch('https://app.ptc.wpml.org/api/v1/source_files', {
method: 'POST',
body: formData
});
const data = await response.json();
console.log(data);
import requests
data = {
'file_path': 'src/locales/en.json',
'output_file_path': 'src/locales/{lang}.json',
'file_tag_name': 'frontend',
'callback_url': 'https://your-app.com/webhooks/complete'
}
response = requests.post('https://app.ptc.wpml.org/api/v1/source_files', data=data)
result = response.json()
print(result)
<?php
$data = [
'file_path' => 'src/locales/en.json',
'output_file_path' => 'src/locales/{lang}.json',
'file_tag_name' => 'frontend',
'callback_url' => 'https://your-app.com/webhooks/complete'
];
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://app.ptc.wpml.org/api/v1/source_files',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
print_r($result);
?>
const axios = require('axios');
const FormData = require('form-data');
const formData = new FormData();
formData.append('file_path', 'src/locales/en.json');
formData.append('output_file_path', 'src/locales/{lang}.json');
formData.append('file_tag_name', 'frontend');
formData.append('callback_url', 'https://your-app.com/webhooks/complete');
const response = await axios.post('https://app.ptc.wpml.org/api/v1/source_files', formData, {
headers: formData.getHeaders()
});
console.log(response.data);
{
"source_file_id": 123,
"status": "completed",
"file_tag_name": "frontend",
"download_url": "https://app.ptc.wpml.org/api/v1/source_files/download_translations?file_path=src/locales/en.json&file_tag_name=frontend",
"file_path": "src/locales/en.json"
}
Process the Source File
Uploads content to an existing source file and starts the translation process.
This endpoint replaces the file’s current content, updates the stored translatable strings, and starts automatic translation.
To use this endpoint, the source file must already exist in the project. If you haven’t created it yet, see Create the Source File.
HTTP Request
PUT https://app.ptc.wpml.org/api/v1/source_files/process
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
file | file | Yes | The source file to upload. The file content is validated to ensure it matches its declared extension. For example, if the file extension is .json , the uploaded content must be valid JSON. |
file_path | string | Yes | The path to the existing source file in the project that should be updated. |
file_tag_name | string | No | The name of the file tag associated with the source file. If not provided, the project’s default file tag is used. |
callback_url | string | No | The URL that receives webhook notifications when file processing is complete. |
Responses
Success Response
- Code:
200 OK
- Content Type:
application/json
{
"source_file": {
"id": 123,
"file_path": "src/locales/en.json",
"created_at": "2024-01-15T10:30:00.000Z",
"file_tag": {
"id": 456,
"name": "frontend"
}
}
}
Response Schema
Field | Type | Description |
---|---|---|
source_file.id | integer | The unique identifier for the processed source file. |
source_file.file_path | string | The path of the source file within the project. |
source_file.created_at | string | An ISO 8601 timestamp indicating when the source file was originally created. |
source_file.file_tag.id | integer | The file tag identifier. |
source_file.file_tag.name | string | The file tag name. |
Error Responses
Source File Not Found
- Code:
422 Unprocessable Entity
{
"errors": {
"file": ["File format is invalid or not supported"]
}
}
Unauthorized
- Code:
401 Unauthorized
{
"error": "Unauthorized access. Please provide a valid API token."
}
Forbidden
- Code:
403 Forbidden
{
"error": "Access denied. Insufficient permissions."
}
Workflow
- Prerequisite: The source file must already be created via Create the Source File.
- File Upload: New content is uploaded and replaces the existing file content.
- Processing: The new translatable strings are extracted and automatically translated.
- Callback: An optional webhook notification is sent when processing finishes.
Webhook Callback
When a callback_url
is provided, PTC will send a POST
request to that URL when processing completes.
Callback request body:
{
"source_file_id": 123,
"status": "completed",
"file_tag_name": "frontend",
"download_url": "https://app.ptc.wpml.org/api/v1/source_files/download_translations?file_path=src/locales/en.json&file_tag_name=frontend",
"file_path": "src/locales/en.json"
}
Example Requests
Basic file processing:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files/process" \
-H "Content-Type: multipart/form-data" \
-F "file=@updated_translations.json" \
-F "file_path=src/locales/en.json" \
-F "file_tag_name=frontend"
Request with callback URL:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files/process" \
-H "Content-Type: multipart/form-data" \
-F "file=@messages.po" \
-F "file_path=locales/messages.po" \
-F "callback_url=https://your-app.com/webhooks/translation-complete"
Code Examples
const formData = new FormData();
const fileInput = document.getElementById('file-input');
formData.append('file', fileInput.files[0]);
formData.append('file_path', 'src/locales/en.json');
formData.append('file_tag_name', 'frontend');
formData.append('callback_url', 'https://your-app.com/webhooks/complete');
const response = await fetch('https://app.ptc.wpml.org/api/v1/source_files/process', {
method: 'POST',
body: formData
});
const data = await response.json();
console.log(data);
import requests
files = {'file': open('updated_translations.json', 'rb')}
data = {
'file_path': 'src/locales/en.json',
'file_tag_name': 'frontend',
'callback_url': 'https://your-app.com/webhooks/complete'
}
response = requests.post('https://app.ptc.wpml.org/api/v1/source_files/process',
files=files, data=data)
result = response.json()
print(result)
<?php
$file_path = 'updated_translations.json';
$post_data = [
'file' => new CURLFile($file_path),
'file_path' => 'src/locales/en.json',
'file_tag_name' => 'frontend',
'callback_url' => 'https://your-app.com/webhooks/complete'
];
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://app.ptc.wpml.org/api/v1/source_files/process',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_data,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
print_r($result);
?>
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const formData = new FormData();
formData.append('file', fs.createReadStream('updated_translations.json'));
formData.append('file_path', 'src/locales/en.json');
formData.append('file_tag_name', 'frontend');
formData.append('callback_url', 'https://your-app.com/webhooks/complete');
const response = await axios.post('https://app.ptc.wpml.org/api/v1/source_files/process', formData, {
headers: formData.getHeaders()
});
console.log(response.data);
Supported File Formats
The endpoint supports various translatable file formats including JSON, PO/POT, XLIFF, and Properties files, among others.
File format validation occurs during upload to ensure compatibility.
Use the List Supported File Formats endpoint to get the full list of supported formats.
Get the Translation Status
Retrieves the current translation progress for a specific source file, including how much is completed and its overall processing status.
This is useful for:
- Progress monitoring – Tracking translation progress for long-running jobs
- UI updates – Displaying completion percentages in your application
- Workflow integration – Triggering actions when translation reaches a defined threshold
HTTP Request
GET https://app.ptc.wpml.org/api/v1/source_files/translation_status
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
file_path | string | Yes | The path to the source file within the project. |
file_tag_name | string | No | The file tag name. If not provided, the project’s default file tag is used. |
Responses
Success Response
- Code:
200 OK
- Content Type:
application/json
{
"translation_status": {
"status": "completed",
"completeness": 100
}
}
Response Schema
Field | Type | Description |
---|---|---|
translation_status.status | string | The current processing status of the source file. See status values below. |
translation_status.completeness | number | The percentage of translated strings (0–100). Calculated as (completed_translatable_strings / total_translatable_strings) × 100 . |
Status Values
The status
field can contain the following values:
Status | Description |
---|---|
pending | The source file is waiting to be processed. |
processing | The translation is currently in progress. |
completed | All translations have been completed. |
failed | The translation process ran into errors. |
Error Responses
Source File Not Found
- Code:
404 Not Found
{
"error": "Source file not found"
}
Unauthorized
- Code:
401 Unauthorized
{
"error": "Unauthorized access. Please provide a valid API token."
}
Forbidden
- Code:
403 Forbidden
{
"error": "Access denied. Insufficient permissions."
}
Invalid Parameters
- Code:
422 Unprocessable Entity
{
"error": "Invalid parameters provided."
}
Example Requests
Basic request:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files/translation_status?file_path=locales/en.po" \
-H "Content-Type: application/json"
Request with file tag:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files/translation_status?file_path=locales/en.po&file_tag_name=frontend" \
-H "Content-Type: application/json"
Code Examples
const response = await fetch('https://app.ptc.wpml.org/api/v1/source_files/translation_status?file_path=locales/en.po&file_tag_name=frontend', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
console.log(`Translation ${data.translation_status.completeness}% complete`);
import requests
headers = {
'Content-Type': 'application/json'
}
params = {
'file_path': 'locales/en.po',
'file_tag_name': 'frontend'
}
response = requests.get('https://app.ptc.wpml.org/api/v1/source_files/translation_status',
headers=headers, params=params)
data = response.json()
print(f"Translation {data['translation_status']['completeness']}% complete")
<?php
$params = http_build_query([
'file_path' => 'locales/en.po',
'file_tag_name' => 'frontend'
]);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.ptc.wpml.org/api/v1/source_files/translation_status?{$params}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
$data = json_decode($response, true);
echo "Translation " . $data['translation_status']['completeness'] . "% complete";
?>
const axios = require('axios');
const response = await axios.get('https://app.ptc.wpml.org/api/v1/source_files/translation_status', {
headers: {
'Content-Type': 'application/json'
},
params: {
file_path: 'locales/en.po',
file_tag_name: 'frontend'
}
});
console.log(`Translation ${response.data.translation_status.completeness}% complete`);
Download All Translations
Downloads all translated files for a specific source file as a ZIP archive.
This endpoint creates and returns a compressed archive containing all translation files in the target languages for the specified source file.
If no translations are available for the file, the request will return a 404 Not Found error.
HTTP Request
GET https://app.ptc.wpml.org/api/v1/source_files/download_translations
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
file_path | string | Yes | The path to the source file within the project. |
file_tag_name | string | No | The file tag name. If not provided, the project’s default file tag is used. A source file is uniquely identified by the combination of file_path and file_tag_name . |
Responses
Success Response
- Code:
200 OK
- Content Type:
application/zip
- Response Body: Binary ZIP file containing translation files
- Headers:
Content-Type: application/zip
Content-Disposition: attachment; filename="translations-{source_file_id}.zip"
ZIP Archive Contents
The downloaded ZIP file contains:
- Translation files – One per target language for the specified source file
- Additional translation files – Additional generated files (if configured), placed at the root level following your configured paths
- File structure – Matches the configuration set during source file creation
Example ZIP structure:
translations-123.zip
├── locales/es.json
├── locales/fr.json
├── locales/de.json
├── locales/es.po
├── locales/fr.po
├── locales/de.po
├── locales/es.mo
├── locales/fr.mo
├── locales/de.mo
Error Responses
Source File Not Found
- Code:
404 Not Found
{
"error": "Source file not found"
}
No Translations Available
- Code:
404 Not Found
{
"error": "No translations are available for this source file"
}
Unauthorized
- Code:
401 Unauthorized
{
"error": "Unauthorized access. Please provide a valid API token."
}
Forbidden
- Code:
403 Forbidden
{
"error": "Access denied. Insufficient permissions."
}
Invalid Parameters
- Code:
422 Unprocessable Entity
{
"error": "Invalid parameters provided."
}
Example Requests
Basic request:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files/download_translations?file_path=locales/en.po" \
-H "Content-Type: application/json" \
-o translations.zip
Request with file tag:
curl -X GET "https://app.ptc.wpml.org/api/v1/source_files/download_translations?file_path=locales/en.po&file_tag_name=frontend" \
-H "Content-Type: application/json" \
-o frontend-translations.zip
Code Examples
const response = await fetch('https://app.ptc.wpml.org/api/v1/source_files/download_translations?file_path=locales/en.po&file_tag_name=frontend', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'translations.zip';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
}
import requests
headers = {
'Content-Type': 'application/json'
}
params = {
'file_path': 'locales/en.po',
'file_tag_name': 'frontend'
}
response = requests.get('https://app.ptc.wpml.org/api/v1/source_files/download_translations',
headers=headers, params=params)
if response.status_code == 200:
with open('translations.zip', 'wb') as f:
f.write(response.content)
print("Translations downloaded successfully")
<?php
$params = http_build_query([
'file_path' => 'locales/en.po',
'file_tag_name' => 'frontend'
]);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.ptc.wpml.org/api/v1/source_files/download_translations?{$params}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode === 200) {
file_put_contents('translations.zip', $response);
echo "Translations downloaded successfully";
}
?>
const axios = require('axios');
const fs = require('fs');
const response = await axios.get('https://app.ptc.wpml.org/api/v1/source_files/download_translations', {
headers: {
'Content-Type': 'application/json'
},
params: {
file_path: 'locales/en.po',
file_tag_name: 'frontend'
},
responseType: 'stream'
});
response.data.pipe(fs.createWriteStream('translations.zip'));
console.log('Translations downloaded successfully');
Upload Source Files in Bulk
Uploads a ZIP archive containing multiple translatable files. Each file in the archive is extracted, validated, and processed. Supported formats are identified automatically.
This is the batch version of Process Source File, designed to speed up large-scale updates.
Additional Information
- If a file matches an existing source file, it is updated with the new content, and translations are triggered again.
- If a file is supported but does not match any existing source file, it is added to the
not_found_files
list and ignored. - Files with unsupported formats are listed under
unsupported_files
and ignored. - Files with invalid content are also listed under
unsupported_files
and ignored. - Large archives may take longer to process. Files are processed one by one to manage resources, so it is best to split very large uploads (more than 100 files) into smaller batches. All files in the archive are set to translate automatically.
- The uploaded ZIP must be valid and readable. All files inside must be in a supported format. File names should not include special characters that could cause path issues.
- If a
callback_url
is provided, aPOST
request is sent for each processed source file with its results.
HTTP Request
POST https://app.ptc.wpml.org/api/v1/source_files/bulk
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
zip_file | file | Yes | A ZIP archive containing the source files to upload. It must be a valid ZIP file. |
file_tag_name | string | No | The file tag name to associate with all source files in the archive. If not specified, the project’s default file tag is used. Each source file is uniquely identified by the combination of file_path and file_tag_name . |
callback_url | string | No | The URL that receives webhook notifications when each file is processed. |
Expected ZIP File Structure
The ZIP file can contain source files in any directory structure. The directory structure is preserved, and files are processed recursively.
Example ZIP Structure:
source-files.zip
├── locales/
│ ├── messages-en.po
│ ├── validation-en.po
│ └── admin-en.po
├── frontend/
│ ├── components-en.json
│ └── pages-en.json
│ └── not-found-en.json
├── app-strings-en.properties
└── readme.txt (will be ignored)
Supported File Types:
- JSON:
.json
files - Gettext:
.po
,.pot
files - Properties:
.properties
files - YAML:
.yml
,.yaml
files - XML:
.xml
files - Strings:
.strings
files - XLIFF:
.xliff
,.xlf
files - CSV:
.csv
files - PHP:
.php
files
Responses
Success Response
- Code:
200 OK
- Content Type:
application/json
{
"success": true,
"processed_files": [
{
"id": 123,
"file_path": "locales/messages-en.po",
"created_at": "2024-01-15T10:30:00.000Z",
"file_tag": {
"id": 456,
"name": "backend"
}
},
{
"id": 124,
"file_path": "locales/validation-en.po",
"created_at": "2024-01-15T10:30:05.000Z",
"file_tag": {
"id": 456,
"name": "backend"
}
}
],
"unsupported_files": [
"readme.txt",
"config.ini"
],
"not_found_files": ["frontend/not-found-en.json"]
}
Response Schema
Field | Type | Description |
---|---|---|
success | boolean | Whether the bulk upload operation was successful. |
processed_files | array[object] | An array of source files that were successfully processed. |
processed_files[].id | integer | The unique identifier for the created source file. |
processed_files[].file_path | string | The path of the source file, preserving the original ZIP structure. |
processed_files[].created_at | string | An ISO 8601 timestamp indicating when the source file was created. |
processed_files[].file_tag | object | The file tag information. |
processed_files[].file_tag.id | integer | The file tag identifier. |
processed_files[].file_tag.name | string | The file tag name. |
unsupported_files | array[string] | An array of file names that are not in a supported format. |
not_found_files | array[string] | An array of supported files that did not match any existing source file and were ignored. |
Error Responses
Invalid ZIP File
- Code:
422 Unprocessable Entity
{
"success": false,
"error": "File format is invalid",
"processed_files": [],
"unsupported_files": []
}
Processing Failed
- Code:
422 Unprocessable Entity
{
"success": false,
"error": "Failed to process ZIP archive",
"processed_files": [],
"unsupported_files": []
}
Unauthorized
- Code:
401 Unauthorized
{
"error": "Unauthorized access. Please provide a valid API token."
}
Forbidden
- Code:
403 Forbidden
{
"error": "Access denied. Insufficient permissions."
}
Webhook Callback
When a callback_url
is provided, a POST
request is sent for each processed file.
Callback request body (per file):
{
"source_file_id": 123,
"status": "completed",
"file_tag_name": "backend",
"download_url": "https://app.ptc.wpml.org/api/v1/source_files/download_translations?file_path=locales/messages-en.po&file_tag_name=backend",
"file_path": "locale/en.po"
}
Example Requests
Basic bulk upload:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files/bulk" \
-H "Content-Type: multipart/form-data" \
-F "zip_file=@source-files.zip" \
-F "file_tag_name=backend"
Request with callback URL:
curl -X POST "https://app.ptc.wpml.org/api/v1/source_files/bulk" \
-H "Content-Type: multipart/form-data" \
-F "zip_file=@translations.zip" \
-F "file_tag_name=localization" \
-F "callback_url=https://your-app.com/webhooks/bulk-complete"
Code Examples
const formData = new FormData();
const fileInput = document.getElementById('zip-file-input');
formData.append('zip_file', fileInput.files[0]);
formData.append('file_tag_name', 'backend');
formData.append('callback_url', 'https://your-app.com/webhooks/complete');
const response = await fetch('https://app.ptc.wpml.org/api/v1/source_files/bulk', {
method: 'POST',
body: formData
});
const data = await response.json();
console.log(`Processed ${data.processed_files.length} files`);
console.log(`Unsupported files: ${data.unsupported_files.join(', ')}`);
import requests
files = {'zip_file': open('source-files.zip', 'rb')}
data = {
'file_tag_name': 'backend',
'callback_url': 'https://your-app.com/webhooks/complete'
}
response = requests.post('https://app.ptc.wpml.org/api/v1/source_files/bulk',
files=files, data=data)
result = response.json()
print(f"Processed {len(result['processed_files'])} files")
print(f"Unsupported files: {', '.join(result['unsupported_files'])}")
<?php
$zip_file_path = 'source-files.zip';
$post_data = [
'zip_file' => new CURLFile($zip_file_path),
'file_tag_name' => 'backend',
'callback_url' => 'https://your-app.com/webhooks/complete'
];
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://app.ptc.wpml.org/api/v1/source_files/bulk',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_data,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
echo "Processed " . count($result['processed_files']) . " files";
?>
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const formData = new FormData();
formData.append('zip_file', fs.createReadStream('source-files.zip'));
formData.append('file_tag_name', 'backend');
formData.append('callback_url', 'https://your-app.com/webhooks/complete');
const response = await axios.post('https://app.ptc.wpml.org/api/v1/source_files/bulk', formData, {
headers: formData.getHeaders()
});
console.log(`Processed ${response.data.processed_files.length} files`);