docs
/
AppEngine API

Collections and schemas

Defining your own datatypes, how schemas drive both validation and UI, and repairing a collection.

A collection is a user-defined datatype. It is stored as a collection record holding a JSON Schema, and once defined it behaves exactly like a built-in datatype — same repository routes, same BaseModel envelope, same lifecycle and permissions.

This is why AppEngine has 261 built-in datatypes and no migration story for adding a 262nd: you add a collection.

Reading collections

GET/repository/collections/:name?/:subName?JWT

With no name, returns every collection in the tenant. getCollections also filters by subType and by CollectionType, and enriches by default.

Schemas define data and UI

Collection schemas are JSON Schema documents extended with x- keywords that the form renderer consumes. One document validates the record and describes the form.

{
  "type": "object",
  "properties": {
    "summary": {
      "type": "string",
      "x-control-variant": "textarea"
    },
    "categories": {
      "type": "array",
      "items": { "type": "string" },
      "x-control": "selectMany",
      "x-control-variant": "tree",
      "dataSource": {
        "source": "collection",
        "collection": "category",
        "value": "name",
        "label": "name",
        "children": "children"
      }
    },
    "css": {
      "type": "string",
      "x-control": "code",
      "x-control-variant": "css",
      "collapsible": true
    }
  }
}
KeywordEffect
x-controlControl type — selectMany, file, code, …
x-control-variantVariant — textarea, chip, combo, tree, css, javascript
x-renderHow to display the stored value
dataSourceOption source: { source: 'collection', collection, value, label, children } or { source: 'function', value }
hidden / hideInHide always, or only in a named context such as generator
readOnlyDisplay but do not edit
collapsibletrue or "close" — render as a collapsible group
group, layout, showIndexGrouping and layout
styleClass, stylingClass hooks for the container and layout
labelPostionLabel placement (spelled this way in the schema)

Studio renders these directly, which is why a new collection gets a working editor with no extra UI work.

Repairing a collection

POST/repository/collections/fixJWT

Body is an array of { action, datatype }. fixCollection reconciles the MongoDB collection with its schema — creating it if missing and adding indexes.

You will meet this indirectly: a full-text search against a collection with no text index fails with text index required for $text query, and search calls fixCollection for that datatype and retries once automatically. The first search on a fresh collection may be slow, but it succeeds.

Time-series collections

createTimeSeriesCollection creates a MongoDB time-series collection for metric-shaped datatypes, rather than a standard one.

Search indexes

createSearchIndex(orgid, datatype, page) walks a collection page by page and indexes its records. Use it after a bulk import, when records were written by a path that skipped indexing.

Settings

Org configuration is stored and read through the same layer, keyed by BaseSettingKeys:

GET/repository/setting/:settingType/:settingName?/:subName?JWT
POST/repository/setting/:settingType/:settingName?/:subName?JWT
DELETE/repository/setting/:settingType/:settingName?/:subName?JWT

settingType is the top-level key; settingName and subName drill into named and nested values. Admin only.

Settings that change platform behavior include securitySettings (enableTwoFactorForUsers, enableNewDeviceAuthentication, alertOnNewDeviceLogin) and passcodeLoginSettings (whether POS sign-in needs a pin or is instant).

Subschemas

A datatype can carry variants in subschema. In a URL they are written with a hyphen:


GET /repository/search/page-landing

The repository splits on the first hyphen: page is the collection, landing the subschema, and the query filters on subschema. If only a collection name is given, no subschema filter is applied.