Dokumentation

CLI, MCP und API

CLI-Referenz komplett

Das ist die vollständige Referenz für das Ads Uploader CLI. Eine Einführung und Anleitung zur Einrichtung findest du unter CLI-Konfiguration.

Befehle

Authentifizierung

BefehlWas er macht
ads loginAuthentifizierung per Browser (öffnet deinen Standardbrowser)
ads logoutLöscht die gespeicherten Anmeldedaten
ads whoamiZeigt die angemeldete E-Mail, das Standard-Werbekonto und die API-URL
ads configZeigt, ob du angemeldet bist, deine E-Mail, das Standard-Werbekonto, die API-URL und den Konfigurationsordner (~/.config/adsuploader/)
ads --versionZeigt die installierte CLI-Version

Ein Login-Token gilt 30 Tage. Danach führst du ads login einfach erneut aus.

Durchsuchen

BefehlWas er macht
ads accountsListet alle Werbekonten auf, die mit deinem Meta-Konto verbunden sind
ads accounts:refreshHolt die Liste der Werbekonten sofort neu von Meta, zum Beispiel nachdem du Zugriff auf ein neues Werbekonto bekommen hast
ads account <id>Legt ein Standard-Werbekonto für künftige Befehle fest
ads pagesListet die Facebook-Seiten auf, mit denen du werben kannst, inklusive eines verknüpften Instagram-Kontos, zur Verwendung mit Profil-Überschreibungen
ads targeting:search "Austin" --type cityFindet City-Keys für das Ad-Set-Targeting
ads targeting:search "90210" --type zipFindet Postleitzahl-Keys für das Ad-Set-Targeting
ads targeting:search "advertising" --type detailedFindet IDs und Typen für detailliertes Targeting
ads campaignsListet aktive Kampagnen auf
ads campaigns --status allSchließt auch inaktive Kampagnen ein
ads campaigns --search "text"Filtert Kampagnen nach Name
ads campaign <id>Zeigt die Ad Sets innerhalb einer Kampagne
ads adsets --campaign <id>Listet die Ad Sets einer Kampagne auf (unterstützt --search, --status)
ads adset <id>Zeigt die Anzeigen innerhalb eines Ad Sets
ads ad <id>Zeigt alle Anzeigendetails inklusive Creative-Einstellungen
ads presetsListet deine gespeicherten API-Presets auf
ads presets <id>Zeigt Details zu einem bestimmten Preset
ads presets:save --from-ad <adId> --name "Preset Name"Speichert eine bestehende Anzeige als API-Preset. Mit --share teilst du es mit deinem Team (Team-Tarife).
ads text-presetsListet deine gespeicherten Text-Presets auf
ads text-presets <id>Zeigt Details zu einem bestimmten Text-Preset
ads uploadsListet die letzten Upload-Batches auf (standardmäßig 20, änderbar mit --limit <n>)
ads uploads <batchId>Zeigt Batch-Details (Dateien, Varianten, Hashes)

Saved Builds

Saved Builds sind dieselben Builds, die du im Fenster Saved Builds des Web-Uploaders siehst. Wie sie funktionieren, erfährst du unter Saved Builds.

BefehlWas er macht
ads buildsListet deine gespeicherten Builds auf (filtern mit --account <id>)
ads builds <buildId>Zeigt einen gespeicherten Build, inklusive seiner aktuellen Revisionsnummer
ads builds:create --spec spec.json --name "Summer Sale"Speichert eine Spec als neuen Build. builds:save ist ein Alias. Akzeptiert außerdem --notes, --account und --web-state <file>.
ads builds:update <buildId> --spec-patch patch.json --expected-revision <n>Ändert einen Teil der Spec eines Builds mit einem JSON-Merge-Patch. --expected-revision ist Pflicht und verhindert, dass du eine neuere Änderung von jemand anderem überschreibst.
ads builds:update <buildId> --name "New name"Benennt einen Build um. --notes, --spec <file> (ersetzt die ganze Spec) und --web-state <file> funktionieren ebenfalls.
ads builds:fork <buildId>Kopiert einen Build in einen neuen Entwurf, das Original bleibt unverändert
ads builds:delete <buildId>Löscht einen gespeicherten Build

Übergib - statt eines Dateinamens, um das JSON von stdin zu lesen. Um einen Build zu starten, nutzt du ads create --build <buildId> (oder create:preview).

Medien-Upload

BefehlWas er macht
ads upload <inputs...>Lädt lokale Pfade und öffentliche HTTPS-URLs in dein Werbekonto hoch
ads upload ./directory/Lädt ein ganzes Verzeichnis hoch
ads upload:drive <folderUrl>Importiert einen öffentlichen Google-Drive-Ordner als Hintergrundjob (akzeptiert --account, --json und --api-timeout)
ads upload --retry-failed [batchId]Wiederholt die fehlgeschlagenen Dateien aus deinem letzten fehlgeschlagenen Upload-Batch oder aus dem Batch, den du angibst. Übergib mit diesem Flag keine Dateien.

HTTPS-Argumente, auch öffentliche Google-Drive-Dateilinks, werden automatisch erkannt. Du kannst lokale Pfade und URLs mischen: Lokale Dateien werden zuerst hochgeladen, dann importiert der Server die URLs in denselben Batch, sodass die Gruppierung über alle Eingaben hinweg funktioniert. Öffentliche Drive-Ordner müssen als Anyone with the link (Viewer) freigegeben sein.

Lokale Dateien werden parallel bereitgestellt, und vorübergehende Netzwerkfehler werden automatisch mit Backoff wiederholt. URL- und Drive-Ordner-Importe laufen in einem Hintergrundjob mit begrenzt parallelen Datei-Pipelines, während das CLI einen Zähler für erledigt/gesamt und jede aktive Datei anzeigt. Diese Flags brauchst du selten, aber es gibt sie:

Upload-FlagBeschreibung
--concurrency <n>Anzahl der parallel bereitgestellten Dateien, 1-6 (Standard: 4). Große Videos werden automatisch gedrosselt, damit der Speicher reicht.
--upload-timeout <ms>Upload-Timeout pro Datei (Standard: 120000)
--api-timeout <ms>Timeout für API-Anfragen in Millisekunden (Standard: 60000). Gibt es auch bei upload:drive. Für alle Befehle setzt du es mit der Umgebungsvariable ADS_API_TIMEOUT_MS.

Upload-Regeln:

  • Jede Datei darf bis zu 4 GB groß sein.
  • Bilder: .jpg, .jpeg, .png, .gif, .bmp, .webp. Videos: .mp4, .mov, .avi, .mkv, .webm, .m4v.
  • Links müssen https:// verwenden. Alles andere wird als lokaler Pfad behandelt.
  • Ein Bild, das wie sein Video plus _thumbnail heißt (zum Beispiel promo_thumbnail.jpg für promo.mp4), wird als eigenes Thumbnail an dieses Video angehängt, statt als separates Medium hochgeladen zu werden.
  • Drückst du während eines Link- oder Drive-Imports Ctrl-C, bittet das CLI den Server, den Import zu stoppen. Bereits fertige Dateien bleiben im Batch.

Anzeigenerstellung

BefehlWas er macht
ads create spec.jsonErstellt Anzeigen aus einer Spec-Datei
ads create:preview spec.jsonProbelauf, der zeigt, was erstellt würde
ads create:test [spec.json]Test Mode nur für Admins mit reinen Validierungsergebnissen von Meta; erstellt keine Meta-Anzeigen
ads create:interactiveGeführter Assistent (akzeptiert alle Create-Flags)

