Guides

Database (collections & documents)

Store and query structured data with collections (your schemas) and documents (the records inside them). This guide walks the full lifecycle from code: create a collection, insert a document, list and query with pagination, fetch one, update it, and delete it - in cURL and the official SDKs. For every path and schema, see the API reference or OpenAPI.

How it fits together

  • A collection defines a schema (its fields) and lives under a project. Collection endpoints are mounted at /api/schemas.
  • A document is a record stored in a collection. Document endpoints are mounted at /api/data.
  • Both accept your project API key on the X-API-Key header for programmatic (server-to-server) access, or a user Bearer token for end-user sessions. This guide uses an API key.

Grab a projectId and an API key from the Console under Settings → API Keys, and give the key the database scope. Never expose an API key in client-side code - call these endpoints from your own backend.

Authenticate

The data and collection endpoints authenticate on the X-API-Key header. In the SDKs there is no unified client wrapper - you build a Configuration, attach the key as a default header, then use the API classes you need.

JavaScript
import { Configuration, CollectionsApi, DataApi } from "mudbase-sdk";

// The key goes out as X-API-Key on every request via baseOptions.
const config = new Configuration({
  basePath: "https://cloud.mudbase.dev",
  baseOptions: {
    headers: { "X-API-Key": process.env.MUDBASE_API_KEY },
  },
});

const collections = new CollectionsApi(config);
const data = new DataApi(config);

const projectId = process.env.MUDBASE_PROJECT_ID;
import { Configuration, CollectionsApi, DataApi } from "mudbase-sdk";

// The key goes out as X-API-Key on every request via baseOptions.
const config = new Configuration({
  basePath: "https://cloud.mudbase.dev",
  baseOptions: {
    headers: { "X-API-Key": process.env.MUDBASE_API_KEY },
  },
});

const collections = new CollectionsApi(config);
const data = new DataApi(config);

const projectId = process.env.MUDBASE_PROJECT_ID;
Python
import os
import mudbase_sdk

config = mudbase_sdk.Configuration(host="https://cloud.mudbase.dev")

api_client = mudbase_sdk.ApiClient(config)
api_client.set_default_header("X-API-Key", os.environ["MUDBASE_API_KEY"])

collections = mudbase_sdk.CollectionsApi(api_client)
data = mudbase_sdk.DataApi(api_client)

project_id = os.environ["MUDBASE_PROJECT_ID"]
import os
import mudbase_sdk

config = mudbase_sdk.Configuration(host="https://cloud.mudbase.dev")

api_client = mudbase_sdk.ApiClient(config)
api_client.set_default_header("X-API-Key", os.environ["MUDBASE_API_KEY"])

collections = mudbase_sdk.CollectionsApi(api_client)
data = mudbase_sdk.DataApi(api_client)

project_id = os.environ["MUDBASE_PROJECT_ID"]

1. Create a collection

Define the collection name and its fields. Each field has a name and a type (string, number, boolean, date, email, url, text, array, object, reference, file, enum, json), plus optional flags like required and unique.

HTTP
POST /api/schemas/projects/{projectId}/collections
X-API-Key: {apiKey}
Content-Type: application/json
POST /api/schemas/projects/{projectId}/collections
X-API-Key: {apiKey}
Content-Type: application/json
Shell
curl -X POST \
  https://cloud.mudbase.dev/api/schemas/projects/685ad30be129932fbb7a1047/collections \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "tasks",
    "fields": [
      { "name": "title", "type": "string", "required": true },
      { "name": "done", "type": "boolean" }
    ]
  }'
curl -X POST \
  https://cloud.mudbase.dev/api/schemas/projects/685ad30be129932fbb7a1047/collections \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "tasks",
    "fields": [
      { "name": "title", "type": "string", "required": true },
      { "name": "done", "type": "boolean" }
    ]
  }'
JavaScript
const { data: created } = await collections.createCollection({
  projectId,
  createCollectionRequest: {
    name: "tasks",
    fields: [
      { name: "title", type: "string", required: true },
      { name: "done", type: "boolean" },
    ],
  },
});

const collectionId = created.collection._id;
const { data: created } = await collections.createCollection({
  projectId,
  createCollectionRequest: {
    name: "tasks",
    fields: [
      { name: "title", type: "string", required: true },
      { name: "done", type: "boolean" },
    ],
  },
});

