Transform your Google Sheets into a powerful REST API — no coding required!
https://sheetapi.pro/api/v1
All API requests require an API key sent in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Work with your Google Sheet data. Replace {sheet_id} with your sheet's unique ID (found in your dashboard).
Fetch rows from your sheet. Returns data as JSON objects with column headers as keys.
a1b2c3d4-e5f6...
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | int | 100 | Maximum number of rows to return |
offset | int | 0 | Number of rows to skip (for pagination) |
q | string | — | Search text across all columns (case insensitive) |
sort | string | — | Column name to sort by |
order | string | asc | Sort direction: asc or desc |
column | string | — | Comma-separated column names to return (e.g., Name,Email) |
Combine multiple params:
?q=john&sort=Date&order=desc&limit=10&column=Name,Email
cURL:
curl "https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows?limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"
JavaScript:
fetch('https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows?limit=10', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
})
.then(res => res.json())
.then(data => console.log(data));
Python:
import requests
url = "https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
params = {"limit": 10}
response = requests.get(url, headers=headers, params=params)
print(response.json())
{
"success": true,
"data": [
{"Date": "2026-02-07", "Name": "Alice", "Email": "alice@test.com"},
{"Date": "2026-02-06", "Name": "Bob", "Email": "bob@test.com"}
],
"sheet_id": "a1b2c3d4...",
"count": 2
}
Add a new row to your sheet. You can send data in two formats:
Use your actual column headers as keys. Easy for no-coders!
{
"Date": "2026-02-07",
"Name": "John",
"Email": "john@test.com"
}
Send values in the same order as your sheet columns:
{
"data": ["2026-02-07", "John", "john@test.com"]
}
cURL:
curl -X POST "https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"Date": "2026-02-07", "Name": "John", "Email": "john@test.com"}'
JavaScript:
fetch('https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"Date": "2026-02-07",
"Name": "John",
"Email": "john@test.com"
})
})
.then(res => res.json())
.then(data => console.log(data));
Python:
import requests
url = "https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"Date": "2026-02-07",
"Name": "John",
"Email": "john@test.com"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
Update an existing row. Index is 1-based — row 1 is the first data row (after the header).
Accepts the same two body formats as POST (column names or array).
curl -X PUT "https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows/1" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"Date": "2026-02-08", "Name": "Jane", "Email": "jane@test.com"}'
Delete a row from your sheet. Index is 1-based. This actually removes the row, not just clears the cells.
curl -X DELETE "https://sheetapi.pro/api/v1/data/YOUR_SHEET_ID/rows/1" \
-H "Authorization: Bearer YOUR_API_KEY"
Get the first 20 rows, then the next 20:
GET /data/{sheet_id}/rows?limit=20&offset=0 # Page 1
GET /data/{sheet_id}/rows?limit=20&offset=20 # Page 2
Find all rows containing "john" in any column:
GET /data/{sheet_id}/rows?q=john
Sort by "Date" column, newest first:
GET /data/{sheet_id}/rows?sort=Date&order=desc
Only return "Name" and "Email" columns:
GET /data/{sheet_id}/rows?column=Name,Email
GET /data/{sheet_id}/rows?q=test&sort=Date&order=desc&limit=10&column=Name,Email
Every response includes useful metadata headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Your per-minute request limit |
X-RateLimit-Daily-Limit | Your daily request limit |
X-RateLimit-Daily-Remaining | Remaining requests today |
X-Cache | HIT (from cache) or MISS (fresh data) |
When something goes wrong, you'll get a JSON response with an error code and message:
| Status Code | Error Code | Meaning |
|---|---|---|
| 400 | INVALID_DATA | Bad request body or parameters |
| 401 | MISSING_API_KEY | No Authorization header provided |
| 403 | FORBIDDEN | This isn't your sheet, or your key is invalid |
| 404 | SHEET_NOT_FOUND | Sheet ID doesn't exist |
| 429 | — | Rate limit exceeded (check Retry-After header) |
| 500 | FETCH_ERROR | Failed to read from Google Sheets |
| 500 | CREATE_ERROR | Failed to create row |
| 500 | UPDATE_ERROR | Failed to update row |
| 500 | DELETE_ERROR | Failed to delete row |
{
"success": false,
"error": "MISSING_API_KEY",
"message": "Authorization header is required"
}
Rate limits prevent abuse and ensure fair usage. Your plan determines your limits:
| Plan | Price | Requests/Min | Requests/Day |
|---|---|---|---|
| Free | €0 | 60 | 100 |
| Starter | €9/mo | 120 | 1,000 |
| Pro | €29/mo | 240 | 10,000 |
| Pro+ | €49/mo | 500 | 16,667 |
| Enterprise | €99/mo | 700 | 33,333 |
When you exceed your limit, you'll get a 429 Too Many Requests response with a Retry-After header telling you when to try again.
X-Cache header — a HIT means you got cached data without using a quota.
/d/ and /edit). The SheetAPI sheet ID is a unique ID we generate when you connect a sheet — you'll find it in your dashboard and use it in API requests.
429 Too Many Requests response. Wait for the time specified in the Retry-After header before making more requests, or upgrade to a higher plan for more capacity.
1 = your first data row, 2 = second data row, etc. The header row is never counted.
column parameter for??column=Name,Email returns only those two columns. Great for reducing payload size and improving performance.
SheetAPI.pro — Built with ❤️ | Dashboard | Playground | Home