Skip to content

Validation Rules API

What is the Arc Rule Validation Service?

The Arc Rule Validation Service is an API-driven tool designed to automatically check content for compliance with a set of predefined rules or business logic before it is published or processed in Arc XP.

This service helps ensure that content meets quality standards and editorial policies as defined by your organization prior to being published and provides consistent checks on content whether that content is created in an Arc experience or via API.

Service Capabilities

  1. Flexible Rule Engine
    • Rules are defined using a standard schema and are highly customizable to meet your specific needs.
  2. Integrations into Arc workflows
    • Because its API based it can be embedded into editorial or programmatic workflows within Arc XP.
    • Arc UIs, and external integrators can use the API to set rules and they can call this API to validate content in real time based on the defined rules.
  3. With the engine it checks your content against Validation Rules
    • Checks your content against a set of custom rules, such as:
      • Are required metadata fields included?
      • Does the body of the content contain Header formatting that is not supported?
      • Do the number of tags included meet editorial rules?
  4. On content submission the service returns:
    • A list of all rule checks performed.
    • Which rules passed or failed.

Example Use Cases

Editorial Gatekeeping
Prevent articles from being published without required fields (e.g., headline, byline, main image).

SEO & Metadata QA
Ensure all stories include SEO metadata, alt text, or canonical URLs.

Developer Automation
With the validation API it enables automating QA checks before publishing content via IFX, custom integrations, or AI workflows.

How It Works (Simplified)

  1. Create or configure rules using Arc’s validation schema.
  2. Send a request with the content data to the Rule Validation API.
  3. Receive a response that shows which rules passed or failed and why.
  4. Take action (e.g., block publish, highlight issues) in Composer or, for those customers not using Arc’s experience layer, provide API level enforcement of rule and surface them in your chosen editorial interface.

Benefits for Customers

  • Faster publishing with fewer manual checks
  • Stronger content consistency and compliance
  • Automation-friendly for large editorial teams or custom workflows
  • Seamless fit with Arc XP architecture

Technical Format

  • Accepts a POST request with:
    • A set of rules
    • The content payload
  • Returns a structured validation result for each rule

Creating & Managing Rules in Arc Rule Validation

The Rule Validation Service is built around a flexible, JSON-based rule definition schema. This allows your team to define rules that suit your specific editorial standards, business requirements, and content types.

Rule Structure Overview

A rule is a set of conditions designed to validate content against predefined criteria. These rules establish what content is considered valid and provide feedback when the content fails to meet the specified standards.

Each rule is defined as a JSON object with specific properties that tell the service:

  • What to check in the content
  • How to evaluate it
  • What error message to show if it fails

A rule is composed of:

  • ruleName: A unique identifier formatted in kebab-case (e.g., headline-length-check)
  • level: The severity level of the rule (error or warning)
  • conditions: A collection of conditions that must be satisfied
  • operation: The specific operation to which this rule applies, it must be formatted in kebab-case (e.g., arc-story-publish)
  • locales: User-friendly messages in various languages for when the rule fails
  • status: Indicates whether the rule is enabled or disabled

Example:

{
"ruleName": "distributor-field-check",
"operation": "arc-story-publish",
"level": "error",
"status": "enabled",
"locales": [
{
"text": "distributor field should exist",
"locale": "en-US"
}
],
"conditions": {
"all": [
{
"field": "distributor",
"operator": "exist"
}
]
}
}

Conditions

Conditions are the fundamental components of a rule that define the validation criteria. They can be organized in two ways:

  • All conditions: Every condition must be true for the rule to pass (all)
  • Any conditions: At least one condition must be true for the rule to pass (any)

Each condition includes:

  • field: The specific field in the content to validate
  • operator: The comparison operator (refer to the Operators section)
  • value: The value to compare against (not required for certain operators)
  • path (optional): JSON path for accessing nested properties

Locales

Locales are essential for defining user-friendly messages that appear when a rule validation fails. They facilitate the internationalization of error and warning messages.

Each locale includes:

  • text: The message to be displayed (maximum length: 100 characters)
  • locale: The language and region code formatted as {language code}-{country code} (e.g., en-US, es-MX)
  • language (optional): Additional language information

A minimum of one locale is required for each rule, with a maximum of four locales allowed per rule. This structure enables feedback to be provided in multiple languages according to user preferences.

Example:

