Skip to content

Fields and validation

A template's fields say what a submission must contain. Validation runs first, costs nothing and answers with one error per problem, named by field.

Fields are the parts of a submission: a title, a description, a price, photos. Each has a type and rules, and every submission is checked against them before any policy runs. That check calls no model and uses no check of your plan.

A submission that breaks a rule comes back with one error per problem, each naming its field, so your form can show every message beside the input it belongs to.

curl https://api.useinfrared.com/v1/moderations \
  -H "Authorization: Bearer $INFRARED_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "listing",
    "content_id": "item_8841",
    "fields": {
      "title": "Bike",
      "description": "Aluminium frame, serviced in spring.",
      "price": -5,
      "colour": "red"
    }
  }'
200 OK, trimmedJSON
{
  "object": "moderation",
  "id": "mod_4tuxoYhQK5SSPJvilyW2mY",
  "template": { "slug": "listing", "version": 1 },
  "type": "form",
  "status": "invalid",
  "flagged": true,
  "recommendation": "reject",
  "severity": "none",
  "policies": {},
  "reasons": ["validation_failed"],
  "validation_errors": [
    { "field": "colour", "code": "unknown_field", "message": "colour is not a field of this template" },
    { "field": "title", "code": "min_length", "message": "Title must be at least 5 characters" },
    { "field": "price", "code": "min", "message": "Price must be at least 0" }
  ],
  "usage": { "checks": 0, "cached": false },
  "test": true,
  "content_id": "item_8841",
  "fields": {
    "title": {
      "object": "moderation",
      "id": "mod_22BnpvM0UrFLx0jGT1a0On",
      "field": "title",
      "status": "invalid",
      "validation_errors": [
        { "field": "title", "code": "min_length", "message": "Title must be at least 5 characters" }
      ],
      "parent_id": "mod_4tuxoYhQK5SSPJvilyW2mY"
    },
    "description": {
      "object": "moderation",
      "id": "mod_7MEzT5TlPhupQ8yADIT7Mo",
      "field": "description",
      "status": "invalid",
      "parent_id": "mod_4tuxoYhQK5SSPJvilyW2mY"
    }
  }
}

The answer is HTTP 200: the request was understood and the content was refused. Every problem is listed at once, on the form and again on the field it belongs to. price has no entry under fields because a number is validated and not screened. Statuses and errors lists every code.

What a field is made of

A field as GET /v1/templates/{slug} returns it, and as the Fields tab of the editor shows it:

keystring

What your requests send: a key of fields, or the value of field. Lowercase letters, digits and underscores, starting with a letter, 64 characters at most. Unique in the template.

namestring

The label, 100 characters at most. Validation messages use it: "Title must be at least 5 characters".

typestring

What the value is. The type decides which rules apply and whether the value is screened.

One oftextimagenumberbooleanenumurljson

requiredbooleanDefault false

Whether a submission must carry a value. Required or Optional in the editor.

descriptionstringOptional

What the field holds, for the models. 500 characters at most.

validationobject

The rules for the value. Which ones exist depends on the type.

triggersarray

Triggers that apply to this field only.

policiesarrayOptional

When present, only these policies run on the field.

A template holds up to 40 fields. A field's key is part of your API: change it and submissions that still send the old key become invalid.

Field types

typeIn the editorWhat happens to the value
textTextScreened by the text policies. In a form it gets its own result under fields.
imageImageOne or more image URLs, each screened. In a form it gets its own result under fields.
numberNumberValidated: a number, or a string that reads as one.
booleanBooleanValidated: true or false.
enumEnumValidated: one of the values you list.
urlURLValidated: a string that starts with http:// or https://.
jsonJSONValidated: an object or an array.

No policy runs on a number, a boolean, an enum, a URL or a JSON value, link policies included. Those values are there for your content rules to test and for the AI instructions to read.

Validation rules

