Note: There is a new custom objects experience. See the Custom Object APIs.

The Legacy Custom Objects API lets you create object records that are based on a blueprint -- or schema -- that you design yourself. A schema defines the named properties of a custom object. The schema doesn't contain information about any specific object. It just describes the information.

You can also define validation rules in the schema to maintain the data integrity of your object records.

A schema in the Custom Objects API is based on the JSON Schema specification. For more information, see the following resources on json-schema.org:

Understanding schemas in the Legacy Custom Objects API

A schema is a template for creating and validating legacy object records of a certain type. The following example is one possible schema for fitness classes:

NameTypeRequiredDescription
idstringyesUnique identifier assigned to the fitness class
namestringyesFriendly public name for the fitness class
sizenumbernoMaximum number of people allowed to take the class

A schema consists of keyword/value pairs in a JSON object. Keywords are schema properties defined in the JSON Schema specification. Legacy custom objects support the following keywords:

  • title
  • description
  • properties
  • type
  • items
  • required

You define the schema as part of creating a legacy object type with the Legacy Custom Objects API. The following example shows the JSON payload to create an object type.

{  "data": {    "key": "fitness_class",    "schema": {      "properties": {        "id": {          "type": "string",          "description": "Unique identifier assigned to the fitness class"        },        "name": {          "type": "string",          "description": "Friendly public name for the fitness class"        },        "size": {          "type": "number",          "description": "Maximum number of people allowed to take the class"        }      },      "required": ["id", "name"]    }  }}

The example uses the following JSON Schema keywords: "properties", "type", "description", and "required".

Defining properties of your legacy custom object

You can define any property you want for your legacy custom object based on the JSON Schema specification, subject to the exceptions described in this section.

A typical property definition consists of a property name and a legacy object with the "type" keyword from JSON Schema.

"schema": {  "properties": {    "exercise_room": {      "type": "string"    }  }}

There's no standard convention for schema property names. Using snake_case or camelCase is common. The names appear in the JSON body of HTTP responses from the Legacy Custom Objects API so use what makes sense for the application that will consume the data.

For legacy custom objects, the following naming rules apply for properties:

  • You can't start a name with an underscore ("_")
  • You can't use an asterisk ("*") as a name
  • You can't use any of the following escape characters: "\b", "\f", "\n", "\r", "\t", "\u0007", "\u0013"

In the JSON Schema, the properties of an object are not restricted to the ones in the schema. For legacy custom objects however, the properties are restricted to the ones in the schema. If the Legacy Custom Objects API receives a request to create or update a legacy object record with a property not in the schema, the API returns a "422 Unprocessable Entity" status. The response specifies that the request has a property that's not allowed by the schema. If you try to override this behavior by using "additionalProperties": true in the schema, the API returns a 400 Bad Request error.

The JSON Schema supports not defining any properties at all in the schema. For legacy custom objects however, the schema must define at least one property.

Specifying required properties

By default, all the properties defined by a schema are optional. You'll probably need at least one or more required properties for your legacy custom object. A typical example of a required property is a record id or name.

Use the "required" keyword to specify one or more required properties for a legacy object. The keyword takes an array of property names. Example (highlighted):

"schema": {  "properties": {    "name": { "type": "string" },    "email": { "type": "string" },    "address": { "type": "string" }  },  "required": ["name", "email"]}

If the Legacy Custom Objects API receives a request to create a record without providing a required property, the API returns a "422 Unprocessable Entity" status. The response specifies that the request has a missing property.

Validating the data type of a property

You can use the "type" keyword in your schema to validate data when creating or updating a record of that legacy object type. The API only creates or updates a record if the value provided for the property matches the declared data type.

"schema": {  "properties": {    "num_locations": {       "type": "number"    }    }  }

For example, if you specify a string for a property that expects an array, the API returns a "422 Unprocessable Entity" status. The response specifies that the request has a property that doesn't match the allowed type.

The "type" can be one of the following:

  • string - a Unicode string
  • integer - an integral number
  • number - any numeric type, either integers or floating point numbers
  • array - an ordered list of values
  • boolean - true or false

The null and object types are not supported for legacy custom objects.

For legacy custom objects, you can specify only one type for a property. In the JSON Schema, you can specify more than one type by specifying an array of supported types such as "type": ["string", "number"].

If you don't want to perform any data validation at all, don't specify a type for the property:

"schema": {  "properties": {    "num_locations": {}  }  }

In that case, the API will accept any data type for the property.

Exception: When defining a property of type array, you must include an items element that defines the type of the items in the array. The type of the items can be boolean, integer, number, or string.

{  "type": "array",  "items": {    "type": "number"  }}

Validating strings

You can validate whether a string is too long or too short. You can also validate a string against a regular expression to make sure it follows a specific format, such as the format for an email address or phone number.

The property's type must be declared as a "string".

To validate the length of a string, use the "minLength" and "maxLength" keywords. Example:

"properties": {  "exercise_room": {     "type": "string",     "minLength": 3,     "maxLength": 18  }}

If the Legacy Custom Objects API receives a request to create or update a record with a string that's too long or too short, the API returns a "422 Unprocessable Entity" status. The response specifies that the string is too long or too short.

To validate a string against a regular expression, use the "pattern" keyword. Example:

"properties": {  "phone_number": {     "type": "string",     "pattern": "^(\([0-9]{3}\))?[0-9]{3}-[0-9]{4}$"  }}

If the Legacy Custom Objects API receives a request to create or update a record with a string that doesn't match the pattern, the API returns a "422 Unprocessable Entity" status. The response specifies that the regex does not match the input string.

Restricting a number to a range of values

You can use the "minimum" and "maximum" keywords to specify a range of accepted values for a property of type number. In the following example, the value of the property can be any number between 0 and 30, inclusive.

"properties": {  "num_weeks": {     "type": "number",     "minimum": 0,     "maximum": 30  }}

To exclude the starting or ending range value, use "exclusiveMinimum" or "exclusiveMaximum".

If the Legacy Custom Objects API receives a request to create or update a record with a number that's outside the range, the API returns a "422 Unprocessable Entity" status. The response specifies that the number is lower than the required minimum or higher than the required maximum.

Annotating your schema

You can annotate the schema for others who might use or edit the schema. The annotations can also form the basis of developer docs you create for your legacy custom object.

You can use any combination of the following keywords to annotate a schema:

  • title - short description
  • description - longer explanation about the purpose of the data

None of the keywords are required and the information has no effect on validating data.

Example:

"distance": {  "type": "number",  "title" : "Race distance",  "description": "Bicycle race distance in kilometers"}

The information will be available to anybody who retrieves the legacy object type with the Legacy Custom Objects API.

Note: The Legacy Custom Objects API doesn't currently "examples" keyword from the JSON Schema.