Authentication
All API requests require authentication using an API key. Include your key in the X-API-Key header.
Keep your API key secure
Never expose your API key in client-side code or public repositories.
Base URL
All API endpoints use the following base URL:
Rate Limits & Concurrency
API Unlimited subscriptions have concurrent request limits based on your worker count:
| Workers | Concurrent Requests | Note |
|---|---|---|
| 1 | 1 per endpoint | Can run /scrape + /google-search simultaneously |
| 3 | 3 per endpoint | 3 scrape requests in parallel |
| 5 | 5 per endpoint | Maximum parallelism |
If you exceed your concurrent limit, you'll receive a 429 response.
Wait for an in-progress request to complete before sending another.
Error Handling
The API returns standard HTTP status codes and JSON error responses:
| Status | Code | Description |
|---|---|---|
400 |
missing_keyword | Required parameter missing |
400 |
blocked_operator | Query contains a blocked search operator |
401 |
invalid_api_key | API key is invalid or missing |
402 |
no_credits | Insufficient credits (pay-as-you-go only) |
403 |
subscription_required | Endpoint requires API Unlimited |
429 |
concurrent_limit | All request slots in use |
503 |
server_provisioning | Resources being set up (wait 5-10 min) |
"error": "All request slots in use",
"message": "All 3 scrape request slots are in use. Please wait.",
"code": "concurrent_limit",
"max_concurrent": 3
}
/v1/scrape/
Extract business leads from Google Maps. Returns detailed business information including name, phone, address, website, ratings, and more.
Request Body
| Parameter | Type | Description |
|---|---|---|
keyword
required
|
string | Business type or search term (e.g., "restaurants", "plumbers") |
location
required
|
string | City, address, or area (e.g., "Miami, FL", "10001") |
max_results
optional
|
integer | Maximum results to return (default: unlimited, max: 500) |
Example Request
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"keyword": "restaurants", "location": "Miami, FL", "max_results": 100}'
Response
"success": true,
"results": [
{
"name": "Joe's Pizza",
"phone": "+1 305-555-0123",
"address": "123 Ocean Drive, Miami, FL 33139",
"website": "https://joespizza.com",
"rating": 4.5,
"num_reviews": 328,
"categories": ["Pizza", "Italian"],
"place_id": "ChIJ...",
"google_maps_url": "https://maps.google.com/...",
"latitude": 25.7617,
"longitude": -80.1918
}
],
"total": 100,
"credits_charged": 0,
"unlimited": true,
"query": {
"keyword": "restaurants",
"location": "Miami, FL",
"max_results": 100
}
}
/v1/google-search/
Perform Google web searches and get organic search results. Returns titles, URLs, and snippets.
Requires: API Unlimited subscription
Request Body
| Parameter | Type | Description |
|---|---|---|
query
required
|
string | Search query (max 500 characters) |
Example Request
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"query": "best CRM software for small business"}'
Response
"success": true,
"results": [
{
"title": "10 Best CRM Software for Small Business in 2024",
"link": "https://example.com/best-crm",
"snippet": "Compare the top CRM solutions for small businesses...",
"displayed_link": "example.com",
"position": 1
}
],
"total": 10,
"query": "best CRM software for small business"
}
Blocked Search Operators
Advanced search operators are not allowed
To ensure fair usage, certain Google search operators are blocked.
| Category | Blocked Operators |
|---|---|
| Site/URL | site: inurl: allinurl: |
| Title | intitle: allintitle: |
| Content | intext: allintext: inanchor: |
| File Type | filetype: ext: |
| Cache/Links | cache: link: related: info: |
| Date | before: after: daterange: |
| Boolean | OR AND -word (exclusion) |
Social media + followers/following searches are blocked
Combining social media platform names with "followers" or "following" triggers automated blocking and is not allowed.
| Query Type | Example | Status |
|---|---|---|
| Social media alone | linkedin jobs |
Allowed |
| "followers" alone | company followers 2024 |
Allowed |
| Social media + followers | instagram followers |
Blocked |
| Social media + following | linkedin following |
Blocked |
Why this restriction?
Through extensive testing, we discovered that combining social media platforms with "followers" or "following" triggers Google's automated blocking systems. This can permanently blacklist server IPs, affecting all users. This restriction protects the service infrastructure.
Error Response for Blocked Operators
"error": "Invalid query",
"message": "site: operator is not allowed. Please use simple search terms.",
"code": "blocked_operator",
"blocked_operator": "site:"
}
Valid queries:
"best restaurants Barcelona"- Simple search"iPhone 15 Pro reviews"- Product search"machine learning courses"- Topic search
Note on minus sign (-)
The exclusion operator blocks -word but allows negative numbers and ranges:
python -tutorial- Blocked (exclusion operator)-5 degrees celsius- Allowed (negative number)price range 100-200- Allowed (number range)
/v1/email-search/
Find email addresses and social media profiles for any domain.
Requires: API Unlimited subscription
Request Body
| Parameter | Type | Description |
|---|---|---|
domain
required
|
string | Domain to search (e.g., "example.com") |
Example Request
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"domain": "stripe.com"}'
Response
"success": true,
"domain": "stripe.com",
"emails": [
"support@stripe.com",
"sales@stripe.com"
],
"social": {
"linkedin": "https://linkedin.com/company/stripe",
"x": "https://x.com/stripe",
"facebook": "https://facebook.com/stripe"
}
}
/v1/credits/
Check your current credit balance (for pay-as-you-go users).
Example Request
-H "X-API-Key: sk_live_your_key"
Response
"credits": 5000,
"email": "user@example.com"
}
/v1/server-status/
Check the status of your dedicated worker(s).
Requires: API Unlimited subscription
Response
"has_subscription": true,
"is_ready": true,
"status": "healthy",
"message": "Your resources are ready and operational.",
"worker_count": 3,
"servers": [
{"index": 0, "status": "healthy"},
{"index": 1, "status": "healthy"},
{"index": 2, "status": "healthy"}
]
}
Code Examples
Python
API_KEY = "sk_live_your_key"
BASE_URL = "https://api.onleads.io"
def scrape_businesses(keyword, location, max_results=100):
response = requests.post(
f"{BASE_URL}/v1/scrape/",
headers={"X-API-Key": API_KEY},
json={
"keyword": keyword,
"location": location,
"max_results": max_results
}
)
return response.json()
# Example usage
results = scrape_businesses("restaurants", "Miami, FL")
print(f"Found {results['total']} businesses")
for biz in results['results']:
print(f" - {biz['name']}: {biz['phone']}")
JavaScript
const BASE_URL = 'https://api.onleads.io';
async function scrapeBusinesses(keyword, location, maxResults = 100) {
const response = await fetch(`${BASE_URL}/v1/scrape/`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ keyword, location, max_results: maxResults })
});
return response.json();
}
// Example usage
scrapeBusinesses('restaurants', 'Miami, FL')
.then(data => console.log(`Found ${data.total} businesses`));
cURL
curl -X POST https://api.onleads.io/v1/scrape/ \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"keyword": "restaurants", "location": "Miami, FL"}'
# Check credits
curl https://api.onleads.io/v1/credits/ \
-H "X-API-Key: sk_live_your_key"
# Google search (API Unlimited only)
curl -X POST https://api.onleads.io/v1/google-search/ \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{"query": "best crm software"}'
Need Help?
If you have questions or run into issues, we're here to help.