> ## 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 a post image

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

Generates the image for a single post and saves it on the plan.

The post's own `image_prompt` wins over the `image_prompt` you send, so the request body only decides the prompt for a post that has none. To change an image that already exists, send `refinement_instruction`.

<Note>If the post already has an `image_url` and you send no `refinement_instruction`, the existing image is returned as-is. Nothing is generated and no credits are charged.</Note>

Generating an image costs 1 credit and fails with a 402 when the workspace is out of quota. Image generation is budgeted at up to 60 seconds per attempt, so use a client timeout above that.

This endpoint is limited to 12 requests per minute, separately from the other social content endpoints.

<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}/virality/posts/{post_id}/generate-image
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}/virality/posts/{post_id}/generate-image:
    post:
      summary: Generate a post image
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        Generates the image for a single post and saves it on the plan.


        The post's own `image_prompt` wins over the `image_prompt` you send, so
        the request body only decides the prompt for a post that has none. To
        change an image that already exists, send `refinement_instruction`.


        <Note>If the post already has an `image_url` and you send no
        `refinement_instruction`, the existing image is returned as-is. Nothing
        is generated and no credits are charged.</Note>


        Generating an image costs 1 credit and fails with a 402 when the
        workspace is out of quota. Image generation is budgeted at up to 60
        seconds per attempt, so use a client timeout above that.


        This endpoint is limited to 12 requests per minute, separately from the
        other social content endpoints.


        <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_image_api_api_apps__app_id__virality_posts__post_id__generate_image_post
      parameters:
        - name: post_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the post, as returned in the content plan. Must be a UUID.
            title: Post Id
          description: ID of the post, as returned in the content plan. Must be a UUID.
          example: 3f2504e0-4f89-11d3-9a0c-0305e82c3301
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app.
            title: App Id
          description: ID of the app.
          example: 6820f3a4e7b91d003c45a1f2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateImagePayload'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostImageResponse'
        '400':
          description: The `post_id` is not a UUID.
        '401':
          description: Missing or invalid credentials.
        '402':
          description: The workspace is out of credits.
        '403':
          description: >-
            You don't have editor access to this app, or you used a workspace
            API key.
        '404':
          description: >-
            App not found, the app has no content plan, the post isn't in it, or
            the social content feature is not enabled for your account.
        '409':
          description: A content plan is currently generating for this app.
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: Rate limit exceeded (12 requests per minute).
        '500':
          description: Generating or saving the image failed. Retry the request.
