Skip to main content

Documentation Index

Fetch the complete documentation index at: https://loops.so/docs/llms.txt

Use this file to discover all available pages before exploring further.

LMX and related Content API endpoints are currently in a closed alpha and are subject to change.
LMX (Loops Markup Language) is an XML-based format for writing email content in Loops. Every piece of content is represented by an explicit PascalCase tag. LMX can be used with the content API to create and update emails programmatically. LMX sits between the API and our editor, making it possible to edit emails across both the editor and API.

LMX examples

Here are some examples of how to use LMX tags to create emails.
<H1>Hello</H1>
<Paragraph>World</Paragraph>
A list
<H2>Release checklist</H2>
<OrderedList>
  <ListItem>Finish QA</ListItem>
  <ListItem>Prepare announcement</ListItem>
  <ListItem>Notify teams</ListItem>
</OrderedList>
Two-column layout
<Columns>
  <ColumnItem>
    <H3>Starter</H3>
    <Paragraph>Best for new projects.</Paragraph>
    <Button href="https://loops.so/pricing">Start free</Button>
  </ColumnItem>
  <ColumnItem>
    <H3>Pro</H3>
    <Paragraph>Advanced automation and analytics.</Paragraph>
    <Button href="https://loops.so/pricing">Upgrade</Button>
  </ColumnItem>
</Columns>
Full email example
<Style themeId="st_default"
  bodyColor="#1F2937"
  bodyYPadding="24" />
<Component componentId="logo" />
<H1>Hi {contact.firstName}, your weekly update is ready</H1>
<Paragraph fontSize="16" lineHeight="150">
  Here is your weekly account summary. Read <Link href="https://loops.so/docs">the docs</Link> for the full changelog.
</Paragraph>
<Button href="https://app.example.com/account/{contact.userId}" align="center" bgColor="#000000" textColor="#ffffff">
  Open dashboard, {contact.firstName}
</Button>
<Divider />
<H2>Top priorities</H2>
<OrderedList>
  <ListItem>Fix onboarding drop-off on step 2</ListItem>
  <ListItem>Publish changelog for API v2</ListItem>
  <ListItem>Review deliverability metrics</ListItem>
</OrderedList>
<Columns gap="24" widths="50,50" verticalAlignment="top">
  <ColumnItem>
    <H3>Docs</H3>
    <Paragraph>Start with the quickstart.</Paragraph>
  </ColumnItem>
  <ColumnItem>
    <Image src="https://example.com/avatar-placeholder.png" dynamicSrc="{contact.avatarUrl}" alt="{contact.firstName}" width="180" />
  </ColumnItem>
</Columns>
<Section blockColor="#F8FAFC" blockBorderRadius="12" paddingTop="16" paddingBottom="16">
  <Paragraph>Review your latest activity and <Strong>update your settings</Strong>.</Paragraph>
</Section>
<Paragraph>
  Need help? <Link href="https://example.com/support">Contact support</Link>.
</Paragraph>
<Icons>
  <Icon name="x-twitter" href="https://twitter.com/loops" />
  <Icon name="linkedin" href="https://www.linkedin.com/company/sendwithloops/" />
</Icons>

Core rules

  • LMX is XML, not HTML or Markdown. Tags are case-sensitive (for example, <Paragraph>, not <paragraph>).
  • LMX is not MJML. Do not use MJML tags (such as <mj-text>) or MJML dynamic tag syntax in LMX documents.
  • A document is a sequence of top-level block tags, optionally with one top-level <Style />.
  • Text is not allowed at the top level. Wrap top-level text in a block tag like <Paragraph>.
  • Top-level inline tags and variables are invalid.
  • Required attributes must be present (for example, <Image /> requires src).
  • Self-closing tags must end with /> (for example, <Image ... />, <Br />).
  • Unknown tags are rejected. Unknown attributes are allowed but reported as warnings.
  • Attribute values are quoted strings. Numbers and booleans are passed as strings.
  • Whitespace between block tags is ignored, so pretty-printing is safe.
  • Escape text and attributes as needed (&lt;, &amp;, &quot;).