Post-ID-Duplizierung

BefehlWas er macht
ads duplicator:post-id [specFile]Dupliziert bestehende Anzeigen, die über die Post-ID einer Seite ausgewählt werden, und behält ihre Post-Referenzen
ads duplicator:post-id:preview [specFile]Vorschau einer Post-ID-Duplizierung mit der Zuordnung von Quelle zu Ziel

Job-Verwaltung

BefehlWas er macht
ads jobs <jobId>Prüft den Status eines Jobs
ads jobs <jobId> --followStreamt Live-Fortschritt
ads jobs cancel <jobId>Bricht einen laufenden Job ab

Create-Flags

Diese Flags gelten für ads create, ads create:preview und ads create:interactive (und für ads create:test, das nur Admins nutzen können). Du kannst sie statt einer Spec-Datei oder zusätzlich dazu verwenden.

FlagBeschreibung
--account <id>Überschreibt das Standard-Werbekonto
--build <buildId>Nutzt einen gespeicherten Build als Spec. Kombiniere das nicht mit einer Spec-Datei.
--preset <id>Nutzt ein gespeichertes API-Preset (Alternative zur Spec-Datei)
--text-preset <id>Lädt ein gespeichertes Text-Preset
--copy-from <adId>Kopiert Einstellungen aus einer bestehenden Anzeige
--upload <batchId>Gibt die Upload-Batch-ID an
--status <PAUSED|ACTIVE>Legt den Anzeigenstatus fest (Standard: ACTIVE)
--pause-at <level>Pausierungsebene: ad (Standard), adSet oder campaign
--daily-budget <amount>Überschreibt das Tagesbudget pro Ad Set (Währungseinheiten, z. B. 50 für 50 $)
--bid-amount <amount>Überschreibt Gebot bzw. Kostenobergrenze pro Ad Set (Währungseinheiten)
--minimum-roas <ratio>Überschreibt das Mindest-ROAS-Ziel pro Ad Set (z. B. 1.5)
--campaign-daily-budget <amount>Setzt ein CBO-Tagesbudget für die Kampagne in ganzen Währungseinheiten. Schließt das Laufzeitbudget aus; lässt du beide weg, wird das Budget der Quellkampagne übernommen.
--campaign-lifetime-budget <amount>Setzt ein CBO-Laufzeitbudget für die Kampagne in ganzen Währungseinheiten. Schließt das Tagesbudget aus; lässt du beide weg, wird das Budget der Quellkampagne übernommen.
--adset-min-spend <amount>Setzt die Mindestausgaben des Ad Sets unter CBO in ganzen Währungseinheiten; 0 entfernt das vom Quell-Ad-Set übernommene Limit.
--adset-max-spend <amount>Setzt die Höchstausgaben des Ad Sets unter CBO in ganzen Währungseinheiten; 0 entfernt das vom Quell-Ad-Set übernommene Limit.
--adset-min-spend-pct <5-100>Setzt die Mindestausgaben des Ad Sets als Prozentsatz des Kampagnenbudgets, in 5-%-Schritten. Funktioniert auch mit einer bestehenden CBO-Kampagne; schließt --adset-min-spend aus.
--adset-max-spend-pct <5-100>Setzt die Höchstausgaben des Ad Sets als Prozentsatz des Kampagnenbudgets, in 5-%-Schritten. Funktioniert auch mit einer bestehenden CBO-Kampagne; schließt --adset-max-spend aus.
--location <ISO>Zielt auf ein Land per zweistelligem ISO-Code. Wiederhole das Flag für mehrere Länder.
--age-min <n>Mindestalter, von 13 bis 65
--age-max <n>Höchstalter, von 13 bis 65 (65 bedeutet 65+)
--gender <gender>all, men oder women. all entfernt eine Geschlechtereinschränkung, die vom Quell-Ad-Set übernommen wurde.
--ai-disclosureLegt selbst offen, dass Creative-Inhalte mit KI erstellt wurden (Metas Transparenz für KI-Inhalte). Standardmäßig aus. Das Spec-Feld findest du unter KI-Offenlegung.
--page <id>Nutzt diese Facebook-Seite statt der aus der Vorlage (siehe Profiloptionen)
--instagram <id>Nutzt dieses Instagram-Konto statt des aus der Vorlage
--use-page-identityNutzt die Facebook-Seite als Instagram-Identität; nicht mit --instagram kombinierbar
--threads <id>Nutzt dieses Threads-Profil statt des aus der Vorlage
--text-file <path>Lädt die Textkonfiguration aus einer JSON-Datei
--expandedZeigt in Vorschauen die vollständigen Werte für Headline, Primärtext und Beschreibung

Flags für die Post-ID-Duplizierung

Diese Flags gelten für ads duplicator:post-id und ads duplicator:post-id:preview. Du kannst sie statt einer Spec-Datei für die Post-ID-Duplizierung oder zusätzlich dazu verwenden. Das ist der Modus für die Post-ID-Duplizierung; weitere Duplizierungsmodi kommen eventuell später dazu.

FlagBeschreibung
--account <id>Überschreibt das Standard-Werbekonto
--post <postId>Findet Quellanzeigen über die Post-ID einer Seite. Bei mehreren Treffern brauchst du eine ausdrückliche Auswahl per --ad.
--ad <adId>Wählt eine exakte Quellanzeigen-ID. Für mehrere Anzeigen wiederholen; nicht mit --post kombinieren.
--campaign <id>Nutzt eine bestehende Zielkampagne
--adset <id>Nutzt ein bestehendes Ziel-Ad-Set oder verwendet es als Vorlage für ein neues Ad Set
--new-adset [name]Erstellt ein neues Ad Set für alle Quellanzeigen. Der Standardname ist {AdName}.
--new-adset-per-ad [name]Erstellt ein neues Ad Set pro Quellanzeige. Der Standardname ist {AdName}.
--ad-name <pattern>Legt das Namensmuster der duplizierten Anzeigen fest. Standard ist {AdName}.
--pausedErstellt die duplizierten Anzeigen pausiert
--use-creative-idVerwendet die ursprünglichen Creative-IDs wieder, statt Creatives mit Post-Referenz zu erstellen
--acknowledge-warningsSetzt einen Live-Lauf fort, nachdem du die Creative-Warnungen in der Vorschau geprüft hast (acknowledgeWarnings: true im JSON)
--jsonGibt rohes JSON für Skripte aus

Spec-Datei für die Post-ID-Duplizierung

Diese v1-Spec wählt eine exakte Quellanzeige, klont ein Ad Set und erstellt pausierte Anzeigen:

{
  "adIds": ["120200000000000001"],
  "campaignId": "120200000000000000",
  "adSetId": "120200000000000002",
  "newAdSet": { "name": "Winners {AdName}" },
  "adNamePattern": "{AdName} - {Index}",
  "paused": true,
  "useCreativeId": false
}

Nutze entweder postIds zum Finden oder geordnete adIds für eine exakte Auswahl, nie beides. Die Vorschau liefert sourceCandidates mit Anzeigen-, Kampagnen- und Ad-Set-IDs. Sind die Treffer mehrdeutig, ist requiresSourceSelection true und resolvedRequest null: Wähle die Anzeigen-IDs aus und starte die Vorschau erneut. Bei einer exakten Auswahl enthält resolvedRequest Anzeigen-IDs und keine Post-IDs. Eine bestehende campaignId ist Pflicht; neue Kampagnen werden nicht unterstützt.

