Quickstart
Make your first call in two minutes with cURL, Python or Node.js.
You need an Upscrape account and a terminal. New accounts start with up to 100 free credits and no card; this guide spends one.
1. Get an API key
Open the console, create a key and copy it. The key is shown once, so keep it somewhere safe, then make it available to your terminal:
export UPSCRAPE_API_KEY="paste_your_key_here"
2. Make the call
This searches Google Maps for coffee shops in San Francisco and asks for the first five. Every endpoint works the same way: you send its ID as capability and its fields as input.
curl https://data.upscrape.com/execute \ -H "Authorization: Bearer $UPSCRAPE_API_KEY" \ -H "Content-Type: application/json" \ -H "Prefer: wait=30" \ -d '{ "capability": "googlemaps.search", "input": { "query": "coffee shops", "location": "San Francisco, CA", "limit": 5 } }'
import osimport requestsresponse = requests.post( "https://data.upscrape.com/execute", headers={ "Authorization": f"Bearer {os.environ['UPSCRAPE_API_KEY']}", "Prefer": "wait=30", }, json={ "capability": "googlemaps.search", "input": {"query": "coffee shops", "location": "San Francisco, CA", "limit": 5}, },)job = response.json()for place in job["results"][0]["data"]["items"]: print(place["name"], place["rating"], place["address"])
const response = await fetch("https://data.upscrape.com/execute", { method: "POST", headers: { Authorization: `Bearer ${process.env.UPSCRAPE_API_KEY}`, "Content-Type": "application/json", Prefer: "wait=30", }, body: JSON.stringify({ capability: "googlemaps.search", input: { query: "coffee shops", location: "San Francisco, CA", limit: 5 }, }),});const job = await response.json();for (const place of job.results[0].data.items) { console.log(place.name, place.rating, place.address);}
For Python, install the requests library first with pip install requests. For Node.js, use version 18 or later, save the code as quickstart.mjs and run node quickstart.mjs.
Prefer: wait=30 asks Upscrape to hold the connection until the result is ready, for up to 30 seconds. This search usually takes one or two.
3. Read the result
The call answers with the job and its result. This is a real response, shortened to the first place:
{ "job_id": "d7ef67f5-8cb8-4989-8b55-8ba67a1aab4f", "state": "completed", "success": true, "capability": "googlemaps.search", "results": [ { "data": { "items": [ { "name": "The Coffee Movement", "rating": 4.8, "address": "1737 Balboa St, San Francisco, CA 94121", "website": "https://www.thecoffeemovement.com/", "place_id": "ChIJTfb1d_uHhYARRpn5d_Fk1SU", "lat": 37.7764721, "lng": -122.4778225 } ], "summary": { "query": "coffee shops", "total_items": 5, "has_more": true } } } ], "billing": {"credits_charged": 1}}
The data is in
results[0].data. Its fields are the endpoint's own; each endpoint's reference page lists every one.The cost is in
billing.credits_charged. A call that fails costs nothing, and asking for the same data again soon after is free.has_more: truemeans there are more places than you asked for. Raiselimitto get them.
The Python and Node.js versions print one line per place:
The Coffee Movement 4.8 1737 Balboa St, San Francisco, CA 94121The Coffee Berry SF 4.9 1410 Lombard St, San Francisco, CA 94123Better Half Coffee 4.9 1448 Pacific Ave, San Francisco, CA 94109Paper Son Coffee 4.7 303 2nd St N102, San Francisco, CA 94107Third Wheel Coffee 4.9 991 Oak St, San Francisco, CA 94117
If a call takes longer
Some endpoints take more than 30 seconds, for example a long crawl. Then the call answers with HTTP 202 and a job that is still queued or running:
{ "job_id": "d7ef67f5-8cb8-4989-8b55-8ba67a1aab4f", "state": "running", "poll_url": "https://data.upscrape.com/jobs/d7ef67f5-8cb8-4989-8b55-8ba67a1aab4f", "poll_after_ms": 2000}
Wait poll_after_ms, then fetch poll_url with the same key until state is completed or failed:
curl https://data.upscrape.com/jobs/d7ef67f5-8cb8-4989-8b55-8ba67a1aab4f \ -H "Authorization: Bearer $UPSCRAPE_API_KEY"
Don't send the first request again: that starts, and pays for, a second job. Long-running calls has a complete loop with a deadline.
Call any other endpoint
Keep the request and change two things: capability and input. Every endpoint's reference page gives its ID, every input field and an example you can paste. For example, a LinkedIn profile:
{ "capability": "linkedin.profile.get", "input": {"url": "https://www.linkedin.com/in/satyanadella"}}
Browse every platform and endpoint, or use Search at the top of the page.
Next
Credits and limits: what a call costs and how many run at once.
Errors and retries: what can go wrong and which errors to retry.
Safe retries: retry after a dropped connection without paying twice.
Connect an AI agent: let Claude, ChatGPT or Cursor make these calls for you.
Something missing or unclear? Ask the team that builds the endpoints.