---
title: "Get last SEO scan"
method: GET
path: "/api/apps/{app_id}/seo/last-scan"
---

# Get last SEO scan

`GET /api/apps/{app_id}/seo/last-scan`

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

Returns the app's last SEO scan in full: its score and every check.

Same payload [Run SEO scan](/api-reference/run-seo-scan) returned when it ran, so poll this rather than re-scanning to re-read a result. It returns `null` until the app is scanned at least once, and the result is only as current as the last scan, so read `scanned_at` before acting on it. That is also the field to compare against [Get SEO score](/api-reference/get-seo-score): the score is stored separately, so the two can briefly answer from different scans.

This endpoint is limited to 30 requests per minute per app, and that budget is shared with the app's other SEO endpoints.

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time.</Warning>

## Path parameters

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

## Response `200`

The last scan, or `null` if the app has never been scanned.

- LastSEOScanResponse — The stored scan, wrapped in the field the endpoint returns it under.
  - `result` SEOScanReport — An SEO scan: its score and every check behind it.
    - `score` SEOOverallScore, required — The scan's score, overall and per category.
      - `overall` integer, required — Overall SEO score for the app, 0 to 100.
      - `grade` string, required — Letter grade for `overall`: `A`, `B`, `C`, `D` or `F`.
      - `categories` object — Per-category breakdown, keyed by the same category names the checks carry: `meta_tags`, `crawlability`, `structured_data`, `ai_discoverability` and `content_quality`. Base44 can add a category, so read the map rather than assuming these five. Every category in the map is scored, including one this scan ran no checks for, which scores 100 with all three counts at zero.
    - `checks` SEOCheckResult[] — The checks behind the score, in the order Base44 reports them. Not every check it ran: a failure that only restates an upstream one is dropped in favour of the root cause, so an unpublished or login-gated app returns the one gating failure rather than the dozen findings that follow from it.
      - `id` string, required — Identifier of the check. Stable across scans, but a check can be missing from a later scan rather than change status, because Base44 collapses cascading failures into their root cause.
      - `category` string, required — Which part of the score this check feeds: `meta_tags`, `crawlability`, `structured_data`, `ai_discoverability` or `content_quality`.
      - `title` string, required — Short name of the check, phrased for the finding rather than the subject, so it changes with `status`.
      - `status` 'pass' | 'warn' | 'fail', required — Outcome of the check. A `warn` scores 50 against the category and a `fail` scores 0. Not every check can return all three.
      - `description` string, required — What the check found, written for the app's owner.
      - `details` unknown[] — Supporting detail for the finding, usually one object per page or entity involved. The keys differ per check, so treat the entries as opaque.
        - unknown
      - `fix_action` SEOFixAction — The remedy Base44 offers for a check, for display.
        - `type` string, required — Identifier of the action the Base44 builder offers for this check.
        - `label` string, required — Label the builder shows on the button for this action.
        - `params` object — Arguments to pass with the action. Empty on every action a scan emits today; keep reading it rather than assuming it stays empty.
      - `info_only` boolean — `true` when the finding is environmental, such as DNS or hosting, and can't be resolved from inside the app.
    - `scanned_at` string, required — When the scan ran, as an ISO 8601 UTC timestamp.

## Other responses

- `401` — Missing or invalid credentials.
- `403` — You don't have access to this app, or you used a workspace API key. These endpoints accept a user's credentials only.
- `404` — App not found.
- `429` — Rate limit exceeded (30 requests per minute).

---

[API](https://skmtc.dev/base44/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/base44/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/base44/base44-app-management-api/revisions/173e4e9c63c2/schema)
