Skip to content
API Now! is currently in closed beta. We are constantly updating these guides as we release updates!

Data Properties

A Data Property represents a data field in your model. Most properties belong directly to an Entity (such as a product’s price or a user’s email).

Additionally, when you create a relationship tagged with an M:N semantic module (such as OrganizationMembers), the platform automatically provisions standard Relationship Edge Properties (such as member role or status).

When configuring properties in the Domain Modeler:

  • Entity Properties: You create and configure properties directly on an entity, specifying their base data type, validations, and semantic tags.
  • Relationship Edge Properties: Edge properties are provisioned automatically by semantic modules. In the UI, you toggle which edge properties to enable for your API and customize settings like display names or allowed enum values, while core attributes (like data types) are managed by the system.

Every property must have a primitive data type selected. The Serverless Engine maps these types to optimized PostgreSQL database types:

Data Modeler TypePostgreSQL Data TypeDescription
StringVARCHAR(255) / TEXTAlphanumeric text. Used for names, descriptions, and codes. Can also define file semantics.
NumberINTEGER / NUMERICWhole numbers or floating-point decimals.
BooleanBOOLEANTrue or False values.
DateDATEA calendar date (year, month, day).
TimeTIMEA time of day (hour, minute, second).
DateTimeTIMESTAMP WITH TIME ZONEA specific timestamp with timezone support.
BinaryJSONB (metadata)File storage metadata. Must define ImageURL or FileURL semantics to be supported.

To handle file uploads, attachments, or images in your Data Domain, you can configure properties using either of these types:

  • Binary Type: A dedicated property type for files. Important: Any property configured as Binary must have either the FileURL or ImageURL semantic module attached, or the platform will throw a validation error. Binary properties do not support format options.
  • String Type: Can also be used to store file attachments by applying the FileURL or ImageURL semantic modules on top of it.

At the database level, both options store a structured JSON metadata block representing the uploaded file in a cloud storage bucket. When queried through the API, clients receive a secure temporary signed download link (rather than raw bytes).

Refer to the File Uploads Guide for a complete overview of the upload lifecycle and configurations.


In the Domain Modeler UI, a property’s basic behavior, indexing, and write permissions are configured by toggling attributes in the property inspector:

  • Required: If checked, the property cannot be null. API requests must provide a value during record creation (POST).
  • Multiple: If checked, the property represents an array or list of values instead of a single value.
  • Primary Key: If checked, this property acts as the unique identifier for the entity. Primary keys are always immutable on update (PUT / PATCH). Depending on whether IDs are generated by the server or assigned by the client, primary keys are paired with either Read Only or Immutable (see Primary Key Patterns).
  • Unique: If checked, a database-level unique index is created on this column to prevent duplicate values (e.g., usernames).
  • Indexed: If checked, a standard B-Tree database index is generated to optimize query lookups on this field.
  • Search Indexed: If checked, a specialized full-text search index (e.g., GIN or pg_trgm in PostgreSQL) is created, allowing clients to query this field using search actions.
  • Read Only: If checked, the property is exclusively managed by the server, database sequences, or semantic runners (e.g., auto-increment id SERIAL, created_at, created_by, or calculated totals). Clients can never supply or edit this field in any request payload (POST, PUT, PATCH). Excluded from all write request bodies in generated OpenAPI specifications. Cannot be combined with Immutable.
  • Immutable: If checked, this is a write-once property. Clients can provide a value when creating the record (POST), but the value is permanently locked thereafter. Any subsequent attempt to modify it via PUT or PATCH is rejected with 400 Bad Request. Excluded from update request bodies in generated OpenAPI specifications. Cannot be combined with Read Only.
  • Write Only: If checked, clients can write this property but it will never be returned in read responses (ideal for passwords).
  • Deprecated: If checked, flags the field as deprecated in generated API specifications.

In API design and data modeling, fields have different lifecycles regarding when and how they can be written by API clients.

The platform cleanly separates two orthogonal concerns:

  1. Relational Role: Does this property identify the entity record? (primary: boolean).
  2. Write Lifecycle: How mutable is the property value over time? (mutable vs. immutable vs. readOnly).
flowchart TD
    subgraph States["Write Lifecycle States"]
        Mutable["Mutable (Default)<br/>readOnly: false, immutable: false"]
        Immutable["Immutable (Write-Once)<br/>immutable: true, readOnly: false"]
        ReadOnly["Read-Only (Write-Never)<br/>readOnly: true, immutable: false"]
    end

    POST_req["POST /entities (Create)"]
    PUT_req["PUT / PATCH /entities/{id} (Update)"]

    POST_req -->|Allowed| Mutable
    POST_req -->|Allowed| Immutable
    POST_req -->|Forbidden 400| ReadOnly

    PUT_req -->|Allowed| Mutable
    PUT_req -->|Forbidden 400| Immutable
    PUT_req -->|Forbidden 400| ReadOnly

To easily understand the three lifecycle states, consider the fields on a government-issued passport or identity card:

  • Mutable (Read-Write): Your Home Address or Phone Number. You set it when you first register, and you can update it whenever you move.
  • Immutable (Write-Once): Your Passport Number or Date of Birth. Established once when your document is issued, and permanently frozen against alteration thereafter.
  • Read-Only (Write-Never): The Issue Timestamp or Security Hologram Serial. You never get to type this in; the issuing agency generates and stamps it on your card.

