Custom Booking Fields
Extend appointments with custom data fields to capture intake information, preferences, or integration-specific metadata.
Environment tip: All examples use
v3.onsched.comfor production. Replace the host withapi-stage.onsched.comwhen calling the staging environment.
What Are Custom Fields?
Custom Fields allow you to attach additional data to appointments beyond the standard properties (customer, time, service, resources). Store information like:
- Intake forms – Health conditions, preferences, special requests
- Business data – Order numbers, project IDs, reference codes
- Integration metadata – External system IDs, sync tokens
- Custom questions – Any information relevant to your workflow
Custom Fields are stored as key-value pairs and returned with appointment data.
How Custom Fields Work
Data Structure
Custom Fields are stored in an HSTORE format (PostgreSQL key-value store):
{
"CustomFields": {
"dietaryRestrictions": "vegan",
"parking": "required",
"referralSource": "google",
"notes": "prefers morning appointments"
}
}- Keys – Field names (strings)
- Values – Field values (strings only)
All values are strings—store numbers, booleans, or dates as strings and parse in your application.
Where Custom Fields Appear
Custom Fields can be attached to:
- Appointments – Most common use case
- Customers – Customer profile data
- Services – Service metadata
- Resources – Resource attributes
- Locations – Location-specific settings
This guide focuses on appointment custom fields.
Creating Appointments with Custom Fields
Basic Example
curl -X POST "https://v3.onsched.com/v3/appointment?\
LocationId=LOCATION_ID&\
ServiceId=SERVICE_ID" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Customer": {
"firstName": "Alex",
"lastName": "Chen",
"email": "[email protected]"
},
"Unavailability": {
"startTime": "2025-12-01T10:00:00Z",
"endTime": "2025-12-01T10:30:00Z"
},
"duration": 30,
"CustomFields": {
"howDidYouHear": "friend referral",
"specialRequests": "needs wheelchair access",
"confirmationPreference": "sms"
}
}'Response includes CustomFields:
{
"id": "appointment-uuid",
"status": "BK",
"Customer": {...},
"CustomFields": {
"howDidYouHear": "friend referral",
"specialRequests": "needs wheelchair access",
"confirmationPreference": "sms"
},
...
}Intake Form Example
For appointments requiring pre-booking questions:
{
"CustomFields": {
"hasAllergies": "true",
"allergyDetails": "peanuts, shellfish",
"medications": "none",
"emergencyContactName": "Jamie Chen",
"emergencyContactPhone": "+15550100",
"insuranceProvider": "BlueCross",
"insuranceId": "BC123456789"
}
}Build intake forms in your UI and pass responses as CustomFields.
Integration Metadata Example
For syncing with external systems:
{
"CustomFields": {
"crmContactId": "salesforce-12345",
"externalOrderId": "ORDER-2025-001",
"syncToken": "abc123def456",
"importedFrom": "legacy-system",
"legacyAppointmentId": "old-db-999"
}
}Use CustomFields to maintain references to external databases.
Updating Custom Fields
Replacing All Custom Fields
Use PUT /v3/appointment/:id to replace CustomFields entirely:
curl -X PUT https://v3.onsched.com/v3/appointment/APPOINTMENT_ID \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"CustomFields": {
"arrived": "true",
"arrivalTime": "2025-12-01T09:55:00Z",
"checkedInBy": "receptionist-jane"
}
}'This replaces any existing CustomFields with the new object.
Partial Updates
To add or modify specific fields without losing existing ones:
- Retrieve current appointment with
GET /v3/appointment/:id - Merge new fields into existing
CustomFields - Send full
CustomFieldsobject viaPUT
Example:
# Step 1: Get current appointment
current_fields=$(curl https://v3.onsched.com/v3/appointment/APPOINTMENT_ID \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" | jq '.CustomFields')
# Step 2: Merge with new fields (application logic)
# Add: "checkedIn": "true"
# Step 3: Update with merged fields
curl -X PUT https://v3.onsched.com/v3/appointment/APPOINTMENT_ID \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"CustomFields": {
...existing_fields,
"checkedIn": "true"
}
}'Retrieving Custom Fields
Custom Fields are included in all appointment responses:
# Get single appointment
curl https://v3.onsched.com/v3/appointment/APPOINTMENT_ID \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# List appointments (includes CustomFields for each)
curl https://v3.onsched.com/v3/appointments?limit=20 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Response:
{
"id": "appointment-uuid",
"status": "BK",
"CustomFields": {
"field1": "value1",
"field2": "value2"
},
...
}Empty CustomFields return as {} (empty object), never null.
Use Cases
Healthcare Intake
Capture patient information before appointments:
{
"CustomFields": {
"reasonForVisit": "annual checkup",
"symptoms": "none",
"hasInsurance": "true",
"primaryPhysician": "Dr. Martinez",
"consentFormSigned": "true"
}
}Event Registration
For workshops, classes, or events:
{
"CustomFields": {
"companyName": "Acme Corp",
"jobTitle": "Marketing Manager",
"attendeeCount": "1",
"dietaryRestrictions": "vegetarian",
"shirtSize": "medium"
}
}Service Customization
For customizable services:
{
"CustomFields": {
"preferredStylist": "Jane",
"serviceAdd-ons": "deep conditioning,scalp massage",
"productPreference": "organic-only",
"colorFormula": "mix-45-30-25"
}
}Delivery or On-Site Services
For mobile or home services:
{
"CustomFields": {
"serviceAddress": "123 Main St, Apt 4B",
"parkingInstructions": "use visitor spots",
"accessCode": "1234",
"petInfo": "friendly dog, will secure before arrival"
}
}Equipment Rentals
For tracking rental details:
{
"CustomFields": {
"equipmentType": "kayak-single",
"helmSize": "large",
"experienceLevel": "beginner",
"emergencyContact": "+15550999",
"liabilityWaiverSigned": "true"
}
}Data Types and Formatting
String Values Only
All CustomFields values are strings. Store other types as strings:
{
"CustomFields": {
"attendeeCount": "5", // number as string
"confirmed": "true", // boolean as string
"preferredDate": "2025-12-15", // date as string
"arrivalTime": "09:45", // time as string
"metadata": "{\"key\":\"value\"}" // JSON as escaped string
}
}Parse values in your application logic.
Multi-Value Fields
For fields with multiple values, use delimiters:
{
"CustomFields": {
"selectedAddOns": "addon1,addon2,addon3",
"allergies": "peanuts|shellfish|dairy"
}
}Split on delimiter (, or |) in your application.
Null or Empty Values
To "unset" a field:
{
"CustomFields": {
"fieldToRemove": ""
}
}Or omit the field when updating. Empty strings are stored as-is.
Validation
No Built-In Validation
OnSched doesn't validate CustomFields—you can store any key-value pairs. Validation is your responsibility:
- Check required fields in your application
- Validate formats (email, phone, date)
- Enforce business rules (e.g., insurance required for certain services)
- Sanitize user input
Field Name Conventions
Use clear, consistent naming:
- camelCase –
emergencyContactName - snake_case –
emergency_contact_name - kebab-case –
emergency-contact-name(less common)
Pick one convention and stick to it.
Size Limitations
While there's no strict limit per field, keep values reasonable:
- Short answers – Under 255 characters
- Long text – Use appointment
notesfield instead - File uploads – Store URLs, not file contents
CustomFields aren't designed for large blobs of data.
Security and Privacy
Sensitive Data
Be cautious storing sensitive information:
- PII (personally identifiable information) – Secure your database
- Payment details – Never store credit card numbers in CustomFields
- Health information – Ensure HIPAA compliance if applicable
CustomFields are stored in plaintext. Encrypt sensitive data before storing if necessary.
Access Control
CustomFields are visible to:
- Authenticated company users via API
- Public appointment endpoints (if exposed)
Don't store internal-only data in CustomFields on public-facing appointments.
Integration Patterns
CRM Sync
Store CRM IDs for bi-directional sync:
{
"CustomFields": {
"salesforceContactId": "003xx000004TmiD",
"salesforceLeadSource": "Website",
"lastSyncedAt": "2025-11-25T12:34:56Z"
}
}Query appointments by CRM ID to update records.
Analytics Tracking
Capture attribution data:
{
"CustomFields": {
"utmSource": "google",
"utmMedium": "cpc",
"utmCampaign": "spring-promo",
"referralCode": "FRIEND20"
}
}Export appointments with CustomFields for reporting.
Order Management
Link appointments to orders:
{
"CustomFields": {
"orderId": "ORD-2025-1234",
"orderTotal": "150.00",
"paymentStatus": "paid",
"invoiceUrl": "https://example.com/invoices/1234"
}
}Track fulfillment status via appointments.
Searching and Filtering
Limitations
OnSched's API doesn't currently support filtering appointments by CustomFields directly in list endpoints.
Workaround:
- Retrieve appointments via
GET /v3/appointments - Filter by CustomFields in your application
Example (pseudocode):
const appointments = await fetchAppointments();
const filtered = appointments.filter(apt =>
apt.CustomFields.referralSource === 'google'
);Future Enhancements
Check API documentation for updates on CustomFields search capabilities.
Best Practices
Plan Your Schema
Document CustomFields before implementation:
Field Name | Type | Required | Example
----------------------|---------|----------|------------------
howDidYouHear | string | no | "google"
specialRequests | string | no | "wheelchair access"
confirmationPreference| string | yes | "email" or "sms"
Consistency across appointments makes reporting easier.
Use Descriptive Names
Avoid cryptic keys:
- Bad:
cf1,data,temp - Good:
referralSource,dietaryRestrictions,emergencyContact
Future you (and your team) will thank you.
Don't Overload CustomFields
For extensive data, consider:
- Appointment notes – Long-form text
- Customer CustomFields – Profile data that persists across appointments
- External database – Link via ID in CustomFields
Keep CustomFields lean and focused.
Version Your Schema
If CustomFields schema evolves:
{
"CustomFields": {
"schemaVersion": "2",
"field1": "value1"
}
}This helps when migrating data or supporting multiple versions.
Test Thoroughly
Before going live:
- Create appointments with various CustomFields
- Retrieve and verify fields are present
- Update appointments and confirm changes persist
- Handle missing or malformed fields gracefully
Troubleshooting
CustomFields not appearing in response
Check:
- Fields were included in create/update request
- Request succeeded (check status code)
- Appointment is from your company (not another company's data)
- Using authenticated endpoints (public endpoints may omit CustomFields)
CustomFields lost after update
Cause: Updates replace CustomFields entirely, not merge them.
Solution: Always include all CustomFields in updates, even unchanged ones.
Cannot filter appointments by CustomField
Limitation: Direct API filtering by CustomFields isn't supported.
Solution: Filter in application layer after fetching appointments.
CustomFields appearing as null
Cause: Appointment was created without CustomFields.
Behavior: OnSched returns {} for empty CustomFields, not null. If you're seeing null, check response parsing logic.
Common Questions
Can I change field names after creating appointments?
CustomFields are flexible—you can add new fields anytime. Old appointments retain their original fields.
To "rename" a field across appointments, write a migration script.
Is there a limit on number of fields?
No hard limit, but keep it reasonable (typically under 20 fields). Excessive fields increase payload size and complexity.
Can I store arrays or objects?
Not natively. Serialize as JSON strings:
{
"CustomFields": {
"selectedOptions": "[\"option1\",\"option2\"]"
}
}Parse in your application.
Are CustomFields indexed for search?
Yes, CustomFields are indexed in PostgreSQL HSTORE, allowing efficient queries at the database level. However, API endpoints don't currently expose CustomField filtering directly.
Can customers see CustomFields?
Depends on your implementation:
- Dashboard: Customers see whatever you display
- API: Public endpoints may include or exclude CustomFields based on configuration
Control visibility in your UI layer.
Related Documentation
- Appointment Guide – Complete appointment management
- Customer Custom Fields – Custom fields on customer records
- Services Overview – Service custom fields
- Getting Started – Authentication and first API calls
Custom Fields unlock powerful customization without requiring schema changes. Plan your fields thoughtfully, validate in your application, and use them to tailor OnSched to your exact business needs.
Updated 4 days ago
