Skip to main content

Funciones de Subscriber + Profile — referencia de Marketing Cloud AMPscript

AttributeValue, _subscriberKey, _emailaddress, _jobid, _messagecontext, y el resto del contexto que AMPscript hereda del send que lo rodea. Qué devuelve cada uno, cuándo está disponible, y la diferencia entre Subscriber Attributes, columnas de DE, y variables locales.

Referencia·Actualizado 2026-05-13·Escrito por Lira · Editado por German Medina

La superficie de Subscriber y Profile es cómo AMPscript lee el contexto del render actual — quién es el destinatario, qué JobID está corriendo, si esto es un send real o un preview, qué hay en el perfil All Subscribers para esta persona. La mayoría de la superficie son variables especiales (el prefijo _var, sin paréntesis) más que llamadas a funciones. Compacta, predecible cuando sabés qué contextos populan qué valor, y una fuente mayor de confusión la primera vez que un bloque AMPscript en una CloudPage trata de usar _jobid y obtiene NULL.

Esta página es el inventario más lo que devuelve cada variable especial entre los contextos de render (email send vs CloudPage vs Mobile vs preview).

Sintaxis oficial

%%[
  /* Variables especiales — sin prefijo @, sin paréntesis */
  SET @subKey  = _subscriberKey
  SET @email   = _emailaddress
  SET @jobId   = _jobid
  SET @listId  = _listid
  SET @msgCtx  = _messagecontext     /* "Send" / "Preview" / "Test" */
  SET @userId  = _userid             /* el usuario API/UI que lo disparó (si está disponible) */

  /* AttributeValue — lee del perfil Subscriber Attribute,
     NO de una columna de DE con el mismo nombre */
  SET @firstName = AttributeValue("FirstName")
  SET @region    = AttributeValue("Region")

  /* RetrieveSalesforceObjects — lee desde Sales/Service Cloud
     (cubierto en detalle en la página de referencia de Cloud-write) */
  SET @leadStatus = Field(
    Row(
      RetrieveSalesforceObjects(
        "Lead",
        "Status",
        "Id", "=", @leadId
      ),
      1
    ),
    "Status"
  )
]%%

<p>Hola %%=v(@firstName)=%% (Subscriber Key: %%=v(@subKey)=%%).</p>

La superficie soportada:

| Nombre | Qué devuelve | Disponible en | |---|---|---| | _subscriberKey | El SubscriberKey del destinatario actual | Email send, Mobile, CloudPage con _subscriberkey en URL | | _emailaddress | El email del destinatario actual | Solo email send; NULL en CloudPages a menos que se setee explícito | | _jobid | El JobID del Send que está corriendo | Solo email send; NULL en preview y CloudPage | | _listid | El ID de la List o DE que potenció el send | Solo email send | | _messagecontext | "Send", "Preview", "Test", etc. | Email send + preview | | _messagetypepreference | La preferencia HTML vs Text del destinatario | Solo email send | | _userid | El usuario API/UI que disparó la acción | Frecuentemente NULL en sends normales | | JobID() | Forma-función de _jobid | Mismas reglas de contexto | | AttributeValue(attrName) | El valor del Subscriber actual para el Subscriber Attribute nombrado | Email send + CloudPage cuando _subscriberkey está presente |

Referencia:

Lo que sobrevive en producción

_subscriberKey vs _emailaddress — elegí uno como identificador estable

Un DE sendable tiene dos formas de identificar al destinatario:

  • SubscriberKey — el ID interno estable de Marketing Cloud para el subscriber. Misma persona, misma key entre todos los sends.
  • EmailAddress — el email. La misma persona puede cambiar de email (evento re-key); la dirección en sí puede cambiar.

AMPscript expone los dos vía _subscriberKey y _emailaddress. La convención Cleon: siempre keyeá la personalización y los lookups por _subscriberKey, nunca por _emailaddress. Las direcciones de email cambian; los subscriber keys están pensados para ser estables.

%%[
  /* DURABLE — joinea sobre identificador estable */
  SET @segment = Lookup("master_segments", "Tier", "SubscriberKey", _subscriberKey)

  /* EN RIESGO — la dirección de email puede haber cambiado desde que se escribió la fila del segmento */
  SET @segment = Lookup("master_segments", "Tier", "EmailAddress", _emailaddress)
]%%

