Improve search_key/error_code API docs and reorganize Fern sections (#SKY-7884) (#4740)
Co-authored-by: Suchintan Singh <suchintan@skyvern.com>
This commit is contained in:
@@ -176,15 +176,20 @@ navigation:
|
||||
hidden: true
|
||||
- GET /v1/runs/{run_id}/timeline
|
||||
- section: Workflows
|
||||
contents:
|
||||
- GET /v1/workflows
|
||||
- POST /v1/workflows
|
||||
- GET /v1/workflows/{workflow_permanent_id}
|
||||
- GET /v1/workflows/{workflow_permanent_id}/versions
|
||||
- POST /v1/workflows/{workflow_id}
|
||||
- POST /v1/workflows/{workflow_id}/delete
|
||||
- section: Workflow Runs
|
||||
contents:
|
||||
- POST /v1/run/workflows
|
||||
- GET /v1/workflows/runs
|
||||
- GET /v1/runs/{run_id}
|
||||
- POST /v1/runs/{run_id}/cancel
|
||||
- POST /v1/runs/{run_id}/retry_webhook
|
||||
- GET /v1/workflows
|
||||
- POST /v1/workflows
|
||||
- POST /v1/workflows/{workflow_id}
|
||||
- POST /v1/workflows/{workflow_id}/delete
|
||||
- GET /v1/runs/{run_id}/timeline
|
||||
- section: Browser Sessions
|
||||
contents:
|
||||
@@ -202,6 +207,7 @@ navigation:
|
||||
contents:
|
||||
- POST /v1/credentials
|
||||
- GET /v1/credentials/{credential_id}
|
||||
- POST /v1/credentials/{credential_id}/update
|
||||
- POST /v1/credentials/{credential_id}/delete
|
||||
- GET /v1/credentials
|
||||
- POST /v1/credentials/totp
|
||||
|
||||
@@ -333,7 +333,7 @@ async def run_task(
|
||||
|
||||
@base_router.post(
|
||||
"/run/workflows",
|
||||
tags=["Workflows"],
|
||||
tags=["Workflow Runs"],
|
||||
openapi_extra={
|
||||
"x-fern-sdk-method-name": "run_workflow",
|
||||
"x-fern-examples": [
|
||||
@@ -438,7 +438,7 @@ async def run_workflow(
|
||||
|
||||
@base_router.get(
|
||||
"/runs/{run_id}",
|
||||
tags=["Agent", "Workflows"],
|
||||
tags=["Agent", "Workflow Runs"],
|
||||
response_model=RunResponse,
|
||||
description="Get run information (task run, workflow run)",
|
||||
summary="Get a run by id",
|
||||
@@ -480,7 +480,7 @@ async def get_run(
|
||||
|
||||
@base_router.post(
|
||||
"/runs/{run_id}/cancel",
|
||||
tags=["Agent", "Workflows"],
|
||||
tags=["Agent", "Workflow Runs"],
|
||||
openapi_extra={
|
||||
"x-fern-sdk-method-name": "cancel_run",
|
||||
"x-fern-examples": [
|
||||
@@ -1444,7 +1444,7 @@ async def get_run_artifacts(
|
||||
|
||||
@base_router.post(
|
||||
"/runs/{run_id}/retry_webhook",
|
||||
tags=["Agent"],
|
||||
tags=["Agent", "Workflow Runs"],
|
||||
openapi_extra={
|
||||
"x-fern-sdk-method-name": "retry_run_webhook",
|
||||
"x-fern-examples": [
|
||||
@@ -1477,7 +1477,7 @@ async def retry_run_webhook(
|
||||
|
||||
@base_router.get(
|
||||
"/runs/{run_id}/timeline",
|
||||
tags=["Agent", "Workflows"],
|
||||
tags=["Agent", "Workflow Runs"],
|
||||
response_model=list[WorkflowRunTimeline],
|
||||
openapi_extra={
|
||||
"x-fern-sdk-method-name": "get_run_timeline",
|
||||
@@ -1992,7 +1992,13 @@ async def get_runs(
|
||||
status: Annotated[list[WorkflowRunStatus] | None, Query()] = None,
|
||||
search_key: str | None = Query(
|
||||
None,
|
||||
description="Search runs by run ID, parameter key, parameter description, run parameter value, or extra HTTP headers.",
|
||||
description=(
|
||||
"Case-insensitive substring search across: workflow run ID, "
|
||||
"parameter key, parameter description, run parameter value, "
|
||||
"and extra HTTP headers. A run is returned if any of these fields match. "
|
||||
"Soft-deleted parameter definitions are excluded from key/description matching."
|
||||
),
|
||||
examples=["login_url", "credential_value", "wr_abc123"],
|
||||
),
|
||||
) -> Response:
|
||||
analytics.capture("skyvern-oss-agent-runs-get")
|
||||
@@ -2205,11 +2211,32 @@ async def run_workflow_legacy(
|
||||
@base_router.get(
|
||||
"/workflows/runs",
|
||||
response_model=list[WorkflowRun],
|
||||
tags=["Workflows"],
|
||||
tags=["Workflow Runs"],
|
||||
description=(
|
||||
"List workflow runs across all workflows for the current organization. "
|
||||
"Results are paginated and can be filtered by status, search key, and error code. "
|
||||
"All filters are combined with AND logic."
|
||||
"List workflow runs across all workflows for the current organization.\n\n"
|
||||
"Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. "
|
||||
"All filters are combined with **AND** logic — a run must match every supplied filter to be returned.\n\n"
|
||||
"### search_key\n\n"
|
||||
"A case-insensitive substring search that matches against **any** of the following fields:\n\n"
|
||||
"| Searched field | Description |\n"
|
||||
"|---|---|\n"
|
||||
"| `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) |\n"
|
||||
"| Parameter **key** | The `key` of any workflow parameter definition associated with the run |\n"
|
||||
"| Parameter **description** | The `description` of any workflow parameter definition |\n"
|
||||
"| Run parameter **value** | The actual value supplied for any parameter when the run was created |\n"
|
||||
"| `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) |\n\n"
|
||||
"Soft-deleted parameter definitions are excluded from key/description matching. "
|
||||
"A run is returned if **any** of the fields above contain the search term.\n\n"
|
||||
"### error_code\n\n"
|
||||
"An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. "
|
||||
"A run matches if **any** of its tasks contains an error object with a matching `error_code` value. "
|
||||
"Error codes are user-defined strings set during workflow execution "
|
||||
"(e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`).\n\n"
|
||||
"### Combining filters\n\n"
|
||||
"All query parameters use AND logic:\n"
|
||||
"- `?status=failed` — only failed runs\n"
|
||||
"- `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error\n"
|
||||
"- `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match"
|
||||
),
|
||||
summary="List workflow runs",
|
||||
openapi_extra={
|
||||
@@ -2241,14 +2268,22 @@ async def get_workflow_runs(
|
||||
search_key: str | None = Query(
|
||||
None,
|
||||
max_length=500,
|
||||
description="Search runs by run ID, parameter key, parameter description, run parameter value, or extra HTTP headers.",
|
||||
examples=["login_url", "credential_value"],
|
||||
description=(
|
||||
"Case-insensitive substring search across: workflow run ID, "
|
||||
"parameter key, parameter description, run parameter value, "
|
||||
"and extra HTTP headers. A run is returned if any of these fields match. "
|
||||
"Soft-deleted parameter definitions are excluded from key/description matching."
|
||||
),
|
||||
examples=["login_url", "credential_value", "wr_abc123"],
|
||||
),
|
||||
error_code: str | None = Query(
|
||||
None,
|
||||
max_length=500,
|
||||
description="Filter runs by user-defined error code stored in task errors. "
|
||||
"Matches against the error_code field in the task errors JSON array.",
|
||||
description=(
|
||||
"Exact-match filter on the error_code field inside each task's errors JSON array. "
|
||||
"A run matches if any of its tasks contains an error with a matching error_code. "
|
||||
"Error codes are user-defined strings set during workflow execution."
|
||||
),
|
||||
examples=["INVALID_CREDENTIALS", "LOGIN_FAILED", "CAPTCHA_DETECTED"],
|
||||
),
|
||||
current_org: Organization = Depends(org_auth_service.get_current_org),
|
||||
@@ -2256,13 +2291,22 @@ async def get_workflow_runs(
|
||||
"""
|
||||
List workflow runs across all workflows for the current organization.
|
||||
|
||||
Results are paginated and can be filtered by status, search key, and error code.
|
||||
All filters are combined with AND logic.
|
||||
All filters (**status**, **search_key**, **error_code**) are combined with AND logic.
|
||||
|
||||
**search_key** performs a case-insensitive substring match across:
|
||||
- `workflow_run_id` — the unique run identifier
|
||||
- Parameter **key** and **description** from workflow parameter definitions (soft-deleted parameters excluded)
|
||||
- Run parameter **value** — the actual value supplied when the run was created
|
||||
- `extra_http_headers` — searched as raw JSON text
|
||||
|
||||
**error_code** performs an exact match against the `error_code` field in the `errors`
|
||||
JSON array on each task. A run matches if *any* of its tasks has a matching error code.
|
||||
|
||||
**Examples:**
|
||||
- All failed runs: `?status=failed`
|
||||
- Failed runs with a specific error: `?status=failed&error_code=INVALID_CREDENTIALS`
|
||||
- Runs matching a parameter value: `?search_key=https://example.com`
|
||||
- Runs matching a run ID: `?search_key=wr_abc123`
|
||||
- Combined: `?status=failed&error_code=LOGIN_FAILED&search_key=my_credential`
|
||||
"""
|
||||
analytics.capture("skyvern-oss-agent-workflow-runs-get")
|
||||
@@ -2280,6 +2324,19 @@ async def get_workflow_runs(
|
||||
"/workflows/{workflow_id}/runs",
|
||||
response_model=list[WorkflowRun],
|
||||
tags=["agent"],
|
||||
description=(
|
||||
"List runs for a specific workflow.\n\n"
|
||||
"Supports filtering by **status**, **search_key**, and **error_code**. "
|
||||
"All filters are combined with **AND** logic.\n\n"
|
||||
"### search_key\n\n"
|
||||
"Case-insensitive substring search across: workflow run ID, "
|
||||
"parameter key, parameter description, run parameter value, "
|
||||
"and extra HTTP headers. Soft-deleted parameter definitions are excluded.\n\n"
|
||||
"### error_code\n\n"
|
||||
"Exact-match filter on the `error_code` field inside each task's `errors` JSON array. "
|
||||
"A run matches if any of its tasks contains an error with a matching `error_code`."
|
||||
),
|
||||
summary="List runs for a workflow",
|
||||
openapi_extra={
|
||||
"x-fern-sdk-method-name": "get_workflow_runs_by_id",
|
||||
},
|
||||
@@ -2291,33 +2348,51 @@ async def get_workflow_runs(
|
||||
)
|
||||
async def get_workflow_runs_by_id(
|
||||
workflow_id: str,
|
||||
page: int = Query(1, ge=1),
|
||||
page_size: int = Query(10, ge=1),
|
||||
status: Annotated[list[WorkflowRunStatus] | None, Query()] = None,
|
||||
page: int = Query(1, ge=1, description="Page number for pagination."),
|
||||
page_size: int = Query(10, ge=1, description="Number of runs to return per page."),
|
||||
status: Annotated[list[WorkflowRunStatus] | None, Query(description="Filter by one or more run statuses.")] = None,
|
||||
search_key: str | None = Query(
|
||||
None,
|
||||
max_length=500,
|
||||
description="Search runs by run ID, parameter key, parameter description, run parameter value, or extra HTTP headers.",
|
||||
description=(
|
||||
"Case-insensitive substring search across: workflow run ID, "
|
||||
"parameter key, parameter description, run parameter value, "
|
||||
"and extra HTTP headers. A run is returned if any of these fields match. "
|
||||
"Soft-deleted parameter definitions are excluded from key/description matching."
|
||||
),
|
||||
examples=["login_url", "credential_value", "wr_abc123"],
|
||||
),
|
||||
error_code: str | None = Query(
|
||||
None,
|
||||
max_length=500,
|
||||
description="Filter runs by user-defined error code stored in task errors. "
|
||||
"Matches against the error_code field in the task errors JSON array.",
|
||||
description=(
|
||||
"Exact-match filter on the error_code field inside each task's errors JSON array. "
|
||||
"A run matches if any of its tasks contains an error with a matching error_code. "
|
||||
"Error codes are user-defined strings set during workflow execution."
|
||||
),
|
||||
examples=["INVALID_CREDENTIALS", "LOGIN_FAILED", "CAPTCHA_DETECTED"],
|
||||
),
|
||||
current_org: Organization = Depends(org_auth_service.get_current_org),
|
||||
) -> list[WorkflowRun]:
|
||||
"""
|
||||
Get workflow runs for a specific workflow permanent id.
|
||||
List runs for a specific workflow permanent id.
|
||||
|
||||
Supports filtering by status, parameter search, and error code. All filters
|
||||
are combined with AND logic.
|
||||
All filters (**status**, **search_key**, **error_code**) are combined with AND logic.
|
||||
|
||||
**search_key** performs a case-insensitive substring match across:
|
||||
- `workflow_run_id` — the unique run identifier
|
||||
- Parameter **key** and **description** from workflow parameter definitions (soft-deleted parameters excluded)
|
||||
- Run parameter **value** — the actual value supplied when the run was created
|
||||
- `extra_http_headers` — searched as raw JSON text
|
||||
|
||||
**error_code** performs an exact match against the `error_code` field in the `errors`
|
||||
JSON array on each task. A run matches if *any* of its tasks has a matching error code.
|
||||
|
||||
**Examples:**
|
||||
- All failed runs: `?status=failed`
|
||||
- Failed runs with a specific error: `?status=failed&error_code=INVALID_CREDENTIALS`
|
||||
- Runs matching a parameter value: `?search_key=https://example.com`
|
||||
- Runs matching a run ID: `?search_key=wr_abc123`
|
||||
- Combined: `?status=failed&error_code=LOGIN_FAILED&search_key=my_credential`
|
||||
"""
|
||||
analytics.capture("skyvern-oss-agent-workflow-runs-get")
|
||||
@@ -2487,9 +2562,20 @@ async def get_workflows(
|
||||
only_templates: bool = Query(False),
|
||||
search_key: str | None = Query(
|
||||
None,
|
||||
description="Unified search across workflow title, folder name, and parameter metadata (key, description, default_value).",
|
||||
description=(
|
||||
"Case-insensitive substring search across: workflow title, folder name, "
|
||||
"and parameter metadata (key, description, default_value). "
|
||||
"A workflow is returned if any of these fields match. "
|
||||
"Soft-deleted parameter definitions are excluded. "
|
||||
"Takes precedence over the deprecated `title` parameter."
|
||||
),
|
||||
examples=["my_workflow", "login_url", "production"],
|
||||
),
|
||||
title: str = Query(
|
||||
"",
|
||||
deprecated=True,
|
||||
description="Deprecated: use search_key instead. Falls back to title-only search if search_key is not provided.",
|
||||
),
|
||||
title: str = Query("", deprecated=True, description="Deprecated: use search_key instead."),
|
||||
folder_id: str | None = Query(None, description="Filter workflows by folder ID"),
|
||||
status: Annotated[list[WorkflowStatus] | None, Query()] = None,
|
||||
current_org: Organization = Depends(org_auth_service.get_current_org),
|
||||
|
||||
Reference in New Issue
Block a user