Wähle einen Zielmodus für das Ad Set:

ZielSpec-Felder
Bestehendes Ad Set"adSetId": "120200000000000002"
Ein neues Ad Set"newAdSet": { "name": "Winners {AdName}" } und optional adSetId als Vorlage
Ein neues Ad Set pro Anzeige"newAdSetPerAd": { "name": "Winners {Index} {AdName}" } und optional adSetId als Vorlage

Bei Live-Läufen mit Creative-Warnungen prüfst du die Vorschau und übergibst --acknowledge-warnings (acknowledgeWarnings: true in JSON/MCP), um fortzufahren. Ein ausdrückliches useCreativeId: true erfüllt diese Entscheidung ebenfalls. Die Vorschau braucht keine Bestätigung.

Zielkampagne, ausgewähltes Ad Set und Quellanzeigen müssen zum selben Werbekonto gehören. Ein ausgewähltes Ad Set muss zu campaignId gehören, auch wenn es als Vorlage für ein neues Set dient. Wähle entweder newAdSet oder newAdSetPerAd; beides zusammen wird abgelehnt. Eine einzelne Quelle mit newAdSetPerAd erstellt einen gemeinsamen Klon und behält {Index} als 1.

Vorschau und Web-Test-Mode lesen die echte Konfiguration jeder Quellanzeige und jeder ausgewählten Vorlage, ohne Meta-Objekte zu erstellen. Spätere Quellen können deshalb fehlende Daten und Creative-Warnungen aufdecken; das Targeting wird für jede Vorlage geprüft, die ein neues Ad Set erzeugt. Simulierte neue Ad Sets nutzen, wenn verfügbar, die Budget- und Gebotseinstellungen der Zielkampagne. Anzeigen sind standardmäßig aktiv; paused betrifft nur Anzeigen, neue Ad Sets bleiben aktiv.

{AdName} fügt den Namen der Quellanzeige ein. {Index} fügt ihre Position (ab 1) in duplizierte Anzeigennamen und in Ad-Set-Namen pro Anzeige ein. Enthält ein neues Ad Set mehrere Quellanzeigen, wird {AdName} im Namen dieses Ad Sets zu Multiple Ads.

So wählt die Post-Suche Anzeigen aus: Eine Suche per Post-ID durchsucht bis zu etwa 2.000 aktuelle Anzeigen im Konto. Sie wählt nie einfach den neuesten Treffer für dich. Passen mehrere Anzeigen, stoppen CLI und MCP und bitten dich um eine Auswahl; sie stoppen auch bei Warnungen, die du noch nicht bestätigt hast. Ein Live-Lauf dupliziert immer exakte Anzeigen-IDs, also reichst du den resolvedRequest aus der Vorschau ein. Um eine bereits geprüfte Auswahl erneut auszuführen, speicherst du resolvedRequest und verwendest es wieder (MCP braucht zusätzlich accountId), statt die reine Post-Suche zu wiederholen. Die Anzeigen-IDs bleiben fest, aber die aktuellen Meta-Einstellungen werden beim Start erneut gelesen und geprüft.

Neue Ad Sets übernehmen Targeting, Budget, Zeitplan und Gebotseinstellungen aus dem ausgewählten --adset oder adSetId, mit derselben Bereinigung und demselben Budgetabgleich mit dem Ziel wie im Web-Duplicator. Ohne ausgewählte Vorlage nutzt ein gemeinsames neues Set das Set der ersten Quellanzeige; der Modus pro Anzeige nutzt jeweils das Set der jeweiligen Quellanzeige.

Quellanzeigen mit Dynamic Creative verwenden ihre Creative-ID wieder und können synchronisiertes Engagement nicht erhalten. Das CLI zeigt dieselbe Warnung wie der Web-Duplicator.

Live-Läufe der Post-ID-Duplizierung streamen den Fortschritt pro Ad Set und pro Anzeige, inklusive Meta-Fehlermeldungen, und enden mit Duplicated X of Y.

Flags zum Durchsuchen

Diese Flags gibt es bei campaigns, adsets, adset und campaign:

FlagBeschreibung
--status <status>active (Standard) oder all
--inactiveKurzform für --status all (bei campaigns)
--search <text>Filtert nach Name (bei campaigns, adsets)

Targeting-Suche

Städte, Postleitzahlen und detailliertes Targeting nutzen Meta-Kennungen statt Namen. Suche über Ads Uploader, um Werte zu bekommen, die du direkt in eine Spec einfügen kannst:

ads targeting:search "Austin" --type city
ads targeting:search "90210" --type zip
ads targeting:search "advertising" --type detailed
FlagBeschreibung
--type <type>Pflicht. city liefert Werte für targeting.cities[].key; zip liefert Werte für targeting.zips[].key; detailed liefert Einträge für targeting.detailedTargetingGroups.
--account <id>Überschreibt das eingestellte Standard-Werbekonto
--limit <n>Liefert 1 bis 25 Treffer (Standard 8)
--jsonLiefert strukturierte Ergebnisse zum Einfügen

Ergebnisse für detailliertes Targeting enthalten id, name, type, einen Bereich für die Zielgruppengröße und den Kategoriepfad. Der type bezeichnet die Kategorie des detaillierten Targetings, zum Beispiel interests, behaviors, work_employers oder work_positions. Suche diese Kennungen immer; rate sie nie.

Detail-Flags

Diese Flags gibt es bei ad:

FlagBeschreibung
--expandedZeigt die vollständigen Werte für Headline, Primärtext und Beschreibung

Allgemeine Flags

FlagBeschreibung
--account <id>Überschreibt das Standard-Werbekonto für jeden Befehl
--jsonGibt rohes JSON aus (bei den meisten Befehlen verfügbar, gedacht für Skripte)

Umgebungsvariablen und Updates

VariableWas sie macht
ADS_API_TIMEOUT_MSTimeout für API-Anfragen in Millisekunden für jeden Befehl (Standard 60000)
ADS_API_URLDie Ads-Uploader-Adresse, mit der das CLI spricht. Für die normale Nutzung lässt du sie leer.

Das CLI prüft einmal am Tag auf eine neue Version und zeigt einen Hinweis, wenn es eine gibt. Aktualisiere mit npm update -g @adsuploader/cli.

Format der Spec-Datei

Die JSON-Spec-Datei steuert jeden Aspekt der Anzeigenerstellung. Gib eine Vorlagenquelle an (adPresetId oder copyFromAd) und dazu entweder uploadId oder erfasste mediaItems mit einem Facebook-mediaHash für jedes Bild und einer mediaId für jedes Video. Standard-, Karussell-, Flexible- und Platzierungsvideos brauchen außerdem thumbnailHash; Multi-Media-Videos nutzen ihre erfasste öffentliche Thumbnail-URL.

Bei Videos muss mediaItems[].mediaId die numerische Facebook-Video-ID sein: Nimm die videoId aus der Upload-Antwort, nicht deren interne id. videoId wird als Alias akzeptiert, und für linkedAssets[] gilt dieselbe Regel. Interne Upload-IDs werden beim Speichern nur aufgelöst, wenn sie zum angemeldeten Benutzer und zum ausgewählten Konto gehören. Ohne numerische ID oder Batch-Verknüpfung macht ein nicht aufgelöstes Video den Build unstartbar. Siehe das kanonische Beispiel für ein Platzierungsvideo.

Minimale Spec

{
  "adPresetId": "your_preset_id",
  "uploadId": "batch_abc123"
}

