Custom Schemas

Custom schemas allow you to define the structure of your data using JSON Schema. Each schema has a category that determines how it’s used in the platform.
Work with the Reach Team for ImplementationWe recommend working directly with our team during implementation. Custom schemas and references can be complex, and our team can provide guidance and hands-on support.We have an internal UI that can help streamline this process and handle much of the technical work for you. We’re working to provide you with a self-service portal to manage custom schemas independently in the future.Please contact Reach to schedule a collaborative session for implementing custom schemas.

Schema Categories

Each schema must have a category that determines its purpose:
  • contacts_schema: Customer/contact information
  • transactions_schema: Transaction and billing data
  • custom_schema: General data models
  • locations_schema: Location/address data

Schema Requirements

Schema names must be URL-safe:
  • Only letters, numbers, hyphens (-), and underscores (_)
  • No spaces or special characters
  • Must be unique (case-insensitive)

PII Annotations

Use x-pii-type to mark fields containing personally identifiable information:
  • EMAIL: Email addresses
  • PHONE: Phone numbers
  • FIRST_NAME, LAST_NAME, NAME: Name fields
  • EXTERNAL_ID: External identifiers

Schema Examples

contacts_schema

For customer/contact information:
{
  "name": "Customer",
  "pluralName": "Customers", 
  "description": "Customer contact information",
  "category": "contacts_schema",
  "external_id_field": "customerId",
  "schema": {
    "type": "object",
    "title": "Customer",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "required": ["customerId"],
    "properties": {
      "customerId": {
        "type": "string",
        "x-pii-type": "EXTERNAL_ID"
      },
      "email": {
        "type": "string",
        "x-pii-type": "EMAIL"
      },
      "phone": {
        "type": "string",
        "x-pii-type": "PHONE"
      },
      "firstName": {
        "type": "string",
        "x-pii-type": "FIRST_NAME"
      },
      "lastName": {
        "type": "string",
        "x-pii-type": "LAST_NAME"
      },
      "emailOptOut": {
        "type": "boolean",
        "description": "Email subscription opt-out status. Defaults to false (opted in)"
      },
      "smsOptOut": {
        "type": "boolean", 
        "description": "SMS subscription opt-out status. Defaults to true (opted out)"
      },
      "customerDetailUrl": {
        "type": "string",
        "description": "URL to click-out to the customer detail page"
      },
      "createdAt": {
        "type": "string",
        "format": "date-time"
      }
    }
  }
}

transactions_schema

For transaction/billing data:
{
  "name": "Transaction",
  "pluralName": "Transactions",
  "description": "Transaction and billing information", 
  "category": "transactions_schema",
  "external_id_field": "transactionId",
  "reference_schemas": ["Customer"],
  "schema": {
    "type": "object",
    "title": "Transaction",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "required": ["transactionId"],
    "properties": {
      "transactionId": {
        "type": "string",
        "x-pii-type": "EXTERNAL_ID",
        "description": "External ID"
      },
      "customerId": {
        "$ref": "reach:schemas/Customer",
        "x-pii-type": "EXTERNAL_ID"
      },
      "transactionDate": {
        "type": "string",
        "format": "date-time",
        "description": "Datetime ISO string with timezone when transaction occurred"
      },
      "transactionTotal": {
        "type": "number",
        "description": "Transaction total in dollars"
      },
      "transactionDetailUrl": {
        "type": "string",
        "description": "URL to click-out to the transaction detail page"
      }
    }
  }
}

locations_schema

For location/address data:
{
  "name": "Location",
  "pluralName": "Locations", 
  "description": "Business location information",
  "category": "locations_schema",
  "external_id_field": "locationId",
  "schema": {
    "type": "object",
    "title": "Location",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "required": ["locationId", "name"],
    "properties": {
      "locationId": {
        "type": "string",
        "x-pii-type": "EXTERNAL_ID"
      },
      "name": {
        "type": "string"
      },
      "address": {
        "type": "string"
      },
      "city": {
        "type": "string"
      },
      "state": {
        "type": "string"
      },
      "zipCode": {
        "type": "string"
      }
    }
  }
}

custom_schema

For general data models:
{
  "name": "Product",
  "pluralName": "Products",
  "description": "Product catalog information",
  "category": "custom_schema", 
  "external_id_field": "productId",
  "schema": {
    "type": "object",
    "title": "Product",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "required": ["productId", "name"],
    "properties": {
      "productId": {
        "type": "string",
        "x-pii-type": "EXTERNAL_ID"
      },
      "name": {
        "type": "string"
      },
      "price": {
        "type": "number"
      },
      "category": {
        "type": "string"
      }
    }
  }
}

Partner Schema Mappings

After creating custom schemas, you need to configure Partner Schema Mappings to tell Reach which fields in your schemas correspond to important data we need to extract and use throughout the platform. Schema mappings define how Reach interprets your custom schema data for:
  • Contact management and communication preferences
  • Transaction processing and revenue tracking
  • Location data for multi-location businesses

