curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/code/content/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"paths": [
"src/App.jsx",
"src/pages/Home.jsx"
],
"max_bytes": 1048576
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/code/content/batch"
payload = {
"paths": ["src/App.jsx", "src/pages/Home.jsx"],
"max_bytes": 1048576
}
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({paths: ['src/App.jsx', 'src/pages/Home.jsx'], max_bytes: 1048576})
};
fetch('https://app.base44.com/api/apps/{app_id}/code/content/batch', 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}/code/content/batch",
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([
'paths' => [
'src/App.jsx',
'src/pages/Home.jsx'
],
'max_bytes' => 1048576
]),
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}/code/content/batch"
payload := strings.NewReader("{\n \"paths\": [\n \"src/App.jsx\",\n \"src/pages/Home.jsx\"\n ],\n \"max_bytes\": 1048576\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}/code/content/batch")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"paths\": [\n \"src/App.jsx\",\n \"src/pages/Home.jsx\"\n ],\n \"max_bytes\": 1048576\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/code/content/batch")
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 \"paths\": [\n \"src/App.jsx\",\n \"src/pages/Home.jsx\"\n ],\n \"max_bytes\": 1048576\n}"
response = http.request(request)
puts response.read_body{
"files": {
"src/pages/Home.jsx": {
"content": "export default function Home() {\n return <h1>Home</h1>;\n}\n"
},
"src/pages/Missing.jsx": {
"error": "file_not_found"
}
}
}Get app code files
Returns the text of up to 32 files in the app’s source in one call.
Get paths from List app code files. files is keyed by each path as Base44 normalized it, so ./src/App.jsx comes back as src/App.jsx, and a path you send twice comes back once. Each file holds either its content or an error, so one unreadable file doesn’t fail the call. Only UTF-8 text files up to 5 MB can be read.
max_bytes caps the total size of the files returned. Files are read in the order you send them, and a file that would take the total over max_bytes comes back with the error batch_limit_exceeded and no content, while later files that still fit are read. Read the ones left out in another call. The other errors are file_not_found, file_too_large for a file over 5 MB, not_text for a folder or a file that isn’t UTF-8 text, file_forbidden, invalid_path and file_read_failed.
A path outside the app, the app root, the app’s .git folder and .agents/.env fail the whole call rather than a single file.
Reads come from the app’s live sandbox, the same files the app editor shows, including changes that haven’t been published yet. If no sandbox is running, the call starts one, so the first call after a quiet period takes noticeably longer than later ones.
Set branch_id to read a branch’s files instead of main’s. Each branch has its own sandbox, so the first read of a branch also takes longer. A merged branch can’t be read: the call returns a 409. On an app imported from GitHub, reading a merged branch can instead return the files as they were when the branch was created, so don’t rely on it there.
This is limited to 120 requests per minute per app for each workspace’s personal API keys, so every key in a workspace shares one allowance. Some workspaces have a different limit.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/code/content/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"paths": [
"src/App.jsx",
"src/pages/Home.jsx"
],
"max_bytes": 1048576
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/code/content/batch"
payload = {
"paths": ["src/App.jsx", "src/pages/Home.jsx"],
"max_bytes": 1048576
}
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({paths: ['src/App.jsx', 'src/pages/Home.jsx'], max_bytes: 1048576})
};
fetch('https://app.base44.com/api/apps/{app_id}/code/content/batch', 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}/code/content/batch",
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([
'paths' => [
'src/App.jsx',
'src/pages/Home.jsx'
],
'max_bytes' => 1048576
]),
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}/code/content/batch"
payload := strings.NewReader("{\n \"paths\": [\n \"src/App.jsx\",\n \"src/pages/Home.jsx\"\n ],\n \"max_bytes\": 1048576\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}/code/content/batch")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"paths\": [\n \"src/App.jsx\",\n \"src/pages/Home.jsx\"\n ],\n \"max_bytes\": 1048576\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/code/content/batch")
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 \"paths\": [\n \"src/App.jsx\",\n \"src/pages/Home.jsx\"\n ],\n \"max_bytes\": 1048576\n}"
response = http.request(request)
puts response.read_body{
"files": {
"src/pages/Home.jsx": {
"content": "export default function Home() {\n return <h1>Home</h1>;\n}\n"
},
"src/pages/Missing.jsx": {
"error": "file_not_found"
}
}
}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 code to read.
Query Parameters
ID of the branch to work on, as returned by List branches. Omit it to work on the app's main branch.
Body
The files to read.
Paths of up to 32 files, relative to the app root.
1 - 32 elements["src/App.jsx", "src/pages/Home.jsx"]
Most bytes of file text to return across all the files, up to 5242880 (5 MB).
x <= 52428801048576
Response
Each file's text, or why it couldn't be read.
The text of each file you asked for.
Each file, keyed by its path relative to the app root.
Show child attributes
Show child attributes
{
"src/pages/Home.jsx": {
"content": "export default function Home() {\n return <h1>Home</h1>;\n}\n"
},
"src/pages/Missing.jsx": { "error": "file_not_found" }
}
Was this page helpful?