Validation
SchemaStack validates request data against your entity's column constraints before persisting. When validation fails, the API returns a 422 Unprocessable Entity response with per-field error details.
How It Works
Constraints defined on your columns (via the SchemaStack UI or API) are automatically enforced on every create and update request. No additional configuration is needed.
- Create (POST): All constraints are checked, and required fields (non-nullable columns) must be present.
- Update (PUT): Only the submitted fields are validated. Missing fields are not treated as errors (partial updates are allowed).
Validation Error Format
When one or more fields fail validation, the response includes a details array listing each error:
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed: 2 error(s)",
"details": [
{ "field": "email", "message": "must be a valid email address" },
{ "field": "name", "message": "name is required" }
]
}
}Constraint Types
| Type | Applies To | Description | Example Value |
|---|---|---|---|
NOT_BLANK | String | Must not be blank or whitespace-only | — |
MIN_LENGTH | String | Minimum character length | "5" |
MAX_LENGTH | String | Maximum character length | "100" |
PATTERN | String | Must match a regex pattern | "^[A-Z]{3}$" |
EMAIL | String | Must be a valid email address | — |
URL | String | Must be a valid URL | — |
MIN | Number | Minimum numeric value | "0" |
MAX | Number | Maximum numeric value | "999" |
POSITIVE | Number | Must be greater than zero | — |
NEGATIVE | Number | Must be less than zero | — |
POSITIVE_OR_ZERO | Number | Must be zero or greater | — |
NEGATIVE_OR_ZERO | Number | Must be zero or less | — |
Built-In Checks
In addition to explicit constraints, the API automatically validates:
- Required fields: Non-nullable columns must be present on create requests.
- Column length: String values cannot exceed the column's defined
length. - Type matching: Values must be compatible with the column type (e.g., numbers for INTEGER columns, strings for VARCHAR).
Create vs. Update
| Check | Create (POST) | Update (PUT) |
|---|---|---|
| Required fields (non-nullable) | Enforced | Skipped |
| Type validation | Enforced | Enforced |
| Column length | Enforced | Enforced |
| Constraint rules | Enforced | Enforced |
Custom Error Messages
When defining constraints, you can optionally set a custom error message. If no custom message is set, a sensible default is used:
json
// Constraint with custom message
{
"type": "PATTERN",
"value": "^[A-Z]{3}-\\d{4}$",
"message": "Product code must follow the format ABC-1234"
}
// Default message: "must match pattern: ^[A-Z]{3}-\\d{4}$"Examples
Creating a Record with Validation Errors
bash
curl -X POST ".../api/v1/acme-corp/sales/products" \
-H "Authorization: Bearer sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"price": -5,
"sku": "invalid"
}'Response (422):
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed: 3 error(s)",
"details": [
{ "field": "name", "message": "name is required" },
{ "field": "price", "message": "must be positive" },
{ "field": "sku", "message": "must match pattern: ^[A-Z]{3}-\\d{4}$" }
]
}
}Updating with Partial Data (Valid)
bash
curl -X PUT ".../api/v1/acme-corp/sales/products/42" \
-H "Authorization: Bearer sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{ "price": 29.99 }'Response (200) — name is not required on update:
json
{
"data": {
"id": 42,
"name": "Widget",
"price": 29.99,
"sku": "WDG-0001"
}
}