Available Schema Types

contacts_schema Mapping

Maps customer/contact information from your schema to Reach’s contact system: Required Fields:
  • schemaId: The ID of your contacts schema
  • email: Field name containing email addresses
  • phone: Field name containing phone numbers
  • userId: Field name for the unique user identifier
Optional Fields:
  • firstName: Field name for first name
  • lastName: Field name for last name
  • fullName: Field name for full name (alternative to firstName/lastName)
  • location: Field name linking to location data
  • emailOptOut: Field name for email subscription status
  • emailOptOutTimestamp: Field name for email opt-out timestamp
  • smsOptOut: Field name for SMS subscription status
  • smsOptOutTimestamp: Field name for SMS opt-out timestamp
  • urlPattern: URL pattern for deep-linking to customer details (e.g., /customers/{userId})
  • status: Object defining active/inactive status mapping
    • field: Field name containing status
    • activeValue: Value indicating active status
    • deactivatedValue: Value indicating inactive status
  • createdDate: Field name for account creation date

transactions_schema Mapping

Maps transaction/billing data for revenue tracking and customer journey analysis: Required Fields:
  • schemaId: The ID of your transactions schema
  • eventType: Type of transaction event (e.g., “purchase”, “subscription”, “refund”)
  • id_field: Field name for unique transaction identifier
  • userId: Field name linking to the customer
  • amount: Object defining monetary value mapping
    • field: Field name containing the amount
    • currency: Static currency code (e.g., “USD”)
Optional Fields:
  • dates: Object mapping various date fields
    • currencyField: Field name containing dynamic currency (optional, defaults to USD when not mapped)
    • createdDate: Transaction creation date
    • paidDate: Payment completion date
    • dueDate: Payment due date
    • startDate: Service start date
    • endDate: Service end date
  • metadata: Array of field names to include as metadata
  • urlPattern: URL pattern for deep-linking to transaction details
  • filter: JSONLogic rule for conditional event creation

locations_schema Mapping

Maps location/address data for multi-location businesses: Required Fields:
  • schemaId: The ID of your locations schema
  • id_field: Field name for unique location identifier
Optional Fields:
  • name: Location name/title
  • address_line_1: Primary address line
  • address_line_2: Secondary address line
  • address_line_3: Additional address line
  • locality: City/locality
  • district: State/province/district
  • postal_code: ZIP/postal code
  • country_code: Country code (ISO format)
  • phone: Location phone number
  • email: Location email address
  • website: Location website URL
  • urlPattern: URL pattern for deep-linking to location details

Schema Mapping Configuration

Schema mappings are configured through the Partner API and define a combined_schema structure:
{
  "type": "combined_schema",
  "contactsSchema": {
    "primarySource": {
      "type": "contacts_schema",
      "schemaId": "Customer",
      "email": "email",
      "phone": "phone", 
      "userId": "customerId",
      "firstName": "firstName",
      "lastName": "lastName",
      "emailOptOut": "emailOptOut",
      "smsOptOut": "smsOptOut",
      "urlPattern": "/customers/{customerId}",
      "status": {
        "field": "status",
        "activeValue": "active",
        "deactivatedValue": "inactive"
      }
    }
  },
  "transactionsSchema": [{
    "type": "transactions_schema",
    "eventType": "purchase",
    "schemaId": "Transaction", 
    "id_field": "transactionId",
    "userId": "customerId",
    "amount": {
      "field": "transactionTotal",
      "currency": "USD"
    },
    "dates": {
      "createdDate": "transactionDate"
    },
    "urlPattern": "/transactions/{transactionId}"
  }],
  "locationsSchema": [{
    "type": "locations_schema",
    "schemaId": "Location",
    "id_field": "locationId",
    "name": "name",
    "address_line_1": "address",
    "locality": "city",
    "district": "state",
    "postal_code": "zipCode"
  }]
}

Field Mapping Examples

URL Patterns

URL patterns support field substitution using {fieldName} syntax:
  • Simple field: /customers/{customerId}
  • Nested field: /orders/{orderId}?customer={customer.email}
  • Multiple fields: /locations/{locationId}/details?region={region}&type={businessType}

Status Mapping

Define how your status values map to Reach’s active/inactive system:
{
  "field": "accountStatus",
  "activeValue": "ACTIVE", 
  "deactivatedValue": "SUSPENDED"
}

Date Field Mapping

Map various date fields to track customer lifecycle:
{
  "createdDate": "signupDate",
  "paidDate": "paymentCompletedAt", 
  "startDate": "serviceStartDate",
  "endDate": "subscriptionExpiresAt"
}

Schema References

To reference another schema, use $ref with the reach:schemas/ URI scheme:
{
  "customerId": {
    "$ref": "reach:schemas/Customer"
  }
}
When creating a schema with references:
  1. Use $ref properties to reference other schemas
  2. Referenced schemas must already exist

