Uber
| Metadata | Value |
|---|---|
| Category | logistics |
| Capabilities | http |
| Website | https://uber.com |
Returns shapes
Section titled “Returns shapes”order— fromget_delivery,get_messages,add_to_cart,checkout,track_deliveryorder[]— fromlist_deliveries,get_cartplace— fromget_storeplace[]— fromsearch_address,list_addresses,search_stores,list_nearby_storesproduct— fromget_item_customizationsproduct[]— fromsearch_productstrip— fromget_triptrip[]— fromlist_trips
Connections
Section titled “Connections”web— Uber rider account — requires cookies from a logged-in browser sessioneats— Uber Eats — requires cookies from a logged-in ubereats.com browser session
Readme
Section titled “Readme”Ride history, trip details, receipts, and account info from Uber. Uses Uber’s internal GraphQL API at riders.uber.com/graphql via browser session cookies. Uber Eats uses a separate RPC API at ubereats.com/_p/api/.
Before extending this skill, read:
- Reverse Engineering overview — methodology, tools, progression
- Transport & Anti-Bot — TLS fingerprinting, WAF bypass, cookie domain filtering
- requirements.md — captured API shapes, endpoint inventory, auth headers
- Uber Eats E2E spec — the plan for what we’re building
Features
Section titled “Features”list_trips— Ride history with pagination. Returns trip ID, destination, fare, date, and map URL. Supportsprofile_type(PERSONAL/BUSINESS) filter and pagination vianext_page_token. Max 50 per page.get_trip— Full trip details: driver info, pickup/dropoff addresses, fare breakdown, distance, duration, vehicle type, surge pricing, map URL, and rating.
Account
Section titled “Account”whoami— Full user profile: name, email, phone, rating, picture URL, Uber One membership, payment methods, and profiles (personal/business).check_session— Validate session cookies and return account identity.
Requires an active Uber session in Brave (or another browser). The skill extracts session cookies from the browser’s cookie database. No API keys needed.
- Log in to riders.uber.com in Brave
- Cookies are extracted automatically when you use the skill
Transport
Section titled “Transport”Cookie auth against .uber.com. The rides API uses a single GraphQL endpoint:
POST https://riders.uber.com/graphqlIMPORTANT: Always use http.headers(waf="cf", accept="json", extra={...}) for all HTTP
requests in this skill. The engine sets zero default headers — without http.headers(), you
get no User-Agent, no sec-ch-, no Sec-Fetch- — and some Uber endpoints reject the request.
We are acting as Brave, so always send what Brave sends. See docs/skills/sdk.md.
Rides-specific headers (pass via extra=):
x-csrf-token: x(literal string, not a real CSRF token)x-uber-rv-session-type: desktop_session
Three GraphQL operations:
CurrentUserRidersWeb— user profileActivities— trip history with filtering/paginationGetTrip— full trip details with receipt
Cookie domain filtering
Section titled “Cookie domain filtering”Uber has cookies on multiple subdomains (.uber.com, .riders.uber.com, .auth.uber.com). The engine’s RFC 6265 domain matching ensures only cookies matching riders.uber.com are sent. This prevents csid collisions from sibling subdomains that caused login redirects before domain filtering was implemented.
See Transport & Anti-Bot docs for details.
Uber Eats (in progress)
Section titled “Uber Eats (in progress)”Uber Eats uses a completely different API from rides. It’s NOT GraphQL — it’s an RPC-style API at www.ubereats.com/_p/api/.
Discovery (2026-04-02)
Section titled “Discovery (2026-04-02)”Used browse capture (CDP network capture via bin/browse-capture.py) to navigate ubereats.com/orders in Brave and capture all API calls. Key findings:
Uber Eats API endpoints (all POST https://www.ubereats.com/_p/api/):
| Endpoint | Purpose | Request body |
|---|---|---|
getPastOrdersV1 | Order history | { "lastWorkflowUUID": "" } (pagination) |
getOrderEntitiesV1 | Order details — items, driver, receipt | {} |
getActiveOrdersV1 | Live orders in progress | { "orderUuid": null, "timezone": "America/Chicago" } |
getCartsViewForEaterUuidV1 | Current cart state | {} |
getSearchHomeV2 | Store browsing / search | { "dropPastOrders": true } |
getDraftOrdersByEaterUuidV1 | Draft (unsent) orders | { "removeAdapters": true } |
getUserV1 | User profile for Eats | { "shouldGetSubsMetadata": true } |
getProfilesForUserV1 | User profiles | {} |
getInstructionForLocationV1 | Delivery instructions | { "location": { "latitude": ..., "longitude": ... } } |
setRobotEventsV1 | Bot detection telemetry | { "action": "rendered", "payload": { "isBot": false } } |
Auth headers for Eats (different from rides):
x-csrf-token: xx-uber-session-id: <from uev2.id.session cookie>x-uber-target-location-latitude: 30.271044x-uber-target-location-longitude: -97.695755x-uber-client-gitref: <client version hash>x-uber-ciid: <client instance ID>x-uber-request-id: <UUID per request>Content-Type: application/jsonCookie domain: .ubereats.com (NOT .uber.com — different domain from rides)
Real-time events: ramenphx/events/recv and ramendca/events/recv — likely SSE or long-polling for live delivery tracking updates.
Key difference from rides: The order_types: "EATS" parameter on the rides GraphQL Activities query does NOT work — EATS is not a valid enum value in RVWebCommonActivityOrderType. Uber Eats order history must be fetched from the Eats-specific getPastOrdersV1 endpoint.
Planned Eats operations
Section titled “Planned Eats operations”See Uber Eats E2E spec for the full plan.
Phase 1 (read):
list_deliveries— Eats order history viagetPastOrdersV1get_delivery— Full delivery details:getReceiptByWorkflowUuidV1for items (HTML parse with lxml),getPastOrdersV1for metadata. Note:getOrderEntityByUuidV1only works for active orders (404 for completed).list_stores— Browse stores viagetSearchHomeV2orgetFeedV1get_menu— Store menu/items viagetStoreV1(not yet captured)
Phase 2 (tracking):
track_delivery— Live driver location via real-time eventslist_messages— Driver communication
Phase 3 (write — requires firewall):
add_to_cart,checkout,approve_substitution,rate_delivery
Reverse Engineering Notes
Section titled “Reverse Engineering Notes”Tools used
Section titled “Tools used”agentos browse request uber— authenticated HTTP request with full header visibility. Used to verify cookie auth and inspect response headers.agentos browse cookies uber— cookie inventory showing all.uber.comcookies with timestamps and provenance.agentos browse auth uber— auth resolution trace showing which provider won (brave-browser) and identity (agentos@contini.co).bin/browse-capture.py— CDP network capture. Connected to Brave via CDP, navigated toubereats.com/orders, captured 90 requests including all/_p/api/calls with full headers and POST bodies.
How to extend
Section titled “How to extend”Step 1: Capture network traffic with CDP
# Launch Brave with CDPopen -a "Brave Browser" --args --remote-debugging-port=9222 --remote-allow-origins="*"
# Capture network traffic for any Uber Eats pagepython3 bin/browse-capture.py https://www.ubereats.com/store/costco/... --port 9222
# Look for /_p/api/ POST requests in the output# Response bodies are captured automatically via CDP Network.getResponseBodyStep 2: Extract full API surface from JS bundles
Don’t just capture what one page loads — extract ALL endpoint names from the client JS:
# Find the main bundle URL from browse-capture output# Then grep for API endpoint patternscurl -s "https://www.ubereats.com/_static/client-main-*.js" \ | grep -oE 'get[A-Z][a-zA-Z]+V[0-9]+' | sort -u # read endpointscurl -s "https://www.ubereats.com/_static/client-main-*.js" \ | grep -oE '[a-z]+[A-Z][a-zA-Z]+V[0-9]+' | sort -u | grep -v '^get' # write endpointsThis revealed 32 endpoints (22 read, 10 write) that weren’t visible from a single page capture. The pattern {verb}{Entity}V{version} is consistent across all Uber Eats endpoints.
Step 3: Test individual endpoints
Use agentos browse request or direct curl to test specific endpoints. The auth headers and cookie domain are documented in requirements.md.
See Reverse Engineering overview for the full methodology and Browse Toolkit spec for tool documentation.
CDP tips for testing Eats endpoints
Section titled “CDP tips for testing Eats endpoints”Making authenticated API calls via CDP:
import json, urllib.request, websocket
# Connect to Brave (must be running with --remote-debugging-port=9222)tabs = json.loads(urllib.request.urlopen("http://127.0.0.1:9222/json").read())ws = websocket.create_connection(tabs[0]["webSocketDebuggerUrl"], timeout=15)
# IMPORTANT: Navigate to ubereats.com first — fetch with credentials: 'include'# only sends cookies for same-origin requestsws.send(json.dumps({"id": 1, "method": "Page.navigate", "params": {"url": "https://www.ubereats.com/"}}))import time; time.sleep(5) # wait for page load
# Call any /_p/api/ endpointjs = """(async () => { const r = await fetch('https://www.ubereats.com/_p/api/getPastOrdersV1', { method: 'POST', credentials: 'include', headers: {'Content-Type': 'application/json', 'x-csrf-token': 'x'}, body: JSON.stringify({"lastWorkflowUUID": ""}) }); return await r.text();})()"""ws.send(json.dumps({"id": 2, "method": "Runtime.evaluate", "params": {"expression": js, "awaitPromise": True, "returnByValue": True}}))
# Read response (skip any navigation events)for _ in range(20): resp = json.loads(ws.recv()) if resp.get("id") == 2: data = json.loads(resp["result"]["result"]["value"]) breakKey gotchas:
- Use
websocketmodule (installed), NOTwebsockets(not installed). Synchronous API, no asyncio. - Brave’s cookie DB is encrypted — can’t extract cookies from SQLite directly. Use CDP
Network.getCookiesor the agentOS engine’s auth resolver. - The
x-csrf-token: xheader is required. Other Eats headers (x-uber-session-id,x-uber-target-location-*) are optional for basic reads — the browser sends them automatically via cookies. - When reading CDP responses, check
resp.get("id")to match your request — navigation and other events arrive on the same websocket.