curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Before refactoring the dashboard"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint"
payload = { "name": "Before refactoring the dashboard" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Before refactoring the dashboard'})
};
fetch('https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Before refactoring the dashboard'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint"
payload := strings.NewReader("{\n \"name\": \"Before refactoring the dashboard\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Before refactoring the dashboard\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Before refactoring the dashboard\"\n}"
response = http.request(request)
puts response.read_body{
"checkpoint_id": "6886b8d390dc7e2f4a2c91b3",
"name": "Before refactoring the dashboard",
"git_commit_hash": "4f9c1a7e8b2d3c5f6a0b1e2d3c4f5a6b7c8d9e0f"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Create a sandbox checkpoint
Saves the app’s current state as a checkpoint you can return to.
Every sandbox-bridge endpoint runs against the app’s live sandbox, the same filesystem the AI edits, so a change here is visible in the app editor immediately.
This is what makes sandbox work restorable. Writes through this API are committed to git but not checkpointed, and only checkpoints appear in the app editor’s version history: a Restore or Revert there rolls the app back to the last checkpoint and discards everything written after it. Take a checkpoint when you finish a unit of work and always before you stop, and one before a risky batch of edits so a bad change is one restore away. Pending writes are flushed first, so the checkpoint captures the sandbox as it stands.
Restore it with Restore checkpoint, and list what an app has with List checkpoints. Checkpoints created here show up alongside the ones the AI takes.
This endpoint is limited to 60 requests per minute per app, shared with the other sandbox-bridge endpoints that change files.
CREDITS_EXHAUSTED. Otherwise the bridge needs a Builder plan or higher on the app’s workspace, and answers 402 below that (PREMIUM_REQUIRED). Workspace API keys are not authorized and are rejected with a 403, and it is unavailable for agent apps. A personal API key works as-is. An OAuth access token needs the sandbox:write scope.extra_data.code alongside the human-readable message. Branch on the code rather than on the message text or the status.curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Before refactoring the dashboard"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint"
payload = { "name": "Before refactoring the dashboard" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Before refactoring the dashboard'})
};
fetch('https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Before refactoring the dashboard'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint"
payload := strings.NewReader("{\n \"name\": \"Before refactoring the dashboard\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Before refactoring the dashboard\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/sandbox-bridge/create_checkpoint")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Before refactoring the dashboard\"\n}"
response = http.request(request)
puts response.read_body{
"checkpoint_id": "6886b8d390dc7e2f4a2c91b3",
"name": "Before refactoring the dashboard",
"git_commit_hash": "4f9c1a7e8b2d3c5f6a0b1e2d3c4f5a6b7c8d9e0f"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
Personal access token, sent as Authorization: Bearer <token>. Each operation lists the permission it needs: read_only or full_access. A full-access token can call every operation. A read-only token can call only the operations that list read_only; anything else returns 403 read_only_credential_route_not_allowed.
Path Parameters
ID of the app whose sandbox to operate on.
Body
Response
The checkpoint that was created.
The checkpoint that was created.
ID of the checkpoint. Pass it as checkpoint_id to Restore checkpoint to come back to this state.
"6886b8d390dc7e2f4a2c91b3"
The checkpoint's title, either the name you sent or one Base44 generated.
"Before refactoring the dashboard"
The commit this checkpoint points at, or null when the app has no committed sandbox revision yet. A checkpoint without one still restores the app state Base44 captured.
"4f9c1a7e8b2d3c5f6a0b1e2d3c4f5a6b7c8d9e0f"
Was this page helpful?