> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate Google Ads text assets

> <Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

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](/api-reference/accept-a-generated-google-ads-asset) to put it on a live campaign. Use [Generate Google Ads assets](/api-reference/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 the language of the app's own site, not the language you ask in, and the response reports which one in `language`.

<Note>Only one generation of each kind runs per app at a time. Calling this while one is running returns a 200 carrying `in_flight` set to `true`, that run's `session_id`, and an empty `assets`. Poll the `session_id` you were given rather than retrying.</Note>

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.

<Note>When Google refuses the page you pointed at, Base44 retries once on the app's own published URL, and that retry costs the same again. Pace requests against the doubled figure, not the single one, or a refusal-heavy app hits a 429 part-way through its own recovery.</Note>

<Note>Generating creative does not spend credits and is not billed. It is capped by rate limits instead, so a burst gets a 429 rather than a bill.</Note>

<Note>This endpoint accepts a personal API key. Workspace API keys are not authorized for it and are rejected with a 403.</Note>

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time. Send only the fields documented here. Other request fields are not supported and their behavior can change.</Warning>



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json post /api/apps/{app_id}/google-ads/assets/generate-text
openapi: 3.1.0
info:
  title: Base44 App Management API
  version: 1.0.0
servers:
  - url: https://app.base44.com
security:
  - ApiKeyAuth: []
paths:
  /api/apps/{app_id}/google-ads/assets/generate-text:
    post:
      summary: Generate Google Ads text assets
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        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](/api-reference/accept-a-generated-google-ads-asset) to put it on
        a live campaign. Use [Generate Google Ads
        assets](/api-reference/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 the language of the app's own site, not the
        language you ask in, and the response reports which one in `language`.


        <Note>Only one generation of each kind runs per app at a time. Calling
        this while one is running returns a 200 carrying `in_flight` set to
        `true`, that run's `session_id`, and an empty `assets`. Poll the
        `session_id` you were given rather than retrying.</Note>


        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.


        <Note>When Google refuses the page you pointed at, Base44 retries once
        on the app's own published URL, and that retry costs the same again.
        Pace requests against the doubled figure, not the single one, or a
        refusal-heavy app hits a 429 part-way through its own recovery.</Note>


        <Note>Generating creative does not spend credits and is not billed. It
        is capped by rate limits instead, so a burst gets a 429 rather than a
        bill.</Note>


        <Note>This endpoint accepts a personal API key. Workspace API keys are
        not authorized for it and are rejected with a 403.</Note>


        <Warning>The response includes fields beyond the ones documented here.
        Don't rely on undocumented response fields, as they can change at any
        time. Send only the fields documented here. Other request fields are not
        supported and their behavior can change.</Warning>
      operationId: >-
        generate_text_assets_api_apps__app_id__google_ads_assets_generate_text_post
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: >-
              ID of the app whose Google Ads creative you want to generate or
              read.
            title: App Id
          description: >-
            ID of the app whose Google Ads creative you want to generate or
            read.
          example: 6820f3a4e7b91d003c45a1f2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              title: GenerateTextAssets
              type: object
              properties:
                channel_type:
                  type: string
                  description: >-
                    Campaign type the copy is for, one of `PERFORMANCE_MAX`,
                    `DEMAND_GEN`, `SEARCH` or `DISPLAY`.
                  default: PERFORMANCE_MAX
                  example: PERFORMANCE_MAX
                asset_field_types:
                  type: array
                  description: >-
                    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.
                  items:
                    type: string
                    description: One of `HEADLINE`, `LONG_HEADLINE` or `DESCRIPTION`.
                    example: HEADLINE
                  default:
                    - HEADLINE
                    - DESCRIPTION
                  example:
                    - HEADLINE
                    - DESCRIPTION
                final_url:
                  type: string
                  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.
                  example: https://example.com/spring
                freeform_prompt:
                  type: string
                  description: >-
                    What the copy should say, in your own words, up to 1500
                    characters.
                  example: Lead with free delivery across Germany
                keywords:
                  type: array
                  description: >-
                    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.
                  items:
                    type: string
                    description: One keyword. It must not be blank or whitespace only.
                    example: oak furniture
                  minItems: 1
                  maxItems: 15
                  example:
                    - oak furniture
                    - handmade table
            example:
              channel_type: PERFORMANCE_MAX
              asset_field_types:
                - HEADLINE
                - DESCRIPTION
              final_url: https://example.com/spring
      responses:
        '200':
          description: The copy that was generated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateTextAssetsResult'
        '400':
          description: >-
            Google Ads rejected the generation request, for example a landing
            page it could not read. The response message carries Google's
            reason.
        '401':
          description: Missing or invalid credentials.
        '403':
          description: >-
            You don't have access to this app, the app does not exist, or you
            used a workspace API key. A missing app and an app you cannot reach
            are deliberately the same answer.
        '409':
          description: >-
            The request to Google Ads timed out after being sent. Nothing was
            attached to a campaign, so retrying is safe.
        '422':
          description: >-
            `asset_field_types` contains a value that is not a text field type,
            is empty, or has more than three entries; `keywords` is present but
            empty, longer than 15 entries, or contains a blank entry;
            `freeform_prompt` is longer than 1500 characters; or the channel is
            `SEARCH` and you asked for `LONG_HEADLINE`.
        '429':
          description: >-
            The app has used up one of the creative rate limits, either 20 copy
            requests a minute or 10 picture requests a minute. Retry later.
components:
  schemas:
    GenerateTextAssetsResult:
      properties:
        session_id:
          type: string
          title: Session Id
          description: >-
            ID of this generation. Pass it as `session_id` to [List Google Ads
            generated assets](/api-reference/list-google-ads-generated-assets),
            or to [Accept a generated Google Ads
            asset](/api-reference/accept-a-generated-google-ads-asset) with one
            of the returned `session_asset_id` values.
          example: 9c1d2e3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f
        assets:
          items:
            $ref: '#/components/schemas/GeneratedAssetSummary'
          type: array
          title: Assets
          description: >-
            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.
          example: []
        language:
          anyOf:
            - type: string
            - type: 'null'
          title: Language
          description: >-
            Language the copy was written in, as a lowercase two-letter code. It
            comes from the app's own site rather than from anything you send.
            The field is absent on a lock-miss response unless you asked for a
            specific campaign.
          example: de
        in_flight:
          anyOf:
            - type: boolean
            - type: 'null'
          title: In Flight
          description: >-
            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.
          example: true
      type: object
      required:
        - session_id
        - assets
      title: GenerateTextAssetsResult
      description: The copy one text generation produced.
    GeneratedAssetSummary:
      properties:
        session_asset_id:
          type: string
          title: Session Asset Id
          description: >-
            ID of this asset within the session. Pass it as `session_asset_id`
            to [Accept a generated Google Ads
            asset](/api-reference/accept-a-generated-google-ads-asset).
          example: b7f3a1c8-52d4-4a0e-9b31-2c6f0d8e4a19
        asset_field_type:
          type: string
          title: Asset Field Type
          description: >-
            Which slot on the ad this asset fills. Text assets are `HEADLINE`,
            `LONG_HEADLINE` or `DESCRIPTION`. Image assets are
            `MARKETING_IMAGE`, `SQUARE_MARKETING_IMAGE`,
            `PORTRAIT_MARKETING_IMAGE` or `TALL_PORTRAIT_MARKETING_IMAGE`.
          example: HEADLINE
        kind:
          type: string
          title: Kind
          description: Whether the asset is copy (`text`) or a picture (`image`).
          example: text
        text:
          anyOf:
            - type: string
            - type: 'null'
          title: Text
          description: The generated copy, or `null` on an image asset.
          example: Handmade oak furniture, built to last
        image_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Image Url
          description: >-
            URL of the generated picture, or `null` on a text asset. It is a
            Base44 preview URL, not a Google one, and it stops resolving once
            the asset is cleaned up.
          example: https://storage.base44.com/gads-assets/b7f3a1c8-square.png
        source:
          type: string
          title: Source
          description: >-
            Which engine wrote it. The value is `google` for Google's own asset
            generation and `inhouse` for the Base44 model that covers languages
            Google does not generate for, and that stands in when Google's call
            fails.
          example: google
        language:
          anyOf:
            - type: string
            - type: 'null'
          title: Language
          description: >-
            Language of a text asset as a lowercase two-letter code, or `null`
            on an image, because image assets carry no copy.
          example: de
        channel_type:
          type: string
          title: Channel Type
          description: >-
            Campaign type the asset was generated for, one of `SEARCH`,
            `PERFORMANCE_MAX`, `DISPLAY` or `DEMAND_GEN`.
          example: PERFORMANCE_MAX
        created_at:
          type: string
          format: date-time
          title: Created At
          description: When the asset was generated.
          example: '2026-08-25T14:05:00Z'
      type: object
      required:
        - session_asset_id
        - asset_field_type
        - kind
        - text
        - image_url
        - source
        - language
        - channel_type
        - created_at
      title: GeneratedAssetSummary
      description: One generated asset in a live generation session.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api_key
      description: Personal API key.

````