Returns every data type defined in the Project, with the count of currently active generated records for each. Requires any effective Project role (viewers included). Returns 404 if the caller has no access to the Project.
Example response
{
"types": [
{
"id": 1,
"name": "User",
"routeName": "users",
"identifierField": "id",
"recordCount": 20
}
]
}
Defines a new data type. routeName becomes part of the Runtime API URL path, so it's restricted to lowercase letters, numbers, and hyphens - and can't be one of this deployment's reserved names (RESERVED_ROUTE_NAMES, default admin/health/payment/payments/register/login/graphql - 422 if it is; these would otherwise silently collide with one of this service's own top-level segments and never actually be reachable). Creating a type immediately auto-creates its standard CRUD Routes - GET/POST /{routeName} and GET/PUT/PATCH/DELETE /{routeName}/{id} - so no separate Route definition is required to reach it via the Runtime API; the Routes endpoints remain available to customize or remove any of these. A type can also be designated this Project's Runtime Auth "user table" - see Runtime Auth docs. identifierField defaults to id if omitted; it and every entry in uniqueFields must be a key present in schema. Requires effective Project editor or admin - other roles receive 403. Returns 409 if name or routeName already exists in this Project, or 422 if the schema, identifierField, uniqueFields, or routeName are invalid.
Request
{
"name": "User",
"routeName": "users",
"schema": {
"id": {
"type": "number"
},
"email": {
"type": "string",
"format": "email",
"required": true
},
"age": {
"type": "number",
"min": 0,
"max": 120
},
"status": {
"type": "string",
"enum": [
"active",
"inactive"
]
},
"address": {
"type": "object",
"properties": {
"street": {
"type": "string",
"format": "streetAddress"
},
"city": {
"type": "string",
"format": "city"
}
}
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
},
"identifierField": "id",
"uniqueFields": [
"email"
],
"generation": {
"recordCount": 10
}
}
Response (201)
{
"id": 1,
"name": "User",
"routeName": "users",
"schema": {
"id": {
"type": "number"
}
},
"identifierField": "id",
"uniqueFields": [
"email"
],
"generation": {
"recordCount": 10
}
}
Returns the full definition of one data type. Requires any effective Project role. Returns 404 if the type or Project doesn't exist, or the caller has no access.
Example response
{
"id": 1,
"name": "User",
"routeName": "users",
"schema": {
"id": {
"type": "number"
}
},
"identifierField": "id",
"uniqueFields": [
"email"
],
"generation": {
"recordCount": 10
},
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
Fully replaces the type's name, routeName, schema, identifierField, uniqueFields, and generation - all fields are required, matching the create request shape (including the same reserved-routeName check described above). Requires effective Project editor or admin. Returns 409 on a name/routeName collision with another type in the same Project, 422 on an invalid schema/identifier/unique-fields/routeName, or 404 if the type doesn't exist.
Permanently deletes the type, along with every Route that exposes it (its own default/custom routes, and any nested route where this type is the child) - those only ever existed to expose it, so they're removed automatically rather than blocking the delete. Requires effective Project editor or admin. Still blocked with 409 if the type is referenced by any Relationship (details.blockedBy: "relationships") - remove that first, which cascades its own nested routes - or if it's the Project's Runtime Auth type.
Example blocked response (409)
{
"code": "conflict",
"message": "This data type is referenced by one or more relationships",
"details": {
"blockedBy": "relationships"
}
}
Each key in schema is a field name mapping to a field spec. A field spec has a required type and these optional properties:
| Property | Applies to | Meaning |
|---|---|---|
type | all | One of string, number, boolean, date, array, object. |
required | all | Whether generated records always populate this field. |
format | string | One of the named formats below. Ignored if enum is also set. |
enum | all | A fixed list of allowed values to pick from at generation time; overrides format. |
min / max | number | Inclusive bounds for generated numeric values. |
items | array | A nested field spec describing each array element. |
properties | object | A nested map of field name to field spec, same shape as the top-level schema. |
Nested array/object fields may be nested up to 5 levels deep.
format valuesThis service owns a fixed vocabulary of formats, independent of the underlying generation library. A string field with no format generates a generic placeholder. Every format below is backed by real generation as of the master template generation engine - see that page for how POST /projects/{projectId}/template/generate uses this vocabulary to build actual records.
| Format | Produces |
|---|---|
firstName | A person's given name. |
lastName | A person's family name. |
fullName | A person's first and last name combined. |
email | An email address. |
phoneNumber | A phone number. |
streetAddress | A street address line. |
city | A city name. |
country | A country name. |
postalCode | A postal/ZIP code. |
companyName | A company name. |
productName | A product name. |
price | A monetary amount. |
pastDate | An ISO date/time in the past. |
futureDate | An ISO date/time in the future. |
paragraph | Several sentences of placeholder text. |
sentence | A single sentence of placeholder text. |
uuid | A randomly generated UUID. |
username | A username-style string. |
imageUrl | A placeholder image URL. |