components:
  schemas:
    GenerateImagePayload:
      properties:
        image_prompt:
          type: string
          maxLength: 2000
          title: Image Prompt
          description: >-
            Prompt to generate the image from. Used only when the post carries
            no `image_prompt` of its own, which is the prompt the plan generated
            for it. Send the post's own `image_prompt` back if you want to be
            sure of what is used.
          example: A freelancer closing a laptop at a tidy desk, warm morning light
        refinement_instruction:
          anyOf:
            - type: string
              maxLength: 500
            - type: 'null'
          title: Refinement Instruction
          description: >-
            What to change about the existing image. Sending this regenerates
            the image even when the post already has one. The first 300
            characters are used.
          example: Make the lighting cooler and remove the coffee cup.
      type: object
      required:
        - image_prompt
      title: GenerateImagePayload
    PostImageResponse:
      properties:
        image_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Image Url
          description: URL of the post image.
          example: https://storage.base44.com/virality/3f2504e0.png
        plan:
          anyOf:
            - $ref: '#/components/schemas/ContentPlan'
            - type: 'null'
          description: The content plan, with this post's `image_url` set.
      type: object
      title: PostImageResponse
      description: The generated image for a post, and the plan it belongs to.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ContentPlan:
      properties:
        id:
          anyOf:
            - type: string
            - type: 'null'
          title: Id
          description: ID of the content plan.
          example: 8c1f9a2e-3b7d-4c5e-9f01-2a3b4c5d6e7f
        app_id:
          anyOf:
            - type: string
            - type: 'null'
          title: App Id
          description: ID of the app the plan belongs to.
          example: 6820f3a4e7b91d003c45a1f2
        strategy:
          anyOf:
            - $ref: '#/components/schemas/ContentStrategy'
            - type: 'null'
          description: The strategy and the per-platform posts.
        created_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Created At
          description: Time the plan was created, as an ISO 8601 timestamp.
          example: '2026-08-24T09:15:00+00:00'
        updated_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Updated At
          description: Time the plan last changed, as an ISO 8601 timestamp.
          example: '2026-08-24T10:02:00+00:00'
      type: object
      title: ContentPlan
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    ContentStrategy:
      properties:
        app_summary:
          anyOf:
            - type: string
            - type: 'null'
          title: App Summary
          description: Short summary of what the app does.
          example: A CRM for freelancers who want to track leads without a spreadsheet.
        marketing_approach:
          anyOf:
            - type: string
            - type: 'null'
          title: Marketing Approach
          description: >-
            The approach the content takes, extracted from the accepted
            strategy. Empty if the strategy text was empty when the plan was
            generated.
          example: Lead with the spreadsheet pain, then show the app solving it.
        platforms:
          items:
            $ref: '#/components/schemas/PlatformContentPlan'
          type: array
          title: Platforms
          description: One entry per platform you approved, in the order you sent them.
      type: object
      title: ContentStrategy
    PlatformContentPlan:
      properties:
        platform:
          anyOf:
            - $ref: '#/components/schemas/Platform'
            - type: 'null'
          description: Platform these posts are written for.
          example: instagram
        mode:
          anyOf:
            - $ref: '#/components/schemas/ContentMode'
            - type: 'null'
          description: >-
            How to read the posts. A `series` is a sequence to publish in order,
            and a `selection` is a set of alternatives to pick one from.
          example: series
        reasoning:
          anyOf:
            - type: string
            - type: 'null'
          title: Reasoning
          description: Why the content for this platform takes the shape it does.
          example: Instagram rewards a consistent series, so these build on each other.
        posts:
          items:
            $ref: '#/components/schemas/SocialPost'
          type: array
          title: Posts
          description: The generated posts for this platform.
      type: object
      title: PlatformContentPlan
    Platform:
      type: string
      enum:
        - x
        - instagram
        - tiktok
        - linkedin
        - reddit
        - facebook
      title: Platform
    ContentMode:
      type: string
      enum:
        - series
        - selection
      title: ContentMode
    SocialPost:
      properties:
        id:
          anyOf:
            - type: string
            - type: 'null'
          title: Id
          description: >-
            ID of the post. Pass it as `post_id` to [Refine a
            post](/api-reference/refine-a-post), [Update post
            content](/api-reference/update-post-content), and [Generate a post
            image](/api-reference/generate-a-post-image).
          example: 3f2504e0-4f89-11d3-9a0c-0305e82c3301
        platform:
          anyOf:
            - $ref: '#/components/schemas/Platform'
            - type: 'null'
          description: Platform the post is written for.
          example: instagram
        angle:
          anyOf:
            - $ref: '#/components/schemas/PostAngle'
            - type: 'null'
          description: Editorial angle the post takes.
          example: pain_point
        angle_label:
          anyOf:
            - type: string
            - type: 'null'
          title: Angle Label
          description: Human-readable label for the angle.
          example: Pain point
        post_number:
          anyOf:
            - type: integer
            - type: 'null'
          title: Post Number
          description: Position of this post within its platform's set, starting at 1.
          example: 1
        total_posts:
          anyOf:
            - type: integer
            - type: 'null'
          title: Total Posts
          description: Number of posts generated for this platform.
          example: 5
        suggested_day:
          anyOf:
            - type: integer
            - type: 'null'
          title: Suggested Day
          description: Suggested day to publish on, counted from the start of the campaign.
          example: 1
        rationale:
          anyOf:
            - type: string
            - type: 'null'
          title: Rationale
          description: Why this post works for this platform and angle.
          example: Opens on the spreadsheet frustration the audience already has.
        content:
          anyOf:
            - type: string
            - type: 'null'
          title: Content
          description: >-
            The post text, ready to publish. Change it with [Update post
            content](/api-reference/update-post-content).
          example: >-
            Still tracking leads in a spreadsheet? I built the thing I wanted
            instead.
        image_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Image Url
          description: >-
            URL of the post image, or `null` if no image was generated yet.
            Create one with [Generate a post
            image](/api-reference/generate-a-post-image).
          example: https://storage.base44.com/virality/3f2504e0.png
        image_prompt:
          anyOf:
            - type: string
            - type: 'null'
          title: Image Prompt
          description: >-
            Prompt used to generate the post image, or `null` if the post has
            none.
          example: A freelancer closing a laptop at a tidy desk, warm morning light
        hashtags:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Hashtags
          description: Suggested hashtags, without the leading `#`.
          example:
            - freelance
            - buildinpublic
        post_title:
          anyOf:
            - type: string
            - type: 'null'
          title: Post Title
          description: >-
            Title for platforms that use one, such as Reddit and LinkedIn, or
            `null` elsewhere.
          example: I built a CRM because spreadsheets kept losing my leads
        suggested_subreddits:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Suggested Subreddits
          description: Subreddits to consider for a Reddit post. Empty for other platforms.
          example:
            - r/freelance
            - r/SideProject
        launch_comment:
          anyOf:
            - type: string
            - type: 'null'
          title: Launch Comment
          description: >-
            First comment to post under the main post, or `null` if none was
            generated.
          example: Happy to answer questions about how it works.
        option_label:
          anyOf:
            - type: string
            - type: 'null'
          title: Option Label
          description: >-
            Label for this post when the platform's `mode` is `selection`, so
            you can tell the alternatives apart, or `null` in `series` mode.
          example: Direct and personal
        best_for_context:
          anyOf:
            - type: string
            - type: 'null'
          title: Best For Context
          description: >-
            When to prefer this option over the others, or `null` if not
            applicable.
          example: Best if your audience already knows you
      type: object
      title: SocialPost
    PostAngle:
      type: string
      enum:
        - pain_point
        - feature_demo
        - social_proof
        - trending_hook
        - user_story
        - before_after
      title: PostAngle
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api_key
      description: Personal API key.

````