Databases

Data lives in documents inside collections inside a database. Documents are JSON. Schema (collections, attributes, indexes) is managed with an API key; document reads and writes go through the permission matrix.

Collections

Create a collection with a permission list and optional per-document security:

Create collection
curl -X POST "https://base.finiteskills.com/v1/databases/main/collections" \
  -H "X-Appwrite-Project: <YOUR_PROJECT_ID>" -H "X-Appwrite-Key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"collectionId":"notes","name":"Notes","documentSecurity":true,
       "permissions":["read(\"any\")","create(\"users\")"]}'

With documentSecurity on, each document can carry its own permissions in addition to the collection's.

Attributes (typed schema)

Attributes are optional — undeclared keys are stored as-is — but declaring them enables validation and defaults. Create them with POST .../attributes/{type}:

Attribute types
string   { key, size, required, default }        // + formats: email, url, ip, enum
integer  { key, min, max, required, default }
float    { key, min, max, required, default }
boolean  { key, required, default }
datetime { key, required, default }
email | url | ip | enum(elements)                // string sub-formats
vector   { key, dimensions }                     // for similarity search
relationship { key, relatedCollection, type }    // see Relationships

Add "array": true to store a list of that type. Validation runs on create and update; violations return 400 general_argument_invalid.

Documents

Create / read / update / delete
POST   /databases/main/collections/notes/documents        { documentId, data, permissions }
GET    /databases/main/collections/notes/documents        (list; supports queries[]=…)
GET    /databases/main/collections/notes/documents/{id}
PATCH  /databases/main/collections/notes/documents/{id}   { data }  (partial merge)
DELETE /databases/main/collections/notes/documents/{id}

Every document carries metadata: $id, $collectionId, $databaseId, $createdAt, $updatedAt, $permissions, $sequence.

Indexes

Create key, unique or fulltext indexes with POST .../indexes. Unique indexes are enforced on every write; fulltext indexes power the search operator.

Auto-expiring documents (TTL)

Set $expiresAt to an ISO-8601 datetime on create or update and the document is removed once that time passes. Pass null to clear an expiry; omit the field to leave it unchanged.

TTL
POST  /databases/main/collections/sessions/documents
  { "documentId":"unique()", "data":{...}, "$expiresAt":"2026-08-01T00:00:00.000Z" }

PATCH /databases/main/collections/sessions/documents/{id}
  { "$expiresAt": null }        # never expire

Cross-collection transactions

Where the atomic batch is scoped to one collection, a transaction applies a list of operations spanning any collections and databases in the project — all-or-nothing. If any operation fails (validation, a permission denial, a unique-index clash), the whole set rolls back and nothing is written.

POST /databases/transactions
curl -X POST "https://base.finiteskills.com/v1/databases/transactions" \
  -H "X-Appwrite-Project: <YOUR_PROJECT_ID>" -H "X-Appwrite-Key: <API_KEY>" \
  -H "Content-Type: application/json" -d '{
    "operations": [
      { "databaseId":"main","collectionId":"accounts","op":"update",
        "documentId":"a1","data":{"balance":40} },
      { "databaseId":"main","collectionId":"accounts","op":"update",
        "documentId":"a2","data":{"balance":60} },
      { "databaseId":"main","collectionId":"ledger","op":"create",
        "data":{"from":"a1","to":"a2","amount":20} }
    ]
  }'

Each operation is { databaseId, collectionId, op, documentId?, data?, permissions? } where op is create, update or delete. Needs a server key.

Evolving & removing schema

Collections, attributes and databases can be edited and dropped (server key). Dropping a collection or database removes its documents:

Schema mutation
PATCH  /databases/{db}/collections/{coll}                  # rename / change permissions & security
DELETE /databases/{db}/collections/{coll}                  # drop the collection
PATCH  /databases/{db}/collections/{coll}/attributes/{key} # change an attribute (e.g. required/default)
DELETE /databases/{db}/collections/{coll}/attributes/{key} # drop an attribute
DELETE /databases/{db}                                     # drop the database