Access Broward VAB Petitioner Petition Details and Evidence

Site bcvab.broward.orgTask access-petitioner-petition-detailsVersion v2Updated Aug 4, 2026Category browser-automation

Log into the Broward County VAB petitioner portal, open one or more petition detail records, and collect or download categorized evidence attachments. This skill was captured from a live agent session on bcvab.broward.org and publishes here verbatim, exactly as an agent receives it.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Purpose

Authenticate to the Broward County Value Adjustment Board petitioner portal and retrieve petition detail records. For a requested range of numeric petition IDs, collect available PAO Evidence, Petitioners Evidence, and Magistrates Worksheets attachments, optionally downloading each attachment with a descriptive filename.

When to Use

Use when the caller provides a petitioner transaction number, petitioner password, and either one target PetitionId or a numeric petition-ID range. The portal session must be authenticated before opening detail pages or their attachment handlers.

Workflow

  1. Navigate to https://bcvab.broward.org/AxiaWeb2025.
  2. Fill input#cphMain_txtTransactionID with {transaction-number} and input#cphMain_txtPetitionerPassword with {petitioner-password}.
  3. Submit using input#cphMain_btnPetitionerSubmit and wait for navigation.
  4. For a single record, navigate directly to https://bcvab.broward.org/AxiaWeb2025/Users/Petitioner/Details.aspx?PetitionId={petition-id}. For a range, substitute each ID from {start-petition-id} through {end-petition-id} and process each page without returning to the transaction list.
  5. On every loaded detail page, run this single evaluate() extractor. It preserves normalized page text and tables and identifies every matching attachment by its visible row context. It also prepares and clicks same-origin BinaryHandler.aspx links to initiate downloads; missing categories simply produce an empty array.
(() => {
  const clean = (value) =>
    (value || "")
      .replace(/\u00a0/g, " ")
      .replace(/[ \t]+/g, " ")
      .replace(/\s*\n\s*\n+/g, "\n")
      .trim();
  const root = document.querySelector("#cphMain") || document.body;
  const tables = [...root.querySelectorAll("table")].map((table) =>
    [...table.querySelectorAll("tr")]
      .map((row) =>
        [...row.querySelectorAll("th,td")].map((cell) => clean(cell.innerText)),
      )
      .filter((row) => row.length),
  );
  const wanted = [
    ["PAO Evidence", "PAO-Evidence"],
    ["Petitioners Evidence", "Petitioners-Evidence"],
    ["Magistrates Worksheet", "Magistrates-Worksheet"],
  ];
  const counters = Object.fromEntries(wanted.map(([, slug]) => [slug, 0]));
  const assets = [];
  for (const anchor of [...root.querySelectorAll("a[href*='BinaryHandler.aspx']")]) {
    const context = anchor.closest("tr") || anchor.parentElement || anchor;
    const rowText = clean(context.innerText);
    const match = wanted.find(([label]) => rowText.includes(label));
    if (!match) continue;
    const slug = match[1];
    const number = ++counters[slug];
    const petitionId =
      new URL(location.href).searchParams.get("PetitionId") || "unknown";
    const filename = `Petition-${petitionId}-${slug}-${number}`;
    const href = anchor.href;
    const downloadAnchor = anchor.cloneNode(true);
    downloadAnchor.removeAttribute("target");
    downloadAnchor.setAttribute("download", filename);
    downloadAnchor.style.display = "none";
    document.body.appendChild(downloadAnchor);
    downloadAnchor.click();
    assets.push({
      petitionId,
      category: slug,
      index: number,
      filename,
      href,
      rowText,
    });
  }
  return {
    url: location.href,
    title: clean(document.title),
    petitionId: new URL(location.href).searchParams.get("PetitionId"),
    text: clean(root.innerText),
    tables,
    assets,
  };
})();

Site-Specific Gotchas

  • This is an authenticated ASP.NET Web Forms application; preserve the session established by the login submission before opening detail URLs or attachment handlers.
  • The login controls use the exact selectors input#cphMain_txtTransactionID, input#cphMain_txtPetitionerPassword, and input#cphMain_btnPetitionerSubmit.
  • Petition detail pages are keyed by the numeric PetitionId; use the caller-provided ID or range and never infer or guess an opaque ID.
  • Attachment URLs use Users/Petitioner/BinaryHandler.aspx?s=..., where s is an opaque, signed/session-dependent token. Read the complete href from the matching attachment anchor on the currently loaded detail page; never construct or persist token values.
  • Categorization depends on the attachment anchor's containing table row or parent text. Keep the row-context matching because the attachment anchor itself may have no useful label.
  • The download attribute and synthetic anchor clicks initiate downloads without navigating away from the detail page. Browser download policies may still require allowing multiple downloads; the returned assets list is the authoritative inventory of links found and attempted.
  • Evidence categories are optional per petition. Do not treat an absent category as an error, and preserve the per-category sequence when naming files.
  • Keep credentials as runtime inputs; never store transaction numbers or passwords in the skill.

Expected Output

For each requested petition, return the authenticated detail URL, document title, petition ID, normalized page text and tables, plus an assets array containing each available PAO Evidence, Petitioners Evidence, or Magistrates Worksheet attachment with its category, sequence number, generated filename, same-origin handler URL, row text, and download attempt status implied by successful extraction.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=bcvab.broward.org&task=access-petitioner-petition-details