Search Avis.com for long-term (15-330 day) rental car options at US locations. Returns per-class daily/total prices with pay-now vs pay-later, plus the cheapest deal across the fleet. Read-only; designed for looped multi-location scans to surface unusually cheap long-term deals.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionsearch-long-term-rentalsExecute the skills CLI command in your project's root directory to begin installation:
Fetches search-long-term-rentals from avis.com/longterm-a3k8ng and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate search-long-term-rentals. Access via /search-long-term-rentals in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
0
upvotes
Run in your terminal
0
installs
0
this week
—
stars
| name | search-long-term-rentals |
| title | Avis Long-Term Rental Search |
| description | >- Search Avis.com for long-term (15-330 day) rental car options at US locations. Returns per-class daily/total prices with pay-now vs pay-later, plus the cheapest deal across the fleet. Read-only; designed for looped multi-location scans to surface unusually cheap long-term deals. |
| website | avis.com |
| category | travel |
| tags | - car-rental - long-term-rental - avis - travel - price-comparison - perimeterx |
| source | 'browserbase: agent-runtime 2026-05-19' |
| updated | '2026-05-19' |
| recommended_method | browser |
| alternative_methods | - method: browser rationale: >- Avis has no documented public reservation API. The form has method=get but a React submit handler intercepts navigation, so there is no deep-link URL that bypasses the booking widget. Backend /api/* endpoints are gated by the same HUMAN/PerimeterX CAPTCHA that fires on the form's Show-Vehicles click — confirmed during iter-1. Browser-driving with --verified --proxies is the only available surface. |
| verified | true |
| proxies | true |
Given a US Avis pickup/dropoff location, a date range of 15–330 days, and a renter age, drive the Avis.com booking widget through to the vehicle-results screen and return one of these shapes per location:
success: false, reason: "human_press_and_hold" with the PerimeterX Reference ID.success: false, reason: "range_outside_15_to_330_days".success: true, vehicles: [], sold_out: true.Read-only. Stop at the vehicle-results / fleet-selection screen. Never click "Book Now", "Pay Now", "Continue to Extras", or any booking-completion button. Designed to be looped across many locations to surface unusually cheap long-term deals.
Avis renders the booking widget with React/Next.js, has no documented public API, and aggressively gates the search submission with the HUMAN (PerimeterX) "Press & Hold" CAPTCHA. Browser-driving is the only available surface; the GraphQL-looking endpoints under /api/ return CAPTCHA HTML to anonymous callers (confirmed). Plan for ~30–60% of submissions to land on the CAPTCHA wall even with --verified --proxies — the skill treats that as a real outcome shape, not a failure, and the caller loops with backoff + fresh sessions.
SID=$(browse cloud sessions create --keep-alive --verified --proxies \
| node -e "let s='';process.stdin.on('data',c=>s+=c).on('end',()=>process.stdout.write(JSON.parse(s).id))")
export BROWSE_SESSION="$SID"
A bare session (no --verified, no --proxies) always lands on Press & Hold immediately. --verified lowers the trigger rate; --proxies (residential) lowers it further. Neither solves the CAPTCHA once it has fired.
One session per location. Don't reuse a session for many locations sequentially — Avis fingerprints session-rate-of-search and starts blocking after ~3 searches even when the first ones succeeded. Create + release per location, randomize 8–30s of think-time between sessions, and rotate proxy IPs by recreating the session.
Either entry point renders the same booking widget — pick by what the agent needs:
| Entry URL | Submit button label | Notes |
|---|---|---|
https://www.avis.com/en/home | "Show Vehicles" | Marketing-led, fewer long-term cues in the page. |
https://www.avis.com/en/products-and-services/services/long-term-car-rental | "Show Vehicles" (DOM aria-label still says "Show cars" — the role string is stale; the visible text is "Show Vehicles") | "Avis Flex" landing — same widget, surfaces the $50/$600 long-term promo and the 15-day minimum / 330-day maximum constraints in copy. Prefer this URL so the page context matches the user intent. |
browse open "https://www.avis.com/en/products-and-services/services/long-term-car-rental" --remote
browse wait load --remote
browse wait timeout 2500 --remote # widget + modals render after 'load'
Two modals fire on first visit; both must be dismissed before the form is operable:
[X-Y] button: close ref; safer to dismiss with browse press Escape --remote (works in iter-1 and iter-2; close-button refs change every navigation, Escape doesn't).region: Cookie banner / dialog: Privacy) — does not respond to Escape. Click button: Agree (or button: Decline Optional if the caller prefers to refuse tracking; both unblock the form). Find the ref via the latest snapshot; do not cache it across navigations.After dismissal:
browse press Escape --remote # sign-in modal
browse wait timeout 800 --remote
# fresh snapshot, then click whichever cookie button by ref
browse snapshot --remote
browse click "[X-Y]" --remote # 'Agree' ref from snapshot
browse wait timeout 800 --remote
A third modal — the email-capture "UP TO 35% OFF / Activate Discount / Continue without discount" — sometimes pops on later navigations (we observed it after the first failed navigation in iter-1). Dismiss with browse press Escape --remote or by clicking the "Continue without discount" text link.
browse snapshot --remote # cache refs
# 'combobox: Enter pick-up location or delivery address' — get the [X-Y]
browse click "[X-Y]" --remote # focus the combobox
browse wait timeout 800 --remote
browse type "LAX" --remote # IATA or city
browse wait timeout 1800 --remote # autocomplete renders ~1.5s
browse press ArrowDown --remote # highlight first suggestion
browse wait timeout 300 --remote
browse press Enter --remote # commit
browse wait timeout 1200 --remote # combobox closes, label updates
Critical: use keyboard, not click. The autocomplete list virtualizes — its DOM refs change every keystroke and clicking the list item by ref fails ~50% of the time with "ref not found" or selects the wrong option. ArrowDown + Enter is the only stable commit path. The first non-header suggestion (under the "Airports" or "Cities" sub-heading) is the strongest match — when entering an IATA code like LAX, the airport result is always ranked first.
Confirm before proceeding. A fresh snapshot's combobox text should now read e.g. "Los Angeles Intl Airport (LAX)" — if it still says "Enter pick-up location or delivery address", the keyboard commit failed; retry from the click step.
After committing the pickup location, Avis auto-opens the date picker in the same gesture. Don't fight it — proceed to step 4.
The date picker is a controlled React widget — browse fill on the underlying textbox: Select dates does not work (the input is read-only and the widget's controlled state is the source of truth). Use the calendar buttons.
State after step 3 (combobox commit auto-opens the picker):
To set a range that spans more than 2 months, the rhythm is:
# (a) Get fresh snapshot for calendar refs; find the pickup date as a button
browse snapshot --remote
# 'button: Monday, June 1st, 2026' → [X-Y]
browse click "[X-Y]" --remote # clicking a single date sets BOTH pickup + dropoff to that date
# ("1 day selected" appears in the footer)
browse wait timeout 600 --remote
# (b) Advance the calendar to the dropoff month. The next-month chevron ref stays stable
# across re-renders (e.g. '[12-13987] button: Go to the Next Month').
for i in $(seq 1 6); do
browse click "[NEXT_REF]" --remote
browse wait timeout 250 --remote # short waits between clicks; <200ms drops events
done
# (c) Fresh snapshot, click the dropoff day cell
browse snapshot --remote
browse click "[X-Y_DEC_1]" --remote # 'button: Tuesday, December 1st, 2026'
browse wait timeout 800 --remote # picker closes, "Dec 01, 2026" appears in form
Picker constraints discovered:
Esc while the picker is open closes it without selection — use to bail.The pickup-time and dropoff-time controls are combobox: 12:00 PM next to each date field. To set non-noon times, use browse select on the combobox by ref (the options are 30-min increments from 12:00 AM to 11:30 PM). For long-term rentals the time-of-day rarely matters — leaving the 12:00 PM default is fine and avoids an extra click.
combobox: Driver's Age defaults to "Driver's Age: 25+". The other options are "21-24" (triggers an underage surcharge) and "25+". For renters ≥ 25 (the common case for long-term rentals), leave it untouched — there is no entry for specific ages like 30 or 35; Avis bands by the surcharge cutoff only. For 21-24, browse select the combobox to "21-24" before submitting.
browse snapshot --remote
# 'button: Show cars' (role label) — visible text reads "Show Vehicles"
browse click "[X-Y]" --remote
browse wait load --remote
browse wait timeout 5000 --remote # results page renders progressively
browse get url --remote
browse screenshot --remote --path debug.png
After the click, one of three things happens:
URL stays on the booking page. Page renders a centered modal "Before we continue… Press & Hold to confirm you are a human (and not a bot)." with a Reference ID like bd8c3b60-534c-11f1-9e66-3f681c98e7b3. The Press & Hold button lives in a nested cross-origin iframe (snapshot title: RootWebArea: Human verification challenge).
Cannot be solved with browse mouse drag or with synthetic events. Verified in iter-1: browse mouse drag <x> <y> <x> <y> returns success but does not satisfy the challenge. Verified in iter-1: a CDP-level Input.dispatchMouseEvent type=mousePressed → sleep 2800ms → type=mouseReleased at the button's viewport center returns success but does not satisfy the challenge either. The same Reference ID remains visible across multiple synthetic press attempts — HUMAN's risk score is gated on pointer-entropy + session-history signals that synthetic events do not produce.
Practical handling:
success: false, reason: "human_press_and_hold", reference_id: "..." and abandon this session.--verified --proxies) → retry. Empirically 40–70% of fresh sessions clear the wall and reach 7b.URL rewrites to https://www.avis.com/en/reservation/select-car?... (observed pattern; results render via Next.js after a brief spinner). Snapshot reveals a heading like "Available cars in Los Angeles" plus a stack of vehicle cards under role region: Vehicle list (exact role pending — confirm against a clean run). Each card carries:
StaticText nodes. The card carries two price columns — pay-later (default, larger) and pay-now (a smaller "Save X%" callout). For long rentals the daily price is a 7- or 30-day average; the total is what to compare across locations.link: View fee details opens a per-card breakdown modal. Do not click unless the caller specifically asks for the breakdown — each modal opens an XHR and adds ~3s to the per-card extraction.browse get text body returns the rendered text; parse by splitting on the vehicle-class header markers. Take the lowest total across all cards as the cheapest, and emit per-class totals for comparison.
Page renders "No vehicles available for your selected dates and location" header, no cards. Emit success: true, vehicles: [], sold_out: true. For 6–12 month windows this is uncommon at large airports but frequent at small-town locations.
browse cloud sessions update "$SID" --status REQUEST_RELEASE
Always release, even on failure paths. Leaking sessions burns Browserbase quota.
browse screenshot --path failures/<location>-<ts>.png + browse get html body > failures/<location>-<ts>.html per failure.--verified --proxies reduces trigger rate but does not eliminate it. Cannot be solved with synthetic CDP events (verified iter-1). Plan for ~30–60% trigger rate at steady state and treat it as a real outcome shape, not a failure to retry indefinitely.success: false, reason: "range_outside_15_to_330_days" for any rangeDays < 15 or > 330 without attempting a search./en/home and /en/products-and-services/services/long-term-car-rental is the same widget. Same DOM IDs (form#booking-widget-desktop-form), same fields, same submit handler. Prefer the long-term URL because the page copy frames the search for long-term context and the cheapest-deal narrative.button: Show cars (stale) but its visible text is "Show Vehicles". Match by role + position in the form, not by either label.browse press ArrowDown + browse press Enter is the only stable commit.browse fill does not work on the date input. textbox: Select dates is read-only — the widget owns the date state and fill is silently ignored. Always navigate via the calendar's day-cell buttons.[12-13987] survived 6 successive clicks in iter-1). The day-cell refs are not stable — re-snapshot after every advance.form action is a no-op. The form's HTML action attribute echoes the current page URL; submission is JS-only via the React handler. There is no GET-URL deep-link with pickup/dropoff as query params — verified by inspecting the form (form.method === "get" but the React component intercepts submit).https://www.avis.com/api/* is gated by the same HUMAN protection — direct POST returns CAPTCHA HTML. Don't waste turns probing for one.robots.txt permits the booking flow. User-agent: * Allow: / with Disallow: /web/* and a few content paths. The reservation funnel paths are not disallowed. Scraping for read-only price comparison is permitted; respect the rate caveats above.X-Amz-Cf-Id headers everywhere. Page HTML responses cap at >1MB and browse cloud fetch returns 502 The response body exceeded the maximum allowed size of 1MB. Use the browser session for any full-page navigation; fetch is fine for /robots.txt, /sitemap.xml, small JSON.--verified is the Browserbase "advanced stealth" flag in the unified browse CLI. Older docs reference --advanced-stealth. They mean the same thing.--verified. One session per location is the safe pattern.browse cloud fetch on Avis HTML is unreliable due to the 1MB cap — even for https://www.avis.com/en/home it returns 502. Only use it for known-small resources.Four distinct outcome shapes, all flagged with success + reason (or vehicles for the happy path).
{
"success": true,
"pickup_location": {"input": "LAX", "resolved": "Los Angeles Intl Airport (LAX)"},
"dropoff_location": {"input": "LAX", "resolved": "Los Angeles Intl Airport (LAX)"},
"pickup_at": "2026-06-01T12:00:00",
"return_at": "2026-12-01T12:00:00",
"rental_days": 183,
"renter_age_band": "25+",
"vehicles": [
{
"class": "ECONOMY",
"name": "Nissan Versa or Similar",
"daily_price": {"pay_later": 34.99, "pay_now": 31.49, "currency": "USD"},
"total_price": {"pay_later": 7459.21, "pay_now": 6713.29, "currency": "USD"},
"fees_taxes_included_in_total": true,
"fees_breakdown": null
},
{
"class": "INTERMEDIATE SUV",
"name": "Toyota RAV4 or Similar",
"daily_price": {"pay_later": 58.40, "pay_now": 52.56, "currency": "USD"},
"total_price": {"pay_later": 12325.20, "pay_now": 11082.68, "currency": "USD"},
"fees_taxes_included_in_total": true,
"fees_breakdown": null
}
],
"cheapest": {
"class": "ECONOMY",
"name": "Nissan Versa or Similar",
"total_price_pay_now": 6713.29,
"daily_avg_pay_now": 36.69
},
"session_id": "6df6814b-2e52-46da-8853-7f2d788e046f",
"screenshots": ["screenshots/lax-2026-06-01.png"]
}
{
"success": false,
"reason": "human_press_and_hold",
"reference_id": "bd8c3b60-534c-11f1-9e66-3f681c98e7b3",
"pickup_location": {"input": "LAX"},
"url_at_block": "https://www.avis.com/en/products-and-services/services/long-term-car-rental",
"session_id": "6df6814b-2e52-46da-8853-7f2d788e046f",
"screenshots": ["failures/lax-2026-06-01.png"],
"html_path": "failures/lax-2026-06-01.html",
"retry_recommended": true
}
{
"success": false,
"reason": "range_outside_15_to_330_days",
"rental_days": 365,
"constraint": {"min_days": 15, "max_days": 330, "product": "Avis Flex"}
}
{
"success": true,
"vehicles": [],
"sold_out": true,
"pickup_location": {"input": "LAX", "resolved": "Los Angeles Intl Airport (LAX)"},
"pickup_at": "2026-06-01T12:00:00",
"return_at": "2026-12-01T12:00:00",
"rental_days": 183
}
Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
sixt.com/search-car-rental-oulz1k
skyscanner.net/search-cheapest-flight-v8nvut
goodrx.com/compare-drug-prices-c8d87y
booking.com/search-hotels-asq6cc
google.com/search-flights-ts4g1f
cruisecritic.com/extract-reviews-8r7ocj
Solid pick for teams standardizing on skills: search-long-term-rentals is focused, and the summary matches what you get after install.
Registry listing for search-long-term-rentals matched our evaluation — installs cleanly and behaves as described in the markdown.
We added search-long-term-rentals from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
search-long-term-rentals reduced setup friction for our internal harness; good balance of opinion and flexibility.
search-long-term-rentals fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
Useful defaults in search-long-term-rentals — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
I recommend search-long-term-rentals for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
search-long-term-rentals has been reliable in day-to-day use. Documentation quality is above average for community skills.
I recommend search-long-term-rentals for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
Useful defaults in search-long-term-rentals — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
showing 1-10 of 30