Runtime verified Differs from official docs Test scripts included

Syntax

Random(min, max)  →  number
2 arguments — exactly

Parameters

Name Type Required Description
min string | number Yes Lower bound (inclusive)
max string | number Yes Upper bound (inclusive)

Example

%%[
  VAR @pick
  SET @pick = Random(1, 3)
]%%
Variant: %%=v(@pick)=%%

Renders Variant: 1, 2 or 3 — both bounds are reachable.

Use it to pick one of a handful of content variants:

%%[
  VAR @pick
  SET @pick = Random(1, 2)
  IF @pick == 1 THEN
]%%
  First offer
%%[ ELSE ]%%
  Second offer
%%[ ENDIF ]%%

The bounds must be whole numbers — a decimal bound aborts the page, see below.

Return value

number — a random whole number within the supplied range.

Across roughly a hundred sampled calls, every returned value rendered as a bare integer; a decimal point never appeared. The value set is bounded only by the arguments you pass, so there is no fixed catalog of possible literals.

Behaviour

Both bounds are inclusive. A single call proves nothing about a range, so this was settled by bulk sampling tight ranges. Random(1, 2) sampled 30 times produced only 1 and 2, and produced both. Random(1, 3) sampled 30 times produced all of 1, 2, and 3 and nothing outside. Both ends of the range are genuinely reachable.

min == max returns that value. Random(5, 5) gives 5.

Argument order does not matter. Random(3, 1) does not abort — the bounds are treated as an unordered pair. Sampled 20 times it produced the full inclusive 13 range, exactly like Random(1, 3).

Negative ranges work. Random(-2, -1) sampled 20 times produced only -2 and -1, and produced both.

Whole-number strings are accepted. Random("1", "2") sampled 20 times behaved identically to the numeric form, with both bounds reachable.

Non-numeric input aborts the page. A non-numeric string (Random("abc", 3)) and a boolean-like string (Random("true", 3)) each abort the CloudPage with HTTP 422.

Decimal bounds are rejected

Four decimal forms were tried and all four failed identically:

Call Result
Random(1.2, 1.8) HTTP 422, page aborted
Random(1, 2.5) HTTP 422, page aborted
Random(1.0, 3.0) HTTP 422, page aborted
Random("1.5", "3.5") HTTP 422, page aborted

Note that Random(1.0, 3.0) fails too, even though the values are mathematically whole — writing the decimal point at all is enough to break the call. Meanwhile the equivalent whole-number calls and whole-number strings return values normally.

This is not an artefact of the test account: the same decimal calls were redeployed to the parent business unit and aborted there as well. Treat the bounds as integers only, and round or truncate before the call. The finding is catalogued on Differs from official docs.

Show test script
%%[
  VAR @b, @i, @s1, @s2
  SET @b = RequestParameter("b")

  /* inclusivity: sample tight ranges in bulk, then check the value set */
  IF @b == "rbounds" THEN
    SET @s1 = ""
    FOR @i = 1 TO 30 DO
      SET @s1 = Concat(@s1, Random(1,2), ",")
    NEXT @i
    OutputLine(Concat("Random(1,2)x30=[", @s1, "]"))

    SET @s2 = ""
    FOR @i = 1 TO 30 DO
      SET @s2 = Concat(@s2, Random(1,3), ",")
    NEXT @i
    OutputLine(Concat("Random(1,3)x30=[", @s2, "]"))

    OutputLine(Concat("Random(5,5)=[", Random(5,5), "]"))
  ENDIF

  /* reversed bounds: accepted, full inclusive range still produced */
  IF @b == "rmm" THEN
    SET @s1 = ""
    FOR @i = 1 TO 20 DO
      SET @s1 = Concat(@s1, Random(3,1), ",")
    NEXT @i
    OutputLine(Concat("Random(3,1)x20=[", @s1, "]"))
  ENDIF

  /* negative range */
  IF @b == "rneg" THEN
    SET @s1 = ""
    FOR @i = 1 TO 20 DO
      SET @s1 = Concat(@s1, Random(-2,-1), ",")
    NEXT @i
    OutputLine(Concat("Random(-2,-1)x20=[", @s1, "]"))
  ENDIF

  /* whole-number strings */
  IF @b == "rstr" THEN
    SET @s1 = ""
    FOR @i = 1 TO 20 DO
      SET @s1 = Concat(@s1, Random("1","2"), ",")
    NEXT @i
    OutputLine(Concat("Random('1','2')x20=[", @s1, "]"))
  ENDIF

  /* decimal bounds: every one of these aborts the page with HTTP 422 */
  IF @b == "rd1" THEN
    OutputLine(Concat("--- rd1 start ---"))
    OutputLine(Concat("Random(1.2,1.8)=[", Random(1.2,1.8), "]"))
  ENDIF

  IF @b == "rd2" THEN
    OutputLine(Concat("--- rd2 start ---"))
    OutputLine(Concat("Random(1,2.5)=[", Random(1,2.5), "]"))
  ENDIF

  IF @b == "rd3" THEN
    OutputLine(Concat("--- rd3 start ---"))
    OutputLine(Concat("Random(1.0,3.0)=[", Random(1.0,3.0), "]"))
  ENDIF

  IF @b == "rd4" THEN
    OutputLine(Concat("--- rd4 start ---"))
    OutputLine(Concat("Random('1.5','3.5')=[", Random("1.5","3.5"), "]"))
  ENDIF

  /* arity and type rejections */
  IF @b == "fewr" THEN
    OutputLine(Concat("--- fewr start ---"))
    OutputLine(Concat("Random(1)=[", Random(1), "]"))
  ENDIF

  IF @b == "manyr" THEN
    OutputLine(Concat("--- manyr start ---"))
    OutputLine(Concat("Random(1,2,3)=[", Random(1,2,3), "]"))
  ENDIF

  IF @b == "strr" THEN
    OutputLine(Concat("--- strr start ---"))
    OutputLine(Concat("Random('abc',3)=[", Random("abc",3), "]"))
  ENDIF

  IF @b == "boolr" THEN
    OutputLine(Concat("--- boolr start ---"))
    OutputLine(Concat("Random('true',3)=[", Random("true",3), "]"))
  ENDIF
]%%

Availability

Platform Available
Marketing Cloud Engagement Yes
Marketing Cloud Next Yes, from API 67.0

Unlike the arithmetic functions, Random is filed under the utilities section of the official reference rather than the math section — its availability table was read separately and states the same API 67.0 support for Next.

See also