Noma

Bulk Operations

Bulk Operations

Create, update, or delete many content entries in one request. All routes are scoped by collection slug.

ActionMethodPath
Bulk createPOST/api/bulk/{collection}/entries
Bulk updatePATCH/api/bulk/{collection}/entries
Bulk deleteDELETE/api/bulk/{collection}/entries

Bulk create

Request

POST /api/bulk/{collection}/entries HTTP/1.1
Host: app.nomacms.com
Content-Type: application/json
project-id: <project-uuid>
Authorization: Bearer <api-token>
Accept: application/json

Requires the create ability.

JSON body

FieldTypeDescription
itemsarray1–50 items

Each item:

FieldTypeDescription
localestringOptional; bulk logic defaults missing locale to the project default_locale.
statestringOptional; draft or published (invalid → draft).
dataobjectRequired (may be {}). Field values keyed by field name.

Singleton collections: If an item would create a second entry for the same locale, validation fails for that index.

Response (201)

{
  "message": "Bulk content created successfully.",
  "data": [ /* array of ContentEntryResource objects */ ]
}

Bulk update

Request

PATCH /api/bulk/{collection}/entries HTTP/1.1
Host: app.nomacms.com
Content-Type: application/json
project-id: <project-uuid>
Authorization: Bearer <api-token>
Accept: application/json

Requires the update ability.

JSON body

FieldTypeDescription
itemsarray1–50 items

Each item:

FieldTypeDescription
uuidstringRequired. Entry UUID in this collection.
localestringOptional.
statestringOptional; draft or published.
dataobjectRequired (may be {}). For each key present, that field’s values are replaced (same per-field behavior as single-entry update).

All UUIDs must exist in the collection; otherwise 422 with a message listing missing UUIDs.

Response (200)

{
  "message": "Bulk content updated successfully.",
  "data": [ /* array of ContentEntryResource objects */ ]
}

Bulk delete

Request

DELETE /api/bulk/{collection}/entries HTTP/1.1
Host: app.nomacms.com
Content-Type: application/json
project-id: <project-uuid>
Authorization: Bearer <api-token>
Accept: application/json

Requires the delete ability.

JSON body

FieldTypeDescription
uuidsarray1–100 entry UUIDs
forcebooleanOptional. Same meaning as Delete an Entry (force delete vs soft delete).

Response (200)

{
  "message": "Bulk content deleted successfully.",
  "count": 2,
  "force": false
}

Errors (common)

StatusWhen
400Missing project-id or project cannot be resolved
401Missing or invalid bearer token
403Token lacks the required ability
404Collection not found
422Validation failed (including per-index keys like items.0.locale for bulk create)
429Rate limited

Example

Use collection slug blog-posts. For bulk update and bulk delete, substitute real entry UUIDs (uuid1 / uuid2 in the SDK snippets, or UUID1 / UUID2 in shell examples).

import { createClient } from "@nomacms/js-sdk"
 
const client = createClient({
  projectId: process.env.NOMA_PROJECT_ID!,
  apiKey: process.env.NOMA_API_KEY!,
})
 
await client.content.bulkCreate("blog-posts", {
  items: [
    { locale: "en", state: "draft", data: { title: "A", slug: "a" } },
    { locale: "en", state: "draft", data: { title: "B", slug: "b" } },
  ],
})
 
await client.content.bulkUpdate("blog-posts", {
  items: [
    { uuid: uuid1, data: { title: "A2" } },
    { uuid: uuid2, state: "published", data: { title: "B2" } },
  ],
})
 
await client.content.bulkDelete("blog-posts", {
  uuids: [uuid1, uuid2],
  force: false,
})
import axios from "axios"
 
const base = "https://app.nomacms.com/api/bulk/blog-posts/entries"
const headers = {
  "Content-Type": "application/json",
  "project-id": process.env.NOMA_PROJECT_ID!,
  Authorization: `Bearer ${process.env.NOMA_API_KEY}`,
  Accept: "application/json",
}
 
async function main() {
  const created = await axios.post(
    base,
    {
      items: [
        { locale: "en", state: "draft", data: { title: "A", slug: "a" } },
        { locale: "en", state: "draft", data: { title: "B", slug: "b" } },
      ],
    },
    { headers },
  )
  console.log(created.data)
 
  const updated = await axios.patch(
    base,
    {
      items: [
        { uuid: uuid1, data: { title: "A2" } },
        { uuid: uuid2, state: "published", data: { title: "B2" } },
      ],
    },
    { headers },
  )
  console.log(updated.data)
 
  const deleted = await axios.delete(base, {
    headers,
    data: {
      uuids: [uuid1, uuid2],
      force: false,
    },
  })
  console.log(deleted.data)
}
 