[
{
"locale": "en-US",
"text": "The headline must be between 10 and 100 characters long."
},
{
"locale": "es-MX",
"text": "El titular debe tener entre 10 y 100 caracteres de longitud."
}
]

Limitations

  1. Rules:

    • A maximum of 5 rules can be created for a single operation
    • Rule names must be formatted in kebab-case (e.g., example-rule)
  2. Conditions:

    • A maximum of 5 conditions per rule
  3. Locales:

    • A maximum of 4 locales per rule

    • The maximum length for locale text is 100 characters

  4. Operations:

    • Operations prefixed with arc- are reserved for Arc system operations

    • Reserved operations (e.g., arc-story-publish, arc-story-save) should not be altered frequently, as changes may affect system behavior

    • Custom integrations should utilize their own operation names

  5. Operators:

    • Numeric operators (lessThan, greaterThan, lengthEquals, lengthGreaterThan, lengthLessThan) require numeric values

    • Certain operators (isEmpty, exist) do not necessitate a value parameter

Supported Operators for Rule Validation

The Arc Rule Validation service supports a variety of operators that compare values from content against specified rules.

  • equal: Checks if the field value matches the specified value.
  • not: Verifies that the field value does not match the specified value.
  • contains: Determines if an array contains a specified value.
  • lessThan: Assesses if the field value is less than the specified value.
  • greaterThan: Evaluates if the field value is greater than the specified value.
  • lengthEquals: Checks if the length of the field value is equal to the specified value.
  • lengthLessThan: Validates if the length of the field value is less than the specified value.
  • lengthGreaterThan: Confirms if the length of the field value is greater than the specified value.
  • isEmpty: Determines if the field value is empty.
  • exist: Checks if the field value exists (is not undefined).

Sample Content:

{
"_id": "5B5FFHTU7BF6LP3MMHAWJFDJBA",
"type": "image",
"version": "0.0.10",
"workflow": {
"status_code": 2
},
"source": {
"source_type": "wired",
"system": "arc i/o"
},
"headlines": "Hello! This is the Headlines <h2>",
"arrayCheck": ["a", "b", "c"],
"emptyCheck": null,
"emptyCheck1": "",
"emptyCheckObject": {},
"taxonomy": {
"keywords": [
{
"keyword": "movies",
"score": "1"
},
{
"keyword": "casting",
"score": "1"
},
{
"keyword": "film",
"score": "1"
},
{
"keyword": "tv",
"score": "1"
},
{
"keyword": "entertainment",
"score": "1"
},
{
"keyword": "acting",
"score": "1"
}
]
}
}

Operator Examples:

equal

Operator checks if the field value is equal to the specified value.

Examples:

Condition: checking field value

{
"field": "type",
"operator": "equal", => success (checks type is image)
"value": "image"
}

Condition: checking object

{
"field": "workflow",
"operator": "equal",
"value": {
"status_code": 2 => success (checks workflow object)
}
}

Condition: checking field within object

{
"field": "source",
"path": "source_type", => sucess (checks source_type is wired)
"operator": "equal",
"value": 'wired'
}

not

Operator checks if the field value is not equal to the specified value. For object values, it does a deep comparison.

Examples:

Condition: checking field value

{
"field": "type",
"operator": "not", => success (checks type is not story)
"value": "story"
}

Condition: checking object

{
"field": "workflow",
"operator": "not",
"value": {
"status_code": 5 => success (cheks workflow not equal)
}
}

Condition: checking field within object

{
"field": "source",
"path": "source_type", => sucess (checks source_type is not online)
"operator": "not",
"value": 'online'
}

contains

Operator checks if array contains specified value. Operator applies to field values with arrays.

Examples

Condition: checking value is in array of strings

{
"field": "arrayCheck",
"operator": "contains", => success (checks if arrayCheck has value 'a')
"value": "a"
}

Condition: checking value is in array of object

{
"field": "taxonomy",
"operator": "contains",
"path": "$.keywords[*].keyword",
"value": "movies"
}

lessThan

Operator checks if the field value is less than the specified value.

Examples:

Condition: checking field value of object less than specified value.

{
"field": "workflow",
"operator": "lessThan",
"path": "$.status_code", => success (sample input has status_code 2)
"value": 3
}

greaterThan

Operator checks if the field value is greater than the specified value.

Examples:

Condition: checking field value of object greater than specified value

{
"field": "workflow",
"operator": "lessThan",
"path": "$.status_code", => success (sample input has status_code 2)
"value": 1
}

lengthEquals

