Skip to content

Collections and fields

Collections are named tables you create in Database (or via the admin SDK / MCP). The table name is the path segment in the data API (/api/p/:projectId/posts).

Plan collection / storage / MAU limits: Pricing.

Type JSON Notes
string string
number number
boolean boolean
datetime ISO-8601 string
array array Element type is configured on the field
map object Arbitrary JSON object
reference string (id) Optional target collection (referencedCollection) for expand()
file file metadata / ids See Files

Fields can be required and/or arrays, depending on how you configure them in the console.

isRequired: on create and on single-document PUT, a missing key or JSON null fails with Field "<name>" is required. Bulk PATCH is partial: absent keys are skipped and the stored value stays. An explicit null on a required field still fails in that partial check.

isArray: true: the value must be a JSON array, and each element is checked as fieldType. Errors look like Field "<name>" must be an array and Field "<name>[i]": ....

fieldType: "array" (the type, separate from the isArray flag): the value must be a list, and there is no per-element schema. If both isArray and type array are set, each element must be a list.

fieldType: "reference": the value must be a string id. The optional target is referencedSchemaId, taken from referencedSchemaId or referencedCollection when the field is created. expand on a reference with no target returns 400 Field "<name>" has no referenced collection; set the target or use join. A scalar reference expands to one object or null. An isArray reference stays an array. See Query for expand versus join.

fieldType: "file" on a write, when the key is present, must be a non-empty string file id. The document body does not accept bytes. If the file field is required, create fails until that id string is present, which fights creating the row and uploading afterwards. Leave file fields optional and upload after create. See Files.

defaultValue is stored on the field. Validation does not read it, and insert does not copy it into the document. An omitted optional field is absent. An omitted required field still errors when defaultValue is set.

Validation skips unknown-field checks for any key that starts with _. Those keys are stored. Create inserts the generated id, then the body, then _createdAt and _updatedAt:

  • _createdAt and _updatedAt in the body are overwritten by the server.
  • A client _id replaces the generated id, because the body is applied after that generated id.
  • Any other _… key is stored.

Schema creation rejects only the reserved names _id, _createdAt, and _updatedAt. A write can still send other _ keys.

POST /api/p/{projectId}/posts with the create endpoint enabled. The body omits required title and adds extra:

Terminal window
curl -s -X POST "https://api.tefily.com/api/p/$PROJECT_ID/posts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"extra":true}'

The response is 400. errors is a JSON array of strings. There is no code field.

{
"success": false,
"message": "Validation failed",
"errors": [
"Field \"title\" is required",
"Unknown field \"extra\""
]
}

Field errors come first, in field order, then unknown keys in body key order. A bulk array prefixes each string with the item index, as in [0] Field "title" is required, and inserts nothing if any item fails. The bulk cap is on Endpoints. Route tables: Dynamic project API.

The SDKs throw KataflaxException with message, errors, and statusCode (status_code in Python).

Do not add these with add_field. They are always present on documents:

Name Type Description
_id string Document id
_createdAt datetime Creation timestamp
_updatedAt datetime Last update timestamp

When you enable end-user auth, Tefily creates a _users collection. Treat it like any other table for extra profile fields (name, role), but do not store passwords in your own columns. The platform hashes credentials.

The console can export Dart model code from your schemas (GET /api/projects/:projectId/export/models). That is optional; the SDKs accept plain maps/objects.

In the console, open a collection to add, edit, and delete rows. You can also:

  • Import CSV or JSON from a file or from pasted text. The browser parses it first and shows a preview in the same columns as the table. Import creates new documents: _id, _createdAt, and _updatedAt are assigned by the server. File fields stay on the single-row editor.
  • Select rows on the current page, then edit or delete them together. Edit applies the fields you check to every selected row and leaves the others unchanged.