{
  "openapi": "3.1.0",
  "info": {
    "title": "smartest.email content languages",
    "version": "1.0.0",
    "description": "Content-language extension to the existing authenticated template/campaign API. Profile locale controls the interface and account emails; contentLocale belongs to one template/campaign. Changing UI language does not change saved content. Changing contentLocale changes language metadata and default direction, not the existing text. Omitted create locale remains unknown except that a campaign created with a template inherits that accessible template’s locale once. Explicit campaign locale wins. Omitted updates preserve the saved value, including when switching a template reference. Duplication retains the value. Unknown legacy content stays unknown until an explicit supported choice; no language is inferred from the author’s profile. New UI documents explicitly start in English. Known content languages are applied to HTML lang/dir, outbound Content-Language, automatic unsubscribe copy, new starter/block copy and the initial AI output language. Explicit per-block directions stay intact. An AI output-language override is request-only and never rewrites document metadata. Existing text is never automatically translated."
  },
  "servers": [
    {
      "url": "https://api.smartest.email/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/templates/": {
      "post": {
        "summary": "Create a template with a content language",
        "description": "Requires template:create. The locale is independent of the current UI language. Existing validation and limits also apply.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTemplate"
              },
              "example": {
                "name": "Welcome in English",
                "contentLocale": "en-gb",
                "mjmlContent": "<mjml><mj-body><mj-section><mj-column><mj-text>Welcome!</mj-text></mj-column></mj-section></mj-body></mjml>"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      }
    },
    "/templates/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Read the saved template language",
        "description": "Requires template:view. Templates may be owned by the workspace or public; campaigns must belong to the workspace.",
        "responses": {
          "200": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      },
      "patch": {
        "summary": "Set the template content language",
        "description": "Requires template:edit. Only owned resources can be updated. Campaign updates remain restricted to draft/paused states. Omit contentLocale for an unrelated edit; never send empty or null to preserve it. This does not translate text.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTemplate"
              },
              "example": {
                "contentLocale": "nl"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      }
    },
    "/templates/{id}/duplicate": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "summary": "Duplicate while preserving content language",
        "description": "Requires template:create.",
        "responses": {
          "201": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      }
    },
    "/campaigns/": {
      "post": {
        "summary": "Create a campaign with a content language",
        "description": "Requires campaign:create. The locale is independent of the current UI language. Existing validation and limits also apply.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaign"
              },
              "example": {
                "name": "English newsletter",
                "type": "regular",
                "contentLocale": "en-gb",
                "subject": "News for our readers"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      }
    },
    "/campaigns/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Read the saved campaign language",
        "description": "Requires campaign:view. Templates may be owned by the workspace or public; campaigns must belong to the workspace.",
        "responses": {
          "200": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      },
      "patch": {
        "summary": "Set the campaign content language",
        "description": "Requires campaign:edit. Only owned resources can be updated. Campaign updates remain restricted to draft/paused states. Omit contentLocale for an unrelated edit; never send empty or null to preserve it. This does not translate text.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCampaign"
              },
              "example": {
                "contentLocale": "nl"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "409": {
            "description": "Campaign is not draft or paused."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      }
    },
    "/campaigns/{id}/duplicate": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "summary": "Duplicate while preserving content language",
        "description": "Requires campaign:create.",
        "responses": {
          "201": {
            "description": "Saved resource including its content language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "404": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          },
          "500": {
            "description": "Existing endpoint failure; missing/inaccessible duplicate sources currently use this status."
          }
        }
      }
    },
    "/emails/render": {
      "post": {
        "summary": "Render using an explicit content language",
        "description": "Raw MJML render, authenticated as an active workspace member. Raw MJML can carry a validated lang/dir root. Explicit contentLocale applies the requested document language. Pass a template’s saved MJML and contentLocale when rendering it; this route does not load a template by ID. Neither profile locale nor request cookies are language fallbacks.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mjml"
                ],
                "properties": {
                  "mjml": {
                    "type": "string"
                  },
                  "data": {
                    "type": "object"
                  },
                  "contentLocale": {
                    "$ref": "#/components/schemas/ContentLocale",
                    "description": "Email content language, independent of the user/profile/interface locale. Optional on requests; explicit empty, null or unsupported codes are invalid."
                  }
                }
              },
              "example": {
                "mjml": "<mjml><mj-body><mj-section><mj-column><mj-text>Welcome!</mj-text></mj-column></mj-section></mj-body></mjml>",
                "contentLocale": "en-gb"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rendered HTML including known content language and default direction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "html": {
                      "type": "string"
                    },
                    "errors": {
                      "type": [
                        "array",
                        "null"
                      ],
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "html"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "401": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "403": {
            "description": "Existing endpoint error response. Invalid explicit contentLocale returns 400; authentication, permissions and resource ownership remain enforced."
          },
          "422": {
            "description": "Invalid or unsupported MJML."
          },
          "429": {
            "description": "Workspace rate limit exceeded."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "schemas": {
      "ContentLocale": {
        "type": "string",
        "enum": [
          "en",
          "en-gb",
          "nl",
          "de",
          "fr",
          "es",
          "pl",
          "ar",
          "pt",
          "pt-br",
          "it",
          "zh",
          "sv",
          "nb",
          "lv",
          "et",
          "fi",
          "el",
          "ja"
        ],
        "description": "Exact canonical locale code. Regional/case aliases are not accepted for content metadata."
      },
      "Template": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "contentLocale": {
            "type": "string",
            "enum": [
              "",
              "en",
              "en-gb",
              "nl",
              "de",
              "fr",
              "es",
              "pl",
              "ar",
              "pt",
              "pt-br",
              "it",
              "zh",
              "sv",
              "nb",
              "lv",
              "et",
              "fi",
              "el",
              "ja"
            ],
            "description": "Empty means unknown legacy content language, not the interface language."
          }
        },
        "required": [
          "id",
          "contentLocale"
        ],
        "additionalProperties": true
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "contentLocale": {
            "type": "string",
            "enum": [
              "",
              "en",
              "en-gb",
              "nl",
              "de",
              "fr",
              "es",
              "pl",
              "ar",
              "pt",
              "pt-br",
              "it",
              "zh",
              "sv",
              "nb",
              "lv",
              "et",
              "fi",
              "el",
              "ja"
            ],
            "description": "Empty means unknown legacy content language, not the interface language."
          }
        },
        "required": [
          "id",
          "contentLocale"
        ],
        "additionalProperties": true
      },
      "CreateTemplate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "mjmlContent": {
            "type": "string"
          },
          "placeholders": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "contentLocale": {
            "$ref": "#/components/schemas/ContentLocale",
            "description": "Email content language, independent of the user/profile/interface locale. Optional on requests; explicit empty, null or unsupported codes are invalid."
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": true
      },
      "UpdateTemplate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "mjmlContent": {
            "type": "string"
          },
          "placeholders": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "contentLocale": {
            "$ref": "#/components/schemas/ContentLocale",
            "description": "Email content language, independent of the user/profile/interface locale. Optional on requests; explicit empty, null or unsupported codes are invalid."
          }
        },
        "additionalProperties": true
      },
      "CreateCampaign": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "regular",
              "ab_test",
              "automated"
            ]
          },
          "subject": {
            "type": "string"
          },
          "previewText": {
            "type": "string"
          },
          "fromName": {
            "type": "string"
          },
          "fromEmail": {
            "type": "string"
          },
          "replyTo": {
            "type": "string"
          },
          "templateId": {
            "type": "string",
            "format": "uuid"
          },
          "content": {
            "type": "object"
          },
          "segmentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "contentLocale": {
            "$ref": "#/components/schemas/ContentLocale",
            "description": "Email content language, independent of the user/profile/interface locale. Optional on requests; explicit empty, null or unsupported codes are invalid."
          }
        },
        "required": [
          "name",
          "type"
        ],
        "additionalProperties": true
      },
      "UpdateCampaign": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "previewText": {
            "type": "string"
          },
          "fromName": {
            "type": "string"
          },
          "fromEmail": {
            "type": "string"
          },
          "replyTo": {
            "type": "string"
          },
          "templateId": {
            "type": "string",
            "format": "uuid"
          },
          "content": {
            "type": "object"
          },
          "segmentIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "contentLocale": {
            "$ref": "#/components/schemas/ContentLocale",
            "description": "Email content language, independent of the user/profile/interface locale. Optional on requests; explicit empty, null or unsupported codes are invalid."
          }
        },
        "additionalProperties": true
      }
    }
  }
}
