curl --request PUT \
--url https://app.base44.com/api/apps/{app_id}/entity-schemas \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"entityNameToSchema": {
"Invoice": {
"name": "Invoice",
"properties": {
"amount": {
"description": "Total amount in cents",
"type": "number"
},
"status": {
"enum": [
"draft",
"sent",
"paid"
],
"type": "string"
}
},
"required": [
"amount"
],
"rls": {
"read": {
"created_by": "{{user.email}}"
}
},
"type": "object"
}
}
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/entity-schemas"
payload = { "entityNameToSchema": { "Invoice": {
"name": "Invoice",
"properties": {
"amount": {
"description": "Total amount in cents",
"type": "number"
},
"status": {
"enum": ["draft", "sent", "paid"],
"type": "string"
}
},
"required": ["amount"],
"rls": { "read": { "created_by": "{{user.email}}" } },
"type": "object"
} } }
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
entityNameToSchema: {
Invoice: {
name: 'Invoice',
properties: {
amount: {description: 'Total amount in cents', type: 'number'},
status: {enum: ['draft', 'sent', 'paid'], type: 'string'}
},
required: ['amount'],
rls: {read: {created_by: '{{user.email}}'}},
type: 'object'
}
}
})
};
fetch('https://app.base44.com/api/apps/{app_id}/entity-schemas', 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}/entity-schemas",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'entityNameToSchema' => [
'Invoice' => [
'name' => 'Invoice',
'properties' => [
'amount' => [
'description' => 'Total amount in cents',
'type' => 'number'
],
'status' => [
'enum' => [
'draft',
'sent',
'paid'
],
'type' => 'string'
]
],
'required' => [
'amount'
],
'rls' => [
'read' => [
'created_by' => '{{user.email}}'
]
],
'type' => 'object'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"api_key: <api-key>"
],
]);
$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}/entity-schemas"
payload := strings.NewReader("{\n \"entityNameToSchema\": {\n \"Invoice\": {\n \"name\": \"Invoice\",\n \"properties\": {\n \"amount\": {\n \"description\": \"Total amount in cents\",\n \"type\": \"number\"\n },\n \"status\": {\n \"enum\": [\n \"draft\",\n \"sent\",\n \"paid\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"amount\"\n ],\n \"rls\": {\n \"read\": {\n \"created_by\": \"{{user.email}}\"\n }\n },\n \"type\": \"object\"\n }\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("api_key", "<api-key>")
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.put("https://app.base44.com/api/apps/{app_id}/entity-schemas")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"entityNameToSchema\": {\n \"Invoice\": {\n \"name\": \"Invoice\",\n \"properties\": {\n \"amount\": {\n \"description\": \"Total amount in cents\",\n \"type\": \"number\"\n },\n \"status\": {\n \"enum\": [\n \"draft\",\n \"sent\",\n \"paid\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"amount\"\n ],\n \"rls\": {\n \"read\": {\n \"created_by\": \"{{user.email}}\"\n }\n },\n \"type\": \"object\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/entity-schemas")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityNameToSchema\": {\n \"Invoice\": {\n \"name\": \"Invoice\",\n \"properties\": {\n \"amount\": {\n \"description\": \"Total amount in cents\",\n \"type\": \"number\"\n },\n \"status\": {\n \"enum\": [\n \"draft\",\n \"sent\",\n \"paid\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"amount\"\n ],\n \"rls\": {\n \"read\": {\n \"created_by\": \"{{user.email}}\"\n }\n },\n \"type\": \"object\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"created": [
"Invoice"
],
"updated": [
"Customer"
],
"deleted": [
"LegacyOrder"
],
"warnings": [
"Invalid RLS rule in Invoice: \"properties.total.rls.delete\" - field-level delete rules are not enforced - delete removes the whole record (there is no field-level delete gate); put the restriction in a top-level rls.delete instead"
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Sync entity schemas
Replaces the app’s entire set of entities with the one you send, in a single call. This is what a deploy uses to make the app’s live schema match its source.
entityNameToSchema is deleted. Include User to keep its custom fields; leaving it out drops them.The response reports what changed, split into created, updated, and deleted. It also carries warnings for problems Base44 accepted instead of rejecting, so a 200 with a non-empty warnings means the sync applied but something in it is not doing what it looks like.
This endpoint is only available for apps whose source code you manage yourself. On an app whose code Base44 generates, it returns a 428. An entity that still has records cannot be deleted, so a sync that drops such an entity returns a 428 and changes nothing.
apps:deploy scope.curl --request PUT \
--url https://app.base44.com/api/apps/{app_id}/entity-schemas \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"entityNameToSchema": {
"Invoice": {
"name": "Invoice",
"properties": {
"amount": {
"description": "Total amount in cents",
"type": "number"
},
"status": {
"enum": [
"draft",
"sent",
"paid"
],
"type": "string"
}
},
"required": [
"amount"
],
"rls": {
"read": {
"created_by": "{{user.email}}"
}
},
"type": "object"
}
}
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/entity-schemas"
payload = { "entityNameToSchema": { "Invoice": {
"name": "Invoice",
"properties": {
"amount": {
"description": "Total amount in cents",
"type": "number"
},
"status": {
"enum": ["draft", "sent", "paid"],
"type": "string"
}
},
"required": ["amount"],
"rls": { "read": { "created_by": "{{user.email}}" } },
"type": "object"
} } }
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
entityNameToSchema: {
Invoice: {
name: 'Invoice',
properties: {
amount: {description: 'Total amount in cents', type: 'number'},
status: {enum: ['draft', 'sent', 'paid'], type: 'string'}
},
required: ['amount'],
rls: {read: {created_by: '{{user.email}}'}},
type: 'object'
}
}
})
};
fetch('https://app.base44.com/api/apps/{app_id}/entity-schemas', 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}/entity-schemas",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'entityNameToSchema' => [
'Invoice' => [
'name' => 'Invoice',
'properties' => [
'amount' => [
'description' => 'Total amount in cents',
'type' => 'number'
],
'status' => [
'enum' => [
'draft',
'sent',
'paid'
],
'type' => 'string'
]
],
'required' => [
'amount'
],
'rls' => [
'read' => [
'created_by' => '{{user.email}}'
]
],
'type' => 'object'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"api_key: <api-key>"
],
]);
$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}/entity-schemas"
payload := strings.NewReader("{\n \"entityNameToSchema\": {\n \"Invoice\": {\n \"name\": \"Invoice\",\n \"properties\": {\n \"amount\": {\n \"description\": \"Total amount in cents\",\n \"type\": \"number\"\n },\n \"status\": {\n \"enum\": [\n \"draft\",\n \"sent\",\n \"paid\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"amount\"\n ],\n \"rls\": {\n \"read\": {\n \"created_by\": \"{{user.email}}\"\n }\n },\n \"type\": \"object\"\n }\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("api_key", "<api-key>")
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.put("https://app.base44.com/api/apps/{app_id}/entity-schemas")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"entityNameToSchema\": {\n \"Invoice\": {\n \"name\": \"Invoice\",\n \"properties\": {\n \"amount\": {\n \"description\": \"Total amount in cents\",\n \"type\": \"number\"\n },\n \"status\": {\n \"enum\": [\n \"draft\",\n \"sent\",\n \"paid\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"amount\"\n ],\n \"rls\": {\n \"read\": {\n \"created_by\": \"{{user.email}}\"\n }\n },\n \"type\": \"object\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/entity-schemas")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityNameToSchema\": {\n \"Invoice\": {\n \"name\": \"Invoice\",\n \"properties\": {\n \"amount\": {\n \"description\": \"Total amount in cents\",\n \"type\": \"number\"\n },\n \"status\": {\n \"enum\": [\n \"draft\",\n \"sent\",\n \"paid\"\n ],\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"amount\"\n ],\n \"rls\": {\n \"read\": {\n \"created_by\": \"{{user.email}}\"\n }\n },\n \"type\": \"object\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"created": [
"Invoice"
],
"updated": [
"Customer"
],
"deleted": [
"LegacyOrder"
],
"warnings": [
"Invalid RLS rule in Invoice: \"properties.total.rls.delete\" - field-level delete rules are not enforced - delete removes the whole record (there is no field-level delete gate); put the restriction in a top-level rls.delete instead"
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
Personal API key.
Path Parameters
ID of the app whose entity schemas you want.
Body
The app's complete set of entities, keyed by entity name. Each value is that entity's JSON Schema. Any entity the app currently has and this map does not is deleted.
Show child attributes
Show child attributes
{
"Invoice": {
"name": "Invoice",
"properties": {
"amount": {
"description": "Total amount in cents",
"type": "number"
},
"status": {
"enum": ["draft", "sent", "paid"],
"type": "string"
}
},
"required": ["amount"],
"rls": {
"read": { "created_by": "{{user.email}}" }
},
"type": "object"
}
}
Response
What the sync created, updated, and deleted, plus any warnings.
Entities that did not exist before and were added.
["Invoice"]
Entities that already existed and were replaced.
["Customer"]
Entities the app had and the request left out, which were removed.
["LegacyOrder"]
Problems Base44 accepted rather than rejected. Currently these are row-level security rules it cannot enforce on an entity that has no previous version, which a deploy usually carried over rather than wrote. The sync still applied.
[
"Invalid RLS rule in Invoice: \"properties.total.rls.delete\" - field-level delete rules are not enforced - delete removes the whole record (there is no field-level delete gate); put the restriction in a top-level rls.delete instead"
]
Was this page helpful?