> ## Documentation Index
> Fetch the complete documentation index at: https://docs.embedreach.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom schemas

# 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.

> <Warning>
>   **Work with the Reach Team for Implementation**
>
>   We 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.
> </Warning>

## 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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "type": "combined_schema",
  "contactsSchema": {
    "primarySource": {
      "type": "contacts_schema",
      "schemaId": "{schemaDefinitionId}",
      "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": "{schemaDefinitionId}", 
    "id_field": "transactionId",
    "userId": "customerId",
    "amount": {
      "field": "transactionTotal",
      "currency": "USD"
    },
    "dates": {
      "createdDate": "transactionDate"
    },
    "urlPattern": "/transactions/{transactionId}"
  }],
  "locationsSchema": [{
    "type": "locations_schema",
    "schemaId": "{schemaDefinitionId}",
    "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:

```json theme={null}
{
  "field": "accountStatus",
  "activeValue": "ACTIVE", 
  "deactivatedValue": "SUSPENDED"
}
```

#### Date Field Mapping

Map various date fields to track customer lifecycle:

```json theme={null}
{
  "createdDate": "signupDate",
  "paidDate": "paymentCompletedAt", 
  "startDate": "serviceStartDate",
  "endDate": "subscriptionExpiresAt"
}
```

## Schema References

To reference another schema, use `$ref` with the `reach:schemas/` URI scheme:

```json theme={null}
{
  "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:

```json theme={null}
// 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:

```json theme={null}
// 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

```bash theme={null}
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)

```bash theme={null}
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

```bash theme={null}
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

```bash theme={null}
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

```bash theme={null}
curl -X GET "https://api.reach.com/partner/schema-definitions" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Get Specific Schema

```bash theme={null}
curl -X GET "https://api.reach.com/partner/schema-definitions/Customer" \
  -H "Authorization: Bearer YOUR_API_KEY"
```