Si el DE sendable está keyeado por email (raro pero pasa en implementaciones legacy), la SQL Activity upstream debería ya haber computado SubscriberKey como columna. AMPscript lee esa columna, no el email crudo.

_jobid es NULL en preview y en CloudPages

El preview de Email Studio no corre un JobID real — _jobid resuelve a NULL. Las CloudPages no corren adentro de un Send, así que _jobid también es NULL ahí. Código que depende del JobID para writes de log o renderizado condicional falla silenciosamente fuera del send real.

%%[
  /* EN RIESGO — _jobid es NULL en preview; la fila de log se escribe con
     JobID = NULL, el cuerpo del email renderea bien, el bug se manifiesta
     solo después del send de producción cuando las queries de auditoría
     no pueden correlacionar filas por JobID */
  InsertData(
    "de_log_engagement",
    "JobID", _jobid,
    "SubscriberKey", _subscriberKey,
    "Action", "render",
    "Ts", Now()
  )

  /* DEFENSIVO — guardar contra render en preview-time */
  IF NOT Empty(_jobid) THEN
    /* solo loggear en sends reales */
    InsertData(
      "de_log_engagement",
      "JobID", _jobid,
      "SubscriberKey", _subscriberKey,
      "Action", "render",
      "Ts", Now()
    )
  ENDIF
]%%

La variable _messagecontext es el chequeo más limpio: devuelve "Send" para sends reales y "Preview" para el path de preview. Ramificá sobre _messagecontext cuando el comportamiento renderado deba diferir.

_messagecontext es el único chequeo confiable de preview-vs-send

%%[
  /* "Send", "Preview", "Test", etc. */
  IF _messagecontext == "Send" THEN
    /* Send de producción real — log + cloud-write son seguros de correr */
    InsertData(
      "de_log_engagement",
      "JobID", _jobid,
      "SubscriberKey", _subscriberKey,
      "Action", "render",
      "Ts", Now()
    )
  ENDIF
]%%

Los valores son tenant-estables como para apoyarse en ellos, pero no case-estables entre tenants"Send" en un tenant puede ser "send" en otro. Usá Lowercase() en la comparación para estar seguro:

%%[
  IF Lowercase(_messagecontext) == "send" THEN
    /* portátil entre tenants */
  ENDIF
]%%

Esta es la herramienta más útil sola para mantener limpio el comportamiento del preview. El preview nunca debería escribir a tus DEs de log, nunca llamar a UpdateSingleSalesforceObject, nunca entregar códigos de claim. Envolvé cada bloque con side-effects en un gate _messagecontext == "Send".

AttributeValue lee del perfil Subscriber Attribute, no de columnas de DE

Reforzado del gotcha #4 porque es el patrón más confuso solo en el lenguaje para devs nuevos de AMPscript:

  • AttributeValue("FirstName") lee del atributo FirstName del perfil All Subscribers. Esto no es lo mismo que la columna FirstName del DE sendable.
  • %%FirstName%% (inline, sin @) típicamente lee de la columna del DE sendable con ese nombre.
  • %%=v(@FirstName)=%% lee la variable local.

Cuando las tres se llaman igual, la resolución en render time no siempre es intuitiva y te pasás una hora preguntándote por qué la personalización "se ve bien" pero matchea la fuente equivocada.

%%[
  /* DURABLE — nombrá las fuentes distinto así la fuente es obvia */
  SET @subFirstName  = AttributeValue("FirstName")         /* perfil */
  SET @deFirstName   = AttributeValue("DEFirstName")       /* columna de DE con prefijo */
  SET @localFirstName = "Mariana"                          /* local */
]%%

La defensa que lista la página de gotchas: nombres distintos. La defensa que esta página agrega: elegí una fuente por email y quedate con ella. Si tu SQL Activity de audience-build está computando FirstName al DE sendable, esa es la fuente — leé %%[FirstName]%% y ignorá el perfil. Si querés leer del perfil, nombrá la columna del DE distinto para que la confusión sea imposible.