const collectionId = created.collection._id;
Python
created = collections.create_collection(
    project_id,
    mudbase_sdk.CreateCollectionRequest(
        name="tasks",
        fields=[
            mudbase_sdk.ModelField(name="title", type="string", required=True),
            mudbase_sdk.ModelField(name="done", type="boolean"),
        ],
    ),
)

collection_id = created.collection.id
created = collections.create_collection(
    project_id,
    mudbase_sdk.CreateCollectionRequest(
        name="tasks",
        fields=[
            mudbase_sdk.ModelField(name="title", type="string", required=True),
            mudbase_sdk.ModelField(name="done", type="boolean"),
        ],
    ),
)

collection_id = created.collection.id

Response (201):

JSON
{
  "message": "Collection created successfully",
  "collection": {
    "_id": "685ada8fd9416ac02f171abf",
    "name": "tasks",
    "slug": "tasks",
    "project": "685ad30be129932fbb7a1047",
    "fields": [
      { "name": "title", "type": "string", "required": true },
      { "name": "done", "type": "boolean" }
    ],
    "createdAt": "2026-08-31T10:00:00.000Z"
  }
}
{
  "message": "Collection created successfully",
  "collection": {
    "_id": "685ada8fd9416ac02f171abf",
    "name": "tasks",
    "slug": "tasks",
    "project": "685ad30be129932fbb7a1047",
    "fields": [
      { "name": "title", "type": "string", "required": true },
      { "name": "done", "type": "boolean" }
    ],
    "createdAt": "2026-08-31T10:00:00.000Z"
  }
}

Keep the returned collection._id - it is the collectionId you use for every document call below.

2. Insert a document

The request body is the document itself - a plain object whose keys match the collection's fields.

HTTP
POST /api/data/projects/{projectId}/collections/{collectionId}/data
POST /api/data/projects/{projectId}/collections/{collectionId}/data
Shell
curl -X POST \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Ship my first Mudbase feature", "done": false }'
curl -X POST \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Ship my first Mudbase feature", "done": false }'
JavaScript
const { data: inserted } = await data.createData({
  projectId,
  collectionId,
  body: { title: "Ship my first Mudbase feature", done: false },
});

const documentId = inserted.data._id;
const { data: inserted } = await data.createData({
  projectId,
  collectionId,
  body: { title: "Ship my first Mudbase feature", done: false },
});

const documentId = inserted.data._id;
Python
inserted = data.create_data(
    project_id,
    collection_id,
    {"title": "Ship my first Mudbase feature", "done": False},
)

document_id = inserted.data["_id"]
inserted = data.create_data(
    project_id,
    collection_id,
    {"title": "Ship my first Mudbase feature", "done": False},
)

document_id = inserted.data["_id"]

Response (201): the stored document, including its generated _id, createdAt, and updatedAt.

JSON
{
  "message": "Document created successfully",
  "data": {
    "_id": "685ae1210136e73fa1dcaf36",
    "title": "Ship my first Mudbase feature",
    "done": false,
    "createdAt": "2026-08-31T10:05:00.000Z",
    "updatedAt": "2026-08-31T10:05:00.000Z"
  }
}
{
  "message": "Document created successfully",
  "data": {
    "_id": "685ae1210136e73fa1dcaf36",
    "title": "Ship my first Mudbase feature",
    "done": false,
    "createdAt": "2026-08-31T10:05:00.000Z",
    "updatedAt": "2026-08-31T10:05:00.000Z"
  }
}

3. List and query documents

List returns a data array plus a pagination object. Narrow results with page, limit, sort, and filter.

HTTP
GET /api/data/projects/{projectId}/collections/{collectionId}/data?page=1&limit=20
GET /api/data/projects/{projectId}/collections/{collectionId}/data?page=1&limit=20
Shell
curl \
  "https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data?page=1&limit=20&sort=-createdAt" \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
curl \
  "https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data?page=1&limit=20&sort=-createdAt" \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
JavaScript
const { data: page } = await data.listData({
  projectId,
  collectionId,
  page: 1,
  limit: 20,
  sort: "-createdAt",
});