void main()
<?php
 
$base = 'https://app.nomacms.com/api/bulk/blog-posts/entries';
$hdr = [
    'Content-Type: application/json',
    'project-id: ' . getenv('NOMA_PROJECT_ID'),
    'Authorization: Bearer ' . getenv('NOMA_API_KEY'),
    'Accept: application/json',
];
 
// Bulk create
$create = json_encode([
    'items' => [
        ['locale' => 'en', 'state' => 'draft', 'data' => ['title' => 'A', 'slug' => 'a']],
        ['locale' => 'en', 'state' => 'draft', 'data' => ['title' => 'B', 'slug' => 'b']],
    ],
]);
$ch = curl_init($base);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $create,
    CURLOPT_HTTPHEADER => array_merge($hdr, ['Content-Length: ' . strlen($create)]),
    CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch) . "\n";
 
// Bulk update (PATCH)
$patchBody = json_encode([
    'items' => [
        ['uuid' => getenv('UUID1'), 'data' => ['title' => 'A2']],
        ['uuid' => getenv('UUID2'), 'state' => 'published', 'data' => ['title' => 'B2']],
    ],
]);
$ch = curl_init($base);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PATCH',
    CURLOPT_POSTFIELDS => $patchBody,
    CURLOPT_HTTPHEADER => array_merge($hdr, ['Content-Length: ' . strlen($patchBody)]),
    CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch) . "\n";
 
// Bulk delete
$delBody = json_encode(['uuids' => [getenv('UUID1'), getenv('UUID2')], 'force' => false]);
$ch = curl_init($base);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_POSTFIELDS => $delBody,
    CURLOPT_HTTPHEADER => array_merge($hdr, ['Content-Length: ' . strlen($delBody)]),
    CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch);
# Bulk create
curl -sS -X POST "https://app.nomacms.com/api/bulk/blog-posts/entries" \
  -H "Content-Type: application/json" \
  -H "project-id: $NOMA_PROJECT_ID" \
  -H "Authorization: Bearer $NOMA_API_KEY" \
  -H "Accept: application/json" \
  -d '{"items":[{"locale":"en","state":"draft","data":{"title":"A","slug":"a"}},{"locale":"en","state":"draft","data":{"title":"B","slug":"b"}}]}'
 
# Bulk update
curl -sS -X PATCH "https://app.nomacms.com/api/bulk/blog-posts/entries" \
  -H "Content-Type: application/json" \
  -H "project-id: $NOMA_PROJECT_ID" \
  -H "Authorization: Bearer $NOMA_API_KEY" \
  -H "Accept: application/json" \
  -d "{\"items\":[{\"uuid\":\"$UUID1\",\"data\":{\"title\":\"A2\"}},{\"uuid\":\"$UUID2\",\"state\":\"published\",\"data\":{\"title\":\"B2\"}}]}"
 
# Bulk delete
curl -sS -X DELETE "https://app.nomacms.com/api/bulk/blog-posts/entries" \
  -H "Content-Type: application/json" \
  -H "project-id: $NOMA_PROJECT_ID" \
  -H "Authorization: Bearer $NOMA_API_KEY" \
  -H "Accept: application/json" \
  -d "{\"uuids\":[\"$UUID1\",\"$UUID2\"],\"force\":false}"
package main
 
import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"
	"os"
)
 
