{"id":23512775,"url":"https://github.com/baethon/mjml-api","last_synced_at":"2025-10-04T18:13:10.212Z","repository":{"id":40932939,"uuid":"163295361","full_name":"baethon/mjml-api","owner":"baethon","description":"Responsive email as a service","archived":false,"fork":false,"pushed_at":"2023-01-23T23:23:00.000Z","size":1026,"stargazers_count":3,"open_issues_count":10,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T07:41:51.496Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/baethon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-27T13:02:35.000Z","updated_at":"2022-01-13T13:50:20.000Z","dependencies_parsed_at":"2023-01-26T10:47:10.833Z","dependency_job_id":null,"html_url":"https://github.com/baethon/mjml-api","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fmjml-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fmjml-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fmjml-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baethon%2Fmjml-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baethon","download_url":"https://codeload.github.com/baethon/mjml-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249692904,"owners_count":21311420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-25T13:19:25.509Z","updated_at":"2025-10-04T18:13:05.164Z","avatar_url":"https://github.com/baethon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mjml-api [![Build Status](https://travis-ci.org/baethon/mjml-api.svg?branch=master)](https://travis-ci.org/baethon/mjml-api)[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\nThis project exposes [mjml](https://mjml.io) as an API service. It's meant* to be compatible with [MJML API ](https://mjml.io/api).\n\n## Requirements\n\n* Node \u003e= 8\n* Yarn\n\n## Running\n\n### From sources\n\n```bash\nyarn\nyarn start\n```\n\n### Using heroku\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/baethon/mjml-api/tree/master)\n\n### Using Docker image\n\n```bash\ndocker run --rm -p 3000:8080 baethon/mjml-api\n```\n\n## Supported env variables\n\n|  Name       | Alias  | Default   | Description                                                                            |\n| ----------- | ------ | --------- | -------------------------------------------------------------------------------------- |\n| `NODE_PORT` | `PORT` | `3000`    | Port to listen on                                                                      |\n| `NODE_HOST` | `HOST` | `0.0.0.0` | Host to listen on                                                                      |\n| `CORS`      |        | `*`       | Set to `*` to enable CORS for all origins, or set a single origin `http://example.com` |\n\n## API\n\nThis API aims to be combatible with MJML API.\n\nYet, there're few differences:\n\n* **there's no client authorization** - make sure that API won't be publicly available\n* `request_id` in errors will always be `NULL`\n* `started_at` will return date in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)\n\n### Endpoints\n\n#### POST /v1/render\n\nRenders given MJML template.\n\n##### Example request\n\n```json\n{ \n    \"mjml\": \"\u003cmjml\u003e  \u003cmj-body\u003e    \u003cmj-section\u003e      \u003cmj-column\u003e        \u003cmj-divider border-color=\\\"#F45E43\\\"\u003e\u003c/mj-divider\u003e        \u003cmj-text font-size=\\\"20px\\\" color=\\\"#F45E43\\\" font-family=\\\"helvetica\\\"\u003eHello World\u003c/mj-text\u003e      \u003c/mj-column\u003e    \u003c/mj-section\u003e  \u003c/mj-body\u003e\u003c/mjml\u003e\" \n}\n```\n\n##### Example response\n\n```json\n{\n    \"html\": \"\\n    \u003c!doctype html\u003e\\n    \u003chtml xmlns=\\\"http://www.w3.org/1999/xhtml\\\" xmlns:v=\\\"urn:schemas-microsoft-com:vml\\\" xmlns:o=\\\"urn:schemas-microsoft-com:office:office\\\"\u003e\\n      \u003chead\u003e\\n        \u003ctitle\u003e\\n          \\n        \u003c/title\u003e\\n        \u003c!--[if !mso]\u003e\u003c!-- --\u003e\\n        \u003cmeta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge\\\"\u003e\\n        \u003c!--\u003c![endif]--\u003e\\n        \u003cmeta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=UTF-8\\\"\u003e\\n        \u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1\\\"\u003e\\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n          #outlook a { padding:0; }\\n          .ReadMsgBody { width:100%; }\\n          .ExternalClass { width:100%; }\\n          .ExternalClass * { line-height:100%; }\\n          body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; }\\n          table, td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; }\\n          img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; }\\n          p { display:block;margin:13px 0; }\\n        \u003c/style\u003e\\n        \u003c!--[if !mso]\u003e\u003c!--\u003e\\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n          @media only screen and (max-width:480px) {\\n            @-ms-viewport { width:320px; }\\n            @viewport { width:320px; }\\n          }\\n        \u003c/style\u003e\\n        \u003c!--\u003c![endif]--\u003e\\n        \u003c!--[if mso]\u003e\\n        \u003cxml\u003e\\n        \u003co:OfficeDocumentSettings\u003e\\n          \u003co:AllowPNG/\u003e\\n          \u003co:PixelsPerInch\u003e96\u003c/o:PixelsPerInch\u003e\\n        \u003c/o:OfficeDocumentSettings\u003e\\n        \u003c/xml\u003e\\n        \u003c![endif]--\u003e\\n        \u003c!--[if lte mso 11]\u003e\\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n          .outlook-group-fix { width:100% !important; }\\n        \u003c/style\u003e\\n        \u003c![endif]--\u003e\\n        \\n        \\n    \u003cstyle type=\\\"text/css\\\"\u003e\\n      @media only screen and (min-width:480px) {\\n        .mj-column-per-100 { width:100% !important; max-width: 100%; }\\n      }\\n    \u003c/style\u003e\\n    \\n  \\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n        \\n        \\n        \u003c/style\u003e\\n        \\n        \\n      \u003c/head\u003e\\n      \u003cbody\u003e\\n        \\n        \\n      \u003cdiv\\n         style=\\\"\\\"\\n      \u003e\\n        \\n      \\n      \u003c!--[if mso | IE]\u003e\\n      \u003ctable\\n         align=\\\"center\\\" border=\\\"0\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" class=\\\"\\\" style=\\\"width:600px;\\\" width=\\\"600\\\"\\n      \u003e\\n        \u003ctr\u003e\\n          \u003ctd style=\\\"line-height:0px;font-size:0px;mso-line-height-rule:exactly;\\\"\u003e\\n      \u003c![endif]--\u003e\\n    \\n      \\n      \u003cdiv  style=\\\"Margin:0px auto;max-width:600px;\\\"\u003e\\n        \\n        \u003ctable\\n           align=\\\"center\\\" border=\\\"0\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" role=\\\"presentation\\\" style=\\\"width:100%;\\\"\\n        \u003e\\n          \u003ctbody\u003e\\n            \u003ctr\u003e\\n              \u003ctd\\n                 style=\\\"direction:ltr;font-size:0px;padding:20px 0;text-align:center;vertical-align:top;\\\"\\n              \u003e\\n                \u003c!--[if mso | IE]\u003e\\n                  \u003ctable role=\\\"presentation\\\" border=\\\"0\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\"\u003e\\n                \\n        \u003ctr\u003e\\n      \\n            \u003ctd\\n               class=\\\"\\\" style=\\\"vertical-align:top;width:600px;\\\"\\n            \u003e\\n          \u003c![endif]--\u003e\\n            \\n      \u003cdiv\\n         class=\\\"mj-column-per-100 outlook-group-fix\\\" style=\\\"font-size:13px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;\\\"\\n      \u003e\\n        \\n      \u003ctable\\n         border=\\\"0\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" role=\\\"presentation\\\" style=\\\"vertical-align:top;\\\" width=\\\"100%\\\"\\n      \u003e\\n        \\n            \u003ctr\u003e\\n              \u003ctd\\n                 style=\\\"font-size:0px;padding:10px 25px;word-break:break-word;\\\"\\n              \u003e\\n                \\n      \u003cp\\n         style=\\\"border-top:solid 4px #F45E43;font-size:1;margin:0px auto;width:100%;\\\"\\n      \u003e\\n      \u003c/p\u003e\\n      \\n      \u003c!--[if mso | IE]\u003e\\n        \u003ctable\\n           align=\\\"center\\\" border=\\\"0\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" style=\\\"border-top:solid 4px #F45E43;font-size:1;margin:0px auto;width:550px;\\\" role=\\\"presentation\\\" width=\\\"550px\\\"\\n        \u003e\\n          \u003ctr\u003e\\n            \u003ctd style=\\\"height:0;line-height:0;\\\"\u003e\\n              \u0026nbsp;\\n            \u003c/td\u003e\\n          \u003c/tr\u003e\\n        \u003c/table\u003e\\n      \u003c![endif]--\u003e\\n    \\n    \\n              \u003c/td\u003e\\n            \u003c/tr\u003e\\n          \\n            \u003ctr\u003e\\n              \u003ctd\\n                 align=\\\"left\\\" style=\\\"font-size:0px;padding:10px 25px;word-break:break-word;\\\"\\n              \u003e\\n                \\n      \u003cdiv\\n         style=\\\"font-family:helvetica;font-size:20px;line-height:1;text-align:left;color:#F45E43;\\\"\\n      \u003e\\n        Hello World\\n      \u003c/div\u003e\\n    \\n              \u003c/td\u003e\\n            \u003c/tr\u003e\\n          \\n      \u003c/table\u003e\\n    \\n      \u003c/div\u003e\\n    \\n          \u003c!--[if mso | IE]\u003e\\n            \u003c/td\u003e\\n          \\n        \u003c/tr\u003e\\n      \\n                  \u003c/table\u003e\\n                \u003c![endif]--\u003e\\n              \u003c/td\u003e\\n            \u003c/tr\u003e\\n          \u003c/tbody\u003e\\n        \u003c/table\u003e\\n        \\n      \u003c/div\u003e\\n    \\n      \\n      \u003c!--[if mso | IE]\u003e\\n          \u003c/td\u003e\\n        \u003c/tr\u003e\\n      \u003c/table\u003e\\n      \u003c![endif]--\u003e\\n    \\n    \\n      \u003c/div\u003e\\n    \\n      \u003c/body\u003e\\n    \u003c/html\u003e\\n  \",\n    \"errors\": [],\n    \"mjml\": \"\u003cmjml\u003e  \u003cmj-body\u003e    \u003cmj-section\u003e      \u003cmj-column\u003e        \u003cmj-divider border-color=\\\"#F45E43\\\"\u003e\u003c/mj-divider\u003e        \u003cmj-text font-size=\\\"20px\\\" color=\\\"#F45E43\\\" font-family=\\\"helvetica\\\"\u003eHello World\u003c/mj-text\u003e      \u003c/mj-column\u003e    \u003c/mj-section\u003e  \u003c/mj-body\u003e\u003c/mjml\u003e\",\n    \"mjml_version\": \"4.2.1\"\n}\n```\n\n##### Example errors\n\n```json\n{\n    \"request_id\": null,\n    \"started_at\": \"2018-12-27T14:01:30.732Z\",\n    \"message\": \"Invalid value [body \u003e mjml]\"\n}\n```\n\n```json\n{\n    \"html\": \"\\n    \u003c!doctype html\u003e\\n    \u003chtml xmlns=\\\"http://www.w3.org/1999/xhtml\\\" xmlns:v=\\\"urn:schemas-microsoft-com:vml\\\" xmlns:o=\\\"urn:schemas-microsoft-com:office:office\\\"\u003e\\n      \u003chead\u003e\\n        \u003ctitle\u003e\\n          \\n        \u003c/title\u003e\\n        \u003c!--[if !mso]\u003e\u003c!-- --\u003e\\n        \u003cmeta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge\\\"\u003e\\n        \u003c!--\u003c![endif]--\u003e\\n        \u003cmeta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=UTF-8\\\"\u003e\\n        \u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1\\\"\u003e\\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n          #outlook a { padding:0; }\\n          .ReadMsgBody { width:100%; }\\n          .ExternalClass { width:100%; }\\n          .ExternalClass * { line-height:100%; }\\n          body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; }\\n          table, td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; }\\n          img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; }\\n          p { display:block;margin:13px 0; }\\n        \u003c/style\u003e\\n        \u003c!--[if !mso]\u003e\u003c!--\u003e\\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n          @media only screen and (max-width:480px) {\\n            @-ms-viewport { width:320px; }\\n            @viewport { width:320px; }\\n          }\\n        \u003c/style\u003e\\n        \u003c!--\u003c![endif]--\u003e\\n        \u003c!--[if mso]\u003e\\n        \u003cxml\u003e\\n        \u003co:OfficeDocumentSettings\u003e\\n          \u003co:AllowPNG/\u003e\\n          \u003co:PixelsPerInch\u003e96\u003c/o:PixelsPerInch\u003e\\n        \u003c/o:OfficeDocumentSettings\u003e\\n        \u003c/xml\u003e\\n        \u003c![endif]--\u003e\\n        \u003c!--[if lte mso 11]\u003e\\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n          .outlook-group-fix { width:100% !important; }\\n        \u003c/style\u003e\\n        \u003c![endif]--\u003e\\n        \\n        \\n        \u003cstyle type=\\\"text/css\\\"\u003e\\n        \\n        \\n        \u003c/style\u003e\\n        \\n        \\n      \u003c/head\u003e\\n      \u003cbody\u003e\\n        \\n        \\n      \u003c/body\u003e\\n    \u003c/html\u003e\\n  \",\n    \"errors\": [\n        {\n            \"line\": 1,\n            \"message\": \"Attribute width has invalid value: 100 for type Unit, only accepts (px) units and 1 value(s)\",\n            \"tagName\": \"mj-image\",\n            \"formattedMessage\": \"Line 1 of /home/radmen/Work/open-source/baethon/mjml-api (mj-image) — Attribute width has invalid value: 100 for type Unit, only accepts (px) units and 1 value(s)\"\n        }\n    ],\n    \"mjml\": \"\u003cmj-image width=\\\"100\\\" src=\\\"/assets/img/logo-small.png\\\"\u003e\u003c/mj-image\u003e\",\n    \"mjml_version\": \"4.2.1\"\n}\n```\n\n## Testing\n\n```bash\nyarn test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaethon%2Fmjml-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaethon%2Fmjml-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaethon%2Fmjml-api/lists"}