Emails automatically have a footer appended, so you don’t need to include your address or unsubscribe link at the bottom of your LMX content.

Block tags

Block tags define the structure of an email.
TagDescriptionSelf-closing
<Style />Style metadata (top-level only)yes
<H1>, <H2>, <H3>Heading blocks
<Paragraph>Paragraph block
<Quote>Quote block
<CodeBlock>Code block
<Button>Button block
<Image />Image blockyes
<Divider />Divider blockyes
<Br />Line breakyes
<OrderedList>Numbered list container
<UnorderedList>Bulleted list container
<ListItem>List item
<Columns>Multi-column container
<ColumnItem>Column content container
<Component>Component containeryes, but can contain children
<Section>Section container
<Icons>Social icon group
<Icon />Individual iconyes

Tag reference

Document styles

Use the optional top-level <Style /> tag to style the email. Use this to apply a theme to your email and add custom styles, just like you would in the Style panel in the editor. Use a combination of themeId and other attributes to bring in defaults while also overriding specific styles. You can also style individual elements in your email using tag attributes (for example, <Button textColor="#000000" /> will override <Style buttonBodyColor="#CCCCCC" />). Styles applied in <Style /> will apply to all content in the email. For example defining buttonBodyColor in the <Style /> tag will apply to all buttons in the email. Self-closing tag. At most one per document.
AttributeNotes
themeIdTheme preset ID to load as the base style before applying overrides.
backgroundColorOuter email hex background color around the body container.
backgroundXPaddingLeft and right spacing (px) between the outer background and body container.
backgroundYPaddingTop and bottom spacing (px) between the outer background and body container.
bodyColorMain body container hex background color.
bodyXPaddingLeft and right inner padding (px) inside the body container.
bodyYPaddingTop and bottom inner padding (px) inside the body container.
bodyFontFamilyFont family from Google Fonts e.g. "Inter", "Noto Sans"
bodyFontCategoryFallback font category. Must be one of: "ui-sans-serif", "ui-serif", "ui-monospace", "sans-serif", "serif", "monospace".
borderColorDefault hex border color for the body container.
borderWidthBorder width (px) for the body container.
borderRadiusCorner radius (px) for the body container.
buttonBodyColorDefault hex background color applied to buttons.
buttonBodyXPaddingDefault left and right internal button padding (px).
buttonBodyYPaddingDefault top and bottom internal button padding (px).
buttonBorderColorDefault hex border color for buttons.
buttonBorderWidthDefault button border width (px).
buttonBorderRadiusDefault button corner radius (px).
buttonTextColorDefault hex text color used in buttons.
buttonTextFontSizeDefault button text size (px).
dividerColorDefault hex line color used by <Divider />.
dividerBorderWidthDefault line thickness (px) used by <Divider />.
textBaseColorDefault hex color for paragraph, quote, and list text.
textBaseFontSizeDefault font size (px) for paragraph, quote, and list text.
textBaseLineHeightDefault line height (percentage) for body text.
textBaseLetterSpacingDefault letter spacing (px) applied to body text.
textLinkColorDefault hex text color for inline <Link>.
heading1ColorDefault hex text color for <H1>.
heading1FontSizeDefault font size (px) for <H1>.
heading1LineHeightDefault line height (percentage) for <H1>.
heading1LetterSpacingDefault letter spacing (px) for <H1>.
heading2ColorDefault hex text color for <H2>.
heading2FontSizeDefault font size (px) for <H2>.
heading2LineHeightDefault line height (percentage) for <H2>.
heading2LetterSpacingDefault letter spacing (px) for <H2>.
heading3ColorDefault hex text color for <H3>.
heading3FontSizeDefault font size (px) for <H3>.
heading3LineHeightDefault line height (percentage) for <H3>.
heading3LetterSpacingDefault letter spacing (px) for <H3>.

Headings

Use <H1>, <H2>, and <H3> for headings.
<H1 align="center" fontSize="34" lineHeight="120">
  Welcome to Loops
</H1>
<H2 paddingTop="16" fontSize="24">
  Your weekly summary
