From ecbb1b12ac0b4d5358e7e5f9f1b37b2a24c9fe98 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 8 Apr 2026 12:26:38 +0000 Subject: [PATCH 1/9] fix(openapi): fix pricingInfo oneOf, version delete 404, maxItems type, and record response schema Error: WARN Response OpenAPI validation error {"url":"/v2/acts/{actId}","method":"GET","errors":[{"message":"must match exactly one schema in oneOf","path":"/response/data/pricingInfos/0"}]} Files: FreeActorPricingInfo.yaml:9, PayPerEventActorPricingInfo.yaml:10, PricePerDatasetItemActorPricingInfo.yaml:10, FlatPricePerMonthActorPricingInfo.yaml:10 Root cause: Each pricing info schema referenced the shared PricingModel enum containing all four values (FREE, PAY_PER_EVENT, PRICE_PER_DATASET_ITEM, FLAT_PRICE_PER_MONTH). This caused FreeActorPricingInfo to match any pricing model since it only requires pricingModel and common fields, violating the oneOf constraint which requires exactly one schema to match. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/packages/types/src/paid_actors.ts#L1 Error: WARN Response OpenAPI validation error {"url":"/v2/acts/{actId}/versions/0.0","method":"DELETE","errors":[{"message":"must be equal to one of the allowed values: actor-not-found","path":"/response/error/type"},{"message":"must be equal to one of the allowed values: record-not-found","path":"/response/error/type"},{"message":"must match exactly one schema in oneOf","path":"/response"}]} Files: acts@{actorId}@versions@{versionNumber}.yaml:75 Root cause: The 404 response for DELETE version used ActorNotFoundError (enum: actor-not-found) but the API actually returns record-or-token-not-found when the actor is not found or access is denied. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/lib/actors.ts#L135 Error: WARN Response OpenAPI validation error {"url":"/v2/actor-runs/{runId}/resurrect","method":"POST","errors":[{"message":"must be integer","path":"/response/data/options/maxItems"}]} Files: RunOptions.yaml:26 Root cause: The maxItems field in RunOptions was defined as type integer but the API can return null when maxItems is not set. The TypeScript type is maxItems?: number which allows the value to be absent or stored as null in MongoDB. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/packages/types/src/actor.ts#L485 Error: WARN Response OpenAPI validation error {"url":"/v2/key-value-stores/{storeId}/records/{recordKey}?attachment=true","method":"GET","errors":[{"message":"must match exactly one schema in oneOf","path":"/response"}]} Files: RecordResponse.yaml:5 Root cause: RecordResponse was defined as type object with additionalProperties but KV store records can contain any JSON value type (array, string, number, boolean, null), not just objects. Removing the type constraint allows the schema to accept any stored JSON value. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/lib/key_value_stores.ts#L442 --- .../FlatPricePerMonthActorPricingInfo.yaml | 4 +++- .../schemas/actor-pricing-info/FreeActorPricingInfo.yaml | 4 +++- .../actor-pricing-info/PayPerEventActorPricingInfo.yaml | 4 +++- .../PricePerDatasetItemActorPricingInfo.yaml | 4 +++- .../openapi/components/schemas/actor-runs/RunOptions.yaml | 2 +- .../components/schemas/key-value-stores/RecordResponse.yaml | 5 ++--- .../actors/acts@{actorId}@versions@{versionNumber}.yaml | 2 +- 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml index 6ce7b75c71..50267b665b 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml @@ -8,7 +8,9 @@ allOf: - trialMinutes properties: pricingModel: - $ref: ./PricingModel.yaml + type: string + enum: + - FLAT_PRICE_PER_MONTH trialMinutes: type: integer description: For how long this Actor can be used for free in trial period diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml index 68c83f0788..4d269f73e5 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml @@ -6,4 +6,6 @@ allOf: - pricingModel properties: pricingModel: - $ref: ./PricingModel.yaml + type: string + enum: + - FREE diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml index 92b5ba9aa3..b7035e5dc7 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml @@ -7,7 +7,9 @@ allOf: - pricingPerEvent properties: pricingModel: - $ref: ./PricingModel.yaml + type: string + enum: + - PAY_PER_EVENT pricingPerEvent: type: object properties: diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml index 845eacd839..6b857820d6 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml @@ -8,7 +8,9 @@ allOf: - unitName properties: pricingModel: - $ref: ./PricingModel.yaml + type: string + enum: + - PRICE_PER_DATASET_ITEM unitName: type: string description: Name of the unit that is being charged diff --git a/apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml b/apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml index 0723482907..dc4b9a3f59 100644 --- a/apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml +++ b/apify-api/openapi/components/schemas/actor-runs/RunOptions.yaml @@ -23,7 +23,7 @@ properties: minimum: 0 examples: [2048] maxItems: - type: integer + type: [integer, "null"] minimum: 1 examples: [1000] maxTotalChargeUsd: diff --git a/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml b/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml index a5c09dc69c..9e7aa22fb8 100644 --- a/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml +++ b/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml @@ -1,9 +1,8 @@ title: RecordResponse description: | The response body contains the value of the record. The content type of the response - is determined by the Content-Type header stored with the record. -type: object -additionalProperties: true + is determined by the Content-Type header stored with the record. The value can be any + JSON type (object, array, string, number, boolean, or null). example: message: Hello, world! count: 42 diff --git a/apify-api/openapi/paths/actors/acts@{actorId}@versions@{versionNumber}.yaml b/apify-api/openapi/paths/actors/acts@{actorId}@versions@{versionNumber}.yaml index cdcd8191af..62629fd94b 100644 --- a/apify-api/openapi/paths/actors/acts@{actorId}@versions@{versionNumber}.yaml +++ b/apify-api/openapi/paths/actors/acts@{actorId}@versions@{versionNumber}.yaml @@ -72,7 +72,7 @@ delete: application/json: schema: oneOf: - - $ref: "../../components/schemas/common/errors/ActorErrors.yaml#/ActorNotFoundError" + - $ref: "../../components/schemas/common/errors/ActorErrors.yaml#/RecordOrTokenNotFoundError" - $ref: "../../components/schemas/common/errors/ActorErrors.yaml#/ActorVersionNotFoundError" "405": $ref: ../../components/responses/MethodNotAllowed.yaml From 1d46f4b953b67678a55e834c820460a3470bf254 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 8 Apr 2026 12:30:37 +0000 Subject: [PATCH 2/9] fix(openapi): fix KV store record GET response content type overlap Error: WARN Response OpenAPI validation error {"url":"/v2/key-value-stores/{storeId}/records/{recordKey}?attachment=true","method":"GET","errors":[{"message":"must match exactly one schema in oneOf","path":"/response"}]} Files: key-value-stores@{storeId}@records@{recordKey}.yaml:41 Root cause: The 200 response defined both application/json (with RecordResponse schema) and */* (with empty schema) content types. The validator creates an internal oneOf between content types, and */* overlaps with application/json causing ambiguous matching. Since KV store records can contain any content type (HTML, text, binary, JSON of any shape), using only */* with an empty schema correctly represents the endpoint behavior without content type ambiguity. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/lib/key_value_stores.ts#L549 --- .../components/schemas/key-value-stores/RecordResponse.yaml | 5 +++-- .../key-value-stores@{storeId}@records@{recordKey}.yaml | 3 --- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml b/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml index 9e7aa22fb8..a5c09dc69c 100644 --- a/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml +++ b/apify-api/openapi/components/schemas/key-value-stores/RecordResponse.yaml @@ -1,8 +1,9 @@ title: RecordResponse description: | The response body contains the value of the record. The content type of the response - is determined by the Content-Type header stored with the record. The value can be any - JSON type (object, array, string, number, boolean, or null). + is determined by the Content-Type header stored with the record. +type: object +additionalProperties: true example: message: Hello, world! count: 42 diff --git a/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml b/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml index c268c09a58..fa55ce1f21 100644 --- a/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml +++ b/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml @@ -38,9 +38,6 @@ get: description: "" headers: {} content: - application/json: - schema: - $ref: ../../components/schemas/key-value-stores/RecordResponse.yaml "*/*": schema: {} "302": From dbf317591f311c98e915bd8403bbb5c8b3aa53d9 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 8 Apr 2026 19:36:58 +0000 Subject: [PATCH 3/9] fix(openapi): revert KV store fix, fix sourceFiles required fields, remove URI format from request URL Revert: KV store record GET content type removal (false positive - oneOf at /response level is a validator bug) Error: WARN Response OpenAPI validation error {"url":"/v2/acts","method":"POST","errors":[{"message":"must have required property 'format'"}]} Files: components/schemas/actors/SourceCodeFile.yaml:3 Root cause: SourceCodeFile schema required format and content, but backend schema marks both as optional with defaults Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/packages/actor/src/actors/actors.both.ts#L272 Error: WARN Response OpenAPI validation error {"url":"/v2/request-queues/{queueId}/head/lock","errors":[{"message":"must match format \"uri\""}]} Files: components/schemas/request-queues/SharedProperties.yaml:18 Root cause: RequestUrl had format: uri but backend does not validate URLs as URIs Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/packages/schemas/src/request_queues.ts#L27 --- .../openapi/components/schemas/actors/SourceCodeFile.yaml | 2 -- .../components/schemas/request-queues/SharedProperties.yaml | 1 - .../key-value-stores@{storeId}@records@{recordKey}.yaml | 3 +++ 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apify-api/openapi/components/schemas/actors/SourceCodeFile.yaml b/apify-api/openapi/components/schemas/actors/SourceCodeFile.yaml index 794b69fb3a..93bd669315 100644 --- a/apify-api/openapi/components/schemas/actors/SourceCodeFile.yaml +++ b/apify-api/openapi/components/schemas/actors/SourceCodeFile.yaml @@ -1,8 +1,6 @@ title: SourceCodeFile type: object required: - - format - - content - name properties: format: diff --git a/apify-api/openapi/components/schemas/request-queues/SharedProperties.yaml b/apify-api/openapi/components/schemas/request-queues/SharedProperties.yaml index 978c9fba9e..0cc68413a8 100644 --- a/apify-api/openapi/components/schemas/request-queues/SharedProperties.yaml +++ b/apify-api/openapi/components/schemas/request-queues/SharedProperties.yaml @@ -15,7 +15,6 @@ UniqueKey: RequestUrl: type: string - format: uri description: The URL of the request. examples: [https://apify.com] diff --git a/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml b/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml index fa55ce1f21..c268c09a58 100644 --- a/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml +++ b/apify-api/openapi/paths/key-value-stores/key-value-stores@{storeId}@records@{recordKey}.yaml @@ -38,6 +38,9 @@ get: description: "" headers: {} content: + application/json: + schema: + $ref: ../../components/schemas/key-value-stores/RecordResponse.yaml "*/*": schema: {} "302": From 2cc6a7d567f3ec168a3c717d41fa3af2786f0bf3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Apr 2026 06:15:37 +0000 Subject: [PATCH 4/9] fix(openapi): fix content types, required fields, parameter serialization, and type constraints Error: unsupported media type application/x-www-form-urlencoded at /v2/acts/{actorId}/runs and 5 other run endpoints Files: paths/actors/acts@{actorId}@runs.yaml:114, paths/actors/acts@{actorId}@run-sync.yaml:40, paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml:63, paths/actor-tasks/actor-tasks@{actorTaskId}@runs.yaml:105, paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync.yaml:40, paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml:63 Root cause: These endpoints use BODY_PARSER_TYPES.raw which accepts any content type via type: () => true. The spec only declared application/json but needs wildcard */* to match actual API behavior. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/middleware/body_parser.ts#L61 Error: must have required property 'name' at POST /v2/actor-tasks Files: components/schemas/actor-tasks/CreateTaskRequest.yaml:3 Root cause: Backend auto-generates task name if not provided (createActorTask generates name from actor name + random suffix). Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/packages/actor-server/src/actor_tasks/actor_tasks.server.ts#L417 Error: Unknown query parameter 'waitForFinish' at GET /v2/acts/{actorId}/runs/last Files: paths/actors/acts@{actorId}@runs@last.yaml:63 Root cause: The runs/last endpoint supports the same parameters as the run object endpoint, including waitForFinish. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/routes/routes_config.ts#L369 Error: must match format "uri" at POST /v2/webhooks for requestUrl Files: components/schemas/webhooks/WebhookCreate.yaml:29 Root cause: Backend validates webhook requestUrl using custom WEBHOOK_REQUEST_URL_REGEXP (HTTP_URL_REGEX | LOCALHOST_URL_REGEXP), not strict URI format. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/packages/consts/src/webhooks.ts#L31 Error: must be object,null for payload at POST /v2/request-queues/{queueId}/requests/batch Files: components/schemas/request-queues/RequestBase.yaml:18 Root cause: Backend request queue schema defines payload as SimpleSchema.oneOf(String, Object) on client side, accepting both string and object types. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/packages/schemas/src/request_queues.ts#L40 Error: Parameter 'status' must be url encoded - reserved characters at GET /v2/acts/{actorId}/runs Files: components/parameters/runAndBuildParameters.yaml:254 Root cause: API accepts comma-separated status values (e.g. ?status=SUCCEEDED,ABORTED). Changed to array type with explode:false to properly model comma-separated serialization. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/routes/actors/act_run_list.ts#L1 Error: Parameter 'filter' must be url encoded - reserved characters at GET /v2/request-queues/{queueId}/requests Files: paths/request-queues/request-queues@{queueId}@requests.yaml:38 Root cause: API accepts comma-separated filter values (e.g. ?filter=pending,locked). Changed to array type with explode:false to properly model comma-separated serialization. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/routes/request_queues/request_queue_request_list.ts#L1 Error: Parameter 'startedAfter' must be url encoded - reserved characters at GET /v2/acts/{actorId}/runs Files: components/parameters/runAndBuildParameters.yaml:266 Root cause: ISO 8601 datetime strings contain colons which are reserved characters. Added allowReserved:true since the API accepts unencoded datetime strings. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/routes/actors/act_run_list.ts#L1 --- .../parameters/runAndBuildParameters.yaml | 10 +++++++--- .../schemas/actor-tasks/CreateTaskRequest.yaml | 1 - .../schemas/request-queues/RequestBase.yaml | 2 +- .../components/schemas/webhooks/WebhookCreate.yaml | 1 - ...s@{actorTaskId}@run-sync-get-dataset-items.yaml | 2 ++ .../actor-tasks@{actorTaskId}@run-sync.yaml | 2 ++ .../actor-tasks@{actorTaskId}@runs.yaml | 2 ++ .../acts@{actorId}@run-sync-get-dataset-items.yaml | 2 ++ .../paths/actors/acts@{actorId}@run-sync.yaml | 2 ++ .../openapi/paths/actors/acts@{actorId}@runs.yaml | 2 ++ .../paths/actors/acts@{actorId}@runs@last.yaml | 1 + .../request-queues@{queueId}@requests.yaml | 14 ++++++++------ 12 files changed, 29 insertions(+), 12 deletions(-) diff --git a/apify-api/openapi/components/parameters/runAndBuildParameters.yaml b/apify-api/openapi/components/parameters/runAndBuildParameters.yaml index 9272da7a8c..32bf01c9a3 100644 --- a/apify-api/openapi/components/parameters/runAndBuildParameters.yaml +++ b/apify-api/openapi/components/parameters/runAndBuildParameters.yaml @@ -258,10 +258,12 @@ status: Single status or comma-separated list of statuses, see ([available statuses](https://docs.apify.com/platform/actors/running/runs-and-builds#lifecycle)). Used to filter runs by the specified statuses only. style: form - explode: true + explode: false schema: - type: string - example: SUCCEEDED + type: array + items: + type: string + example: [SUCCEEDED] startedAfter: name: startedAfter @@ -271,6 +273,7 @@ startedAfter: The value must be a valid ISO 8601 datetime string (UTC). style: form explode: true + allowReserved: true schema: type: string format: date-time @@ -284,6 +287,7 @@ startedBefore: The value must be a valid ISO 8601 datetime string (UTC). style: form explode: true + allowReserved: true schema: type: string format: date-time diff --git a/apify-api/openapi/components/schemas/actor-tasks/CreateTaskRequest.yaml b/apify-api/openapi/components/schemas/actor-tasks/CreateTaskRequest.yaml index 715f3bc970..ba57eca13d 100644 --- a/apify-api/openapi/components/schemas/actor-tasks/CreateTaskRequest.yaml +++ b/apify-api/openapi/components/schemas/actor-tasks/CreateTaskRequest.yaml @@ -1,7 +1,6 @@ title: CreateTaskRequest required: - actId - - name type: object properties: actId: diff --git a/apify-api/openapi/components/schemas/request-queues/RequestBase.yaml b/apify-api/openapi/components/schemas/request-queues/RequestBase.yaml index 516e3f04fa..1a830adbab 100644 --- a/apify-api/openapi/components/schemas/request-queues/RequestBase.yaml +++ b/apify-api/openapi/components/schemas/request-queues/RequestBase.yaml @@ -15,7 +15,7 @@ properties: description: The final URL that was loaded, after redirects (if any). examples: [https://apify.com/jobs] payload: - type: [object, "null"] + type: [string, object, "null"] description: The request payload, typically used with POST or PUT requests. examples: [null] headers: diff --git a/apify-api/openapi/components/schemas/webhooks/WebhookCreate.yaml b/apify-api/openapi/components/schemas/webhooks/WebhookCreate.yaml index ed7a8df11b..d9f5d51d05 100644 --- a/apify-api/openapi/components/schemas/webhooks/WebhookCreate.yaml +++ b/apify-api/openapi/components/schemas/webhooks/WebhookCreate.yaml @@ -27,7 +27,6 @@ properties: examples: [false] requestUrl: type: string - format: uri examples: ["http://example.com/"] payloadTemplate: type: [string, "null"] 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 e1766d758d..850f4cefff 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 @@ -156,6 +156,8 @@ post: type: object example: foo: bar + "*/*": + schema: {} required: true responses: "201": 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 ee5ee2c95f..de1a00d34b 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 @@ -115,6 +115,8 @@ post: type: object example: foo: bar + "*/*": + schema: {} required: true responses: "201": 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 1d0d28e124..707d0d3f32 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 @@ -106,6 +106,8 @@ post: type: object example: foo: bar + "*/*": + schema: {} required: true responses: "201": 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 ed1b8ab7f6..77961ef52c 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 @@ -64,6 +64,8 @@ post: type: object example: foo: bar + "*/*": + schema: {} required: true responses: "201": 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 cc6d0e753a..74e08e01b7 100644 --- a/apify-api/openapi/paths/actors/acts@{actorId}@run-sync.yaml +++ b/apify-api/openapi/paths/actors/acts@{actorId}@run-sync.yaml @@ -42,6 +42,8 @@ post: type: object example: foo: bar + "*/*": + schema: {} required: true responses: "201": diff --git a/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml b/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml index 91724f0700..ba01efc75e 100644 --- a/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml +++ b/apify-api/openapi/paths/actors/acts@{actorId}@runs.yaml @@ -117,6 +117,8 @@ post: type: object example: foo: bar + "*/*": + schema: {} required: true responses: "201": diff --git a/apify-api/openapi/paths/actors/acts@{actorId}@runs@last.yaml b/apify-api/openapi/paths/actors/acts@{actorId}@runs@last.yaml index 2a2db848c2..d1ab17b904 100644 --- a/apify-api/openapi/paths/actors/acts@{actorId}@runs@last.yaml +++ b/apify-api/openapi/paths/actors/acts@{actorId}@runs@last.yaml @@ -60,6 +60,7 @@ get: parameters: - $ref: "../../components/parameters/runAndBuildParameters.yaml#/actorId" - $ref: "../../components/parameters/runAndBuildParameters.yaml#/statusLastRun" + - $ref: "../../components/parameters/runAndBuildParameters.yaml#/waitForFinishRun" responses: "200": description: "" diff --git a/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests.yaml b/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests.yaml index e72f06e0af..bb494c0ef0 100644 --- a/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests.yaml +++ b/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests.yaml @@ -39,13 +39,15 @@ get: in: query description: Filter requests by their state. Possible values are `locked` and `pending`. (Is not compatible with deprecated `exclusiveStartId` parameter.) style: form - explode: true + explode: false schema: - type: string - enum: - - locked - - pending - example: locked + type: array + items: + type: string + enum: + - locked + - pending + example: [locked] responses: "200": description: "" From 84e88e9099acab7b51678b58d884dd0b45b24e23 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Apr 2026 06:41:10 +0000 Subject: [PATCH 5/9] fix(openapi): add waitForFinish to actor-tasks runs/last, add identity to Content-Encoding enum Error: Unknown query parameter 'waitForFinish' at GET /v2/actor-tasks/{actorTaskId}/runs/last Files: paths/actor-tasks/actor-tasks@{actorTaskId}@runs@last.yaml:55 Root cause: The actor-tasks runs/last endpoint forwards all query parameters (including waitForFinish) to the actual run endpoint via routeToLastRunRoutes(), same as the actors runs/last endpoint. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/routes/actor_tasks/last_run.ts#L1 Error: must be equal to one of the allowed values: gzip, deflate, br at PUT /v2/key-value-stores/{storeId}/records/{recordKey} Files: components/objects/key-value-stores/key-value-stores@{storeId}@records@{recordKey}put.yaml:13 Root cause: The API accepts identity encoding for HTML records (checked at record.ts:102 against [...RECORD_SUPPORTED_ENCODING_TYPES_LIST, IDENTITY_ENCODING_TYPE]). The identity value was missing from the spec's Content-Encoding enum. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/routes/key_value_stores/record.ts#L102 --- .../key-value-stores@{storeId}@records@{recordKey}put.yaml | 1 + .../paths/actor-tasks/actor-tasks@{actorTaskId}@runs@last.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/apify-api/openapi/components/objects/key-value-stores/key-value-stores@{storeId}@records@{recordKey}put.yaml b/apify-api/openapi/components/objects/key-value-stores/key-value-stores@{storeId}@records@{recordKey}put.yaml index 8cb3d634df..fe4b3fb606 100644 --- a/apify-api/openapi/components/objects/key-value-stores/key-value-stores@{storeId}@records@{recordKey}put.yaml +++ b/apify-api/openapi/components/objects/key-value-stores/key-value-stores@{storeId}@records@{recordKey}put.yaml @@ -14,6 +14,7 @@ shared: &shared - gzip - deflate - br + - identity type: string requestBody: description: "" diff --git a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs@last.yaml b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs@last.yaml index a0c7a1045e..ffc9ed16a6 100644 --- a/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs@last.yaml +++ b/apify-api/openapi/paths/actor-tasks/actor-tasks@{actorTaskId}@runs@last.yaml @@ -53,6 +53,7 @@ get: parameters: - $ref: "../../components/parameters/runAndBuildParameters.yaml#/actorTaskId" - $ref: "../../components/parameters/runAndBuildParameters.yaml#/statusLastRun" + - $ref: "../../components/parameters/runAndBuildParameters.yaml#/waitForFinishRun" responses: "200": description: "" From 0b907d7b96ab79b8bddee0fb0f595011ca49569a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Apr 2026 06:57:04 +0000 Subject: [PATCH 6/9] fix(openapi): add missing view parameter to run-sync-get-dataset-items endpoints Error: Unknown query parameter 'view' at POST /v2/acts/{actorId}/run-sync-get-dataset-items and POST /v2/actor-tasks/{actorTaskId}/run-sync-get-dataset-items Files: paths/actors/acts@{actorId}@run-sync-get-dataset-items.yaml, paths/actor-tasks/actor-tasks@{actorTaskId}@run-sync-get-dataset-items.yaml Root cause: The run-sync-get-dataset-items endpoints call respondWithDatasetItemsStream() which processes the view query parameter, but the spec was missing this parameter. Also extracted the inline view parameter from datasets@{datasetId}@items.yaml into a reusable component in datasetItemsParameters.yaml. Reference: https://github.com/apify/apify-core/tree/e8976db3b5b2476d2f01af1a84d4268fc61e839f/src/api/src/routes/actors/run_sync_dataset.ts#L57 --- .../parameters/datasetItemsParameters.yaml | 11 ++++++++++ ...torTaskId}@run-sync-get-dataset-items.yaml | 2 ++ ...@{actorId}@run-sync-get-dataset-items.yaml | 2 ++ .../datasets/datasets@{datasetId}@items.yaml | 20 ++----------------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/apify-api/openapi/components/parameters/datasetItemsParameters.yaml b/apify-api/openapi/components/parameters/datasetItemsParameters.yaml index 57d6174053..b8ea1cfb4d 100644 --- a/apify-api/openapi/components/parameters/datasetItemsParameters.yaml +++ b/apify-api/openapi/components/parameters/datasetItemsParameters.yaml @@ -206,6 +206,17 @@ descDataset: type: boolean example: true +view: + name: view + in: query + description: | + Defines the view configuration for dataset items based on the schema definition. + This parameter determines how the data will be filtered and presented. + For complete specification details, see the [dataset schema documentation](/platform/actors/development/actor-definition/dataset-schema). + schema: + type: string + example: overview + skipFailedPages: name: skipFailedPages in: query 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 850f4cefff..0acc7f3d49 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 @@ -49,6 +49,7 @@ get: - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipHidden" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipEmpty" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/simplified" + - $ref: "../../components/parameters/datasetItemsParameters.yaml#/view" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipFailedPages" responses: "201": @@ -147,6 +148,7 @@ post: - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipHidden" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipEmpty" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/simplified" + - $ref: "../../components/parameters/datasetItemsParameters.yaml#/view" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipFailedPages" requestBody: description: "" 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 77961ef52c..74a47d4236 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 @@ -55,6 +55,7 @@ post: - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipHidden" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipEmpty" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/simplified" + - $ref: "../../components/parameters/datasetItemsParameters.yaml#/view" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipFailedPages" requestBody: description: "" @@ -158,6 +159,7 @@ get: - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipHidden" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipEmpty" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/simplified" + - $ref: "../../components/parameters/datasetItemsParameters.yaml#/view" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipFailedPages" responses: "201": diff --git a/apify-api/openapi/paths/datasets/datasets@{datasetId}@items.yaml b/apify-api/openapi/paths/datasets/datasets@{datasetId}@items.yaml index 449f9fe6ab..33b5b957f8 100644 --- a/apify-api/openapi/paths/datasets/datasets@{datasetId}@items.yaml +++ b/apify-api/openapi/paths/datasets/datasets@{datasetId}@items.yaml @@ -173,15 +173,7 @@ get: - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipHidden" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipEmpty" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/simplified" - - name: view - in: query - description: | - Defines the view configuration for dataset items based on the schema definition. - This parameter determines how the data will be filtered and presented. - For complete specification details, see the [dataset schema documentation](/platform/actors/development/actor-definition/dataset-schema). - schema: - type: string - example: overview + - $ref: "../../components/parameters/datasetItemsParameters.yaml#/view" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipFailedPages" - $ref: "../../components/parameters/storageParameters.yaml#/signature" responses: @@ -274,15 +266,7 @@ head: - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipHidden" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipEmpty" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/simplified" - - name: view - in: query - description: | - Defines the view configuration for dataset items based on the schema definition. - This parameter determines how the data will be filtered and presented. - For complete specification details, see the [dataset schema documentation](/platform/actors/development/actor-definition/dataset-schema). - schema: - type: string - example: overview + - $ref: "../../components/parameters/datasetItemsParameters.yaml#/view" - $ref: "../../components/parameters/datasetItemsParameters.yaml#/skipFailedPages" - $ref: "../../components/parameters/storageParameters.yaml#/signature" responses: From cb46377f5f94ed10cea4254da996c9325d2e6b32 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 9 Apr 2026 11:49:27 +0200 Subject: [PATCH 7/9] Add syntax hint about const for agents --- AGENTS.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 9223bb4cda..6780350178 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -71,6 +71,22 @@ Add code samples by creating files in `apify-api/openapi/code_samples/{javascrip - Each endpoint that has `runs/last` in its path or that has any ID related parameter (for example `actorId`, `buildId`, `runId`, `datasetId` and so on) should have at least one 404 (Not Found) error. - Each endpoint that has `requestBody` should have at least following error responses: 413 (Payload Too Large), 415 (Unsupported Media Type). +#### Syntax hints +- Instead of using one item `enum`, use `const`: +Avoid this: +```yaml +schema: + type: string + enum: + - "constantValue" +``` +Use this: +```yaml +schema: + type: string + const: "constantValue" +``` + ### Theme system Uses `@apify/docs-theme` package - a shared theme across all 6+ documentation repos. Don't modify theme files directly. Changes to the theme propagate via CI to all projects. From 63945b426cad2c15b8ff0c55069be765d0e425ef Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Apr 2026 09:54:40 +0000 Subject: [PATCH 8/9] refactor(openapi): replace single-item enums with const Per reviewer feedback and updated AGENTS.md syntax hints, replace all single-item enum definitions with const (OpenAPI 3.1 syntax). Files: - components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml:11 - components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml:10 - components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml:12 - components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml:12 - paths/request-queues/request-queues@{queueId}@requests@batch.yaml:95 --- .../actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml | 3 +-- .../schemas/actor-pricing-info/FreeActorPricingInfo.yaml | 3 +-- .../actor-pricing-info/PayPerEventActorPricingInfo.yaml | 3 +-- .../PricePerDatasetItemActorPricingInfo.yaml | 3 +-- .../request-queues@{queueId}@requests@batch.yaml | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml index 50267b665b..5668199a77 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/FlatPricePerMonthActorPricingInfo.yaml @@ -9,8 +9,7 @@ allOf: properties: pricingModel: type: string - enum: - - FLAT_PRICE_PER_MONTH + const: FLAT_PRICE_PER_MONTH trialMinutes: type: integer description: For how long this Actor can be used for free in trial period diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml index 4d269f73e5..c6e87d7429 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/FreeActorPricingInfo.yaml @@ -7,5 +7,4 @@ allOf: properties: pricingModel: type: string - enum: - - FREE + const: FREE diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml index b7035e5dc7..8e68109096 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/PayPerEventActorPricingInfo.yaml @@ -8,8 +8,7 @@ allOf: properties: pricingModel: type: string - enum: - - PAY_PER_EVENT + const: PAY_PER_EVENT pricingPerEvent: type: object properties: diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml index 6b857820d6..a912818d51 100644 --- a/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml +++ b/apify-api/openapi/components/schemas/actor-pricing-info/PricePerDatasetItemActorPricingInfo.yaml @@ -9,8 +9,7 @@ allOf: properties: pricingModel: type: string - enum: - - PRICE_PER_DATASET_ITEM + const: PRICE_PER_DATASET_ITEM unitName: type: string description: Name of the unit that is being charged diff --git a/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests@batch.yaml b/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests@batch.yaml index de00a3ab63..f466404f5f 100644 --- a/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests@batch.yaml +++ b/apify-api/openapi/paths/request-queues/request-queues@{queueId}@requests@batch.yaml @@ -92,9 +92,8 @@ delete: required: true style: simple schema: - enum: - - application/json type: string + const: application/json - $ref: "../../components/parameters/storageParameters.yaml#/clientKey" requestBody: description: "" From 775e660cbcefc6a6c8d37ea99df6caf9a2a965ae Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 10 Apr 2026 08:04:27 +0200 Subject: [PATCH 9/9] Remove unused `PricingModel.yaml` --- .../schemas/actor-pricing-info/PricingModel.yaml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 apify-api/openapi/components/schemas/actor-pricing-info/PricingModel.yaml diff --git a/apify-api/openapi/components/schemas/actor-pricing-info/PricingModel.yaml b/apify-api/openapi/components/schemas/actor-pricing-info/PricingModel.yaml deleted file mode 100644 index d8092098ae..0000000000 --- a/apify-api/openapi/components/schemas/actor-pricing-info/PricingModel.yaml +++ /dev/null @@ -1,7 +0,0 @@ -title: PricingModel -type: string -enum: - - PAY_PER_EVENT - - PRICE_PER_DATASET_ITEM - - FLAT_PRICE_PER_MONTH - - FREE