IsEmailAddress
Checks a value against email address syntax only. Runtime-proven on a live Marketing Cloud Engagement CloudPage — including a domain without a top-level domain, which the official reference documents as valid and the engine rejects.
Syntax
IsEmailAddress(value) → boolean
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
value |
string | Yes | Value to validate; trim it first, as a leading or trailing space fails |
Example
%%[ VAR @ok SET @ok = IsEmailAddress("tomas.q@example.com") ]%%
%%=v(@ok)=%%
Renders True.
Validating a form field means trimming it first — the raw value from a query string keeps its spaces, and a space is enough to fail the check:
%%[
VAR @input, @ok
SET @input = Trim(RequestParameter("email"))
SET @ok = IsEmailAddress(@input)
]%%
%%=IIf(@ok, "thanks", "please check that address")=%%
Return value
boolean — True for a syntactically valid address, False otherwise.
Both literals were produced in the same render, as the capitalised words True and False. They are genuine booleans: each compares equal to the corresponding boolean value, so IIf and IF consume the result directly.
Behaviour
The check is syntax only. A well-formed address at a domain that resolves to nothing still returns True, so nothing here says the mailbox can receive mail.
A leading or trailing space fails. IsEmailAddress(" tomas.q@example.com") and the same address with a trailing space both return False, while the trimmed form returns True. No source mentions this, and an untrimmed form field is the usual way to meet it.
Local-part decoration is fine. A plus tag, dots, hyphens, underscores and digits are all accepted — a.b-c_d+e9@x-y.z.example.museum returns True.
Multi-label domains are accepted. tomas.q@mail.corp.example.com returns True.
A number does not abort the call. IsEmailAddress(123) returns False, as does the empty string.
Which inputs are accepted
| Call | Renders |
|---|---|
IsEmailAddress("tomas.q@example.com") |
True |
IsEmailAddress("tomas.q+news@example.com") |
True |
IsEmailAddress("tomas.q@mail.corp.example.com") |
True |
IsEmailAddress("a.b-c_d+e9@x-y.z.example.museum") |
True |
IsEmailAddress("tomas.q@example") |
False |
IsEmailAddress("tomas.q.example.com") |
False |
IsEmailAddress(" tomas.q@example.com") |
False |
IsEmailAddress("tomas.q@example.com ") |
False |
IsEmailAddress("a@b@example.com") |
False |
IsEmailAddress("@example.com") |
False |
IsEmailAddress("a@.com") |
False |
IsEmailAddress("") |
False |
A domain with no top-level domain is rejected
The official reference lists an address whose domain is a single label — no .com, no dot at all — as a valid result, with a note that such domains do exist. The engine returns False for that shape. Every other example in the same table matched what the engine did. See the differs-from-docs card.
Show test script
%%[
VAR @b
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"), "]"))
/* the accepted/rejected matrix - safe on every request */
OutputLine(Concat("--- E start ---"))
OutputLine(Concat("E1_valid=[", IsEmailAddress("tomas.q@example.com"), "]"))
OutputLine(Concat("E2_plustag=[", IsEmailAddress("tomas.q+news@example.com"), "]"))
OutputLine(Concat("E3_subdomain=[", IsEmailAddress("tomas.q@mail.corp.example.com"), "]"))
OutputLine(Concat("E4_no_at=[", IsEmailAddress("tomas.q.example.com"), "]"))
OutputLine(Concat("E5_no_tld=[", IsEmailAddress("tomas.q@example"), "]"))
OutputLine(Concat("E6_lead_space=[", IsEmailAddress(" tomas.q@example.com"), "]"))
OutputLine(Concat("E7_trail_space=[", IsEmailAddress("tomas.q@example.com "), "]"))
OutputLine(Concat("E8_absurd=[", IsEmailAddress("a.b-c_d+e9@x-y.z.example.museum"), "]"))
OutputLine(Concat("E9_double_at=[", IsEmailAddress("a@b@example.com"), "]"))
OutputLine(Concat("E10_no_local=[", IsEmailAddress("@example.com"), "]"))
OutputLine(Concat("E11_no_sld=[", IsEmailAddress("a@.com"), "]"))
OutputLine(Concat("--- E done ---"))
/* the empty string, in its own branch: the sibling IsCHTMLBrowser aborts
on it, so the four functions must not share one empty-string branch */
IF @b == "e_empty" THEN
OutputLine(Concat("--- e_empty start ---"))
OutputLine(Concat("E_EMPTY=[", IsEmailAddress(""), "]"))
OutputLine(Concat("--- e_empty done ---"))
ENDIF
/* a non-string argument */
IF @b == "g_num" THEN
OutputLine(Concat("--- g_num start ---"))
OutputLine(Concat("E_NUM=[", IsEmailAddress(123), "]"))
OutputLine(Concat("--- g_num done ---"))
ENDIF
/* the rendered literals compared against real booleans */
IF @b == "g_tok" THEN
OutputLine(Concat("--- g_tok start ---"))
OutputLine(Concat("E_EQTRUE=[", IIf(IsEmailAddress("tomas.q@example.com") == true, "matches-true", "no"), "]"))
OutputLine(Concat("E_EQFALSE=[", IIf(IsEmailAddress("nope") == false, "matches-false", "no"), "]"))
OutputLine(Concat("--- g_tok 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 | No |
See also
- Domain — extracts the domain from an address, and performs no validation of its own
- IsPhoneNumber — the sibling format check for telephone numbers
- The single-label domain the docs accept
- Official reference · ampscript.guide