</H2>
<H3 blockColor="#F3F4F6" blockBorderRadius="8" paddingLeft="12" paddingRight="12">
  Highlights
</H3>
AttributeTypeNotes
fontSizenumber
lineHeightnumberPercentage value such as "150"
alignstring"left" (default), "center", "right"
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Paragraphs

Use <Paragraph> for paragraph text.
<Paragraph fontSize="16" lineHeight="160" align="left" paddingBottom="12">
  Thanks for trying Loops. Here is what changed this week.
</Paragraph>
AttributeTypeNotes
fontSizenumber
lineHeightnumberPercentage value such as "150"
alignstring"left" (default), "center", "right"
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Quotes

Use <Quote> for blockquote content.
<Quote blockColor="#F9FAFB" blockBorderRadius="8" paddingLeft="16" paddingRight="16">
  Great emails feel personal and timely.
</Quote>
AttributeTypeNotes
fontSizenumber
lineHeightnumberPercentage value such as "150"
alignstring"left" (default), "center", "right"
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Code blocks

Use <CodeBlock> for code blocks. Note: inline tags and variable parsing are disabled inside code blocks.
<CodeBlock>
  curl -X POST https://app.loops.so/api/v1/events/send
</CodeBlock>
AttributeTypeNotes
fontSizenumber
lineHeightnumberPercentage value such as "150"
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Buttons

Use <Button> for buttons. Button content may contain plain text and dynamic content variables such as {contact.firstName}. Inline formatting tags are not allowed inside buttons.
<Button href="https://app.example.com/users/{contact.userId}">
  Open profile, {contact.firstName}
</Button>
AttributeTypeRequiredNotes
hrefurlThe button’s URL. May contain dynamic variables
alignstring"left" (default), "center", "right"
notrackboolean"true" disables link tracking
bgColorhex
textColorhex
borderRadiusnumber
borderWidthnumber
borderColorhex
innerXPaddingnumberInner padding of the button content
innerYPaddingnumberInner padding of the button content
fontSizenumber
blockColorhex
blockBorderRadiusnumber
paddingTopnumberPadding of the container block
paddingRightnumberPadding of the container block
paddingBottomnumberPadding of the container block
paddingLeftnumberPadding of the container block

Images

Use <Image /> for images. The image must be hosted somewhere and have a public URL.
Only existing images are supported. Image upload is coming soon.
Self-closing tag.
<Image
  src="https://images.example.com/launch-banner.png"
  alt="Launch banner"
  href="https://example.com/changelog"
  width="560"
  align="center"
  borderRadius="10"
/>

Dynamic images

If you want to create a dynamic image URL for each contact, set dynamicSrc to a URL containing a variable (for example, {contact.avatarUrl}). The image URL should come from a contact property. You must also set src to a static placeholder URL (this image will render in the Loops editor). When the email is generated for each recipient, the resolved dynamicSrc value is injected as the image src. More about dynamic images.
<Image
  src="https://example.com/avatar-placeholder.png"
  dynamicSrc="{contact.avatarUrl}"
  alt="{contact.firstName}"
  width="180"
  align="center"
/>
AttributeTypeRequiredNotes
srcurlyesImage URL. Always required. When dynamicSrc is set, src is a placeholder for the editor; at send time the resolved dynamicSrc value is used as the image URL.
dynamicSrcstringPer-recipient image URL from a contact property, such as {contact.avatarUrl}. See dynamic images.
notrackboolean"true" disables link tracking
altstringAlt text
hrefurlAdd a link to the image. May contain dynamic variables
widthnumberPixel width, maximum is 600px. Default is full width (600px). If you add padding, width will auto-adjust to be maximum 600px.
alignstring"left" (default), "center", "right"
borderRadiusnumber
borderWidthnumber
borderColorhex
blockColorhexBackground color of the container block
blockBorderRadiusnumberBorder radius of the container block
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Dividers

Use <Divider /> for divider lines. Self-closing tag.
<Divider align="center" width="80" borderWidth="1" color="#E5E7EB" />
AttributeTypeNotes
alignstring"left" (default), "center", "right"
widthnumberPercentage value
borderWidthnumber
colorhexColor of the divider line
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Line breaks

