Skip to main content

HTML Content Blocks

Introduction

A content library lets you store reusable HTML blocks that can be referenced dynamically in email campaigns. Specific blocks can be assigned to profiles based on your data model, a personalization file, or an API call — enabling highly targeted content without rebuilding emails from scratch.

Common use cases:

  • A media outlet pushes different articles to profiles based on their declared interests
  • A retailer adds product recommendations tailored to each recipient
  • A team updates a single content block to refresh several emails at once
  • An active scenarized email has its content updated via API without touching the campaign itself

Steps overview

  1. Create a content library
  2. Create blocks in the library
  3. Reference blocks in your email HTML
  4. Import the HTML into a campaign
  5. Map the personalization tag
  6. Analyze click reports

Step 1. Create a content library

POST /external-content/v5/entities/{entity}/content-libraries

The library name cannot contain special characters and should be unambiguous — it will be used to reference blocks in your emails later.

Example request:

curl --location 'https://api.actito.com/external-content/v5/entities/actito/content-libraries' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer XXXX' \
--data '{
"name": "myLibrary",
"displayName": "My First Library"
}'

The response contains the library id, which you'll need in the next step.

Step 2. Create blocks in the content library

POST /external-content/v5/entities/{entity}/content-libraries/{libraryId}/contents

Key fields:

  • name — Cannot contain special characters. Used to reference the block in emails.
  • displayName and label — Used to identify blocks in the Actito UI.
  • html — The block's HTML content. Must be valid and properly escaped for JSON.

Example request:

curl --location 'https://api.actito.com/external-content/v5/entities/actito/content-libraries/500129/contents' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer XXXX' \
--data '{
"name": "first_block",
"displayName": "My first block",
"label": "firstLabel",
"html": "<div>This is the content of my very first block.</div>"
}'

A successful call returns a 200 response with the block id, required for future updates.

info

A library can contain up to 1,500 content blocks.

Updating a content block

PATCH /external-content/v5/entities/{entity}/content-libraries/{libraryId}/contents/{contentId}

Use this to update block content without touching the campaign itself — particularly useful for active scenarized emails, which cannot be updated as a whole via API.

tip

After patching a content block, allow up to 1 minute for the new content to be applied to triggered emails.

Visualizing blocks in the UI

Blocks can also be managed via the Manage content libraries app in the Actito interface, where marketers can browse libraries, preview block rendering, and validate HTML before use. Tech-savvy users can also create or edit blocks directly in the UI.

Step 3. Reference blocks in your email HTML

Use the data-actito-content attribute to embed content blocks in your email HTML. There are two approaches:

Static reference — All recipients see the same block. Useful when you want to update an active email's content by patching the block.

<span data-actito-content="@{content:myLibrary#first_block}">Default content if block is missing</span>

Dynamic reference — The block name is resolved via a personalization variable, allowing each profile to receive different content.

<span data-actito-content="@{content:myLibrary#${personalizedBlock}}">Default content if block is missing</span>
Handling missing blocks

Add data-actito-content-default="true" to display a fallback value if a content block is missing (e.g. due to an invalid personalization). Without it, the email will fail to generate.

<span
data-actito-content="@{content:myLibrary#${personalizedBlock}}"
data-actito-content-default="true"
>
This is the default value if missing content block
</span>

The default value can also be a fixed content block.

Using personalizations inside a content block

The HTML stored in a block can include ${variable} personalization variables:

{
"name": "perso_block",
"displayName": "Block with firstname",
"label": "secondLabel",
"html": "<div>Hello ${firstName}! This is the content of a personalized block.</div>"
}
info

Any personalization variable used inside a content block must also appear in the fixed part of the email HTML — otherwise it will not be resolved.

Combining content blocks with loop personalizations

Content blocks can be used inside loop personalizations to repeat dynamic content based on a profile's linked data.

Example: a movie theatre sends each subscriber the program for all their favorite theatres, stored in a Linked Data table.

<div data-actito-each="theater:${favoriteTheaters}">
<span>Favourite cinema code: ${theater.code}</span>
<span>Name: ${theater.name}</span>
<span data-actito-content="@{content:showtimeBlock#${theater.code}}" data-actito-link-id="link_2"></span>
</div>

Step 4. Import the HTML into a campaign

Import the HTML file into the email body via API:

POST /email-campaigns/v4/entity/{e}/mail/{m}/content/body

Alternatively, marketers can import the HTML file directly in the Actito UI. In the preview, static block content is rendered immediately, while dynamic blocks display a placeholder — the personalization tag is only resolved at send time.

Step 5. Map the personalization tag

Actito detects personalization tags used in dynamic content block references and requires them to be defined. There are three ways to handle this:

  • Profile attribute match — If the variable name matches an attribute in the profile table, it is mapped automatically. No action needed.
  • Mass campaigns — Push a personalization file via API to assign values to all profiles in the target:
POST /email-campaigns/v4/entity/{e}/mail/{m}/personalization
  • Scenarized and transactional campaigns — Pass the value in the API call that triggers the email for a specific profile:
POST /email-campaigns/v4/entity/{e}/mail/{m}/profile/{p}

or

POST /transactional-sendings/v4/entity/{e}/transactionalmail/{m}/contact

Example — trigger an email and resolve a dynamic block:

curl --location 'https://api.actito.com/email-campaigns/v4/entity/actito/mail/emailWithContentBlocks/profile/123' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer XXX' \
--data '[
{
"key": "personalizedContentBlock",
"values": ["second_block"]
}
]'

This triggers the emailWithContentBlocks email for profile 123, replacing ${personalizedContentBlock} with the second_block created in Step 2.

Step 6. Analyze click reports

When a content block contains links, clicks on that block are tracked as a single element — regardless of how many links the block contains or which specific block was shown to each profile.

Example: profile A sees image ONE and clicks it; profile B sees image TWO and clicks it. The report shows 2 clicks on the same header block reference.

info

Even if a content block contains multiple links, the entire block is tracked as a single clickable element.

Retrieve click results for a campaign via:

GET /email-campaigns/v5/entities/{entity}/email-campaigns/{campaignId}/click-results

Content block references appear as "type": "CONTENT" entries, separate from regular URL links:

{
"trackedElements": [
{
"type": "URL",
"reference": "https://www.actito.com",
"trackingName": "Actito",
"clicked": 3145
},
{
"type": "URL",
"reference": "https://www.actito.com/fr-BE/plateforme/pro",
"trackingName": "Actito PRO (FR)",
"clicked": 1589
},
{
"type": "CONTENT",
"reference": "@{content:library#social_media}",
"clicked": 1256
}
]
}