Creating Resources

Use the /api/resources/:schemaName endpoint:
// POST /api/resources/Customer
{
  "resource_external_id": "customer-123",
  "data": {
    "customerId": "customer-123",
    "email": "john@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "emailOptOut": false,
    "smsOptOut": true,
    "customerDetailUrl": "https://admin.example.com/customers/customer-123"
  }
}
For schemas with references, use external IDs:
// POST /api/resources/Transaction  
{
  "resource_external_id": "txn-456",
  "data": {
    "transactionId": "txn-456",
    "customerId": "customer-123", // Reference by external ID
    "transactionTotal": 99.99,
    "transactionDate": "2024-01-15T10:30:00Z"
  }
}

API Examples

Create Customer Schema

curl -X POST "https://api.reach.com/partner/schema-definitions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "name": "Customer",
    "pluralName": "Customers",
    "description": "Customer contact information",
    "category": "contacts_schema",
    "externalIdField": "customerId",
    "schema": {
      "type": "object",
      "title": "Customer",
      "$schema": "http://json-schema.org/draft-07/schema#",
      "required": ["customerId"],
      "properties": {
        "customerId": {
          "type": "string",
          "x-pii-type": "EXTERNAL_ID"
        },
        "email": {
          "type": "string",
          "x-pii-type": "EMAIL"
        },
        "phone": {
          "type": "string",
          "x-pii-type": "PHONE"
        },
        "firstName": {
          "type": "string",
          "x-pii-type": "FIRST_NAME"
        },
        "lastName": {
          "type": "string",
          "x-pii-type": "LAST_NAME"
        },
        "emailOptOut": {
          "type": "boolean",
          "description": "Email subscription opt-out status. Defaults to false (opted in)"
        },
        "smsOptOut": {
          "type": "boolean", 
          "description": "SMS subscription opt-out status. Defaults to true (opted out)"
        },
        "customerDetailUrl": {
          "type": "string",
          "description": "URL to click-out to the customer detail page"
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    }
  }'

Create Transaction Schema (with Customer reference)

curl -X POST "https://api.reach.com/partner/schema-definitions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "name": "Transaction",
    "pluralName": "Transactions",
    "description": "Transaction and billing information",
    "category": "transactions_schema",
    "externalIdField": "transactionId",
    "referenceSchemas": ["Customer"],
    "schema": {
      "type": "object",
      "title": "Transaction",
      "$schema": "http://json-schema.org/draft-07/schema#",
      "required": ["transactionId"],
      "properties": {
        "transactionId": {
          "type": "string",
          "x-pii-type": "EXTERNAL_ID",
          "description": "External ID"
        },
        "customerId": {
          "$ref": "reach:schemas/Customer",
          "x-pii-type": "EXTERNAL_ID"
        },
        "transactionDate": {
          "type": "string",
          "format": "date-time",
          "description": "Datetime ISO string with timezone when transaction occurred"
        },
        "transactionTotal": {
          "type": "number",
          "description": "Transaction total in dollars"
        },
        "transactionDetailUrl": {
          "type": "string",
          "description": "URL to click-out to the transaction detail page"
        }
      }
    }
  }'

Create Product Schema

curl -X POST "https://api.reach.com/partner/schema-definitions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "name": "Product",
    "pluralName": "Products",
    "description": "Product catalog information",
    "category": "custom_schema",
    "externalIdField": "productId",
    "schema": {
      "type": "object",
      "title": "Product",
      "$schema": "http://json-schema.org/draft-07/schema#",
      "required": ["productId", "name"],
      "properties": {
        "productId": {
          "type": "string",
          "x-pii-type": "EXTERNAL_ID"
        },
        "name": {
          "type": "string"
        },
        "price": {
          "type": "number"
        },
        "category": {
          "type": "string"
        }
      }
    }
  }'

Create Location Schema

curl -X POST "https://api.reach.com/partner/schema-definitions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "name": "Location",
    "pluralName": "Locations",
    "description": "Business location information",
    "category": "locations_schema",
    "externalIdField": "locationId",
    "schema": {
      "type": "object",
      "title": "Location",
      "$schema": "http://json-schema.org/draft-07/schema#",
      "required": ["locationId", "name"],
      "properties": {
        "locationId": {
          "type": "string",
          "x-pii-type": "EXTERNAL_ID"
        },
        "name": {
          "type": "string"
        },
        "address": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "state": {
          "type": "string"
        },
        "zipCode": {
          "type": "string"
        }
      }
    }
  }'

List All Schemas

curl -X GET "https://api.reach.com/partner/schema-definitions" \
  -H "Authorization: Bearer YOUR_API_KEY"

Get Specific Schema

curl -X GET "https://api.reach.com/partner/schema-definitions/Customer" \
  -H "Authorization: Bearer YOUR_API_KEY"