Runtime verified Differs from official docs Test scripts included

Syntax

ClaimRow(dataExt, claimColumn, claimantColumn, claimantValue)  →  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

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. This schema was created via the API and advanced correctly — no Contact Builder UI wizard was required.

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.

Show test script
%%[
  VAR @b, @em, @i, @code, @rs, @row, @cr

  SET @b = RequestParameter("b")
  SET @em = RequestParameter("em")

  /* 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
]%%

Availability

Platform Available
Marketing Cloud Engagement Yes
Marketing Cloud Next No

See also