> ## 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 may include fields beyond the ones documented here. Don't use any undocumented fields, as they can change at any time.</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 may include fields beyond the ones documented
        here. Don't use any undocumented fields, as they can change at any
        time.</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: >-
            The image URL, and the content plan with the image saved on the
            post.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostImageResponse'
        '400':
          description: '`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
    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. `series` is a sequence to publish in order,
            `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.
            `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. `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.

````