Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Book restaurant reservations via browser automation. Use when asked to make dinner reservations, book a table, or find availability at restaurants. Supports OpenTable, Resy, and direct restaurant booking sites.
.claude/skills/gooseworks-ai-restaurant-booking/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 146% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 161% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 44% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 32% | 0% |
Read your credentials from ~/.gooseworks/credentials.json:
bashexport GOOSEWORKS_API_KEY=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json'))['api_key'])") export GOOSEWORKS_API_BASE=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json')).get('api_base','https://api.gooseworks.ai'))")
If ~/.gooseworks/credentials.json does not exist, tell the user to run: npx gooseworks login
All endpoints use Bearer auth: -H "Authorization: Bearer $GOOSEWORKS_API_KEY"
Book reservations using Notte browser automation via Orthogonal.
npm install -g @orth/cli) or API keybashcurl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/start"}' --body '{"browser_type":"chromium","headless":true,"solve_captchas":true,"idle_timeout_minutes":10}'
Save the session_id from the response.
bashcurl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"goto","url":"https://www.opentable.com/r/{restaurant}?datetime=2026-02-17T19:00&covers=2"}'
bashcurl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"click","selector":"button:has-text(\"7:00 PM\")"}'
bashcurl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"click","selector":"button:has-text(\"Select\")"}'
bash# First name curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"fill","selector":"input#firstName","value":"John"}' # Last name curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"fill","selector":"input#lastName","value":"Doe"}' # Email curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"fill","selector":"input#email","value":"john@example.com"}' # Phone curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"fill","selector":"input#phoneNumber","value":"4155551234"}'
bashcurl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"click","selector":"text=I agree to the restaurant"}'
bashcurl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/execute"}' --body '{"type":"click","selector":"button:has-text(\"Complete reservation\")"}'
bashcurl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \ -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"api":"notte","path":"/sessions/{session_id}/page/scrape"}' --body '{"only_main_content":true}'
Look for "confirmed" in the response.
bash# Start session curl -X POST "https://api.orth.sh/v1/run" \ -H "Content-Type: application/json" \ -d '{ "api": "notte", "path": "/sessions/start", "body": { "browser_type": "chromium", "headless": true, "solve_captchas": true, "idle_timeout_minutes": 10 } }' # Execute actions (same pattern) curl -X POST "https://api.orth.sh/v1/run" \ -H "Content-Type: application/json" \ -d '{ "api": "notte", "path": "/sessions/{session_id}/page/execute", "body": {"type":"goto","url":"https://www.opentable.com/..."} }'
| Field | Selector | |-------|----------| | First name | input#firstName | | Last name | input#lastName | | Email | input#email | | Phone | input#phoneNumber | | Terms checkbox | text=I agree to the restaurant | | Submit | button:has-text('Complete reservation') | | Time slots | button:has-text('7:00 PM') | | Seating select | button:has-text('Select') |
Search OpenTable and extract from URL:
restref=1906 → Foreign CinemaExample URL format:
https://www.opentable.com/r/{restaurant-slug}?restref={id}&datetime={YYYY-MM-DDTHH:MM}&covers={n}fill action with value param (not type with text)If restaurant uses Resy:
https://resy.com/cities/{city}/venues/{restaurant}?date={YYYY-MM-DD}&seats={n}Similar flow but different selectors. Scrape page first to identify form fields.
gog calendar createOther measured skills in the registry, with their headline benchmark lift.