_listid es el ID de la fuente sendable, no la List de All Subscribers

_listid devuelve el ID del DE (o list rara) que potenció el send — no la list All Subscribers. Este naming es legacy de cuando las "Lists" eran la fuente primaria de audiencia; hoy casi cada send es desde un DE, y _listid devuelve el CustomerKey/ID del DE.

%%[
  /* @listId es el ID del DE sendable, útil para audit logging */
  SET @listId = _listid

  InsertData(
    "de_log_sends",
    "JobID", _jobid,
    "ListId", @listId,
    "Action", "render",
    "Ts", Now()
  )
]%%

No esperes que esto sea human-readable en tenants MC legacy; es un ID opaco. Usalo para cross-referenciar, no para mostrar a subscribers.

Nombres de Subscriber Attribute con espacios o caracteres especiales

El perfil All Subscribers permite nombres de atributo con espacios y caracteres inusuales ("First Name", "Customer ID #"). AttributeValue acepta el nombre exacto como string, así que el quoting maneja los espacios:

%%[
  SET @firstName = AttributeValue("First Name")        /* perfil legacy con espacio */
  SET @customerId = AttributeValue("Customer ID #")    /* legacy con chars especiales */
]%%

La convención Cleon: cuando diseñes Subscriber Attributes nuevos, usá lowercase-snake-case o PascalCase sin espacios ni caracteres especiales. La falla del hand-off: un atributo de perfil llamado "First Name" (con espacio) aparece como un placeholder %%First Name%% en el email, que no interpola de la misma manera que un nombre sin espacio. El resolvedor de atributo inline de AMPscript tiene problemas con espacios. Las llamadas AttributeValue con quoting siempre funcionan.

_emailaddress en una CloudPage — usualmente NULL

En una CloudPage rendereada desde una URL como /cp/preferences?_subscriberkey=abc123, _subscriberKey se popula desde la URL pero _emailaddress no se resuelve automáticamente. Para conseguir el email en contexto de CloudPage, hacé un Lookup contra la list All Subscribers (o contra tu DE master):

%%[
  /* Contexto CloudPage */
  SET @subKey = _subscriberKey                         /* desde URL */
  SET @email = _emailaddress                           /* frecuentemente NULL en CP */

  IF Empty(@email) THEN
    /* Fallback: buscar el email por SubscriberKey */
    SET @email = Lookup("master_subscribers", "EmailAddress", "SubscriberKey", @subKey)
  ENDIF
]%%

La falla del hand-off: AMPscript copiado de un template de email que lee _emailaddress directo se cae en una CloudPage, el email aparece en blanco, y alguien se pasa una hora preguntándose por qué el mismo código andaba ayer. El contexto cambió; la disponibilidad de la variable cambió con él.

Decisión rápida

Usá _subscriberKey cuando:

  • Necesitás un identificador estable per-destinatario. Siempre preferí este sobre _emailaddress.

Usá _emailaddress cuando:

  • Específicamente necesités la dirección de email en sí para personalización (el patrón "tu email en archivo"). Si no, preferí el patrón SubscriberKey + Lookup.

Usá _jobid cuando:

  • Writes de logging o audit-trail que necesitan correlacionar filas al send específico. Guardalo con chequeo Empty() o gate _messagecontext.

Usá _messagecontext cuando:

  • Gateás código con side-effects (writes, claims, cloud-writes). Lowercaseá la comparación para portabilidad.

Usá AttributeValue cuando:

  • El data vive en el perfil Subscriber Attribute y no en el DE sendable. Quoteá el nombre; maneja espacios y caracteres especiales.

Usá referencias de columna del DE sendable (%%Col%% o %%[Col]%%) cuando:

  • El data está en el DE sendable que potenció el Send. Más rápido que AttributeValue (sin lookup al perfil) y más claro sobre la fuente.

Usá un Lookup con _subscriberKey cuando:

  • El data está en un DE distinto keyeado por SubscriberKey. Pre-formateá upstream donde se pueda para evitar lookups per-destinatario.

Relacionado

Más páginas de referencia AMPscript en camino: Cloud-write · Encoding/Hashing · Style Guide.