Publishing API
REST API reference for publishing label profiles to the CDN and managing drafts.
Publish a profile
Generates a content-addressed label file, uploads it to R2, and purges the Cloudflare CDN cache. After publishing, changes propagate globally in ~60 seconds.
POST /v1/profiles/:name/publish
Authorization: Bearer i18n_at_...
{
"profile": "en:prod",
"url": "https://cdn.i18n.shipeasy.ai/v1/labels/i18n_pk_abc123/en:prod/index.json",
"hash": "sha256-abc123...",
"keyCount": 142,
"publishedAt": "2026-04-11T10:00:00Z"
}
Publish specific chunks
POST /v1/profiles/:name/publish
Authorization: Bearer i18n_at_...
Content-Type: application/json
{
"chunks": ["index", "checkout"]
}
Omit chunks to publish all chunks.
Publish multiple profiles
POST /v1/publish/batch
Authorization: Bearer i18n_at_...
Content-Type: application/json
{
"profiles": ["en:prod", "fr:prod", "de:prod"]
}
Profiles are published in parallel. Returns an array of publish results.
{
"results": [
{ "profile": "en:prod", "status": "ok", "keyCount": 142 },
{ "profile": "fr:prod", "status": "ok", "keyCount": 118 },
{ "profile": "de:prod", "status": "error", "error": "profile_not_found" }
]
}
Drafts
Drafts let you stage changes to a profile before they go live. The in-browser editor creates drafts automatically. i18n translate also creates drafts.
List drafts
GET /v1/profiles/:name/drafts
Authorization: Bearer i18n_at_...
{
"data": [
{
"id": "draft_abc123",
"name": "Q1 marketing copy",
"profile": "fr:prod",
"keyCount": 24,
"status": "pending",
"createdAt": "2026-04-10T09:00:00Z",
"createdBy": "user_xyz"
}
]
}
Create a draft
POST /v1/profiles/:name/drafts
Authorization: Bearer i18n_at_...
Content-Type: application/json
{
"name": "Spring promo copy",
"keys": {
"nav.home": "Accueil",
"nav.signIn": "Se connecter",
"checkout.submit": "Passer la commande"
}
}
{
"id": "draft_def456",
"name": "Spring promo copy",
"profile": "fr:prod",
"keyCount": 3,
"status": "pending",
"previewUrl": "https://app.i18n.shipeasy.ai/dashboard/profiles/fr:prod?draft=draft_def456",
"createdAt": "2026-04-11T10:00:00Z"
}
Get draft diff
Returns the keys changed by this draft relative to the live profile:
GET /v1/drafts/:id/diff
Authorization: Bearer i18n_at_...
{
"id": "draft_def456",
"profile": "fr:prod",
"changes": [
{
"key": "nav.home",
"before": "Maison",
"after": "Accueil"
},
{
"key": "nav.signIn",
"before": null,
"after": "Se connecter"
}
]
}
before: null means the key had no value before (new translation).
Publish a draft
Merges draft values into the live profile and publishes:
POST /v1/drafts/:id/publish
Authorization: Bearer i18n_at_...
{
"id": "draft_def456",
"status": "published",
"publishedAt": "2026-04-11T10:05:00Z",
"keysUpdated": 3
}
Discard a draft
DELETE /v1/drafts/:id
Authorization: Bearer i18n_at_...
{ "deleted": true }
CDN label files
Published label files are served from the CDN at:
https://cdn.i18n.shipeasy.ai/v1/labels/{i18n_pk_key}/{profile}/{chunk}.json
These files are public and unauthenticated — they contain only your translated string values, not account metadata or credentials.
File format
{
"v": 1,
"profile": "en:prod",
"chunk": "index",
"hash": "sha256-abc123...",
"publishedAt": "2026-04-11T10:00:00Z",
"keys": {
"nav.home": "Home",
"nav.signIn": "Sign in",
"footer.privacy": "Privacy Policy"
}
}
Cache behavior
CDN files use Cache-Control: public, max-age=3600, stale-while-revalidate=86400. After a publish, the cache is purged via Cloudflare Cache API — changes propagate in ~60 seconds.
The loader script (cdn.i18n.shipeasy.ai/v1/loader.js) handles CDN fetching automatically. You only need to call the CDN directly if you're building a custom integration.