Error Codes Reference
Understand OnSched API error responses, status codes, and how to handle common issues in your integration.
Environment tip: All examples use
v3.onsched.comfor production. Replace the host withapi-stage.onsched.comwhen calling the staging environment.
Error Response Format
OnSched returns structured error responses with HTTP status codes and descriptive messages. All errors follow this format:
{
"statusCode": 400,
"name": "BadRequestError",
"message": "Missing required parameter: ServiceId",
"errors": [
{
"field": "ServiceId",
"message": "ServiceId is required"
}
]
}- statusCode: HTTP status code indicating error type
- name: Error class name for programmatic handling
- message: Human-readable description
- errors: Array of validation errors (when applicable)
HTTP Status Codes
400 Bad Request
The request is malformed or missing required parameters.
Common causes:
- Missing required query parameters or body fields
- Invalid data types (e.g., string where UUID expected)
- Parameter values outside acceptable ranges
- Date formatting errors
Example:
{
"statusCode": 400,
"name": "BadRequestError",
"message": "Invalid date format. Use ISO 8601 or YYYY-MM-DD",
"errors": [
{
"field": "startDate",
"message": "Invalid date format"
}
]
}How to fix:
- Verify all required parameters are present
- Check parameter types match API schema
- Validate date strings follow ISO 8601 format
- Review the Swagger documentation for endpoint requirements
401 Unauthorized
Authentication credentials are missing, invalid, or expired.
Common causes:
- Missing
Authorizationheader - Expired access token (tokens last one hour)
- Invalid client credentials
- Malformed Bearer token
Example:
{
"statusCode": 401,
"name": "UnauthorizedError",
"message": "Invalid or expired access token"
}How to fix:
- Request a fresh access token via
POST /v3/oauth/token - Ensure
Authorization: Bearer <token>header is included - For dashboard authentication, verify you're including
x-api-keyandx-client-idheaders - See Authentication Guide for credential setup
403 Forbidden
You're authenticated but lack permission for the requested resource.
Common causes:
- Attempting to access another company's data
- Scope restrictions on OAuth token
- Accessing disabled or suspended accounts
- User role lacks necessary permissions
Example:
{
"statusCode": 403,
"name": "ForbiddenError",
"message": "You do not have permission to manage this resource"
}How to fix:
- Verify the resource belongs to your authenticated company
- Check OAuth scope includes required permissions (
read,write) - Ensure company and location accounts are not suspended
- Contact support if role permissions need adjustment
404 Not Found
The requested resource doesn't exist or has been deleted.
Common causes:
- Invalid UUID in URL path
- Resource was soft-deleted (archived)
- Typo in endpoint URL
- Resource belongs to different company
Example:
{
"statusCode": 404,
"name": "NotFoundError",
"message": "Document not found"
}How to fix:
- Double-check UUID values are correct
- Verify resource hasn't been deleted
- Ensure endpoint path matches documentation
- Use
GETendpoints to list resources and confirm IDs
422 Unprocessable Entity
The request is well-formed but fails business logic validation.
Common causes:
- Appointment slot is no longer available
- Time slot conflicts with existing booking
- Duration doesn't align with service configuration
- Resource not linked to requested service
- Date/time is in the past
- Booking exceeds configured limits
Example:
{
"statusCode": 422,
"name": "UnprocessableEntityError",
"message": "The selected time slot is not available. Another appointment may have been booked.",
"errors": [
{
"field": "Unavailability.startTime",
"message": "Time slot conflicts with existing appointment"
}
]
}How to fix:
- Call
GET /v3/availabilitybefore creating appointments - Verify selected resources are linked to the service
- Check service allows requested duration (if using
overrideDuration) - Ensure booking doesn't violate service limits (see Booking Limits)
- For rescheduling, confirm new slot passes validation
500 Internal Server Error
An unexpected error occurred on the server.
Common causes:
- Database connectivity issues
- External service timeout (e.g., calendar sync)
- Unhandled edge case in processing
Example:
{
"statusCode": 500,
"name": "InternalServerError",
"message": "Something went wrong"
}How to fix:
- Retry the request after a brief delay
- Check service status page for known issues
- If persistent, contact support with request details (timestamp, endpoint, request ID if available)
Validation Errors
Endpoints that accept structured input return detailed validation errors:
{
"statusCode": 400,
"name": "BadRequestError",
"message": "Validation failed",
"errors": [
{
"field": "Customer.email",
"message": "Invalid email format"
},
{
"field": "duration",
"message": "Duration must be greater than 0"
}
]
}Each error in the errors array specifies:
- field: Dot-notation path to the invalid field (e.g.,
Customer.email,Unavailability.startTime) - message: Specific reason the field is invalid
Use these to display inline validation messages in your UI.
Common Scenarios
Availability Check Returns Empty
If GET /v3/availability returns no slots:
- Service may have no resources assigned at the location
- Requested date range is outside resource schedules
- All slots are booked
- Service duration doesn't fit within operating hours
Not an error: An empty availability response with status 200 is valid—it means no slots are open.
Appointment Creation Fails After Availability Check
Race conditions can occur if another user books the same slot between your availability check and appointment creation.
Best practice:
- Show available slots from
GET /v3/availability - User selects a slot
- Create appointment immediately—if it fails with
422, refresh availability and ask user to pick again - Consider using holds (
POST /appointment/hold) for multi-step checkouts
Token Expires Mid-Session
OAuth2 tokens last one hour. If you receive 401 errors on long-running sessions:
- Implement automatic token refresh when
401is encountered - Store token expiration time (
expires_in) and proactively refresh before expiry - Don't hardcode tokens—request them programmatically
Error Handling Best Practices
Retry Logic
Implement exponential backoff for transient errors:
- Retry:
500,503status codes (server errors) - Don't retry:
400,401,403,404,422(client errors require fixing the request)
Example retry strategy:
- Wait 1 second, retry
- If still failing, wait 2 seconds, retry
- If still failing, wait 4 seconds, retry
- After 3 attempts, show error to user
User-Friendly Messages
Don't expose raw API errors to end users:
| API Error | User-Friendly Message |
|---|---|
401 Unauthorized | "Session expired. Please log in again." |
404 Not Found | "This appointment could not be found. It may have been cancelled." |
422 Unprocessable Entity (slot conflict) | "This time is no longer available. Please choose another slot." |
500 Internal Server Error | "We're experiencing technical difficulties. Please try again shortly." |
Logging
Log all API errors with context for debugging:
- Request method and URL
- Request headers (excluding sensitive tokens)
- Request body
- Response status and body
- Timestamp
- User/session identifier
Webhook Errors
Webhook deliveries don't retry automatically. If your webhook endpoint fails:
- Return a
2xxstatus code to acknowledge receipt - Process webhook payloads asynchronously to avoid timeouts
- Log all incoming webhooks for manual reprocessing if needed
- Monitor webhook endpoint health
- See Webhook Guide for details
Testing Error Scenarios
Use invalid data to test error handling:
# Test 400 - missing required parameter
curl https://v3.onsched.com/v3/availability \
-H "Authorization: Bearer YOUR_TOKEN"
# Test 401 - invalid token
curl https://v3.onsched.com/v3/company \
-H "Authorization: Bearer invalid_token_12345"
# Test 404 - nonexistent resource
curl https://v3.onsched.com/v3/appointment/00000000-0000-0000-0000-000000000000 \
-H "Authorization: Bearer YOUR_TOKEN"
# Test 422 - invalid business logic
curl -X POST "https://v3.onsched.com/v3/appointment?LocationId=LOC_ID&ServiceId=SVC_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Unavailability": {
"startTime": "2020-01-01T10:00:00Z",
"endTime": "2020-01-01T10:30:00Z"
},
"duration": 30
}'Build comprehensive error handling early—it improves user experience and makes debugging easier.
Need Help?
If you encounter errors not covered here:
- Check the Swagger documentation for endpoint-specific requirements
- Review related guides (Authentication, Availability, Appointments)
- Contact support with error details and request information
- Consult the Glossary for terminology clarification
Updated 4 days ago
