API-Referenz
Meta-Copilot
Der Stand des Meta-Copiloten auf dem Werbekonto des Unternehmens, seine Meldungen (verlorene Reaktionen, Ablehnungen, Ausgabensprünge) und der Notstopp. Das Mandat lässt sich nur in der App einstellen.
Endpunkte
-
GET
/meta-copilotStand des Copiloten abrufen -
PATCH
/meta-copilot/mandateMandat des Copiloten aktualisieren -
GET
/meta-copilot/alertsMeldungen des Copiloten abrufen -
POST
/meta-copilot/stopNotstopp ausführen -
GET
/meta-copilot/opportunitiesChancen des Copiloten abrufen -
POST
/meta-copilot/opportunities/{opportunity}/acceptEine Chance vom Copiloten umsetzen lassen -
POST
/meta-copilot/opportunities/{opportunity}/dismissEine Chance ablehnen -
GET
/meta-copilot/approvalsVorschläge des Copiloten abrufen -
POST
/meta-copilot/approvals/{approval}/approveEinen Vorschlag genehmigen -
POST
/meta-copilot/approvals/{approval}/rejectEinen Vorschlag ablehnen -
GET
/meta-copilot/timelineDie Zeitleiste abrufen -
GET
/meta-copilot/digestsWochenberichte abrufen -
GET
/meta-copilot/briefingsMorgenbriefings abrufen -
GET
/meta-copilot/revenueDie Umsatzbrücke abrufen -
GET
/meta-copilot/statsDie Kampagnenzahlen abrufen -
GET
/meta-copilot/crewDas Team des Co-Piloten abrufen -
GET
/meta-copilot/valueAbrufen, was der Co-Pilot gebracht hat -
GET
/meta-copilot/milestonesMeilensteine abrufen -
GET
/meta-copilot/benchmarkDu im Vergleich zu ähnlichen Unternehmen -
GET
/meta-copilot/seasonalityDen Saisonkalender abrufen -
POST
/meta-copilot/tips/{tip}/respondAuf den Tipp von heute antworten -
GET
/meta-copilot/competitorsVerfolgte Wettbewerber abrufen -
POST
/meta-copilot/competitorsEinem Wettbewerber folgen -
DELETE
/meta-copilot/competitors/{competitor}Einem Wettbewerber nicht mehr folgen -
POST
/meta-copilot/competitors/ads/{ad}/variantEine Variante auf eine Wettbewerberanzeige erstellen -
GET
/meta-copilot/ads/{ad}/previewVorschau einer Anzeige -
GET
/meta-copilot/imagesBilder der Bibliothek abrufen -
GET
/meta-copilot/starterStand einer neuen Kampagne abrufen -
PUT
/meta-copilot/starter/intakeAntworten auf die Startfragen speichern -
POST
/meta-copilot/starter/proposeEine neue Kampagne vorschlagen -
POST
/meta-copilot/imagesEin Bild hochladen -
DELETE
/meta-copilot/images/{image}Ein Bild löschen
Stand des Copiloten abrufen
/api/v1/meta-copilot
Der Modus (aus, Schatten, Copilot oder Autopilot), das Profil, das Ziel, das Monatsbudget und die Zähler offener Meldungen und wartender Vorschläge. 404, wenn das Unternehmen kein Meta-Werbekonto hat.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot",
"ad_account_id": "act_123456789",
"ad_account_name": "Veranda BV",
"currency": "EUR",
"mode": "shadow",
"profile": "standard",
"goal_metric": "cost_per_quote",
"goal_value": "45.00",
"monthly_budget": "1500.00",
"autonomous_classes": [],
"open_alerts": 1,
"pending_proposals": 0,
"enabled_at": null,
"tier": "autopilot",
"ad_budget_ceiling": "7500.00",
"on_expiry": "lapse",
"stopped_at": null,
"connection_active": true,
"running": {
"state": "running",
"since": null,
"kind": "operational"
}
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Mandat des Copiloten aktualisieren
/api/v1/meta-copilot/mandate
Setzt Profil, Ziel, Monatsbudget, Tagesbudget-Obergrenze, Ruhetage, die Grundlage für Kundendaten und ob ein unentschiedener Vorschlag nach der Frist trotzdem umgesetzt wird. Wird das Mandat WEITER (mehr autonome Klassen, höhere oder entfernte Tagesobergrenze, weniger Ruhetage, Kundendaten erlaubt, abgelaufene Vorschläge umsetzen), ist confirm_widening: true Pflicht; ohne diese Bestätigung folgt 422 validation_failed mit der Erklärung. Verkleinern braucht keine Bestätigung. Das Monatsbudget kann die Werbebudget-Obergrenze der Stufe (ad_budget_ceiling) nicht überschreiten. Jede Erweiterung erscheint als Meldung in der Zeitleiste.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
profile
erforderlich
|
string | Das Mandatsprofil: careful, standard oder broad. einer von: careful, standard, broad |
goal_metric
optional
|
string | Worauf der Copilot optimiert. kann leer sein (null) · einer von: cost_per_quote, cost_per_lead, cost_per_conversion, roas |
goal_value
optional
|
number | Der Zielwert als Text mit zwei Dezimalstellen. kann leer sein (null) · von 0 bis 1000000 |
monthly_budget
optional
|
number | Die monatliche Budgetvereinbarung. kann leer sein (null) · von 0 bis 10000000 |
max_daily_budget_euros
optional
|
number | Die Tagesbudget-Obergrenze pro Kampagne in Euro; leer = keine eigene Obergrenze. kann leer sein (null) · von 1 bis 1000000 |
quiet_days
optional
|
array | Die Ruhetage (monday … sunday): der Copilot ändert dann nichts selbst, alles geht zur Freigabe. |
crm_audience_allowed
optional
|
boolean | Ob gehashte E-Mail-Adressen und Telefonnummern von Kunden für Zielgruppen an Meta gehen dürfen. Weggelassen = die gespeicherte Wahl bleibt. |
on_expiry
optional
|
string | Was mit einem nicht rechtzeitig entschiedenen Vorschlag geschieht: lapse (verfällt, Standard) oder apply (wird nach der Frist trotzdem umgesetzt, innerhalb aller festen Grenzen). einer von: lapse, apply |
confirm_widening
optional
|
boolean | true, um eine Erweiterung des Mandats bewusst zu bestätigen. Pflicht, sobald die Eingabe das Mandat weiter macht als jetzt. |
notes
optional
|
string | Eine Notiz für den Copiloten in Alltagssprache, zum Beispiel "nie sonntags werben". kann leer sein (null) · höchstens 2000 Zeichen |
Beispielanfrage
curl -X PATCH "https://app.klantly.com/api/v1/meta-copilot/mandate" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profile": "standard",
"goal_metric": "cost_per_quote",
"goal_value": 45,
"monthly_budget": 1500,
"quiet_days": [
"sunday"
],
"on_expiry": "lapse"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('PATCH', 'meta-copilot/mandate', [
'json' => [
'profile' => 'standard',
'goal_metric' => 'cost_per_quote',
'goal_value' => 45,
'monthly_budget' => 1500,
'quiet_days' => [
0 => 'sunday',
],
'on_expiry' => 'lapse',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/mandate', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"profile": "standard",
"goal_metric": "cost_per_quote",
"goal_value": 45,
"monthly_budget": 1500,
"quiet_days": [
"sunday"
],
"on_expiry": "lapse"
}),
});
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://app.klantly.com/api/v1/meta-copilot/mandate",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
json={
"profile": "standard",
"goal_metric": "cost_per_quote",
"goal_value": 45,
"monthly_budget": 1500,
"quiet_days": [
"sunday"
],
"on_expiry": "lapse"
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot",
"ad_account_id": "act_123456789",
"ad_account_name": "Veranda BV",
"currency": "EUR",
"mode": "shadow",
"profile": "standard",
"goal_metric": "cost_per_quote",
"goal_value": "45.00",
"monthly_budget": "1500.00",
"autonomous_classes": [],
"open_alerts": 1,
"pending_proposals": 0,
"enabled_at": null,
"tier": "autopilot",
"ad_budget_ceiling": "7500.00",
"on_expiry": "lapse",
"stopped_at": null,
"connection_active": true,
"running": {
"state": "running",
"since": null,
"kind": "operational"
}
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden.
Meldungen des Copiloten abrufen
/api/v1/meta-copilot/alerts
Die Meldungen der Wächter und der Engagement-Überwachung, neueste zuerst. Filter nach Status oder Dringlichkeit. Titel und Erläuterung in der Sprache von Accept-Language.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
filter[status]
|
string | Nur Meldungen mit diesem Status: open oder resolved. einer von: open, resolved |
filter[severity]
|
string | Nur Meldungen mit dieser Dringlichkeit: info, warning oder critical. einer von: info, warning, critical |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/alerts?filter[status]=open" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/alerts', [
'query' => [
'filter[status]' => 'open',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/alerts?filter[status]=open', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/alerts",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "open"
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_alert",
"id": "4821",
"kind": "engagement_post_replaced",
"severity": "critical",
"status": "open",
"title": "Advertentie \"Veranda zomer\" hangt aan een andere post: reacties en likes lopen niet meer mee",
"detail": "De post waarop 143 reacties, 27 opmerkingen en 9 keer delen stonden, wordt niet meer geadverteerd.",
"cause": "external",
"target_id": "120210000000000001",
"occurrences": 1,
"first_seen_at": null,
"last_seen_at": null,
"resolved_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Notstopp ausführen
/api/v1/meta-copilot/stop
Schaltet den Copiloten aus: offene Vorschläge und offene Chancen werden zurückgezogen und bei Meta installierte Regeln deaktiviert. Die Kampagnen laufen weiter wie sie stehen. 409 conflict, wenn der Copilot bereits aus ist.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/stop" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/stop', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/stop', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/stop",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot",
"ad_account_id": "act_123456789",
"ad_account_name": "Veranda BV",
"currency": "EUR",
"mode": "shadow",
"profile": "standard",
"goal_metric": "cost_per_quote",
"goal_value": "45.00",
"monthly_budget": "1500.00",
"autonomous_classes": [],
"open_alerts": 1,
"pending_proposals": 0,
"enabled_at": null,
"tier": "autopilot",
"ad_budget_ceiling": "7500.00",
"on_expiry": "lapse",
"stopped_at": null,
"connection_active": true,
"running": {
"state": "running",
"since": null,
"kind": "operational"
}
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Chancen des Copiloten abrufen
/api/v1/meta-copilot/opportunities
Was die Chancen-Engine und der Copilot selbst gefunden haben: verschwendete Ausgaben, verschlissene Anzeigen, gesättigte Zielgruppen, Budgetkonzentration, Platzierungen ohne Ergebnis, Angebote, die nie gewonnen werden, ein einbrechender Funnel, ein CPL über dem Klantly-Median. Neueste zuerst; standardmäßig alle Status. Titel und Erläuterung in der Sprache von Accept-Language.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
filter[status]
|
string | Nur Chancen mit diesem Status: open, accepted, done, dismissed oder expired. einer von: open, accepted, done, dismissed, expired |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/opportunities?filter[status]=open" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/opportunities', [
'query' => [
'filter[status]' => 'open',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/opportunities?filter[status]=open', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/opportunities",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "open"
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_opportunity",
"id": "318",
"source": "signal",
"kind": "wasted_spend",
"status": "open",
"title": "\"Retargeting winter\" gaf € 184,20 uit zonder één conversie",
"body": "In de laatste 30 dagen is er € 184,20 besteed en zijn er 212 klikken geweest, maar geen enkele conversie.",
"impact_cents": 18420,
"confidence": "high",
"reversible": true,
"actionable": true,
"reuse_post": null,
"image_id": null,
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"dismissed_reason": null,
"action_id": null,
"variant": {
"reference_ad_id": "120210000000000009",
"headline": "Veranda op maat, binnen 4 weken geplaatst",
"primary_text": "Langer buiten zitten zonder gedoe? Onze aluminium veranda wordt op maat gemaakt en binnen vier weken geplaatst. Vraag vandaag een vrijblijvende offerte aan.",
"description": "Op maat gemaakt",
"cta_type": "GET_QUOTE"
},
"blueprint": {
"branch": "veranda",
"city": "Nijmegen",
"radius_km": 40,
"age_min": 30,
"age_max": 65,
"daily_budget_cents": 1500,
"has_pixel": true,
"landing_url": "https://configurator.klantly.com/offerte-aanvragen/01k7x?utm_source=facebook",
"image_id": "12",
"headline": "Veranda op maat van Veranda Boys",
"primary_text": "Langer buiten zitten, ook in het najaar? Veranda Boys maakt veranda's op maat. Vraag vrijblijvend een offerte aan.",
"description": "Vrijblijvende offerte",
"cta_type": "GET_QUOTE",
"peer_accounts": 7,
"peer_median_cpl": "31.20"
},
"decided_at": null,
"expires_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Eine Chance vom Copiloten umsetzen lassen
/api/v1/meta-copilot/opportunities/{opportunity}/accept
„Lass den Copiloten das machen.“ Trägt die Chance eine Aktion und steht der Copilot nicht im Schattenmodus, wird die Aktion sofort innerhalb des Mandats umgesetzt; sonst wird sie zum nächsten Schritt in der Strategie. 409 conflict, wenn die Chance nicht mehr offen ist.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
opportunity erforderlich |
string | Die Id der Chance. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/accept" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/accept', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/accept', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/accept",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_opportunity",
"id": "318",
"source": "signal",
"kind": "wasted_spend",
"status": "open",
"title": "\"Retargeting winter\" gaf € 184,20 uit zonder één conversie",
"body": "In de laatste 30 dagen is er € 184,20 besteed en zijn er 212 klikken geweest, maar geen enkele conversie.",
"impact_cents": 18420,
"confidence": "high",
"reversible": true,
"actionable": true,
"reuse_post": null,
"image_id": null,
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"dismissed_reason": null,
"action_id": null,
"variant": {
"reference_ad_id": "120210000000000009",
"headline": "Veranda op maat, binnen 4 weken geplaatst",
"primary_text": "Langer buiten zitten zonder gedoe? Onze aluminium veranda wordt op maat gemaakt en binnen vier weken geplaatst. Vraag vandaag een vrijblijvende offerte aan.",
"description": "Op maat gemaakt",
"cta_type": "GET_QUOTE"
},
"blueprint": {
"branch": "veranda",
"city": "Nijmegen",
"radius_km": 40,
"age_min": 30,
"age_max": 65,
"daily_budget_cents": 1500,
"has_pixel": true,
"landing_url": "https://configurator.klantly.com/offerte-aanvragen/01k7x?utm_source=facebook",
"image_id": "12",
"headline": "Veranda op maat van Veranda Boys",
"primary_text": "Langer buiten zitten, ook in het najaar? Veranda Boys maakt veranda's op maat. Vraag vrijblijvend een offerte aan.",
"description": "Vrijblijvende offerte",
"cta_type": "GET_QUOTE",
"peer_accounts": 7,
"peer_median_cpl": "31.20"
},
"decided_at": null,
"expires_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Eine Chance ablehnen
/api/v1/meta-copilot/opportunities/{opportunity}/dismiss
Mit self=true vermerkst du, dass du es selbst übernimmst; sonst gilt „nicht relevant“. Der Grund geht als Lernpunkt an den Copiloten, und dieselbe Chance bleibt dreißig Tage stumm. 409 conflict, wenn die Chance nicht mehr offen ist.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
opportunity erforderlich |
string | Die Id der Chance. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/dismiss" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"reason": "Deze campagne stopt eind van de maand toch.",
"self": false
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/dismiss', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'reason' => 'Deze campagne stopt eind van de maand toch.',
'self' => false,
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/dismiss', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"reason": "Deze campagne stopt eind van de maand toch.",
"self": false
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/opportunities/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/dismiss",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"reason": "Deze campagne stopt eind van de maand toch.",
"self": False
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_opportunity",
"id": "318",
"source": "signal",
"kind": "wasted_spend",
"status": "open",
"title": "\"Retargeting winter\" gaf € 184,20 uit zonder één conversie",
"body": "In de laatste 30 dagen is er € 184,20 besteed en zijn er 212 klikken geweest, maar geen enkele conversie.",
"impact_cents": 18420,
"confidence": "high",
"reversible": true,
"actionable": true,
"reuse_post": null,
"image_id": null,
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"dismissed_reason": null,
"action_id": null,
"variant": {
"reference_ad_id": "120210000000000009",
"headline": "Veranda op maat, binnen 4 weken geplaatst",
"primary_text": "Langer buiten zitten zonder gedoe? Onze aluminium veranda wordt op maat gemaakt en binnen vier weken geplaatst. Vraag vandaag een vrijblijvende offerte aan.",
"description": "Op maat gemaakt",
"cta_type": "GET_QUOTE"
},
"blueprint": {
"branch": "veranda",
"city": "Nijmegen",
"radius_km": 40,
"age_min": 30,
"age_max": 65,
"daily_budget_cents": 1500,
"has_pixel": true,
"landing_url": "https://configurator.klantly.com/offerte-aanvragen/01k7x?utm_source=facebook",
"image_id": "12",
"headline": "Veranda op maat van Veranda Boys",
"primary_text": "Langer buiten zitten, ook in het najaar? Veranda Boys maakt veranda's op maat. Vraag vrijblijvend een offerte aan.",
"description": "Vrijblijvende offerte",
"cta_type": "GET_QUOTE",
"peer_accounts": 7,
"peer_median_cpl": "31.20"
},
"decided_at": null,
"expires_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Vorschläge des Copiloten abrufen
/api/v1/meta-copilot/approvals
Die Vorschläge, die auf eine Entscheidung warten (Standard filter[status]=proposed), oder mit Filter die Absichten aus dem Schattenmodus sowie Umgesetztes, Abgelehntes, Abgelaufenes und Fehlgeschlagenes. Ohne Payload und ohne Mitarbeiternamen.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
filter[status]
|
string | Nur Vorschläge mit diesem Status: proposed, simulated, applied, dismissed, expired oder failed. Ohne Filter: proposed. einer von: proposed, simulated, applied, dismissed, expired, failed |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/approvals?filter[status]=proposed" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/approvals', [
'query' => [
'filter[status]' => 'proposed',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/approvals?filter[status]=proposed', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/approvals",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "proposed"
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_approval",
"id": "2077",
"status": "proposed",
"action_type": "adjust_budget",
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"title": "Budget van \"Retargeting winter\" verlagen van € 40 naar € 30 per dag",
"rationale": "De kosten per offerte liggen hier 60% boven het accountgemiddelde.",
"risk": "low",
"impact_estimate_cents": 30000,
"change": {
"kind": "budget",
"level": "adset",
"manual": false,
"from_cents": 4000,
"to_cents": 3000,
"placements": [
"audience_network"
],
"devices": [
"mobile"
],
"min": 30,
"max": 65,
"genders": [
"female"
],
"audience_name": null,
"headline": null,
"days": 14,
"template": null,
"purpose": null,
"percent": 1,
"country": "NL",
"strategy": "cost_cap",
"cap_cents": null,
"daily_budget_cents": null
},
"simulated": false,
"reuse_post": null,
"image_id": null,
"approval_deadline_at": null,
"applied_at": null,
"outcome": null,
"error": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Einen Vorschlag genehmigen
/api/v1/meta-copilot/approvals/{approval}/approve
Setzt den Vorschlag bei Meta um, innerhalb des Mandats des Kontos. Nur für einen Vorschlag mit Status proposed; sonst 409 conflict. Im Schattenmodus verweigert der Ausführer. Bei einer Anzeigenvariante mit demselben Text wie das Original wählt reuse_post, ob der bestehende Beitrag wiederverwendet wird (Standard true).
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
approval erforderlich |
string | Die Id des Vorschlags. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/approve" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/approve', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/approve', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/approve",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_approval",
"id": "2077",
"status": "proposed",
"action_type": "adjust_budget",
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"title": "Budget van \"Retargeting winter\" verlagen van € 40 naar € 30 per dag",
"rationale": "De kosten per offerte liggen hier 60% boven het accountgemiddelde.",
"risk": "low",
"impact_estimate_cents": 30000,
"change": {
"kind": "budget",
"level": "adset",
"manual": false,
"from_cents": 4000,
"to_cents": 3000,
"placements": [
"audience_network"
],
"devices": [
"mobile"
],
"min": 30,
"max": 65,
"genders": [
"female"
],
"audience_name": null,
"headline": null,
"days": 14,
"template": null,
"purpose": null,
"percent": 1,
"country": "NL",
"strategy": "cost_cap",
"cap_cents": null,
"daily_budget_cents": null
},
"simulated": false,
"reuse_post": null,
"image_id": null,
"approval_deadline_at": null,
"applied_at": null,
"outcome": null,
"error": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Einen Vorschlag ablehnen
/api/v1/meta-copilot/approvals/{approval}/reject
Setzt den Vorschlag (oder eine Absicht aus dem Schattenmodus) auf dismissed. Bei Meta ändert sich nichts.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
approval erforderlich |
string | Die Id des Vorschlags. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reject" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reject', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reject', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/approvals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reject",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_approval",
"id": "2077",
"status": "proposed",
"action_type": "adjust_budget",
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"title": "Budget van \"Retargeting winter\" verlagen van € 40 naar € 30 per dag",
"rationale": "De kosten per offerte liggen hier 60% boven het accountgemiddelde.",
"risk": "low",
"impact_estimate_cents": 30000,
"change": {
"kind": "budget",
"level": "adset",
"manual": false,
"from_cents": 4000,
"to_cents": 3000,
"placements": [
"audience_network"
],
"devices": [
"mobile"
],
"min": 30,
"max": 65,
"genders": [
"female"
],
"audience_name": null,
"headline": null,
"days": 14,
"template": null,
"purpose": null,
"percent": 1,
"country": "NL",
"strategy": "cost_cap",
"cap_cents": null,
"daily_budget_cents": null
},
"simulated": false,
"reuse_post": null,
"image_id": null,
"approval_deadline_at": null,
"applied_at": null,
"outcome": null,
"error": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Die Zeitleiste abrufen
/api/v1/meta-copilot/timeline
Runden, Änderungen und Absichten, Meldungen und Moduswechsel in einer Liste, neueste zuerst. Kein Cursor: höchstens 100 Zeilen.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl Zeilen, höchstens 100 (Standard 50). von 1 bis 100 · Standard: 50 |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/timeline" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/timeline');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/timeline', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/timeline",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_timeline_entry",
"id": "action-2077",
"type": "action",
"at": null,
"kind": "adjust_budget",
"status": "applied",
"title": "Budget van \"Retargeting winter\" verlaagd naar € 30 per dag",
"rationale": "De kosten per offerte liggen hier 60% boven het accountgemiddelde.",
"target_name": "Retargeting winter",
"actor": "copilot",
"cause": null,
"severity": null,
"simulated": false,
"action_id": "2077",
"alert_id": null
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Wochenberichte abrufen
/api/v1/meta-copilot/digests
Die Wochenübersichten, die der Copilot am Montag erstellt: Ausgaben, Ergebnisse, was er getan hat und was er vorschlägt. Als Daten, nicht als Text.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/digests" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/digests');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/digests', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/digests",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_digest",
"id": "56",
"period_start": "2026-10-12",
"period_end": "2026-10-18",
"language": "nl",
"spend": "412.80",
"previous_spend": "398.10",
"conversions": 9,
"cost_per_conversion": "45.87",
"copilot_runs": 7,
"copilot_applied": 2,
"copilot_intentions": 0,
"outcomes": {
"improved": 1,
"neutral": 1,
"worsened": 0
},
"waiting": {
"proposals": 1,
"alerts": 0,
"opportunities": 3
},
"next_steps": [
"Nieuwe variant naast \"Veranda zomer\" testen"
],
"sent_at": null,
"created_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Morgenbriefings abrufen
/api/v1/meta-copilot/briefings
Ein Briefing pro Tag über den Vortag: Ausgaben, Leads, Angebote und gewonnene Aufträge aus Klantly gegen den Tagesdurchschnitt der Vorwoche, mit der Art des Tages und den Meilensteinen des Morgens. Überschrift und Text folgen Accept-Language.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/briefings" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/briefings');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/briefings', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/briefings",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_briefing",
"id": "412",
"date": "2026-10-22",
"kind": "quotes",
"headline": "Twee offerteaanvragen uit Meta gisteren.",
"body": "Besteed € 38,20 (gemiddeld € 41,10 per dag), 3 leads (gemiddeld 2,4), 2 offertes, 0 gewonnen.",
"spend": "38.20",
"avg_spend": "41.10",
"leads": 3,
"avg_leads": 2.4,
"clicks": 61,
"quotes": 2,
"won": 0,
"won_value": "0.00",
"cost_per_lead": "12.73",
"mtd_spend": "812.40",
"milestone_ids": [
"18"
],
"tip": {
"key": "frequency_high",
"category": "audience",
"actor": "copilot",
"title": "Je doelgroep ziet elke advertentie 3,4 keer",
"body": "Boven de 3 vertoningen per persoon stijgen de kosten per lead.",
"action": "Laat de co-pilot dit oppakken"
},
"pushed_at": null,
"created_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Die Umsatzbrücke abrufen
/api/v1/meta-copilot/revenue
Werbekosten → Leads → Angebote → gewonnen → Umsatz über die letzten `days` Tage (Standard 30), pro Kampagne und pro Kalendermonat, auf echtem Klantly-Umsatz. Angebote zählen nur, wenn das Kampagnen-Makro sie einer Kampagne dieses Kontos zuordnet.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
days
|
integer | Wie viele Tage zurück, 7 bis 365 (Standard 30). Die Monatsreihe sind immer die letzten sechs Kalendermonate. von 7 bis 365 · Standard: 30 |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/revenue?days=30" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/revenue', [
'query' => [
'days' => '30',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/revenue?days=30', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/revenue",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"days": "30"
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_revenue",
"since": "2026-09-24",
"until": "2026-10-23",
"uses_quotes": true,
"spend": "1240.50",
"clicks": 1830,
"impressions": 92400,
"leads": 74,
"quotes": 31,
"quotes_value": "142300.00",
"won": 6,
"won_value": "27850.00",
"cost_per_lead": "16.76",
"cost_per_quote": "40.02",
"cost_per_won": "206.75",
"roas": 22.45,
"revenue_source": "quotes",
"purchases": 0,
"purchase_value": "0.00",
"cost_per_purchase": null,
"meta_roas": null,
"copilot_impact": "412.00",
"campaigns": [
{
"campaign_id": "120210000000001",
"name": "Veranda voorjaar",
"spend": "812.00",
"leads": 51,
"quotes": 22,
"quotes_value": "98400.00",
"won": 4,
"won_value": "19200.00",
"cost_per_lead": "15.92",
"roas": 23.65,
"purchases": 0,
"purchase_value": "0.00",
"meta_roas": null
}
],
"months": [
{
"month": "2026-10",
"spend": "1240.50",
"leads": 74,
"quotes": 31,
"quotes_value": "142300.00",
"won": 6,
"won_value": "27850.00",
"cost_per_lead": "16.76",
"roas": 22.45,
"purchases": 0,
"purchase_value": "0.00",
"meta_roas": null
}
]
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Die Kampagnenzahlen abrufen
/api/v1/meta-copilot/stats
Ausgaben, Impressionen, Klicks und Ergebnisse über die letzten `days` Tage (7, 14, 30 oder 90; Standard 30): Summen, derselbe Zeitraum davor, pro Tag und pro Kampagne. Geeignet für Diagramme. Der Co-Pilot aktualisiert die Zahlen jeden Morgen und Nachmittag.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
days
|
integer | Wie viele Tage zurück: 7, 14, 30 oder 90 (Standard 30). einer von: 7, 14, 30, 90 · Standard: 30 |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/stats?days=30" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/stats', [
'query' => [
'days' => '30',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/stats?days=30', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/stats",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"days": "30"
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_stats",
"since": "2026-09-26",
"until": "2026-10-25",
"days": 30,
"currency": "EUR",
"result_kind": "leads",
"latest_date": "2026-10-04",
"synced_at": null,
"totals": {
"spend": "412.30",
"impressions": 31840,
"clicks": 612,
"results": 23,
"leads": 23,
"purchases": 0,
"purchase_value": "0.00",
"ctr": 1.92,
"cpc": "0.67",
"cpm": "12.95",
"cost_per_result": "17.93",
"roas": null
},
"previous": {
"spend": "412.30",
"impressions": 31840,
"clicks": 612,
"results": 23,
"leads": 23,
"purchases": 0,
"purchase_value": "0.00",
"ctr": 1.92,
"cpc": "0.67",
"cpm": "12.95",
"cost_per_result": "17.93",
"roas": null
},
"daily": [
{
"date": "2026-10-25",
"spend": "14.20",
"impressions": 1080,
"clicks": 21,
"results": 1,
"leads": 1,
"purchases": 0,
"purchase_value": "0.00",
"ctr": 1.94,
"cpc": "0.68",
"cpm": "13.15",
"cost_per_result": "14.20"
}
],
"campaigns": [
{
"campaign_id": "120210000000001",
"name": "Veranda voorjaar",
"status": "ACTIVE",
"share": 64.2,
"daily_spend": [
"12.40",
"14.10"
],
"spend": "264.70",
"impressions": 20410,
"clicks": 402,
"results": 16,
"leads": 16,
"purchases": 0,
"purchase_value": "0.00",
"ctr": 1.97,
"cpc": "0.66",
"cpm": "12.97",
"cost_per_result": "16.54",
"roas": null
}
]
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Das Team des Co-Piloten abrufen
/api/v1/meta-copilot/crew
Was jeder Agent des Co-Piloten zuletzt getan hat, wann er laut Planung wieder loslegt, und die Zähler für heute und diese Woche. Alles aus echten Handlungen und der echten Planung.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/crew" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/crew');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/crew', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/crew",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_crew",
"state": "active",
"mode": "copilot",
"agents": [
{
"role": "optimizer",
"status": "ready",
"last_at": "2026-10-25T05:03:11Z",
"last_kind": "run_operational",
"last_facts": {
"status": "completed",
"tool_calls": 14,
"proposals": 2
},
"next_at": "2026-10-28T06:00:00Z",
"next_kind": "operational",
"count_7d": 3,
"week": [
0,
1,
0,
0,
1,
0,
1
]
}
],
"today": {
"checks": 14,
"campaigns": 4,
"opportunities": 1,
"proposals": 2
},
"week": {
"checks": 98,
"rounds": 3,
"proposals": 5,
"applied": 2
},
"next": {
"role": "guard",
"at": "2026-10-26T05:45:00Z"
},
"feed": [
{
"role": "analyst",
"kind": "stats_synced",
"at": "2026-10-25T04:45:12Z",
"facts": {
"campaigns": 4,
"days": 14,
"rows": 56
}
}
]
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Abrufen, was der Co-Pilot gebracht hat
/api/v1/meta-copilot/value
Was der Co-Pilot seit dem Einschalten getan hat und was es gebracht hat: umgesetzte Verbesserungen (selbst oder nach Zustimmung), die Messung eine Woche später (besser, gleich, schlechter, wird noch gemessen), der geschätzte Ertrag, was er überwacht hat, und Kosten pro Ergebnis in den Tagen vor und seit dem Einschalten. Die Schätzung ist die Erwartung bei jedem Vorschlag, keine Messung; der Vergleich erscheint erst ab sieben Tagen und fünf Ergebnissen auf beiden Seiten.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/value" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/value');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/value', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/value",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_value",
"since": "2026-10-02T08:14:00Z",
"days_on": 26,
"mode": "autopilot",
"currency": "EUR",
"actions": {
"applied": 9,
"by_itself": 7,
"approved": 2,
"rolled_back": 0
},
"outcomes": {
"improved": 5,
"neutral": 1,
"worsened": 1,
"measuring": 2
},
"estimated_value": "640.00",
"watch": {
"checks_30d": 412,
"alerts": 6,
"alerts_resolved": 5
},
"comparison": {
"available": true,
"days": 26,
"result_kind": "leads",
"before": {
"spend": "812.40",
"results": 31,
"cost_per_result": "26.21"
},
"after": {
"spend": "790.10",
"results": 42,
"cost_per_result": "18.81"
},
"change_pct": -28.2
},
"recent": [
{
"id": 4182,
"title": "Budget van Veranda voorjaar met 15% verhoogd",
"action_type": "update_campaign_budget",
"at": "2026-10-24T05:12:00Z",
"by_itself": true,
"outcome": "measuring",
"rollback": false,
"impact_estimate": "120.00"
}
],
"generated_at": "2026-10-28T09:30:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Meilensteine abrufen
/api/v1/meta-copilot/milestones
Gefeierte Meilensteine (die still erfasste Nullmessung eines bestehenden Kontos fehlt), neueste zuerst: Leads aus Meta, gewonnene Aufträge, die beste Woche und Wochen in Folge ohne Verschwendung. Titel und Text folgen Accept-Language.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/milestones" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/milestones');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/milestones', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/milestones",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_milestone",
"id": "18",
"kind": "leads",
"threshold": 100,
"period": "",
"value": "104.00",
"title": "De 100e lead uit Meta",
"detail": "Sinds het begin van de meting kwamen er 104 leads uit je Meta-advertenties.",
"reached_on": "2026-10-22",
"created_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Du im Vergleich zu ähnlichen Unternehmen
/api/v1/meta-copilot/benchmark
Kosten pro Lead, CTR, CPC und CPM dieses Kontos über 30 Tage gegen Median und bestes Viertel aller verfolgten Konten mit Volumen, anonym und erst ab fünf Konten. position = der Anteil der Konten, die schlechter abschneiden.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/benchmark" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/benchmark');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/benchmark', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/benchmark",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_benchmark",
"available": true,
"accounts": 12,
"min_accounts": 5,
"period_days": 30,
"metrics": [
{
"metric": "cost_per_lead",
"own": 14.2,
"median": 19.8,
"best_quartile": 11.5,
"position": 71,
"higher_is_better": false
}
]
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Den Saisonkalender abrufen
/api/v1/meta-copilot/seasonality
Wie viele Angebotsanfragen vergleichbare Klantly-Unternehmen pro Kalendermonat erhalten (die Branche des KI-Agenten, sonst die gesamte Plattform), als Faktor zum Zweijahresdurchschnitt. Anonym und nur oberhalb der Volumenschwelle; sonst available=false.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/seasonality" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/seasonality');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/seasonality', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/seasonality",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_seasonality",
"available": true,
"scope": "branch",
"label": "Veranda en overkappingen",
"companies": 23,
"quotes_per_month": 410,
"months": [
{
"month": 3,
"factor": 1.42
}
],
"current_month": 10,
"current_factor": 0.84,
"next_month": 11,
"next_factor": 0.61,
"peak_month": 3,
"low_month": 12
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Auf den Tipp von heute antworten
/api/v1/meta-copilot/tips/{tip}/respond
accept = der Copilot übernimmt (der Tipp wird eine Chance und ein nächster Schritt in seiner Strategie), self = du übernimmst selbst, dismiss = nicht relevant. Derselbe Tipp bleibt danach neunzig Tage aus. 404 bei unbekanntem Tipp-Schlüssel.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
tip erforderlich |
string | Der Schlüssel des Tipps, wie er im Briefing steht (zum Beispiel frequency_high). |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/tips/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/respond" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/tips/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/respond', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/tips/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/respond', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/tips/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/respond",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_tip_response",
"tip": "frequency_high",
"category": "audience",
"actor": "copilot",
"title": "Je doelgroep ziet elke advertentie 3,4 keer",
"vars": {
"spend": "€ 600.00"
},
"response": "accept",
"opportunity_id": "321",
"responded_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
validation_failed— Die Eingabe ist ungültig. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Verfolgte Wettbewerber abrufen
/api/v1/meta-copilot/competitors
Die Facebook-Seiten, denen das Unternehmen folgt (höchstens fünf), jede mit ihren Anzeigen aus der öffentlichen Ad Library von Meta (höchstens 25, laufende und neue zuerst): Überschrift, Text, Plattformen, Laufzeit und Reichweite in der EU. Der Copilot liest die Bibliothek wöchentlich; is_new bleibt vierzehn Tage stehen. Kein Cursor.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/competitors" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/competitors');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/competitors', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/competitors",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_competitor",
"id": "7",
"page_id": "115115300320906",
"page_name": "Veranda Boys",
"library_url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&view_all_page_id=115115300320906",
"ads_active": 6,
"ads_total": 14,
"last_scanned_at": null,
"ads": [],
"created_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Einem Wettbewerber folgen
/api/v1/meta-copilot/competitors
Über die numerische Facebook-Seiten-ID (in der Ad Library zu finden oder im Dashboard per Namenssuche). Die Nullmessung seiner Anzeigen erfolgt sofort; was dann schon läuft, zählt nicht als neu. 409 conflict bei einer schon verfolgten Seite, über dem Maximum von fünf oder ohne aktive Meta-Verbindung.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/competitors" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/competitors', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/competitors', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/competitors",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 201
{
"data": {
"object": "meta_copilot_competitor",
"id": "7",
"page_id": "115115300320906",
"page_name": "Veranda Boys",
"library_url": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&view_all_page_id=115115300320906",
"ads_active": 6,
"ads_total": 14,
"last_scanned_at": null,
"ads": [],
"created_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
validation_failed— Die Eingabe ist ungültig. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Einem Wettbewerber nicht mehr folgen
/api/v1/meta-copilot/competitors/{competitor}
Entfernt die Seite und ihre gespeicherten Anzeigen.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
competitor erforderlich |
string | Die ID des verfolgten Wettbewerbers. |
Beispielanfrage
curl -X DELETE "https://app.klantly.com/api/v1/meta-copilot/competitors/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('DELETE', 'meta-copilot/competitors/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/competitors/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.delete(
"https://app.klantly.com/api/v1/meta-copilot/competitors/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "note",
"id": "9d3f7b41-2d6f-4e8c-9b3a-4f5d6e7a8b92",
"deleted": true
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Eine Variante auf eine Wettbewerberanzeige erstellen
/api/v1/meta-copilot/competitors/ads/{ad}/variant
Der Copilot schreibt eine Variante auf die eigene beste Anzeige mit dem ANSATZ dieser Wettbewerberanzeige — nicht mit ihrem Text: kein Satz wird übernommen, das eigene Bild bleibt, und es kommt kein Versprechen hinzu, das das eigene Original nicht trägt. Das Ergebnis ist eine Chance der Art creative_advice mit der Variante zur Freigabe (Status 201). 409 conflict, wenn der Copilot aus ist, keine eigene aktive Anzeige mit Text vorhanden ist, dieselbe Quellanzeige in den letzten sechzig Tagen schon eine Variante bekam oder keine brauchbare Variante herauskam. Kostet einen Modellaufruf.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
ad erforderlich |
string | Die ID der Wettbewerberanzeige (aus der Liste der verfolgten Wettbewerber). |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/competitors/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/variant" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/competitors/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/variant', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/competitors/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/variant', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/competitors/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/variant",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 201
{
"data": {
"object": "meta_copilot_opportunity",
"id": "318",
"source": "signal",
"kind": "wasted_spend",
"status": "open",
"title": "\"Retargeting winter\" gaf € 184,20 uit zonder één conversie",
"body": "In de laatste 30 dagen is er € 184,20 besteed en zijn er 212 klikken geweest, maar geen enkele conversie.",
"impact_cents": 18420,
"confidence": "high",
"reversible": true,
"actionable": true,
"reuse_post": null,
"image_id": null,
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"dismissed_reason": null,
"action_id": null,
"variant": {
"reference_ad_id": "120210000000000009",
"headline": "Veranda op maat, binnen 4 weken geplaatst",
"primary_text": "Langer buiten zitten zonder gedoe? Onze aluminium veranda wordt op maat gemaakt en binnen vier weken geplaatst. Vraag vandaag een vrijblijvende offerte aan.",
"description": "Op maat gemaakt",
"cta_type": "GET_QUOTE"
},
"blueprint": {
"branch": "veranda",
"city": "Nijmegen",
"radius_km": 40,
"age_min": 30,
"age_max": 65,
"daily_budget_cents": 1500,
"has_pixel": true,
"landing_url": "https://configurator.klantly.com/offerte-aanvragen/01k7x?utm_source=facebook",
"image_id": "12",
"headline": "Veranda op maat van Veranda Boys",
"primary_text": "Langer buiten zitten, ook in het najaar? Veranda Boys maakt veranda's op maat. Vraag vrijblijvend een offerte aan.",
"description": "Vrijblijvende offerte",
"cta_type": "GET_QUOTE",
"peer_accounts": 7,
"peer_median_cpl": "31.20"
},
"decided_at": null,
"expires_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Vorschau einer Anzeige
/api/v1/meta-copilot/ads/{ad}/preview
Die Adresse der Vorschau, wie Meta die Anzeige zeigt (format: MOBILE_FEED_STANDARD, INSTAGRAM_STANDARD, INSTAGRAM_STORY oder DESKTOP_FEED_STANDARD; standardmäßig der Feed auf dem Handy). Die Adresse in ein iframe setzen. Nur für eine Anzeige des eigenen Werbekontos (sonst 404); kann Meta keine Vorschau erstellen, dann 409. Die Adresse gilt einige Stunden.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
ad erforderlich |
string | Die ID der Wettbewerberanzeige (aus der Liste der verfolgten Wettbewerber). |
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/preview" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/preview');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/preview', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/ads/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/preview",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_ad_preview",
"ad_id": "120211234567890",
"format": "MOBILE_FEED_STANDARD",
"url": "https://www.facebook.com/ads/api/preview_iframe.php?d=AQ...&t=AQ..."
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
validation_failed— Die Eingabe ist ungültig.
Bilder der Bibliothek abrufen
/api/v1/meta-copilot/images
Die Bilder und Videos, die das Unternehmen für Anzeigenvarianten hochgeladen hat, neueste zuerst, je mit signiertem Download-Link. Der Stand eines Videos, das Meta noch verarbeitet, wird beim Abrufen aktualisiert. Kein Cursor.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/images" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/images');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/images', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/images",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "meta_copilot_image",
"id": "12",
"kind": "image",
"video_status": null,
"name": "Veranda antraciet avond",
"width": 1200,
"height": 1200,
"size": 348211,
"usable": true,
"download_url": "https://app.klantly.com/api/files/quote-attachment/9d3f9e56-af10-4123-b345-e6f7a8b9c0d5?expires=1789000000&signature=8f1c…",
"created_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Stand einer neuen Kampagne abrufen
/api/v1/meta-copilot/starter
Die erkannte Branche (aus dem KI-Agenten, den Angeboten und dem Firmenprofil), die Startfragen mit der Antwort des Unternehmens und dem Vorschlag des Copiloten je Frage (was verkaufen Sie, in welchem Gebiet, wo landet ein Kunde, wie viel pro Tag, welches Bild, welche Seite), ob alles vollständig ist und was sonst noch fehlt (blocked: no_image, no_page oder no_landing). Funktioniert auch auf einem Konto ohne Kampagnen.
- Scope
-
meta_copilot.read— Stand und Meldungen des Meta-Copiloten lesen - Erforderliche Funktion
meta_copilot
Beispielanfrage
curl "https://app.klantly.com/api/v1/meta-copilot/starter" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'meta-copilot/starter');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/starter', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/meta-copilot/starter",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_starter",
"branch": "veranda",
"branch_label": "veranda's en overkappingen",
"branch_confidence": "high",
"complete": false,
"blocked": "no_image",
"has_active_campaign": false,
"questions": []
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Antworten auf die Startfragen speichern
/api/v1/meta-copilot/starter/intake
Jedes Feld kann einzeln gesendet werden; null entfernt eine Antwort, sodass wieder der Vorschlag des Copiloten gilt. product ist eine Branche aus der Liste; landing ein Schlüssel aus den Optionen (form:<id> oder website) oder url:https://…; daily_budget_cents zwischen 500 und 20000 und nie über der Tagesobergrenze des Mandats (sonst 422); image_id ein Bild aus der Bibliothek. Gibt den aktualisierten Stand zurück.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
product
optional
|
string | Die Branche: veranda, dakkapel, aanbouw, kozijnen, zonwering, vloeren, badkamer, keuken oder generic. kann leer sein (null) · einer von: veranda, dakkapel, aanbouw, kozijnen, zonwering, vloeren, badkamer, keuken, generic |
area_city
optional
|
string | Der Ort, um den das Einsatzgebiet liegt. kann leer sein (null) · höchstens 120 Zeichen |
area_radius_km
optional
|
integer | Der Radius in Kilometern (5–80). kann leer sein (null) · von 5 bis 80 |
landing
optional
|
string | Wo ein Kunde landet: ein Schlüssel aus den Optionen (form:<id> oder website) oder url:https://… für eine eigene Adresse. kann leer sein (null) · höchstens 600 Zeichen |
daily_budget_cents
optional
|
integer | Das Tagesbudget in Cent (500–20000), nie über der Tagesobergrenze des Mandats. kann leer sein (null) · von 500 bis 20000 |
image_id
optional
|
integer | Ein Bild oder Video aus der Bibliothek. kann leer sein (null) |
page_id
optional
|
string | Die Facebook-Seite, die als Absender dient. kann leer sein (null) · höchstens 40 Zeichen |
Beispielanfrage
curl -X PUT "https://app.klantly.com/api/v1/meta-copilot/starter/intake" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product": "veranda",
"area_city": "Nijmegen",
"area_radius_km": 40,
"daily_budget_cents": 1500
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('PUT', 'meta-copilot/starter/intake', [
'json' => [
'product' => 'veranda',
'area_city' => 'Nijmegen',
'area_radius_km' => 40,
'daily_budget_cents' => 1500,
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/starter/intake', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"product": "veranda",
"area_city": "Nijmegen",
"area_radius_km": 40,
"daily_budget_cents": 1500
}),
});
const { data } = await response.json();import os
import requests
response = requests.put(
"https://app.klantly.com/api/v1/meta-copilot/starter/intake",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
json={
"product": "veranda",
"area_city": "Nijmegen",
"area_radius_km": 40,
"daily_budget_cents": 1500
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "meta_copilot_starter",
"branch": "veranda",
"branch_label": "veranda's en overkappingen",
"branch_confidence": "high",
"complete": false,
"blocked": "no_image",
"has_active_campaign": false,
"questions": []
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand.
Eine neue Kampagne vorschlagen
/api/v1/meta-copilot/starter/propose
Der Copilot erstellt den Plan für eine vollständige Kampagne (Kampagne, Anzeigengruppe und Anzeige) aus den Antworten, dem Aufbau, der vergleichbaren Unternehmen derselben Branche die günstigsten Anfragen brachte (sonst das Playbook der Branche), und einem Anzeigentext des Modells und legt ihn als Chance der Art campaign_blueprint an (Status 201, mit blueprint). Diese Chance anzunehmen ist die Freigabe: alles wird pausiert erstellt und erst danach live gesetzt. Nie autonom. 409, wenn die Fragen unvollständig sind, kein Bild oder keine Seite vorhanden ist oder der Copilot aus ist. Kostet einen Modellaufruf.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/starter/propose" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/starter/propose', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/starter/propose', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/starter/propose",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 201
{
"data": {
"object": "meta_copilot_opportunity",
"id": "318",
"source": "signal",
"kind": "wasted_spend",
"status": "open",
"title": "\"Retargeting winter\" gaf € 184,20 uit zonder één conversie",
"body": "In de laatste 30 dagen is er € 184,20 besteed en zijn er 212 klikken geweest, maar geen enkele conversie.",
"impact_cents": 18420,
"confidence": "high",
"reversible": true,
"actionable": true,
"reuse_post": null,
"image_id": null,
"target_level": "adset",
"target_id": "120210000000000001",
"target_name": "Retargeting winter",
"dismissed_reason": null,
"action_id": null,
"variant": {
"reference_ad_id": "120210000000000009",
"headline": "Veranda op maat, binnen 4 weken geplaatst",
"primary_text": "Langer buiten zitten zonder gedoe? Onze aluminium veranda wordt op maat gemaakt en binnen vier weken geplaatst. Vraag vandaag een vrijblijvende offerte aan.",
"description": "Op maat gemaakt",
"cta_type": "GET_QUOTE"
},
"blueprint": {
"branch": "veranda",
"city": "Nijmegen",
"radius_km": 40,
"age_min": 30,
"age_max": 65,
"daily_budget_cents": 1500,
"has_pixel": true,
"landing_url": "https://configurator.klantly.com/offerte-aanvragen/01k7x?utm_source=facebook",
"image_id": "12",
"headline": "Veranda op maat van Veranda Boys",
"primary_text": "Langer buiten zitten, ook in het najaar? Veranda Boys maakt veranda's op maat. Vraag vrijblijvend een offerte aan.",
"description": "Vrijblijvende offerte",
"cta_type": "GET_QUOTE",
"peer_accounts": 7,
"peer_median_cpl": "31.20"
},
"decided_at": null,
"expires_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Ein Bild hochladen
/api/v1/meta-copilot/images
Fügt der Bibliothek des Copiloten ein Bild oder Video hinzu und registriert es im selben Aufruf bei Meta (adimages oder advideos). Als multipart/form-data mit dem Feld file senden: ein Bild (jpg, png oder webp, mindestens 600 × 600 Pixel, bis 10 MB) oder ein Video (mp4 oder mov, bis 30 MB); höchstens 30 pro Konto. Eine Variante (Vorschlag oder Chance mit create_ad_variant) kann es danach über image_id bei approve oder accept tragen; ein Video erst, sobald Meta es verarbeitet hat (video_status ready). 409 conflict, wenn das Bild zu klein oder das Video zu groß ist, das Maximum erreicht ist, Meta es ablehnt oder keine aktive Meta-Verbindung besteht.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
file
erforderlich
|
string (binary) | Das Bild oder Video selbst, als multipart/form-data. Bild: jpg, png oder webp, mindestens 600 × 600 Pixel, höchstens 10 MB. Video: mp4 oder mov, höchstens 30 MB; Meta verarbeitet es noch kurz nach (video_status). |
name
optional
|
string | Der Name (Dateiname ohne Erweiterung oder der mitgegebene name). kann leer sein (null) · höchstens 255 Zeichen |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/meta-copilot/images" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'meta-copilot/images');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/images', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/meta-copilot/images",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 201
{
"data": {
"object": "meta_copilot_image",
"id": "12",
"kind": "image",
"video_status": null,
"name": "Veranda antraciet avond",
"width": 1200,
"height": 1200,
"size": 348211,
"usable": true,
"download_url": "https://app.klantly.com/api/files/quote-attachment/9d3f9e56-af10-4123-b345-e6f7a8b9c0d5?expires=1789000000&signature=8f1c…",
"created_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt.
Ein Bild löschen
/api/v1/meta-copilot/images/{image}
Entfernt das Bild aus der Bibliothek; eine bereits erstellte Anzeige behält ihr Bild bei Meta.
- Scope
-
meta_copilot.write— Den Meta-Copiloten per Notstopp anhalten, Chancen umsetzen lassen oder ablehnen und Vorschläge genehmigen oder ablehnen (das Mandat lässt sich nur in der App einstellen) - Erforderliche Funktion
meta_copilot
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
image erforderlich |
string | Die ID des Bildes in der Bibliothek. |
Beispielanfrage
curl -X DELETE "https://app.klantly.com/api/v1/meta-copilot/images/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('DELETE', 'meta-copilot/images/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/meta-copilot/images/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.delete(
"https://app.klantly.com/api/v1/meta-copilot/images/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "note",
"id": "9d3f7b41-2d6f-4e8c-9b3a-4f5d6e7a8b92",
"deleted": true
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Das Objekt
Alle Felder sind immer vorhanden; ein Feld ohne Wert ist null.
| Feld | Typ | Beschreibung |
|---|---|---|
object |
string | Immer "meta_copilot". |
ad_account_id |
string | Das Meta-Werbekonto in der act_-Form. |
ad_account_name |
string | Der Name des Werbekontos bei Meta. kann leer sein (null) |
currency |
string | Die Währung des Kontos. |
mode |
string | Der Modus: off, shadow (mitschauen, nichts ändern), copilot (alles zur Freigabe) oder autopilot (setzt innerhalb des Mandats um). einer von: off, shadow, copilot, autopilot |
profile |
string | Das Mandatsprofil: careful, standard oder broad. kann leer sein (null) · einer von: careful, standard, broad |
goal_metric |
string | Worauf der Copilot optimiert. kann leer sein (null) · einer von: cost_per_quote, cost_per_lead, cost_per_conversion, roas |
goal_value |
string | Der Zielwert als Text mit zwei Dezimalstellen. kann leer sein (null) |
monthly_budget |
string | Die monatliche Budgetvereinbarung. kann leer sein (null) |
autonomous_classes |
array<string> | Die Aktionsklassen, die der Copilot selbst umsetzen darf; leer im Schattenmodus. |
open_alerts |
integer | Anzahl offener Meldungen. |
pending_proposals |
integer | Anzahl Vorschläge, die auf eine Entscheidung warten. |
enabled_at |
string (date-time) | Wann der Copilot eingeschaltet wurde. kann leer sein (null) |
tier |
string | Die Stufe des Abonnements: copilot (Schatten und Copilot, Werbebudget bis 2.500 € pro Monat), autopilot (auch Autopilot, bis 7.500 €) oder plus (unbegrenzt, tägliche operative Runde); null ohne Copilot. kann leer sein (null) · einer von: copilot, autopilot, plus |
ad_budget_ceiling |
string | Das monatliche Werbebudget, bis zu dem der Copilot auf dieser Stufe Budget verschiebt, als Text mit zwei Dezimalen; null = unbegrenzt. kann leer sein (null) |
on_expiry |
string | Was mit einem nicht rechtzeitig entschiedenen Vorschlag geschieht: lapse (verfällt, Standard) oder apply (wird nach der Frist trotzdem umgesetzt, innerhalb aller festen Grenzen). einer von: lapse, apply |
stopped_at |
string (date-time) | Wann der Copilot zuletzt gestoppt wurde. kann leer sein (null) |
connection_active |
boolean | Ob die Meta-Verbindung funktioniert. |
running |
object | Ob der Co-Pilot gerade arbeitet: null, wenn nichts läuft. kann leer sein (null) |
running.state |
string | queued (die Runde wurde angefordert und wartet) oder running (die Runde läuft). einer von: queued, running |
running.since |
string (date-time) | Seit wann. kann leer sein (null) |
running.kind |
string | Art der Runde: operational oder strategy; null, solange sie noch wartet. kann leer sein (null) · einer von: operational, strategy |