TypeRuleIn the editorA value passes whenError code
textmin_lengthMin charactersIt has at least this many characters.min_length
textmax_lengthMax charactersIt has at most this many characters.max_length
textnumericNumbers onlyIt holds digits, with an optional sign, spaces, dots and commas.numeric
textpatternPatternIt matches the regular expression.pattern
numberminMinimumIt is at least this number.min
numbermaxMaximumIt is at most this number.max
enumenum_valuesAllowed valuesIt is one of the listed values.enum
imagemin_itemsMin filesIt holds at least this many files.min_items
imagemax_itemsMax filesIt holds at most this many files.max_items

An image field has three more rules, for size and dimensions. They are reported and never reject: see Image size and dimensions.

What the table does not say:

  • A value of the wrong JSON type answers type: a number where text is expected, a word where a number is.
  • Characters are counted as Unicode code points, so an accented letter is one character.
  • Every text is also held to 20,000 characters, whatever Max characters says.
  • pattern is searched for anywhere in the value. Start it with ^ and end it with $ to match the whole value.
  • An image field with no Max files takes up to 20 files, and Max files goes up to 50. A required image field needs at least one file.
  • Each file of an image field must be an http or https URL. One that is not answers url.

Image size and dimensions

Max size (max_bytes, entered in megabytes), Min width and Min height (min_width and min_height, in pixels) never reject a submission. They are read once the image is downloaded, during screening. An image that misses one of them is still screened and still counted, and a note is added to validation_errors of that field's result: the image's url, the code max_bytes or dimensions, and a message.

The note is returned for a whole form only. A single image object and the test console do not return it.

Whatever the field allows, an image over 10 MB is not downloaded. That is a failed fetch, not a validation error, and the submission stays valid. Moderate images says how images are fetched and what a failed fetch returns.

Required, empty and unknown values

  • A value is empty when its key is missing, or when it is null, an empty string or an empty list. false and 0 are values.
  • An empty required field answers required. An empty optional field is skipped, and none of its rules apply.
  • A key the template does not have answers unknown_field and makes the whole submission invalid. Nothing is dropped silently.

One check comes earlier, on the shape of the request itself. A form with no fields, with more than 40, or with a key that holds anything but lowercase letters, digits and underscores answers 422 validation_error, and no moderation is created.

One object and its field

A request that sends a single object can say which field it is, with "field": "title". That field's rules then apply to input. Without field, a text is held to the 20,000 character limit only, and an image request takes exactly one URL.

field has to name a field of the right kind. A text can name any field that is not an image field, and an image can only name an image field. A mismatch answers type_mismatch, and a key the template does not have answers unknown_field. Moderate text shows such a request.

Tell the models what a field holds

What it holds is the field's description: a sentence for the models, not for your users. They read it whenever they judge the field, and it replaces any assumption about what a text or a picture is. "Photos of the item itself. A brand label on the item is normal." keeps a logo from being read as an advertisement.

A description reaches the models only when the request says which field the content is: in a form, or in a single object with field.

Run only some policies on a field

Only run these policies limits a text or image field to the policies you pick, from those the template enables. Left empty, every enabled policy that fits the field's type runs on it.

The limit covers the scoring of the field itself. The AI instructions and your guidelines, which read all fields together, still read it.

Edit fields in the dashboard

Open a template in Templates. The Fields tab lists the fields with their type, rule, validation and triggers.

The Fields tab of the Listing template: title, description, price and photos, each with its type, validation and triggers.
Dashboard, TemplatesThe Fields tab: one row per field, with its validation in words and its triggers as badges.

Add field opens the form: Name, Key (filled in from the name as you type), Type, the Rule switch, What it holds, then the validation inputs of the chosen type. For a text or image field, Triggers and Only run these policies follow. The arrows on a row change the order, which is also the order of the form on the Test tab.

Removing a field removes the rule conditions that compare it. Changes apply once you choose Save draft and then Publish version, as Versions, testing and diff describes.

Next

Something missing or unclear on this page? Write to support@useinfrared.com.