func main() {
	base := "https://app.nomacms.com/api/bulk/blog-posts/entries"
	h := func(req *http.Request) {
		req.Header.Set("Content-Type", "application/json")
		req.Header.Set("project-id", os.Getenv("NOMA_PROJECT_ID"))
		req.Header.Set("Authorization", "Bearer "+os.Getenv("NOMA_API_KEY"))
		req.Header.Set("Accept", "application/json")
	}
 
	// Bulk create
	createBody := map[string]any{
		"items": []any{
			map[string]any{"locale": "en", "state": "draft", "data": map[string]any{"title": "A", "slug": "a"}},
			map[string]any{"locale": "en", "state": "draft", "data": map[string]any{"title": "B", "slug": "b"}},
		},
	}
	raw, _ := json.Marshal(createBody)
	req, _ := http.NewRequest("POST", base, bytes.NewReader(raw))
	h(req)
	do(req)
 
	// Bulk update
	patchBody := map[string]any{
		"items": []any{
			map[string]any{"uuid": os.Getenv("UUID1"), "data": map[string]any{"title": "A2"}},
			map[string]any{"uuid": os.Getenv("UUID2"), "state": "published", "data": map[string]any{"title": "B2"}},
		},
	}
	raw, _ = json.Marshal(patchBody)
	req, _ = http.NewRequest("PATCH", base, bytes.NewReader(raw))
	h(req)
	do(req)
 
	// Bulk delete
	delBody := map[string]any{
		"uuids": []string{os.Getenv("UUID1"), os.Getenv("UUID2")},
		"force": false,
	}
	raw, _ = json.Marshal(delBody)
	req, _ = http.NewRequest("DELETE", base, bytes.NewReader(raw))
	h(req)
	do(req)
}
 
func do(req *http.Request) {
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	_, _ = io.Copy(os.Stdout, res.Body)
}
require "net/http"
require "json"
require "uri"
 
uri = URI("https://app.nomacms.com/api/bulk/blog-posts/entries")
headers = {
  "Content-Type" => "application/json",
  "project-id" => ENV.fetch("NOMA_PROJECT_ID"),
  "Authorization" => "Bearer #{ENV.fetch('NOMA_API_KEY')}",
  "Accept" => "application/json"
}
 
# Bulk create
req = Net::HTTP::Post.new(uri)
headers.each { |k, v| req[k] = v }
req.body = JSON.generate(
  "items" => [
    { "locale" => "en", "state" => "draft", "data" => { "title" => "A", "slug" => "a" } },
    { "locale" => "en", "state" => "draft", "data" => { "title" => "B", "slug" => "b" } }
  ]
)
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") { |http| puts http.request(req).body }
 
# Bulk update
req = Net::HTTP::Patch.new(uri)
headers.each { |k, v| req[k] = v }
req.body = JSON.generate(
  "items" => [
    { "uuid" => ENV.fetch("UUID1"), "data" => { "title" => "A2" } },
    { "uuid" => ENV.fetch("UUID2"), "state" => "published", "data" => { "title" => "B2" } }
  ]
)
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") { |http| puts http.request(req).body }
 
# Bulk delete
req = Net::HTTP::Delete.new(uri)
headers.each { |k, v| req[k] = v }
req.body = JSON.generate("uuids" => [ENV.fetch("UUID1"), ENV.fetch("UUID2")], "force" => false)
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") { |http| puts http.request(req).body }
import json
import os
import urllib.request
 
base = "https://app.nomacms.com/api/bulk/blog-posts/entries"
hdr = {
    "Content-Type": "application/json",
    "project-id": os.environ["NOMA_PROJECT_ID"],
    "Authorization": f"Bearer {os.environ['NOMA_API_KEY']}",
    "Accept": "application/json",
}
 
# Bulk create
create = {
    "items": [
        {"locale": "en", "state": "draft", "data": {"title": "A", "slug": "a"}},
        {"locale": "en", "state": "draft", "data": {"title": "B", "slug": "b"}},
    ]
}
req = urllib.request.Request(
    base,
    data=json.dumps(create).encode(),
    headers=hdr,
    method="POST",
)
with urllib.request.urlopen(req) as res:
    print(res.read().decode())
 
# Bulk update
patch = {
    "items": [
        {"uuid": os.environ["UUID1"], "data": {"title": "A2"}},
        {"uuid": os.environ["UUID2"], "state": "published", "data": {"title": "B2"}},
    ]
}
req = urllib.request.Request(
    base,
    data=json.dumps(patch).encode(),
    headers=hdr,
    method="PATCH",
)
with urllib.request.urlopen(req) as res:
    print(res.read().decode())
 
# Bulk delete
delete = {"uuids": [os.environ["UUID1"], os.environ["UUID2"]], "force": False}
req = urllib.request.Request(
    base,
    data=json.dumps(delete).encode(),
    headers=hdr,
    method="DELETE",
)
with urllib.request.urlopen(req) as res:
    print(res.read().decode())
  • Create an Entry - Single create
  • Update an Entry - Single update semantics
  • Delete an Entry - Single delete and force
  • JavaScript SDK - content.bulkCreate, content.bulkUpdate, content.bulkDelete

Search documentation

Find guides and reference pages