Use <Br /> for line breaks in inline contexts. It is not valid at the top level. Self-closing tag.
<Paragraph>
  Thanks for reading.<Br />
  See you next week.
</Paragraph>

Lists

Use <OrderedList> or <UnorderedList> with <ListItem> children only. These tags must contain at least one <ListItem>.
AttributeTypeNotes
alignstring"left" (default), "center", "right"
startnumberItem number to start at (ordered lists only)
<OrderedList>
  <ListItem>Review campaign draft</ListItem>
  <ListItem>Send internal preview</ListItem>
</OrderedList>

<UnorderedList>
  <ListItem>Open rate up 12%</ListItem>
  <ListItem>Clicks up 18%</ListItem>
</UnorderedList>

List items

Use <ListItem> for list items. Only valid inside <OrderedList> and <UnorderedList> tags. Can only contain inline content.
<UnorderedList>
  <ListItem fontSize="15" lineHeight="150" paddingBottom="8">
    Use clear call-to-action labels.
  </ListItem>
</UnorderedList>
AttributeTypeNotes
fontSizenumber
lineHeightnumberPercentage value such as "150"
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Columns

Use <Columns> for columns. Must contain between two and four <ColumnItem> children. No other tags are allowed.
<Columns gap="16" widths="60,40" verticalAlignment="top" stackOnMobile="true">
  <ColumnItem>
    <H3>What shipped</H3>
    <Paragraph>New audience filters and event export support.</Paragraph>
  </ColumnItem>
  <ColumnItem>
    <Image src="https://images.example.com/product-shot.png" alt="Product screenshot" width="220" />
  </ColumnItem>
</Columns>
AttributeTypeNotes
gapnumberSpace between columns (px)
widthsstringComma-separated percentages, one for each column, must total 100.
verticalAlignmentstring"top", "middle", "bottom"
stackOnMobileboolean
reverseOnMobileboolean
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber
Use <ColumnItem> for column content containers. Only valid inside a <Columns> tag. No attributes.
<Columns>
  <ColumnItem>
    <Paragraph>Left column content</Paragraph>
  </ColumnItem>
  <ColumnItem>
    <Paragraph>Central column content</Paragraph>
  </ColumnItem>
  <ColumnItem>
    <Paragraph>Right column content</Paragraph>
  </ColumnItem>
</Columns>

Components

Use <Component> to add a component. Can be self-closing, or can contain block elements, which will override the component’s default content. Children are block tags. Nested <Component> tags are not supported.
<Component componentId="header-hero" />

<Component componentId="feature-section">
  <H2>Updated override title</H2>
  <Paragraph>This content replaces the component's defaults.</Paragraph>
</Component>
AttributeTypeRequiredNotes
componentIdstringyesThe component’s ID
alignstring"left" (default), "center", "right"
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Sections

Use <Section> to group related block content in a shared clickable or styled container. Children are block tags. Nested <Section> tags are not supported.
<Section
  href="https://example.com/account/{contact.userId}"
  blockColor="#F8FAFC"
  blockBorderRadius="12"
  paddingTop="16"
  paddingBottom="16"
>
  <H2>Account summary</H2>
  <Paragraph>Review your latest activity and settings.</Paragraph>
</Section>
AttributeTypeRequiredNotes
hrefurlSection link URL. May contain dynamic variables
notrackboolean"true" disables link tracking
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber

Icons

Use <Icons> for lists of icons. Children must be <Icon /> with no other tags allowed. At least one <Icon /> child is required (maximum 100).
<Icons align="center" gap="12" size="20" color="#000000">
  <Icon name="x-twitter" href="https://twitter.com/loops" />
  <Icon name="linkedin" href="https://www.linkedin.com/company/sendwithloops/" />
