Validation Rules
Learn how to create, update, and manage validation rules on monday.com boards to enforce data quality through the API
Only available in API versions
2026-07and later
Validation rules let you enforce data quality on monday.com boards by defining constraints on column values. Unlike required columns which simply mark a column as mandatory, validation rules support comparison operators, value ranges, and conditional logic.
This guide walks you through the validation rules API from simple constraints to conditional rules. By the end, you'll be able to programmatically enforce business rules like "amounts must be at least 5" or "if the status is Done, the description must be filled in."
Key concepts
How validation rules work
A validation rule has two parts:
| Part | Required | Description |
|---|---|---|
then | Yes | The constraint that must be satisfied. Defines what the column value should look like. |
if | No | A condition that triggers the rule. When provided, the then constraint only applies when the if condition is met. |
Rules without an if clause are non-conditional — they always apply. Rules with an if clause are conditional — they only apply when the condition is met.
Enforcement
Validation rules are enforced both in the monday.com interface and through the API. When you create or update items via mutations like create_item, change_simple_column_value, or change_column_values, the API checks active validation rules and rejects requests that violate them with a DATA_VALIDATIONS_ERROR error (422 status code).
The error response includes details about which columns failed validation:
{
"errors": [
{
"message": "data_validation_error",
"extensions": {
"code": "DATA_VALIDATIONS_ERROR",
"status_code": 422,
"error_data": [
{
"itemId": null,
"columnIds": ["numeric_mm1pddwd"],
"message": "'Amount' must be at least [5]"
}
]
}
}
]
}Relationship to required columns
Validation rules and required columns are separate features that coexist on the same board:
- Required columns (
add_required_column/remove_required_column) mark a column as mandatory. The column must have a value, but there's no constraint on what that value is. - Validation rules (
create_validation_rule/update_validation_rule/delete_validation_rule) define constraints on what values are acceptable.
Both appear in the validations query response — required columns in required_column_ids and rules in rules.
Prerequisites
- API authentication token
- A board ID (find it in the URL:
monday.com/boards/{board_id}) - Familiarity with the column IDs on your board (query
boards→columns→id) - Requests must include the
API-Version: 2026-07header - Pro or Enterprise monday.com account
Creating your first rule
Simple unconditional rule
Let's create a rule that requires a status column to be one of two specific values (label indices 1 and 2):
mutation {
create_validation_rule(
id: 1234567890,
type: board,
rule: {
then: {
operator: AND,
groups: [{
operator: ANY_OF,
column_id: "status",
compare_value: [1, 2]
}]
}
}
) {
id
if
then
}
}The response includes the generated rule ID:
{
"data": {
"create_validation_rule": {
"id": "cd7f1b7b-452e-40d3-886c-346184ffee7e",
"if": null,
"then": {
"operator": "AND",
"groups": [
{
"operator": "ANY_OF",
"column_id": "status",
"compare_value": [1, 2]
}
]
}
}
}
}Key things to note:
- The
thenclause requires anoperator(ANDorOR) and agroupsarray of constraints - Each constraint targets a
column_idwith a comparisonoperatorand optionalcompare_value - Non-conditional rules return
nullfor theiffield - The returned
idis a UUID you'll use for updates and deletes
Numeric constraint
Require a numbers column to be at least 5:
mutation {
create_validation_rule(
id: 1234567890,
type: board,
rule: {
then: {
operator: AND,
groups: [{
operator: GREATER_THAN_OR_EQUALS,
column_id: "numbers0",
compare_value: [5]
}]
}
}
) {
id
then
}
}Date range constraint
Require a date column to fall within a specific range:
mutation {
create_validation_rule(
id: 1234567890,
type: board,
rule: {
then: {
operator: AND,
groups: [{
operator: BETWEEN,
column_id: "date0",
compare_value: ["2026-01-01", "2026-12-31"]
}]
}
}
) {
id
then
}
}Text constraint
Require a text column to contain a specific substring:
mutation {
create_validation_rule(
id: 1234567890,
type: board,
rule: {
then: {
operator: AND,
groups: [{
operator: CONTAINS_TEXT,
column_id: "text0",
compare_value: ["REQ-"]
}]
}
}
) {
id
then
}
}Conditional rules
Conditional rules use an if clause to gate when the then constraint applies. This lets you build logic like "if the status is Done, then the description must be filled in."
Basic conditional rule
mutation {
create_validation_rule(
id: 1234567890,
type: board,
rule: {
if: {
operator: AND,
groups: [{
operator: ANY_OF,
column_id: "status",
compare_value: [1]
}]
},
then: {
operator: AND,
groups: [{
operator: IS_NOT_EMPTY,
column_id: "text0"
}]
}
}
) {
id
if
then
}
}
IS_NOT_EMPTY in conditional rulesThe
IS_NOT_EMPTYoperator is only available inside conditional rules (rules with anifclause). It cannot be used in non-conditional rules. Use it in thethenclause to require a column to have a value when a condition is met.
Multiple then constraints
Conditional rules can enforce multiple constraints at once. If a condition is met, require both a numbers column and a date column to be filled:
mutation {
create_validation_rule(
id: 1234567890,
type: board,
rule: {
if: {
operator: AND,
groups: [{
operator: ANY_OF,
column_id: "priority",
compare_value: [1]
}]
},
then: {
operator: AND,
groups: [
{
operator: IS_NOT_EMPTY,
column_id: "numbers0"
},
{
operator: IS_NOT_EMPTY,
column_id: "date0"
}
]
}
}
) {
id
if
then
}
}Updating and deleting rules
Update a rule
Use update_validation_rule with the rule's ID. You must provide the full rule definition — partial updates are not supported:
mutation {
update_validation_rule(
id: 1234567890,
type: board,
rule_id: "cd7f1b7b-452e-40d3-886c-346184ffee7e",
rule: {
then: {
operator: AND,
groups: [{
operator: GREATER_THAN_OR_EQUALS,
column_id: "numbers0",
compare_value: [10]
}]
}
}
) {
id
if
then
}
}Delete a rule
mutation {
delete_validation_rule(
id: 1234567890,
type: board,
rule_id: "cd7f1b7b-452e-40d3-886c-346184ffee7e"
) {
id
}
}The mutation returns the deleted rule's data.
Reading validation rules
Query the validations endpoint to see all validation rules and required columns on a board:
query {
validations(id: 1234567890) {
required_column_ids
rules
}
}The rules field returns a JSON object where each key is a rule ID and each value is the rule definition:
{
"data": {
"validations": {
"required_column_ids": null,
"rules": {
"80d2c9d3-c93d-40be-9d34-b611241345b5": {
"then": {
"operator": "AND",
"groups": [{
"operator": "GREATER_THAN_OR_EQUALS",
"column_id": "numbers0",
"compare_value": [5]
}]
}
},
"31933592-171a-47ae-93a5-7a1c214fc9a3": {
"if": {
"operator": "AND",
"groups": [{
"operator": "ANY_OF",
"column_id": "status",
"compare_value": [1]
}]
},
"then": {
"operator": "AND",
"groups": [{
"operator": "IS_NOT_EMPTY",
"column_id": "text0",
"compare_value": []
}]
}
}
}
}
}
}
NOTEIn the query response, conditional rules include both
ifandthenkeys. Non-conditional rules only have athenkey (theifkey is absent, notnull). This differs from the mutation response whereifis explicitlynull.
Supported operators by column type
Not all operators work with all column types. Here's a summary of supported combinations for non-conditional rules:
| Column Type | ANY_OF | NOT_ANY_OF | GREATER_THAN | GREATER_THAN_OR_EQUALS | LOWER_THAN | LOWER_THAN_OR_EQUAL | BETWEEN | CONTAINS_TEXT | STARTS_WITH_TEXT | NOT_CONTAINS_TEXT |
|---|---|---|---|---|---|---|---|---|---|---|
| Status | ✅ | ✅ | — | — | — | — | — | — | — | — |
| Numbers | — | — | ✅ | ✅ | ✅ | ✅ | — | — | — | — |
| Text | — | — | — | — | — | — | — | ✅ | ✅ | ✅ |
| Date | — | — | ✅ | — | — | — | ✅ | — | — | — |
| Rating | ✅ | — | — | — | — | — | — | — | — | — |
For conditional rules, the then clause additionally supports IS_NOT_EMPTY and IS_EMPTY across column types.
Constraints and limitations
| Constraint | Description |
|---|---|
| One non-conditional rule per column | A column can have at most one non-conditional rule. |
| No mixing rule types | A column cannot have both conditional and non-conditional rules. |
Single if constraint | Conditional rules must have exactly one constraint in the if clause. |
Single then for non-conditional | Non-conditional rules must have exactly one constraint in the then clause. |
Multiple then for conditional | Conditional rules can have multiple constraints in the then clause. |
| Pro/Enterprise only | Validation rules require a Pro or Enterprise plan. |
| Enforced in UI and API | Rules are enforced in both the monday.com UI and via the API. API requests that violate rules return a DATA_VALIDATIONS_ERROR (422). |
Compare value formats
The compare_value array format varies by column type:
| Column Type | Operator | compare_value | Notes |
|---|---|---|---|
| Status | ANY_OF | [1, 2] | Label indices as integers |
| Numbers | GREATER_THAN | [5] | Single numeric value |
| Text | CONTAINS_TEXT | ["search term"] | Single string |
| Date | BETWEEN | ["2026-01-01", "2026-12-31"] | Two date strings in YYYY-MM-DD |
| Date | GREATER_THAN | ["EXACT", "2026-01-01"] | Prefix with "EXACT" for exact date |
| Rating | ANY_OF | [4, 5] | Rating values as integers |
| Any | IS_EMPTY | (omit or empty) | No compare_value needed |
| Any | IS_NOT_EMPTY | (omit or empty) | No compare_value needed |
Next steps
- Validations reference — Full query and mutation documentation
- Validations other types — Input types, enums, and operator details
- Columns reference — Column types and IDs
If you have questions, post them in the monday developer community.
Updated about 1 hour ago