Vollständiges Beispiel

{
  "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"
  }
}

Vorlagenquelle

Du brauchst eines davon, damit das CLI weiß, welche Anzeigenkonfiguration als Basis dient.

FeldBeschreibung
adPresetIdEine gespeicherte API-Preset-ID. Legt Kampagne, Ad Set und Anzeigenkonfiguration fest.
copyFromAdEine Facebook-Anzeigen-ID, aus der Einstellungen kopiert werden.

Wenn du copyFromAd nutzt, gib den Upload-Batch an oder starte einen gespeicherten Web-Build, dessen erfasste Bilder einen mediaHash und dessen Videos eine mediaId haben. Optional kannst du Kampagne und Ad Set festlegen:

{
  "copyFromAd": "120233848667930472",
  "uploadId": "batch_abc123",
  "campaign": { "id": "120233848666410472" },
  "adSet": { "id": "120233848666620472" }
}

Die richtige Anzeigen-ID findest du, indem du dich durch dein Konto klickst: ads campaigns, dann ads campaign <id>, dann ads adset <id>, dann ads ad <id>.

Profiloptionen

Standardmäßig übernehmen neue Anzeigen die Facebook-Seite, das Instagram-Konto und das Threads-Profil aus der Vorlagenanzeige oder dem Preset. Das ist dieselbe Profile-Options-Steuerung, die du in der Web-App im Defaults-Bereich findest. Überschreibe jedes davon mit einem profile-Block (oder mit den Flags --page / --instagram / --use-page-identity / --threads, die Vorrang vor der Spec-Datei haben):

{
  "copyFromAd": "120233848667930472",
  "uploadId": "batch_abc123",
  "profile": {
    "pageId": "123456789012345",
    "instagramId": "17841400000000000",
    "threadsId": "987654321098765"
  }
}

Führe ads pages aus, um die nutzbaren Seiten-IDs samt verknüpftem Instagram-Konto jeder Seite aufzulisten.

Überschreibst du nur die Seite, nutzt Ads Uploader automatisch deren verknüpftes Instagram-Konto. Ist kein Instagram-Konto verknüpft, wird die Facebook-Seite als Instagram-Identität verwendet. Threads wird trotzdem zurückgesetzt, weil es zur alten Seite gehören kann; setze es bei Bedarf ausdrücklich.

Für eine ausdrückliche Wahl der Seite als Absender nutzt du --use-page-identity oder setzt "useFacebookPage": true innerhalb von profile. Kombiniere das nicht mit --instagram oder instagramId. Du kannst auch nur das Instagram- oder Threads-Profil ändern, ohne die Seite anzufassen, indem du nur diese Felder setzt.

Bei Launches mit mehreren Kampagnen weist du Identitäten unabhängig mit profile.campaigns zu. Verknüpfe jede Überschreibung mit der passenden Kampagnen-id (empfohlen) oder mit einem eindeutigen Kampagnennamen:

{
  "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 funktioniert nur, wenn campaign.mode "duplicate" oder "split" ist und campaign.campaigns mindestens zwei Einträge hat. Jeder Schlüssel muss zu einer dieser Kampagnen passen; nicht passende oder mehrdeutige Schlüssel werden vor dem Launch abgelehnt.

Kampagnenstruktur

Standardmäßig landen Anzeigen in der Kampagne der Vorlagenanzeige. Mit campaign.name erstellst du eine neue Kampagne.

Für Modi mit mehreren Kampagnen nutzt du campaign.mode mit einem campaigns-Array:

{
  "campaign": {
    "mode": "duplicate",
    "campaigns": [
      { "name": "Campaign A" },
      { "name": "Campaign B" }
    ]
  }
}
ModusVerhalten
"single"Standard. Eine Kampagne.
"duplicate"Alle Medien werden in jede Kampagne dupliziert.
"split"Die Medien werden gleichmäßig auf die Kampagnen verteilt.

Ad-Set-Modi

Standardmäßig landen Anzeigen im bestehenden Ad Set der Vorlagenanzeige. Mit den folgenden Modi steuerst du, wie Anzeigen auf Ad Sets verteilt werden.

Neues Ad Set erstellen:

{ "adSet": { "name": "My Ad Set" } }

Bestehendes Ad Set per ID nutzen:

{ "adSet": { "id": "120233848666620472" } }

Ein Ad Set pro hochgeladener Datei:

{ "adSet": { "mode": "perUpload" } }

Automatisch in Ad Sets fester Größe gruppieren:

{ "adSet": { "mode": "autoGroup", "adsPerAdSet": 5 } }

Eigene Gruppen mit voller Kontrolle darüber, welche Dateien wohin gehen:

{
  "adSet": {
    "groups": [
      { "name": "Images - April 10", "media": ["hero.jpg", "banner.jpg"] },
      { "name": "Videos - April 10", "media": ["promo.mp4"] }
    ]
  }
}

Namensmuster für Ad Sets in Modi mit mehreren Ad Sets:

{ "adSet": { "mode": "perUpload", "namePattern": "Ad Set {index:01}" } }

Varianten-Gruppierung fasst Anzeigen nach Variantenkennung im selben Ad Set zusammen:

{ "adSet": { "mode": "autoGroup", "groupVariations": true, "variationIdentifier": "-" } }

Budget und Gebotssteuerung überschreiben

Überschreibe das Tagesbudget und/oder den Gebotsbetrag bei neuen Ad Sets. Die Werte sind in den Währungseinheiten deines Kontos (z. B. 50 für 50 $ oder 50 Euro).

dailyBudget und bidAmount nutzen die Währungseinheiten des Kontos. minimumRoas ist ein Verhältnis, 1.5 bedeutet also ein ROAS-Ziel von 1,5x.

  • ABO-Kampagnen (das Budget liegt beim Ad Set): Kombiniere dailyBudget mit bidAmount für Gebots- bzw. Kostenobergrenzen-Strategien oder mit minimumRoas für LOWEST_COST_WITH_MIN_ROAS.
  • CBO-Kampagnen (das Budget liegt bei der Kampagne): Setze kein dailyBudget am Ad Set. Setze campaign.dailyBudget oder campaign.lifetimeBudget (schließen sich gegenseitig aus), um das Budget der Quellkampagne zu überschreiben, oder lass beide weg, um es zu übernehmen. Mindest- und Höchstausgaben pro Ad Set können ganze Beträge oder 5-100 % des Kampagnenbudgets in 5-%-Schritten sein; prozentuale Limits funktionieren auch mit einer bestehenden CBO-Kampagne. Setze bidAmount oder minimumRoas am Ad Set, wenn dessen Quellstrategie diese Steuerung nutzt.

bidAmount und minimumRoas schließen sich gegenseitig aus, weil sie zu unterschiedlichen Gebotsstrategien gehören.

{ "adSet": { "dailyBudget": 50 } }
{ "adSet": { "bidAmount": 5 } }
{ "adSet": { "minimumRoas": 1.5 } }
{ "adSet": { "dailyBudget": 50, "bidAmount": 5 } }

Für CBO-Ausgabenlimits in einer Spec setzt du diese Felder auf adSet:

FeldWas es festlegt
minSpendMindestausgaben des Ad Sets in ganzen Währungseinheiten. 0 entfernt das vom Quell-Ad-Set kopierte Limit.
maxSpendHöchstausgaben des Ad Sets in ganzen Währungseinheiten. 0 entfernt das vom Quell-Ad-Set kopierte Limit.
minSpendPercentageMindestausgaben des Ad Sets als Prozentsatz des Kampagnenbudgets (5 bis 100, in 5er-Schritten)
maxSpendPercentageHöchstausgaben des Ad Sets als Prozentsatz des Kampagnenbudgets (5 bis 100, in 5er-Schritten)
{
  "campaign": { "dailyBudget": 200 },
  "adSet": { "minSpend": 20, "maxSpendPercentage": 50 }
}

Auch als CLI-Flags verfügbar: --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 und --adset-max-spend-pct 80.

Ad-Set-Targeting

Targeting gilt für neue Ad Sets. Lass den targeting-Block auf oberster Ebene weg, um die Zielgruppe des Quell-Ad-Sets unverändert zu übernehmen. Jeder Modus kann adSet.targetingPerAdSet nutzen, verknüpft wie texts.perAdset über den finalen Ad-Set-Namen, die Ad-Set-ID oder einen kollisionssicheren campaign::key. Der Custom-Modus unterstützt zusätzlich adSet.groups[].targeting. Die Reihenfolge ist targetingPerAdSet, dann groups[].targeting, dann der Standard des Builds, dann die Quellzielgruppe. Targeting pro Ad Set gibt es nur in der Spec, weil CLI-Flags kein bestimmtes geplantes Ad Set ansprechen können.

Bei mehreren Kampagnen wird die Kopie eines Ad Sets in jeder Kampagne separat ausgerichtet; nutze "Campaign name::Ad set name" als Schlüssel für eine bestimmte Kopie.

{
  "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"] }
    }
  }
}

