curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"channel_type": "PERFORMANCE_MAX",
"asset_field_types": [
"HEADLINE",
"DESCRIPTION"
],
"final_url": "https://example.com/spring"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text"
payload = {
"channel_type": "PERFORMANCE_MAX",
"asset_field_types": ["HEADLINE", "DESCRIPTION"],
"final_url": "https://example.com/spring"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
channel_type: 'PERFORMANCE_MAX',
asset_field_types: ['HEADLINE', 'DESCRIPTION'],
final_url: 'https://example.com/spring'
})
};
fetch('https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text', 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/assets/generate-text",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'channel_type' => 'PERFORMANCE_MAX',
'asset_field_types' => [
'HEADLINE',
'DESCRIPTION'
],
'final_url' => 'https://example.com/spring'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text"
payload := strings.NewReader("{\n \"channel_type\": \"PERFORMANCE_MAX\",\n \"asset_field_types\": [\n \"HEADLINE\",\n \"DESCRIPTION\"\n ],\n \"final_url\": \"https://example.com/spring\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"channel_type\": \"PERFORMANCE_MAX\",\n \"asset_field_types\": [\n \"HEADLINE\",\n \"DESCRIPTION\"\n ],\n \"final_url\": \"https://example.com/spring\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"channel_type\": \"PERFORMANCE_MAX\",\n \"asset_field_types\": [\n \"HEADLINE\",\n \"DESCRIPTION\"\n ],\n \"final_url\": \"https://example.com/spring\"\n}"
response = http.request(request)
puts response.read_body{
"session_id": "9c1d2e3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
"assets": [],
"language": "de",
"in_flight": true
}Generate Google Ads text assets
Writes ad copy for the app and returns it as previews.
Nothing reaches Google Ads here. Each line comes back with a session_asset_id you pass to Accept a generated Google Ads asset to put it on a live campaign. Use Generate Google Ads assets instead when you want copy and pictures in one call.
Pick the lines you want with asset_field_types. SEARCH campaigns do not take LONG_HEADLINE, so Google rejects that combination.
Grounding is flexible here, unlike image generation. You may send final_url and freeform_prompt together, and sending neither grounds the copy in the app’s own home page.
The copy is written in language_code when you send it, then in the campaign’s language when you send campaign_id, and otherwise in the language of the app’s own site. The response reports which one in language.
in_flight set to true, that run’s session_id, and an empty assets. Poll the session_id you were given rather than retrying.This endpoint costs 2 of 20 copy requests a minute per app, shared with the other Google Ads endpoints that write copy, and up to 4 when the retry below happens.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"channel_type": "PERFORMANCE_MAX",
"asset_field_types": [
"HEADLINE",
"DESCRIPTION"
],
"final_url": "https://example.com/spring"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text"
payload = {
"channel_type": "PERFORMANCE_MAX",
"asset_field_types": ["HEADLINE", "DESCRIPTION"],
"final_url": "https://example.com/spring"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
channel_type: 'PERFORMANCE_MAX',
asset_field_types: ['HEADLINE', 'DESCRIPTION'],
final_url: 'https://example.com/spring'
})
};
fetch('https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text', 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/assets/generate-text",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'channel_type' => 'PERFORMANCE_MAX',
'asset_field_types' => [
'HEADLINE',
'DESCRIPTION'
],
'final_url' => 'https://example.com/spring'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text"
payload := strings.NewReader("{\n \"channel_type\": \"PERFORMANCE_MAX\",\n \"asset_field_types\": [\n \"HEADLINE\",\n \"DESCRIPTION\"\n ],\n \"final_url\": \"https://example.com/spring\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"channel_type\": \"PERFORMANCE_MAX\",\n \"asset_field_types\": [\n \"HEADLINE\",\n \"DESCRIPTION\"\n ],\n \"final_url\": \"https://example.com/spring\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/google-ads/assets/generate-text")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"channel_type\": \"PERFORMANCE_MAX\",\n \"asset_field_types\": [\n \"HEADLINE\",\n \"DESCRIPTION\"\n ],\n \"final_url\": \"https://example.com/spring\"\n}"
response = http.request(request)
puts response.read_body{
"session_id": "9c1d2e3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
"assets": [],
"language": "de",
"in_flight": true
}Authorizations
Personal access token, sent as Authorization: Bearer <token>. Each operation lists the permission it needs: read_only or full_access. A full-access token can call every operation. A read-only token can call only the operations that list read_only; anything else returns 403 read_only_credential_route_not_allowed.
Path Parameters
ID of the app whose Google Ads creative you want to generate or read.
Body
Campaign type the copy is for, one of PERFORMANCE_MAX, DEMAND_GEN, SEARCH or DISPLAY.
"PERFORMANCE_MAX"
Which kinds of line to write, from HEADLINE, LONG_HEADLINE or DESCRIPTION. Send between one and three entries. An image field type here is rejected with a 422.
One of HEADLINE, LONG_HEADLINE or DESCRIPTION.
["HEADLINE", "DESCRIPTION"]
Page to base the copy on. Unlike image generation you may send this together with freeform_prompt, and sending neither grounds the copy in the app's own home page.
"https://example.com/spring"
What the copy should say, in your own words, up to 1500 characters.
"Lead with free delivery across Germany"
Keywords to work into the copy. Send between 1 and 15 of them, and none of them blank. Omit the field entirely rather than sending an empty list.
1 - 15 elementsOne keyword. It must not be blank or whitespace only.
["oak furniture", "handmade table"]
Two-letter code of the language to write the copy in, for example de. A regional tag such as pt-BR is reduced to pt. Omit it to use the campaign's language when you send campaign_id, and otherwise the language of the app's own site. A language Google Ads doesn't support returns a 400.
"de"
The id of a campaign from List campaigns whose language to write in when you don't send language_code. Nothing is attached to the campaign.
"6886b8d390dc7e2f4a2c91b3"
Set to true for a quick replacement of one line. The copy comes back in seconds and counts as one copy request instead of two, at somewhat lower quality. Several lines can still come back, so use the first.
true
The session_id of an earlier generation to add these previews to. List Google Ads generated assets returns the combined set for an hour. Omit it to start a new generation.
"3f9c2a7b8d1e4f6a9b0c1d2e3f4a5b6c"
Response
The copy that was generated.
The copy one text generation produced.
ID of this generation. Pass it as session_id to List Google Ads generated assets, or to Accept a generated Google Ads asset with one of the returned session_asset_id values.
"9c1d2e3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f"
The copy that was generated, one entry per line. Empty when the engine produced nothing and when a generation for this app was already running, which in_flight tells apart.
Show child attributes
Show child attributes
[]
Language the copy was written in, as a lowercase two-letter code: language_code when you sent it, then the campaign's language when you sent campaign_id, and otherwise the language of the app's own site. The field is absent on a lock-miss response unless you sent language_code or campaign_id.
"de"
Present and true only when a text generation for this app was already running, in which case session_id is that run's and assets is empty. Poll the returned session_id rather than retrying. The field is absent on every other response.
true
Was this page helpful?