diff --git a/apify-api/openapi/components/schemas/actor-tasks/TaskOptions.yaml b/apify-api/openapi/components/schemas/actor-tasks/TaskOptions.yaml
index c1b9c71641..323b1f5bb3 100644
--- a/apify-api/openapi/components/schemas/actor-tasks/TaskOptions.yaml
+++ b/apify-api/openapi/components/schemas/actor-tasks/TaskOptions.yaml
@@ -13,3 +13,7 @@ properties:
type: number
nullable: true
example: 128
+ restartOnError:
+ type: boolean
+ nullable: true
+ example: false
diff --git a/apify-api/openapi/components/schemas/actors/Actor.yaml b/apify-api/openapi/components/schemas/actors/Actor.yaml
index 7b6614b51e..34cb6c6002 100644
--- a/apify-api/openapi/components/schemas/actors/Actor.yaml
+++ b/apify-api/openapi/components/schemas/actors/Actor.yaml
@@ -31,8 +31,8 @@ properties:
example: My favourite actor!
restartOnError:
type: boolean
- nullable: true
example: false
+ deprecated: true # Use defaultRunOptions.restartOnError instead
isPublic:
type: boolean
example: false
diff --git a/apify-api/openapi/components/schemas/actors/CreateActorRequest.yaml b/apify-api/openapi/components/schemas/actors/CreateActorRequest.yaml
index 4b6d5058a9..8631096eec 100644
--- a/apify-api/openapi/components/schemas/actors/CreateActorRequest.yaml
+++ b/apify-api/openapi/components/schemas/actors/CreateActorRequest.yaml
@@ -27,8 +27,8 @@ properties:
example: My actor is the best
restartOnError:
type: boolean
- nullable: true
example: false
+ deprecated: true # Use defaultRunOptions.restartOnError instead
versions:
type: array
items:
@@ -46,6 +46,4 @@ properties:
description: ''
nullable: true
defaultRunOptions:
- oneOf:
- - nullable: true
- - $ref: ./DefaultRunOptions.yaml
+ $ref: ./DefaultRunOptions.yaml
diff --git a/apify-api/openapi/components/schemas/actors/DefaultRunOptions.yaml b/apify-api/openapi/components/schemas/actors/DefaultRunOptions.yaml
index 64f6a6a3b2..7c8efa84dc 100644
--- a/apify-api/openapi/components/schemas/actors/DefaultRunOptions.yaml
+++ b/apify-api/openapi/components/schemas/actors/DefaultRunOptions.yaml
@@ -14,3 +14,6 @@ properties:
memoryMbytes:
type: number
example: 2048
+ restartOnError:
+ type: boolean
+ example: false
diff --git a/apify-api/openapi/components/schemas/actors/UpdateActorRequest.yaml b/apify-api/openapi/components/schemas/actors/UpdateActorRequest.yaml
index ce242295c6..6be07cd905 100644
--- a/apify-api/openapi/components/schemas/actors/UpdateActorRequest.yaml
+++ b/apify-api/openapi/components/schemas/actors/UpdateActorRequest.yaml
@@ -1,8 +1,4 @@
title: ActUpdate
-required:
- - name
- - isPublic
- - versions
type: object
properties:
name:
@@ -29,8 +25,8 @@ properties:
example: My Actor
restartOnError:
type: boolean
- nullable: true
example: false
+ deprecated: true # Use defaultRunOptions.restartOnError instead
versions:
type: array
items:
@@ -47,9 +43,7 @@ properties:
description: ''
nullable: true
defaultRunOptions:
- oneOf:
- - nullable: true
- - $ref: ./DefaultRunOptions.yaml
+ $ref: ./DefaultRunOptions.yaml
taggedBuilds:
type: object
description: |
@@ -104,3 +98,8 @@ properties:
latest:
buildId: z2EryhbfhgSyqj6Hn
beta: null
+required:
+ - name
+ - isPublic
+ - versions
+
diff --git a/apify-api/openapi/components/schemas/schedules/ScheduleActionsRunOptions.yaml b/apify-api/openapi/components/schemas/schedules/ScheduleActionsRunOptions.yaml
index 5d86e5de45..b63f294a1b 100644
--- a/apify-api/openapi/components/schemas/schedules/ScheduleActionsRunOptions.yaml
+++ b/apify-api/openapi/components/schemas/schedules/ScheduleActionsRunOptions.yaml
@@ -13,3 +13,7 @@ properties:
type: number
nullable: true
example: 1024
+ restartOnError:
+ type: boolean
+ nullable: true
+ example: false
diff --git a/apify-api/openapi/paths/actor-runs/actor-runs@{runId}@resurrect.yaml b/apify-api/openapi/paths/actor-runs/actor-runs@{runId}@resurrect.yaml
index 4cba3f46d6..1df4b2feb8 100644
--- a/apify-api/openapi/paths/actor-runs/actor-runs@{runId}@resurrect.yaml
+++ b/apify-api/openapi/paths/actor-runs/actor-runs@{runId}@resurrect.yaml
@@ -54,6 +54,14 @@ post:
example: 10
description: |
Optional maximum cost of the run, in USD. Used for pay-per-event Actors. The value can only be increased beyond the value specified when the Actor run was started.
+ - name: restartOnError
+ in: query
+ required: false
+ schema:
+ type: boolean
+ example: false
+ description: |
+ Determines whether the resurrected run will be restarted if it fails. By default, the resurrected run uses the same setting as before.
responses:
'200':
description: ''
diff --git a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml
index 3c43531982..eee73ffa96 100644
--- a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml
+++ b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml
@@ -476,6 +476,15 @@ post:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
diff --git a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync.yaml b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync.yaml
index 488cdcb98e..9782b7b5c6 100644
--- a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync.yaml
+++ b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync.yaml
@@ -223,6 +223,15 @@ post:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
diff --git a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs.yaml b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs.yaml
index c9c9da4293..5c7c80418d 100644
--- a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs.yaml
+++ b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs.yaml
@@ -215,6 +215,15 @@ post:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
diff --git a/apify-api/openapi/paths/actors/acts.yaml b/apify-api/openapi/paths/actors/acts.yaml
index b07febbf7d..45e416677f 100644
--- a/apify-api/openapi/paths/actors/acts.yaml
+++ b/apify-api/openapi/paths/actors/acts.yaml
@@ -142,7 +142,6 @@ post:
isPublic: false
seoTitle: My Actor
seoDescription: My Actor is the best
- restartOnError: false
versions:
- versionNumber: '0.0'
sourceType: SOURCE_FILES
@@ -161,6 +160,7 @@ post:
build: latest
timeoutSecs: 3600
memoryMbytes: 2048
+ restartOnError: false
required: true
responses:
'201':
@@ -183,7 +183,6 @@ post:
name: MyActor
username: jane35
description: My favourite Actor!
- restartOnError: false
isPublic: false
createdAt: '2019-07-08T11:27:57.401Z'
modifiedAt: '2019-07-08T14:01:05.546Z'
@@ -225,6 +224,7 @@ post:
build: latest
timeoutSecs: 3600
memoryMbytes: 2048
+ restartOnError: false
exampleRunInput:
body: '{ "helloWorld": 123 }'
contentType: application/json; charset=utf-8
diff --git a/apify-api/openapi/paths/actors/acts@{actorId}.yaml b/apify-api/openapi/paths/actors/acts@{actorId}.yaml
index f86cfb3428..89f32a89a8 100644
--- a/apify-api/openapi/paths/actors/acts@{actorId}.yaml
+++ b/apify-api/openapi/paths/actors/acts@{actorId}.yaml
@@ -28,7 +28,6 @@ get:
name: MyActor
username: jane35
description: My favourite Actor!
- restartOnError: false
isPublic: false
createdAt: '2019-07-08T11:27:57.401Z'
modifiedAt: '2019-07-08T14:01:05.546Z'
@@ -70,6 +69,7 @@ get:
build: latest
timeoutSecs: 3600
memoryMbytes: 2048
+ restartOnError: false
exampleRunInput:
body: '{ "helloWorld": 123 }'
contentType: application/json; charset=utf-8
@@ -143,7 +143,6 @@ put:
seoTitle: My Actor
seoDescription: My Actor is the best
title: My Actor
- restartOnError: false
versions:
- versionNumber: '0.0'
sourceType: SOURCE_FILES
@@ -162,6 +161,7 @@ put:
build: latest
timeoutSecs: 3600
memoryMbytes: 2048
+ restartOnError: false
taggedBuildsCreateOrReassignTag:
summary: 'Create or reassign a build tag'
value:
@@ -196,7 +196,6 @@ put:
name: MyActor
username: jane35
description: My favourite Actor!
- restartOnError: false
isPublic: false
createdAt: '2019-07-08T11:27:57.401Z'
modifiedAt: '2019-07-08T14:01:05.546Z'
@@ -238,6 +237,7 @@ put:
build: latest
timeoutSecs: 3600
memoryMbytes: 2048
+ restartOnError: false
exampleRunInput:
body: '{ "helloWorld": 123 }'
contentType: application/json; charset=utf-8
diff --git a/apify-api/openapi/paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml b/apify-api/openapi/paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml
index 949392d0c4..3e9bbfdcae 100644
--- a/apify-api/openapi/paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml
+++ b/apify-api/openapi/paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml
@@ -88,6 +88,15 @@ post:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
@@ -490,6 +499,15 @@ get:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
diff --git a/apify-api/openapi/paths/actors/acts@{actorId}@run-sync.yaml b/apify-api/openapi/paths/actors/acts@{actorId}@run-sync.yaml
index 84fe42c1d9..209320c11d 100644
--- a/apify-api/openapi/paths/actors/acts@{actorId}@run-sync.yaml
+++ b/apify-api/openapi/paths/actors/acts@{actorId}@run-sync.yaml
@@ -94,6 +94,15 @@ post:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
@@ -255,6 +264,15 @@ get:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
diff --git a/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml b/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml
index 2dd68c4d86..3e39d6a6c0 100644
--- a/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml
+++ b/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml
@@ -230,6 +230,15 @@ post:
type: number
format: double
example: 5
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the run will be restarted if it fails.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
- name: build
in: query
description: |
diff --git a/apify-api/openapi/paths/actors/acts@{actorId}@runs@{runId}@resurrect.yaml b/apify-api/openapi/paths/actors/acts@{actorId}@runs@{runId}@resurrect.yaml
index 46617a6a5b..968cc59e04 100644
--- a/apify-api/openapi/paths/actors/acts@{actorId}@runs@{runId}@resurrect.yaml
+++ b/apify-api/openapi/paths/actors/acts@{actorId}@runs@{runId}@resurrect.yaml
@@ -68,6 +68,15 @@ post:
type: number
format: double
example: 256
+ - name: restartOnError
+ in: query
+ description: |
+ Determines whether the resurrected run will be restarted if it fails. By default, the resurrected run uses the same setting as before.
+ style: form
+ explode: true
+ schema:
+ type: boolean
+ example: false
responses:
'200':
description: ''
diff --git a/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-json.png b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-json.png
new file mode 100644
index 0000000000..91d89e4b65
Binary files /dev/null and b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-json.png differ
diff --git a/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-object.png b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-object.png
new file mode 100644
index 0000000000..08755016dc
Binary files /dev/null and b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-object.png differ
diff --git a/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-string.png b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-string.png
new file mode 100644
index 0000000000..650f52d13d
Binary files /dev/null and b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-array-string.png differ
diff --git a/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-json.png b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-json.png
new file mode 100644
index 0000000000..51eb921efa
Binary files /dev/null and b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-json.png differ
diff --git a/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-ui.png b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-ui.png
new file mode 100644
index 0000000000..82d6ca276c
Binary files /dev/null and b/sources/platform/actors/development/actor_definition/input_schema/images/sub-schema-ui.png differ
diff --git a/sources/platform/actors/development/actor_definition/input_schema/specification.md b/sources/platform/actors/development/actor_definition/input_schema/specification.md
index 7651f4d6be..236428ab32 100644
--- a/sources/platform/actors/development/actor_definition/input_schema/specification.md
+++ b/sources/platform/actors/development/actor_definition/input_schema/specification.md
@@ -400,15 +400,176 @@ Rendered input:
Properties:
-| Property | Value | Required | Description |
-| --- | --- | --- |--------------------------------------------------------------------------------------------------------------|
-| `editor` | One of
`json`
`proxy`
`hidden`
| Yes | UI editor used for input. |
-| `patternKey` | String | No | Regular expression that will be used to validate the keys of the object. |
-| `patternValue` | String | No | Regular expression that will be used to validate the values of object. |
-| `maxProperties` | Integer | No | Maximum number of properties the object can have. |
-| `minProperties` | Integer | No | Minimum number of properties the object can have. |
-| `nullable` | Boolean | No | Specifies whether null is an allowed value. |
-| `isSecret` | Boolean | No | Specifies whether the input field will be stored encrypted. Only available with `json` and `hidden` editors. |
+| Property | Value | Required | Description |
+|------------------------|----------------------------------------------------------------------------------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `editor` | One of
`json`
`proxy`
`schemaBased`
`hidden`
| Yes | UI editor used for input. |
+| `patternKey` | String | No | Regular expression that will be used to validate the keys of the object. |
+| `patternValue` | String | No | Regular expression that will be used to validate the values of object. |
+| `maxProperties` | Integer | No | Maximum number of properties the object can have. |
+| `minProperties` | Integer | No | Minimum number of properties the object can have. |
+| `nullable` | Boolean | No | Specifies whether null is an allowed value. |
+| `isSecret` | Boolean | No | Specifies whether the input field will be stored encrypted. Only available with `json` and `hidden` editors. |
+| `properties` | Object | No | Defines the sub-schema properties for the object used for validation and UI rendering (`schemaBased` editor). See more info below. |
+| `additionalProperties` | Boolean | No | Controls if sub-properties not listed in `properties` are allowed. Defaults to `true`. Set to `false` to make requests with extra properties fail. |
+| `required` | String array | No | An array of sub-properties keys that are required. Note: This applies only if the object field itself is present. If the object field is optional and not included in the input, its required subfields are not validated. |
+
+#### Object fields validation
+
+Like root-level input schemas, you can define a schema for sub-properties of an object using the `properties` field.
+
+Each sub-property within this sub-schema can define the same fields as those available at the root level of the input schema, except for the fields that apply only at the root level: `sectionCaption` and `sectionDescription`.
+
+Validation is performed both in the UI and during Actor execution via the API. Sub-schema validation works independently of the editor selected for the parent object. It also respects the `additionalProperties` and `required` fields, giving you precise control over whether properties not defined in `properties` are permitted and which properties are mandatory.
+
+:::note Recursive nesting
+
+Object sub-properties can define their own sub-schemas recursively with no nesting depth limit.
+
+:::
+
+```json title="Example of an object property with sub-schema properties"
+{
+ "title": "Configuration",
+ "type": "object",
+ "description": "Advanced configuration options",
+ "editor": "json",
+ "properties": {
+ "locale": {
+ "title": "Locale",
+ "type": "string",
+ "description": "Locale identifier.",
+ "pattern": "^[a-z]{2,3}-[A-Z]{2}$"
+ },
+ "timeout": {
+ "title": "Timeout",
+ "type": "integer",
+ "description": "Request timeout in seconds",
+ "minimum": 1,
+ "maximum": 300
+ },
+ "debugMode": {
+ "title": "Debug Mode",
+ "type": "boolean",
+ "description": "Enable verbose logging during scraping"
+ }
+ },
+ "required": ["locale", "timeout"],
+ "additionalProperties": false
+}
+```
+
+Rendered input:
+
+
+In this example, the object has validation rules for its properties:
+
+- The `timeout` property must be an integer between 1 and 300
+- The `locale` property must be a string matching the pattern `^[a-z]{2,3}-[A-Z]{2}$`
+- The `debugMode` property is optional and can be either `true` or `false`
+- The `timeout` and `locale` properties are required
+- No additional properties beyond those defined are allowed
+
+##### Handling default and prefill values for object sub-properties
+
+When defining object with sub-properties, it's possible to set `default` and `prefill` values in two ways:
+
+1. _At the parent object level_: You can provide a complete object as the `default` or `prefill` value, which will set values for all sub-properties at once.
+2. _At the individual sub-property level_: You can specify `default` or `prefill` values for each sub-property separately within the `properties` definition.
+
+When both methods are used, the values defined at the parent object level take precedence over those defined at the sub-property level.
+For example, in the input schema like this:
+
+```json
+{
+ "title": "Configuration",
+ "type": "object",
+ "description": "Advanced configuration options",
+ "editor": "schemaBased",
+ "default": {
+ "timeout": 60
+ },
+ "properties": {
+ "locale": {
+ "title": "Locale",
+ "type": "string",
+ "description": "Locale identifier.",
+ "pattern": "^[a-z]{2,3}-[A-Z]{2}$",
+ "editor": "textfield",
+ "default": "en-US"
+ },
+ "timeout": {
+ "title": "Timeout",
+ "type": "integer",
+ "description": "Request timeout in seconds",
+ "minimum": 1,
+ "maximum": 300,
+ "editor": "number",
+ "default": 120
+ }
+ }
+}
+```
+
+The `timeout` sub-property will have a default value of `60` (from the parent object), while the `locale` sub-property will have a default value of `"en-US"` (from its own definition).
+
+#### `schemaBased` editor
+
+Object with sub-schema defined can use the `schemaBased` editor, which provides a user-friendly interface for editing each property individually.
+It renders all properties based on their type (and `editor` field), providing a user-friendly interface for complex objects.
+This feature works for objects (and arrays of objects), enabling each property to have its own input field in the UI.
+
+Objects with a defined sub-schema can use the `schemaBased` editor, which provides a user-friendly interface for editing each property individually.
+It renders all properties based on their type (and optionally the `editor` field), making it ideal for visually managing complex object structures.
+This editor supports both single objects and arrays of objects (see [below](#array)), allowing each property to be represented with an appropriate input field in the UI.
+
+```json title="Example of an object property with sub-schema properties using schemaBased editor"
+{
+ "title": "Configuration",
+ "type": "object",
+ "description": "Advanced configuration options",
+ "editor": "schemaBased",
+ "properties": {
+ "locale": {
+ "title": "Locale",
+ "type": "string",
+ "description": "Locale identifier.",
+ "pattern": "^[a-z]{2,3}-[A-Z]{2}$",
+ "editor": "textfield"
+ },
+ "timeout": {
+ "title": "Timeout",
+ "type": "integer",
+ "description": "Request timeout in seconds",
+ "minimum": 1,
+ "maximum": 300,
+ "editor": "number"
+ },
+ "debugMode": {
+ "title": "Debug Mode",
+ "type": "boolean",
+ "description": "Enable verbose logging during scraping",
+ "editor": "checkbox"
+ }
+ },
+ "required": ["locale", "timeout"],
+ "additionalProperties": false
+}
+```
+
+Rendered input:
+
+
+Each sub-property is rendered with its own input field according to its type and `editor` configuration:
+
+- The `locale` property is rendered as a text field.
+- The `timeout` property is rendered as a numeric input with validation limits.
+- The `debugMode` property is rendered as a checkbox toggle.
+
+##### Limitations
+
+The `schemaBased` editor supports only **top-level sub-properties** (level 1 nesting).
+While deeper nested properties can still define sub-schemas for validation, they cannot use the `schemaBased` editor for rendering.
+For example, if the Configuration object above included a property that was itself an object with its own sub-properties, those deeper levels would need to use a different editor, such as `json`.
### Array
@@ -446,19 +607,19 @@ Rendered input:
Properties:
-| Property | Value | Required | Description |
-| --- | --- | --- | --- |
-| `editor` | One of
`json`
`requestListSources`
`pseudoUrls`
`globs`
`keyValue`
`stringList`
`fileupload`
`select`
`hidden`
| Yes | UI editor used for input. |
-| `placeholderKey` | String | No | Placeholder displayed for key field when no value is specified. Works only with `keyValue` editor. |
-| `placeholderValue` | String | No | Placeholder displayed in value field when no value is provided. Works only with `keyValue` and `stringList` editors. |
-| `patternKey` | String | No | Regular expression that will be used to validate the keys of items in the array. Works only with `keyValue` editor. |
-| `patternValue` | String | No | Regular expression that will be used to validate the values of items in the array. Works only with `keyValue` and `stringList` editors. |
-| `maxItems` | Integer | No | Maximum number of items the array can contain. |
-| `minItems` | Integer | No | Minimum number of items the array can contain. |
-| `uniqueItems` | Boolean | No | Specifies whether the array should contain only unique values. |
-| `nullable` | Boolean | No | Specifies whether null is an allowed value. |
-| `items` | object | No | Specifies format of the items of the array, useful mainly for multiselect (see below) |
-| `isSecret` | Boolean | No | Specifies whether the input field will be stored encrypted. Only available with `json` and `hidden` editors. |
+| Property | Value | Required | Description |
+|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `editor` | One of
`json`
`requestListSources`
`pseudoUrls`
`globs`
`keyValue`
`stringList`
`fileupload`
`select`
`schemaBased`
`hidden`
| Yes | UI editor used for input. |
+| `placeholderKey` | String | No | Placeholder displayed for key field when no value is specified. Works only with `keyValue` editor. |
+| `placeholderValue` | String | No | Placeholder displayed in value field when no value is provided. Works only with `keyValue` and `stringList` editors. |
+| `patternKey` | String | No | Regular expression that will be used to validate the keys of items in the array. Works only with `keyValue` editor. |
+| `patternValue` | String | No | Regular expression that will be used to validate the values of items in the array. Works only with `keyValue` and `stringList` editors. |
+| `maxItems` | Integer | No | Maximum number of items the array can contain. |
+| `minItems` | Integer | No | Minimum number of items the array can contain. |
+| `uniqueItems` | Boolean | No | Specifies whether the array should contain only unique values. |
+| `nullable` | Boolean | No | Specifies whether null is an allowed value. |
+| `items` | object | No | Specifies format of the items of the array, useful mainly for multiselect and for `schemaBased` editor (see below). |
+| `isSecret` | Boolean | No | Specifies whether the input field will be stored encrypted. Only available with `json` and `hidden` editors. |
Usage of this field is based on the selected editor:
@@ -489,6 +650,182 @@ Editor type `select` allows the user to pick items from a select, providing mult
To correctly define options for multiselect, you need to define the `items` property and then provide values and (optionally) labels in `enum` and `enumTitles` properties.
+#### Array items validation
+
+Arrays in the input schema can define an `items` field to specify the type and validation rules for each item.
+Each array item is validated according to its `type` and inside the `items` field it's also possible to define additional validation rules such as `pattern`, `minimum`, `maximum`, etc., depending on the item type.
+
+If the item type is an `object`, it can define its own `properties`, `required`, and `additionalProperties` fields,
+working in the same way as a single object field (see [Object fields validation](#object-fields-validation)).
+
+Validation is performed both in the UI and during Actor execution via the API.
+Array items can themselves be objects with sub-schemas, and objects within objects, recursively, without any limit on nesting depth.
+
+```json title="Example of an array of objects property with sub-schema"
+{
+ "title": "Request Headers",
+ "type": "array",
+ "description": "List of custom HTTP headers",
+ "editor": "json",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Header Name",
+ "description": "Name of the HTTP header",
+ "type": "string",
+ "minLength": 1
+ },
+ "value": {
+ "title": "Header Value",
+ "description": "Value of the HTTP header",
+ "type": "string",
+ "minLength": 1
+ }
+ },
+ "required": ["name", "value"],
+ "additionalProperties": false
+ },
+ "minItems": 1,
+ "maxItems": 20
+}
+```
+
+Rendered input:
+
+
+In this example:
+
+- The array must contain between 1 and 20 items.
+- Each item must be an object with `name` and `value` properties.
+- Both `name` and `value` are required.
+- No additional properties beyond those defined are allowed.
+- The validation of each object item works the same as for a single object field (see [Object fields validation](#object-fields-validation)).
+
+##### Handling default and prefill values array with object sub-properties
+
+When defining an array of objects with sub-properties, it's possible to set `default` and `prefill` values in two ways:
+
+1. _At the parent array level_: You can provide an array of complete objects as the `default` or `prefill` value, which will be used only if there is no value specified for the field.
+2. _At the individual sub-property level_: You can specify `default` or `prefill` values for each sub-property within the `properties` definition of the object items. These values will be applied to each object in the array value.
+
+For example, having an input schema like this:
+
+```json
+{
+ "title": "Requests",
+ "type": "array",
+ "description": "List of HTTP requests",
+ "editor": "schemaBased",
+ "default": [
+ { "url": "https://apify.com/", "port": 80 }
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "title": "URL",
+ "type": "string",
+ "description": "Request URL",
+ "editor": "textfield"
+ },
+ "port": {
+ "title": "Port",
+ "type": "integer",
+ "description": "Request port",
+ "editor": "number",
+ "default": 8080
+ }
+ },
+ "required": ["url", "port"],
+ "additionalProperties": false
+ }
+}
+```
+
+If there is no value specified for the field, the array will default to containing one object:
+
+```json
+[
+ { "url": "https://apify.com/", "port": 80 }
+]
+```
+
+However, if the user adds a new item to the array, the `port` sub-property of that new object will default to `8080`, as defined in the sub-property itself.
+
+#### `schemaBased` editor
+
+Arrays can use the `schemaBased` editor to provide a user-friendly interface for editing each item individually.
+It works for arrays of primitive types (like strings or numbers) as well as arrays of objects, rendering each item according to its type and optional `editor` configuration.
+
+This makes it easy to manage complex arrays in the UI while still enforcing validation rules defined in the items field.
+
+```json title="Example of an array of strings property with sub-schema"
+{
+ "title": "Start URLs",
+ "type": "array",
+ "description": "List of URLs for the scraper to visit",
+ "editor": "schemaBased",
+ "items": {
+ "type": "string",
+ "pattern": "^https?:\\/\\/(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(?:\\/\\S*)?$"
+ },
+ "minItems": 1,
+ "maxItems": 50,
+ "uniqueItems": true
+}
+```
+
+Rendered input:
+
+
+- Each item is rendered as a text field.
+- The array must contain between 1 and 50 items.
+- Duplicate values are not allowed.
+
+```json title="Example of an array of objects property with sub-schema"
+{
+ "title": "Request Headers",
+ "type": "array",
+ "description": "List of custom HTTP headers",
+ "editor": "schemaBased",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Header Name",
+ "description": "Name of the HTTP header",
+ "type": "string",
+ "minLength": 1,
+ "editor": "textfield"
+ },
+ "value": {
+ "title": "Header Value",
+ "description": "Value of the HTTP header",
+ "type": "string",
+ "minLength": 1,
+ "editor": "textfield"
+ }
+ },
+ "required": ["name", "value"],
+ "additionalProperties": false
+ },
+ "minItems": 1,
+ "maxItems": 20
+}
+```
+
+Rendered input:
+
+
+- Each array item is represented as a group of input fields (`name` and `value`).
+- Validation ensures all required sub-properties are filled and no extra properties are allowed.
+- New items can be added up to the `maxItems` limit, and each item is validated individually.
+
+##### Limitations
+
+As with objects, the sub-schema feature for arrays only works for level 1 sub-properties. While the objects in the array can have properties with their own schema definitions, those properties cannot themselves use the `schemaBased` editor.
+
### Resource type
Resource type identifies what kind of Apify Platform object is referred to in the input field. For example, the Key-value store resource type can be referred to using a string ID.
diff --git a/sources/platform/actors/development/programming_interface/environment_variables.md b/sources/platform/actors/development/programming_interface/environment_variables.md
index 3daf654ccf..7830d19ebf 100644
--- a/sources/platform/actors/development/programming_interface/environment_variables.md
+++ b/sources/platform/actors/development/programming_interface/environment_variables.md
@@ -50,6 +50,7 @@ Here's a table of key system environment variables:
| `ACTOR_INPUT_KEY` | Key of the record in the default key-value store that holds the [Actor input](/platform/actors/running/input-and-output#input). |
| `ACTOR_MAX_PAID_DATASET_ITEMS` | For paid-per-result Actors, the user-set limit on returned results. Do not exceed this limit. |
| `ACTOR_MAX_TOTAL_CHARGE_USD` | For pay-per-event Actors, the user-set limit on run cost. Do not exceed this limit. |
+| `ACTOR_RESTART_ON_ERROR` | If **1**, the Actor run will be restarted if it fails. |
| `APIFY_HEADLESS` | If **1**, web browsers inside the Actor should run in headless mode (no windowing system available). |
| `APIFY_IS_AT_HOME` | Contains **1** if the Actor is running on Apify servers. |
| `ACTOR_MEMORY_MBYTES` | Size of memory allocated for the Actor run, in megabytes. Can be used to optimize memory usage or finetuning of low-level external libraries. |
diff --git a/src/pages/img/platform_icons/mcp.svg b/src/pages/img/platform_icons/mcp.svg
new file mode 100644
index 0000000000..d7588500e6
--- /dev/null
+++ b/src/pages/img/platform_icons/mcp.svg
@@ -0,0 +1,19 @@
+
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 0d3b18947d..ffb16bf363 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -30,6 +30,7 @@ import WebScrapingForBeginners from './img/academy_icons/web_scraping_for_beginn
import Actors from './img/platform_icons/actors.svg';
import Collaboration from './img/platform_icons/collaboration.svg';
import Integrations from './img/platform_icons/integrations.svg';
+import MCP from './img/platform_icons/mcp.svg';
import Monitoring from './img/platform_icons/monitoring.svg';
import Proxy from './img/platform_icons/proxy.svg';
import Schedules from './img/platform_icons/schedules.svg';
@@ -169,6 +170,12 @@ export default function Home() {
description="Learn about Apify platform security and data protection."
to="/platform/security"
/>
+ }
+ title="MCP"
+ description="Discover and use Actors with AI agents and LLMs via Apify MCP server."
+ to="/platform/integrations/mcp"
+ />