# Profiles

## List profiles

`GET /profiles`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "List profiles",
  "description": "Lists persistent profiles (temporary profiles are hidden), newest first, pinned on top. Each entry is enriched with live run state.",
  "responses": {
    "200": {
      "description": "Profile list.",
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProfileListItem"
            }
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    }
  }
}
```

## Create a profile

`POST /profiles`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Create a profile",
  "description": "Persists a profile from a client-supplied `fingerprint` **exactly as given** (no re-randomization; uniquification already happened in `/fingerprint/new`). Use `folder` to file it; bind a proxy by stored `proxy_id` or attach one inline via `proxy` (a string that is NOT saved to the proxy store).",
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreateProfileRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Created profile metadata.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ProfileMeta"
          }
        }
      }
    },
    "400": {
      "description": "Missing/!object `fingerprint`, or an unparseable proxy string.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    }
  }
}
```

## Create a temporary profile

`POST /profiles/temporary`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Create a temporary profile",
  "description": "Creates a profile from a random (or specified) library fingerprint, uniquified like `/fingerprint/new` and stored verbatim, flagged `temporary`: hidden from listings and **auto-deleted when its browser closes** (or purged on next app start after a crash). Pair with `POST /profiles/{id}/start`.",
  "requestBody": {
    "required": false,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TempProfileRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Created temporary profile.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "fingerprint_id": {
                "type": "string",
                "description": "The library entry the profile was generated from."
              },
              "temporary": {
                "type": "boolean",
                "example": true
              },
              "proxy_inline": {
                "type": "boolean",
                "description": "Whether an inline proxy string was attached."
              }
            }
          }
        }
      }
    },
    "400": {
      "description": "Unparseable proxy string, or an unknown noise vector.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "404": {
      "description": "No matching fingerprint / empty library.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
```

## Get a profile

`GET /profiles/{id}`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Get a profile",
  "description": "Returns the full stored profile: the `_meta` envelope plus the flattened FingerprintConfig. If the profile is running, `running` and `cdp` are added.",
  "parameters": [
    {
      "$ref": "#/components/parameters/ProfileId"
    }
  ],
  "responses": {
    "200": {
      "description": "The stored profile.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StoredProfile"
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "404": {
      "description": "No such profile.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
```

## Delete a profile

`DELETE /profiles/{id}`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Delete a profile",
  "description": "Moves the profile to Trash. It can be restored for 7 days. The archive includes cookies, logins, web data, preferences, Local Storage, and IndexedDB. Cache data is excluded. The original configuration and user data directory are deleted after the archive is created.\n\nTemporary profiles are deleted automatically when their browser closes and are not moved to Trash.",
  "parameters": [
    {
      "$ref": "#/components/parameters/ProfileId"
    }
  ],
  "responses": {
    "200": {
      "description": "Profile moved to Trash.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "deleted": {
                "type": "boolean",
                "example": true
              },
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "trashed": {
                "type": "boolean",
                "example": true,
                "description": "Can be restored from Trash for 7 days."
              }
            }
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "500": {
      "description": "Deletion failed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
```

## Edit a profile

`PATCH /profiles/{id}`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Edit a profile",
  "description": "Updates only the provided fields. When `fingerprint` is given it REPLACES the stored fingerprint verbatim (no re-randomization). `folder: \"\"` unfiles the profile; `proxy_id: \"\"` unbinds the proxy; a `proxy` string is stored (deduped) + full-tested, then bound. Returns the updated stored profile.",
  "parameters": [
    {
      "$ref": "#/components/parameters/ProfileId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/EditProfileRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Updated stored profile.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/StoredProfile"
          }
        }
      }
    },
    "400": {
      "description": "Bad fingerprint (not an object) or unparseable proxy.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "404": {
      "description": "No such profile.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
```

## Launch a profile (with CDP)

`POST /profiles/{id}/start`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Launch a profile (with CDP)",
  "description": "Spawns the ShardX browser for the profile with remote-debugging enabled, resolves any `auto` timezone/locale/geo from the bound proxy, and returns the CDP endpoint once Chrome has written its DevToolsActivePort. CDP is enabled **only** on API launches (UI launches stay debugging-free for anti-detect). The call waits up to 30 seconds for the endpoint; if it still has none, `cdp` is `null` and `cdp_error` says what happened and where to read the port yourself. Works for both regular and temporary profiles.",
  "parameters": [
    {
      "$ref": "#/components/parameters/ProfileId"
    }
  ],
  "requestBody": {
    "required": false,
    "description": "Optional. Empty body launches headed.",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "headless": {
              "type": "boolean",
              "default": false,
              "description": "Launch headless (--headless=new)."
            }
          }
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Launched.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "profile_id": {
                "type": "string"
              },
              "pid": {
                "type": "integer",
                "format": "int64",
                "description": "OS process id."
              },
              "headless": {
                "type": "boolean"
              },
              "cdp": {
                "nullable": true,
                "allOf": [
                  {
                    "$ref": "#/components/schemas/CdpInfo"
                  }
                ]
              },
              "cdp_error": {
                "type": "string",
                "nullable": true,
                "description": "Why `cdp` is null, when it is. Absent otherwise."
              }
            }
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "500": {
      "description": "Binary not configured / spawn failed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
```

## Stop a profile

`POST /profiles/{id}/stop`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Stop a profile",
  "description": "Sends the browser a graceful shutdown (SIGTERM on Unix; 5s grace then SIGKILL). Temporary profiles are deleted as part of close. `stopped` is `false` if the profile wasn't running.",
  "parameters": [
    {
      "$ref": "#/components/parameters/ProfileId"
    }
  ],
  "responses": {
    "200": {
      "description": "Stop requested.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "profile_id": {
                "type": "string"
              },
              "stopped": {
                "type": "boolean"
              }
            }
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    }
  }
}
```

## Export cookies

`GET /profiles/{id}/cookies`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Export cookies",
  "description": "Reads the profile's Chromium cookie store and returns all cookies **decrypted**. Works whether the profile is running or stopped. Empty array if the profile has never launched.",
  "parameters": [
    {
      "$ref": "#/components/parameters/ProfileId"
    }
  ],
  "responses": {
    "200": {
      "description": "Cookies.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "cookies": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Cookie"
                }
              }
            }
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "500": {
      "description": "Cookie DB read/decrypt failed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
```

## Import cookies

`POST /profiles/{id}/cookies`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "Import cookies",
  "description": "Writes cookies into the profile's cookie store (re-encrypting to Chromium's v10 scheme). The profile **must be stopped**; a running browser rewrites the store on exit and would clobber the import.",
  "parameters": [
    {
      "$ref": "#/components/parameters/ProfileId"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "required": [
            "cookies"
          ],
          "properties": {
            "cookies": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Cookie"
              }
            }
          }
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Imported.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "imported": {
                "type": "integer",
                "description": "Number of cookies written."
              }
            }
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    },
    "409": {
      "description": "Profile is running; stop it first.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "500": {
      "description": "Cookie DB write failed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
```

## List running profiles

`GET /running`

```json
{
  "tags": [
    "Profiles"
  ],
  "summary": "List running profiles",
  "description": "Profiles with a live browser process, including the CDP endpoint when launched via the API.",
  "responses": {
    "200": {
      "description": "Running profiles.",
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunningProfile"
            }
          }
        }
      }
    },
    "401": {
      "$ref": "#/components/responses/Unauthorized"
    }
  }
}
```
