Output
Writes the result of a nested function call into the rendered content. Runtime-proven on a live Marketing Cloud Engagement CloudPage — including a string literal argument, which renders nothing at all rather than the error the official reference promises.
Syntax
Output(content) → void
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
content |
function call | Yes | Function call whose result is written; a literal or bare variable renders nothing |
There is no upper bound on the argument count — several values are written in turn — but the single-argument form is the only one the official reference supports.
Example
%%[ Output(Concat("Hello ", "world")) ]%%
Renders Hello world.
The value must go through a function call, so a plain string needs a single-argument Concat around it:
%%[
VAR @label
SET @label = "checkpoint reached"
Output(Concat(@label))
]%%
Passing @label directly renders nothing at all, silently — see below.
Return value
void — nothing is returned.
There is no value to test for, and no closed set of sentinel values. Because nothing comes back, the call cannot be nested inside another function: placing it inside a Concat aborts the surrounding block with HTTP 422.
Behaviour
Exactly the argument is written, and nothing else. A pair of delimiters written by their own calls came back as <O1>A</O1> on one line, with no space, no break and no wrapping element around the value. That is the entire difference from OutputLine, which appends a carriage return and line feed.
An argument that produces no text writes nothing. <O2></O2> came back with the delimiters adjacent — not even a space.
Several arguments are written in turn. Two arguments rendered ab and three rendered abc, with no separator inserted. A call with no argument at all is accepted too and writes nothing.
A number or a date is accepted but renders nothing. Output(123) came back empty, while the same date routed through FormatDate rendered 2026-08-08. The argument is a function call, not a scalar — so this is not a type that can be widened.
The literal argument that vanishes
The official reference states that a value which is not a function call makes this function return an error. It does not. A string literal, a bare variable and a bare number each render nothing, at HTTP 200, with every surrounding marker printing normally:
| Call | Renders |
|---|---|
Output(Concat("A")) |
A |
Output("bare") |
(nothing) |
Output(@v) where @v is "vee" |
(nothing) |
Output(123) |
(nothing) |
Output() |
(nothing) |
A debugging line written this way disappears without any signal that something went wrong. See the differs-from-docs card.
Show test script
%%[
VAR @b, @v
SET @b = RequestParameter("b")
/* known-good control: renders on every request, so a run of HTTP 422s
can be told apart from a broken deploy */
OutputLine(Concat("CTRL=[", Uppercase("ok"), "]"))
/* what is written, delimited so any injected byte is visible.
Compare each pair against its OutputLine twin below it. */
OutputLine(Concat("--- O start ---"))
Output(Concat("<O1>"))
Output(Concat("A"))
Output(Concat("</O1>"))
OutputLine(Concat(""))
Output(Concat("<L1>"))
OutputLine(Concat("A"))
Output(Concat("</L1>"))
OutputLine(Concat(""))
/* an argument that produces no text */
Output(Concat("<O2>"))
Output(Concat(""))
Output(Concat("</O2>"))
OutputLine(Concat(""))
/* a bare literal and a bare variable: both render nothing */
SET @v = "vee"
Output(Concat("<O3>"))
Output("bare")
Output(Concat("</O3>"))
OutputLine(Concat(""))
Output(Concat("<O4>"))
Output(@v)
Output(Concat("</O4>"))
OutputLine(Concat(""))
OutputLine(Concat("--- O done ---"))
/* argument counts the catalogued signature does not allow */
IF @b == "arity" THEN
OutputLine(Concat("--- arity start ---"))
Output()
Output(Concat("a"), Concat("b"))
OutputLine(Concat(""))
Output(Concat("a"), Concat("b"), Concat("c"))
OutputLine(Concat(""))
OutputLine(Concat("--- arity done ---"))
ENDIF
/* nesting the call inside another function: aborts this branch only */
IF @b == "nest" THEN
OutputLine(Concat("--- nest start ---"))
OutputLine(Concat("NEST=[", Concat("x", Output(Concat("y")), "z"), "]"))
OutputLine(Concat("--- nest done ---"))
ENDIF
/* non-string arguments */
IF @b == "nonstr" THEN
OutputLine(Concat("--- nonstr start ---"))
Output(Concat("<N1>"))
Output(123)
Output(Concat("</N1>"))
OutputLine(Concat(""))
Output(Concat("<N2>"))
Output(FormatDate(Now(), "yyyy-MM-dd"))
Output(Concat("</N2>"))
OutputLine(Concat(""))
OutputLine(Concat("--- nonstr done ---"))
ENDIF
]%%
Every marker and label in the test script goes through Concat(...), including single-argument ones. A bare string literal passed to OutputLine renders an empty line while the page still returns HTTP 200, so the marker silently vanishes.
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | Yes, from API 67.0 |
See also
- OutputLine — the same, plus a carriage return and line feed
- Differs from docs: the literal argument
- Official reference · ampscript.guide