The model JSON file declaratively defines a LoopBack model.
Page Contents


The LoopBack Model generator creates a model JSON file for each model in either the server/models or the common/models directory (depending on your response to the generator’s prompts). The file is named model-name.json, where model-name is the model name; for example, customer.json. The model JSON file defines models, relations between models, and access to models. 

For example, here is an excerpt from a model definition file for a customer model that would be in /common/models/customer.json:


  "name": "Customer",  // See Top-level properties below
  "description": "A Customer model representing our customers.",
  "base": "User",
  "idInjection": false,
  "strict": true,
  "options": { ... }, // See Options below - can also declare as top-level properties
  "properties": { ... }, // See Properties below
  "hidden": [...], // See Hidden properties below
  "validations": [...],  // See Validations below
  "relations": {...},  // See Relations below
  "acls": [...],  // See ACLs below
  "scopes": {...},  // See Scopes below
  "indexes" : { ...}, // See Indexes below
  "methods": [...],  // See Methods below
  "remoting": {
      "normalizeHttpPath": true
  "http": {"path": "/foo/mypath"}

Top-level properties

Properties are required unless otherwise designated.

Property Type Default Description
acls Array N/A Set of ACL specifications that describes access control for the model. See ACLs below.
base String None Name of another model that this model extends. The model will "inherit" properties and methods of the base model.
description String or Array None Optional description of the model.

You can split long descriptions into arrays of strings (lines) to keep line lengths manageable; for example:
[ "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
  "sed do eiusmod tempor incididunt ut labore et dolore",
"magna aliqua." ]
forceId Boolean true If true, prevents clients from setting the auto-generated ID value manually.
http.path None String Customized HTTP path for REST endpoints of this model.
strict Boolean false.
If the data source is backed by a relational database, then default is true.
Specifies whether the model accepts only predefined properties or not. One of:
  • true: Only properties defined in the model are accepted. Use if you want to ensure the model accepts only predefined properties. If you try to save a model instance with properties that are not predefined, LoopBack throws a ValidationError.
  • false: The model is an open model and accepts all properties, including ones not predefined in the model. This mode is useful to store free-form JSON data to a schema-less database such as MongoDB.
idInjection Boolean true Whether to automatically add an id property to the model:
  • true: id property is added to the model automatically. This is the default.
  • false: id property is not added to the model
See ID properties for more information. The idInjection property in options (if present) takes precedence.
name String None Name of the model.
options Object N/A JSON object that specifies model options. See Options below.
plural String Plural of name property using standard English conventions. Plural form of the model name.
properties Object N/A JSON object that specifies the properties in the model. See Properties below.
relations Object N/A Object containing relation names and relation definitions. See Relations below.
Boolean false If true, in HTTP paths, converts:
  • Uppercase letters to lowercase.
  • Underscores (_) to dashes (-).
  • CamelCase to dash-delimited.
Does not affect placeholders (for example ":id"). For example, "MyClass" or "My_class" becomes "my-class".
replaceOnPUT Boolean false If true, replaceOrCreate() and replaceById() use the HTTP PUT method; if false, updateOrCreate() and updateAttributes()/patchAttributes() use the HTTP PUT method.
For more information, see Exposing models over REST.
scopes Object N/A See Scopes below.


The options key specifies advanced options, for example data source-specific options.

Advanced options

Property Type Description
validateUpsert Boolean By default, the upsert() (updateOrCreate()) method does not enforce valid model data. Instead, it logs validation errors to the console. This preserves backwards compatibility with older 2.x versions.

Set this property to true to ensure that upsert() returns an error when validation fails. The next major version of LoopBack will enable this option (set as true) by default.

Set this property to false to prevent upsert() from calling any validators at all.

By default, upsert() calls all validators and reports any validation errors to the console log.
allowEternalTokens Boolean Allow access tokens that never expire.

Data source-specific options

When a model is attached a data source of certain type such as Oracle or MySQL, you can specify the name of the database schema and table as properties under the key with the name of the connector type. The value of this key must match the value of the corresponding connector property in datasources.json. For example, in the snippet below, there would be an entry in datasources.json like this:  "myDB": { "name": "myDB",  "connector": "mysql", ... }.

  "options": {
    "mysql": {
      "table": "location"
    "mongodb": {
      "collection": "location"
    "oracle": {
      "schema": "BLACKPOOL",
      "table": "LOCATION"


The properties key defines one or more  properties, each of which is an object that has keys described in the following table. Below is an example a basic property definition:

"properties": {
  "firstName": {
    "type": "String", 
    "required": "true"
  "id": {
    "type": "Number", 
    "id": true, 
    "description": "User ID"

General property properties

Each model property can have the properties described in the following table. Only the type property is required; for properties with only a type, you can use the following shorthand:

"propertyName": "type"

For example:

"emailVerified": "boolean",
"status": "string",
Key Required? Type Description
default No Any* Default value for the property. The type must match that specified by type.
defaultFn No String A name of the function to call to set the default value for the property. Must be one of:
  • "guid": generate a new globally unique identifier (GUID) using the computer MAC address and current time (UUID version 1).
  • "uuid": generate a new universally unique identifier (UUID) using the computer MAC address and current time (UUID version 1).
  • "uuidv4": generate a new universally unique identifier using the UUID version 4 algorithm.
  • "now": use the current date and time as returned by new Date()
NOTE: For discussion of providing additional options, see LoopBack issue 292 on GitHub.
description No String or Array Documentation for the property. You can split long descriptions into arrays of strings (lines) to keep line lengths manageable. For example:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
"sed do eiusmod tempor incididunt ut labore et dolore",
"magna aliqua."
doc No String Documentation for the property. Deprecated, use "description" instead.
id No Boolean Whether the property is a unique identifier. Default is false. See Id property below.
index No Boolean Whether the property represents a column (field) that is a database index.
required No Boolean Whether a value for the property is required. If true, then adding or updating a model instance requires a value for the property.

Default is false.
type Yes String Property type. Can be any type described in LoopBack types.
* No Any See below.

ID properties

A model representing data to be persisted in a database usually has one or more ID properties that uniquely identify the model instance. For example, the user model might have user IDs.

By default, if no ID properties are defined and the idInjection property is true (or is not set, since true is the default), LoopBack automatically adds an id property to the model as follows:

id: {type: Number, generated: true, id: true}

The generated property indicates the ID will be automatically generated by the database. If true, the connector decides what type to use for the auto-generated key. For relational databases, such as Oracle or MySQL, it defaults to number. If your application generates unique IDs, set it to false.

To explicitly specify a property as ID, set the id property of the option to true. The id property value must be one of:

  • true: the property is an ID.
  • false (or any value that converts to false): the property is not an ID (default).
  • Positive number, such as 1 or 2: the property is the index of a composite ID.

In database terms, ID properties are primary key column(s) are. Such properties are defined with the ‘id’ attribute set to true or a number as the position for a composite key.

For example,

  "myId": {
    "type": "string", 
    "id": true 


  1. If a model doesn’t have explicitly-defined ID properties, LoopBack automatically injects a property named “id” unless the idInjection option is set to false.
  2. If an ID property has generated set to true, the connector decides what type to use for the auto-generated key. For example for SQL Server, it defaults to number.
  3. LoopBack CRUD methods expect the model to have an “id” property if the model is backed by a database.
  4. A model without any “id” properties can only be used without attaching to a database.

Composite IDs

LoopBack supports the definition of a composite ID that has more than one property. For example:

var InventoryDefinition = { 
  productId: {type: String, id: 1}, 
  locationId: {type: String, id: 2}, 
  qty: Number 

The composite ID is (productId, locationId) for an inventory model.

Data mapping properties

When using a relational database data source, you can specify the following properties that describe the columns in the database.

Property Type Description
columnName String Column name
dataType String Data type as defined in the database
dataLength Number Data length
dataPrecision Number Numeric data precision
dataScale Number Numeric data scale
nullable Boolean If true, data can be null

For example, to map a property to a column in an Oracle database table, use the following:

"name": {
      "type": "String",
      "required": false,
      "length": 40,
      "oracle": {
        "columnName": "NAME",
        "dataType": "VARCHAR2",
        "dataLength": 40,
        "nullable": "Y"
Non-public Information
Removed until is resolved.

Conversion and formatting properties

Format conversions are declared in properties, as described in the following table:

Key Type Description
trim Boolean Whether to trim the string
lowercase Boolean Whether to convert a string to lowercase
uppercase Boolean Whether to convert a string to uppercase
format Regular expression Format for a date property.

Exclude properties from base model

By default, a model inherits all properties from the base. To exclude some base properties from being visible, you need to set the property to false or null.

For example,


"base": "User",
"properties": {
  "lastUpdated": false,
  "credentials": null,
  "challenges": null,
  "modified": "date"

Hidden properties

A hidden property is not sent in the JSON data in the application’s HTTP response. The property value is an array of strings, and each string in the array must match a property name defined for the model.

An example of a hidden property is User.password:


  "properties": {
    "password": {
      "type": "string",
      "required": true
   "hidden": ["password"],

If you want to white-list the fields returned instead of black-listing them, consider:

  • Applying the fields of the model’s defaultscope. This will operate at the database response layer so limiting your ability to check a field in the database that you otherwise would not wish exposed to the outside world (a private flag, for example).
  • Overriding your model’s toJSON method

See discussion of white-listing on GitHub.

Protected properties

A protected property is not sent in the JSON data in the application’s HTTP response if the object is nested inside another object. For instance if you have an Author object and a Book object. A book has a relation to with Author, and book is public API. Author will have personal information such as social security number etc, and they can now be “protected” such that anyone looking up the author of the book will not get those information back (from GitHub pull request). The property value is an array of strings, and each string in the array must match a property name defined for the model.

An example of a hidden property is


  "properties": {
    "email": {
      "type": "string",
      "required": true
   "protected": ["email"],


Specify constraints on data with validations properties. See also Validatable class.

Key Type Description
default Any Default value of the property.
required Boolean Whether the property is required.
pattern String Regular expression pattern that a string should match
max Number Maximum length for string types.
min Number Minimum length for string types. 
length Number Maximum size of a specific type, for example for CHAR types.

For example:

"username": {
  "type": "string", 
  "description": "User account name",  
  "min": 6, 
  "max": 24


The relations key defines relationships between models through a JSON object. Each key in this object is the name of a related model, and the value is a JSON object as described in the table below.

For example:

"relations": {
  "accessTokens": {
    "model": "accessToken",
    "type": "hasMany",
    "foreignKey": "userId"
  "account": {
    "model": "account",
    "type": "belongsTo"
  "transactions": {
    "model": "transaction",
    "type": "hasMany"
Key Type Description
foreignKey String Optional foreign key used to find related model instances.
keyThrough String Foreign key to be used in a HasMany relation.
model String Name of the related model. Required.
type String Relation type. Required. See Creating model relations for more information. One of:
  • hasMany
  • belongsTo
  • hasAndBelongsToMany

For hasMany, you can also specify a hasManyThrough relation by adding a "through" key:

{through: 'modelName'}

See example below.

through String Name of model creating hasManyThrough relation. See example below.

Example of hasManyThrough:

"patient": {
    "model": "physician",
    "type": "hasMany", 
    "through" : "appointment"


The value of the acls key is an array of objects that describes the access controls for the model. Each object has the keys described in the table below.

"acls": [
      "permission": "ALLOW",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "property": "myMethod"
Key Type Description
accessType String The type of access to apply. One of:
  • READ
  • * (default)
permission String Type of permission granted. Required. One of:
  • ALLOW - Explicitly grants access to the resource.
  • DENY - Explicitly denies access to the resource.
principalId String Principal identifier. Required. The value must be one of:
  • A user ID (String|number|any)
  • An application ID (String|number|any)
  • One of the following predefined dynamic roles:
    • $everyone - Everyone
    • $owner - Owner of the object
    • $authenticated - Authenticated user
    • $unauthenticated - Unauthenticated user
  • A custom role name, either:
    • static, directly mapped to a principal
    • dynamic, registered with a custom role resolver
principalType String Type of the principal. Required. One of:
  • APP
  • USER
  • ROLE
property String
Array of Strings 
Specifies a property/method/relation on a given model. It further constrains where the ACL applies. Can be:
  • A string, for example: "create"
  • An array of strings, for example: ["create", "update"]


Scopes enable you to specify commonly-used queries that you can reference as method calls on a model.

The scopes key defines one or more scopes (named queries) for models. A scope maps a name to a predefined filter object to be used by the model’s find() method; for example:

	"vips": {"where": {"vip": true}}, 
	"top5": {"limit": 5, "order": "age"}

The snippet above defines two named queries for the model:

  • vips: Find all model instances with vip flag set to true
  • top5: Find top five model instances ordered by age

Within the scopes object, the keys are the names, and each value defines a filter object for PersistedModel.find().

You can also define a scope programmatically using a model’s scope() method, for example:

User.scope('vips', {where: {vip: true}});
User.scope('top5', {limit: 5, order: 'age'});

Now you can call the methods defined by the scopes; for example:

User.vips(function(err, vips) {

Default scope

If you wish for a scope to be applied across all queries to the model, you can use the default scope for the model itself.

For example:

  "name": "Product",
  "properties": {
  "scope": {
    "order": "name",
    "limit": 100,
    "where": {
      "deleted": false

Now, any CRUD operation with a query parameter runs in the default scope will be applied; for example, assuming the above scope, a find opearation such as

Product.find({offset: 0}, cb);

Becomes the equivalent of this:

Product.find({order: "name", offset: 0, limit: 100, where: {deleted: false}}, cb)

Default scopes with where filters

Adding a scope to a model definition (in the model.json file) automatically adds a method to model called defaultScope(). LoopBack will call this method whenever a model is created, updated, or queried.

Each time a model instance is created or updated, the generated defaultScope() method will modify the model’s properties matching the where filter to enforce the values specified.

If you don’t want to have the default scope applied in this way, use named scopes where possible.

If you must use a default scope, but don’t want it to affect upsert(), for example, simply override the model’s defaultScope() method prior to calling upsert(); for  example:

var defaultScope = Report.defaultScope;
  Report.defaultScope = function(){};
  Report.upsert({id: reportId, 'deleted': true}, function(...) {
    Report.defaultScope = defaultScope;


You can declare remote methods here. Until this feature is implemented, you must declare remote methods in code. See Remote methods.


Declare indexes for a model with the indexes property, for example:

"indexes": {
  "name_age_index": {
    "keys": {"name": 1, "age": -1}
  "age_index": {"age": -1}

The snippet above creates two indexes for the declaring model:

  • A composite index named name_age_index with two keys: name in ascending order and age in descending order.
  • A simple index named age_index with one key: age in descending order.

The full syntax for an individual index is:

"<indexName>": {
  "keys": {
     "<key1>": 1,
     "<key2>": -1
   "options": {
     "unique": true

If you don’t need to specify any options, you can use a shortened form:

"<indexName>": {
  "<key1>": 1,
  "<key2>": -1

You can specify indexes at the model property level too, for example:

  "name": {
    "type": "String",
    "index": true
  "email": {
    "type": "String",
    "index": {
      "unique": true
  "age": "Number"

This example creates two indexes: one for the name key and another one for the email key. The email index is unique.

MySQL indexes

For MySQL, you can declare multi-column indexes as follows (for example):

    "UNIQUE_INDEX":  {
        "columns": "column1,column2,...",
        "kind": "unique"
Tags: models