Operator Checks if the length of the field value is equal to the specified value

  • String - checks character count
  • Array - checks number of elements

Examples:

Condition: checking headline characters are equals to specified value

{
"field": "headlines",
"operator": "lengthEquals",
"value": 8
}

lengthLessThan

Operator checks if the length of the field value is less than the specified value.

  • String - checks character count
  • Array - checks number of elements

Examples:

Condition: checking headline characters is less than to specified value

{
"field": "headlines",
"operator": "lengthLessThan",
"value": 8
}

Condition: checking array length are equals to specified value

{
"field": "arrayCheck",
"operator": "lengthLessThan",
"value": 3
}

lengthGreaterThan

Operator checks if the length of the field value is greater than the specified value.

  • String - checks character count
  • Array - checks number of elements

Examples:

Condition: checking field value of object greater than specified value

{
"field": "headlines",
"operator": "lengthGreaterThan",
"value": 8
}

Condition: checking array length are equals to specified value

{
"field": "arrayCheck",
"operator": "lengthGreaterThan",
"value": 3
}

isEmpty

Operator checks if the field value is empty.

  • Returns true if:
    • The value is null
    • The value is an empty string
    • The value is an empty array
    • The value is an empty object (no keys)

Examples:

Condition: checking field has empty value or null value

{
"field": "emptyCheck", => success (emptyCheck is null)
"operator": "isEmpty"
}
------------------------------------------------------------------------
{
"field": "emptyCheck1", => success (emptyCheck1 is empty string)
"operator": "isEmpty"
}
------------------------------------------------------------------------
{
"field": "emptyCheckObject", => success (emptyCheckObject has not keys)
"operator": "isEmpty"
}
------------------------------------------------------------------------
{
"field": "arrayCheck", => failure (arrayCheck array has values)
"operator": "isEmpty"
}

exist

Checks if the field value exists (is not undefined)

Examples:

Condition: checking field is present

{
"field": "existCheck", => failure (existCheck is not present in content)
"operator": "exist"
}
--------------------------------------------------------------------------------
{
"field": "arrayCheck", => success (arrayCheck field is present)
"operator": "exist"
}

Where Rules Are Stored

  • Individual Rules can be submitted in-line in a validation API call.
  • Individual rules and rule sets can also be stored centrally in a system Arc XP or your dev team configures (e.g., GitHub, config store, or admin UI).
  • Individual rules and rule sets can also be stored in a source control system and sent to the API when called for. We suggested GitHub or similar service.

Rule Validation Workflow

Rule-sets are specified on their keys which act as events. Arc integrations will trigger on those events. For example Composer has created their own arc-composer-save and arc-composer-publish events.

For Draft API we only have one event that is implemented to run a check against arc-story-publish for when you publish a story.

Therefore rule-sets will apply to attempts to publish a piece of content. Meaning it impacts any attempt to publish in Draft API.

Tips for Building Effective Rules

  • Keep rules clear and actionable for editors
  • Balance quality enforcement with editorial flexibility
  • Test rule sets in a staging environment first
  • Review and update rules as editorial standards evolve
  • Ensure you consider required fields that exist in Composer Settings so there is not overlap or confusion
    • Required fields are available in Composer Settings and should be used for basic requirements
    • Validation rules should be used for more complex operations.