console.log(page.data);        // array of documents
console.log(page.pagination);  // { page, limit, total, totalPages }
const { data: page } = await data.listData({
  projectId,
  collectionId,
  page: 1,
  limit: 20,
  sort: "-createdAt",
});

console.log(page.data);        // array of documents
console.log(page.pagination);  // { page, limit, total, totalPages }
Python
page = data.list_data(project_id, collection_id, page=1, limit=20, sort="-createdAt")

print(page.data)        # list of documents
print(page.pagination)  # page, limit, total, total_pages
page = data.list_data(project_id, collection_id, page=1, limit=20, sort="-createdAt")

print(page.data)        # list of documents
print(page.pagination)  # page, limit, total, total_pages

Response (200):

JSON
{
  "data": [
    {
      "_id": "685ae1210136e73fa1dcaf36",
      "title": "Ship my first Mudbase feature",
      "done": false,
      "createdAt": "2026-08-31T10:05:00.000Z",
      "updatedAt": "2026-08-31T10:05:00.000Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
}
{
  "data": [
    {
      "_id": "685ae1210136e73fa1dcaf36",
      "title": "Ship my first Mudbase feature",
      "done": false,
      "createdAt": "2026-08-31T10:05:00.000Z",
      "updatedAt": "2026-08-31T10:05:00.000Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
}

See the Pagination guide for looping through large result sets.

4. Fetch one document

HTTP
GET /api/data/projects/{projectId}/collections/{collectionId}/data/{documentId}
GET /api/data/projects/{projectId}/collections/{collectionId}/data/{documentId}
Shell
curl \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data/685ae1210136e73fa1dcaf36 \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
curl \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data/685ae1210136e73fa1dcaf36 \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
JavaScript
const { data: one } = await data.getData({ projectId, collectionId, documentId });
const { data: one } = await data.getData({ projectId, collectionId, documentId });
Python
one = data.get_data(project_id, collection_id, document_id)
one = data.get_data(project_id, collection_id, document_id)

5. Update a document

Updates are a partial PATCH - send only the fields you want to change.

HTTP
PATCH /api/data/projects/{projectId}/collections/{collectionId}/data/{documentId}
PATCH /api/data/projects/{projectId}/collections/{collectionId}/data/{documentId}
Shell
curl -X PATCH \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data/685ae1210136e73fa1dcaf36 \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "done": true }'
curl -X PATCH \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data/685ae1210136e73fa1dcaf36 \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "done": true }'
JavaScript
const { data: updated } = await data.updateData({
  projectId,
  collectionId,
  documentId,
  body: { done: true },
});
const { data: updated } = await data.updateData({
  projectId,
  collectionId,
  documentId,
  body: { done: true },
});
Python
updated = data.update_data(project_id, collection_id, document_id, {"done": True})
updated = data.update_data(project_id, collection_id, document_id, {"done": True})

6. Delete a document

HTTP
DELETE /api/data/projects/{projectId}/collections/{collectionId}/data/{documentId}
DELETE /api/data/projects/{projectId}/collections/{collectionId}/data/{documentId}
Shell
curl -X DELETE \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data/685ae1210136e73fa1dcaf36 \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
curl -X DELETE \
  https://cloud.mudbase.dev/api/data/projects/685ad30be129932fbb7a1047/collections/685ada8fd9416ac02f171abf/data/685ae1210136e73fa1dcaf36 \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
JavaScript
await data.deleteData({ projectId, collectionId, documentId });
await data.deleteData({ projectId, collectionId, documentId });
Python
data.delete_data(project_id, collection_id, document_id)
data.delete_data(project_id, collection_id, document_id)

Response (200): { "message": "Document deleted successfully" }.

Error handling

CodeMeaning
400Invalid body or a field that violates the collection schema
401Missing or invalid X-API-Key (or an expired key)
403The key lacks the database scope, or the resource belongs to another project
404Project, collection, or document not found
429Rate limit exceeded - back off and retry (see Rate Limits)

Next steps

  • Pagination - iterate large collections safely.
  • Realtime Events - subscribe to document changes as they happen.
  • API Keys - scopes, rotation, and per-key rate limits.
  • API reference - full request/response schemas for every collection and data endpoint.
Chat with us