Text card, Neo-brutalist 1.0.0
| Template | Text card, tpl_71aae4d0157f |
|---|---|
| Variant | Neo-brutalist |
| Version | 1.0.0, the newest: what a channel following this variant draws |
| Shapes | 9x16, 4x5, 1x1, 16x9, 2x3 |
| Length | 20 seconds |
Example video
The 1x1 cut of this version, drawn from its own worked example. Open the video on its own.
What it accepts
One to twelve statements shown one at a time, large, with the words that carry each one marked, under an optional kicker and over who said them. metaData is the post's title, descriptions and hashtags and is never drawn.
| Field | Type | Required | Limit | What it is |
|---|---|---|---|---|
clipData | group | yes | Clip data: Everything drawn: a kicker, the statements one after another with the words each one marks, who said or published them, the source and the look. | |
clipData.kicker | text | up to 20 characters | Kicker: A word above the statements, such as BREAKING or ANNOUNCEMENT. | |
clipData.statements | list | yes | at least 1, up to 12 | Statements: Shown one at a time, in this order, each for a share of the clip that grows with its length. Each adds about four and a half seconds; twelve run just under a minute. |
clipData.statements[] | group | Statement | ||
clipData.statements[].text | text | yes | up to 120 characters | Statement |
clipData.statements[].highlight | text | up to 60 characters | Words to mark: Words from the statement, written exactly as they appear in it, marked as with a highlighter. Left out, nothing is marked. | |
clipData.attribution | text | up to 60 characters | Attribution: Who said or published the statements, shown under them throughout. | |
clipData.source | text | up to 60 characters | Source | |
clipData.look | group | Look: How the clip looks and moves within its style. The same four switches in every format of the collections. Leave a switch out, or set it to the style's own, and the style decides. | ||
clipData.look.theme | enum | auto, brand, light, dark, bold | Theme: The style's own choice; your brand's own colours and background; a light or dark page tinted with your brand colour; or your brand colour as the page. | |
clipData.look.pace | enum | auto, calm, standard, punchy | Pace: How things arrive: the style's own rhythm, calm fades, a standard rhythm, or punchy slams and cuts. | |
clipData.look.corners | enum | auto, square, soft, round | Corners: The shape of cards, panels and marks. | |
clipData.look.align | enum | auto, start, centre | Text alignment: Where the text lines up. | |
metaData | group | Meta data: Everything about the post that is never drawn in the clip: its title, its description in four lengths, one per kind of platform, and its hashtags. Reelwire adds the brand's description, link and hashtags after it. Left out, the post text is generated from the clip data. | ||
metaData.title | text | up to 100 characters | Title: Used where the platform has a title of its own: Facebook Feed, LinkedIn, Pinterest and YouTube. Up to 100 characters, which every one of them takes. | |
metaData.captionTiny | text | up to 200 characters | Tiny description (Pinterest, Threads, X): Up to 200 characters. The brand's description, link and hashtags follow it within the platform's limit. | |
metaData.captionShort | text | up to 500 characters | Short description (Telegram, Threema, WeChat, WhatsApp): Up to 500 characters. The brand's description, link and hashtags follow it within the platform's limit. | |
metaData.captionMedium | text | up to 1500 characters | Medium description (Discord, Facebook Reels, Instagram, LinkedIn, Signal, Slack, TikTok): Up to 1500 characters. The brand's description, link and hashtags follow it within the platform's limit. | |
metaData.captionLong | text | up to 4000 characters | Long description (Facebook Feed, YouTube): Up to 4000 characters. The brand's description, link and hashtags follow it within the platform's limit. | |
metaData.hashtags | list | up to 15 | Hashtags: Written without the #. Up to 15, which every platform takes. | |
metaData.hashtags[] | text | up to 60 characters | Hashtag |
locales carries other languages: under each language code, the parts of clipData and metaData that differ, laid over the default, so a language with no copy still renders.
A picture is always a file from your media library: media:// followed by its id or its name.
Anything the table does not list is refused, and so is anything over its limit, with a 422 that
names the field.
The JSON Schema
{
"type": "object",
"properties": {
"clipData": {
"type": "object",
"properties": {
"kicker": {
"type": "string",
"maxLength": 20,
"title": "Kicker",
"description": "A word above the statements, such as BREAKING or ANNOUNCEMENT."
},
"statements": {
"type": "array",
"items": {
"type": "object",
"properties": {
"text": {
"type": "string",
"maxLength": 120,
"title": "Statement"
},
"highlight": {
"type": "string",
"maxLength": 60,
"title": "Words to mark",
"description": "Words from the statement, written exactly as they appear in it, marked as with a highlighter. Left out, nothing is marked."
}
},
"required": [
"text"
],
"additionalProperties": false,
"title": "Statement"
},
"minItems": 1,
"maxItems": 12,
"title": "Statements",
"description": "Shown one at a time, in this order, each for a share of the clip that grows with its length. Each adds about four and a half seconds; twelve run just under a minute."
},
"attribution": {
"type": "string",
"maxLength": 60,
"title": "Attribution",
"description": "Who said or published the statements, shown under them throughout."
},
"source": {
"type": "string",
"maxLength": 60,
"title": "Source"
},
"look": {
"type": "object",
"properties": {
"theme": {
"type": "string",
"enum": [
"auto",
"brand",
"light",
"dark",
"bold"
],
"title": "Theme",
"description": "The style's own choice; your brand's own colours and background; a light or dark page tinted with your brand colour; or your brand colour as the page."
},
"pace": {
"type": "string",
"enum": [
"auto",
"calm",
"standard",
"punchy"
],
"title": "Pace",
"description": "How things arrive: the style's own rhythm, calm fades, a standard rhythm, or punchy slams and cuts."
},
"corners": {
"type": "string",
"enum": [
"auto",
"square",
"soft",
"round"
],
"title": "Corners",
"description": "The shape of cards, panels and marks."
},
"align": {
"type": "string",
"enum": [
"auto",
"start",
"centre"
],
"title": "Text alignment",
"description": "Where the text lines up."
}
},
"additionalProperties": false,
"title": "Look",
"description": "How the clip looks and moves within its style. The same four switches in every format of the collections. Leave a switch out, or set it to the style's own, and the style decides."
}
},
"required": [
"statements"
],
"additionalProperties": false,
"title": "Clip data",
"description": "Everything drawn: a kicker, the statements one after another with the words each one marks, who said or published them, the source and the look."
},
"metaData": {
"type": "object",
"properties": {
"title": {
"type": "string",
"maxLength": 100,
"title": "Title",
"description": "Used where the platform has a title of its own: Facebook Feed, LinkedIn, Pinterest and YouTube. Up to 100 characters, which every one of them takes."
},
"captionTiny": {
"type": "string",
"maxLength": 200,
"title": "Tiny description (Pinterest, Threads, X)",
"description": "Up to 200 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"captionShort": {
"type": "string",
"maxLength": 500,
"title": "Short description (Telegram, Threema, WeChat, WhatsApp)",
"description": "Up to 500 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"captionMedium": {
"type": "string",
"maxLength": 1500,
"title": "Medium description (Discord, Facebook Reels, Instagram, LinkedIn, Signal, Slack, TikTok)",
"description": "Up to 1500 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"captionLong": {
"type": "string",
"maxLength": 4000,
"title": "Long description (Facebook Feed, YouTube)",
"description": "Up to 4000 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"hashtags": {
"type": "array",
"items": {
"type": "string",
"maxLength": 60,
"title": "Hashtag"
},
"maxItems": 15,
"title": "Hashtags",
"description": "Written without the #. Up to 15, which every platform takes."
}
},
"additionalProperties": false,
"title": "Meta data",
"description": "Everything about the post that is never drawn in the clip: its title, its description in four lengths, one per kind of platform, and its hashtags. Reelwire adds the brand's description, link and hashtags after it. Left out, the post text is generated from the clip data."
},
"locales": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"clipData": {
"type": "object",
"properties": {
"kicker": {
"type": "string",
"maxLength": 20,
"title": "Kicker",
"description": "A word above the statements, such as BREAKING or ANNOUNCEMENT."
},
"statements": {
"type": "array",
"items": {
"type": "object",
"properties": {
"text": {
"type": "string",
"maxLength": 120,
"title": "Statement"
},
"highlight": {
"type": "string",
"maxLength": 60,
"title": "Words to mark",
"description": "Words from the statement, written exactly as they appear in it, marked as with a highlighter. Left out, nothing is marked."
}
},
"required": [
"text"
],
"additionalProperties": false,
"title": "Statement"
},
"minItems": 1,
"maxItems": 12,
"title": "Statements",
"description": "Shown one at a time, in this order, each for a share of the clip that grows with its length. Each adds about four and a half seconds; twelve run just under a minute."
},
"attribution": {
"type": "string",
"maxLength": 60,
"title": "Attribution",
"description": "Who said or published the statements, shown under them throughout."
},
"source": {
"type": "string",
"maxLength": 60,
"title": "Source"
},
"look": {
"type": "object",
"properties": {
"theme": {
"type": "string",
"enum": [
"auto",
"brand",
"light",
"dark",
"bold"
],
"title": "Theme",
"description": "The style's own choice; your brand's own colours and background; a light or dark page tinted with your brand colour; or your brand colour as the page."
},
"pace": {
"type": "string",
"enum": [
"auto",
"calm",
"standard",
"punchy"
],
"title": "Pace",
"description": "How things arrive: the style's own rhythm, calm fades, a standard rhythm, or punchy slams and cuts."
},
"corners": {
"type": "string",
"enum": [
"auto",
"square",
"soft",
"round"
],
"title": "Corners",
"description": "The shape of cards, panels and marks."
},
"align": {
"type": "string",
"enum": [
"auto",
"start",
"centre"
],
"title": "Text alignment",
"description": "Where the text lines up."
}
},
"additionalProperties": false,
"title": "Look",
"description": "How the clip looks and moves within its style. The same four switches in every format of the collections. Leave a switch out, or set it to the style's own, and the style decides."
}
},
"additionalProperties": false,
"title": "Clip data",
"description": "Everything drawn: a kicker, the statements one after another with the words each one marks, who said or published them, the source and the look."
},
"metaData": {
"type": "object",
"properties": {
"title": {
"type": "string",
"maxLength": 100,
"title": "Title",
"description": "Used where the platform has a title of its own: Facebook Feed, LinkedIn, Pinterest and YouTube. Up to 100 characters, which every one of them takes."
},
"captionTiny": {
"type": "string",
"maxLength": 200,
"title": "Tiny description (Pinterest, Threads, X)",
"description": "Up to 200 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"captionShort": {
"type": "string",
"maxLength": 500,
"title": "Short description (Telegram, Threema, WeChat, WhatsApp)",
"description": "Up to 500 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"captionMedium": {
"type": "string",
"maxLength": 1500,
"title": "Medium description (Discord, Facebook Reels, Instagram, LinkedIn, Signal, Slack, TikTok)",
"description": "Up to 1500 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"captionLong": {
"type": "string",
"maxLength": 4000,
"title": "Long description (Facebook Feed, YouTube)",
"description": "Up to 4000 characters. The brand's description, link and hashtags follow it within the platform's limit."
},
"hashtags": {
"type": "array",
"items": {
"type": "string",
"maxLength": 60,
"title": "Hashtag"
},
"maxItems": 15,
"title": "Hashtags",
"description": "Written without the #. Up to 15, which every platform takes."
}
},
"additionalProperties": false,
"title": "Meta data",
"description": "Everything about the post that is never drawn in the clip: its title, its description in four lengths, one per kind of platform, and its hashtags. Reelwire adds the brand's description, link and hashtags after it. Left out, the post text is generated from the clip data."
}
},
"additionalProperties": false
},
"propertyNames": {
"enum": [
"aa",
"ab",
"ae",
"af",
"ak",
"am",
"an",
"ar",
"as",
"av",
"ay",
"az",
"ba",
"be",
"bg",
"bi",
"bm",
"bn",
"bo",
"br",
"bs",
"ca",
"ce",
"ch",
"co",
"cr",
"cs",
"cu",
"cv",
"cy",
"da",
"de",
"dv",
"dz",
"ee",
"el",
"en",
"eo",
"es",
"et",
"eu",
"fa",
"ff",
"fi",
"fj",
"fo",
"fr",
"fy",
"ga",
"gd",
"gl",
"gn",
"gu",
"gv",
"ha",
"he",
"hi",
"ho",
"hr",
"ht",
"hu",
"hy",
"hz",
"ia",
"id",
"ie",
"ig",
"ii",
"ik",
"io",
"is",
"it",
"iu",
"ja",
"jv",
"ka",
"kg",
"ki",
"kj",
"kk",
"kl",
"km",
"kn",
"ko",
"kr",
"ks",
"ku",
"kv",
"kw",
"ky",
"la",
"lb",
"lg",
"li",
"ln",
"lo",
"lt",
"lu",
"lv",
"mg",
"mh",
"mi",
"mk",
"ml",
"mn",
"mr",
"ms",
"mt",
"my",
"na",
"nb",
"nd",
"ne",
"ng",
"nl",
"nn",
"no",
"nr",
"nv",
"ny",
"oc",
"oj",
"om",
"or",
"os",
"pa",
"pi",
"pl",
"ps",
"pt",
"qu",
"rm",
"rn",
"ro",
"ru",
"rw",
"sa",
"sc",
"sd",
"se",
"sg",
"si",
"sk",
"sl",
"sm",
"sn",
"so",
"sq",
"sr",
"ss",
"st",
"su",
"sv",
"sw",
"ta",
"te",
"tg",
"th",
"ti",
"tk",
"tl",
"tn",
"to",
"tr",
"ts",
"tt",
"tw",
"ty",
"ug",
"uk",
"ur",
"uz",
"ve",
"vi",
"vo",
"wa",
"wo",
"xh",
"yi",
"yo",
"za",
"zh",
"zu",
"zh-CN",
"zh-TW",
"pt-BR"
]
}
}
},
"required": [
"clipData"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Ask Reelwire for the same document yourself, without signing in:
curl "http://localhost:4000/v1/formats/template/tpl_71aae4d0157f?variant=Neo-brutalist&version=1.0.0"
Delivery JSON
Your own system sends this to one of your streams, POST /v1/stream, and every channel listening to
that stream draws it with its template. data is the document described above; a stream with an
empty field map passes it to the template unchanged. Try it first on POST /v1/stream/validate,
which answers the same without publishing anything. Streams and feeds
explains the rest, including how to map a document of your own shape instead.
{
"streamId": "st_your_stream_id",
"eventId": "01M2SQMKK3G1NVFXV31DCBVB95",
"occurredAt": "2026-09-23T07:00:00Z",
"locale": "en",
"data": {
"clipData": {
"kicker": "Breaking",
"statements": [
{
"text": "The Bank of Arden cuts its main interest rate by a quarter point to 3.75%, its first cut in more than four years.",
"highlight": "a quarter point to 3.75%"
},
{
"text": "Governor Mara Ellison says inflation is now close enough to the 2% target for the bank to begin easing policy.",
"highlight": "close enough to the 2% target"
},
{
"text": "Households on tracker mortgages will see lower monthly payments from their next statement, the bank says.",
"highlight": "lower monthly payments"
},
{
"text": "The next decision is due on 10 December. Markets now price in two further cuts before the end of next year.",
"highlight": "two further cuts"
}
],
"attribution": "Bank of Arden, monetary policy statement",
"source": "Bank of Arden, 1 October 2026, 13:00 local time",
"look": {
"theme": "auto",
"pace": "auto",
"corners": "auto",
"align": "auto"
}
},
"metaData": {
"title": "Bank of Arden cuts its main rate to 3.75%, the first cut in more than four years",
"captionTiny": "Breaking: the Bank of Arden cuts its main rate by a quarter point to 3.75%, its first cut in more than four years. Tracker mortgages get cheaper from the next statement.",
"captionShort": "Breaking: the Bank of Arden has cut its main interest rate by a quarter point to 3.75%, its first cut in more than four years. Governor Mara Ellison said inflation is now close enough to the 2% target for the bank to begin easing. Households on tracker mortgages will see lower payments from their next statement. The next decision is due on 10 December, and markets now price in two further cuts before the end of next year.",
"captionMedium": "Breaking: the Bank of Arden has cut its main interest rate by a quarter point to 3.75%. It is the bank's first cut in more than four years, and it came a little earlier than most economists had expected at the start of the summer.\n\nGovernor Mara Ellison told reporters that inflation is now close enough to the 2% target for the bank to begin easing policy, while warning that the path from here depends on wages and energy prices over the winter.\n\nWhat it means for households: anybody on a tracker mortgage will see lower monthly payments from their next statement. Fixed-rate borrowers see no change until their deal ends, but new fixed offers have already been falling for several weeks as lenders anticipated the move. Savers can expect easy-access rates to drift lower over the coming months.\n\nWhat comes next: the next decision is due on 10 December. Markets now price in two further cuts before the end of next year, which would take the main rate to 3.25%.\n\nFigures are illustrative and the bank, governor and dates are fictional.",
"captionLong": "Breaking: the Bank of Arden has cut its main interest rate by a quarter point to 3.75%. It is the bank's first cut in more than four years, and it came a little earlier than most economists had expected at the start of the summer, when the bank was still warning that services inflation was proving stubborn.\n\nWhat the bank said: Governor Mara Ellison told reporters that inflation is now close enough to the 2% target for the bank to begin easing policy. She stressed that this was the start of a gradual path rather than a sharp turn, and that the committee would watch wages and energy prices over the winter before deciding how far and how fast to go. The vote was seven to two, with the two dissenting members preferring to wait until December.\n\nWhy now: headline inflation has fallen for five months in a row and stood at 2.4% in August. Wage growth has slowed from its peak, and the bank's own surveys show fewer firms planning large price rises. Growth has been weak, with the economy barely expanding over the past two quarters, which strengthened the case for a first move.\n\nWhat it means for households: anybody on a tracker mortgage will see lower monthly payments from their next statement. Fixed-rate borrowers see no change until their deal ends, but new fixed offers have already been falling for several weeks as lenders anticipated the move. Savers can expect easy-access rates to drift lower over the coming months, so it may be worth checking whether a fixed-term account still pays more.\n\nWhat it means for businesses: firms with variable-rate loans will pay a little less interest, and the bank hopes the move will support investment decisions that were put on hold during the period of high rates. Business groups welcomed the cut but said a single quarter point would not change much on its own.\n\nWhat comes next: the next decision is due on 10 December. Markets now price in two further cuts before the end of next year, which would take the main rate to 3.25%. The bank's next set of forecasts will be published alongside the December decision.\n\nFigures are illustrative and the bank, governor and dates are fictional. This is not financial advice.",
"hashtags": [
"interestrates",
"centralbank",
"ratecut",
"mortgages",
"inflation",
"economy",
"breakingnews",
"markets",
"personalfinance",
"savings"
]
}
}
}
The delivery names no version: which build draws it is the channel's choice, the newest of its
variant or the one it is pinned to. eventId is a ULID you make once per event: sending the same
one again changes nothing. occurredAt is when the thing happened, not when you sent it. locale
is the language of the text in data, and data.locales carries other languages beside it.