Example Use Cases with Rules

  1. Allow editors to save stories but prevent them from publishing unless they have 4 or more tags added to Story tags field

    story publish

    Terminal window
    curl --location 'https://api.{{ORG}}.arcpublishing.com/rule-validation/rules/add-rule' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {{TRIDENT_TOKEN}}' \
    --data '{
    "ruleName": "story-tags-len-req-pub",
    "operation": "arc-composer-publish",
    "level": "error",
    "locales": [
    {
    "locale": "en-US",
    "language": "english",
    "text": "Story tags must always have 4 or more tags before publish"
    }
    ],
    "conditions": {
    "all": [
    {
    "path": "$.tags",
    "field": "taxonomy",
    "value": 3,
    "operator": "lengthGreaterThan"
    }
    ]
    },
    "status": "enabled"
    }'
  2. Always require 2 or more stories to be added to Related items before publish

    story publish

    Terminal window
    curl --location 'https://api.{{ORG}}.arcpublishing.com/rule-validation/rules/add-rule' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {{TRIDENT_TOKEN}}' \
    --data '{
    "ruleName": "rel-stories-len-req-pub",
    "operation": "arc-composer-publish",
    "level": "error",
    "locales": [
    {
    "locale": "en-US",
    "language": "english",
    "text": "2 or more related stories must be added before publish"
    }
    ],
    "conditions": {
    "all": [
    {
    "path": "$.basic",
    "field": "related_content",
    "value": 1,
    "operator": "lengthGreaterThan"
    }
    ]
    },
    "status": "enabled"
    }'

    story save

    Terminal window
    curl --location 'https://api.{{ORG}}.arcpublishing.com/rule-validation/rules/add-rule' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {{TRIDENT_TOKEN}}' \
    --data '{
    "ruleName": "rel-stories-len-req-sav",
    "operation": "arc-composer-save",
    "level": "warning",
    "locales": [
    {
    "locale": "en-US",
    "language": "english",
    "text": "Include 2 related stories to the content you're writing"
    }
    ],
    "conditions": {
    "all": [
    {
    "path": "$.basic",
    "field": "related_content",
    "value": 1,
    "operator": "lengthGreaterThan"
    }
    ]
    },
    "status": "enabled"
    }'
  3. Always require a basic featured media item to be added before publish, and warn on save

    story publish

    Terminal window
    curl --location 'https://api.{{ORG}}.arcpublishing.com/rule-validation/rules/add-rule' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {{TRIDENT_TOKEN}}' \
    --data '{
    "ruleName": "feat-media-basic-chk-pub",
    "operation": "arc-composer-publish",
    "level": "error",
    "locales": [
    {
    "locale": "en-US",
    "language": "english",
    "text": "Featured media basic must exist before publish"
    }
    ],
    "conditions": {
    "all": [
    {
    "field": "promo_items",
    "path": "$.basic",
    "operator": "exist"
    }
    ]
    },
    "status": "enabled"
    }'

    story save

    Terminal window
    curl --location 'https://api.{{ORG}}.arcpublishing.com/rule-validation/rules/add-rule' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer {{TRIDENT_TOKEN}}' \
    --data '{
    "ruleName": "feat-media-basic-chk-sav",
    "operation": "arc-composer-save",
    "level": "warning",
    "locales": [
    {
    "locale": "en-US",
    "language": "english",
    "text": "Make sure to include a basic featured media item"
    }
    ],
    "conditions": {
    "all": [
    {
    "field": "promo_items",
    "path": "$.basic",
    "operator": "exist"
    }
    ]
    },
    "status": "enabled"
    }'

Use Cases Not Covered by Arc Validation Service

  1. Media File Validation Cannot analyze image quality (e.g. resolution, format compliance)

    Example: “Reject any image that’s blurry or doesn’t meet a 16:9 ratio.”

  2. Language or Tone Analysis

    • Cannot write a rule to search/evaluate all the content elements.writing style, grammar, reading level, tone of voice, or bias. (You can write an IFX integration that can do this kind of assessment with 3rd party tools.)
    • No natural language processing or sentiment detection

    Example: “Block any article with negative sentiment in the title.”

  3. Live Data Dependency or External API Checks

    Doesn’t support calling external APIs (e.g., fact-checking, keyword validation via SEO tools, or other 3rd party data validation). This includes content ‘PowerUps’ that are pulled dynamically.

    Example: “Validate that this stock price is current” or “Check that the top tag is a trending topic.”

  4. Referential Content Validation

    • Cannot check rules across multiple content items (e.g., duplicates across site)
    • Doesn’t compare an article to existing stories or previous revisions of the content

    Example: “Prevent publishing if this headline is too similar to another story published today.”

  5. Workflow or User Role-Based Logic

    • Doesn’t validate based on who is editing or what stage of workflow the content is in
    • No conditional logic based on role or assignment

    Example: “Only allow editors to skip the photo requirement for breaking news stories.”

  6. Real-Time User Behavior Triggers

    • Not reactive to user or audience behavior (views, bounce rate, etc.)
    • Cannot adapt based on engagement or downstream analytics

    Example: “If this article didn’t reach 500 views in 1 hour, update the headline automatically.”

  7. Automated Content Correction

    Cannot suggest or auto-correct content fields (e.g., fixing a headline, auto-generating alt text)

    Example: “Automatically change long headlines to under 60 characters.”

  8. Scheduling, Publishing Logic, or Rate Limiting

    • Doesn’t control when content gets published
    • Not meant to throttle publishing or enforce editorial calendars

    Example: “Only allow one sports story to publish per hour.”