{
  "openapi": "3.1.0",
  "servers": [
    {
      "url": "https://api.smooth.sh/api/v1"
    }
  ],
  "info": {
    "title": "Smooth",
    "version": "0.4.1",
    "description": "# Introduction\n\nThe Smooth API allows for programmatic browser automation and task execution. You can run simple one-shot tasks, or create interactive browser sessions for multi-step workflows.\n\nThis documentation provides a guide to using the API directly, as well as through our Python SDK.\n\n# Authentication\n\nTo use the API, you need an API key. The API key must be sent in the `apikey` header with every request.\n\nExample: `apikey: YOUR_API_KEY`\n\nIf you are using the Python SDK, you can provide the API key in two ways:\n\n1.  **Directly in the client constructor**:\n\n    ```python\n    from smooth import SmoothClient\n    client = SmoothClient(api_key=\"YOUR_API_KEY\")\n    ```\n\n2.  **As an environment variable**:\n    Set the `CIRCLEMIND_API_KEY` environment variable, and the client will automatically use it.\n\n    ```bash\n    export CIRCLEMIND_API_KEY=\"YOUR_API_KEY\"\n    ```\n\n# Python SDK\n\nThe Smooth Python SDK provides a convenient way to interact with the Smooth API.\n\n## Installation\n\nYou can install the Smooth Python SDK using pip:\n\n```bash\npip install smooth-py\n```\n\n## Features\n\n*   **Synchronous and Asynchronous Clients**: Choose between `SmoothClient` for traditional sequential programming and `SmoothAsyncClient` for high-performance asynchronous applications.\n*   **Simple Tasks**: Run one-shot browser automation tasks with `client.run()`.\n*   **Session Workflows**: Create browser sessions for multi-step workflows with `client.session()`.\n*   **Custom Tools**: Register Python functions that the agent can call during execution.\n\n## Usage\n\n### Simple Task\n\nRun a one-shot task and wait for the result:\n\n```python\nfrom smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\n\ntask_handle = client.run(\n    task=\"Go to https://www.google.com and search for 'Smooth SDK'\"\n)\nprint(f\"Task started with ID: {task_handle.id()}\")\nprint(f\"Live view: {task_handle.live_url()}\")\n\nresult = task_handle.result()  # Blocks until task is done\n\nif result.status == 'done':\n    print(\"Task Output:\", result.output)\nelse:\n    print(\"Task Failed:\", result.output)\n```\n\n### Session Workflow\n\nFor multi-step workflows, create a session and run multiple actions:\n\n```python\nfrom smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\n\nwith client.session(url=\"https://example.com\") as session:\n    # Run a task within the session\n    result = session.run_task(\"Search for flights from NYC to LA\")\n    print(f\"Task output: {result.output}\")\n    \n    # Extract structured data\n    flights = session.extract(\n        schema={\"type\": \"array\", \"items\": {\"type\": \"object\", \"properties\": {\"price\": {\"type\": \"number\"}}}},\n        prompt=\"Extract the first 3 flight prices\"\n    )\n    print(f\"Flights: {flights.output}\")\n    \n    # Navigate to a URL\n    session.goto(\"https://example.com/checkout\")\n    \n    # Execute JavaScript\n    title = session.evaluate_js(\"document.title\")\n    print(f\"Page title: {title.output}\")\n```\n\n### Asynchronous Client\n\nFor async applications:\n\n```python\nimport asyncio\nfrom smooth import SmoothAsyncClient\n\nasync def main():\n    async with SmoothAsyncClient(api_key=\"YOUR_API_KEY\") as client:\n        task_handle = await client.run(\n            task=\"Go to Github and search for 'smooth-sdk'\"\n        )\n        print(f\"Task started with ID: {task_handle.id()}\")\n        \n        result = await task_handle.result()\n        print(\"Task Output:\", result.output)\n\nasyncio.run(main())\n```"
  },
  "security": [
    {
      "APIKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "Task",
      "description": "Operations for running and managing browser automation tasks"
    },
    {
      "name": "Event",
      "description": "Operations for sending events to running tasks (session actions, custom tool responses)"
    },
    {
      "name": "Profile",
      "description": "Operations for managing browser profiles (persistent cookies and authentication)"
    },
    {
      "name": "File",
      "description": "Operations for uploading and managing files"
    },
    {
      "name": "Extension",
      "description": "Operations for managing browser extensions"
    }
  ],
  "paths": {
    "/task": {
      "post": {
        "summary": "Submit Task",
        "description": "Submits a task to be executed by the Smooth agent. If `task` is `null`, opens a browser session that waits for actions via the Event endpoint.",
        "tags": [
          "Task"
        ],
        "operationId": "submit_task",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskRequest"
              },
              "examples": {
                "simple_task": {
                  "summary": "Simple task",
                  "value": {
                    "task": "Go to hacker news and get the top 5 stories.",
                    "device": "desktop",
                    "max_steps": 32
                  }
                },
                "session_mode": {
                  "summary": "Open session (task=null)",
                  "description": "Opens a browser session that waits for actions via the Event endpoint",
                  "value": {
                    "task": null,
                    "url": "https://example.com",
                    "device": "desktop"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Task successfully submitted. The initial response will have a status of 'waiting'.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_TaskResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid Request"
          },
          "403": {
            "description": "Access to a premium feature was requested, but it is not available on the current plan."
          },
          "422": {
            "description": "Validation Error"
          },
          "429": {
            "description": "API credits exhausted or concurrent session limit reached."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST \"https://api.smooth.sh/api/v1/task\" \\\n     -H \"Content-Type: application/json\" \\\n     -H \"apikey: YOUR_API_KEY\" \\\n     -d '{\n       \"task\": \"Go to hacker news and get the top 5 stories.\",\n       \"device\": \"desktop\",\n       \"max_steps\": 32,\n       \"enable_recording\": true\n     }'"
          },
          {
            "lang": "python",
            "label": "Python (sync)",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\n\ntask_handle = client.run(\n    task=\"Go to hacker news and get the top 5 stories.\",\n    device=\"desktop\",\n    max_steps=32\n)\n\nprint(f\"Task ID: {task_handle.id()}\")\nprint(f\"Live URL: {task_handle.live_url()}\")\n\n# Wait for the result\nresult = task_handle.result()\nprint(f\"Output: {result.output}\")"
          },
          {
            "lang": "python",
            "label": "Python (async)",
            "source": "import asyncio\nfrom smooth import SmoothAsyncClient\n\nasync def run_task():\n    async with SmoothAsyncClient(api_key=\"YOUR_API_KEY\") as client:\n        task_handle = await client.run(\n            task=\"Go to hacker news and get the top 5 stories.\",\n            device=\"desktop\",\n            max_steps=32\n        )\n        print(f\"Task ID: {task_handle.id()}\")\n        \n        result = await task_handle.result()\n        print(f\"Output: {result.output}\")\n\nasyncio.run(run_task())"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const apiKey = 'YOUR_API_KEY';\nconst url = 'https://api.smooth.sh/api/v1/task';\n\nconst payload = {\n  task: 'Go to hacker news and get the top 5 stories.',\n  device: 'desktop',\n  max_steps: 32,\n  enable_recording: true\n};\n\nasync function runTask() {\n  const response = await fetch(url, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'apikey': apiKey\n    },\n    body: JSON.stringify(payload)\n  });\n\n  const data = await response.json();\n  console.log('Task ID:', data.r.id);\n  // Poll GET /task/{id} for results\n}\n\nrunTask();"
          }
        ]
      },
      "get": {
        "summary": "List Tasks",
        "description": "List all tasks for the authenticated user.",
        "tags": [
          "Task"
        ],
        "operationId": "list_tasks",
        "parameters": [
          {
            "name": "t",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Timestamp to paginate from (returns tasks created before this timestamp)"
            }
          },
          {
            "name": "l",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 128,
              "default": 32,
              "description": "Limit number of results"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of tasks",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_TaskList"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET \"https://api.smooth.sh/api/v1/task?l=10\" \\\n     -H \"apikey: YOUR_API_KEY\""
          }
        ]
      }
    },
    "/task/{task_id}": {
      "get": {
        "summary": "Get Task",
        "description": "Returns the status and result of a task by its ID. Use `event_t` parameter for polling to receive only new events since the given timestamp.",
        "tags": [
          "Task"
        ],
        "operationId": "get_task",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Task Id"
            }
          },
          {
            "name": "event_t",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "description": "Timestamp of last event received. Only events after this timestamp will be returned."
            }
          },
          {
            "name": "downloads",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "description": "Whether to include the download URL for files downloaded during the task."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task has completed (status is 'done', 'failed', or 'cancelled').",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_TaskResponse"
                }
              }
            }
          },
          "202": {
            "description": "Task is still running (status is 'waiting' or 'running').",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_TaskResponse"
                }
              }
            }
          },
          "404": {
            "description": "Task not found"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET \"https://api.smooth.sh/api/v1/task/YOUR_TASK_ID\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "curl",
            "label": "cURL (polling with event_t)",
            "source": "# Poll for new events since timestamp 1699999999999\ncurl -X GET \"https://api.smooth.sh/api/v1/task/YOUR_TASK_ID?event_t=1699999999999\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "# The SDK handles polling automatically via task_handle.result()\nfrom smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\ntask_handle = client.run(task=\"Go to google.com\")\n\n# This polls internally until the task completes\nresult = task_handle.result()\nprint(f\"Status: {result.status}\")\nprint(f\"Output: {result.output}\")"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const apiKey = 'YOUR_API_KEY';\nconst taskId = 'YOUR_TASK_ID';\n\nasync function pollTask() {\n  let eventT = 0;\n  \n  while (true) {\n    const response = await fetch(\n      `https://api.smooth.sh/api/v1/task/${taskId}?event_t=${eventT}`,\n      { headers: { 'apikey': apiKey } }\n    );\n    \n    const data = await response.json();\n    const task = data.r;\n    \n    if (task.status === 'done' || task.status === 'failed') {\n      console.log('Final output:', task.output);\n      break;\n    }\n    \n    // Update eventT for next poll\n    if (task.events && task.events.length > 0) {\n      eventT = task.events[task.events.length - 1].timestamp;\n    }\n    \n    await new Promise(r => setTimeout(r, 1000));\n  }\n}\n\npollTask();"
          }
        ]
      },
      "delete": {
        "summary": "Cancel Task",
        "description": "Cancel a running task by its ID.",
        "tags": [
          "Task"
        ],
        "operationId": "cancel_task",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Task Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task successfully cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_Bool"
                }
              }
            }
          },
          "404": {
            "description": "Task not found or already completed."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.smooth.sh/api/v1/task/YOUR_TASK_ID\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "# For sessions, use session.close()\nwith client.session() as session:\n    session.run_task(\"Do something\")\n    session.close()  # Closes the session"
          }
        ]
      }
    },
    "/task/{task_id}/event": {
      "post": {
        "summary": "Send Event",
        "description": "Send an event to a running task. This is used for:\n\n- **Session actions**: `run_task`, `goto`, `extract`, `evaluate_js`, `close`\n- **Custom tool responses**: Responding to tool calls from the agent\n\nThe SDK handles this automatically when using `session.run_task()`, `session.goto()`, etc.",
        "tags": [
          "Event"
        ],
        "operationId": "send_task_event",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Task Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskEvent"
              },
              "examples": {
                "run_task": {
                  "summary": "Run task in session",
                  "value": {
                    "name": "session_action",
                    "payload": {
                      "name": "run_task",
                      "input": {
                        "task": "Search for flights from NYC to LA",
                        "max_steps": 32
                      }
                    },
                    "id": "evt_abc123"
                  }
                },
                "goto": {
                  "summary": "Navigate to URL",
                  "value": {
                    "name": "browser_action",
                    "payload": {
                      "name": "goto",
                      "input": {
                        "url": "https://example.com"
                      }
                    },
                    "id": "evt_def456"
                  }
                },
                "extract": {
                  "summary": "Extract data",
                  "value": {
                    "name": "browser_action",
                    "payload": {
                      "name": "extract",
                      "input": {
                        "schema": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "title": {"type": "string"},
                              "price": {"type": "number"}
                            }
                          }
                        },
                        "prompt": "Extract the first 5 products"
                      }
                    },
                    "id": "evt_ghi789"
                  }
                },
                "evaluate_js": {
                  "summary": "Execute JavaScript",
                  "value": {
                    "name": "browser_action",
                    "payload": {
                      "name": "evaluate_js",
                      "input": {
                        "js": "document.title"
                      }
                    },
                    "id": "evt_jkl012"
                  }
                },
                "close": {
                  "summary": "Close session",
                  "value": {
                    "name": "session_action",
                    "payload": {
                      "name": "close"
                    },
                    "id": "evt_mno345"
                  }
                },
                "tool_response": {
                  "summary": "Custom tool response",
                  "description": "Response to a tool call from the agent",
                  "value": {
                    "name": "tool_call",
                    "payload": {
                      "code": 200,
                      "output": {"result": "Tool execution successful"}
                    },
                    "id": "evt_pqr678"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event successfully sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_TaskEventResponse"
                }
              }
            }
          },
          "400": {
            "description": "Session closed or invalid event."
          },
          "404": {
            "description": "Task not found."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL (run_task)",
            "source": "curl -X POST \"https://api.smooth.sh/api/v1/task/YOUR_TASK_ID/event\" \\\n     -H \"Content-Type: application/json\" \\\n     -H \"apikey: YOUR_API_KEY\" \\\n     -d '{\n       \"name\": \"session_action\",\n       \"payload\": {\n         \"name\": \"run_task\",\n         \"input\": {\n           \"task\": \"Search for flights from NYC to LA\",\n           \"max_steps\": 32\n         }\n       },\n       \"id\": \"evt_abc123\"\n     }'"
          },
          {
            "lang": "curl",
            "label": "cURL (extract)",
            "source": "curl -X POST \"https://api.smooth.sh/api/v1/task/YOUR_TASK_ID/event\" \\\n     -H \"Content-Type: application/json\" \\\n     -H \"apikey: YOUR_API_KEY\" \\\n     -d '{\n       \"name\": \"browser_action\",\n       \"payload\": {\n         \"name\": \"extract\",\n         \"input\": {\n           \"schema\": {\"type\": \"object\", \"properties\": {\"title\": {\"type\": \"string\"}}},\n           \"prompt\": \"Extract the page title\"\n         }\n       },\n       \"id\": \"evt_def456\"\n     }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "# The SDK handles events automatically\nfrom smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\n\nwith client.session(url=\"https://example.com\") as session:\n    # These methods send events internally\n    result = session.run_task(\"Click the login button\")\n    data = session.extract(\n        schema={\"type\": \"object\", \"properties\": {\"title\": {\"type\": \"string\"}}},\n        prompt=\"Extract the page title\"\n    )\n    session.goto(\"https://example.com/dashboard\")\n    js_result = session.evaluate_js(\"document.title\")"
          }
        ]
      }
    },
    "/profile": {
      "post": {
        "summary": "Create Profile",
        "description": "Creates a new browser profile. Profiles persist cookies and authentication across tasks.",
        "tags": [
          "Profile"
        ],
        "operationId": "create_profile",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Profile successfully created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_ProfileResponse"
                }
              }
            }
          },
          "403": {
            "description": "Access to premium features is not available on the free plan."
          },
          "409": {
            "description": "Profile with this ID already exists."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST \"https://api.smooth.sh/api/v1/profile\" \\\n     -H \"Content-Type: application/json\" \\\n     -H \"apikey: YOUR_API_KEY\" \\\n     -d '{\"id\": \"my-profile\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\nprofile = client.create_profile(profile_id=\"my-profile\")\nprint(f\"Profile ID: {profile.id}\")"
          }
        ]
      },
      "get": {
        "summary": "List Profiles",
        "description": "List all browser profiles for the user.",
        "tags": [
          "Profile"
        ],
        "operationId": "list_profiles",
        "responses": {
          "200": {
            "description": "List of profiles",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_ProfileList"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET \"https://api.smooth.sh/api/v1/profile\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\nprofiles = client.list_profiles()\nfor profile in profiles:\n    print(f\"Profile ID: {profile.id}\")"
          }
        ]
      }
    },
    "/profile/{profile_id}": {
      "delete": {
        "summary": "Delete Profile",
        "description": "Delete a browser profile by its ID.",
        "tags": [
          "Profile"
        ],
        "operationId": "delete_profile",
        "parameters": [
          {
            "name": "profile_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profile successfully deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_Bool"
                }
              }
            }
          },
          "404": {
            "description": "Profile not found."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.smooth.sh/api/v1/profile/my-profile\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\nclient.delete_profile(\"my-profile\")"
          }
        ]
      }
    },
    "/file": {
      "post": {
        "summary": "Upload File",
        "description": "Upload a file to be used by tasks. Files can be passed to tasks via the `files` parameter.",
        "tags": [
          "File"
        ],
        "operationId": "upload_file",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file to upload."
                  },
                  "file_purpose": {
                    "type": "string",
                    "description": "Optional description of the file's purpose (max 64 characters)."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "File successfully uploaded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_UploadFileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file or filename."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST \"https://api.smooth.sh/api/v1/file\" \\\n     -H \"apikey: YOUR_API_KEY\" \\\n     -F \"file=@/path/to/your/file.pdf\" \\\n     -F \"file_purpose=invoice document\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\n\nwith open(\"/path/to/your/file.pdf\", \"rb\") as f:\n    response = client.upload_file(f, purpose=\"invoice document\")\n    print(f\"File ID: {response.id}\")\n\n# Use the file in a task\ntask = client.run(\n    task=\"Process this invoice\",\n    files=[response.id]\n)"
          }
        ]
      }
    },
    "/file/{file_id}": {
      "delete": {
        "summary": "Delete File",
        "description": "Delete an uploaded file by its ID.",
        "tags": [
          "File"
        ],
        "operationId": "delete_file",
        "parameters": [
          {
            "name": "file_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File successfully deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_Bool"
                }
              }
            }
          },
          "404": {
            "description": "File not found."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.smooth.sh/api/v1/file/YOUR_FILE_ID\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\nclient.delete_file(file_id=\"YOUR_FILE_ID\")"
          }
        ]
      }
    },
    "/extension": {
      "post": {
        "summary": "Upload Extension",
        "description": "Upload a browser extension (.zip file) to be used in tasks.",
        "tags": [
          "Extension"
        ],
        "operationId": "upload_extension",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The zipped extension file (.zip format)."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extension successfully uploaded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_UploadExtensionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid file format. Only ZIP files are allowed."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST \"https://api.smooth.sh/api/v1/extension\" \\\n     -H \"apikey: YOUR_API_KEY\" \\\n     -F \"file=@/path/to/extension.zip\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\n\nwith open(\"/path/to/extension.zip\", \"rb\") as f:\n    response = client.upload_extension(f)\n    print(f\"Extension ID: {response.id}\")\n\n# Use the extension in a task\ntask = client.run(\n    task=\"Do something\",\n    extensions=[response.id]\n)"
          }
        ]
      },
      "get": {
        "summary": "List Extensions",
        "description": "List all uploaded browser extensions.",
        "tags": [
          "Extension"
        ],
        "operationId": "list_extensions",
        "responses": {
          "200": {
            "description": "List of extensions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_ExtensionList"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET \"https://api.smooth.sh/api/v1/extension\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\nextensions = client.list_extensions()\nfor ext in extensions:\n    print(f\"ID: {ext.id}, Name: {ext.file_name}\")"
          }
        ]
      }
    },
    "/browser/extension/{extension_id}": {
      "delete": {
        "summary": "Delete Extension",
        "description": "Delete an uploaded browser extension by its ID.",
        "tags": [
          "Extension"
        ],
        "operationId": "delete_extension",
        "parameters": [
          {
            "name": "extension_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Extension successfully deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_Bool"
                }
              }
            }
          },
          "404": {
            "description": "Extension not found."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.smooth.sh/api/v1/browser/extension/YOUR_EXTENSION_ID\" \\\n     -H \"apikey: YOUR_API_KEY\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\nclient.delete_extension(extension_id=\"YOUR_EXTENSION_ID\")"
          }
        ]
      }
    },
    "/browser/session": {
      "post": {
        "summary": "Open Browser Session (Deprecated)",
        "description": "**Deprecated**: Use `POST /task` with `task=null` instead, and send actions via `POST /task/{task_id}/event`.\n\nOpens an interactive browser instance for 5 minutes.",
        "tags": [
          "Profile"
        ],
        "operationId": "open_browser_session",
        "deprecated": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrowserSessionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session opened.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse_BrowserSessionResponse"
                }
              }
            }
          },
          "403": {
            "description": "Access to premium features is not available on the free plan."
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python (Recommended)",
            "source": "# Use the new session() method instead\nfrom smooth import SmoothClient\n\nclient = SmoothClient(api_key=\"YOUR_API_KEY\")\n\nwith client.session(url=\"https://example.com\") as session:\n    session.run_task(\"Click the login button\")\n    session.close()"
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ApiResponse_TaskResponse": {
        "type": "object",
        "properties": {
          "r": {
            "$ref": "#/components/schemas/TaskResponse"
          }
        },
        "required": ["r"]
      },
      "ApiResponse_TaskList": {
        "type": "object",
        "properties": {
          "r": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaskResponse"
            }
          }
        },
        "required": ["r"]
      },
      "ApiResponse_TaskEventResponse": {
        "type": "object",
        "properties": {
          "r": {
            "$ref": "#/components/schemas/TaskEventResponse"
          }
        },
        "required": ["r"]
      },
      "ApiResponse_ProfileResponse": {
        "type": "object",
        "properties": {
          "r": {
            "$ref": "#/components/schemas/ProfileResponse"
          }
        },
        "required": ["r"]
      },
      "ApiResponse_ProfileList": {
        "type": "object",
        "properties": {
          "r": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProfileResponse"
            }
          }
        },
        "required": ["r"]
      },
      "ApiResponse_UploadFileResponse": {
        "type": "object",
        "properties": {
          "r": {
            "$ref": "#/components/schemas/UploadFileResponse"
          }
        },
        "required": ["r"]
      },
      "ApiResponse_UploadExtensionResponse": {
        "type": "object",
        "properties": {
          "r": {
            "$ref": "#/components/schemas/UploadExtensionResponse"
          }
        },
        "required": ["r"]
      },
      "ApiResponse_ExtensionList": {
        "type": "object",
        "properties": {
          "r": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Extension"
            }
          }
        },
        "required": ["r"]
      },
      "ApiResponse_BrowserSessionResponse": {
        "type": "object",
        "properties": {
          "r": {
            "$ref": "#/components/schemas/BrowserSessionResponse"
          }
        },
        "required": ["r"]
      },
      "ApiResponse_Bool": {
        "type": "object",
        "properties": {
          "r": {
            "type": "boolean"
          }
        },
        "required": ["r"]
      },
      "TaskRequest": {
        "type": "object",
        "properties": {
          "task": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "The task to run. If `null`, opens a browser session that waits for actions via the Event endpoint.",
            "title": "Task"
          },
          "response_model": {
            "anyOf": [
              {"type": "object"},
              {"type": "null"}
            ],
            "description": "JSON schema describing the desired output structure. If provided, the agent will return structured data matching this schema.",
            "title": "Response Model"
          },
          "url": {
            "anyOf": [
              {"type": "string", "format": "uri"},
              {"type": "null"}
            ],
            "description": "The starting URL for the task. If not provided, the agent will infer it from the task.",
            "title": "URL"
          },
          "metadata": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {"type": "string"},
                    {"type": "number"},
                    {"type": "boolean"}
                  ]
                }
              },
              {"type": "null"}
            ],
            "description": "Variables or parameters passed to the agent. Max 16 keys, max 2048 chars per value.",
            "title": "Metadata"
          },
          "files": {
            "anyOf": [
              {
                "type": "array",
                "items": {"type": "string"}
              },
              {"type": "null"}
            ],
            "description": "List of file IDs (from Upload File endpoint) to pass to the agent.",
            "title": "Files"
          },
          "agent": {
            "type": "string",
            "enum": ["smooth", "smooth-lite"],
            "description": "The agent to use for the task.",
            "default": "smooth",
            "title": "Agent"
          },
          "max_steps": {
            "type": "integer",
            "minimum": 2,
            "maximum": 128,
            "description": "Maximum number of steps the agent can take.",
            "default": 32,
            "title": "Max Steps"
          },
          "device": {
            "type": "string",
            "enum": ["desktop", "mobile", "desktop-lg"],
            "description": "Device type for the task.",
            "default": "desktop",
            "title": "Device"
          },
          "allowed_urls": {
            "anyOf": [
              {
                "type": "array",
                "items": {"type": "string"}
              },
              {"type": "null"}
            ],
            "description": "List of allowed URL patterns using glob syntax on the domain and path. If not provided, all URLs are allowed. To match everything on example.com, use `https://**.example.com/**`.",
            "title": "Allowed URLs"
          },
          "enable_recording": {
            "type": "boolean",
            "description": "Enable video recording of the task execution.",
            "default": true,
            "title": "Enable Recording"
          },
          "profile_id": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Browser profile ID to use. Each profile maintains its own cookies and login credentials.",
            "title": "Profile ID"
          },
          "profile_read_only": {
            "type": "boolean",
            "description": "If true, changes made during the task will not be saved to the profile.",
            "default": false,
            "title": "Profile Read Only"
          },
          "stealth_mode": {
            "type": "boolean",
            "description": "Run the browser in stealth mode to avoid detection.",
            "default": false,
            "title": "Stealth Mode"
          },
          "proxy_server": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Proxy server URL (e.g., `http://proxy.example.com:8080` or `socks5://proxy.example.com:1080`). Use `self` to route through your own IP.",
            "title": "Proxy Server"
          },
          "proxy_username": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Proxy server username for authentication.",
            "title": "Proxy Username"
          },
          "proxy_password": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Proxy server password for authentication.",
            "title": "Proxy Password"
          },
          "certificates": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Certificate"
                }
              },
              {"type": "null"}
            ],
            "description": "List of client certificates for accessing secure websites.",
            "title": "Certificates"
          },
          "use_adblock": {
            "anyOf": [
              {"type": "boolean"},
              {"type": "null"}
            ],
            "description": "Enable ad-blocking in the browser.",
            "default": true,
            "title": "Use Adblock"
          },
          "additional_tools": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {"type": "object"},
                    {"type": "null"}
                  ]
                }
              },
              {"type": "null"}
            ],
            "description": "Additional built-in tools to enable. Supported: `screenshot`, `hover`, `print_page`. Use `null` for default config.",
            "title": "Additional Tools"
          },
          "custom_tools": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ToolSignature"
                }
              },
              {"type": "null"}
            ],
            "description": "Custom tool definitions that the agent can call during execution.",
            "title": "Custom Tools"
          },
          "experimental_features": {
            "anyOf": [
              {"type": "object"},
              {"type": "null"}
            ],
            "description": "Experimental features to enable.",
            "title": "Experimental Features"
          },
          "extensions": {
            "anyOf": [
              {
                "type": "array",
                "items": {"type": "string"}
              },
              {"type": "null"}
            ],
            "description": "List of extension IDs (from Upload Extension endpoint) to load in the browser.",
            "title": "Extensions"
          },
          "show_cursor": {
            "type": "boolean",
            "description": "Show mouse cursor in the browser.",
            "default": false,
            "title": "Show Cursor"
          }
        },
        "title": "TaskRequest",
        "description": "Request model for submitting a task."
      },
      "TaskResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The unique ID of the task.",
            "title": "ID"
          },
          "status": {
            "type": "string",
            "enum": ["waiting", "running", "done", "failed", "cancelled"],
            "description": "The current status of the task.",
            "title": "Status"
          },
          "output": {
            "anyOf": [{}, {"type": "null"}],
            "description": "The output of the task. If `response_model` was provided, this matches the specified schema.",
            "title": "Output"
          },
          "credits_used": {
            "anyOf": [
              {"type": "integer"},
              {"type": "null"}
            ],
            "description": "Number of credits used. 1 credit = $0.01.",
            "title": "Credits Used"
          },
          "device": {
            "anyOf": [
              {
                "type": "string",
                "enum": ["desktop", "mobile", "desktop-lg"]
              },
              {"type": "null"}
            ],
            "description": "The device type used for the task.",
            "title": "Device"
          },
          "live_url": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "URL to view the task execution in real-time.",
            "title": "Live URL"
          },
          "recording_url": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "URL to download the video recording (available after task completes).",
            "title": "Recording URL"
          },
          "downloads_url": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "URL to download files created during the task.",
            "title": "Downloads URL"
          },
          "created_at": {
            "anyOf": [
              {"type": "integer"},
              {"type": "null"}
            ],
            "description": "Unix timestamp when the task was created.",
            "title": "Created At"
          },
          "events": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TaskEvent"
                }
              },
              {"type": "null"}
            ],
            "description": "List of new events fired since last poll (when using `event_t` parameter).",
            "title": "Events"
          }
        },
        "required": ["id", "status"],
        "title": "TaskResponse",
        "description": "Response model for task operations."
      },
      "TaskEvent": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Event type: `browser_action`, `session_action`, or `tool_call`.",
            "title": "Name"
          },
          "payload": {
            "type": "object",
            "description": "Event payload. For actions: `{name, input}`. For tool responses: `{code, output}`.",
            "title": "Payload"
          },
          "id": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Unique event ID. Used to match responses to requests.",
            "title": "ID"
          },
          "timestamp": {
            "anyOf": [
              {"type": "integer"},
              {"type": "null"}
            ],
            "description": "Unix timestamp of the event.",
            "title": "Timestamp"
          }
        },
        "required": ["name", "payload"],
        "title": "TaskEvent",
        "description": "Event model for sending actions to running tasks."
      },
      "TaskEventResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the created event.",
            "title": "ID"
          }
        },
        "required": ["id"],
        "title": "TaskEventResponse",
        "description": "Response model for send event operation."
      },
      "ToolSignature": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "The name of the tool.",
            "title": "Name"
          },
          "description": {
            "type": "string",
            "description": "A description of what the tool does and when to use it.",
            "title": "Description"
          },
          "inputs": {
            "type": "object",
            "description": "JSON schema describing the tool's input parameters.",
            "title": "Inputs"
          },
          "output": {
            "type": "string",
            "description": "Description of the tool's output type.",
            "title": "Output"
          }
        },
        "required": ["name", "description", "inputs", "output"],
        "title": "ToolSignature",
        "description": "Custom tool definition."
      },
      "Certificate": {
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "description": "Base64-encoded p12 certificate file.",
            "title": "File"
          },
          "password": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Password for the certificate file.",
            "title": "Password"
          }
        },
        "required": ["file"],
        "title": "Certificate",
        "description": "Client certificate for secure websites."
      },
      "ProfileRequest": {
        "type": "object",
        "properties": {
          "id": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Optional custom ID for the profile. If not provided, a random ID will be generated.",
            "title": "ID"
          }
        },
        "title": "ProfileRequest",
        "description": "Request model for creating a browser profile."
      },
      "ProfileResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the browser profile.",
            "title": "ID"
          }
        },
        "required": ["id"],
        "title": "ProfileResponse",
        "description": "Response model for profile operations."
      },
      "UploadFileResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID assigned to the uploaded file.",
            "title": "ID"
          }
        },
        "required": ["id"],
        "title": "UploadFileResponse",
        "description": "Response model for file upload."
      },
      "UploadExtensionResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID assigned to the uploaded extension.",
            "title": "ID"
          }
        },
        "required": ["id"],
        "title": "UploadExtensionResponse",
        "description": "Response model for extension upload."
      },
      "Extension": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The unique identifier for the extension.",
            "title": "ID"
          },
          "file_name": {
            "type": "string",
            "description": "The original filename of the extension.",
            "title": "File Name"
          },
          "creation_time": {
            "type": "integer",
            "description": "Unix timestamp when the extension was uploaded.",
            "title": "Creation Time"
          }
        },
        "required": ["id", "file_name", "creation_time"],
        "title": "Extension",
        "description": "Browser extension model."
      },
      "BrowserSessionRequest": {
        "type": "object",
        "properties": {
          "profile_id": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "The profile ID to use. If not provided, a new profile will be created.",
            "title": "Profile ID"
          },
          "live_view": {
            "type": "boolean",
            "description": "Request a live URL to interact with the browser.",
            "default": true,
            "title": "Live View"
          },
          "device": {
            "anyOf": [
              {
                "type": "string",
                "enum": ["desktop", "mobile"]
              },
              {"type": "null"}
            ],
            "description": "Device type for the browser session.",
            "default": "desktop",
            "title": "Device"
          },
          "url": {
            "anyOf": [
              {"type": "string", "format": "uri"},
              {"type": "null"}
            ],
            "description": "Starting URL to open.",
            "title": "URL"
          },
          "proxy_server": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Proxy server address.",
            "title": "Proxy Server"
          },
          "proxy_username": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Proxy server username.",
            "title": "Proxy Username"
          },
          "proxy_password": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "Proxy server password.",
            "title": "Proxy Password"
          },
          "extensions": {
            "anyOf": [
              {
                "type": "array",
                "items": {"type": "string"}
              },
              {"type": "null"}
            ],
            "description": "List of extension IDs to load.",
            "title": "Extensions"
          }
        },
        "title": "BrowserSessionRequest",
        "description": "Request model for opening a browser session (deprecated)."
      },
      "BrowserSessionResponse": {
        "type": "object",
        "properties": {
          "profile_id": {
            "type": "string",
            "description": "The ID of the browser profile.",
            "title": "Profile ID"
          },
          "live_id": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "The ID of the live browser session.",
            "title": "Live ID"
          },
          "live_url": {
            "anyOf": [
              {"type": "string"},
              {"type": "null"}
            ],
            "description": "URL to interact with the browser session.",
            "title": "Live URL"
          }
        },
        "required": ["profile_id"],
        "title": "BrowserSessionResponse",
        "description": "Response model for browser session (deprecated)."
      }
    },
    "securitySchemes": {
      "APIKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "apikey"
      }
    }
  }
}
