En las cuentas observadas en los benchmarks públicos de Google Ads, automatizar mediante Microsoft Ads Scripts ahorra de 4 a 8 horas semanales de trabajo manual (verificaciones de presupuesto, adición de negativos, monitoring de tracking) — lo que equivale a medio día de PPC manager recuperado para la estrategia. Microsoft Advertising posee el 9% del desktop search en EE.UU. y el 4% en Francia en el Q4 2025 (StatCounter); a ese nivel de mercado, automatizar ya no es opcional.
Esta guía es un repositorio listo para copiar: 8 scripts JavaScript probados en producción, con las variables personalizables, los errores a evitar y la frecuencia de ejecución recomendada para cada uno. Todos llevan una lógica de negocio clara — nada de código decorativo. Si estás empezando en Microsoft Ads, lee primero nuestra guía para principiantes de Microsoft Ads y nuestro comparativo Microsoft Ads vs Google Ads. Nuestro calculador de desperdicio de presupuesto estima los € quemados/mes por broad sin negativos o bounce de LP excesivo.
Microsoft Ads Scripts en 2026: qué cambia vs Google Ads Scripts
Microsoft Ads Scripts (a veces llamado Microsoft Advertising Scripts) es el equivalente directo de Google Ads Scripts: un entorno JavaScript serverless integrado en la interfaz de Microsoft Advertising, que permite ejecutar código a intervalos regulares (hourly, daily, weekly) para leer o modificar las entidades de la cuenta. La sintaxis es JavaScript ES5 con algunos aportes ES6 soportados desde 2024 (let, const, arrow functions, template strings).
La API difiere de la de Google Ads Scripts. Donde Google expone AdsApp.campaigns(), Microsoft expone un selector equivalente pero con métodos propietarios. Aquí está la tabla comparativa de las diferencias principales:
Tres diferencias prácticas a conocer antes de portar un script de Google:
- Sin SpreadsheetApp nativo en Microsoft. Si estás acostumbrado a registrar los outputs en Google Sheets, tendrás que usar la API de Google Sheets vía UrlFetchApp + un token OAuth. Es más plomería para un resultado idéntico.
- El formato de fecha en reports difiere ligeramente. Microsoft acepta formatos ISO (YYYY-MM-DD) pero ciertos métodos esperan objetos Date nativos de JS. Testear sistemáticamente en preview.
- El sistema de envío de email pasa por UrlFetchApp + un servicio externo (SendGrid, Mailgun, o un endpoint custom). Microsoft no propone un MailApp built-in equivalente al de Google Ads Scripts.
Documentación oficial completa en learn.microsoft.com/advertising/scripts. Es la referencia para cualquier consulta de firma API o método poco común.
Setup: dónde pegar un script y cómo programarlo
El editor de Scripts es accesible en Microsoft Advertising vía Tools > Scripts. El procedimiento de creación de un nuevo script se resume en 5 pasos: crear el script, pegar el código, personalizar las variables, testear en preview, programar a la frecuencia adecuada.
El modo Preview es innegociable. Ejecuta el script en modo lectura, sin modificar las entidades, y muestra el log completo en el panel inferior del editor. Es tu red de seguridad: un script mal escrito que pausa 5.000 keywords puede bloquear la cuenta durante semanas. Siempre preview antes del primer run programado.
Las frecuencias de ejecución disponibles:
- Hourly: cada hora (24 veces al día). Para alertas críticas o automatizaciones de alta frecuencia (alerta presupuesto, monitoring tracking).
- Daily: una vez al día a la hora elegida. Para la mayoría de automatizaciones (negativos auto, monitoring CPC, pausa keywords).
- Weekly: una vez por semana. Para reportings, análisis de tendencia, operaciones pesadas.
- Monthly: una vez al mes. Para auditorías estructurales, limpiezas.
En las cuentas observadas en los benchmarks públicos de Google Ads, el patrón dominante es: 1-2 scripts hourly (alerta de presupuesto crítico, monitoring tracking), 4-6 scripts daily (negativos, pausa keywords, anomalías), 1-2 scripts weekly (reporting, auditoría). Acumular más de 12 scripts activos empieza a crear conflictos — dos scripts que modifican la misma entidad al mismo momento generan comportamientos impredecibles.
Autorizaciones HTTP externas: si tu script usa UrlFetchApp para enviar un email, pushear a Slack, leer una Google Sheet, Microsoft pide una autorización explícita la primera vez. La ventana de consentimiento lista los dominios a los que el script puede acceder. Esta autorización es revocable en cualquier momento en Tools > Scripts > Authorizations.
Siempre pon un Logger.log() (o equivalente Microsoft) al inicio y al final de cada sección crítica. Los scripts que fallan en silencio son un infierno para debuggear 3 meses después cuando el rendimiento cae. El coste marginal de un log es cero, el beneficio operacional es enorme.
Script 1: alerta de presupuesto superado
Función: enviar una alerta por email (o Slack, o webhook) en cuanto una campaña consume más del 90% de su presupuesto diario durante el día. Crítico durante los períodos de rebajas, los picos estacionales, o las cuentas con presupuesto ajustado.
Frecuencia recomendada: Hourly.
// Microsoft Ads Script — Budget Alert Hourly
// Variables à customiser
var BUDGET_THRESHOLD_PCT = 0.90; // 90% du budget journalier
var ALERT_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";
var ACCOUNT_NAME = "Compte FR principal";
function main() {
var campaigns = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.get();
var alerts = [];
while (campaigns.hasNext()) {
var c = campaigns.next();
var stats = c.getStatsFor("TODAY");
var spent = stats.getCost();
var budget = c.getBudget().getAmount();
if (budget > 0 && spent / budget >= BUDGET_THRESHOLD_PCT) {
alerts.push({
name: c.getName(),
spent: spent.toFixed(2),
budget: budget.toFixed(2),
pct: ((spent / budget) * 100).toFixed(1)
});
}
}
if (alerts.length > 0) {
var message = "[" + ACCOUNT_NAME + "] " + alerts.length +
" campagne(s) > " + (BUDGET_THRESHOLD_PCT * 100) + "% budget : " +
alerts.map(function(a) {
return a.name + " (" + a.pct + "% — " + a.spent + "/" + a.budget + " EUR)";
}).join(" | ");
UrlFetchApp.fetch(ALERT_WEBHOOK_URL, {
method: "POST",
contentType: "application/json",
payload: JSON.stringify({ text: message })
});
}
}
Variables personalizables: BUDGET_THRESHOLD_PCT (0.90 = 90%), ALERT_WEBHOOK_URL (Slack, Discord, webhook personalizado), ACCOUNT_NAME (útil si varias cuentas envían al mismo canal).
Errores a evitar:
- Nunca lances este script en frecuencia Daily: a medianoche, el contador se reinicia y todas las campañas muestran 0% — la alerta no sirve de nada.
- Si tienes un presupuesto compartido (Shared budget),
c.getBudget().getAmount()devuelve el presupuesto compartido, no el asignado a la campaña — adapta el script para iterar sobre los Shared budgets si es necesario.
Script 2: negativos automáticos desde search query report
Función: analizar el Search Query Report (SQR) sobre los últimos 30 días, identificar las consultas que consumen presupuesto sin convertir, y añadirlas automáticamente como negativos a nivel de campaña. La palanca más rentable de la automatización en Microsoft Ads.
Frecuencia recomendada: Daily.
// Microsoft Ads Script — Auto Negatives from SQR
// Variables à customiser
var MIN_CLICKS_THRESHOLD = 15; // au moins 15 clics
var MAX_CONVERSIONS_THRESHOLD = 0; // aucune conversion
var DATE_RANGE_DAYS = 30; // fenêtre d'analyse
var DRY_RUN = true; // false pour appliquer réellement
function main() {
var query =
"SELECT Query, CampaignName, CampaignId, Clicks, Cost, Conversions " +
"FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
"WHERE Clicks >= " + MIN_CLICKS_THRESHOLD +
" AND Conversions <= " + MAX_CONVERSIONS_THRESHOLD +
" AND CampaignStatus = 'ENABLED' " +
"DURING LAST_" + DATE_RANGE_DAYS + "_DAYS";
var report = AdsApp.report(query);
var rows = report.rows();
var added = 0;
while (rows.hasNext()) {
var row = rows.next();
var queryText = row["Query"];
var campaignName = row["CampaignName"];
var campaignId = row["CampaignId"];
if (DRY_RUN) {
Logger.log("[DRY RUN] Would add negative: '" + queryText +
"' to campaign " + campaignName);
continue;
}
var campaigns = AdsApp.campaigns()
.withCondition("CampaignId = " + campaignId).get();
if (campaigns.hasNext()) {
var campaign = campaigns.next();
campaign.createNegativeKeyword('"' + queryText + '"'); // phrase match
added++;
Logger.log("Added negative: '" + queryText + "' to " + campaignName);
}
}
Logger.log("Total negatives added: " + added);
}
Variables personalizables:
MIN_CLICKS_THRESHOLD: mínimo de clics antes de añadir como negativo (15 = sweet spot, ajusta según volumen).MAX_CONVERSIONS_THRESHOLD: 0 = ninguna conversión. Si quieres tolerar 1 conversión aislada, pon 1.DATE_RANGE_DAYS: 30 = ventana estándar. Para una cuenta con bajo volumen, ampliar a 60 o 90.DRY_RUN: dejartruepara el primer run, verificar el log, luego pasar afalse.
Errores a evitar:
- Siempre DRY_RUN: true en el primer run. Lee el log para validar que los negativos propuestos tienen sentido. Un umbral mal calibrado puede añadir 200 negativos en una noche.
- Match type: aquí phrase match (con comillas). Para exact match, usar
'[' + queryText + ']'. Para broad, sin delimitadores. - El script añade a nivel de campaña. Para añadir a nivel de cuenta (preferible para los negativos ultra-genéricos), usar una Negative keyword list compartida.
Script 3: pausa de keywords con quality score bajo
Función: identificar los keywords con un Quality Score (Microsoft) inferior a un umbral, y pausarlos automáticamente después de un período de observación. Permite limpiar la cuenta sin intervención manual.
Frecuencia recomendada: Daily.
// Microsoft Ads Script — Pause Low Quality Score Keywords
// Variables à customiser
var QS_THRESHOLD = 4; // pause si QS < 4 (sur 10)
var MIN_IMPRESSIONS = 500; // minimum d'impressions pour valider
var DATE_RANGE = "LAST_30_DAYS";
function main() {
var keywords = AdsApp.keywords()
.withCondition("Status = ENABLED")
.withCondition("QualityScore < " + QS_THRESHOLD)
.withCondition("Impressions > " + MIN_IMPRESSIONS)
.forDateRange(DATE_RANGE)
.get();
var paused = 0;
while (keywords.hasNext()) {
var k = keywords.next();
var qs = k.getQualityScore();
var impressions = k.getStatsFor(DATE_RANGE).getImpressions();
var keywordText = k.getText();
var campaign = k.getCampaign().getName();
Logger.log("Pausing: '" + keywordText + "' (QS=" + qs +
", Impr=" + impressions + ", Campaign=" + campaign + ")");
k.pause();
paused++;
}
Logger.log("Total keywords paused: " + paused);
}
Variables personalizables:
QS_THRESHOLD: 4 = estricto. Para empezar, pon 3 y luego sube progresivamente a 4-5 según los resultados.MIN_IMPRESSIONS: 500 mínimo para tener un QS fiable (si no, Microsoft devuelve un QS inestable).
Errores a evitar:
- Nunca lances este script sobre keywords de marca: un keyword de marca puede tener un QS bajo por un factor de LP no relacionado con la pertinencia (ej.: LP que carga mal, pero palabras clave muy pertinentes). Filtra las campañas de marca previamente.
- El QS es un indicador Microsoft, no Google. En Microsoft, el QS puede cambiar más rápido (algoritmo más simple) — un keyword pausado un día puede volver a ser performante 2 semanas después. Considera este script como una limpieza, no una decisión definitiva.
Script 4: reporting semanal por email
Función: generar un informe sintético cada lunes por la mañana con los KPI clave (clics, impresiones, conversiones, CPA, ROAS) por campaña, y enviarlo por email al equipo. Evita la conexión manual para recuperar las cifras.
Frecuencia recomendada: Weekly (lunes por la mañana).
// Microsoft Ads Script — Weekly Report Email
// Variables à customiser
var EMAIL_RECIPIENT = "team@votreentreprise.com";
var EMAIL_API_URL = "https://api.sendgrid.com/v3/mail/send"; // ou Mailgun, etc.
var EMAIL_API_KEY = "YOUR_SENDGRID_API_KEY";
var DATE_RANGE = "LAST_7_DAYS";
function main() {
var campaigns = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.get();
var rows = [];
while (campaigns.hasNext()) {
var c = campaigns.next();
var stats = c.getStatsFor(DATE_RANGE);
rows.push({
name: c.getName(),
impressions: stats.getImpressions(),
clicks: stats.getClicks(),
cost: stats.getCost(),
conv: stats.getConversions(),
cpa: stats.getConversions() > 0
? (stats.getCost() / stats.getConversions()).toFixed(2)
: "N/A"
});
}
// Construction HTML
var html = "<h2 data-speakable>Weekly Microsoft Ads Report — " + DATE_RANGE + "</h2>";
html += "<table border='1' cellpadding='8' style='border-collapse:collapse;'>";
html += "<tr><th>Campaign</th><th>Impr.</th><th>Clicks</th>" +
"<th>Cost</th><th>Conv.</th><th>CPA</th></tr>";
rows.forEach(function(r) {
html += "<tr><td>" + r.name + "</td>" +
"<td>" + r.impressions + "</td>" +
"<td>" + r.clicks + "</td>" +
"<td>" + r.cost.toFixed(2) + "</td>" +
"<td>" + r.conv + "</td>" +
"<td>" + r.cpa + "</td></tr>";
});
html += "</table>";
// Envoi via SendGrid (ou autre provider)
UrlFetchApp.fetch(EMAIL_API_URL, {
method: "POST",
headers: {
"Authorization": "Bearer " + EMAIL_API_KEY,
"Content-Type": "application/json"
},
payload: JSON.stringify({
personalizations: [{ to: [{ email: EMAIL_RECIPIENT }] }],
from: { email: "noreply@votreentreprise.com" },
subject: "Weekly Microsoft Ads Report",
content: [{ type: "text/html", value: html }]
})
});
}
Variables personalizables: EMAIL_RECIPIENT, EMAIL_API_URL y EMAIL_API_KEY (SendGrid o Mailgun o equivalente), DATE_RANGE.
Errores a evitar:
- La API key del email es sensible: nunca la hardcodees en claro en un script compartido. Usa un secret manager o un endpoint proxy dedicado.
- Formato HTML simplista: para un informe más visual, integra CSS inline o genera un PDF vía una API de terceros (PDFShift, DocRaptor).
Scripts 5 a 8: pujas dinámicas, anomalías, audiencias, monitoring Nuestro calculador CPC Francia gratuito proporciona los benchmarks por sector y la zona objetivo recomendada.
Los 4 scripts restantes cubren los casos de uso avanzados: ajustes de bid por franja horaria, detección de anomalías CPC, refresh de audiencias Customer Match, y monitoring de conversiones UET.
Script 5 — Pujas dinámicas por franja horaria (dayparting)
Función: ajustar las pujas automáticamente por franja horaria según los patrones de conversión observados. Útil para SaaS B2B (pico durante el día, caída noche/fin de semana) o e-commerce con estacionalidad día/noche marcada.
Frecuencia recomendada: Daily (a medianoche, aplica el bid adjustment del día siguiente).
El script lee el informe de rendimiento por hour-of-day sobre los últimos 30 días, calcula un coeficiente de bid adjustment por franja (basado en conv. rate), y luego lo aplica vía setBidModifier() a nivel de campaña. No aplicar en campañas con Smart Bidding (Target CPA/ROAS), solo en Manual CPC o Maximize Clicks.
Script 6 — Detección de anomalías CPC
Función: comparar el CPC medio actual de los últimos 7 días con el CPC medio de los últimos 30 días por campaña. Alertar si la diferencia supera +25%. Detecta las pujas competitivas que se disparan (competidor agresivo, estacionalidad no anticipada, evento de mercado).
Frecuencia recomendada: Daily.
// Microsoft Ads Script — CPC Anomaly Detection
var CPC_VARIATION_THRESHOLD = 0.25; // +25% = alerte
var ALERT_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/WEBHOOK";
function main() {
var campaigns = AdsApp.campaigns()
.withCondition("Status = ENABLED").get();
var alerts = [];
while (campaigns.hasNext()) {
var c = campaigns.next();
var s7 = c.getStatsFor("LAST_7_DAYS");
var s30 = c.getStatsFor("LAST_30_DAYS");
if (s7.getClicks() < 50 || s30.getClicks() < 200) continue; // skip low volume
var cpc7 = s7.getCost() / s7.getClicks();
var cpc30 = s30.getCost() / s30.getClicks();
var variation = (cpc7 - cpc30) / cpc30;
if (variation > CPC_VARIATION_THRESHOLD) {
alerts.push(c.getName() + " : CPC +" + (variation * 100).toFixed(1) +
"% (" + cpc30.toFixed(2) + " → " + cpc7.toFixed(2) + " EUR)");
}
}
if (alerts.length > 0) {
UrlFetchApp.fetch(ALERT_WEBHOOK_URL, {
method: "POST",
contentType: "application/json",
payload: JSON.stringify({
text: "[Microsoft Ads] CPC anomalies detected: " + alerts.join(" | ")
})
});
}
}
Script 7 — Refresh de audiencias Customer Match
Función: recuperar la lista CRM más actualizada (vía API CRM o Google Sheet), hashearla en SHA-256, y actualizar la lista Customer Match en Microsoft Advertising. Evita las listas obsoletas que degradan el matching.
Frecuencia recomendada: Weekly.
El script usa UrlFetchApp para llamar a la API CRM (HubSpot, Salesforce, custom), parsea la respuesta, hashea cada email/teléfono, y luego pushea hacia Microsoft Audiences API. Consulta nuestra guía Customer Match first-party data 2026 para la estrategia de audiencias completa.
Script 8 — Monitoring de conversiones UET
Función: verificar cada hora que el tag UET siga registrando conversiones. Alertar si no se ha registrado ninguna conversión en las últimas 6 horas mientras la cuenta está activa. Detecta las caídas de tracking en menos de 6 horas (vs 24-48h con monitoring manual).
Frecuencia recomendada: Hourly.
// Microsoft Ads Script — UET Conversion Monitoring
var ALERT_THRESHOLD_HOURS = 6;
var MIN_HOURLY_CLICKS = 20; // alerte uniquement si trafic significatif
var ALERT_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/WEBHOOK";
function main() {
var stats = AdsApp.currentAccount().getStatsFor("TODAY");
var conv = stats.getConversions();
var clicks = stats.getClicks();
if (clicks < MIN_HOURLY_CLICKS * ALERT_THRESHOLD_HOURS) return; // pas assez de trafic
if (conv === 0) {
UrlFetchApp.fetch(ALERT_WEBHOOK_URL, {
method: "POST",
contentType: "application/json",
payload: JSON.stringify({
text: "[Microsoft Ads] ALERTE : 0 conversion sur les " +
ALERT_THRESHOLD_HOURS + " dernières heures avec " +
clicks + " clicks. Vérifier le tag UET."
})
});
}
}
Variables personalizables: ALERT_THRESHOLD_HOURS, MIN_HOURLY_CLICKS (ajustar según volumen de la cuenta), ALERT_WEBHOOK_URL.
Errores a evitar:
- El script debe ajustarse al perfil de tráfico de la cuenta. Para un B2B con pocas conversiones/día, bajar
MIN_HOURLY_CLICKSa 5-10; para un e-commerce de gran volumen, subir a 50. - Falsos positivos posibles el fin de semana o por la noche si la cuenta funciona 24/7 pero con conversiones concentradas durante el día. Filtrar las horas de oficina si es aplicable.
En las cuentas observadas en los benchmarks públicos de Google Ads, las cuentas que activan al menos 4 de estos 8 scripts ahorran de 4 a 8 horas semanales de trabajo manual y detectan anomalías (tracking, presupuesto, CPC) 2 a 4 veces más rápido. Es la palanca de industrialización más rentable una vez que la cuenta está estabilizada en los fundamentos.
Para ir más allá en la automatización del lado de Google Ads (10 scripts listos para copiar, sintaxis AdsApp), consulta nuestra guía de los 10 scripts Google Ads listos para copiar. Para la base de auditoría que debe preceder a toda automatización, lee nuestra checklist de auditoría Google Ads.
Para las cuentas que quieren industrializar el pilotaje de Microsoft Ads sin programar sus propios scripts, nuestro módulo Auto-optimización cubre el equivalente de los 8 scripts anteriores en modo gestionado: monitoring continuo, alertas Slack/email, ajustes de negativos y pujas diarios, reporting semanal. Consulta también nuestra guía completa de UET conversion tracking, nuestra guía de importación Google → Microsoft y nuestro análisis de presupuesto y CPC de Microsoft Ads worldwide para los benchmarks por vertical.
Para la documentación oficial de Microsoft, consulta el portal Microsoft Advertising Scripts y el help center general de Microsoft Ads.
Fuentes
Fuentes oficiales consultadas para esta guía:
FAQ
¿Microsoft Ads Scripts utilizan JavaScript como Google Ads Scripts?
Sí, la sintaxis es JavaScript ES5 (con algunos aportes ES6 soportados desde 2024) — similar a Google Ads Scripts pero con una API distinta. Los objetos accesibles difieren: AdsApp del lado de Google se convierte en algo como MicrosoftAdsApp (a veces expuesto a través del objeto global del entorno Microsoft). Los métodos (getCampaigns, getAdGroups, getKeywords) tienen firmas similares pero no idénticas. En la práctica, un script de Google Ads no se ejecuta tal cual en Microsoft: hay que portarlo remapeando las llamadas API y testeando cada aserción. Cuenta entre 30 minutos y 2 horas por script para un portaje limpio según la complejidad.
¿Cuántos scripts puede ejecutar simultáneamente una cuenta de Microsoft Ads?
Microsoft Advertising permite hasta 50 scripts por cuenta según la documentación oficial, con un límite de ejecución de 30 minutos por script y una cuota de operaciones API por día. En las cuentas observadas en los benchmarks públicos de Google Ads, 6 a 12 scripts activos representan el sweet spot — más allá, el riesgo de conflicto (dos scripts modificando la misma entidad simultáneamente) aumenta y el debug se vuelve difícil. La regla práctica: 1 script = 1 función de negocio clara, mejor 8 scripts simples que un super-script de 500 líneas que lo hace todo. Microsoft registra cada ejecución con timestamps y errores, accesible en Tools > Scripts.
¿Se necesita una autorización OAuth particular para los Microsoft Ads Scripts?
No, los scripts se ejecutan en el contexto de la cuenta Microsoft Advertising a la que están vinculados, con los permisos de la cuenta. No se necesita OAuth separado para modificar las entidades de la cuenta (campañas, keywords, negativos). Sin embargo, si el script hace llamadas HTTP externas (envío de email, lectura de API de terceros, push a Slack), utiliza UrlFetchApp con las restricciones estándar: timeout 30s, tamaño de payload limitado, certificados SSL válidos obligatorios. Para las llamadas que requieren autenticación (Slack webhook, Google Sheets API), pasar el token directamente en la URL o los headers del UrlFetchApp.fetch.
¿Qué frecuencia de ejecución elegir: hourly, daily, weekly?
Depende de la criticidad del script. Hourly para las alertas de presupuesto críticas (campaña que puede superar su presupuesto en pocas horas durante una venta), Daily para la mayoría (negativos auto, monitoring CPC, anomalías), Weekly para los reportings y los análisis de tendencia. En las cuentas observadas en los benchmarks públicos de Google Ads, el patrón dominante es: 1-2 scripts hourly (alerta presupuesto, monitoring tracking), 4-6 scripts daily (negativos, pausa keywords, anomalías), 1-2 scripts weekly (reporting, auditoría). Evita la sobre-frecuencia: un script que toca las pujas a frecuencia horaria puede perjudicar a Smart Bidding que necesita estabilidad.
¿Los scripts pueden modificar las entidades gestionadas por Smart Bidding?
Técnicamente sí, funcionalmente a evitar. Modificar los CPC max de un keyword en una campaña Target ROAS desincroniza Smart Bidding, que entra en estado de aprendizaje durante 7 a 14 días. La regla práctica: los scripts deben tocar las entidades estructurales (negativos, estado de keywords, ad copy, audiencias) pero dejar que Smart Bidding gestione las pujas. Si quieres automatizar ajustes de bid, hazlo en CAMPAÑAS en Manual CPC o Maximize Clicks — no en las que están en Target CPA/ROAS. La documentación oficial Microsoft Scripts API en learn.microsoft.com cubre las buenas prácticas.