Google Ads
Create Search and Display campaigns via Zernio API - No MCC or Standard Access application required
Requires the Ads add-on. No MCC or Standard Access application needed. Zernio operates under our own approved developer token.
What's Supported
| Feature | Status |
|---|---|
| Search campaigns (Responsive Search Ads) | Yes |
| Display campaigns (Responsive Display Ads) | Yes |
| Campaign > Ad Group > Ad hierarchy | Yes |
| Keyword targeting (Broad, Phrase, Exact) | Yes |
| Geo + language targeting | Yes |
| Real-time analytics (spend, CPC, CPM) | Yes |
| Conversions API (offline/enhanced) via Data Manager | Yes |
| Performance Max | Roadmap |
| Shopping, Video, Demand Gen | Roadmap |
| Customer Match audiences | Roadmap |
Create a Search Campaign
const ad = await zernio.ads.createStandaloneAd({ body: {
accountId: "acc_googleads_123",
adAccountId: "987-654-3210",
name: "US DevOps Search",
campaignType: "SEARCH",
goal: "traffic",
budgetAmount: 50,
budgetType: "daily",
keywords: [
{ text: "platform engineering tools", matchType: "BROAD" },
{ text: "internal developer platform", matchType: "PHRASE" },
],
countries: ["US", "CA", "GB"],
additionalHeadlines: ["Build your Dev Platform", "Ship DevEx Faster", "Internal Platforms, Done Right"],
additionalDescriptions: ["Spec-driven platform. Free tier available.", "Enterprise features. Startup price."],
linkUrl: "https://example.com/platform",
}});ad = client.ads.create_standalone_ad(
account_id="acc_googleads_123",
ad_account_id="987-654-3210",
name="US DevOps Search",
campaign_type="SEARCH",
goal="traffic",
budget_amount=50,
budget_type="daily",
keywords=[
{"text": "platform engineering tools", "matchType": "BROAD"},
{"text": "internal developer platform", "matchType": "PHRASE"},
],
countries=["US", "CA", "GB"],
additional_headlines=["Build your Dev Platform", "Ship DevEx Faster", "Internal Platforms, Done Right"],
additional_descriptions=["Spec-driven platform. Free tier available.", "Enterprise features. Startup price."],
link_url="https://example.com/platform",
)curl -X POST "https://zernio.com/api/v1/ads/create" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "googleads",
"accountId": "acc_googleads_123",
"adAccountId": "987-654-3210",
"name": "US DevOps Search",
"campaignType": "SEARCH",
"goal": "traffic",
"budget": { "amount": 50, "type": "daily" },
"schedule": { "startDate": "2026-04-20" },
"targeting": {
"geoTargets": ["US", "CA", "GB"],
"languages": ["en"],
"keywords": [
{ "text": "platform engineering tools", "matchType": "BROAD" },
{ "text": "internal developer platform", "matchType": "PHRASE" }
]
},
"creative": {
"headlines": ["Build your Dev Platform", "Ship DevEx Faster", "Internal Platforms, Done Right"],
"descriptions": ["Spec-driven platform. Free tier available.", "Enterprise features. Startup price."],
"landingPageUrl": "https://example.com/platform"
}
}'Create a Display Campaign
const ad = await zernio.ads.createStandaloneAd({ body: {
accountId: "acc_googleads_123",
adAccountId: "987-654-3210",
name: "Retargeting Display",
campaignType: "DISPLAY",
goal: "conversions",
budgetAmount: 40,
budgetType: "daily",
countries: ["US"],
additionalHeadlines: ["Finish your signup", "Get 30% off this week"],
additionalDescriptions: ["Come back and upgrade today."],
imageUrl: "https://cdn.example.com/retarget-1200x628.jpg",
linkUrl: "https://example.com/upgrade",
}});ad = client.ads.create_standalone_ad(
account_id="acc_googleads_123",
ad_account_id="987-654-3210",
name="Retargeting Display",
campaign_type="DISPLAY",
goal="conversions",
budget_amount=40,
budget_type="daily",
countries=["US"],
additional_headlines=["Finish your signup", "Get 30% off this week"],
additional_descriptions=["Come back and upgrade today."],
image_url="https://cdn.example.com/retarget-1200x628.jpg",
link_url="https://example.com/upgrade",
)curl -X POST "https://zernio.com/api/v1/ads/create" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "googleads",
"accountId": "acc_googleads_123",
"adAccountId": "987-654-3210",
"name": "Retargeting Display",
"campaignType": "DISPLAY",
"goal": "conversions",
"budget": { "amount": 40, "type": "daily" },
"targeting": { "geoTargets": ["US"], "languages": ["en"] },
"creative": {
"headlines": ["Finish your signup", "Get 30% off this week"],
"descriptions": ["Come back and upgrade today."],
"imageUrls": ["https://cdn.example.com/retarget-1200x628.jpg"],
"landingPageUrl": "https://example.com/upgrade"
}
}'Conversions API
Import offline conversions (deal closed, lead qualified, subscription renewed) into Google Ads via the Data Manager API ingestEvents method — the endpoint Google recommends for all new integrations as of December 2025 (replacing the legacy uploadClickConversions). Zernio uses the Google Ads account you already connected; no additional OAuth, no developer token to apply for.
The same endpoint handles both attribution paths:
- Click attribution — include a
gclid,gbraid, orwbraidfrom the originating ad click - Enhanced Conversions for Leads — include hashed email / phone when no click ID is available
PII is SHA-256 hashed server-side. For @gmail.com / @googlemail.com addresses, we strip dots and +suffix from the local part before hashing per Google's spec so john.doe+promo@gmail.com matches johndoe@gmail.com.
Discover available conversion actions
curl "https://zernio.com/api/v1/accounts/ACCOUNT_ID/conversion-destinations" \
-H "Authorization: Bearer YOUR_API_KEY"Returns every enabled conversion action across accessible customers. The id is the conversion action resource name (customers/{customerId}/conversionActions/{id}). The type field reflects the action's category (PURCHASE, LEAD, SIGN_UP, etc.) — Google locks the event type to the conversion action, not the per-event eventName.
Send a conversion event
const result = await zernio.ads.sendConversions({ body: {
accountId: 'ACCOUNT_ID',
destinationId: 'customers/1234567890/conversionActions/987654321',
consent: { adUserData: 'GRANTED', adPersonalization: 'GRANTED' }, // required for EEA/UK
events: [{
eventName: 'Purchase',
eventTime: Math.floor(Date.now() / 1000),
eventId: 'order_abc_123', // dedup — mapped to transactionId
value: 129.99,
currency: 'USD',
user: {
email: 'customer@example.com',
phone: '+14155551234',
clickIds: { gclid: 'EAIaIQobChMI...' },
},
}],
}});result = client.ads.send_conversions(
account_id="ACCOUNT_ID",
destination_id="customers/1234567890/conversionActions/987654321",
consent={"adUserData": "GRANTED", "adPersonalization": "GRANTED"},
events=[{
"eventName": "Purchase",
"eventTime": int(time.time()),
"eventId": "order_abc_123",
"value": 129.99,
"currency": "USD",
"user": {
"email": "customer@example.com",
"phone": "+14155551234",
"clickIds": {"gclid": "EAIaIQobChMI..."},
},
}],
)curl -X POST "https://zernio.com/api/v1/ads/conversions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accountId": "ACCOUNT_ID",
"destinationId": "customers/1234567890/conversionActions/987654321",
"consent": { "adUserData": "GRANTED", "adPersonalization": "GRANTED" },
"events": [{
"eventName": "Purchase",
"eventTime": 1744732800,
"eventId": "order_abc_123",
"value": 129.99,
"currency": "USD",
"user": {
"email": "customer@example.com",
"phone": "+14155551234",
"clickIds": { "gclid": "EAIaIQobChMI..." }
}
}]
}'EEA / UK consent
Google enforces strict consent signaling for European users under the February 2026 Data Manager restrictions. Pass consent at the request root with adUserData and adPersonalization set to GRANTED or DENIED. Omit the field for non-EEA requests where you don't have consent data; Google applies region defaults.
Deduplication
Pass a stable eventId on every event — Zernio maps it to Google's transactionId so repeated uploads of the same conversion are deduped.
Batching + reporting
Up to 2,000 events per request (Zernio chunks larger batches automatically). Conversions take up to 3 hours to appear in Google Ads reports. The response carries a requestId you can reference if conversions don't appear as expected.
Media Requirements
| Type | Format | Max Size | Notes |
|---|---|---|---|
| Responsive Search Ad | Text | 15 headlines / 4 descriptions | 30/90 chars |
| Responsive Display | JPEG, PNG | 5120 KB/asset | 1.91:1 and 1:1 |
| Keyword | Text | 80 chars | BROAD, PHRASE, EXACT |
Version Migrations
Google Ads API ships v22, v23, v24... twice a year with breaking changes. Zernio absorbs these at our layer, so your integration keeps working without code changes.