Bulk Upsert Entries
curl --request POST \
--url https://api.example.com/shared-stores/{store_id}/entries/bulkimport requests
url = "https://api.example.com/shared-stores/{store_id}/entries/bulk"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/shared-stores/{store_id}/entries/bulk', 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://api.example.com/shared-stores/{store_id}/entries/bulk",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/shared-stores/{store_id}/entries/bulk"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/shared-stores/{store_id}/entries/bulk")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/shared-stores/{store_id}/entries/bulk")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyShared Stores
Bulk Upsert Entries
Create or replace as many as 5,000 entries in one request.
POST
/
shared-stores
/
{store_id}
/
entries
/
bulk
Bulk Upsert Entries
curl --request POST \
--url https://api.example.com/shared-stores/{store_id}/entries/bulkimport requests
url = "https://api.example.com/shared-stores/{store_id}/entries/bulk"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/shared-stores/{store_id}/entries/bulk', 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://api.example.com/shared-stores/{store_id}/entries/bulk",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/shared-stores/{store_id}/entries/bulk"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/shared-stores/{store_id}/entries/bulk")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/shared-stores/{store_id}/entries/bulk")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyThis page documents its request, success response, and error response fields in full.
The complete store cannot exceed 10,000 entries. Existing IDs are replaced and do not consume additional slots. If an ID occurs more than once in the request, the last occurrence wins.
This endpoint has no query parameters.
Request
Headers
| Header | Type | Required | Allowed value and meaning |
|---|---|---|---|
Authorization | string | Yes | Bearer <Mosaic API key>. The key’s organization must own the store. |
Content-Type | string | Yes | application/json. |
Path parameters
| Parameter | Type | Required | Allowed value and meaning |
|---|---|---|---|
store_id | UUID string | Yes | Mosaic-generated store.id that will own every entry in the request. |
curl -X POST \
"https://api.mosaic.so/shared-stores/11111111-1111-4111-8111-111111111111/entries/bulk" \
-H "Authorization: Bearer mk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"entries": [
{
"entry_id": "0689B",
"display_name": "Jordan Lee",
"metadata": { "age": 31, "market": "Austin" }
},
{
"entry_id": "0712C",
"display_name": "Taylor Kim",
"metadata": { "age": 28, "market": "Chicago" }
}
]
}'
JSON body
| Field | Type | Required | Possible values |
|---|---|---|---|
entries | array | Yes | Between 1 and 5,000 entry inputs. |
entries[].entry_id | string | Yes | Any non-empty store-scoped ID. Duplicate IDs are accepted; the last occurrence wins. |
entries[].display_name | string | Yes | Any non-empty label after surrounding whitespace is removed. |
entries[].metadata | JSON object | No | Any object up to 256 KB. Omitted or null becomes {}. |
Response
200 OK
{
"success": true,
"count": 2,
"entries": [
{
"entry_id": "0689B",
"display_name": "Jordan Lee",
"metadata": { "age": 31, "market": "Austin" },
"created_at": "2026-08-03T20:00:00Z"
},
{
"entry_id": "0712C",
"display_name": "Taylor Kim",
"metadata": { "age": 28, "market": "Chicago" },
"created_at": "2026-08-03T20:00:00Z"
}
]
}
| Field | Type | Meaning and possible values |
|---|---|---|
success | boolean | Always true in a 200 OK response. |
count | integer | Number of unique entry IDs written, from 1 to 5,000. When the request repeats an ID, that ID contributes 1 because its last occurrence wins. |
entries | array | Complete created or replaced entry objects. Contains exactly count items; array ordering is not an API contract. |
entries[] | object | One complete written entry. The object always contains every field listed below. |
entries[].entry_id | string | Caller-defined store-scoped ID from the request. Unique within this response after duplicate IDs are collapsed. |
entries[].display_name | string | Trimmed non-empty label from the last request occurrence for this ID. |
entries[].metadata | JSON object | Metadata from the last request occurrence for this ID. Always an object and never null; omitted or null request metadata becomes {}. May contain any JSON values and is limited to 256 KB per entry. |
entries[].created_at | ISO 8601 string | UTC initial-creation timestamp. Existing entries preserve their timestamp; new entries receive the time at which they were created. |
Error responses
| Status | Payload | Possible value |
|---|---|---|
400 Bad Request | { "error": "entries is required" } | entries is missing, is not an array, or is empty. |
400 Bad Request | { "error": "entries must include entry_id and display_name" } | An entry is missing a non-empty ID or display name. |
400 Bad Request | { "detail": "metadata must be a JSON object" } | Any metadata value is an array, string, number, or boolean. |
401 Unauthorized | { "detail": string } | detail is exactly Authorization header must start with Bearer, invalid_api_key, or API key must be associated with an organization. |
403 Forbidden | { "detail": "api_access_required" } | API access is unavailable for the organization. |
404 Not Found | { "error": "Shared store not found" } | The store does not exist or belongs to another organization. |
409 Conflict | { "error": string, "code": "shared_store_entry_limit_reached", "limit": 10000 } | New IDs would take the store beyond 10,000 entries. Existing IDs do not consume slots. |
413 Payload Too Large | { "error": "A bulk request may contain at most 5000 entries" } | The request contains more than 5,000 entries. |
413 Payload Too Large | { "detail": "metadata must be 256 KB or smaller" } | Any UTF-8 encoded metadata object exceeds 256,000 bytes. |
500 Internal Server Error | { "error": "Failed to upsert shared store entries" } | Capacity could not be checked or entries could not be written. |
Was this page helpful?
⌘I