Im Custom-Modus bleibt groups[].targeting gültig und hält die Überschreibung direkt neben ihrer Mediengruppe:

{
  "adSet": {
    "mode": "custom",
    "groups": [{
      "name": "Canada Women",
      "media": ["canada.jpg"],
      "targeting": { "countries": ["CA"], "genders": "women" }
    }]
  }
}

Targeting-Regeln:

  • Alter und Geschlecht musst du aktiv einschalten. Setze ageSelected: true oder genderSelected: true, sonst werden die Werte für Alter oder Geschlecht ignoriert.
  • Detailliertes Targeting ersetzt, es wird nicht zusammengeführt. detailedTargetingGroups wird zur kompletten detaillierten Zielgruppe, alles, was du weglässt, fällt also weg.
  • Der Stadtradius bleibt zwischen 10 und 50 Meilen bzw. 17 und 80 Kilometern. Ein Wert außerhalb dieses Bereichs wird auf die nächste Grenze gesetzt, und ein fehlender Radius nutzt das Minimum.

Mit ads targeting:search findest du den key einer Stadt (Typ city), den key einer Postleitzahl wie US:90210 (Typ zip) und id, name und type jeder detaillierten Auswahl (Typ detailed). Lass Länder, Städte und Postleitzahlen weg, um die Standorte der Quelle zu übernehmen. Länder, Städte und Postleitzahlen werden als Alternativen kombiniert: Fügst du Austin oder eine Postleitzahl zu countries: ["US"] hinzu, erreichst du trotzdem die ganzen USA. Lass die Länder weg, um nur die Stadt oder Postleitzahl anzusprechen. Postleitzahlen haben keinen Radius.

Textkonfiguration

Gemeinsamer Text verwendet denselben Text für alle Anzeigen:

{
  "texts": {
    "common": {
      "headlines": ["Headline 1", "Headline 2"],
      "bodies": ["Primary text"],
      "descriptions": ["Description"]
    },
    "strategy": "flexible"
  }
}

Text pro Anzeige lässt dich für jede Datei eigenen Text festlegen:

{
  "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"]
      }
    }
  }
}

Die Schlüssel pro Anzeige sind Dateinamen (keine vollständigen Pfade). Jeder Eintrag unterstützt: headlines, bodies, descriptions, cta, link, displayUrl, urlTags. Felder, die du nicht angibst, werden aus der Vorlagenanzeige übernommen.

Text pro Ad Set wendet einen Textblock auf jede Anzeige in einem Ziel-Ad-Set an. Nutze einen einfachen Ad-Set-Namen bzw. eine ID, wenn sie eindeutig ist, oder einen campaign::key-Eintrag, wenn derselbe Ad-Set-Name in mehr als einer Kampagne vorkommt:

{
  "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
      }
    }
  }
}

Jeder Schlüssel in texts.perAdset muss zu einem geplanten Ad Set passen. Nicht passende Schlüssel werden abgelehnt, statt auf den gemeinsamen Text zurückzufallen.

Text-Presets laden eine gespeicherte Textkonfiguration:

{ "textPresetId": "preset_id_here" }

Du kannst textPresetId nicht mit texts kombinieren.

KI-Offenlegung

Lege selbst offen, dass das Creative einer Anzeige mit KI erstellt oder wesentlich bearbeitet wurde (Metas Selbstauskunft für KI-Inhalte). Das ist standardmäßig aus und wird nie automatisch für dich eingeschaltet.

{ "aiDisclosure": true }

Das Feld aiDisclosure auf oberster Ebene (oder das Flag --ai-disclosure) gilt für jede Anzeige im Launch. Du kannst aiDisclosure auch in einem Eintrag von texts.perAd oder texts.perAdset auf true oder false setzen; dieser Wert pro Eintrag gewinnt immer, auch ein ausdrückliches false.

Strategie-Optionen steuern, wie mehrere Textvarianten behandelt werden:

  • "flexible" (Standard) lässt Meta über deine Textvarianten hinweg optimieren. Mehrere Headlines und Texte werden zu Optionen, die Facebook kombiniert.
  • "separate" erstellt eine eigene Anzeige für jede Textkombination.

Ein CTA auf oberster Ebene gilt für alle Anzeigen. CTAs pro Anzeige in texts.perAd und pro Ad Set in texts.perAdset überschreiben ihn.

{
  "cta": {
    "type": "SHOP_NOW",
    "link": "https://example.com",
    "displayUrl": "example.com"
  },
  "urlTags": "utm_source=facebook&utm_medium=paid"
}

Standard-CTA-Typen: LEARN_MORE, SHOP_NOW, SIGN_UP, SUBSCRIBE, GET_OFFER, GET_QUOTE, CONTACT_US, GET_IN_TOUCH, BOOK_TRAVEL (angezeigt als Book Now), ORDER_NOW, BUY_NOW, APPLY_NOW, DOWNLOAD, SEE_DETAILS, WATCH_MORE, LISTEN_NOW, PLAY_GAME, DONATE_NOW, OPEN_LINK

Nutze den Meta-Wert (etwa SHOP_NOW), nicht die Beschriftung des Buttons.

Zielabhängige CTAs werden aus der Vorlagenanzeige übernommen und sollten nicht manuell gesetzt werden. Setzt du sie beim falschen Kampagnentyp, gibt es einen Fehler der Facebook API.

CTAErforderliches Kampagnenziel
MESSAGE_PAGEZiel Messenger
WHATSAPP_MESSAGEZiel WhatsApp
INSTAGRAM_MESSAGEZiel Instagram-DM
CALL_NOWAnruf-Kampagne

URL-Split-Test (Split Destination)

Gib 2 bis 5 Ziel-URLs unter texts.urlVariants an, und jedes erzeugte Ad Set wird einmal pro URL dupliziert, damit Meta jede Kombination aus Anzeige und Landingpage unabhängig optimiert.

