diff --git a/api-reference/endpoint/feedback.mdx b/api-reference/endpoint/feedback.mdx index 478bc699a..ce5faad6c 100644 --- a/api-reference/endpoint/feedback.mdx +++ b/api-reference/endpoint/feedback.mdx @@ -1,14 +1,16 @@ --- -title: 'Endpoint Feedback' -description: 'Submit feedback for a completed v2 endpoint job.' +title: 'Feedback' +description: 'Submit feedback for a Firecrawl job.' openapi: '/api-reference/v2-openapi.json POST /feedback' --- -Use endpoint feedback to tell Firecrawl whether a completed job result was useful, partial, or bad. This is for endpoint-level output quality on jobs such as `scrape`, `parse`, `map`, and `search`. +Submit feedback on the quality of a job's output, including useful results, missing content, or incorrect data. -The generic feedback schema can carry search-style fields too, but [Search Feedback](/api-reference/endpoint/search-feedback) is the preferred search-specific entry point because it is scoped to a search job ID and highlights valuable sources, missing content, query suggestions, and refund behavior. +For jobs created with an API key, include your key and use the Authenticated request format. For keyless jobs, omit `Authorization` and use the Search, Scrape, or Parse request format. -### Example Request +For authenticated Search jobs, [Search Feedback](/api-reference/endpoint/search-feedback) remains the preferred search-specific entry point for valuable sources, missing content, query suggestions, and refund behavior. + +### Authenticated example ```bash curl -X POST "https://api.firecrawl.dev/v2/feedback" \ @@ -23,3 +25,59 @@ curl -X POST "https://api.firecrawl.dev/v2/feedback" \ "url": "https://example.com/pricing" }' ``` + +### Keyless example + +```bash +curl -X POST "https://api.firecrawl.dev/v2/feedback" \ + -H "Content-Type: application/json" \ + -d '{ + "endpoint": "search", + "jobId": "550e8400-e29b-41d4-a716-446655440000", + "rating": "good", + "task": "Find the documented retry behavior", + "assessment": "The API reference answered the retry question.", + "observations": [ + { + "kind": "useful", + "source": "web", + "position": 1, + "detail": "The reference specifies the retry intervals.", + "basis": "output" + } + ] + }' +``` + +### Keyless feedback + +Feedback is optional and does not affect continued keyless access or consume operation allowance. It remains available after the operation allowance is exhausted. The API invitation says: + +> Consider submitting feedback to POST /v2/feedback, especially if this result is wrong, incomplete, blocked, or an error. Include specific evidence to help improve Firecrawl. + +Use evidence already available from the task; no extra investigation or user interview is required. + +Eligible keyless Search, Scrape, and Parse responses include a job ID and a feedback invitation. Search returns them in `metadata`; successful Scrape and Parse calls return them in `data.metadata`. Failed jobs return them in `metadata`. The invitation includes `jobId`, `endpoint`, and `expiresAt`. Submit from the same IP address used for the job before the invitation's `expiresAt` deadline, which provides a 24-hour feedback window for the job. Each job accepts one submission; retrying a successful submission within the feedback window returns its original feedback ID. If you receive a `429`, wait for `retry_after_seconds` before retrying. + +Keyless requests require `endpoint`, `jobId`, `rating` (`good`, `partial`, or `bad`), `task`, `assessment`, and 1-20 `observations`. Each observation requires `kind`, `detail`, and `basis` (`output`, `source_comparison`, or `expectation`). Source comparisons also require `comparison: {reference, detail}`, describing the correct content from a source already inspected. Parse additionally requires `docClass`: `born_digital`, `scanned`, `mixed`, or `unknown`. + +`task`, `assessment`, and each `detail` must contain 10-2000 characters after trimming leading and trailing whitespace. For Scrape and Parse observations other than failures, `format` must name a requested format. Include it when multiple formats were requested and the basis is `output` or `source_comparison`. + +Keep observations concise and avoid copying full results. Stored feedback must fit within 8 KiB (8192 UTF-8 bytes), including server defaults and verification flags. The [OpenAPI schema](/api-reference/v2-openapi.json) lists each endpoint's observation kinds and reason codes. + +Keyless Parse feedback does not automatically retain the document, extracted output, page images, or layout blocks. Submitted observations and corrections are retained. + +For Search, `position` starts at 1 within the returned `web`, `images`, or `news` results. Set `source` for `images`, `news`, or a search with multiple sources; otherwise it defaults to `web`. Report positions that appear in the response. + +If a failed response includes a feedback invitation, use the reported error in a `failure` observation: + +```json +{ + "kind": "failure", + "reason": "timeout", + "basis": "output", + "detail": "The operation returned a timeout before producing a result." +} +``` + +For failures, omit result-specific fields such as `position`, `format`, or `page`. Parse still requires `docClass`, which may be `unknown`. Requests rejected before execution, such as invalid input or exhausted operation quota, have no feedback job. diff --git a/api-reference/endpoint/parse.mdx b/api-reference/endpoint/parse.mdx index 418cecc2a..82d40cabe 100644 --- a/api-reference/endpoint/parse.mdx +++ b/api-reference/endpoint/parse.mdx @@ -22,3 +22,5 @@ Use `/parse` when the source document is **a local file** or **not publicly acce **Using Firecrawl through MCP?** Use `firecrawl_parse` for local files. Local MCP can read the file directly when configured with `FIRECRAWL_API_URL`. Remote hosted MCP returns a short-lived upload command first, then parses the returned `uploadRef`. Public document URLs should still use `/scrape`. + +Keyless responses may include an invitation to submit [feedback](/api-reference/endpoint/feedback) about the result. diff --git a/api-reference/endpoint/scrape.mdx b/api-reference/endpoint/scrape.mdx index 8c99698ca..9335960fe 100644 --- a/api-reference/endpoint/scrape.mdx +++ b/api-reference/endpoint/scrape.mdx @@ -16,3 +16,5 @@ See the [Interact documentation](/features/interact) for full details and exampl Optionally you can also use the `actions` parameter, although it's not recommended to use it for complex interactions. > Are you an AI agent that needs a Firecrawl API key? See [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) for automated onboarding instructions. + +Keyless responses may include an invitation to submit [feedback](/api-reference/endpoint/feedback) about the result. diff --git a/api-reference/endpoint/search.mdx b/api-reference/endpoint/search.mdx index c2d943a0a..8997fa7f5 100644 --- a/api-reference/endpoint/search.mdx +++ b/api-reference/endpoint/search.mdx @@ -125,3 +125,5 @@ Each result includes a `category` field indicating its source: Use the `tbs` parameter to filter results by time periods, including custom date ranges. See the [Search Feature documentation](https://docs.firecrawl.dev/features/search#time-based-search) for detailed examples and supported formats. > Are you an AI agent that needs a Firecrawl API key? See [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) for automated onboarding instructions. + +Keyless responses may include an invitation to submit [feedback](/api-reference/endpoint/feedback) about the result. diff --git a/api-reference/v2-openapi.json b/api-reference/v2-openapi.json index 48bd7ffd2..15dd84b28 100644 --- a/api-reference/v2-openapi.json +++ b/api-reference/v2-openapi.json @@ -6717,6 +6717,7 @@ "Feedback" ], "security": [ + {}, { "bearerAuth": [] } @@ -6726,7 +6727,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EndpointFeedbackRequest" + "anyOf": [ + { + "title": "Authenticated", + "allOf": [ + { + "$ref": "#/components/schemas/EndpointFeedbackRequest" + } + ] + }, + { + "$ref": "#/components/schemas/KeylessFeedbackRequest" + } + ] } } } @@ -6753,7 +6766,7 @@ } }, "403": { - "description": "Feedback is not available for this team", + "description": "Feedback is not available for this caller", "content": { "application/json": { "schema": { @@ -6763,7 +6776,7 @@ } }, "404": { - "description": "Job not found for this team", + "description": "Job not found for this caller", "content": { "application/json": { "schema": { @@ -6791,8 +6804,39 @@ } } } + }, + "401": { + "description": "Authentication failed or keyless access is unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeedbackErrorResponse" + } + } + } + }, + "429": { + "description": "Too many feedback requests", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeedbackErrorResponse" + } + } + } + }, + "503": { + "description": "Feedback is temporarily unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeedbackErrorResponse" + } + } + } } - } + }, + "description": "Submit feedback for a job. Keyless feedback supports Search, Scrape, and Parse." } }, "/team/threat-protection": { @@ -12930,6 +12974,11 @@ "items": { "type": "object" } + }, + "retry_after_seconds": { + "type": "integer", + "minimum": 1, + "description": "Seconds to wait before retrying a throttled feedback submission." } }, "required": [ @@ -12991,6 +13040,1229 @@ } } }, + "FeedbackComparison": { + "type": "object", + "properties": { + "reference": { + "type": "string", + "description": "URL or location of the source you compared.", + "minLength": 1, + "maxLength": 2048 + }, + "detail": { + "type": "string", + "description": "The correct content from the inspected source, including correct text or cell values when known.", + "minLength": 10, + "maxLength": 2000 + } + }, + "required": [ + "reference", + "detail" + ], + "additionalProperties": false + }, + "FeedbackDetail": { + "type": "string", + "description": "Describe what you observed.", + "minLength": 10, + "maxLength": 2000 + }, + "FeedbackBasis": { + "type": "string", + "enum": [ + "output", + "source_comparison", + "expectation" + ], + "description": "What supports the observation. Use `output` for returned content, `source_comparison` for a source you already inspected, or `expectation` for an unmet need. Include `comparison` when using `source_comparison`." + }, + "KeylessFeedbackRequest": { + "anyOf": [ + { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "enum": [ + "search" + ] + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Job ID returned by /search." + }, + "rating": { + "type": "string", + "enum": [ + "good", + "partial", + "bad" + ], + "description": "Overall quality of the result." + }, + "task": { + "type": "string", + "description": "What you were trying to accomplish.", + "minLength": 10, + "maxLength": 2000 + }, + "assessment": { + "type": "string", + "description": "How well the result met your needs.", + "minLength": 10, + "maxLength": 2000 + }, + "observations": { + "type": "array", + "description": "Specific observations about the result. Text limits exclude leading and trailing whitespace. Unmentioned results are unassessed; a full ranking is not required.", + "minItems": 1, + "maxItems": 20, + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "useful" + ] + }, + "source": { + "type": "string", + "enum": [ + "web", + "images", + "news" + ], + "description": "Delivered group the position refers to. Required for multi-source jobs. Omission defaults to `web`, so images-only and news-only jobs must explicitly name their source." + }, + "position": { + "type": "integer", + "minimum": 1, + "description": "Position in the returned result group, starting at 1.", + "example": 1 + }, + "vertical": { + "type": "string", + "enum": [ + "web_general", + "social", + "business", + "research", + "developer", + "news", + "government", + "finance", + "other" + ], + "description": "Subject area you were looking for." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "position" + ], + "additionalProperties": false, + "title": "useful", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "irrelevant" + ] + }, + "source": { + "type": "string", + "enum": [ + "web", + "images", + "news" + ], + "description": "Delivered group the position refers to. Required for multi-source jobs. Omission defaults to `web`, so images-only and news-only jobs must explicitly name their source." + }, + "position": { + "type": "integer", + "minimum": 1, + "description": "Position in the returned result group, starting at 1.", + "example": 1 + }, + "vertical": { + "type": "string", + "enum": [ + "web_general", + "social", + "business", + "research", + "developer", + "news", + "government", + "finance", + "other" + ], + "description": "Subject area you were looking for." + }, + "reason": { + "type": "string", + "enum": [ + "aggregator_over_official", + "off_topic", + "stale", + "wrong_content_type", + "snippet_misleading", + "blocked_or_paywalled" + ], + "description": "- `aggregator_over_official`: An intermediary was returned where the task needed an available official or primary source.\n- `off_topic`: The result addresses a different topic from the task.\n- `stale`: The content is outdated for the time or version the task requires.\n- `wrong_content_type`: The destination has the wrong content type for the task, such as a discussion instead of a reference.\n- `snippet_misleading`: The returned description misrepresents source content already inspected.\n- `blocked_or_paywalled`: Access to the destination was observed to be blocked or require a subscription; do not infer this from its URL or snippet." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + }, + "knownSources": { + "type": "array", + "description": "Known sources that should have ranked instead of this result.", + "maxItems": 20, + "items": { + "type": "string", + "format": "uri", + "pattern": "^https?://", + "maxLength": 2048 + } + } + }, + "required": [ + "kind", + "detail", + "basis", + "position", + "reason" + ], + "additionalProperties": false, + "title": "irrelevant", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "missing" + ] + }, + "vertical": { + "type": "string", + "enum": [ + "web_general", + "social", + "business", + "research", + "developer", + "news", + "government", + "finance", + "other" + ], + "description": "Subject area you were looking for." + }, + "topic": { + "type": "string", + "description": "Information missing from the results.", + "minLength": 1, + "maxLength": 200 + }, + "knownSources": { + "type": "array", + "description": "Known sources that were missing from the results.", + "maxItems": 20, + "items": { + "type": "string", + "format": "uri", + "pattern": "^https?://", + "maxLength": 2048 + } + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "vertical" + ], + "additionalProperties": false, + "title": "missing", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "title": "failure", + "description": "An explicitly reported failure of this job. Accepted only when the saved job failed. No result position or output format is required.", + "properties": { + "kind": { + "type": "string", + "enum": [ + "failure" + ] + }, + "reason": { + "type": "string", + "enum": [ + "timeout", + "transport_error", + "proxy_error", + "other" + ], + "description": "- `timeout`: The operation explicitly reported a timeout.\n- `transport_error`: The operation explicitly reported a network, connection, or TLS failure.\n- `proxy_error`: The operation explicitly reported a proxy failure.\n- `other`: Another operation failure was reported; describe the returned error without guessing its cause." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "reason", + "detail", + "basis" + ], + "additionalProperties": false, + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + } + ] + } + }, + "origin": { + "type": "string", + "description": "Client submitting the feedback.", + "minLength": 1, + "maxLength": 100, + "default": "api" + }, + "integration": { + "type": "string", + "description": "Supported integration name, or a custom name beginning with `_`.", + "maxLength": 100, + "nullable": true, + "minLength": 1, + "pattern": "^(?:_|(?:dify|zapier|pipedream|raycast|langchain|crewai|llamaindex|n8n|camelai|make|flowise|metagpt|relevanceai|viasocket|cli|hermes|gstack|prometheus)$)" + } + }, + "required": [ + "endpoint", + "jobId", + "rating", + "task", + "assessment", + "observations" + ], + "additionalProperties": false, + "title": "Search" + }, + { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "enum": [ + "scrape" + ] + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Job ID returned by /scrape." + }, + "rating": { + "type": "string", + "enum": [ + "good", + "partial", + "bad" + ], + "description": "Overall quality of the result." + }, + "task": { + "type": "string", + "description": "What you were trying to accomplish.", + "minLength": 10, + "maxLength": 2000 + }, + "assessment": { + "type": "string", + "description": "How well the result met your needs.", + "minLength": 10, + "maxLength": 2000 + }, + "observations": { + "type": "array", + "description": "Specific observations about the result. Text limits exclude leading and trailing whitespace.", + "minItems": 1, + "maxItems": 20, + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "correct" + ] + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "location": { + "type": "string", + "description": "Location of the content in the page or output.", + "minLength": 1, + "maxLength": 200 + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis" + ], + "additionalProperties": false, + "title": "correct", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "wrong_success" + ] + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "location": { + "type": "string", + "description": "Location of the content in the page or output.", + "minLength": 1, + "maxLength": 200 + }, + "reason": { + "type": "string", + "enum": [ + "blocked_shell", + "login_required", + "paywall", + "empty", + "wrong_page", + "stale", + "wrong_locale" + ], + "description": "- `blocked_shell`: The successful response contains a bot challenge or access-blocking shell instead of the requested content.\n- `login_required`: The successful response contains a login requirement instead of the requested content.\n- `paywall`: The successful response contains a subscription barrier instead of the requested content.\n- `empty`: The successful response contains no meaningful requested content.\n- `wrong_page`: The successful response contains a different page or resource.\n- `stale`: The content is outdated for the time or version the task requires.\n- `wrong_locale`: The response uses the wrong language or region for the task." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "reason" + ], + "additionalProperties": false, + "title": "wrong_success", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "incomplete" + ], + "description": "Prefer `source_comparison` when the source is already available, and provide the correct content in `comparison.detail`." + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "location": { + "type": "string", + "description": "Location of the content in the page or output.", + "minLength": 1, + "maxLength": 200 + }, + "reason": { + "type": "string", + "enum": [ + "partial_content", + "dynamic_content", + "pagination", + "main_content_stripped", + "format_lost" + ], + "description": "- `partial_content`: Only part of the expected content was returned, without a more specific known cause.\n- `dynamic_content`: Content loaded by client-side rendering or interaction is missing.\n- `pagination`: Expected content on additional pages is missing.\n- `main_content_stripped`: Content filtering removed requested primary content.\n- `format_lost`: Text is present, but meaningful structure such as headings, lists, or code formatting was lost." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "reason" + ], + "additionalProperties": false, + "title": "incomplete", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "incorrect" + ], + "description": "Prefer `source_comparison` when the source is already available, and provide the correct content in `comparison.detail`." + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "location": { + "type": "string", + "description": "Location of the content in the page or output.", + "minLength": 1, + "maxLength": 200 + }, + "reason": { + "type": "string", + "enum": [ + "wrong", + "hallucinated", + "missing_fields" + ], + "description": "- `wrong`: Returned facts or values conflict with the inspected source.\n- `hallucinated`: The output asserts content unsupported by the inspected source.\n- `missing_fields`: Requested fields are absent from the structured output.\n\n`hallucinated` applies only to `json`, `deterministicJson`, `summary`, `question`, `highlights`, and `changeTracking` in `json` mode. `missing_fields` applies only to `json` and `deterministicJson`." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "reason" + ], + "additionalProperties": false, + "title": "incorrect", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "title": "failure", + "description": "An explicitly reported failure of this job. Accepted only when the saved job failed. No result position or output format is required.", + "properties": { + "kind": { + "type": "string", + "enum": [ + "failure" + ] + }, + "reason": { + "type": "string", + "enum": [ + "timeout", + "transport_error", + "proxy_error", + "other" + ], + "description": "- `timeout`: The operation explicitly reported a timeout.\n- `transport_error`: The operation explicitly reported a network, connection, or TLS failure.\n- `proxy_error`: The operation explicitly reported a proxy failure.\n- `other`: Another operation failure was reported; describe the returned error without guessing its cause." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "reason", + "detail", + "basis" + ], + "additionalProperties": false, + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + } + ] + } + }, + "origin": { + "type": "string", + "description": "Client submitting the feedback.", + "minLength": 1, + "maxLength": 100, + "default": "api" + }, + "integration": { + "type": "string", + "description": "Supported integration name, or a custom name beginning with `_`.", + "maxLength": 100, + "nullable": true, + "minLength": 1, + "pattern": "^(?:_|(?:dify|zapier|pipedream|raycast|langchain|crewai|llamaindex|n8n|camelai|make|flowise|metagpt|relevanceai|viasocket|cli|hermes|gstack|prometheus)$)" + } + }, + "required": [ + "endpoint", + "jobId", + "rating", + "task", + "assessment", + "observations" + ], + "additionalProperties": false, + "title": "Scrape" + }, + { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "enum": [ + "parse" + ] + }, + "jobId": { + "type": "string", + "format": "uuid", + "description": "Job ID returned by /parse." + }, + "rating": { + "type": "string", + "enum": [ + "good", + "partial", + "bad" + ], + "description": "Overall quality of the result." + }, + "task": { + "type": "string", + "description": "What you were trying to accomplish.", + "minLength": 10, + "maxLength": 2000 + }, + "assessment": { + "type": "string", + "description": "How well the result met your needs.", + "minLength": 10, + "maxLength": 2000 + }, + "docClass": { + "type": "string", + "enum": [ + "born_digital", + "scanned", + "mixed", + "unknown" + ], + "description": "Type of document. Use `unknown` if you cannot determine the type." + }, + "observations": { + "type": "array", + "description": "Specific observations about the result. Text limits exclude leading and trailing whitespace.", + "minItems": 1, + "maxItems": 20, + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "correct", + "formula", + "chart_figure", + "reading_order", + "headers_footers", + "headings_formatting", + "images_dropped" + ] + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "page": { + "type": "integer", + "minimum": 1, + "description": "Page number, starting at 1.", + "example": 1 + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis" + ], + "additionalProperties": false, + "title": "Other", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "text_ocr" + ] + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "page": { + "type": "integer", + "minimum": 1, + "description": "Page number, starting at 1.", + "example": 1 + }, + "reason": { + "type": "string", + "enum": [ + "misread_chars", + "garbled", + "missing_text" + ], + "description": "- `misread_chars`: Characters were recognized incorrectly.\n- `garbled`: Extracted text is corrupted or unreadable.\n- `missing_text`: Visible source text was omitted." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "reason" + ], + "additionalProperties": false, + "title": "text_ocr", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "table" + ] + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "page": { + "type": "integer", + "minimum": 1, + "description": "Page number, starting at 1.", + "example": 1 + }, + "reason": { + "type": "string", + "enum": [ + "structure", + "cells_glued", + "digits" + ], + "description": "- `structure`: Table rows, columns, or header relationships were reconstructed incorrectly.\n- `cells_glued`: Distinct table cells were merged.\n- `digits`: Numeric table values were recognized incorrectly." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "reason" + ], + "additionalProperties": false, + "title": "table", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "completeness" + ] + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "page": { + "type": "integer", + "minimum": 1, + "description": "Page number, starting at 1.", + "example": 1 + }, + "reason": { + "type": "string", + "enum": [ + "pages_missing", + "truncated_at_max_pages", + "sections_dropped" + ], + "description": "- `pages_missing`: Source pages are absent from the output.\n- `truncated_at_max_pages`: Extraction ended at the configured page limit; this does not by itself imply a parser error.\n- `sections_dropped`: Sections within processed pages were omitted." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "reason" + ], + "additionalProperties": false, + "title": "completeness", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "incorrect" + ], + "description": "Incorrect `json` or `summary` output." + }, + "format": { + "type": "string", + "description": "Requested output format this observation refers to. Required when the job requested multiple formats and `basis` is `output` or `source_comparison`.", + "minLength": 1 + }, + "page": { + "type": "integer", + "minimum": 1, + "description": "Page number, starting at 1.", + "example": 1 + }, + "reason": { + "type": "string", + "enum": [ + "wrong", + "hallucinated", + "missing_fields" + ], + "description": "- `wrong`: Returned facts or values conflict with the inspected source.\n- `hallucinated`: The output asserts content unsupported by the inspected source.\n- `missing_fields`: Requested fields are absent from the structured output." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "detail", + "basis", + "reason" + ], + "additionalProperties": false, + "title": "incorrect", + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + }, + { + "type": "object", + "title": "failure", + "description": "An explicitly reported failure of this job. Accepted only when the saved job failed. No result position or output format is required.", + "properties": { + "kind": { + "type": "string", + "enum": [ + "failure" + ] + }, + "reason": { + "type": "string", + "enum": [ + "timeout", + "transport_error", + "proxy_error", + "other" + ], + "description": "- `timeout`: The operation explicitly reported a timeout.\n- `transport_error`: The operation explicitly reported a network, connection, or TLS failure.\n- `proxy_error`: The operation explicitly reported a proxy failure.\n- `other`: Another operation failure was reported; describe the returned error without guessing its cause." + }, + "detail": { + "$ref": "#/components/schemas/FeedbackDetail" + }, + "basis": { + "$ref": "#/components/schemas/FeedbackBasis" + }, + "comparison": { + "$ref": "#/components/schemas/FeedbackComparison" + } + }, + "required": [ + "kind", + "reason", + "detail", + "basis" + ], + "additionalProperties": false, + "not": { + "properties": { + "basis": { + "enum": [ + "source_comparison" + ] + } + }, + "not": { + "required": [ + "comparison" + ] + } + } + } + ] + } + }, + "origin": { + "type": "string", + "description": "Client submitting the feedback.", + "minLength": 1, + "maxLength": 100, + "default": "api" + }, + "integration": { + "type": "string", + "description": "Supported integration name, or a custom name beginning with `_`.", + "maxLength": 100, + "nullable": true, + "minLength": 1, + "pattern": "^(?:_|(?:dify|zapier|pipedream|raycast|langchain|crewai|llamaindex|n8n|camelai|make|flowise|metagpt|relevanceai|viasocket|cli|hermes|gstack|prometheus)$)" + } + }, + "required": [ + "endpoint", + "jobId", + "rating", + "task", + "assessment", + "observations", + "docClass" + ], + "additionalProperties": false, + "title": "Parse" + } + ], + "description": "Feedback for a keyless Search, Scrape, or Parse job. Submit within 24 hours from the same IP address used for the job. Each job accepts one submission; retrying a successful submission within the feedback window returns its original feedback ID. Keep observations concise; feedback over 8 KiB is rejected." + }, "AgentPendingApproval": { "type": "object", "description": "What the turn stopped to ask. Answer it on the next turn of the thread with `exchange.approve` or `exchange.decline`.",