Ukratko
Autentifikacija na Google Ads API-ju ima tri sloja koja se stalno mešaju - OAuth2 kredencijali koji kažu ko ste, developer token koji kaže koja je aplikacija u pitanju, i login-customer-id koji kaže koji nalog gađate. Postoji i četvrti, opcioni sloj (service account) za uži slučaj upotrebe nego što quick-start dokumentacija sugeriše. Pogrešite li bilo koji od ta tri, ne dobijate upozorenje - dobijate konkretan kod greške i mrtav skript.
4
vrednosti u google-ads.yaml
7
dana pre nego refresh token u Testing modu umre
4
česte auth greške mapirane na rešenja ispod
€0
koliko košta da se ovo podesi kako treba
Brz odgovor
Developer token na Google Ads API-ju identifikuje vašu aplikaciju i nikad se ne menja; OAuth2 client (client ID i secret) identifikuje aplikaciju Google-ovim auth serverima; refresh token identifikuje osobu koja je odobrila pristup i može isteći. Za solo operatera ili agenciju koja vodi sopstvene skriptove, koristite OAuth2 desktop (installed app) tok - najjednostavniji je put i offline pristup je uključen po default-u. Web application tok koristite samo ako gradite nešto u šta se korisnici uloguju kroz browser. Service account ima smisla isključivo kad radite server-to-server automatizaciju unutar Google Workspace domena sa podešenom domain-wide delegacijom za adwords scope - Google-ov sopstveni vodič za service account to ne objašnjava, ali bez toga, poziv preko service account-a na Google Ads API-ju ne prolazi sa AuthenticationError.NOT_ADS_USER.
Moja Basic Access prijava za Google Ads API prošla je pregled za par sati umesto uobičajenih dana - tačne korake opisao sam u vodiču za Basic Access. Ali odobren token ne znači ništa dok ne prođete kroz auth handshake, a to je sasvim odvojen problem - prvi put me je to sasekao na tokenu za Google Merchant Center koji je umro usred skripta, bez ijednog upozorenja.
Ovaj vodič pokriva deo koji niko čisto ne objasni: OAuth2 desktop naspram web toka, zamku od 7 dana, šta je developer token header stvarno u odnosu na OAuth token, kad je service account zaista pravi alat (a kad to samo izgleda tako), i test od dva minuta u Python-u kojim proverite da ceo lanac radi pre nego što na njemu gradite bilo šta.
Tri (plus jedan) sloja Google Ads API autentifikacije
Najčešća zabuna kod početnika: developer token nije OAuth token, i njegovo odobrenje samo po sebi ne autentifikuje ništa. To su dva potpuno nezavisna kredencijala koja moraju biti prisutna na svakom pozivu, plus treći koji je bitan tek kad radite kroz manager nalog.
| Sloj | Šta je | Gde se nalazi | Ako fali ili je pogrešan |
|---|---|---|---|
| OAuth2 client (client ID + secret) | Identifikuje vašu aplikaciju Google-ovim auth serverima | Cloud Console → Credentials → Create OAuth client ID | Auth tok ne može ni da počne |
| Refresh token | Dugotrajna propusnica koja se razmenjuje za kratkotrajne access tokene | Izlaz iz OAuth consent toka (desktop ili web) | invalid_grant - skript staje |
| Developer token | Identifikuje vašu aplikaciju Google Ads API-ju - ne korisnika | API Center, u tvom manager nalogu | DEVELOPER_TOKEN_NOT_APPROVED |
| login-customer-id | Kaže koji nalog (MCC ili klijentski) gađate | Header koji sami podešavate, obavezan kad idete kroz MCC | USER_PERMISSION_DENIED |
Sam developer token - kako se generiše, i nivoi pristupa Test / Explorer / Basic / Standard koji određuju šta može da poziva - pokriven je u celini u vodiču za Basic Access. Ovaj post pretpostavlja da već imate token (bilo koji nivo radi za testiranje) i fokusira se na to da ostali slojevi rade kako treba.
OAuth2: desktop tok naspram web toka
Google Ads API podržava dva OAuth2 toka, i izbor pravog štedi celu klasu bagova kasnije. Prema Google-ovoj dokumentaciji o OAuth internom radu, desktop (installed app) tok ima offline pristup - mogućnost da se token osveži bez korisnika koji sedi ispred ekrana - uključen po default-u: eksplicitno ga ne morate tražiti. Web application tok to nema; treba mu eksplicitan access_type=offline parametar na auth zahtevu, ili refresh token uopšte ne stiže.
Za solo operatera ili agenciju koja vodi interne skriptove - izvlačenje reportova, provere trošenja budžeta, promene bidova - desktop tok je pravi default. Njega pokrećem za svaki klijentski nalog pod sopstvenim manager nalogom. Web tok je za drugi slučaj: aplikaciju sa ekranom za login koju koristi treća strana.
InstalledAppFlow.run_local_server() u Python-u otvara browser, odobrite pristup svojim Google nalogom, i tok vam u terminalu vraća refresh token.Ako ste već prošli kroz OAuth consent screen radi verifikacije brenda - korak 4 u vodiču za Basic Access - prepoznaćete ovaj ekran. Isti je; sad ste tu iz drugog razloga.
Zamka: Testing mode ubija refresh token za 7 dana
Ovo je dokumentovano, ali se lako previdi. Prema Google-ovoj OAuth 2.0 dokumentaciji, Cloud projekat sa External tipom korisnika i Testing statusom objave izdaje refresh tokene koji ističu za 7 dana - bez mejla, bez upozorenja, ničega. Sledeći poziv jednostavno padne sa invalid_grant ("Token has been expired or revoked"), i ako skript radi bez nadzora preko noći, saznajete tek kad report ne stigne. Tačno ovako mi je umro jedan token za Google Merchant Center, a ceo taj incident i rešenje opisao sam u vodiču za Google API pristupe za agencije. Ako je vaš projekat isti onaj koji ste već gurnuli u In production radi verifikacije brenda (korak 4 iz vodiča za Basic Access), ovo je već rešeno. Ako niste, proverite sad: Cloud Console → APIs and services → OAuth consent screen → tab Audience.
Developer token header + login-customer-id
Još dve stvari se stalno mešaju jedna sa drugom, i nijedna nije OAuth koncept.
Developer token nije header koji dobijate iz OAuth toka - to je fiksan string iz API Center-a vašeg manager naloga (22 karaktera u mojim nalozima), i ide na svaki zahtev kao developer-token HTTP/gRPC header. Identifikuje aplikaciju, ne osobu koja poziva, i ista je vrednost bez obzira koji je Google nalog autentifikovao poziv.
login-customer-id je bitan tek kad vaš autentifikovan nalog ima pristup manager (MCC) nalogu. Ako pozivate API da uradite nešto na klijentskom nalogu ispod tog MCC-a, morate Google-u reći u kontekstu kog naloga radite - postavite login-customer-id header na ID MCC-a. Preskočite to i dobijate USER_PERMISSION_DENIED: "the authorized customer does not have access to the operating customer", iako u Google Ads interfejsu jasno imate pristup.
Service account - deo koji quick reference preskače
Google-ov sopstveni vodič za service account deluje jednostavno: napravite service account, preuzmite JSON ključ, ulogujte se u Google Ads kao admin, idite na Admin → Access and security, dodajte email service account-a kao korisnika, postavite json_key_file_path u konfiguraciji. Četiri koraka, gotovo.
Zašto ovde ljudi zapinju
U praksi, taj vodič preskače jedan korak. Bez Google Workspace domena i podešene domain-wide delegacije za adwords scope, poziv i dalje ne prolazi - obično sa AuthenticationError.NOT_ADS_USER, istom greškom koju biste dobili od OAuth naloga bez ikakvog pristupa Google Ads-u. Programeri koji su na ovo naleteli rešenje su dokumentovali na Google-ovom sopstvenom forumu za Ads API developere: service account mora da impersonira stvarnog Workspace korisnika preko subject parametra, i taj korak impersonacije je ono što stvarno autentifikuje zahtev, ne sam kredencijal service account-a.
Kad se isplati: server-to-server automatizacija bez čoveka u petlji za svako osvežavanje tokena, i - korisno - pristup koji ne pukne onog dana kad zaposleni ode, jer nije vezan ni za čiji lični Google nalog. Prema Google-ovom vodiču, jedan email service account-a može se dodati na do 20 Google Ads naloga; iznad toga, preporuka je da se doda kroz manager nalog.
Kad se ne isplati: solo operater ili mali tim bez Workspace domena. To je i moja stvarna postavka - svaki skript koji pokrećem prema Google Ads API-ju koristi desktop OAuth tok opisan gore, ne service account, jer se jednostavnije podešava i ne zahteva podizanje domain-wide delegacije za automatizaciju jedne osobe.
google-ads.yaml: šta fajlu stvarno treba
Koji god tok da koristite, Python client biblioteka čita sve iz jednog YAML fajla. Evo kako izgleda - zamenite svaku vrednost, naravno, ovo nije stvarna konfiguracija:
developer_token: "UPIŠI_DEVELOPER_TOKEN_OVDE"
client_id: "UPIŠI_OAUTH2_CLIENT_ID_OVDE"
client_secret: "UPIŠI_OAUTH2_CLIENT_SECRET_OVDE"
refresh_token: "UPIŠI_REFRESH_TOKEN_OVDE"
login_customer_id: "1234567890" # MCC ID, samo cifre, bez crtica; izostavite ovaj red za samostalan nalog
use_proto_plus: TrueDve stvari vredne isticanja: login_customer_id je MCC ID bez crtica, i mora se postaviti samo ako pozivate kroz manager nalog - izostavite ga za samostalan nalog. A use_proto_plus: True nije opciona kozmetika; client biblioteka zahteva ovo polje u konfiguraciji, i njegovo odsustvo pravi konfuzne greške tipova koje s autentifikacijom nemaju veze.
Proveri da radi: minimalan Python test
Pre nego što na ovome bilo šta gradite, proverite da ceo lanac - OAuth2, developer token, login-customer-id - stvarno radi. Isti princip kao testiranje na Explorer pristupu pre prijave za Basic: prvo dokažite da lanac radi na najmanjem mogućem pozivu.
# 1) Jednokratno: generiši refresh token (desktop OAuth tok)
from google_auth_oauthlib.flow import InstalledAppFlow
SCOPES = ["https://www.googleapis.com/auth/adwords"]
flow = InstalledAppFlow.from_client_secrets_file("client_secret.json", scopes=SCOPES)
credentials = flow.run_local_server(port=8080, prompt="consent")
print(credentials.refresh_token) # nalepi ovo u google-ads.yaml
# 2) Prvi poziv: da li konekcija stvarno radi?
from google.ads.googleads.client import GoogleAdsClient
client = GoogleAdsClient.load_from_storage("google-ads.yaml")
ga_service = client.get_service("GoogleAdsService")
query = "SELECT customer.id, customer.descriptive_name FROM customer LIMIT 1"
response = ga_service.search(customer_id="9876543210", query=query)
for row in response:
print(row.customer.descriptive_name)Ako to vrati ime naloga, svaki sloj - OAuth2, developer token, login-customer-id - pravilno je povezan. Ako padne, greška koju dobijete nazad kaže tačno koji sloj popraviti; vidi tabelu ispod.
Česte greške i šta ih stvarno izaziva
| Greška | Šta znači | Tipičan uzrok | Rešenje |
|---|---|---|---|
invalid_grant / RefreshError | Refresh token je mrtav | OAuth consent screen u Testing statusu - refresh tokeni ističu za 7 dana | Prebaci status objave na In production; regeneriši refresh token jednom |
USER_PERMISSION_DENIED | Nemaš prava na ovaj nalog, u ovom pozivu | Fali login-customer-id pri pozivu klijentskog naloga ispod MCC-a | Postavi login-customer-id header na ID svog MCC-a |
AuthenticationError.NOT_ADS_USER | Nalog iza tokena nije Google Ads korisnik | (a) OAuth nalog nema pristup Google Ads-u, ili (b) service account-u fali subject parametar impersonacije | (a) Autentifikuj se nalogom koji ima pristup Ads-u; (b) dodaj subject/impersonirani email i potvrdi domain-wide delegaciju |
DEVELOPER_TOKEN_NOT_APPROVED | Tvoj token ne može da koristi ovaj nalog ili ovaj servis | Token na Test nivou protiv produkcijskog naloga, ili token na Explorer nivou koji poziva servis koji Explorer ne pokriva | Vidi progresiju Test → Explorer → Basic u vodiču za Basic Access |
Sva četiri opisa gore citirana su iz Google-ove zvanične dokumentacije o čestim greškama. Uzroci i rešenja su ono na šta sam stvarno naleteo povezujući ovo za klijentske naloge.
Najčešća pitanja
Koja je razlika između developer token-a i OAuth2 token-a na Google Ads API-ju?▼
Zašto mi refresh token prestane da radi na svakih 7 dana?▼
invalid_grant ili RefreshError. Prebacivanje statusa objave na In production uklanja taj rok od 7 dana - to radite samo jednom po projektu.Da li mi treba Google Workspace za service account na Google Ads API-ju?▼
adwords scope, poziv ne prolazi sa AuthenticationError.NOT_ADS_USER - service account mora da impersonira stvarnog Workspace korisnika preko subject parametra da bi se uspešno autentifikovao. Za solo operatera ili mali tim bez Workspace domena, OAuth2 desktop tok je jednostavniji i ništa od ovoga mu ne treba.Šta je login-customer-id i kad mi treba?▼
login-customer-id je header koji Google Ads API-ju kaže u kontekstu kog naloga radite. Obavezan je kad autentifikovan nalog pristupa klijentskom nalogu kroz manager (MCC) nalog - postavite ga na ID MCC-a. Izostavljanje kad je potreban proizvodi USER_PERMISSION_DENIED, čak i ako nalog jasno vidite u Google Ads interfejsu.Šta znači AuthenticationError.NOT_ADS_USER?▼
subject/impersonirani parametar potreban da se autentifikuje kao stvaran Workspace korisnik.Hoćete da API radi nadzor umesto vas?
Gradim i vodim tačno ovaj auth stack za klijentske naloge - noćni reporti, provere trošenja budžeta, upozorenja za odbijene oglase - na vrhu ispravno podešene Google Ads API konekcije, bez iznenađenja tipa invalid_grant u 3 ujutru.
Zakažite besplatnu konsultacijuGoogle Ads Konsultacije
Jednokratni audit ili tekuća saradnja na strategiji.
Google Ads Upravljanje
Kompletno vođenje naloga, uključujući nadzor preko API-ja.
Google Ads API Basic Access Vodič
Kako da vam odobre developer token, uključujući brzu prijavu od jula 2026.
Google API Pristupi za Agencije
Jedan Cloud projekat, šest API-ja: Ads, GA4, Search Console, GTM i drugi.
Offline Conversion Import za B2B
Kako zatvorene poslove vraćate nazad u Google Ads, na istom API-ju.
Besplatni video audit
Dobijte personalizovani video audit vašeg Google Ads naloga
Snimićemo 15-minutni pregled vaših kampanja gde pokazujemo tačno gde gubite novac i šta bi prvi popravili.
Besplatni personalizovani video audit
Želite video pregled vašeg Google Ads naloga?
Lično ću snimiti 15-minutni video u kome prolazim kroz vaše kampanje, pokazujem gde gubite novac i dajem 3 konkretne stvari za popravku odmah. Bez prodaje - samo vrednost.
Šta dobijate:
- 15-min personalizovana video analiza
- 3 konkretna quick wins za implementaciju
- Preporuke za budžet i bidding
Uslovi:
- Ad spend: €1.500+/mesečno
- Aktivan nalog minimum 3 meseca
- eCommerce ili Lead Gen biznis
Ograničeno na 5 audita mesečno. Odgovor u roku od 48h.
Procitaj sledece
Google Search kampanje: kompletan vodič [2026]
Search · 12 min