{
  "texts": {
    "common": { "headlines": ["Hero"], "bodies": ["Copy"] },
    "urlVariants": [
      { "link": "https://example.com/homepage", "label": "homepage" },
      { "link": "https://example.com/quiz", "label": "quiz-v2" }
    ]
  }
}
  • label ist optional. Fehlt es, wird der letzte Slug des URL-Pfads verwendet (/quiz-v2 wird zu quiz-v2), bei Root-URLs ersatzweise der Hostname.
  • Im Modus mit einem Ad Set wird das Label jeder Variante zum vollständigen Ad-Set-Namen.
  • In den Modi perUpload und autoGroup bekommt der Name jedes duplizierten Ad Sets -{label} angehängt (zum Beispiel Ad Set 01-quiz-v2), oder das Label ersetzt ein {destination}-Token, wenn du eines einfügst.
  • Das Token {date} in einem Label wird zum heutigen Datum (zum Beispiel wird launch-{date} zu launch-2026-04-27).
  • Jede Ziel-URL muss eindeutig sein. Identische URLs (oder Varianten derselben URL mit Schrägstrich am Ende bzw. anderer Groß- und Kleinschreibung) werden zu einem Eintrag zusammengefasst. Achte also darauf, mindestens 2 unterschiedliche Ziele zu haben.
  • Dein Ad-Set-Budget wird mit der Anzahl der Varianten multipliziert, da jedes Duplikat ein eigenes Ad Set ist.
  • Nicht kompatibel mit Quellanzeigen mit Sonderzielen (Lead-Formular, Messenger, WhatsApp, Instagram-DM, Anruf). Das CLI lehnt diese Kombination mit einer klaren Fehlermeldung ab, weil diese Formate kein cta.link verwenden.
  • Überschreibungen von link pro Anzeige in texts.perAd verlieren gegen die Varianten-URL, wenn beides gesetzt ist.

Creative Enhancements

Steuere die Advantage+ Creative Enhancements:

{ "creativeEnhancements": "none" }
WertWirkung
weggelassenÜbernimmt die Enhancements der Vorlagenanzeige oder des Presets
"metaDefaults"Veraltet. Setzt keine Features, also wird jedes Feature als aus gesendet.
"all"Alle Features an
"none"Alle Features aus
["feature1", "feature2"]Nur die aufgelisteten Features an, der Rest aus
{ "feature1": true, "feature2": false }Jedes aufgelistete Feature ausdrücklich an- oder ausschalten

Verfügbare Features: 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

Der Schlüssel show_destination_blurbs wird als Show spotlights angezeigt, und pac_relaxation als Flex media.

Wenn du Features einzeln auswählst, liste nur solche auf, die zum Medientyp passen. Video-Features (video_auto_crop, video_filtering) gelten nur für Videoanzeigen. Karussell-Features (carousel_to_video, carousel_dynamic_description, multi_share_end_card, multi_share_optimized) gelten nur für Karussellanzeigen.

product_tags gilt für Bild- und Videoanzeigen und funktioniert nur beim Klonen. Es lässt sich nur aktivieren, wenn die Quellanzeige einen verknüpften Katalog und ausdrücklich positionierte Produkt-Tags hat; alle Tags der Quelle und ihre Positionen bleiben erhalten. "all" schließt es nur bei einer geeigneten Quelle ein und erfindet nie ein Produkt-Tag.

Karussellanzeigen

Fasse hochgeladene Dateien zu Karussellanzeigen zusammen, mit Text pro Karte und optionalem Gesamttext für das Karussell. cardTexts steuert die einzelnen Karten. Der Gesamttext des Karussells kann direkt am Karussell-Objekt stehen oder in texts.perAd über den name des Karussells gesetzt werden; direkt am Objekt gesetzte Felder gewinnen, wenn beides vorhanden ist.

{
  "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" }
      ]
    }
  ]
}

Alternative Form für den Gesamttext:

{
  "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"]
    }
  ]
}

Karten müssen auf Dateinamen aus dem Upload-Batch oder auf erfasste Medien eines Saved Builds verweisen. Jedes Karussell braucht 2 bis 10 Karten. Dateien, die ein Karussell belegt, werden aus der Liste der Standardanzeigen entfernt.

Flexible Ads

Fasse mehrere Assets zu einer einzigen Flexible Ad zusammen, bei der Meta pro Platzierung das beste Asset auswählt:

{
  "flexible": [
    {
      "name": "Multi-Asset Ad",
      "assets": ["hero.jpg", "promo.mp4", "banner.jpg"]
    }
  ]
}

Jede Flexible-Gruppe braucht 2 bis 10 Assets. Dateien, die eine Flexible-Gruppe belegt, werden aus der Liste der Standardanzeigen entfernt.

Multi-Media-Anzeigen

Fasse 2-10 hochgeladene Bilder oder Videos zu einer Multi-Media-Anzeige von Meta zusammen:

{
  "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"
        }
      ]
    }
  ]
}

Assets müssen auf Dateinamen aus dem Upload-Batch oder auf erfasste Medien eines Saved Builds verweisen. assetTexts ist optional und wird über den Index assets zugeordnet; jedes Feld ist eine einzelne Überschreibung für dieses Asset, und leere Felder fallen auf den Haupttext und die URLs der Anzeige zurück. Das primär angezeigte Asset nutzt Haupttext und URL der Anzeige, und eine Textüberschreibung für das primäre Asset wird zur ersten Haupttext-Option. Videos brauchen eine erfasste, zwischengespeicherte öffentliche Thumbnail-URL. Dateien, die eine Multi-Media-Gruppe belegt, werden aus der Liste der Standardanzeigen entfernt.

Anzeigenbenennung

Lege fest, wie deine Anzeigen benannt werden:

{ "adNamePattern": "{filename} - {date}" }
PlatzhalterWas er einfügt
{filename}Ursprünglicher Dateiname ohne Endung
{index}Positionsnummer (1, 2, 3...)
{index:01}Position mit führenden Nullen. Die Zahl legt Start und Auffüllung fest: {index:01} ergibt 01, 02, 03; {index:50} ergibt 50, 51, 52.
{variation}Variantenkennung, wenn die Varianten-Gruppierung aktiv ist
{campaign}Kampagnenname
{date}Aktuelles Datum (YYYY-MM-DD)
{date:short}Kurzes Datum (MMDD)
{timestamp}Unix-Zeitstempel in Millisekunden

Transformationen umschließen einen Wert. Ein leerer Wert steht für den Dateinamen:

TransformationWas sie macht
{split:_:2}Teilt den Dateinamen am Trennzeichen (hier _) und fügt den 2. Teil ein
{clean:}Entfernt ein Seitenverhältnis-Suffix am Ende, etwa _9x16 oder -1x1
{uppercase:}, {lowercase:}, {titlecase:}Ändern die Groß- und Kleinschreibung

Transformationen lassen sich verschachteln, zum Beispiel {titlecase:{split:_:2}}. Ein Muster darf bis zu 200 Zeichen lang sein. Mehr Beispiele findest du unter Anzeigenbenennung.

Optionen

{
  "options": {
    "status": "PAUSED",
    "pauseAt": "adSet",
    "schedule": {
      "startTime": "2026-04-01T09:00:00",
      "endTime": "2026-04-30T23:59:59"
    }
  }
}
FeldWerteBeschreibung
status"PAUSED", "ACTIVE"Status der Anzeige beim Launch (Standard: ACTIVE)
pauseAt"ad", "adSet", "campaign"Auf welcher Ebene pausiert wird (Standard: ad)
schedule.startTimeISO-8601-StringGeplante Startzeit (nutzt die Zeitzone des Werbekontos)
schedule.endTimeISO-8601-StringGeplante Endzeit (optional)

