Skript 3 · nur lesend
Findet kaputte Ziel-URLs , bevor der Klick sie findet.
Ruft die Ziel-URLs aktiver Anzeigen und Keywords ab und meldet Fehlercodes — und auf Wunsch Weiterleitungen auf die Startseite. Dieses Skript verändert nichts in deinem Konto: Es liest, es protokolliert, es schreibt nicht.
Der Defekt dahinter
Warum das im Konto nicht auffällt
Eine 404 kostet dich den Klick zweimal: Du bezahlst ihn, und der Interessent geht sofort wieder. Google lehnt die Anzeige dabei nicht ab — die Prüfung läuft unregelmäßig, und eine Seite, die auf die Startseite weiterleitet, antwortet ordnungsgemäß mit 200. Im Konto sieht beides aus wie eine ganz normale, funktionierende Anzeige.
Was das Skript findet
- Fehlercodes
- Alles ab Status 400: 404 (Seite weg), 410 (dauerhaft entfernt), 5xx (Serverfehler). Jeder Fund nennt den Code, die Weiterleitungskette davor und die Stellen im Konto, an denen die Adresse hängt.
- Weiterleitung auf die Startseite
- Die klassische Spur eines ausgebauten Produkts: Die Unterseite ist weg, das Content-System schickt alles auf die Startseite, der Status ist 200 und der Interessent sucht wieder von vorn. Abschaltbar, weil manche Seiten das absichtlich so machen.
- Gar nicht erreichbar
- Zeitüberschreitung, kaputtes Zertifikat, falscher Hostname. Wird getrennt gemeldet, weil das kein Inhalts-, sondern ein Infrastrukturproblem ist.
Der komplette Code
Alles, was du einfügst — nichts dahinter
360 Zeilen, eine Datei, keine Abhängigkeiten. Die Einstellungen stehen im CONFIG-Block ganz oben; der E-Mail-Versand ist ab Werk aus. Getestet gegen Google Ads Scripts, Stand 08/2026.
ziel-url-pruefung.js
Version 1.0.0 · Stand 2026-08-30 · 360 Zeilen
/**
* KAPUTTE-ZIEL-URL-PRUEFUNG — Google Ads Script
* Version 1.0.0 · Stand 2026-08-30
* https://visnakovs.de/google-ads-scripts/ziel-url-pruefung/
*
* Ruft die Ziel-URLs aller aktiven Anzeigen und Keywords ab und meldet, welche
* mit einem Fehlercode antworten. Zusaetzlich - abschaltbar - welche auf die
* Startseite weiterleiten: technisch eine 200, fuer den Klickenden eine
* Sackgasse, und in Google Ads eine ganz normale, teure Anzeige.
*
* ⛔ GARANTIE — Dieses Skript verändert nichts in deinem Konto: Es liest, es
* protokolliert, es schreibt nicht. Es pausiert nichts, es beschriftet nichts,
* es korrigiert keine URL. Die Abrufe gehen an deine eigene Website, nicht an
* Google Ads.
*
* Getestet gegen Google Ads Scripts, Stand 08/2026.
*
* Umlaute stehen in diesem Code bewusst als ae/oe/ue: der Script-Editor zeigt
* kopierte Dateien je nach Browser in wechselnder Kodierung an, und ein
* kaputtes Sonderzeichen im Protokoll oder in einer Bedingung faellt still aus.
*/
// ---------------------------------------------------------------------------
// CONFIG
// ---------------------------------------------------------------------------
var CONFIG = {
// E-Mail-Zusammenfassung. Bewusst AUS - erst lesen, dann einschalten.
EMAIL_SENDEN: false,
EMPFAENGER: 'dein.name@beispiel.de',
BETREFF: 'Google Ads: kaputte Ziel-URLs',
EMAIL_AB_FUNDEN: 1,
// Obergrenze der geprueften Adressen pro Lauf. Ein Skript hat 30 Minuten,
// und jeder Abruf kostet Zeit; die Tageskontingente fuer UrlFetchApp kommen
// ausserdem aus Apps Script. 400 ist konservativ und laeuft in jedem Konto
// durch. Wird die Grenze erreicht, sagt das Protokoll es - der Rest faellt
// nicht still weg.
MAX_URLS: 400,
// Abbruch, wenn weniger Sekunden Laufzeit uebrig sind. Ein abgewuergter
// Lauf hinterlaesst ein Protokoll, das nach "nichts gefunden" aussieht.
MIN_RESTZEIT_SEKUNDEN: 120,
// Weiterleitungen werden von Hand verfolgt, damit das Ziel sichtbar ist.
MAX_WEITERLEITUNGEN: 5,
// Weiterleitung auf die Startseite melden, wenn die Ausgangsadresse einen
// Pfad hatte. Klassiker nach dem Ausbau eines Produkts.
PRUEFE_STARTSEITEN_WEITERLEITUNG: true,
// Pause zwischen zwei Abrufen in Millisekunden. 0 = keine Pause. Hoeher
// setzen, wenn die eigene Firewall bei schnellen Serien blockt.
PAUSE_MS: 0,
// Wie viele Funde maximal ins Protokoll geschrieben werden. Google kuerzt
// das Protokoll bei 100 KB - danach faellt der Rest ohne Hinweis weg.
MAX_PROTOKOLL_ZEILEN: 200
};
var MELDEN_AB_STATUS = 400;
// ---------------------------------------------------------------------------
function main() {
Logger.log('Ziel-URL-Pruefung 1.0.0 — Konto ' + AdsApp.currentAccount().getCustomerId());
if (istVorschau()) Logger.log('Vorschau-Lauf. Das Skript schreibt ohnehin nichts.');
Logger.log('Dieses Skript liest nur. Es schreibt nichts ins Konto.');
Logger.log('');
var gesammelt = sammleUrls();
var adressen = schluessel(gesammelt);
Logger.log('Gefunden: ' + adressen.length + ' verschiedene Ziel-URLs aus aktiven Anzeigen und Keywords.');
var zuPruefen = adressen.slice(0, CONFIG.MAX_URLS);
if (adressen.length > zuPruefen.length) {
Logger.log('Geprueft werden davon ' + zuPruefen.length + ' (MAX_URLS). ' +
(adressen.length - zuPruefen.length) + ' Adressen bleiben in diesem Lauf ungeprueft.');
}
Logger.log('');
var funde = [];
var geprueft = 0;
var abgebrochen = false;
for (var i = 0; i < zuPruefen.length; i++) {
if (restzeitSekunden() < CONFIG.MIN_RESTZEIT_SEKUNDEN) { abgebrochen = true; break; }
var adresse = zuPruefen[i];
var ergebnis = pruefeAdresse(adresse);
geprueft++;
if (ergebnis.problem) {
funde.push({
url: adresse,
problem: ergebnis.problem,
detail: ergebnis.detail,
orte: gesammelt[adresse]
});
}
if (CONFIG.PAUSE_MS > 0) Utilities.sleep(CONFIG.PAUSE_MS);
}
berichte(funde, geprueft, adressen.length, abgebrochen);
}
// --- Konto lesen -----------------------------------------------------------
/**
* Ziel-URLs aller aktiven Anzeigen und Keywords, mit den Orten, an denen sie
* haengen. Mehrere Anzeigen teilen sich oft eine Adresse - geprueft wird sie
* einmal, gemeldet werden alle Fundstellen.
*
* Was hier NICHT eingesammelt wird, steht im Kopf der Seite: Sitelinks,
* Snippets, Bilder-Assets und die Endziele von Performance-Max-Assetgruppen
* haengen an anderen Objekten und brauchen einen eigenen Durchlauf.
*/
function sammleUrls() {
var karte = {};
var anzeigen = AdsApp.ads()
.withCondition('ad_group_ad.status = ENABLED')
.withCondition('ad_group.status = ENABLED')
.withCondition('campaign.status = ENABLED')
.get();
while (anzeigen.hasNext()) {
var anzeige = anzeigen.next();
merke(karte, urlVon(anzeige), 'Anzeige: ' + nameVon(anzeige.getCampaign()) + ' » ' +
nameVon(anzeige.getAdGroup()));
}
var keywords = AdsApp.keywords()
.withCondition('ad_group_criterion.status = ENABLED')
.withCondition('ad_group.status = ENABLED')
.withCondition('campaign.status = ENABLED')
.get();
while (keywords.hasNext()) {
var keyword = keywords.next();
merke(karte, urlVon(keyword), 'Keyword: ' + textVon(keyword) + ' (' +
nameVon(keyword.getCampaign()) + ')');
}
return karte;
}
function merke(karte, adresse, ort) {
if (!adresse) return;
if (adresse.indexOf('http') !== 0) return; // Platzhalter und leere Felder
if (!karte[adresse]) karte[adresse] = [];
if (karte[adresse].length < 5) karte[adresse].push(ort);
}
function urlVon(entitaet) {
try {
var urls = entitaet.urls();
return urls ? urls.getFinalUrl() : null;
} catch (fehler) {
return null;
}
}
function textVon(keyword) {
try { return keyword.getText(); } catch (fehler) { return '(ohne Text)'; }
}
function nameVon(entitaet) {
if (!entitaet) return '(ohne)';
try { return entitaet.getName(); } catch (fehler) { return '(ohne)'; }
}
// --- Pruefung --------------------------------------------------------------
/**
* Eine Adresse abrufen und die Weiterleitungen von Hand verfolgen.
*
* followRedirects steht auf false, weil die Antwort sonst nicht verraet, WO
* man gelandet ist - und genau das braucht die Startseiten-Erkennung.
* muteHttpExceptions verhindert, dass ein 404 den ganzen Lauf abbricht.
*/
function pruefeAdresse(adresse) {
var aktuell = adresse;
var sprung = 0;
var kette = [];
while (sprung <= CONFIG.MAX_WEITERLEITUNGEN) {
var antwort;
try {
antwort = UrlFetchApp.fetch(aktuell, {
muteHttpExceptions: true,
followRedirects: false,
validateHttpsCertificates: true,
method: 'get'
});
} catch (fehler) {
return { problem: 'nicht erreichbar', detail: kuerze(String(fehler), 180) };
}
var status = antwort.getResponseCode();
if (status >= 300 && status < 400) {
var ziel = ausHeader(antwort, 'Location');
if (!ziel) {
return { problem: 'Weiterleitung ohne Ziel', detail: 'Status ' + status + ', kein Location-Header' };
}
aktuell = absolut(aktuell, ziel);
kette.push(status + ' → ' + aktuell);
sprung++;
continue;
}
if (status >= MELDEN_AB_STATUS) {
return {
problem: 'Status ' + status,
detail: (kette.length ? 'nach ' + kette.join(', ') + '; ' : '') + beschreibeStatus(status)
};
}
if (CONFIG.PRUEFE_STARTSEITEN_WEITERLEITUNG && kette.length > 0 &&
hatPfad(adresse) && !hatPfad(aktuell)) {
return {
problem: 'Weiterleitung auf die Startseite',
detail: 'Status ' + status + ' nach ' + kette.join(', ') +
' — die beworbene Unterseite gibt es so nicht mehr'
};
}
return { problem: null, detail: 'Status ' + status };
}
return {
problem: 'zu viele Weiterleitungen',
detail: 'mehr als ' + CONFIG.MAX_WEITERLEITUNGEN + ' Spruenge: ' + kette.join(', ')
};
}
function beschreibeStatus(status) {
if (status === 404) return 'Seite nicht gefunden';
if (status === 403) return 'Zugriff verweigert (auch eine Firewall gegen Rechenzentren sieht so aus)';
if (status === 410) return 'Seite dauerhaft entfernt';
if (status === 429) return 'zu viele Anfragen — PAUSE_MS erhoehen und erneut pruefen';
if (status >= 500) return 'Serverfehler auf deiner Seite';
return 'Fehlercode';
}
/** Hat die Adresse einen echten Pfad, oder ist sie die blanke Startseite? */
function hatPfad(adresse) {
var ohneSchema = String(adresse).replace(/^https?:\/\//i, '');
var schnitt = ohneSchema.indexOf('/');
if (schnitt === -1) return false;
var pfadTeil = ohneSchema.substring(schnitt).replace(/[?#].*$/, '');
return pfadTeil.replace(/\/+$/, '').length > 0;
}
/** Relative Location-Header zu einer absoluten Adresse machen. */
function absolut(basis, ziel) {
if (/^https?:\/\//i.test(ziel)) return ziel;
var ohneSchema = String(basis).replace(/^(https?:\/\/)/i, '');
var schema = String(basis).substring(0, String(basis).length - ohneSchema.length);
var schnitt = ohneSchema.indexOf('/');
var host = schnitt === -1 ? ohneSchema : ohneSchema.substring(0, schnitt);
if (ziel.indexOf('/') === 0) return schema + host + ziel;
var pfad = schnitt === -1 ? '/' : ohneSchema.substring(schnitt);
var bisSlash = pfad.substring(0, pfad.lastIndexOf('/') + 1);
return schema + host + bisSlash + ziel;
}
function ausHeader(antwort, name) {
var kopfzeilen = antwort.getAllHeaders();
for (var schluesselName in kopfzeilen) {
if (!kopfzeilen.hasOwnProperty(schluesselName)) continue;
if (schluesselName.toLowerCase() !== name.toLowerCase()) continue;
var wert = kopfzeilen[schluesselName];
return (wert && wert.length && typeof wert !== 'string') ? wert[0] : wert;
}
return null;
}
// --- Ausgabe ---------------------------------------------------------------
function berichte(funde, geprueft, gesamt, abgebrochen) {
Logger.log('Geprueft: ' + geprueft + ' von ' + gesamt + ' Adressen.');
if (abgebrochen) {
Logger.log('ABGEBROCHEN vor dem Zeitlimit. Der Rest ist ungeprueft, nicht in Ordnung.');
}
if (funde.length === 0) {
Logger.log('Ergebnis: keine kaputte Ziel-URL unter den geprueften Adressen.');
Logger.log('Das heisst nicht, dass alle Ziele stimmen: Sitelinks, Snippets und die');
Logger.log('Assets von Performance Max haengen an anderen Objekten und sind hier');
Logger.log('nicht dabei. Eine ausgelaufene Produktseite hinterlaesst Reste in');
Logger.log('mehreren davon gleichzeitig.');
} else {
Logger.log('Ergebnis: ' + funde.length + ' Adresse(n) mit Problem.');
Logger.log('');
var grenze = Math.min(funde.length, CONFIG.MAX_PROTOKOLL_ZEILEN);
for (var i = 0; i < grenze; i++) {
var f = funde[i];
Logger.log('[' + f.problem + '] ' + f.url);
Logger.log(' ' + f.detail);
Logger.log(' Fundstellen: ' + f.orte.join(' | '));
}
if (funde.length > grenze) {
Logger.log('… und ' + (funde.length - grenze) + ' weitere.');
}
}
Logger.log('');
Logger.log('Lauf beendet: ' + geprueft + ' Adressen geprueft · ' + funde.length + ' Fund(e).');
vielleichtMailen(funde, geprueft, gesamt, abgebrochen);
}
function vielleichtMailen(funde, geprueft, gesamt, abgebrochen) {
if (!CONFIG.EMAIL_SENDEN) return;
if (funde.length < CONFIG.EMAIL_AB_FUNDEN) return;
if (!CONFIG.EMPFAENGER || CONFIG.EMPFAENGER.indexOf('@') === -1) {
Logger.log('E-Mail uebersprungen: EMPFAENGER ist keine Adresse.');
return;
}
var zeilen = [];
zeilen.push('Konto: ' + AdsApp.currentAccount().getCustomerId());
zeilen.push('Geprueft: ' + geprueft + ' von ' + gesamt + ' Adressen.');
if (abgebrochen) zeilen.push('Lauf vorzeitig beendet - der Rest ist ungeprueft.');
zeilen.push('Funde: ' + funde.length);
zeilen.push('');
var grenze = Math.min(funde.length, CONFIG.MAX_PROTOKOLL_ZEILEN);
for (var i = 0; i < grenze; i++) {
zeilen.push('[' + funde[i].problem + '] ' + funde[i].url);
zeilen.push(' ' + funde[i].detail);
zeilen.push(' ' + funde[i].orte.join(' | '));
zeilen.push('');
}
if (funde.length > grenze) zeilen.push('… und ' + (funde.length - grenze) + ' weitere.');
zeilen.push('Dieses Skript liest nur. Es hat nichts im Konto veraendert.');
MailApp.sendEmail(CONFIG.EMPFAENGER, CONFIG.BETREFF + ' (' + funde.length + ')', zeilen.join('\n'));
Logger.log('E-Mail an ' + CONFIG.EMPFAENGER + ' verschickt.');
}
// --- Kleinkram -------------------------------------------------------------
function restzeitSekunden() {
try {
return AdsApp.getExecutionInfo().getRemainingTime();
} catch (fehler) {
return 9999; // Ohne Auskunft laeuft das Skript bis zum harten Limit weiter.
}
}
function istVorschau() {
try { return AdsApp.getExecutionInfo().isPreview() === true; } catch (fehler) { return false; }
}
function schluessel(karte) {
var raus = [];
for (var k in karte) if (karte.hasOwnProperty(k)) raus.push(k);
raus.sort();
return raus;
}
function kuerze(text, laenge) {
var t = String(text);
return t.length > laenge ? t.substring(0, laenge) + '…' : t;
}
In die Zwischenablage kopiert.
Einbau
In fünf Schritten im Konto
Der letzte Schritt ist der wichtigste: erst die Vorschau, dann der echte Lauf.
-
1
Code kopieren
Der vollständige Code steht weiter unten auf dieser Seite. Kein Download, kein Formular, keine E-Mail-Adresse — der Knopf legt ihn in die Zwischenablage.
-
2
In Google Ads: Tools → Skripte
Linke Leiste „Tools“ → „Bulk-Aktionen“ → „Skripte“. Dann auf das Plus, um ein leeres Skript anzulegen. In manchen Konten heißt der Punkt nur „Skripte“ — die Suchleiste oben findet ihn zuverlässig.
-
3
Einfügen und benennen
Den Beispielcode im Editor komplett markieren, überschreiben, und dem Skript oben einen Namen geben. Die Einstellungen im CONFIG-Block ganz oben anpassen — mehr musst du im Code nicht anfassen.
-
4
Autorisieren
Google fragt einmal nach Berechtigungen. Das Skript braucht Lesezugriff auf das Konto, und wenn du die E-Mail einschaltest, das Recht, in deinem Namen Mails zu schicken. Das ist eine Google-Abfrage, keine Anmeldung bei mir.
-
5
Erst „Vorschau“, dann „Ausführen“
Die Vorschau lässt das Skript durchlaufen und zeigt das Protokoll, ohne etwas zu speichern. Lies das Protokoll einmal ganz. Erst danach „Ausführen“ und, wenn es passt, einen Zeitplan setzen.
Ehrliche Grenzen
Was dieses Skript nicht sieht
Ein Waldstück, das niemand abgesucht hat, ist nicht leer. Deshalb steht hier, wo dieses Skript gar nicht erst hinschaut — und im Protokoll steht derselbe Satz noch einmal, direkt neben dem Ergebnis.
- Nur die Ziel-URLs von Anzeigen und Keywords. Sitelinks, Snippets, Bild- und Video-Assets und die Endziele von Performance-Max-Assetgruppen hängen an anderen Objekten — sie brauchen einen eigenen Durchlauf (v2). Das ist die wichtigste Grenze dieses Skripts: Ein eingestelltes Produkt hinterlässt Reste in mehreren Objekttypen gleichzeitig, und dieses Skript sieht zwei davon.
- Höchstens 400 Adressen pro Lauf. Ein Skript hat 30 Minuten Laufzeit, und jeder Abruf kostet Zeit; die Tageskontingente für die Abrufe kommen außerdem aus Apps Script. Wird die Grenze erreicht, steht das im Protokoll — der Rest fällt nicht still weg. Gleiche Adresse an zwanzig Anzeigen wird einmal geprüft und zwanzigmal gemeldet.
- Geprüft wird die Ziel-URL, nicht die Adresse nach dem Tracking-Template. Wer serverseitig weiterleitet oder Parameter auswertet, prüft damit den Anfang der Kette, nicht ihr Ende.
- Manche Server antworten einem Rechenzentrum mit 403, obwohl die Seite für Menschen funktioniert. Das Skript nennt diesen Fall beim Namen, statt ihn als kaputt zu verkaufen — nachsehen musst du trotzdem selbst.
- Ein Status 200 ist kein Beweis für eine richtige Seite. Eine Fehlerseite, die 200 zurückgibt, sieht für jeden Abruf gesund aus.
Was mit Schreibrechten besser wäre — und trotzdem fehlt
Diese Bibliothek ist in Version 1 per Konstruktion nur lesend. Nicht aus Bequemlichkeit: Der Code landet in fremden, laufenden Konten, und ein Skript, das dort selbstständig pausiert oder umschreibt, richtet im Zweifel einen Schaden an, den niemand kommen sieht. Prüfungen, die mit einem Schreibzugriff besser wären, stehen deshalb hier statt im Code.
- v2 Die betroffenen Anzeigen und Keywords pausieren, solange das Ziel kaputt ist. Der wirksamste Eingriff — und der, bei dem ein falscher Fund am meisten kostet, etwa wenn deine Firewall dem Skript einen 403 zurückgibt.
- v2 Sitelinks, Snippets und Performance-Max-Assets mitprüfen. Kein Schreibzugriff nötig, nur mehr Code — steht auf der Liste für v2.
FAQ
Kaputte-Ziel-URL-Prüfung: häufige Fragen
Ist dieses Google Ads Script sicher?
Ändert das Skript etwas in meinem Konto?
Wie oft sollte ich es laufen lassen?
Warum sehe ich nichts im Protokoll?
Ergebnisse, die ich gemessen habe.
14 Kundenstimmen · 22 Case Studies
-
Käufe +50 % 2022 → 2024, vor und nach der Übernahme Stimme von Natalja Richert unten
-
Über Google Ads erfasste Buchungen
≈1.466
1. August 2024–31. Juli 2026
-
Google Ads zugeschriebener Umsatz > 1,5 Mio. € 12 Monate Stimme von Patrick Zitzer unten
-
Klickrate in der Google-Suche
1,02 % →
17,35 %
1. → 2. Halbjahr 2023
„Mir ist besonders wichtig, dass es bei Google Ads nicht einfach darum geht, mehr Budget auszugeben und mehr Umsatz zu machen, sondern dass die Wirtschaftlichkeit für uns stimmt – und genau das berücksichtigt Daniils bei seiner Arbeit.“
Vollständige Bewertung lesenBewertung einklappen
„Wir arbeiten jetzt schon seit mehreren Jahren mit Danny zusammen und ich schätze vor allem den direkten und unkomplizierten Austausch mit ihm. Er schaut sich die Zahlen genau an, hinterfragt Dinge und kommt auch immer wieder selbst mit neuen Ideen und Ansätzen auf uns zu. Mir ist besonders wichtig, dass es bei Google Ads nicht einfach darum geht, mehr Budget auszugeben und mehr Umsatz zu machen, sondern dass die Wirtschaftlichkeit für uns stimmt – und genau das berücksichtigt Daniils bei seiner Arbeit. Ich schätze außerdem sehr, dass wir uns offen austauschen können.“
Natalja RichertGeschäftsführerin · MYTRAURINGstore
Case Study lesen
„Die Zusammenarbeit mit Daniils ist ein riesiger Gewinn für unsere Firma.“
Vollständige Bewertung lesenBewertung einklappen
„Die Zusammenarbeit mit Daniils ist ein riesiger Gewinn für unsere Firma. Bei Fragen oder auch Problemen, wir erreichen uns immer. Daniils hat sich in die Materie Sauna voll eingearbeitet und unterstützt uns wo er nur kann. Ich freue mich, dass ich Dich persönlich kennenlernen durfte und wir eine so tolle Zusammenarbeit pflegen. Wie schon angemerkt: Du bist ein Ausnahmetalent, Chapeau!“
Anke Della-BellaGeschäftsführerin · Finsterbusch – die Wellness Factory GmbH
Case Study lesen
„Danach konnten wir unsere Conversion Rate auf Sales fast verdoppeln.“
Vollständige Bewertung lesenBewertung einklappen
„Ich betreue unsere Kampagnen selbst und habe Danny für die Google-Ads-Beratung dazugeholt. Wir standen unter Zeitdruck und brauchten eine klare Richtung.
Danny hat sich schnell in unser Geschäft hineingedacht und uns konkrete Empfehlungen zur Gebotsstrategie und zum passenden Conversion-Ziel gegeben. Danach konnten wir unsere Conversion Rate auf Sales fast verdoppeln.
Für mich hat sich vor allem das Gefühl verändert: Ich habe einen Ansprechpartner per Call oder WhatsApp und muss die schwierigsten Entscheidungen nicht mehr allein tragen. Der Austausch ist herzlich, cool und entspannt. Ich würde Danny jedem empfehlen, der seine Kampagnen selbst betreut und jemanden braucht, der wirklich mitdenkt.“
Merlin FaudeGeschäftsführer
„Wir konnten unsere Marketingziele messbar verbessern.“
Vollständige Bewertung lesenBewertung einklappen
„Daniils ist ein äußerst professioneller und zuverlässiger Partner. Die Zusammenarbeit verläuft effizient, lösungsorientiert und immer auf Augenhöhe. Besonders hervorzuheben sind die kurzen Kommunikationswege und seine schnelle Reaktionszeit — man fühlt sich jederzeit gut betreut. Wir konnten unsere Marketingziele messbar verbessern. Eine Zusammenarbeit, die wir uneingeschränkt weiterempfehlen können.“
Patrick ZitzerZitberg GmbH
Case Study lesen
„Du hast uns nicht nur bei Google Ads geholfen, sondern unser gesamtes Online-Marketing auf ein neues Level gehoben.“
Vollständige Bewertung lesenBewertung einklappen
„Daniils, danke für deine großartige Unterstützung! Du hast uns nicht nur bei Google Ads geholfen, sondern unser gesamtes Online-Marketing auf ein neues Level gehoben. Deine strukturierte Herangehensweise, dein Blick fürs Detail und dein ehrliches Feedback haben uns extrem weitergebracht. Besonders schätze ich, dass du dich wirklich in unser Business hineingedacht hast – es ging nie um schnelle Tricks, sondern um nachhaltige Performance. Man merkt einfach, dass du weißt, was du tust, und dass du Spaß daran hast. Ich kann dich von Herzen weiterempfehlen!“
„Daniils ist ein echtes Ausnahmetalent.“
Vollständige Bewertung lesenBewertung einklappen
„Daniils ist ein echtes Ausnahmetalent. Er beherrscht nicht nur alles rund um Google, sondern bringt auch ein starkes unternehmerisches Gespür mit. Komplexe Themen erklärt er verständlich und hilft so, fundierte Geschäftsentscheidungen zu treffen. Eine klare Empfehlung!“
Chris CerraRemoteBase
„Besonders schätze ich, wie verständlich er komplexe Themen erklärt.“
Vollständige Bewertung lesenBewertung einklappen
„Daniils ist ein großartiger Google-Ads-Experte! Er ist schnell, hands-on und bringt kreative Lösungen. Besonders schätze ich, wie verständlich er komplexe Themen erklärt. Wer Hilfe bei Google Ads braucht — Daniils ist die richtige Wahl!“
Samantha ScottAll Things Remote
„Daniils hat zwei meiner Kunden hervorragend bei ihren Google-Ads-Kampagnen unterstützt.“
Vollständige Bewertung lesenBewertung einklappen
„Daniils hat zwei meiner Kunden hervorragend bei ihren Google-Ads-Kampagnen unterstützt. Mit seinem Fachwissen, seiner Professionalität und wertvollen Strategien konnten sie ihre Sichtbarkeit steigern und die Conversion Rates verbessern. Seine Expertise hat wirklich den Unterschied gemacht — absolut empfehlenswert!“
Tim RautenbergXM CROSSMEDIA
„Daniils leistet super Arbeit und bringt absolute Kompetenz im Bereich Ads und Tracking mit!“
Pascal RähseFunnelforms-Gründer
„Daniils hat uns mit seiner Marketingstrategie für die Events eines Kunden auf ein ganz neues Level gebracht.“
Vollständige Bewertung lesenBewertung einklappen
„Daniils hat uns mit seiner Marketingstrategie für die Events eines Kunden auf ein ganz neues Level gebracht. Er war schnell, engagiert und persönlich dabei — und hat uns sogar mit weiteren Expert:innen vernetzt. Fachlich top und mit ganzem Herzen dabei — absolute Empfehlung!“
Alexandra MonitskaMar Sabi Studio
„Daniils hat mir in kürzester Zeit bei der Lösung eines Problems geholfen, bei dem ich selbst nicht weitergekommen bin.“
Vollständige Bewertung lesenBewertung einklappen
„Daniils hat mir in kürzester Zeit bei der Lösung eines Problems geholfen, bei dem ich selbst nicht weitergekommen bin. Reaktionsschnell, freundlich und höchst kompetent hat er den Auftrag erledigt und sich danach sogar noch Zeit für ein gemeinsames Videomeeting genommen, um die Ergebnisse zu besprechen. Vielen Dank dafür!“
Daniel Fischerdigitalpositiv
„Sehr gute Kommunikation.“
Vollständige Bewertung lesenBewertung einklappen
„Sehr gute Kommunikation. In unseren zwei Beratungsterminen hat sich Daniils intensiv mit meiner Situation beschäftigt und mir klares, gut begründetes Feedback zu Google Ads, Analytics und meiner gesamten digitalen Strategie gegeben.“
„Top Beratung und Kompetenz. Daniils nimmt sich wirklich die Zeit, das Problem gemeinsam zu lösen. Kann ich jedem weiterempfehlen.“
„Daniils kommuniziert sehr gut und hat den Auftrag super schnell und zuverlässig umgesetzt. Ich werde künftig öfter mit ihm arbeiten :)“
Lieber jemanden, der hinschaut?
Die Skripte finden, was sich beweisen lässt. Struktur, Gebote und die Frage, ob überhaupt das Richtige gemessen wird, gehen wir im Gespräch durch.