> ## Documentation Index
> Fetch the complete documentation index at: https://tbd-6fc993ce-hypeship-webmcp-control-telemetry.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Fill Browser Fields

> Map vault fields to browser inputs without returning their values to your application

invoke an item's `fill` operation to write selected values into an attached browser. your request contains field names and css selectors, not credential values. the result reports outcomes without returning the values.

<Warning>
  fill writes real values into the browser. page scripts, extensions, devtools, and an agent with unrestricted browser access may read them.
</Warning>

## Check availability

retrieve the item and require `fill` in `available_operations`. KERNEL rechecks eligibility when you invoke it.

| item         | requirements                                         |
| ------------ | ---------------------------------------------------- |
| `credential` | ready, with a stored value for every requested field |

attach the vault when creating the browser. the browser and vault must belong to the same project, and the attachment can't change later. attaching a vault grants access to all its items, including items added later; use separate vaults for tasks that must not share credentials.

## Map fields to inputs

the following examples continue with a `kernel` client, a per-user vault such as `user-12345`, and a browser attached to that vault. `loginURL` / `login_url` is the exact current url of a login page you control; the selectors match that page's inputs.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const item = await kernel.vaults.items.retrieve("portal-login", {
    id_or_name: vault.id,
  });
  if (!item.available_operations.some((operation) => operation.type === "fill")) {
    throw new Error("fill is unavailable");
  }
  const result = await kernel.vaults.items.performOperation(item.key, {
    id_or_name: vault.id,
    type: "fill",
    browser_id: browser.session_id,
    page_url: loginURL,
    fields: [
      { field: "username", selector: "#username" },
      { field: "password", selector: "#password" },
    ],
  });
  if (result.type !== "fill" || result.status !== "completed") {
    throw new Error("stop and reconcile the fill outcome before continuing");
  }
  ```

  ```python Python theme={null}
  item = kernel.vaults.items.retrieve("portal-login", id_or_name=vault.id)
  if not any(operation.type == "fill" for operation in item.available_operations):
      raise RuntimeError("fill is unavailable")
  result = kernel.vaults.items.perform_operation(
      item.key,
      id_or_name=vault.id,
      type="fill",
      browser_id=browser.session_id,
      page_url=login_url,
      fields=[
          {"field": "username", "selector": "#username"},
          {"field": "password", "selector": "#password"},
      ],
  )
  if result.type != "fill" or result.status != "completed":
      raise RuntimeError("stop and reconcile the fill outcome before continuing")
  ```
</CodeGroup>

`field` is a declared credential field name. a totp field writes a generated code, never its seed. `format` isn't accepted for credentials.

## Select the page and elements

`page_url` must exactly match one current top-level page, including path, query, and fragment. it isn't a navigation instruction or a prefix match. credentials can omit it only when the browser has exactly one open page.

credential items have no destination allowlist. your trusted controller must authorize the destination before disclosing credentials; neither `description` nor `page_url` grants or restricts that permission.

each selector must identify exactly one editable input or select across the main frame and all descendant frames. a selector may identify a container only if it resolves to one unique editable element inside it. zero matches, multiple matches, or two bindings targeting the same element fail validation. selects match option values, not labels.

KERNEL validates bindings before writing, then fills in request order. if navigation or a disappearing target interrupts filling, it stops instead of choosing a different page or element. `timeout_ms` is the total operation deadline, not a timeout per field; it defaults to 10,000 and accepts 1–30,000 milliseconds.

## Handle the outcome

| result          | next action                                                             |
| --------------- | ----------------------------------------------------------------------- |
| `completed`     | all fields were filled; inspect the page and decide whether to submit   |
| `failed`        | inspect the per-field outcomes; earlier writes aren't rolled back       |
| `unknown`       | stop and reconcile; at least one field's outcome can't be determined    |
| transport error | treat the outcome as uncertain because writes may already have happened |

known execution failures can return http `200` with a `failed` or `unknown` status. inspect the response body, not only the http status. each entry in `fields` identifies its request binding by zero-based `index` and reports `filled`, `failed`, `unknown`, or `not_attempted`. bindings after the first failed or unknown field are `not_attempted`.

fill doesn't click buttons or submit forms, but input/change handlers can trigger site behavior. `completed` doesn't mean login succeeded or a form was submitted.

**don't automatically retry fill after a failure or uncertain outcome.** a lost response can follow successful writes; another request can repeat events, overwrite edits, or generate a different totp code. deliberate recovery starts with inspecting the existing attempt, not replaying it.

for the full application and agent handoff, follow [use vault credentials in a browser agent](/browsers/use-vault-credentials-in-browser-agent).