Wenn die Anzeigen in ein bestehendes Ad Set gehen, funktioniert options.schedule nur bei Kampagnen für Verkäufe und App-Promotion, weil Meta Zeitpläne pro Anzeige nur für diese Ziele unterstützt. Bei anderen Zielen erstellst du ein neues Ad Set oder entfernst options.schedule.

Spec-Limits

LimitMaximum
Headlines, Primärtexte oder Beschreibungen in einer Anzeige (flexibler Text oder ein Eintrag pro Anzeige)je 5
Textvarianten mit der Strategie "separate"50
Einträge in texts.perAd oder texts.perAdset200
Eigene Ad-Set-Gruppen (adSet.groups)50
Medien in einer eigenen Gruppe100
Karussell-, Flexible- oder Multi-Media-Gruppen (je Typ)50
Karten oder Assets in einer Karussell-, Flexible- oder Multi-Media-Gruppe2 bis 10
Länge von adNamePattern200 Zeichen

Upload und Varianten-Erkennung

Variantengruppen werden, genau wie in der Web-App, automatisch anhand von Dateinamenskonventionen erkannt. Alle Details zu den Namenskonventionen findest du unter Seitenverhältnis-Varianten.

Seitenverhältnis-Suffixe: hero_1x1.jpg + hero_4x5.jpg + hero_9x16.jpg + hero_16x9.jpg + hero_1.91x1.jpg werden zu einer Variantenanzeige gruppiert. Bis zu 5 Seitenverhältnisse pro Gruppe.

Position des Tokens: Das Seitenverhältnis-Token kann am Ende (hero_4x5.jpg), in der Mitte (hero_4x5_v2.jpg) oder am Anfang (4x5_hero.jpg) stehen.

Alte Wort-Suffixe: hero.jpg + hero_vertical.jpg + hero_horizontal.jpg funktionieren weiterhin und werden 9x16 und 16x9 zugeordnet.

Das Standard-Trennzeichen ist _. Du kannst es unter Account > Defaults > Placements > Filename Separator ändern (oder mehrere zulassen).

Gängige Muster

Hochladen und mit einem Preset erstellen

ads upload ./creatives/hero.jpg ./creatives/banner.jpg
ads create:preview spec.json
ads create spec.json

Dabei enthält spec.json:

{ "adPresetId": "PRESET_ID", "uploadId": "BATCH_ID" }

Einstellungen aus einer bestehenden Anzeige kopieren

Durchsuche dein Konto, um die Anzeige zu finden:

ads campaigns
ads campaign 120233848666410472
ads adset 120233848666620472
ads ad 120233848667930472

Erstelle dann eine Spec, die darauf verweist:

{
  "copyFromAd": "120233848667930472",
  "uploadId": "BATCH_ID"
}

Die Quellanzeige muss Inline-Creative-Einstellungen haben. Wurde sie aus einem bestehenden Seitenbeitrag erstellt, lehnt das CLI sie ab, bevor eine Create-Anfrage gesendet wird.

Ein API-Preset aus einer bestehenden Anzeige speichern

ads presets:save --from-ad 120233848667930472 --name "Spring Purchase Template"
ads create --preset PRESET_ID --upload BATCH_ID

Damit wird dieselbe API-Preset-Struktur gespeichert, die auch die Web-App nutzt. Die Quellanzeige muss Inline-Creative-Einstellungen haben; Anzeigen auf Basis eines Seitenbeitrags können nicht als API-Presets gespeichert werden.

Text pro Anzeige mit eigenem Text pro Datei

{
  "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"
      }
    }
  }
}

Automatisch in mehrere Ad Sets gruppieren

{
  "adPresetId": "PRESET_ID",
  "uploadId": "BATCH_ID",
  "adSet": { "mode": "autoGroup", "adsPerAdSet": 3 }
}

Wichtige Hinweise

  1. Immer zuerst die Vorschau. create:preview findet Konfigurationsfehler, bevor Facebook überhaupt angefasst wird.
  2. Anzeigen sind standardmäßig aktiv. Nutze --status PAUSED oder "status": "PAUSED" in der Spec, um sie pausiert zu erstellen.
  3. uploadId kommt aus der Upload-Ausgabe. Es ist die Batch-ID, die ads upload zurückgibt.
  4. Uploads sind an ein Werbekonto gebunden. Dateien werden direkt in die Facebook-Medienbibliothek des ausgewählten Kontos hochgeladen. Die Batch-ID funktioniert nur mit demselben Konto.
  5. copyFromAd braucht auflösbare Medien. Gib uploadId an oder starte einen gespeicherten Build, dessen erfasste Bilder einen mediaHash und dessen Videos eine mediaId haben. Optional steuerst du mit campaign.id und adSet.id, wo die Anzeigen landen.
  6. Die Textschlüssel pro Anzeige sind Dateinamen. Nutze "hero.jpg", nicht "/path/to/hero.jpg".
  7. textPresetId und texts schließen sich gegenseitig aus. Nutze das eine oder das andere, nicht beides.
  8. Zielabhängige CTAs werden aus der Vorlage übernommen. Setze MESSAGE_PAGE, WHATSAPP_MESSAGE usw. nicht manuell.

Partnership Ads mit deinen eigenen Medien

CLI und MCP können Partnership Ads mit hochgeladenen Medien auf Facebook und Instagram starten. Nutze deine normale Spec für Bild-/Videomedien, Karussell, Flexible, Multi Media oder Platzierungsvarianten und füge profile.partnership.enabled: true hinzu. Hochgeladene Medien werden ganz normal mit einer Second Identity zusammengesetzt. Lass uploaderMode weg oder setze es auf false; true wählt importierte Beiträge und kann nicht mit Uploads genutzt werden.

Wähle deine First Identity mit profile.pageId und profile.instagramId. Der gemeinsame Partner ist die 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" }
}

Für unterschiedliche Partner pro Anzeige fügst du diesen texts-Block zur selben Spec hinzu. Die zweite Zeile nutzt ausdrücklich No Partner:

{
  "texts": {
    "mode": "perAd",
    "perAd": {
      "one.jpg": { "sponsorPageId": "555", "sponsorInstagramId": "666" },
      "two.jpg": { "sponsorPageId": null, "sponsorInstagramId": null }
    }
  }
}

Für Ad-Set-Bereiche nutzt du texts.mode: "perAdset" und texts.perAdset, verknüpft über den finalen Ad-Set-Namen bzw. die ID oder campaign::key. Bei Launches mit mehreren Kampagnen nutzt du profile.campaigns[<id or unambiguous name>] für Sponsor-Überschreibungen pro Kampagne. Die Reihenfolge ist gemeinsamer Partner, dann Kampagne, dann die aktive Zeile. Weggelassene Sponsor-Felder werden jeweils unabhängig übernommen; setze beide IDs ausdrücklich auf null für No Partner. Wechselst du nur die Partner-Seite, wird eine übernommene Instagram-ID bei hochgeladenen Medien nicht gelöscht; setze diese ID ausdrücklich, wenn du das Paar änderst. Die First-Identity-Felder einer Zeile (pageId, instagramId, threadsId) bleiben unabhängig.

Für eine Second Identity nur auf Instagram setzt du sponsorPageId: null, sponsorInstagramId auf die freigegebene Konto-ID und sponsorPageUseInstagramAccount: true. Eine Facebook-Seite als Partner wird bei hochgeladenen Medien ebenfalls unterstützt. Die Einschränkung für Facebook-Beitragsimporte gilt nicht für hochgeladene Medien.

