Defining Custom Schemas

Here, we'll go over features and best practices to know when defining your own custom schemas.

As a reminder, schemas are defined using the JSON Schema Specification. If you are unfamiliar with the standard, here's a good introduction to how the standard works.

Special Cases

Naming Schemas

By default, Endgrate has straightforward built-in display names for schemas given their endgrate_type. For example, on configuration screens crm-contact is displayed as Contact and accounting-invoice is displayed as Invoice.

If you'd like to override this, specify a title for your schema.

{
  "endgrate_type": "crm-contact",
  "title": "Company Person",
  "type": "object",
  "properties": {...}
}
curl --request POST \
     --url https://endgrate.com/api/push/transfer \
     --header 'accept: application/json' \
     --header 'authorization: Bearer API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "session_id": "SESSION_ID",
  "endgrate_type": "Company Person", // the title defined in your schema
  "transfer_data": [
    {
      "data": {
        "company_name": "Endgrate",
        "website": "https://endgrate.com"
      }
    }
  ]
}
'
curl --request POST \
     --url https://endgrate.com/api/pull/transfer \
     --header 'accept: application/json' \
     --header 'authorization: Bearer API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "session_id": "SESSION_ID",
  "endgrate_type": "Company Person", // the title defined in your schema
}
'

This is useful when you have multiple schemas with overlapping endgrate_types. When that is the case, the title is the unique identifier for the schema and should be used in place of endgrate_type in subsequent API calls to push or pull data.

The unspecified endgrate_type

unspecified is a special endgrate_type that encompasses all types of data. If your dynamic resource doesn't correspond to any single endgrate_type, you should use the unspecified type when defining your custom schema. You'll need to provide a title for this schema, which will be used in subsequent API calls to push or pull data. The specified title will be the unique identifier for the schema and should be used in place of endgrate_type in subsequent API calls to push or pull data.

If you do not specify an endgrate_type in your schema, it will default to unspecified. Additionally, if you use the unspecified endgrate_type, you must enable the resource_selection flag. More information about the resource_selection flag is available here.

{
  "endgrate_type": "unspecified",
  "title": "Data",
  "type": "object",
  "properties": {...}
}
curl --request POST \
     --url https://endgrate.com/api/push/transfer \
     --header 'accept: application/json' \
     --header 'authorization: Bearer API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "session_id": "SESSION_ID",
  "endgrate_type": "Data", // the title defined in your schema
  "transfer_data": [
    {
      "data": {
        "company_name": "Endgrate",
        "website": "https://endgrate.com"
      }
    }
  ]
}
'
curl --request POST \
     --url https://endgrate.com/api/pull/transfer \
     --header 'accept: application/json' \
     --header 'authorization: Bearer API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "session_id": "SESSION_ID",
  "endgrate_type": "Data", // the title defined in your schema
}
'

JSON Schema Features

In its core, the JSON Schema standard obeys the following format:

"attribute_name": {
  "type": "attribute_type"
}

The key is the attribute name, and the value is an object that describe the properties of the attribute.

If the type is an object, Endgrate requires the properties to be present, and if the type is an array, Endgrate requires the items to be present.

In addition, you can specify other properties of the attribute that Endgrate will use, including:

  1. The title. This is a human-readable name of the attribute (we highly recommend including this). Endgrate will use this value to aid AI field mapping.
  2. The description. This is a human-readable description of the attribute (we highly recommend including this). Endgrate will use this value to aid AI field mapping.
  3. The format if the type is a string. We highly recommend including the format of a string if it is one we support. When the format is provided for an attribute, Endgrate will automatically format both incoming and outgoing data to meet the specification requirements. Endgrate supports the following formats:
    1. Email (email): specification, e.g. "[email protected]".
    2. URI (uri): specification, e.g. "https://endgrate.com".
    3. Date (date): "%Y-%m-%d", e.g. "2000-01-01", UTC.
    4. Time (time): "%H:%M:%S", e.g. "00:00:00", UTC.
    5. Date Time (date-time): "%Y-%m-%d %H:%M:%S", e.g. "2000-01-01 00:00:00", UTC.
  4. A default value. When a default value is provided for an attribute, Endgrate will automatically fallback to the default value in both incoming and outgoing data if the attribute does not exist.
  5. Enumeration values. Specifying this is useful when you want to restrict an attribute only to be within a fixed set of values.

If the type is an object, you can also specify the required property to enforce certain fields to be present. Endgrate will automatically skip data in both incoming and outgoing data if the attribute field(s) do(es) not exist.

Schema Attribute Examples

Here are some examples of schema attributes, including how to add title/description, string formatting, enumeration values, and required fields.

{
  "first_name": {
    "type": "string",
    "title": "First Name",
    "description": "The first name of the contact"
  }
}
{
  "email_address": {
    "type": "string",
    "format": "email"
  }
}
{
  "shirt_size": {
    "type": "string",
    "oneOf": [
      {
        "const": "S",
        "title": "Small",
        "description": ""
      },
      {
        "const": "L",
        "title": "Large",
        "description": ""
      }
    ]
  }
}
{
  "my_object": {
    "type": "object",
    "properties": {
      "a": {
        "type": "string"
      },
      "b": {
        "type": "string"
      }
    },
    "required": [
      "a"
    ]
  }
}