Restore checkpoint

Changed on

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

Returns the app to a saved checkpoint and answers with the restored app.

Restoring rolls the app's code back to the checkpoint's commit, redeploys its backend functions from that code, restores the entity schemas the checkpoint saved, and rewinds the app's chat history to the point the checkpoint was taken.

<Note>A 200 does not confirm that every backend function redeployed. A function whose deployment fails is recorded and skipped rather than failing the restore, so an app that depends on its functions is worth checking afterwards.</Note>

<Warning>The chat messages after the checkpoint are dropped from the conversation and do not come back. The code does come back: a restore deletes no checkpoints, so every version stays in List checkpoints and restoring a later one returns the code you rolled back from.</Warning>

The work happens while you wait, and there is a lot of it: a code rollback, a redeploy per backend function, and a schema sync. Allow for that in your client's timeout. The app's status is processing for the duration and ready once the restore finishes, so if your request times out, poll Get app instead of sending this again.

Restoring the checkpoint the app is already on is not a no-op. There is no shortcut for that case: the rollback, the redeploy and the sync all run again.

Set branch_id to restore one of a branch's checkpoints. Only the branch changes: its code, the backend functions it owns, and its chat. Its entity schemas are rebuilt from the restored code rather than from the checkpoint, and a 200 doesn't confirm that rebuild either. On a branch, the response is main's app rather than the branch, so watch the branch's run_state in Get branch instead of the app's status.

<Note>This endpoint accepts a personal API key. A read-only key is refused, and workspace API keys are not accepted.</Note>

post/api/apps/{app_id}/app-checkpoints/{checkpoint_id}/load

Request

  • Base URL: https://app.base44.com
  • URL: https://app.base44.com/api/apps/{app_id}/app-checkpoints/{checkpoint_id}/load
  • Auth: HTTP bearer

Path parameters

checkpoint_idstring required

ID of the checkpoint, as returned in id by List checkpoints.

app_idstring required

ID of the app.

Query parameters

branch_idstring

ID of the branch to work on, as returned by List branches. Omit it to work on the app's main branch.

Response

The app, as restored to the checkpoint. With branch_id, main's app, which the branch restore doesn't change.

idstring

ID of the app.

created_datestring date-time

Time the app was created, as a UTC timestamp in ISO 8601 format.

updated_datestring date-time

Time the app document was last written, as a UTC timestamp in ISO 8601 format.

created_bystring nullable

Email of the user who created the app.

organization_idstring nullable

ID of the workspace the app belongs to.

app_typestring

Kind of app, set when it's created. One of user_app (a web app), user_agent (an AI agent), mobile_app (a native mobile app), user_game (a game), slide (a presentation), or imported_app (an app imported from an existing code repository). List apps returns it as stored, so an older agent app can report agent instead of user_agent, and some older apps don't include it. Get app always returns one of the values above.

namestring

Display name of the app.

user_descriptionstring nullable

Description of the app, or null if none was set. An app created without a name gets a generated description once a build turn changes it.

logo_urlstring nullable

URL of the app's logo, or null if it has none. Set it with Set app logo or Generate app logo.

social_image_urlstring nullable

URL of the image shown when the app is shared on social platforms, or null if none was set, in which case the logo is shown instead. Set it with Set social image.

public_settings'private_with_login' | 'public_with_login' | 'public_without_login' | 'workspace_with_login'

Who can open the published app. Each value is described under Update app, which also changes it.

hide_entity_created_byboolean

Whether the app's entity records leave out the email of the user who created each one (created_by). Newer apps always leave the email out, whatever this is set to.

is_remixableboolean

Whether others can remix the app. While it's true, the published app also shows the Base44 badge if public_settings is public_with_login or public_without_login.

main_branch_protectedboolean

Whether the app's main branch is protected, so changes to main must go through a branch that's merged back. Always true for imported apps. Change it with Set main branch protection.

slugstring nullable

URL slug for the app, auto generated from the name and app ID or set to a custom value, or null if the app has no slug yet. The published URL is built from it.

is_unpublishedboolean

Whether the app was taken offline with Unpublish app and hasn't been published again since. While it's true, the published URL is offline and last_deployed_at still shows the last publish.

last_deployed_atstring date-time nullable

Time the app was last published, as a UTC timestamp in ISO 8601 format, or null if it has never been published.

screenshot_urlstring nullable

URL of a screenshot of the published app. Captured shortly after each publish, so it can briefly lag or be null right after publishing.

preview_screenshot_urlstring nullable

URL of a preview screenshot taken before publishing, distinct from screenshot_url, or null if none has been captured.

owner_idstring nullable

ID of the user who owns the app. It starts as the creator and changes when ownership is transferred.

dev_environment_enabledboolean

Whether test data is on, which gives the app a test database next to its live one.

Example response

{
  "id": "6820f3a4e7b91d003c45a1f2",
  "created_date": "2026-08-01T09:15:00",
  "updated_date": "2026-08-02T14:30:00",
  "created_by": "developer@example.com",
  "organization_id": "67e0b12c4d8a3f005b21c9e4",
  "app_type": "user_app",
  "name": "My CRM",
  "user_description": "A CRM to track leads and deals",
  "logo_url": "https://storage.base44.com/6820f3a4e7b91d003c45a1f2/3f2504e0_logo.png",
  "social_image_url": "https://storage.base44.com/6820f3a4e7b91d003c45a1f2/7c9e6679_social.png",
  "public_settings": "public_with_login",
  "auth_config": {
    "enable_username_password": true,
    "enable_google_login": true
  },
  "hide_entity_created_by": true,
  "slug": "my-crm-3c45a1f2",
  "last_deployed_at": "2026-08-02T14:30:00",
  "screenshot_url": "https://storage.base44.com/screenshots/6820f3a4e7b91d003c45a1f2.png",
  "preview_screenshot_url": "https://storage.base44.com/previews/6820f3a4e7b91d003c45a1f2.png",
  "owner_id": "6706af53b9c1e2004a37d85f",
  "status": {
    "state": "ready",
    "details": "Publishing app",
    "request_id": "a1b2c3d4e5f67890abcdef12",
    "last_updated_date": "2026-08-02T14:30:00Z",
    "error_source": "build",
    "paywall_context": {
      "billing_organization_id": "67e0b12c4d8a3f005b21c9e4",
      "user_id": "6706af53b9c1e2004a37d85f",
      "evaluated_at": "2026-08-02T14:30:00Z"
    }
  }
}

Changes

    • breaking

      query request parameter branch_id list-of-types was narrowed by removing types null

    • info

      for the query request parameter branch_id, the type was generalized from no type to string

    • info

      added the new optional query request parameter branch_id

    • info

      added the non-success response with the status