displayMode gilt für den ganzen Launch: both (Standard), first oder dynamic. Jeder wirksame Partner muss sich von der First Identity unterscheiden und freigegebenen Zugriff auf Partnership-Werbung haben. Eine ausstehende oder fehlende Freigabe wird mit Nennung der Identität abgelehnt. Jede Zeile braucht einen vollständigen übernommenen oder ausdrücklichen Partner oder eine ausdrückliche No-Partner-Überschreibung. Partnerships ohne jeden Sponsor zu aktivieren, wird abgelehnt. Die Freigabe wird bei Vorschau und Erstellung erneut geprüft; ein gespeicherter Build speichert keine Berechtigungen.

ads create:preview und ads_preview zeigen für jede Anzeige den wirksamen Partner, die Freigabe und den Header-Modus, gruppiert nach Ad Set. Das Admins vorbehaltene ads create:test oder ads_create mit options.testMode: true validiert geeignete Aufrufe bei Meta, ohne Anzeigen zu erstellen, und meldet die Anzahl bestandener, fehlgeschlagener und nicht geprüfter Aufrufe. Vollständige, im Web gespeicherte Partnership-Builds mit hochgeladenen Medien lassen sich über CLI und MCP starten; über diese Tools bearbeitete Builds stellen im Web-Uploader Partnership Ads, Identitäten, Partner pro Zeile und Header-Modus wieder her.

Spec für Partnerships mit bestehenden Instagram-Beiträgen

CLI-JSON-Specs und die MCP-Tools ads_preview / ads_create akzeptieren Instagram-Beiträge mit mediaItems[].kind: "partnershipPost". Die Quellanzeige oder das Preset liefert die Einstellungen; der importierte Beitrag liefert seine feste Creator-Identität und seine organische Bildunterschrift. Wähle den gemeinsamen Sponsor in profile.partnership oder setze Sponsor und optionale Textüberschreibungen in texts.perAdset oder texts.perAd. Headline, CTA, Website-URL und Testimonial dürfen leer sein. Ein nicht leerer CTA braucht eine Website-URL. Facebook-Beitragsimporte werden nicht unterstützt.

Die Vorschau prüft Inhalte und Berechtigungen über Lese- und reine Validierungsaufrufe bei Meta, ohne Anzeigen zu erstellen oder Codes zu speichern. Ihre codefreie resolvedSpec kann gespeichert werden, aber die Codes musst du bei der Erstellung erneut angeben. Bei der Erstellung wird die Berechtigung noch einmal geprüft.

Nutze mediaItems[].kind: "partnershipPost" mit platform: "instagram". Wähle genau eine Fundstelle: sourceInstagramMediaId, import.postUrl oder import.instagramShortcode. Ein passender import.adCode kann eine Fundstelle begleiten oder allein verwendet werden. Die Quellanzeige oder das Preset liefert Einstellungen, nicht den Beitrag. Optionale creator.pageId und creator.instagramId bestätigen den aufgelösten Creator.

{
  "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" }
}

Für einen Import nur per Code nutzt du diesen vollständigen Request-Body mit deinen IDs und einem Code, den ein Secret-Producer im Arbeitsspeicher einsetzt. Speichere den echten Code nicht in einer Datei:

{
  "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" }
}

Nutze 1 bis 250 Beiträge pro Anfrage, jeden mit einem eindeutigen mediaName von höchstens 200 Zeichen. sponsorPageId muss für jede geplante Anzeige auf eine echte Facebook-Seite der Marke auflösen; sponsorInstagramId ist optional. Der Header-displayMode gilt für den ganzen Launch: both, first oder dynamic. Bei importierten Beiträgen bedeutet first einen Header nur mit dem Creator, im Uploader beschriftet als Partner identity only in the header, nicht einen Header nur mit der Marke.

Sponsoren pro Kampagne nutzen profile.campaigns, verknüpft über Kampagnen-ID oder einen eindeutigen Kampagnennamen, mit sponsorPageId und optional sponsorInstagramId. Die Reihenfolge ist gemeinsamer Sponsor, dann Kampagne, dann die aktive Überschreibung pro Ad Set oder pro Anzeige. Gemeinsame Sponsor-Felder gehören in profile.partnership, nie in texts.common; ein adCode gehört in den import der Zeile oder in einen aktiven Block pro Anzeige bzw. pro Ad Set. Die Werte pageId / instagramId des Creators sind Bestätigungen, keine Möglichkeit, den Autor des Beitrags zu ändern.

multiAdvertiserAds ist standardmäßig true; setze es ausdrücklich auf false, um dich abzumelden. CTA-Werte müssen Meta-Enums wie SHOP_NOW oder LEARN_MORE sein, keine Beschriftungen wie Shop Now, und ein nicht leerer CTA braucht ein Ziel mit http:// oder https://. Die organische Bildunterschrift lässt sich nicht bearbeiten. Textblöcke für importierte Beiträge unterstützen eine Headline, CTA, Link, URL-Tags, Testimonial, KI-Offenlegung und die Multi-Advertiser-Wahl. Jede Überschreibungs-Map pro Anzeige bzw. pro Ad Set unterstützt höchstens 200 Einträge.

Bei importierten Beiträgen lehnen CLI und MCP Folgendes ab: Facebook-Beitragsimporte, Batches, die importierte Beiträge und hochgeladene Medien mischen, Karussell-, Flexible- und Multi-Media-Strukturen, die Gruppierung nach Platzierungsvarianten und Threads-Identitäten. Hochgeladene Medien unterstützen die normalen Creative-Formate und Partner pro Zeile. Neue Facebook-Beitragsimporte werden derzeit auch im Web-Uploader nicht unterstützt. Einen Browser für freigegebene Beiträge gibt es im Uploader nicht; importiere eine autorisierte Instagram-URL, Post-ID oder einen Code.

Bei texts.mode: "perAd" verknüpfst du texts.perAd über mediaName. Bei texts.mode: "perAdset" verknüpfst du texts.perAdset über den finalen Ad-Set-Namen bzw. die ID oder campaign::key. Gemeinsamer Text nutzt texts.common. adSet.groups[].media enthält diese Mediennamen; verwende eine Medienzeile in mehreren Gruppen wieder, statt dieselbe Quelle zweimal zu importieren.

Nutze ads create:preview /dev/stdin --account act_123 für die Vorschau und dann ads create /dev/stdin --account act_123 --status PAUSED zum Erstellen. Übergib sensible Codes nur über stdin, nie als Argumente, in Query-Strings oder in einer auf der Festplatte gespeicherten Datei. Gib die Codes bei der Erstellung erneut an; gespeicherte Builds und die Vorschau-Ausgabe lassen sie weg. Nutze --account oder setze vorher ads account act_123, auch wenn das JSON eine accountId enthält.

Admins können ads create:test /dev/stdin --account act_123 --status PAUSED ausführen. Das erstellt keine Meta-Anzeigen und meldet metaValidation-Aufrufe als bestanden, fehlgeschlagen oder nicht geprüft. Eine Ablehnung durch Meta beendet mit Exit-Code 1. Aufrufe, die simulierte IDs brauchen, werden nicht geprüft; eine bestandene Validierung garantiert weder Auslieferung noch Darstellung. Test Mode kann verschlüsselte Autorisierungscodes und Launch-Datensätze speichern.