/api
All API endpoints require authentication via API token. Token can be provided in two ways:
Authorization: Bearer <your_token>
?token=<your_token>&projectId=<project_id>
Generate i18n access code (TypeScript/JavaScript) from project translations.
URL: /api/gen
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectId | number | Yes | Project ID |
| codeLanguage | string | Yes | Target code language. Supported: typescript, javascript, java, kotlin, swift, dart, python, rust, go, json |
| token | string | Yes* | API token (*if not in Authorization header) |
Type: text/plain
Returns generated code as plain text. The code includes:
SUPPORT_LANGUAGES arraydefaultLanguage stringtexts object containing all translation texts organized by key and languageKeys object with key constantsT class with nested accessor classestestAllKeys, testAllLanguages) for validating translations// Auto-generated by string.fit at 2026-05-28T01:45:15.149Z. Don't modify me manually.
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";
dayjs.extend(utc);
dayjs.extend(timezone);
export const SUPPORT_LANGUAGES = ["en-US", "zh-CN"];
export const defaultLanguage = "en-US";
// MARK: - Test Functions
export function testAllKeys(t: T): void {
console.log(t.sign.in.login.button);
// ... more keys
}
export function testAllLanguages(): void {
for (const lang of SUPPORT_LANGUAGES) {
const t = T.create(lang);
console.log(`Testing ${lang}:`);
testAllKeys(t);
}
}
export const texts = { /* all translation texts by key and language */ };
export const Keys = { /* key constants */ };
// ... T class and nested classes
// Main call
testAllLanguages();
200 Success 401 Unauthorized
Import translation strings into a project.
URL: /api/import
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectId | number | Yes | Project ID |
| token | string | Yes* | API token (*if not in Authorization header) |
Authorization: Bearer <token> (if token not in query)
Content-Type: application/json
{
"strings": [
{
"key": "sign.in.login.button",
"translations": {
"zh-CN": {
"content": "登录",
"params": []
},
"en-US": {
"content": "Login",
"params": []
}
}
}
]
}
Translation value can be either a simple string or an object with content and params:
// Simple string form
"content": "Hello World"
// Object form with params
{
"content": "Hello @{name}, you have @{count} messages",
"params": [
{ "paramName": "name", "type": "simple" },
{ "paramName": "count", "type": "number", "numberFormat": { "style": "decimal" } }
]
}
Note: Parameter placeholders use @{paramName} syntax, not {paramName}.
The params array defines placeholders in the translation text. Each parameter has:
| Field | Type | Required | Description |
|---|---|---|---|
| paramName | string | Yes | Name of the parameter, used in the content as @{paramName} |
| type | string | Yes | Parameter type (see below) |
| list | array | No | Required for select and selectordinal types |
| numberFormat | object | No | Format options for number type |
| style | string | No | Style for date, time, duration types |
| format | string | No | Format pattern string |
| zoneId | string | No | Timezone ID for date, time types (e.g., "Asia/Shanghai") |
| Type | Required Fields | Optional Fields | Example |
|---|---|---|---|
simple |
paramName, type | — | { "paramName": "name", "type": "simple" } |
number |
paramName, type | numberFormat | { "paramName": "count", "type": "number", "numberFormat": { "style": "decimal" } } |
select |
paramName, type, list | — | { "paramName": "gender", "type": "select", "list": [{ "value": "male", "text": "He" }, { "value": "female", "text": "She" }] } |
selectordinal |
paramName, type, list | — | Same as select, but for ordinal numbers (1st, 2nd, 3rd) |
plural |
paramName, type, list | — | Same as select, but for pluralization rules |
date |
paramName, type | style, format, zoneId | { "paramName": "startDate", "type": "date", "style": "medium", "zoneId": "Asia/Shanghai" } |
time |
paramName, type | style, format, zoneId | { "paramName": "startTime", "type": "time", "style": "short", "zoneId": "Asia/Shanghai" } |
duration |
paramName, type | style | { "paramName": "elapsed", "type": "duration", "style": "short" } |
{
"value": string; // The option value (e.g., "male", "one", "other")
"text": string; // The display text for this option
}
{
style?: string; // e.g., "decimal", "currency", "percent"
unit?: string; // e.g., "kilogram", "meter", "byte"
precisionMode?: 'fixed' | 'max';
precisionLength?: number;
compact?: string; // e.g., "short", "long"
percent?: string; // e.g., "percent" (×100, appends %), "permille" (×1000, appends ‰)
currency?: string; // e.g., "USD", "CNY"
format?: string;
}
{
"strings": [
{
"key": "user.greeting",
"translations": {
"zh-CN": {
"content": "你好 @{name},今天是 @{date}",
"params": [
{ "paramName": "name", "type": "simple" },
{ "paramName": "date", "type": "date", "style": "full", "zoneId": "Asia/Shanghai" }
]
},
"en-US": {
"content": "Hello @{name}, today is @{date}",
"params": [
{ "paramName": "name", "type": "simple" },
{ "paramName": "date", "type": "date", "style": "full", "zoneId": "America/New_York" }
]
}
}
},
{
"key": "product.count",
"translations": {
"zh-CN": "有 @{count} 个产品",
"en-US": "@{count} products"
}
},
{
"key": "order.items",
"translations": {
"zh-CN": {
"content": "您有 @{count}",
"params": [
{ "paramName": "count", "type": "plural", "list": [
{ "value": "one", "text": "1 个项目" },
{ "value": "other", "text": "# 个项目" }
]}
]
},
"en-US": {
"content": "You have @{count}",
"params": [
{ "paramName": "count", "type": "plural", "list": [
{ "value": "one", "text": "1 item" },
{ "value": "other", "text": "# items" }
]}
]
}
}
}
]
}
Note: Placeholders use @{paramName} syntax. For plural and select types, use list to define options with value (matching rule like one, other following ICU plural rules) and text (display text). The # symbol in text is a placeholder for the original numeric value — this is a model format, not an ICU message format string.
{
"code": 1000,
"message": "success",
"data": {
"imported": 10,
"totalStrings": 15,
"createdKeys": 5,
"skippedTranslations": [
{
"key": "sign.in.login.button",
"languages": ["en-US"]
}
],
"conflicts": []
}
}
| Field | Type | Description |
|---|---|---|
| imported | number | Number of translations inserted |
| totalStrings | number | Total strings in request |
| createdKeys | number | New keys created |
| skippedTranslations | array | Translations skipped (already exist) |
| conflicts | array | Keys that could not be imported |
{
key: string; // The conflicting key
reason: string; // Reason for conflict
suggestedKey?: string; // Suggested alternative key
}
200 Success 400 Bad Request 401 Unauthorized
. and _ allowed{
"code": 401,
"message": "Invalid or missing token"
}
{
"code": 400,
"message": "projectId is required"
}
curl -s -H "Authorization: Bearer <token>" \
"https://string.fit/api/gen?projectId=33&codeLanguage=typescript" \
-o T.ts
curl -s -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
"https://string.fit/api/import?projectId=33" \
-d '{
"strings": [
{
"key": "hello.world",
"translations": {
"zh-CN": "你好,世界",
"en-US": "Hello, World"
}
}
]
}'
const response = await fetch(
`https://string.fit/api/gen?projectId=33&codeLanguage=typescript`,
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
const code = await response.text();
console.log(code);
const response = await fetch(
`https://string.fit/api/import?projectId=33`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
strings: [{
key: 'hello.world',
translations: {
'zh-CN': { content: '你好,世界' },
'en-US': { content: 'Hello, World' }
}
}]
})
}
);
const result = await response.json();
console.log(result);