curl --request GET \
--url https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "68c2d1e5f8a92e004d56b2a3",
"app_id": "6820f3a4e7b91d003c45a1f2",
"campaign_name": "Spring sale in Berlin",
"business_name": "Oakline Furniture",
"landing_page_url": "https://oakline.base44.app",
"phone_number": "+493012345678",
"daily_budget_micros": 15000000,
"currency_code": "EUR",
"headlines": [
"Handmade oak tables",
"Built in Berlin"
],
"long_headlines": [
"Solid oak dining tables, made to order in Berlin"
],
"descriptions": [
"Visit our showroom or order online with free delivery."
],
"images": [
{
"field_type": "MARKETING_IMAGE",
"url": "https://storage.base44.com/gads-assets/b7f3a1c8-landscape.png"
}
],
"logos": [
{
"field_type": "MARKETING_IMAGE",
"url": "https://storage.base44.com/gads-assets/logo.png"
}
],
"geo_targets": [
"geoTargetConstants/1003854"
],
"targeted_locations": [
{
"name": "Berlin",
"resource_name": "geoTargetConstants/1003854"
}
],
"language": "de",
"created_date": "2026-09-14T10:02:00Z",
"launched_at": "2026-09-14T10:20:00Z"
}Get Google Ads campaign launch draft
Returns a Performance Max campaign the builder chat prepared for someone to review before launch.
The chat saves a draft when you ask it to set up a campaign and choose a budget. It holds the copy, pictures, budget and locations as the chat left them. Nothing in it is checked against Google until launch, so a draft can be incomplete: a missing logo or landing page is common. Review it, fill in what is missing, and use its fields to build the request for Launch Google Ads campaign.
launched_at only records a launch from the draft’s review page in the builder. Launching through the API doesn’t mark the draft, so launched_at stays null and nothing stops the same draft from being launched again. Keep track of which drafts you have launched yourself.
Only a draft for the app in the path is returned. Any other ID returns a 404.
This is limited to 120 requests a minute per app, shared with List Google Ads advertising languages. Some workspaces have a different limit.
curl --request GET \
--url https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/google-ads/campaign-launch-drafts/{draft_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "68c2d1e5f8a92e004d56b2a3",
"app_id": "6820f3a4e7b91d003c45a1f2",
"campaign_name": "Spring sale in Berlin",
"business_name": "Oakline Furniture",
"landing_page_url": "https://oakline.base44.app",
"phone_number": "+493012345678",
"daily_budget_micros": 15000000,
"currency_code": "EUR",
"headlines": [
"Handmade oak tables",
"Built in Berlin"
],
"long_headlines": [
"Solid oak dining tables, made to order in Berlin"
],
"descriptions": [
"Visit our showroom or order online with free delivery."
],
"images": [
{
"field_type": "MARKETING_IMAGE",
"url": "https://storage.base44.com/gads-assets/b7f3a1c8-landscape.png"
}
],
"logos": [
{
"field_type": "MARKETING_IMAGE",
"url": "https://storage.base44.com/gads-assets/logo.png"
}
],
"geo_targets": [
"geoTargetConstants/1003854"
],
"targeted_locations": [
{
"name": "Berlin",
"resource_name": "geoTargetConstants/1003854"
}
],
"language": "de",
"created_date": "2026-09-14T10:02:00Z",
"launched_at": "2026-09-14T10:20:00Z"
}Authorizations
Personal access token, sent as Authorization: Bearer <token>.
Path Parameters
ID of the app to advertise.
ID of the draft. The builder chat returns it as draft_id when it saves a launch draft, and its review link carries it as ?draft=.
Response
The draft as the builder chat saved it.
A Performance Max campaign the builder chat prepared for review.
ID of the draft.
"68c2d1e5f8a92e004d56b2a3"
ID of the app the draft is for.
"6820f3a4e7b91d003c45a1f2"
Name for the campaign. Empty when the chat did not choose one.
"Spring sale in Berlin"
Business name to show in the ads. Empty when the chat did not set one.
"Oakline Furniture"
Page the ads send clicks to. Empty when the chat did not set one.
"https://oakline.base44.app"
Phone number for a call button, in a form Google can place. Empty when there is none, including when the chat suggested a number Google couldn't place.
"+493012345678"
Daily budget in micros of currency_code, so 15000000 is 15.00.
15000000
Currency of daily_budget_micros, the currency the account is charged in, as a three-letter ISO 4217 code. It can differ from the currency of the Google Ads account's own budget.
"EUR"
Headlines, up to 15.
["Handmade oak tables", "Built in Berlin"]
Long headlines, up to 5.
[
"Solid oak dining tables, made to order in Berlin"
]
Descriptions, up to 5.
[
"Visit our showroom or order online with free delivery."
]
Pictures for the campaign, up to 20.
Show child attributes
Show child attributes
[
{
"field_type": "MARKETING_IMAGE",
"url": "https://storage.base44.com/gads-assets/b7f3a1c8-landscape.png"
}
]
Logos, up to 5. Often empty, and a Performance Max campaign needs one to launch.
Show child attributes
Show child attributes
[
{
"field_type": "MARKETING_IMAGE",
"url": "https://storage.base44.com/gads-assets/logo.png"
}
]
Locations to target, as Google geo target constants. Empty means everywhere.
["geoTargetConstants/1003854"]
The same locations as geo_targets, with their names.
Show child attributes
Show child attributes
[
{
"name": "Berlin",
"resource_name": "geoTargetConstants/1003854"
}
]
Two-letter code of the language the ads are written in.
"de"
When the chat saved the draft.
"2026-09-14T10:02:00Z"
When someone launched a campaign from this draft's review page in the builder, or null while nobody has. Launching through the API doesn't set it.
"2026-09-14T10:20:00Z"
Was this page helpful?