---
title: "Apply SEO fix"
method: POST
path: "/api/apps/{app_id}/seo/fix"
---

# Apply SEO fix

`POST /api/apps/{app_id}/seo/fix`

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

Applies the fix for one check from an SEO scan and returns what it did.

Get the checks from [Run SEO scan](/api-reference/run-seo-scan) or [Get last SEO scan](/api-reference/get-last-seo-scan). Each check Base44 can act on carries a `fix_action`. Send its `type` as `fix_type` and its `params` as `params`.

These actions change the app's SEO settings. Each one replaces the value it sets, including a value someone edited by hand:
- `enable_llms_txt` turns on the generated `/llms.txt`.
- `enable_ai_crawlers` allows known AI crawlers in the generated `robots.txt`.
- `generate_json_ld` replaces `custom_json_ld` with markup generated from the app's entities.
- `generate_page_meta` replaces the title and description of every page except the home page. Each page keeps its `noindex` and `og_image` values.
- `generate_website_schema`, `generate_organization_schema` and `generate_faq_schema` replace the saved WebSite, Organization and FAQPage markup.
- `generate_breadcrumb_schema` turns on `synthesized_breadcrumb_enabled` and deletes the saved `breadcrumb_schema`.
- `generate_canonical` sets `canonical_url` to the app's current URL.

These actions change the app itself:
- `generate_description` replaces the app's description with one an AI model writes from the app's name, pages and entities. When the model's answer doesn't pass Base44's length and wording checks, Base44 saves a description built from a template instead.
- `suggest_shorter_title` shortens an app name longer than 60 characters to 57 or fewer, cutting at a word boundary. A name of 60 characters or fewer is left as it is.

The rest change nothing. `set_app_title`, `edit_app_description`, `edit_public_access`, `open_seo_advanced`, `set_og_image`, `connect_domain`, `edit_slug`, `enable_https` and `publish_app` return a `redirect` naming the builder screen where the app's owner makes the fix. `fix_with_ai` marks a check that needs a change to the app's code, which the builder makes by sending the action's `params.prompt` to the app's AI chat.

No action edits the app's code, creates a checkpoint or uses the workspace's credits.

A call can succeed and still report `success` as `false` when the action had nothing to apply, such as `generate_json_ld` on an app with no entity Base44 can match to a Schema.org type.

Calling an action again applies it again. Most land on the same result every time, but `generate_description` writes a new description on each call.

Saving itself is immediate. The live site is served from a separate copy, which is updated right after, but that update isn't guaranteed to happen in the same moment and can lag. A successful call means the change is stored, not that the live site has caught up.

This is limited to 30 requests a minute per caller for each app, shared with the app's other SEO endpoints. Some workspaces have a different limit.

<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 `fix_type` values documented here. Other values are not supported and their behavior can change.</Warning>

## Path parameters

- `app_id` string, required — ID of the app to fix.

## Request body

- object
  - `fix_type` 'enable_llms_txt' | 'enable_ai_crawlers' | 'generate_json_ld' | 'generate_page_meta' | 'generate_website_schema' | 'generate_organization_schema' | 'generate_faq_schema' | 'generate_breadcrumb_schema' | 'generate_canonical' | 'generate_description' | 'suggest_shorter_title' | 'set_app_title' | 'edit_app_description' | 'edit_public_access' | 'open_seo_advanced' | 'set_og_image' | 'connect_domain' | 'edit_slug' | 'enable_https' | 'publish_app' | 'fix_with_ai', required — Action to apply, the `type` of a check's `fix_action` in [Get last SEO scan](/api-reference/get-last-seo-scan).
  - `params` object — Arguments for the action, the `params` of the same `fix_action`, sent as they are. Defaults to an empty object.

## Response `200`

What the action did.

- SEOFixResponse — The outcome of a fix action.
  - `result` SEOFixResult, required — What one fix action did.
    - `success` boolean, required — Whether the action was applied. It's `false` when the action had nothing to apply, and `message` says why.
    - `message` string, required — What the action did, written for the app's owner.
    - `redirect` 'overview' | 'app-settings' | 'seo-meta-tags' | 'domains' | 'publish', nullable — Builder screen where the app's owner makes this fix: `"overview"`, `"app-settings"`, `"seo-meta-tags"`, `"domains"`, or `"publish"`. The key is present only for the actions that change nothing.

## Other responses

- `400` — `fix_type` isn't an action Base44 knows.
- `401` — Missing or invalid credentials.
- `403` — You don't have access to this app, you used a workspace API key, or you used a read-only personal access token. These endpoints accept a user's credentials only, and none of them accept a read-only credential, including the ones that only read.
- `404` — App not found.
- `422` — The body is missing or isn't a JSON object, `fix_type` is missing or isn't a string, or `params` isn't an object.
- `429` — Rate limit exceeded. The base limit is 30 requests per minute, shared with the app's other SEO endpoints. See [Rate limits](/developers/references/apps-api/get-started/rate-limits) for the multiplier your plan gets.

## Changes

- **2026-09-30** `63675fa5257c` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/idealspot/apis/base44-app-management-api/changes/api/apps/:app_id/seo/fix/post.md)

---

[API](https://skmtc.dev/idealspot/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/idealspot/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc.dev/idealspot/apis/base44-app-management-api/revisions/e58d4ff7b1f8?raw)