</Icons>
AttributeTypeNotes
alignstring"left" (default), "center", "right"
gapnumberSpace between icons (px)
sizenumberIcon size (px)
colorhex#000000 (black, default), #808080 (gray), #FFFFFF (white)
blockColorhex
blockBorderRadiusnumber
paddingTopnumber
paddingRightnumber
paddingBottomnumber
paddingLeftnumber
Use <Icon /> for individual icons. Self-closing tag. Only valid inside an <Icons> tag.
AttributeTypeRequiredNotes
namestringyesIcon name (available icons listed here)
hrefurlA URL for the icon
notrackboolean"true" disables link tracking

Inline tags

Inline tags format text content inside block elements.
TagDescription
<Strong>Bold text
<Em>Italic text
<Underline>Underlined text
<Code>Inline code
<Strike>Strikethrough text
<Text>No format, useful for textColor
<Link href="...">Link with URL
Inline tags are valid only inside inline-content blocks such as <Paragraph>, headings, <Quote>, and <ListItem>.
<Paragraph>
  <Strong textColor="#111827">Important:</Strong>
  <Em textColor="#4B5563"> review your campaign settings</Em>
  <Underline textColor="#111827"> before sending</Underline>.
  Use <Code textColor="#7C3AED">audience_filters</Code> for targeting,
  remove outdated copy with <Strike textColor="#6B7280">old messaging</Strike>,
  and keep defaults with <Text textColor="#374151">plain text</Text>.
  Read more in
  <Link href="https://loops.so/docs/creating-emails" notrack="true"> the docs</Link>.
</Paragraph>

Inline tag attributes

TagAttributeTypeRequiredNotes
<Strong>textColorhex
<Em>textColorhex
<Underline>textColorhex
<Code>textColorhex
<Strike>textColorhex
<Text>textColorhex
<Link>hrefurlyesMay contain dynamic variables
<Link>notrackboolean"true" disables link tracking

Dynamic content

You can add dynamic content like contact properties by using a tag syntax with a prefix, for example {contact.firstName}. Unprefixed placeholders like {firstName} are not valid in LMX. Neither are other Loops variable prefixes used in MJML or the editor: LMX campaign content uses {contact.apiName} only.
Unprefixed placeholders like {firstName} and prefixed forms like {EVENT_PROPERTY:firstName} are still valid in MJML emails and in the Loops editor. They are not valid in LMX. In the future, all variables will require a prefix.
SyntaxVariable typeUse caseExample
{contact.X}Contact propertyCampaign personalization{contact.firstName}
Variables are allowed in:
  • Inline content (headings, paragraphs, quotes, and list items)
  • Button text
  • Button href, Link href, Image alt, Image href, Image dynamicSrc, and Section href
Variables are not allowed at the top level or inside <CodeBlock> (they are treated as literal text there).

Variables in attributes

Only these attribute values may include variables:
  • Button href
  • Image alt, href, and dynamicSrc
  • Link href
  • Section href
Image src must be a static URL with no variables. Putting a variable like {contact.avatarUrl} in src is not supported and validation returns unsupported_dynamic_attr. When the image URL should vary per contact, set dynamicSrc to a contact property such as {contact.avatarUrl} and keep src as a static placeholder; at send time, the resolved dynamicSrc value replaces src.

Fallback values

LMX does not support inline fallback syntax in variable references. These forms are not valid in LMX: {contact.firstName|there}, {contact.firstName:there}, {contact.firstName ?? "there"}, and fallback="there" on variable attributes. Use plain variable references in LMX (for example, {contact.firstName}), and configure fallback values through the Loops editor.

Nesting rules

LMX validates structure, not just syntax. A few key rules:
  • Root-level content must use supported top-level block tags (H1, H2, H3, Paragraph, Quote, CodeBlock, Button, Image, Divider, OrderedList, UnorderedList, Columns, Component, Section, Icons, Style).
  • Inline tags cannot appear at the top level.
  • <ListItem> and <Quote> only accept inline content.
  • <Columns> can only contain <ColumnItem> tags.
  • <ColumnItem> can contain block content, but not other <ColumnItem> tags.
  • <Style /> is metadata and is only allowed at the top level.
If a tag, attribute, or nesting pattern is invalid, validation issues are returned so problems can be fixed before sending.
Last modified on May 20, 2026