SERP Data API
Export your SERP ranking data programmatically. Pull positions, competitor URLs, and full result pages into your reporting tools or data warehouse.
Endpoint
GET https://app.serp360.ai/api/v1/serp
Authentication
Pass your API key in the X-API-Key header:
curl -X GET "https://app.serp360.ai/api/v1/serp?..." \ -H "X-API-Key: sk_live_your_key_here"
How it works
The SERP endpoint uses a two-step pingback flow:
- Queue – Call with a
pingback_url. We return immediately with statusqueued. - Wait – We POST to your pingback URL when the data is ready (after the next ETL run).
- Retrieve – Call again without
pingback_urlto fetch the data. Credits are charged here.
This flow ensures you're not polling repeatedly. Set up a webhook endpoint, and we'll tell you when to collect.
Parameters
| Parameter | Required | Description |
|---|---|---|
keyword |
Yes | The keyword text (case insensitive) |
search_engine |
Yes | google , bing , or yahoo |
search_group |
Yes | Your search group name (case insensitive) |
pingback_url |
Step 1 only | HTTPS URL where we'll POST when data is ready |
Step 1: Queue the request
curl -X GET "https://app.serp360.ai/api/v1/serp?keyword=organic%20coffee%20beans&search_engine=google&search_group=my-client&pingback_url=https://your-server.com/webhook" \ -H "X-API-Key: sk_live_your_key_here"
Response
{
"success": true,
"status": "queued",
"message": "We'll notify you when data is ready.",
"request_id": "a1b2c3d4",
"credits_used": 0,
"meta": {
"request_id": "a1b2c3d4",
"duration_ms": 45.12
}
}
Pingback notification
When your data is ready, we POST to your pingback_url :
{
"event": "serp_data_ready",
"keyword": "organic coffee beans",
"search_engine": "google",
"search_group": "my-client",
"date": "2025-11-28",
"request_id": "a1b2c3d4",
"message": "Your SERP data is ready. Call the API without pingback_url to retrieve."
}
Your endpoint should return a 2xx status. We'll retry failed deliveries up to 3 times.
Step 2: Retrieve the data
Once you receive the pingback, call the same endpoint without pingback_url :
curl -X GET "https://app.serp360.ai/api/v1/serp?keyword=organic%20coffee%20beans&search_engine=google&search_group=my-client" \ -H "X-API-Key: sk_live_your_key_here"
Response
{
"success": true,
"data": {
"keyword": "organic coffee beans",
"search_engine": "google",
"search_group": "my-client",
"date": "2025-11-29",
"your_position": 4,
"your_url": "https://example.com/coffee-beans",
"serp_results": [
{
"position": 1,
"url": "https://coffeeroasters.com/organic/",
"title": "Premium Organic Coffee Beans | Fresh Roasted Daily",
"description": "Discover our range of certified organic coffee beans...",
"domain": "coffeeroasters.com"
},
{
"position": 2,
"url": "https://beanbox.com/organic-coffee",
"title": "Organic Coffee Subscription | Bean Box",
"description": "Get freshly roasted organic coffee delivered...",
"domain": "beanbox.com"
}
],
"total_results": 100
},
"credits_used": 0.5,
"balance": 14999.5,
"meta": {
"request_id": "b2c3d4e5",
"duration_ms": 120.34
}
}
Response fields
| Field | Type | Description |
|---|---|---|
keyword |
string | The keyword you queried |
search_engine |
string | The search engine (google, bing, yahoo) |
search_group |
string | Your search group name |
date |
string | Date of the SERP data (YYYY-MM-DD) |
your_position |
integer|null | Your tracked domain's position, or null if not ranking |
your_url |
string|null | Your ranking URL, or null if not ranking |
serp_results |
array | Up to 100 SERP results |
serp_results[].position |
integer | Position in SERP (1-100) |
serp_results[].url |
string | Full URL of the result |
serp_results[].title |
string | Page title |
serp_results[].description |
string | Meta description snippet |
serp_results[].domain |
string | Domain name |
total_results |
integer | Number of results returned |
Error responses
Keyword not found
{
"success": false,
"error": "Keyword not found in the specified search group.",
"code": "KEYWORD_NOT_FOUND",
"meta": {
"request_id": "c3d4e5f6",
"duration_ms": 12.45
}
}
No data available
{
"success": false,
"error": "No SERP data available for this keyword yet.",
"code": "NO_DATA",
"meta": {
"request_id": "d4e5f6g7",
"duration_ms": 15.67
}
}
Missing pingback
{
"success": false,
"error": "No completed pingback found. Queue a request first with pingback_url.",
"code": "PINGBACK_REQUIRED",
"meta": {
"request_id": "e5f6g7h8",
"duration_ms": 8.23
}
}
Pricing
0.5 credits per successful retrieval.
Credits are only charged when you retrieve data in step 2. Queuing requests, receiving pingbacks, and error responses are free.
Example: Python integration
import requests
import time
API_KEY = "sk_live_your_key_here"
BASE_URL = "https://app.serp360.ai/api/v1/serp"
def queue_serp_request(keyword, search_engine, search_group, pingback_url):
"""Queue a SERP data request."""
response = requests.get(
BASE_URL,
headers={"X-API-Key": API_KEY},
params={
"keyword": keyword,
"search_engine": search_engine,
"search_group": search_group,
"pingback_url": pingback_url
}
)
return response.json()
def retrieve_serp_data(keyword, search_engine, search_group):
"""Retrieve SERP data after pingback received."""
response = requests.get(
BASE_URL,
headers={"X-API-Key": API_KEY},
params={
"keyword": keyword,
"search_engine": search_engine,
"search_group": search_group
}
)
return response.json()
# Queue the request
result = queue_serp_request(
keyword="organic coffee beans",
search_engine="google",
search_group="my-client",
pingback_url="https://your-server.com/webhook"
)
print(f"Queued: {result['request_id']}")
# After receiving pingback, retrieve data
data = retrieve_serp_data(
keyword="organic coffee beans",
search_engine="google",
search_group="my-client"
)
print(f"Position: {data['data']['your_position']}")
Example: Webhook handler (Node.js/Express)
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
const { event, keyword, search_engine, search_group, date } = req.body;
if (event === 'serp_data_ready') {
console.log(`SERP data ready for "${keyword}" on ${search_engine}`);
// Trigger your data retrieval process
// e.g., add to a job queue, call the API, update your database
}
res.status(200).send('OK');
});
app.listen(3000);
Tips
- Match parameters exactly – The keyword, search engine, and search group must match what's configured in SERP360.
- Use HTTPS for pingbacks – We only POST to secure endpoints.
- Handle retries – Your webhook might receive duplicate notifications. Use the
request_idto deduplicate. - Check your balance – The
balancefield in responses shows your remaining credits.