Referencia completa del CLI
Esta es la referencia completa del CLI de Ads Uploader. Para una introducción y una guía de configuración, consulta Configuración por CLI.
Comandos
Autenticación
| Comando | Qué hace |
|---|---|
ads login | Inicia sesión desde el navegador (abre tu navegador por defecto) |
ads logout | Borra las credenciales guardadas |
ads whoami | Muestra el correo con el que iniciaste sesión, la cuenta publicitaria por defecto y la URL de la API |
ads config | Muestra si has iniciado sesión, tu correo, la cuenta publicitaria por defecto, la URL de la API y la carpeta de configuración (~/.config/adsuploader/) |
ads --version | Muestra la versión del CLI instalada |
Un token de inicio de sesión dura 30 días. Después, vuelve a ejecutar ads login.
Explorar
| Comando | Qué hace |
|---|---|
ads accounts | Lista todas las cuentas publicitarias conectadas a tu cuenta de Meta |
ads accounts:refresh | Vuelve a obtener al momento la lista de cuentas publicitarias de Meta, por ejemplo después de que te den acceso a una cuenta publicitaria nueva |
ads account <id> | Define una cuenta publicitaria por defecto para los próximos comandos |
ads pages | Lista las páginas de Facebook con las que puedes anunciarte, incluida cualquier cuenta de Instagram vinculada, para usarlas al cambiar los perfiles |
ads targeting:search "Austin" --type city | Busca claves de ciudad para la segmentación del conjunto de anuncios |
ads targeting:search "90210" --type zip | Busca claves de código postal para la segmentación del conjunto de anuncios |
ads targeting:search "advertising" --type detailed | Busca IDs y tipos de segmentación detallada |
ads campaigns | Lista las campañas activas |
ads campaigns --status all | Incluye también las campañas inactivas |
ads campaigns --search "text" | Filtra las campañas por nombre |
ads campaign <id> | Muestra los conjuntos de anuncios de una campaña |
ads adsets --campaign <id> | Lista los conjuntos de anuncios de una campaña (admite --search y --status) |
ads adset <id> | Muestra los anuncios de un conjunto de anuncios |
ads ad <id> | Muestra todos los detalles del anuncio, incluida la configuración de la creatividad |
ads presets | Lista tus preajustes de API guardados |
ads presets <id> | Muestra los detalles de un preajuste concreto |
ads presets:save --from-ad <adId> --name "Preset Name" | Guarda un anuncio existente como preajuste de API. Añade --share para compartirlo con tu equipo (planes de equipo). |
ads text-presets | Lista tus preajustes de texto guardados |
ads text-presets <id> | Muestra los detalles de un preajuste de texto concreto |
ads uploads | Lista los lotes de subida recientes (20 por defecto; cámbialo con --limit <n>) |
ads uploads <batchId> | Muestra los detalles de un lote (archivos, variantes, hashes) |
Builds guardados
Los builds guardados son los mismos builds que ves en la ventana Saved Builds del uploader web. Consulta Builds guardados para ver cómo funcionan.
| Comando | Qué hace |
|---|---|
ads builds | Lista tus builds guardados (filtra con --account <id>) |
ads builds <buildId> | Muestra un build guardado, incluido su número de revisión actual |
ads builds:create --spec spec.json --name "Summer Sale" | Guarda una especificación como build nuevo. builds:save es un alias. También acepta --notes, --account y --web-state <file>. |
ads builds:update <buildId> --spec-patch patch.json --expected-revision <n> | Cambia parte de la especificación de un build con un JSON merge patch. --expected-revision es obligatorio y evita que sobrescribas una edición más reciente de otra persona. |
ads builds:update <buildId> --name "New name" | Renombra un build. También funcionan --notes, --spec <file> (reemplaza toda la especificación) y --web-state <file>. |
ads builds:fork <buildId> | Copia un build en un borrador nuevo sin cambiar el original |
ads builds:delete <buildId> | Elimina un build guardado |
Pasa - en lugar de un nombre de archivo para leer el JSON desde stdin. Para lanzar un build, usa ads create --build <buildId> (o create:preview).
Subida de medios
| Comando | Qué hace |
|---|---|
ads upload <inputs...> | Sube rutas locales y URLs HTTPS públicas a tu cuenta publicitaria |
ads upload ./directory/ | Sube una carpeta entera |
ads upload:drive <folderUrl> | Importa una carpeta pública de Google Drive como trabajo en segundo plano (acepta --account, --json y --api-timeout) |
ads upload --retry-failed [batchId] | Reintenta los archivos fallidos de tu último lote de subida con errores, o del lote que indiques. No pases archivos con este flag. |
Los argumentos HTTPS, incluidos los enlaces públicos a archivos de Google Drive, se detectan automáticamente. Puedes mezclar rutas locales y URLs: primero se suben los archivos locales y luego el servidor importa las URLs en el mismo lote, para que la agrupación funcione con todas las entradas. Las carpetas públicas de Drive deben estar compartidas como Anyone with the link (Viewer).
Los archivos locales se preparan en paralelo, y los fallos de red pasajeros se reintentan automáticamente con espera progresiva. Las importaciones de URLs y de carpetas de Drive usan procesos de archivos en paralelo con un límite, dentro de un trabajo en segundo plano, mientras el CLI muestra un contador de completados sobre el total y cada archivo activo. Rara vez tendrás que tocar estos flags, pero están disponibles:
| Flag de subida | Descripción |
|---|---|
--concurrency <n> | Número de archivos que se preparan en paralelo, de 1 a 6 (por defecto: 4). Los videos grandes se limitan automáticamente para no pasarse de memoria. |
--upload-timeout <ms> | Tiempo de espera de subida por archivo (por defecto: 120000) |
--api-timeout <ms> | Tiempo de espera de las solicitudes a la API en milisegundos (por defecto: 60000). También en upload:drive. Puedes definirlo para todos los comandos con la variable de entorno ADS_API_TIMEOUT_MS. |
Reglas de subida:
- Cada archivo puede pesar hasta 4 GB.
- Imágenes:
.jpg,.jpeg,.png,.gif,.bmp,.webp. Videos:.mp4,.mov,.avi,.mkv,.webm,.m4v. - Los enlaces deben usar
https://. Todo lo demás se trata como una ruta local. - Una imagen con el nombre de su video más
_thumbnail(por ejemplopromo_thumbnail.jpgparapromo.mp4) se asocia a ese video como su miniatura personalizada en lugar de subirse como un medio aparte. - Pulsar Ctrl-C durante una importación por enlace o de Drive le pide al servidor que detenga la importación. Los archivos que ya terminaron se quedan en el lote.
Creación de anuncios
| Comando | Qué hace |
|---|---|
ads create spec.json | Crea anuncios a partir de un archivo de especificación |
ads create:preview spec.json | Ejecución de prueba que muestra lo que se crearía |
ads create:test [spec.json] | Test Mode solo para administradores, con resultados de validación de Meta sin crear nada; no crea anuncios en Meta |
ads create:interactive | Asistente guiado (acepta todos los flags de creación) |
Duplicación por Post ID
| Comando | Qué hace |
|---|---|
ads duplicator:post-id [specFile] | Duplica anuncios existentes seleccionados por el Post ID de la página conservando sus referencias a la publicación |
ads duplicator:post-id:preview [specFile] | Previsualiza una duplicación por Post ID y su correspondencia entre origen y destino |
Gestión de trabajos
| Comando | Qué hace |
|---|---|
ads jobs <jobId> | Consulta el estado de un trabajo |
ads jobs <jobId> --follow | Muestra el progreso en directo |
ads jobs cancel <jobId> | Cancela un trabajo en curso |
Flags de creación
Estos flags se aplican a ads create, ads create:preview y ads create:interactive (y a ads create:test, solo para administradores). Puedes usarlos en lugar de un archivo de especificación o junto con él.
| Flag | Descripción |
|---|---|
--account <id> | Sustituye la cuenta publicitaria por defecto |
--build <buildId> | Usa un build guardado como especificación. No lo combines con un archivo de especificación. |
--preset <id> | Usa un preajuste de API guardado (alternativa al archivo de especificación) |
--text-preset <id> | Carga un preajuste de texto guardado |
--copy-from <adId> | Copia la configuración de un anuncio existente |
--upload <batchId> | Indica el ID del lote de subida |
--status <PAUSED|ACTIVE> | Define el estado del anuncio (por defecto: ACTIVE) |
--pause-at <level> | Nivel de pausa: ad (por defecto), adSet o campaign |
--daily-budget <amount> | Sustituye el presupuesto diario por conjunto de anuncios (en unidades de moneda, por ejemplo 50 para $50) |
--bid-amount <amount> | Sustituye el límite de puja o de costo por conjunto de anuncios (en unidades de moneda) |
--minimum-roas <ratio> | Sustituye el objetivo de ROAS mínimo por conjunto de anuncios (por ejemplo 1.5) |
--campaign-daily-budget <amount> | Define un presupuesto diario de campaña CBO en unidades enteras de moneda. Es incompatible con el presupuesto total; omite los dos para heredar el presupuesto de la campaña de origen. |
--campaign-lifetime-budget <amount> | Define un presupuesto total de campaña CBO en unidades enteras de moneda. Es incompatible con el presupuesto diario; omite los dos para heredar el presupuesto de la campaña de origen. |
--adset-min-spend <amount> | Define el gasto mínimo del conjunto de anuncios con CBO en unidades enteras de moneda; 0 quita el límite heredado del conjunto de anuncios de origen. |
--adset-max-spend <amount> | Define el gasto máximo del conjunto de anuncios con CBO en unidades enteras de moneda; 0 quita el límite heredado del conjunto de anuncios de origen. |
--adset-min-spend-pct <5-100> | Define el gasto mínimo del conjunto de anuncios como porcentaje del presupuesto de la campaña, en pasos del 5%. También funciona con una campaña CBO existente; es incompatible con --adset-min-spend. |
--adset-max-spend-pct <5-100> | Define el gasto máximo del conjunto de anuncios como porcentaje del presupuesto de la campaña, en pasos del 5%. También funciona con una campaña CBO existente; es incompatible con --adset-max-spend. |
--location <ISO> | Segmenta un país por su código ISO de dos letras. Repite el flag para varios países. |
--age-min <n> | Edad mínima, de 13 a 65 |
--age-max <n> | Edad máxima, de 13 a 65 (65 significa 65+) |
--gender <gender> | all, men o women. all quita una restricción de género heredada del conjunto de anuncios de origen. |
--ai-disclosure | Declara que la creatividad tiene contenido generado con IA (transparencia de contenido de IA de Meta). Desactivado por defecto. Consulta Declaración de IA para el campo de la especificación. |
--page <id> | Usa esta página de Facebook en lugar de la de la plantilla (consulta Opciones de perfil) |
--instagram <id> | Usa esta cuenta de Instagram en lugar de la de la plantilla |
--use-page-identity | Usa la página de Facebook como identidad de Instagram; no se puede combinar con --instagram |
--threads <id> | Usa este perfil de Threads en lugar del de la plantilla |
--text-file <path> | Carga la configuración de textos desde un archivo JSON |
--expanded | Muestra completos los valores de título, texto principal y descripción en las vistas previas |
Flags de duplicación por Post ID
Estos flags se aplican a ads duplicator:post-id y ads duplicator:post-id:preview. Se pueden usar en lugar de un archivo de especificación de duplicación por Post ID o junto con él. Este es el modo de duplicación por Post ID; más adelante se pueden añadir otros modos de duplicación.
| Flag | Descripción |
|---|---|
--account <id> | Sustituye la cuenta publicitaria por defecto |
--post <postId> | Busca los anuncios de origen por el Post ID de la página. Si hay varias coincidencias, hace falta una selección explícita con --ad. |
--ad <adId> | Selecciona un ID de anuncio de origen exacto. Repítelo para varios anuncios; no lo combines con --post. |
--campaign <id> | Usa una campaña de destino existente |
--adset <id> | Usa un conjunto de anuncios de destino existente, o úsalo como plantilla para un conjunto de anuncios nuevo |
--new-adset [name] | Crea un conjunto de anuncios nuevo para todos los anuncios de origen. El nombre por defecto es {AdName}. |
--new-adset-per-ad [name] | Crea un conjunto de anuncios nuevo por cada anuncio de origen. El nombre por defecto es {AdName}. |
--ad-name <pattern> | Define el patrón de nombre de los anuncios duplicados. El valor por defecto es {AdName}. |
--paused | Crea los anuncios duplicados en pausa |
--use-creative-id | Reutiliza los IDs de creatividad originales en lugar de crear creatividades que hagan referencia a la publicación |
--acknowledge-warnings | Continúa una ejecución real después de revisar los avisos de creatividad de la vista previa (acknowledgeWarnings: true en JSON) |
--json | Devuelve JSON sin formato para scripts |
Archivo de especificación de duplicación por Post ID
Esta especificación v1 selecciona un anuncio de origen exacto, clona un conjunto de anuncios y crea anuncios en pausa:
{
"adIds": ["120200000000000001"],
"campaignId": "120200000000000000",
"adSetId": "120200000000000002",
"newAdSet": { "name": "Winners {AdName}" },
"adNamePattern": "{AdName} - {Index}",
"paused": true,
"useCreativeId": false
}
Usa postIds para buscar o adIds ordenados para una selección exacta, nunca los dos. La vista previa devuelve sourceCandidates con los IDs de anuncio, campaña y conjunto de anuncios. Cuando las coincidencias son ambiguas, requiresSourceSelection es true y resolvedRequest es null: elige los IDs de anuncio y vuelve a previsualizar. Con una selección exacta, resolvedRequest contiene IDs de anuncio y ningún Post ID. Hace falta un campaignId existente; no se admiten campañas nuevas.
Elige un modo de destino para el conjunto de anuncios:
| Destino | Campos de la especificación |
|---|---|
| Conjunto de anuncios existente | "adSetId": "120200000000000002" |
| Un conjunto de anuncios nuevo | "newAdSet": { "name": "Winners {AdName}" } y, opcionalmente, adSetId como plantilla |
| Un conjunto de anuncios nuevo por anuncio | "newAdSetPerAd": { "name": "Winners {Index} {AdName}" } y, opcionalmente, adSetId como plantilla |
Para ejecuciones reales con avisos de creatividad, revisa la vista previa y pasa --acknowledge-warnings (acknowledgeWarnings: true en JSON/MCP) para continuar. Un useCreativeId: true explícito también cumple con esta elección. La vista previa no necesita confirmación.
La campaña de destino, el conjunto de anuncios seleccionado y los anuncios de origen deben pertenecer a la misma cuenta publicitaria. Un conjunto de anuncios seleccionado debe pertenecer a campaignId, también cuando se usa como plantilla para un conjunto nuevo. Elige newAdSet o newAdSetPerAd; combinar los dos se rechaza. Un solo origen con newAdSetPerAd crea un único clon compartido y mantiene {Index} en 1.
La vista previa y el Test Mode de la web leen la configuración real de cada anuncio de origen y de cada plantilla seleccionada sin crear objetos en Meta. Por eso, los orígenes posteriores pueden revelar datos que faltan y avisos de creatividad; la segmentación se valida en cada plantilla que se usa para crear un conjunto de anuncios nuevo. Los conjuntos de anuncios nuevos simulados usan la configuración de presupuesto y puja de la campaña de destino cuando está disponible. Los anuncios se crean activos por defecto; paused afecta solo a los anuncios, y los conjuntos de anuncios nuevos quedan activos.
{AdName} inserta el nombre del anuncio de origen. {Index} inserta su posición, empezando en 1, en los nombres de los anuncios duplicados y en los nombres de conjunto de anuncios por anuncio. Cuando un conjunto de anuncios nuevo contiene varios anuncios de origen, {AdName} en el nombre de ese conjunto de anuncios pasa a ser Multiple Ads.
Cómo elige anuncios la búsqueda por publicación: una búsqueda por Post ID revisa hasta unos 2,000 anuncios recientes de la cuenta. Nunca elige por ti la coincidencia más reciente. Cuando coinciden varios anuncios, el CLI y el MCP se detienen y te piden que elijas, y también se detienen ante avisos que no hayas confirmado. Una ejecución real siempre duplica IDs de anuncio exactos, así que envía el resolvedRequest de la vista previa. Para repetir una selección que ya revisaste, guarda y reutiliza resolvedRequest (el MCP también necesita accountId) en lugar de repetir la búsqueda solo por publicación. Los IDs de anuncio se mantienen fijos, pero la configuración actual de Meta se vuelve a leer y comprobar al lanzar.
Los conjuntos de anuncios nuevos heredan la segmentación, el presupuesto, la programación y la configuración de puja del --adset o adSetId seleccionado, con la misma limpieza y el mismo ajuste al presupuesto de destino que el Duplicator de la web. Sin una plantilla seleccionada, un conjunto nuevo compartido usa el conjunto del primer anuncio de origen; el modo por anuncio usa el conjunto propio de cada anuncio de origen.
Los anuncios de origen con creatividad dinámica reutilizan su ID de creatividad y no pueden mantener la interacción sincronizada. El CLI muestra el mismo aviso que el Duplicator de la web.
Las ejecuciones reales de duplicación por Post ID muestran el progreso por conjunto de anuncios y por anuncio, incluidos los mensajes de error de Meta, y terminan con Duplicated X of Y.
Flags de exploración
Estos flags están disponibles en campaigns, adsets, adset y campaign:
| Flag | Descripción |
|---|---|
--status <status> | active (por defecto) o all |
--inactive | Atajo de --status all (en campaigns) |
--search <text> | Filtra por nombre (en campaigns y adsets) |
Búsqueda de segmentación
La segmentación por ciudad, código postal y detallada usa identificadores de Meta en lugar de nombres. Busca a través de Ads Uploader para obtener valores que puedas pegar en una especificación:
ads targeting:search "Austin" --type city
ads targeting:search "90210" --type zip
ads targeting:search "advertising" --type detailed
| Flag | Descripción |
|---|---|
--type <type> | Obligatorio. city devuelve valores de targeting.cities[].key; zip devuelve valores de targeting.zips[].key; detailed devuelve entradas para targeting.detailedTargetingGroups. |
--account <id> | Sustituye la cuenta publicitaria configurada por defecto |
--limit <n> | Devuelve de 1 a 25 coincidencias (por defecto 8) |
--json | Devuelve resultados estructurados listos para pegar |
Los resultados de segmentación detallada incluyen id, name, type, un rango de tamaño del público y la ruta de la categoría. El type identifica la categoría de segmentación detallada, como interests, behaviors, work_employers o work_positions. Busca siempre estos identificadores; nunca los adivines.
Flags de detalle
Estos flags están disponibles en ad:
| Flag | Descripción |
|---|---|
--expanded | Muestra completos los valores de título, texto principal y descripción |
Flags comunes
| Flag | Descripción |
|---|---|
--account <id> | Sustituye la cuenta publicitaria por defecto en cualquier comando |
--json | Devuelve JSON sin formato (disponible en la mayoría de los comandos, pensado para scripts) |
Variables de entorno y actualizaciones
| Variable | Qué hace |
|---|---|
ADS_API_TIMEOUT_MS | Tiempo de espera de las solicitudes a la API en milisegundos para todos los comandos (por defecto 60000) |
ADS_API_URL | La dirección de Ads Uploader con la que habla el CLI. Déjala sin definir para el uso normal. |
El CLI busca una versión nueva una vez al día y muestra un aviso cuando sale. Actualízalo con npm update -g @adsuploader/cli.
Formato del archivo de especificación
El archivo de especificación JSON controla todos los aspectos de la creación de anuncios. Indica un origen de plantilla (adPresetId o copyFromAd) más uploadId o mediaItems capturados con un mediaHash de Facebook para cada imagen y un mediaId para cada video. Los videos estándar, de carrusel, flexibles y de ubicación también necesitan thumbnailHash; los videos Multi Media usan su URL pública de miniatura capturada.
Para los videos, mediaItems[].mediaId debe ser el ID numérico de video de Facebook: usa el videoId de la respuesta de la subida, no su id interno. videoId se acepta como alias, y linkedAssets[] siguen la misma regla. Los IDs internos de subida solo se resuelven al guardar cuando pertenecen al usuario autenticado y a la cuenta seleccionada. Sin un ID numérico ni un enlace de lote, un video sin resolver hace que el build no se pueda lanzar. Consulta el elemento canónico de video con ubicaciones.
Especificación mínima
{
"adPresetId": "your_preset_id",
"uploadId": "batch_abc123"
}
Ejemplo completo
{
"adPresetId": "preset_id_here",
"uploadId": "batch_abc123",
"adSet": {
"name": "My New Ad Set",
"dailyBudget": 50
},
"adNamePattern": "{filename}",
"texts": {
"perAd": {
"hero.jpg": {
"headlines": ["Main Headline"],
"bodies": ["Ad copy here."],
"descriptions": ["Short description"],
"cta": "SHOP_NOW",
"link": "https://example.com/landing"
}
}
},
"creativeEnhancements": "none",
"options": {
"status": "PAUSED",
"pauseAt": "adSet"
}
}
Origen de la plantilla
Necesitas uno de estos campos para decirle al CLI qué configuración de anuncio usar como base.
| Campo | Descripción |
|---|---|
adPresetId | El ID de un preajuste de API guardado. Fija la configuración de la campaña, el conjunto de anuncios y el anuncio. |
copyFromAd | El ID de un anuncio de Facebook del que copiar la configuración. |
Cuando uses copyFromAd, indica el lote de subida, o lanza un build web guardado cuyas imágenes capturadas tengan mediaHash y cuyos videos tengan mediaId. Opcionalmente puedes definir la campaña y el conjunto de anuncios:
{
"copyFromAd": "120233848667930472",
"uploadId": "batch_abc123",
"campaign": { "id": "120233848666410472" },
"adSet": { "id": "120233848666620472" }
}
Para encontrar el ID de anuncio correcto, recorre tu cuenta: ads campaigns, luego ads campaign <id>, luego ads adset <id> y luego ads ad <id>.
Opciones de perfil
Por defecto, los anuncios nuevos heredan la página de Facebook, la cuenta de Instagram y el perfil de Threads del anuncio plantilla o del preajuste. Es el mismo control Profile Options disponible en el panel Defaults de la app web. Puedes cambiar cualquiera de ellos con un bloque profile (o con los flags --page / --instagram / --use-page-identity / --threads, que tienen prioridad sobre el archivo de especificación):
{
"copyFromAd": "120233848667930472",
"uploadId": "batch_abc123",
"profile": {
"pageId": "123456789012345",
"instagramId": "17841400000000000",
"threadsId": "987654321098765"
}
}
Ejecuta ads pages para listar los IDs de página que puedes usar, junto con la cuenta de Instagram vinculada a cada página.
Si cambias solo la página, Ads Uploader usa automáticamente su cuenta de Instagram vinculada. Si no hay ninguna cuenta de Instagram vinculada, usa la página de Facebook como identidad de Instagram. Threads se restablece igualmente porque puede pertenecer a la página anterior; defínelo de forma explícita cuando haga falta.
Para elegir de forma explícita que actúe la página, usa --use-page-identity o pon "useFacebookPage": true dentro de profile. No lo combines con --instagram ni con instagramId. También puedes cambiar solo el perfil de Instagram o de Threads sin tocar la página, definiendo solo esos campos.
En lanzamientos con varias campañas, asigna las identidades por separado con profile.campaigns. Usa como clave de cada cambio el id de la campaña correspondiente (recomendado) o un nombre de campaña que no sea ambiguo:
{
"campaign": {
"mode": "duplicate",
"campaigns": [
{ "id": "prospecting", "name": "Prospecting" },
{ "id": "retargeting", "name": "Retargeting" }
]
},
"profile": {
"campaigns": {
"prospecting": { "pageId": "page_1", "instagramId": "ig_1", "threadsId": null },
"retargeting": { "pageId": "page_2", "useFacebookPage": true, "threadsId": "threads_2" }
}
}
}
profile.campaigns solo funciona cuando campaign.mode es "duplicate" o "split" con al menos dos entradas en campaign.campaigns. Cada clave debe coincidir con una de esas campañas; las claves que no coinciden o son ambiguas se rechazan antes del lanzamiento.
Estructura de campañas
Por defecto, los anuncios van a la campaña del anuncio plantilla. Puedes crear una campaña nueva indicando campaign.name.
Para los modos con varias campañas, usa campaign.mode con un array campaigns:
{
"campaign": {
"mode": "duplicate",
"campaigns": [
{ "name": "Campaign A" },
{ "name": "Campaign B" }
]
}
}
| Modo | Comportamiento |
|---|---|
"single" | Por defecto. Una campaña. |
"duplicate" | Todos los medios se duplican en cada campaña. |
"split" | Los medios se reparten por igual entre las campañas. |
Modos de conjunto de anuncios
Por defecto, los anuncios van al conjunto de anuncios existente del anuncio plantilla. Los siguientes modos te dan control sobre cómo se reparten los anuncios entre los conjuntos de anuncios.
Crear un conjunto de anuncios nuevo:
{ "adSet": { "name": "My Ad Set" } }
Usar un conjunto de anuncios existente por ID:
{ "adSet": { "id": "120233848666620472" } }
Un conjunto de anuncios por archivo subido:
{ "adSet": { "mode": "perUpload" } }
Agrupar automáticamente en conjuntos de anuncios de un tamaño fijo:
{ "adSet": { "mode": "autoGroup", "adsPerAdSet": 5 } }
Grupos personalizados con control total sobre qué archivos van a cada sitio:
{
"adSet": {
"groups": [
{ "name": "Images - April 10", "media": ["hero.jpg", "banner.jpg"] },
{ "name": "Videos - April 10", "media": ["promo.mp4"] }
]
}
}
Patrón de nombre de conjunto de anuncios para los modos con varios conjuntos de anuncios:
{ "adSet": { "mode": "perUpload", "namePattern": "Ad Set {index:01}" } }
La agrupación de variantes agrupa los anuncios por identificador de variación en el mismo conjunto de anuncios:
{ "adSet": { "mode": "autoGroup", "groupVariations": true, "variationIdentifier": "-" } }
Cambiar el presupuesto y el control de puja
Cambia el presupuesto diario, el importe de puja o ambos en los conjuntos de anuncios nuevos. Los valores van en las unidades de moneda de tu cuenta (por ejemplo 50 para $50 o 50 euros).
dailyBudget y bidAmount usan unidades de moneda de la cuenta. minimumRoas es una proporción, así que 1.5 significa un objetivo de ROAS de 1.5x.
- Campañas ABO (el presupuesto está en el conjunto de anuncios): combina
dailyBudgetconbidAmountpara estrategias de límite de puja o de costo, o conminimumRoasparaLOWEST_COST_WITH_MIN_ROAS. - Campañas CBO (el presupuesto está en la campaña): no pongas
dailyBudgeten el conjunto de anuncios. Definecampaign.dailyBudgetocampaign.lifetimeBudget(son incompatibles entre sí) para cambiar el presupuesto de la campaña de origen, u omite los dos para heredarlo. Los límites de gasto mínimo y máximo del conjunto de anuncios pueden usar importes en unidades enteras o del 5 al 100% del presupuesto de la campaña en pasos del 5%; los límites en porcentaje también funcionan con una campaña CBO existente. DefinebidAmountominimumRoasen el conjunto de anuncios cuando su estrategia de origen use ese control.
bidAmount y minimumRoas son incompatibles entre sí porque pertenecen a estrategias de puja distintas.
{ "adSet": { "dailyBudget": 50 } }
{ "adSet": { "bidAmount": 5 } }
{ "adSet": { "minimumRoas": 1.5 } }
{ "adSet": { "dailyBudget": 50, "bidAmount": 5 } }
Para los límites de gasto con CBO en una especificación, define estos campos en adSet:
| Campo | Qué define |
|---|---|
minSpend | Gasto mínimo del conjunto de anuncios en unidades enteras de moneda. 0 quita el límite copiado del conjunto de anuncios de origen. |
maxSpend | Gasto máximo del conjunto de anuncios en unidades enteras de moneda. 0 quita el límite copiado del conjunto de anuncios de origen. |
minSpendPercentage | Gasto mínimo del conjunto de anuncios como porcentaje del presupuesto de la campaña (de 5 a 100, en pasos de 5) |
maxSpendPercentage | Gasto máximo del conjunto de anuncios como porcentaje del presupuesto de la campaña (de 5 a 100, en pasos de 5) |
{
"campaign": { "dailyBudget": 200 },
"adSet": { "minSpend": 20, "maxSpendPercentage": 50 }
}
También disponible como flags del CLI: --daily-budget 50, --bid-amount 5, --minimum-roas 1.5, --campaign-daily-budget 100, --campaign-lifetime-budget 1000, --adset-min-spend 20, --adset-max-spend 80, --adset-min-spend-pct 20 y --adset-max-spend-pct 80.
Segmentación del conjunto de anuncios
La segmentación se aplica a los conjuntos de anuncios nuevos. Omite el bloque targeting de primer nivel para heredar sin cambios el público del conjunto de anuncios de origen. Cualquier modo puede usar adSet.targetingPerAdSet, con claves como en texts.perAdset: el nombre final del conjunto de anuncios, su ID o campaign::key para evitar colisiones. El modo personalizado también admite adSet.groups[].targeting. El orden de prioridad es targetingPerAdSet, luego groups[].targeting, luego el valor por defecto del build y luego el público de origen. La segmentación por conjunto de anuncios solo se puede definir en la especificación, porque los flags del CLI no pueden apuntar a un conjunto de anuncios planificado concreto.
Con varias campañas, la copia de un conjunto de anuncios en cada campaña se segmenta por separado; usa "Campaign name::Ad set name" como clave para una copia concreta.
{
"targeting": {
"countries": ["US"],
"cities": [
{
"key": "2525495",
"name": "Austin",
"region": "Texas",
"countryCode": "US",
"radius": 25,
"distance_unit": "mile"
}
],
"zips": [
{
"key": "US:90210",
"name": "90210",
"region": "California",
"countryCode": "US"
}
],
"selectionVersion": 4,
"ageSelected": true,
"ageMin": 21,
"ageMax": 55,
"genderSelected": true,
"genders": "women",
"detailedTargetingSelected": true,
"detailedTargetingGroups": [[
{
"id": "112002898811624",
"name": "Advertising agency",
"type": "work_employers"
}
]]
}
}
{
"targeting": { "countries": ["US"], "ageMin": 21, "ageMax": 55 },
"adSet": {
"mode": "perUpload",
"namePattern": "Ad Set {index:01}",
"targetingPerAdSet": {
"Ad Set 02": { "countries": ["CA"], "genders": "women" },
"Ad Set 01": { "countries": ["GB"] }
}
}
}
En el modo personalizado, groups[].targeting sigue siendo válido y mantiene el cambio junto a su grupo de medios:
{
"adSet": {
"mode": "custom",
"groups": [{
"name": "Canada Women",
"media": ["canada.jpg"],
"targeting": { "countries": ["CA"], "genders": "women" }
}]
}
}
Reglas de segmentación:
- La edad y el género hay que activarlos. Pon
ageSelected: trueogenderSelected: true; si no, se ignoran los valores de edad o de género. - La segmentación detallada reemplaza, no combina.
detailedTargetingGroupspasa a ser el público detallado completo, así que todo lo que dejes fuera se elimina. - El radio de ciudad se mantiene entre 10 y 50 millas, o entre 17 y 80 kilómetros. Un valor fuera de ese rango se ajusta al límite más cercano, y si falta el radio se usa el mínimo.
Usa ads targeting:search para encontrar la key de la ciudad (tipo city), la key del código postal, como US:90210 (tipo zip), y el id, name y type de cada selección detallada (tipo detailed). Omite los países, las ciudades y los códigos postales para heredar las ubicaciones de origen. Los países, las ciudades y los códigos postales se combinan como alternativas, así que añadir Austin o un código postal a countries: ["US"] sigue segmentando todo Estados Unidos; omite los países para segmentar solo la ciudad o el código postal. Los códigos postales no tienen radio.
Configuración de textos
El texto común aplica el mismo texto a todos los anuncios:
{
"texts": {
"common": {
"headlines": ["Headline 1", "Headline 2"],
"bodies": ["Primary text"],
"descriptions": ["Description"]
},
"strategy": "flexible"
}
}
El texto por anuncio te permite definir un texto único para cada archivo:
{
"texts": {
"perAd": {
"hero.jpg": {
"headlines": ["Hero Headline"],
"bodies": ["Hero copy"],
"descriptions": ["Hero desc"],
"cta": "LEARN_MORE",
"link": "https://example.com/hero",
"urlTags": "utm_content=hero"
},
"banner.jpg": {
"headlines": ["Banner Headline"],
"bodies": ["Banner copy"]
}
}
}
}
Las claves por anuncio son nombres de archivo (no rutas completas). Cada entrada admite: headlines, bodies, descriptions, cta, link, displayUrl, urlTags. Los campos que no indiques se heredan del anuncio plantilla.
El texto por conjunto de anuncios aplica un bloque de texto a todos los anuncios de un conjunto de anuncios de destino. Usa un nombre o ID de conjunto de anuncios sin más cuando sea único, o una entrada campaign::key cuando el mismo nombre de conjunto de anuncios aparezca en más de una campaña:
{
"texts": {
"perAdset": {
"Prospecting::prospecting_set": {
"headlines": ["Prospecting headline"],
"bodies": ["Prospecting copy"],
"descriptions": ["Prospecting description"],
"cta": "SHOP_NOW",
"link": "https://example.com/prospecting",
"displayUrl": "example.com/prospecting",
"urlTags": "utm_campaign=prospecting",
"aiDisclosure": false
}
}
}
}
Cada clave de texts.perAdset debe coincidir con un conjunto de anuncios planificado. Las claves que no coinciden se rechazan en lugar de recurrir al texto común.
Los preajustes de texto te permiten cargar una configuración de textos guardada:
{ "textPresetId": "preset_id_here" }
No puedes combinar textPresetId con texts.
Declaración de IA
Declara que la creatividad de un anuncio se hizo o se editó de forma importante con IA (la autodeclaración de contenido de IA de Meta). Está desactivada por defecto y nunca se activa por ti.
{ "aiDisclosure": true }
El campo aiDisclosure de primer nivel (o el flag --ai-disclosure) se aplica a todos los anuncios del lanzamiento. También puedes poner aiDisclosure en true o false en una entrada de texts.perAd o texts.perAdset; ese valor por entrada siempre tiene prioridad, incluido un false explícito.
Las opciones de estrategia controlan cómo se tratan las distintas variaciones de texto:
"flexible"(por defecto) deja que Meta optimice entre tus variaciones de texto. Los distintos títulos y textos se convierten en opciones que Facebook combina."separate"crea un anuncio aparte por cada combinación de textos.
CTA y enlaces
Un CTA de primer nivel se aplica a todos los anuncios. Los CTA por anuncio en texts.perAd y los CTA por conjunto de anuncios en texts.perAdset tienen prioridad sobre él.
{
"cta": {
"type": "SHOP_NOW",
"link": "https://example.com",
"displayUrl": "example.com"
},
"urlTags": "utm_source=facebook&utm_medium=paid"
}
Tipos de CTA estándar: LEARN_MORE, SHOP_NOW, SIGN_UP, SUBSCRIBE, GET_OFFER, GET_QUOTE, CONTACT_US, GET_IN_TOUCH, BOOK_TRAVEL (se muestra como Book Now), ORDER_NOW, BUY_NOW, APPLY_NOW, DOWNLOAD, SEE_DETAILS, WATCH_MORE, LISTEN_NOW, PLAY_GAME, DONATE_NOW, OPEN_LINK
Usa el valor de Meta (como SHOP_NOW), no la etiqueta del botón.
Los CTA específicos de un objetivo se heredan del anuncio plantilla y no deben definirse a mano. Ponerlos en un tipo de campaña equivocado provoca un error de la API de Facebook.
| CTA | Objetivo de campaña necesario |
|---|---|
MESSAGE_PAGE | Destino Messenger |
WHATSAPP_MESSAGE | Destino WhatsApp |
INSTAGRAM_MESSAGE | Destino Instagram DM |
CALL_NOW | Campaña de llamadas |
Prueba de URLs (Split Destination)
Indica de 2 a 5 URLs de destino en texts.urlVariants y cada conjunto de anuncios generado se duplica una vez por URL, para que Meta optimice cada combinación de anuncio y página de destino por separado.
{
"texts": {
"common": { "headlines": ["Hero"], "bodies": ["Copy"] },
"urlVariants": [
{ "link": "https://example.com/homepage", "label": "homepage" },
{ "link": "https://example.com/quiz", "label": "quiz-v2" }
]
}
}
labeles opcional. Si lo omites, se usa el último fragmento de la ruta de la URL (/quiz-v2pasa a serquiz-v2), y para las URLs raíz se recurre al nombre del dominio.- En el modo de un solo conjunto de anuncios, la etiqueta de cada variante pasa a ser el nombre completo del conjunto de anuncios.
- En los modos
perUploadyautoGroup, al nombre de cada conjunto de anuncios duplicado se le añade-{label}al final (por ejemploAd Set 01-quiz-v2), o la etiqueta reemplaza un token{destination}si incluyes uno. - El token
{date}en una etiqueta se convierte en la fecha de hoy (por ejemplo,launch-{date}pasa a serlaunch-2026-04-27). - Cada URL de destino debe ser única. Las URLs idénticas (o las variantes de la misma URL que solo cambian en la barra final o en mayúsculas) se reducen a una sola entrada, así que asegúrate de tener al menos 2 destinos distintos.
- El presupuesto de tu conjunto de anuncios se multiplica por el número de variantes, ya que cada duplicado es su propio conjunto de anuncios.
- No es compatible con anuncios de origen con destinos especiales (formulario de clientes potenciales, Messenger, WhatsApp, Instagram DM, llamada). El CLI rechaza esta combinación con un error claro, porque esos formatos no usan
cta.link. - Los
linkpor anuncio entexts.perAdpierden frente a la URL de la variante cuando se definen los dos.
Mejoras de la creatividad
Controla las mejoras de la creatividad de Advantage+:
{ "creativeEnhancements": "none" }
| Valor | Efecto |
|---|---|
| omitido | Hereda las mejoras del anuncio plantilla o del preajuste |
"metaDefaults" | Obsoleto. No define ninguna función, así que todas se envían desactivadas. |
"all" | Todas las funciones activadas |
"none" | Todas las funciones desactivadas |
["feature1", "feature2"] | Solo las funciones indicadas activadas, el resto desactivadas |
{ "feature1": true, "feature2": false } | Activa o desactiva cada función indicada de forma explícita |
Funciones disponibles: text_translation, inline_comment, enhance_cta, text_optimizations, reveal_details_over_time, show_destination_blurbs, image_brightness_and_contrast, image_touchups, video_auto_crop, video_filtering, pac_relaxation, image_animation, image_templates, adapt_to_placement, product_extensions, product_tags, description_automation, add_text_overlay, music, carousel_to_video, carousel_dynamic_description, multi_share_end_card, multi_share_optimized
La clave show_destination_blurbs se muestra como Show spotlights, y pac_relaxation como Flex media.
Cuando elijas funciones una a una, indica solo las que correspondan al tipo de medio. Las funciones de video (video_auto_crop, video_filtering) solo se aplican a anuncios de video. Las funciones de carrusel (carousel_to_video, carousel_dynamic_description, multi_share_end_card, multi_share_optimized) solo se aplican a anuncios de carrusel.
product_tags se aplica a anuncios de imagen y de video y solo funciona al clonar. Solo se puede activar cuando el anuncio de origen tiene un catálogo asociado y etiquetas de producto explícitas con posición; se conservan todas las etiquetas de origen y sus posiciones. "all" la incluye solo con un origen que cumpla los requisitos y nunca inventa una etiqueta de producto.
Anuncios de carrusel
Agrupa los archivos subidos en anuncios de carrusel con texto por tarjeta y un texto general del carrusel opcional. cardTexts controla las tarjetas individuales. El texto general del carrusel puede ir dentro del propio objeto del carrusel o definirse en texts.perAd con el name del carrusel; los campos dentro del objeto tienen prioridad cuando existen los dos.
{
"carousel": [
{
"name": "My Carousel",
"cards": ["slide1.jpg", "slide2.jpg", "slide3.jpg"],
"headlines": ["Overall Carousel Headline"],
"bodies": ["Overall primary text"],
"descriptions": ["Overall description"],
"cta": "SHOP_NOW",
"link": "https://example.com/carousel",
"urlTags": "utm_content=my_carousel",
"cardTexts": [
{ "headline": "Slide 1", "description": "First card", "link": "https://example.com/1" },
{ "headline": "Slide 2", "description": "Second card", "link": "https://example.com/2" }
]
}
]
}
Forma alternativa del texto general:
{
"texts": {
"perAd": {
"My Carousel": {
"headlines": ["Overall Carousel Headline"],
"bodies": ["Overall primary text"],
"descriptions": ["Overall description"],
"cta": "SHOP_NOW",
"link": "https://example.com/carousel",
"urlTags": "utm_content=my_carousel"
}
}
},
"carousel": [
{
"name": "My Carousel",
"cards": ["slide1.jpg", "slide2.jpg", "slide3.jpg"]
}
]
}
Las tarjetas deben hacer referencia a nombres de archivo del lote de subida o a medios capturados de un build guardado. Cada carrusel necesita de 2 a 10 tarjetas. Los archivos que usa un carrusel se quitan de la lista de anuncios estándar.
Anuncios flexibles
Agrupa varios recursos en un solo anuncio flexible en el que Meta elige el mejor recurso para cada ubicación:
{
"flexible": [
{
"name": "Multi-Asset Ad",
"assets": ["hero.jpg", "promo.mp4", "banner.jpg"]
}
]
}
Cada grupo flexible necesita de 2 a 10 recursos. Los archivos que usa un grupo flexible se quitan de la lista de anuncios estándar.
Multi Media Ads
Agrupa de 2 a 10 imágenes o videos subidos en un anuncio Multi Media de Meta:
{
"multimedia": [
{
"name": "Mixed Media Ad",
"assets": ["hero.jpg", "promo.mp4", "banner.jpg"],
"assetTexts": [
{
"headline": "Hero headline",
"primaryText": "Hero primary text",
"description": "Hero description",
"link": "https://example.com/hero",
"displayUrl": "example.com/hero"
}
]
}
]
}
Los recursos deben hacer referencia a nombres de archivo del lote de subida o a medios capturados de un build guardado. assetTexts es opcional y se empareja con assets por posición; cada campo es un cambio único para ese recurso, y los campos vacíos recurren al texto principal y a las URLs del anuncio. El recurso principal que se muestra usa el texto principal y la URL del anuncio, y cualquier texto que definas para el recurso principal pasa a ser la primera opción del texto principal. Los videos necesitan una URL pública de miniatura capturada y en caché. Los archivos que usa un grupo Multi Media se quitan de la lista de anuncios estándar.
Nombres de anuncios
Personaliza cómo se nombran tus anuncios:
{ "adNamePattern": "{filename} - {date}" }
| Marcador | Qué inserta |
|---|---|
{filename} | El nombre original del archivo sin la extensión |
{index} | El número de posición (1, 2, 3...) |
{index:01} | La posición con ceros a la izquierda. El número fija el inicio y el relleno: {index:01} da 01, 02, 03; {index:50} da 50, 51, 52. |
{variation} | El identificador de variación, si la agrupación de variantes está activada |
{campaign} | El nombre de la campaña |
{date} | La fecha actual (YYYY-MM-DD) |
{date:short} | La fecha corta (MMDD) |
{timestamp} | La marca de tiempo Unix en milisegundos |
Las transformaciones envuelven un valor. Un valor vacío significa el nombre del archivo:
| Transformación | Qué hace |
|---|---|
{split:_:2} | Divide el nombre del archivo por el delimitador (aquí _) e inserta la 2.ª parte |
{clean:} | Quita un sufijo de relación al final, como _9x16 o -1x1 |
{uppercase:}, {lowercase:}, {titlecase:} | Cambian las mayúsculas y minúsculas |
Las transformaciones se pueden anidar, por ejemplo {titlecase:{split:_:2}}. Un patrón puede tener hasta 200 caracteres. Consulta Patrones de nombres de anuncios para ver más ejemplos.
Opciones
{
"options": {
"status": "PAUSED",
"pauseAt": "adSet",
"schedule": {
"startTime": "2026-04-01T09:00:00",
"endTime": "2026-04-30T23:59:59"
}
}
}
| Campo | Valores | Descripción |
|---|---|---|
status | "PAUSED", "ACTIVE" | Estado del anuncio al lanzar (por defecto: ACTIVE) |
pauseAt | "ad", "adSet", "campaign" | En qué nivel pausar (por defecto: ad) |
schedule.startTime | Cadena ISO 8601 | Hora de inicio programada (usa la zona horaria de la cuenta publicitaria) |
schedule.endTime | Cadena ISO 8601 | Hora de fin programada (opcional) |
Cuando los anuncios van a un conjunto de anuncios existente, options.schedule solo funciona en campañas de Sales y App promotion, porque Meta solo admite programación por anuncio en esos objetivos. Para otros objetivos, crea un conjunto de anuncios nuevo o quita options.schedule.
Límites de la especificación
| Límite | Máximo |
|---|---|
| Títulos, textos principales o descripciones en un anuncio (texto flexible o una entrada por anuncio) | 5 de cada uno |
Variantes de texto con la estrategia "separate" | 50 |
Entradas en texts.perAd o texts.perAdset | 200 |
Grupos de conjuntos de anuncios personalizados (adSet.groups) | 50 |
| Medios en un grupo personalizado | 100 |
| Grupos de carrusel, flexibles o Multi Media (de cada tipo) | 50 |
| Tarjetas o recursos en un grupo de carrusel, flexible o Multi Media | De 2 a 10 |
Longitud de adNamePattern | 200 caracteres |
Subida y detección de variantes
Los grupos de variantes se detectan automáticamente a partir de las convenciones de nombres de archivo, igual que en la aplicación web. Consulta Variantes de relación de aspecto para ver todos los detalles de las convenciones de nombres.
Sufijos de relación: hero_1x1.jpg + hero_4x5.jpg + hero_9x16.jpg + hero_16x9.jpg + hero_1.91x1.jpg se agrupan como un solo anuncio con variantes. Hasta 5 relaciones por grupo.
Posición del token: el token de relación puede ir al final (hero_4x5.jpg), en medio (hero_4x5_v2.jpg) o al principio (4x5_hero.jpg).
Sufijos antiguos con palabras: hero.jpg + hero_vertical.jpg + hero_horizontal.jpg siguen funcionando y equivalen a 9x16 y 16x9.
El delimitador por defecto es _. Puedes cambiarlo (o aceptar varios) en Account > Defaults > Placements > Filename Separator.
Patrones comunes
Subir y crear con un preajuste
ads upload ./creatives/hero.jpg ./creatives/banner.jpg
ads create:preview spec.json
ads create spec.json
Donde spec.json contiene:
{ "adPresetId": "PRESET_ID", "uploadId": "BATCH_ID" }
Copiar la configuración de un anuncio existente
Explora tu cuenta para encontrar el anuncio:
ads campaigns
ads campaign 120233848666410472
ads adset 120233848666620472
ads ad 120233848667930472
Luego crea una especificación que haga referencia a él:
{
"copyFromAd": "120233848667930472",
"uploadId": "BATCH_ID"
}
El anuncio de origen debe tener la configuración de la creatividad incluida. Si se creó a partir de una publicación existente de una página, el CLI lo rechazará antes de enviar una solicitud de creación.
Guardar un preajuste de API a partir de un anuncio existente
ads presets:save --from-ad 120233848667930472 --name "Spring Purchase Template"
ads create --preset PRESET_ID --upload BATCH_ID
Esto guarda un preajuste de API con la misma forma que usa la app web. El anuncio de origen debe tener la configuración de la creatividad incluida; los anuncios basados en una publicación de página no se pueden guardar como preajustes de API.
Texto por anuncio con un texto único por archivo
{
"adPresetId": "PRESET_ID",
"uploadId": "BATCH_ID",
"texts": {
"perAd": {
"hero.jpg": {
"headlines": ["Summer Sale Now On"],
"bodies": ["Save up to 50% on all items"],
"cta": "SHOP_NOW",
"link": "https://example.com/summer"
},
"banner.jpg": {
"headlines": ["New Collection Available"],
"bodies": ["Browse our latest styles"],
"cta": "LEARN_MORE",
"link": "https://example.com/new"
}
}
}
}
Agrupar automáticamente en varios conjuntos de anuncios
{
"adPresetId": "PRESET_ID",
"uploadId": "BATCH_ID",
"adSet": { "mode": "autoGroup", "adsPerAdSet": 3 }
}
Notas importantes
- Previsualiza siempre primero.
create:previewdetecta errores de configuración antes de tocar Facebook. - Los anuncios se crean activos por defecto. Usa
--status PAUSEDo"status": "PAUSED"en la especificación para crearlos en pausa. uploadIdsale del resultado de la subida. Es el batch ID que devuelveads upload.- Las subidas están ligadas a una cuenta publicitaria. Los archivos se suben directamente a la biblioteca de medios de Facebook de la cuenta seleccionada. El batch ID solo se puede usar con esa misma cuenta.
copyFromAdnecesita medios que se puedan resolver. IndicauploadId, o lanza un build guardado cuyas imágenes capturadas tenganmediaHashy cuyos videos tenganmediaId. Opcionalmente, indicacampaign.idyadSet.idpara controlar dónde van.- Las claves del texto por anuncio son nombres de archivo. Usa
"hero.jpg", no"/path/to/hero.jpg". textPresetIdytextsson incompatibles entre sí. Usa uno u otro, no los dos.- Los CTA específicos de un objetivo se heredan de la plantilla. No definas a mano
MESSAGE_PAGE,WHATSAPP_MESSAGE, etc.
Anuncios de partnership con tus propios medios
El CLI y el MCP pueden lanzar anuncios de partnership con medios subidos en Facebook e Instagram. Usa tu especificación normal de imagen o video, carrusel, flexible, Multi Media o variantes de ubicación y añade profile.partnership.enabled: true. Los medios subidos se montan de la forma habitual con una Second Identity. Omite uploaderMode o ponlo en false; true selecciona publicaciones importadas y no se puede usar con subidas.
Elige tu First Identity con profile.pageId y profile.instagramId. El socio compartido es la Second Identity:
{
"accountId": "act_123",
"copyFromAd": "SOURCE_AD_ID",
"adSet": { "id": "EXISTING_AD_SET_ID" },
"mediaItems": [
{ "mediaName": "one.jpg", "mediaType": "image", "mediaHash": "UPLOADED_IMAGE_HASH_ONE" },
{ "mediaName": "two.jpg", "mediaType": "image", "mediaHash": "UPLOADED_IMAGE_HASH_TWO" }
],
"profile": {
"pageId": "111",
"instagramId": "222",
"partnership": {
"enabled": true,
"sponsorPageId": "333",
"sponsorInstagramId": "444",
"displayMode": "both"
}
},
"options": { "status": "PAUSED" }
}
Para socios distintos por anuncio, añade este bloque texts a la misma especificación. La segunda fila usa explícitamente No Partner:
{
"texts": {
"mode": "perAd",
"perAd": {
"one.jpg": { "sponsorPageId": "555", "sponsorInstagramId": "666" },
"two.jpg": { "sponsorPageId": null, "sponsorInstagramId": null }
}
}
}
Para ámbitos por conjunto de anuncios, usa texts.mode: "perAdset" y texts.perAdset, con claves por el nombre o ID final del conjunto de anuncios o por campaign::key. En lanzamientos con varias campañas, usa profile.campaigns[<id or unambiguous name>] para cambiar el patrocinador por campaña. El orden de resolución es el socio compartido, luego la campaña y luego la fila activa. Los campos de patrocinador omitidos se heredan cada uno por separado; pon explícitamente los dos IDs en null para No Partner. Cambiar solo la página del socio no borra un ID de Instagram heredado en los medios subidos; define ese ID de forma explícita cuando cambies la pareja. Los campos de First Identity de cada fila (pageId, instagramId, threadsId) siguen siendo independientes.
Para una Second Identity solo de Instagram, pon sponsorPageId: null, sponsorInstagramId con el ID de la cuenta aprobada y sponsorPageUseInstagramAccount: true. Con medios subidos también se admite una página de Facebook del socio. La restricción sobre las importaciones de publicaciones de Facebook no se aplica a los medios subidos.
displayMode se aplica a todo el lanzamiento: both (por defecto), first o dynamic. Cada socio efectivo debe ser distinto de la First Identity y tener acceso aprobado a la publicidad de partnership. Una aprobación pendiente o inexistente se rechaza indicando la identidad. Cada fila necesita un socio completo, heredado o explícito, o un cambio explícito a No Partner. Activar partnerships sin ningún patrocinador se rechaza. La aprobación se vuelve a comprobar al previsualizar y al crear; un build guardado no guarda los permisos concedidos.
ads create:preview y ads_preview muestran el socio efectivo, la aprobación y el modo de cabecera de cada anuncio, agrupados por conjunto de anuncios. ads create:test, solo para administradores, o ads_create con options.testMode: true validan con Meta las llamadas que cumplen los requisitos sin crear anuncios e informan de cuántas pasaron, fallaron o no se comprobaron. Los builds de partnership con medios subidos completos y guardados en la web se pueden lanzar desde el CLI y el MCP; los builds editados con estas herramientas restauran en el uploader web Partnership Ads, las identidades, los socios por fila y el modo de cabecera.
Especificación de partnership con publicación existente de Instagram
Las especificaciones JSON del CLI y las herramientas MCP ads_preview / ads_create aceptan publicaciones de Instagram con mediaItems[].kind: "partnershipPost". El anuncio de origen o el preajuste aporta la configuración; la publicación importada aporta su identidad de creador fija y su texto orgánico. Elige el patrocinador compartido en profile.partnership, o define el patrocinador y cambios de texto opcionales en texts.perAdset o texts.perAd. El título, el CTA, la URL del sitio web y el testimonio pueden quedar vacíos. Un CTA que no esté vacío necesita una URL del sitio web. No se admiten importaciones de publicaciones de Facebook.
La vista previa comprueba el contenido y los permisos mediante llamadas de lectura y de solo validación a Meta, sin crear anuncios ni guardar códigos. Su resolvedSpec sin códigos se puede guardar, pero los códigos hay que volver a aportarlos al crear. La creación vuelve a comprobar el permiso.
Usa mediaItems[].kind: "partnershipPost" con platform: "instagram". Elige exactamente un localizador: sourceInstagramMediaId, import.postUrl o import.instagramShortcode. Un import.adCode que coincida puede acompañar a un localizador, o usarse solo. El anuncio de origen o el preajuste aporta la configuración, no la publicación. Los campos opcionales creator.pageId y creator.instagramId confirman el creador resuelto.
{
"accountId": "act_123",
"copyFromAd": "456",
"adSet": { "mode": "single", "id": "789" },
"mediaItems": [{ "kind": "partnershipPost", "mediaName": "creator-post-one", "platform": "instagram", "import": { "postUrl": "https://www.instagram.com/p/POST_SHORTCODE/" } }],
"profile": { "partnership": { "enabled": true, "uploaderMode": true, "sponsorPageId": "111", "sponsorInstagramId": "222", "displayMode": "both" } },
"texts": { "mode": "common", "common": { "headline": "Discover the collection", "callToAction": "LEARN_MORE", "link": "https://example.com/", "multiAdvertiserAds": false } },
"options": { "status": "PAUSED", "pauseAt": "ad" }
}
Para una importación solo con código, usa este cuerpo de solicitud completo con tus IDs y un código insertado por un generador de secretos en memoria. No guardes el código real en un archivo:
{
"accountId": "act_123",
"copyFromAd": "456",
"adSet": { "mode": "single", "id": "789" },
"mediaItems": [{ "kind": "partnershipPost", "mediaName": "creator-post-one", "platform": "instagram", "import": { "adCode": "REPLACE_IN_MEMORY" } }],
"profile": { "partnership": { "enabled": true, "uploaderMode": true, "sponsorPageId": "111", "sponsorInstagramId": "222", "displayMode": "both" } },
"texts": { "mode": "common", "common": { "headline": "Discover the collection", "callToAction": "LEARN_MORE", "link": "https://example.com/", "multiAdvertiserAds": false } },
"options": { "status": "PAUSED", "pauseAt": "ad" }
}
Usa de 1 a 250 publicaciones por solicitud, cada una con un mediaName único de 200 caracteres como máximo. sponsorPageId debe corresponder a una página de Facebook real de la marca para cada anuncio planificado; sponsorInstagramId es opcional. El displayMode de la cabecera se aplica a todo el lanzamiento: both, first o dynamic. Para las publicaciones importadas, first significa la cabecera solo con el creador, que en el uploader se llama Partner identity only in the header, no una cabecera solo con la marca.
Los patrocinadores por campaña usan profile.campaigns, con claves por ID de campaña o por un nombre de campaña que no sea ambiguo, con sponsorPageId y sponsorInstagramId opcional. El orden de resolución es el patrocinador compartido, luego la campaña y luego el cambio activo por conjunto de anuncios o por anuncio. Pon los campos del patrocinador compartido en profile.partnership, nunca en texts.common; un adCode va en el import de la fila o en un bloque activo por anuncio o por conjunto de anuncios. Los valores pageId / instagramId del creador son comprobaciones, no una forma de cambiar el autor de la publicación.
multiAdvertiserAds es true por defecto; ponlo explícitamente en false para desactivarlo. Los valores de CTA deben ser enums de Meta como SHOP_NOW o LEARN_MORE, no etiquetas como Shop Now, y un CTA que no esté vacío necesita un destino http:// o https://. El texto orgánico no se puede editar. Los bloques de texto de publicaciones importadas admiten un título, un CTA, un enlace, etiquetas de URL, un testimonio, la declaración de IA y la opción de varios anunciantes. Cada mapa de cambios por anuncio o por conjunto de anuncios admite como máximo 200 entradas.
Para las publicaciones importadas, el CLI y el MCP rechazan las importaciones de publicaciones de Facebook, los lotes que mezclan publicaciones importadas y medios subidos, las estructuras de carrusel, flexibles o Multi Media, la agrupación por variaciones de ubicación y las identidades de Threads. Los medios subidos admiten los formatos creativos normales y los socios por fila. Por ahora, el uploader web tampoco admite nuevas importaciones de publicaciones de Facebook. No hay un explorador de publicaciones aprobadas en el uploader; importa una URL, un Post ID o un código de Instagram autorizados.
Para texts.mode: "perAd", usa mediaName como clave de texts.perAd. Para texts.mode: "perAdset", usa como clave de texts.perAdset el nombre o ID final del conjunto de anuncios o campaign::key. El texto compartido usa texts.common. adSet.groups[].media contiene esos nombres de medio; reutiliza una misma fila de medio en varios grupos en lugar de importar el mismo origen dos veces.
Usa ads create:preview /dev/stdin --account act_123 para previsualizar y luego ads create /dev/stdin --account act_123 --status PAUSED para crear. Pasa los códigos sensibles solo por stdin, nunca como argumentos, en cadenas de consulta ni en un archivo guardado en disco. Vuelve a aportar los códigos al crear; los builds guardados y el resultado de la vista previa no los incluyen. Usa --account o ejecuta antes ads account act_123, aunque el JSON contenga accountId.
Los administradores pueden ejecutar ads create:test /dev/stdin --account act_123 --status PAUSED. No crea anuncios en Meta e informa de las llamadas metaValidation como aprobadas, fallidas o no comprobadas. Un rechazo de Meta termina con código 1. Las llamadas que necesitan IDs simulados no se comprueban; una validación aprobada no garantiza la entrega ni el aspecto. Test Mode puede guardar códigos de autorización cifrados y registros de lanzamiento.