ClaimRow
Claims the next unclaimed row of a data extension for a caller and returns the whole row, flipping its claim flag and recording the claimant.
Syntax
ClaimRow(dataExt, claimColumn, claimantColumn, claimantValue[, additionalColumnNameN, additionalColumnValueN, ...]) → row
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
dataExt |
string | Yes | Name or external key of the claimable data extension |
claimColumn |
string | Yes | Boolean column that marks a row as claimed; must be required and default to False |
claimantColumn |
string | Yes | Column written with the claimant value when a row is claimed |
claimantValue |
string | Yes | The value identifying who is claiming — a distinct value claims the next row; a repeated value returns that claimant’s existing row |
additionalColumnNameN |
string | No | Name of a further column to write on the claimed row (record extra context at claim time). Repeatable as name/value pairs. |
additionalColumnValueN |
string | No | Value written to the paired additionalColumnNameN column on the claimed row |
Example
%%[
VAR @row
SET @row = ClaimRow("Coupons", "IsClaimed", "EmailAddress", emailaddr)
]%%
Your code: %%=Field(@row, "CouponCode")=%%
Each distinct claimantValue claims the next unclaimed row: the first caller receives the first unclaimed row, the second caller the next one, and so on. The claimed row’s claimColumn flips to True and its claimantColumn records the claimant. A claimant date column, if present, is auto-populated.
Return value
row — the claimed row. Read individual columns with Field. When the data extension has no unclaimed rows left, an empty row is returned (see Behaviour) — guard it with Empty. The scalar twin ClaimRowValue returns a single column value plus a fallback instead of the whole row.
Behaviour
Distinct claimants advance; a repeated claimant does not. Claiming is keyed on claimantValue. Passing a new value claims the next unclaimed row and advances. Passing a value that already holds a row returns that same row without advancing — per-subscriber idempotency, so a subscriber re-opening an email keeps the same coupon.
A claimable data extension needs the documented schema. A text primary key, a claimant text column, a required non-nullable Boolean claim column defaulting to False, and (optionally) a nullable claimant date column.
Exhaustion returns an empty row, not an exception. The official reference says ClaimRow returns an exception when no unclaimed rows remain. At runtime it returns an empty row and the page keeps rendering, so Empty() on the result is true and nothing aborts. Guard with Empty() rather than expecting a raised error.
Optional trailing name/value pairs record extra columns on the claimed row. Beyond the four required arguments you may append repeated columnName, columnValue pairs. Each pair is written to the claimed row alongside the claim, so ClaimRow("Coupons", "IsClaimed", "EmailAddress", emailaddr, "Region", "Central") records Region = Central on the row it claims. The returned row carries the extra column value, and it persists to the data extension. The pairs record additional context — they are not extra filter criteria for choosing which row to claim.
AMPscript caches data-extension reads within a single render. Drive advancement across separate HTTP requests, each passing a distinct claimant — a single render that claims repeatedly reads the cached state and appears not to advance.
Show test script
%%[
VAR @b, @em, @rg, @i, @code, @rs, @row, @cr
SET @b = RequestParameter("b")
SET @em = RequestParameter("em")
SET @rg = RequestParameter("rg")
/* reset: reseed C1..C4 all unclaimed (delete then insert - never pass an
empty string to the Date column, that aborts the page) */
IF @b == "reset" THEN
SET @rs = DeleteData("AMP_VERIFY_CLAIM", "CouponCode", "C1")
SET @rs = DeleteData("AMP_VERIFY_CLAIM", "CouponCode", "C2")
SET @rs = DeleteData("AMP_VERIFY_CLAIM", "CouponCode", "C3")
SET @rs = DeleteData("AMP_VERIFY_CLAIM", "CouponCode", "C4")
SET @rs = InsertData("AMP_VERIFY_CLAIM", "CouponCode", "C1", "IsClaimed", "False")
SET @rs = InsertData("AMP_VERIFY_CLAIM", "CouponCode", "C2", "IsClaimed", "False")
SET @rs = InsertData("AMP_VERIFY_CLAIM", "CouponCode", "C3", "IsClaimed", "False")
SET @rs = InsertData("AMP_VERIFY_CLAIM", "CouponCode", "C4", "IsClaimed", "False")
OutputLine(Concat("reset done"))
ENDIF
/* dump: read each known coupon row by its PK and print its claim state */
IF @b == "dump" THEN
FOR @i = 1 TO 4 DO
SET @code = Concat("C", @i)
SET @rs = LookupRows("AMP_VERIFY_CLAIM", "CouponCode", @code)
IF RowCount(@rs) > 0 THEN
SET @row = Row(@rs, 1)
OutputLine(Concat(@code, ": IsClaimed=[", Field(@row, "IsClaimed"), "] EmailAddress=[", Field(@row, "EmailAddress"), "] ClaimedDate=[", Field(@row, "ClaimedDate"), "]"))
ELSE
OutputLine(Concat(@code, ": MISSING"))
ENDIF
NEXT @i
ENDIF
/* claim: claim the next unclaimed row for the given distinct claimant.
An exhausted DE returns an EMPTY row (Empty() true) rather than raising. */
IF @b == "claim" THEN
SET @cr = ClaimRow("AMP_VERIFY_CLAIM", "IsClaimed", "EmailAddress", @em)
IF Empty(@cr) THEN
OutputLine(Concat("claim em=[", @em, "] -> EMPTY row"))
ELSE
OutputLine(Concat("claim em=[", @em, "] -> CouponCode=[", Field(@cr, "CouponCode"), "] IsClaimed=[", Field(@cr, "IsClaimed"), "] EmailAddress=[", Field(@cr, "EmailAddress"), "]"))
ENDIF
ENDIF
/* claimpair: claim AND record an extra column via an optional trailing
name/value pair beyond the 4 required args. The returned row carries the
extra value and it persists to the DE (verify with ?b=dump-style reads). */
IF @b == "claimpair" THEN
SET @cr = ClaimRow("AMP_VERIFY_CLAIM", "IsClaimed", "EmailAddress", @em, "Region", @rg)
IF Empty(@cr) THEN
OutputLine(Concat("claimpair em=[", @em, "] -> EMPTY row"))
ELSE
OutputLine(Concat("claimpair em=[", @em, "] -> CouponCode=[", Field(@cr, "CouponCode"), "] EmailAddress=[", Field(@cr, "EmailAddress"), "] Region=[", Field(@cr, "Region"), "]"))
ENDIF
ENDIF
]%%
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | Yes, from API 68.0 |
See also
ClaimRowValue— the scalar twin; returns one column value plus a fallback when exhaustedEmpty— guard the exhausted-DE empty rowFieldLookupRows- Official reference
- ampscript.guide