curl --request PATCH \
--url https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": {
"status": "draft"
},
"data": {
"$set": {
"status": "sent"
}
}
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many"
payload = {
"query": { "status": "draft" },
"data": { "$set": { "status": "sent" } }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({query: {status: 'draft'}, data: {$set: {status: 'sent'}}})
};
fetch('https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many', 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}/entities/{entity_name}/update-many",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'query' => [
'status' => 'draft'
],
'data' => [
'$set' => [
'status' => 'sent'
]
]
]),
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}/entities/{entity_name}/update-many"
payload := strings.NewReader("{\n \"query\": {\n \"status\": \"draft\"\n },\n \"data\": {\n \"$set\": {\n \"status\": \"sent\"\n }\n }\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": {\n \"status\": \"draft\"\n },\n \"data\": {\n \"$set\": {\n \"status\": \"sent\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": {\n \"status\": \"draft\"\n },\n \"data\": {\n \"$set\": {\n \"status\": \"sent\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"updated": 42,
"has_more": false
}Update entity records by filter
Applies the same change to up to 500 records in one of the app’s entities that match a filter, and returns how many changed.
Send query, a filter written the same way as the q parameter of List entity records, and data, the change written as MongoDB update operators on the entity’s field names. For example, {"query": {"status": "draft"}, "data": {"$set": {"status": "sent"}}} marks every draft as sent. A field can appear in only one operator per call, and the operators you can use are:
$set,$unset, and$rename$inc,$mul,$min, and$max$currentDate$addToSet,$push, and$pull
The values aren’t checked against the entity’s schema, so a field the schema doesn’t declare, or a value of another type, is stored as sent.
Row-level security applies. The filter only reaches records the entity’s rls update rule lets you change, and the rest are left alone rather than failing the call. If a field-level rule refuses the change on any matching record, the call is rejected and no records change.
When more than 500 records match, 500 of them change and has_more is true. Call again to change the rest, with a filter that no longer matches the records you’ve already changed, as the draft filter in the example does. A filter that still matches them changes the same records again.
Repeating $set, $unset, $rename, $min, $max, $addToSet, or $pull leaves the records as the first call did, so it’s safe to retry. Repeating $inc, $mul, $push, or $currentDate applies the change a second time.
Unlike Update entity record, this doesn’t trigger the app’s webhooks, automations, or workflows.
curl --request PATCH \
--url https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": {
"status": "draft"
},
"data": {
"$set": {
"status": "sent"
}
}
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many"
payload = {
"query": { "status": "draft" },
"data": { "$set": { "status": "sent" } }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({query: {status: 'draft'}, data: {$set: {status: 'sent'}}})
};
fetch('https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many', 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}/entities/{entity_name}/update-many",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'query' => [
'status' => 'draft'
],
'data' => [
'$set' => [
'status' => 'sent'
]
]
]),
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}/entities/{entity_name}/update-many"
payload := strings.NewReader("{\n \"query\": {\n \"status\": \"draft\"\n },\n \"data\": {\n \"$set\": {\n \"status\": \"sent\"\n }\n }\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": {\n \"status\": \"draft\"\n },\n \"data\": {\n \"$set\": {\n \"status\": \"sent\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/entities/{entity_name}/update-many")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": {\n \"status\": \"draft\"\n },\n \"data\": {\n \"$set\": {\n \"status\": \"sent\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"updated": 42,
"has_more": false
}Authorizations
Personal access token, sent as Authorization: Bearer <token>.
Path Parameters
ID of the app that owns the entity.
Name of the entity, exactly as List entity schemas reports it. Don't pass User here. It doesn't fail, but it reads and writes a separate, disconnected set of records stored under that name, not the app's real user accounts, which are managed through their own endpoints.
Body
Response
How many records changed.
How many records a filtered update changed.
Always true. An update that doesn't happen returns an error instead.
true
Number of matching records the call changed. A record that already held the new values still counts, because its updated_date changes, and 0 means no record matched.
42
Whether more than 500 records matched, so only 500 of them were changed and more may be left.
false
Was this page helpful?