A property can exist in exactly one of three write lifecycle states:

  • readOnly: false, immutable: false
  • Create (POST): Allowed. Callers can supply a value. If omitted, default generators or nullability rules apply.
  • Update (PUT / PATCH): Allowed. Callers can edit the value anytime.
  • Examples: name, status, description, price.
  • immutable: true, readOnly: false
  • Create (POST): Allowed. Callers can supply a custom value (e.g. project key MYPROJ, currency USD, custom SKU). If omitted and an automatic default generator is attached, the server populates it.
  • Update (PUT / PATCH): Forbidden. Once saved, the value cannot be modified. Any attempt to change it returns a 400 Bad Request error.
  • Examples: Project keys (key: "ALPHA"), natural SKUs, country of incorporation, original currency, external reference IDs.

3. Read-Only (Write-Never / System-Managed)

Section titled “3. Read-Only (Write-Never / System-Managed)”
  • readOnly: true, immutable: false
  • Create (POST): Forbidden. Callers can never provide this field in a creation payload. Supplying it returns a 400 Bad Request error.
  • Update (PUT / PATCH): Forbidden. Callers cannot update or overwrite this field.
  • OpenAPI 3.0/3.1 Compliance: Emits readOnly: true in component schemas and completely omits the property from write request bodies (Create<Entity>Request, Update<Entity>Request, Patch<Entity>Request), ensuring client SDK generators produce clean request parameter types.
  • Examples: Auto-increment database IDs (id SERIAL), audit timestamps (created_at, updated_at), system-managed actors (created_by), calculated totals.

The primary: true attribute designates a property as the unique identity of an entity. In REST APIs and relational database modeling, a primary key is always immutable on update — callers cannot change a record’s identity in-place (e.g., sending a new ID in PUT /projects/{id}).

However, during creation (POST), primary keys fall into two distinct architectural patterns:

Primary Key PatternConfigurationCreate (POST)Update (PUT / PATCH)Common Use Cases
Server-Generated Identifierprimary: true
readOnly: true
❌ Rejected (400)❌ Rejected (400)PostgreSQL SERIAL, BIGINT IDENTITY, server-enforced UUIDv4. Protects database sequences from client ID injection.
Client-Assignable Identifierprimary: true
immutable: true
✅ Allowed (or auto-defaulted)❌ Rejected (400)User-selected Project Keys (e.g., PROJ), ISO currency codes (USD), client-generated UUIDv7, product SKUs.

Schema Flagscreate (POST)put (PUT)patch (PATCH)OpenAPI Create SchemaOpenAPI Update Schema
readOnly: true❌ Rejected (400)❌ Rejected (400)❌ Rejected (400)OmittedOmitted
immutable: true✅ Allowed❌ Rejected (400)❌ Rejected (400)IncludedOmitted
primary: true, readOnly: true❌ Rejected (400)❌ Rejected (400)❌ Rejected (400)OmittedOmitted
primary: true, immutable: true✅ Allowed❌ Rejected (400)❌ Rejected (400)IncludedOmitted
(default mutable)✅ Allowed✅ Allowed✅ AllowedIncludedIncluded

You can define standard validations and formats in the property’s settings panel:

  • Minimum / Maximum (minimum / maximum): Numeric inputs to define bounds for numbers, dates, times, or datetimes.
  • Exclusive Minimum / Maximum (exclusiveMinimum / exclusiveMaximum): Checkboxes that make the corresponding minimum or maximum bounds exclusive (e.g., value > minimum instead of value >= minimum).
  • Multiple Of (multipleOf): Restricts values to multiples of a specified number (e.g., entering 2 allows only even numbers).
  • Enum (enum): A list input to restrict allowed property values to a specific set of strings.
  • Default Value (defaultValue): Input to specify a value that auto-populates when the property is omitted during record creation.
  • Pattern (pattern): Text input to enforce a regular expression match on string properties (e.g., ZIP code regex).

To translate the data model schema into external API formats (RAML and OpenAPI), configure the Web Bindings section on the property settings panel:

  • Format (format): A dropdown to specify precision formats. Currently, format constraints only support numerical types (such as float, double, int32, or int64), though support for more data formats may be added in the future.
  • Exposed Name (name): Text input to override the property name exposed in the generated web schema.
  • Accepted File Types (fileTypes): Input to specify a list of accepted file MIME types (only valid for file/image properties).
  • Hidden (hidden): A checkbox to hide the property from the generated OpenAPI specification.

When choosing a Format for a Number property in the Web Bindings panel, use this reference:

  • Whole Numbers (Integers):
    • int32 (Standard Integer): For counting values up to 2 billion (e.g., user age, quantity in stock, total page views).
    • int64 (Large Integer): For numbers that can exceed 2 billion (e.g., millisecond timestamps, global transaction IDs).
  • Decimals (Floating-point):
    • float (Standard Precision): For decimals where minor rounding is acceptable (e.g., temperature 72.5°F, weight 150.4 lbs, percentages 15.5%).
    • double (Double Precision): For high-precision decimals where rounding errors cause major issues (e.g., GPS coordinates 37.774929, -122.419416, exact money/split-payment calculations).

Rather than writing custom code to validate, encrypt, or process standard fields, you can attach Semantic Modules to your properties.

When you apply a semantic module, the platform automatically intercepts read/write requests at the runtime layer to apply logic:

  • Password: Automatically salts and hashes the value on write, and completely hides the field from all API reads to prevent credential leaks.
  • Email: Enforces strict RFC-compliant email syntax checking on the API gateway and normalizes inputs to lowercase.
  • CreatedTimestamp / UpdatedTimestamp: Auto-populates dates and times when records are created or edited without client input.