Data Processor
API Documentation
Upload CSV files and run data operations โ statistics, text processing, column management, and more โ powered by pandas, over a simple REST API. Built for developers.
Overview
The Data Processor API lets you upload CSV files and process them with pandas-backed operations. Upload a CSV to get its parsed structure, then run statistics, text processing, column management, or cleaning. Designed for data pipelines and lightweight analytics.
Base URL & Authentication
Base URL
Base URL
https://odivora.com/api/v1
Authentication
Include your API credentials in every request header.
Headers
X-API-Key: your_api_key
X-API-Secret: your_secret
Content-Type: application/json
Use the credentials shown in your API Keys section. In production, store them in environment variables or a secure secret store rather than source code.
Get API Keys
Follow these steps to obtain your API credentials:
Access Your Profile
Once you log in, click on your profile picture in the top-right corner, then click on "Your profile" from the dropdown menu.
Create API Key
From your profile page, proceed to the "API Keys" section and create a key by filling in a name you prefer.
"CSV analytics bot" or "My Reporting Pipeline"
Save Your Credentials
Click on "Create API Key" to generate your credentials, then immediately copy and save both the API Key and Secret.
Your secret key will only be displayed once! Copy it immediately and store it securely. You won't be able to see it again.
Never share your API keys publicly or commit them to version control. Treat them like passwords โ regenerate immediately if compromised.
20 requests per minute per API key (health: 30/min, upload: 10/min, process: 20/min). Check your dashboard for current usage and limits.
Endpoints
GET /data_processor/healthPOST /data_processor/uploadPOST /data_processor/processHealth Check
Health check endpoint to verify the Data Processor service status, available backend, and supported formats.
Response
Success Response
{
"success": true,
"status": "healthy",
"data_processor_backends": {
"pandas": true
},
"supported_formats": [".csv"],
"max_file_size_mb": 50,
"timestamp": "2026-08-07T12:00:00"
}
Code Examples
Python
import requests
url = "https://odivora.com/api/v1/data_processor/health"
headers = {
"X-API-Key": "your_api_key",
"X-API-Secret": "your_secret"
}
res = requests.get(url, headers=headers)
print(res.json())
cURL
curl -X GET https://odivora.com/api/v1/data_processor/health \
-H "X-API-Key: your_api_key" \
-H "X-API-Secret: your_secret"
JavaScript
fetch('https://odivora.com/api/v1/data_processor/health', {
method: 'GET',
headers: {
'X-API-Key': 'your_api_key',
'X-API-Secret': 'your_secret'
}
})
.then(res => res.json())
.then(console.log);
Upload CSV
Upload a CSV file and receive its parsed structure (columns, rows, shape). Upload the file as multipart/form-data.
Form Parameters
| Field | Type | Description |
|---|---|---|
file | File | CSV file (required) โ only .csv files are supported, up to 50MB |
Response
Success Response
{
"success": true,
"data": {
"columns": ["name", "age", "city"],
"data": [
["name", "age", "city"],
["Alice", 30, "New York"],
["Bob", 25, "London"]
],
"shape": [2, 3],
"info": "2 rows ร 3 columns"
}
}
cURL Example
cURL
curl -X POST "https://odivora.com/api/v1/data_processor/upload" \
-H "X-API-Key: your_api_key" \
-H "X-API-Secret: your_secret" \
-F "file=@data.csv"
Code Examples
Python
import requests
url = "https://odivora.com/api/v1/data_processor/upload"
headers = {
"X-API-Key": "your_api_key",
"X-API-Secret": "your_secret"
}
with open("data.csv", "rb") as f:
files = {"file": f}
response = requests.post(url, headers=headers, files=files)
if response.status_code == 200:
result = response.json()
print("Columns:", result.get("data", {}).get("columns"))
print("Info:", result.get("data", {}).get("info"))
else:
print(response.json())
JavaScript
const form = new FormData();
form.append('file', fileInput.files[0]);
fetch('https://odivora.com/api/v1/data_processor/upload', {
method: 'POST',
headers: {
'X-API-Key': 'your_api_key',
'X-API-Secret': 'your_secret'
},
body: form
})
.then(res => res.json())
.then(data => console.log(data.data.info));
Process Data
Run a data operation on CSV data. Send the request as JSON with Content-Type: application/json. Use the data array returned by the upload endpoint.
JSON Parameters
| Field | Type | Default | Description |
|---|---|---|---|
data | array | โ | CSV data as a list of rows (first row = headers) (required) |
operation | string | โ | Operation โ statistics, add_column, remove_columns, text_processing, or cleaning (required) |
selected_columns | array | [] | Columns to process (statistics, remove_columns, text_processing) |
selected_metrics | array | [] | Metrics for statistics โ mean, median, mode, total, count |
column_name | string | โ | Name of the new column (add_column) |
text_operation | string | โ | Text operation โ trim, uppercase, lowercase, replace |
find_text | string | โ | Text to find (text_processing replace) |
replace_text | string | โ | Replacement text (text_processing replace) |
remove_duplicates | boolean | false | Remove repeated rows (cleaning) |
fill_rules | object | {} | Per-column missing-value rules for cleaning, for example {"Age": {"method": "mean"}}. Methods: mean, median, mode, custom. |
selected_duplicate_rows | array | [] | Duplicate row index groups to remove, retaining the first row in each group (cleaning) |
selected_duplicate_columns | array | [] | Duplicate column names to remove (cleaning) |
On success the endpoint returns the processed data (and operation results) in JSON.
Cleaning example
Cleaning can remove duplicate rows and fill missing values. The response includes original_rows, new_rows, operations_applied, and the processed data.
Request body
{
"data": [["Name", "Age", "City"], ["Alice", 30, "Nairobi"], ["Alice", 30, "Nairobi"], ["Bob", null, "Nairobi"]],
"operation": "cleaning",
"remove_duplicates": true,
"fill_rules": {
"Age": {"method": "mean"},
"City": {"method": "mode"}
}
}
cURL Example
cURL
curl -X POST "https://odivora.com/api/v1/data_processor/process" \
-H "X-API-Key: your_api_key" \
-H "X-API-Secret: your_secret" \
-H "Content-Type: application/json" \
-d '{
"data": [
["name", "age", "city"],
["Alice", 30, "New York"],
["Bob", 25, "London"]
],
"operation": "statistics",
"selected_columns": ["age"],
"selected_metrics": ["mean", "count"]
}'
Code Examples
Python
import requests
url = "https://odivora.com/api/v1/data_processor/process"
headers = {
"X-API-Key": "your_api_key",
"X-API-Secret": "your_secret",
"Content-Type": "application/json"
}
payload = {
"data": [
["name", "age", "city"],
["Alice", 30, "New York"],
["Bob", 25, "London"]
],
"operation": "statistics",
"selected_columns": ["age"],
"selected_metrics": ["mean", "median", "count"]
}
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 200:
print(response.json())
else:
print(response.json())
JavaScript
const payload = {
data: [
['name', 'age', 'city'],
['Alice', 30, 'New York'],
['Bob', 25, 'London']
],
operation: 'statistics',
selected_columns: ['age'],
selected_metrics: ['mean', 'count']
};
fetch('https://odivora.com/api/v1/data_processor/process', {
method: 'POST',
headers: {
'X-API-Key': 'your_api_key',
'X-API-Secret': 'your_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => console.log(data));
Python SDK
Install the only dependency with pip install requests, then save the example as data_processor_example.py and run python data_processor_example.py. Replace the two placeholder credentials before running it.
Python example
import csv
import os
import requests
BASE_URL = "https://odivora.com/api/v1"
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
HEADERS = {"X-API-Key": API_KEY, "X-API-Secret": API_SECRET}
SAMPLE_ROWS = [
["Name", "Age", "City", "Salary"],
["Alice", 30, "Nairobi", 50000],
["Bob", 25, "Nairobi", 45000],
["Alice", 30, "Nairobi", 50000],
["Carol", "", "Mombasa", 60000],
]
def show_error(response):
try:
detail = response.json()
except ValueError:
detail = response.text
labels = {401: "Authentication failure", 400: "Bad request",
413: "File too large", 429: "Rate limit exceeded",
500: "Server error"}
print(f"{labels.get(response.status_code, 'Request failed')} "
f"({response.status_code}): {detail}")
def request(method, path, **kwargs):
response = requests.request(method, f"{BASE_URL}{path}", headers=HEADERS,
timeout=120, **kwargs)
if not response.ok:
show_error(response)
return None
return response.json()
def ensure_sample_csv(csv_path):
directory = os.path.dirname(csv_path)
if directory:
os.makedirs(directory, exist_ok=True)
with open(csv_path, "w", encoding="utf-8", newline="") as output:
csv.writer(output).writerows(SAMPLE_ROWS)
def upload_csv(csv_path):
with open(csv_path, "rb") as source:
return request("POST", "/data_processor/upload", files={"file": source})
def process_data(data, operation, **params):
payload = {"data": data, "operation": operation, **params}
return request("POST", "/data_processor/process", json=payload)
if __name__ == "__main__":
print("=== ODIVORA DATA PROCESSOR API TEST ===")
ensure_sample_csv("sample_data.csv")
health = request("GET", "/data_processor/health")
if health:
print("[1] Health Check โ", health["status"], health["data_processor_backends"])
uploaded = upload_csv("sample_data.csv")
if uploaded:
data = uploaded["data"]["data"]
print("[2] CSV Upload โ", uploaded["data"]["columns"], uploaded["data"]["shape"])
statistics = process_data(data, "statistics", selected_columns=["Age", "Salary"],
selected_metrics=["mean", "median", "count"])
if statistics:
print("[3] Statistics โ", statistics["data"]["results"])
added = process_data(data, "add_column", column_name="Bonus")
if added:
print("[4] Add Column โ", added["data"]["data"][0])
removed = process_data(data, "remove_columns", selected_columns=["Salary"])
if removed:
print("[5] Remove Columns โ", removed["data"]["data"][0])
text = process_data(data, "text_processing", selected_columns=["Name", "City"],
text_operation="uppercase")
if text:
print("[6] Text Processing โ", text["data"]["data"][1:3])
cleaning = process_data(data, "cleaning", remove_duplicates=True,
fill_rules={"Age": {"method": "mean"},
"City": {"method": "mode"}})
if cleaning:
result = cleaning["data"]
print("[7] Cleaning โ", result["new_rows"], result["operations_applied"])
print("All tests completed.")
# Keep credentials out of source control in production: use environment
# variables or another secure secret store.
Errors & Status Codes
Error Response Format
Error Response
{
"success": false,
"error": "Only CSV files supported"
}
Status Codes
| Code | Meaning |
|---|---|
200 | Success |
400 | Bad request / no file / no request data / unsupported operation / invalid CSV |
401 | Invalid or missing API key/secret |
413 | File too large (max 50MB) |
429 | Rate limit exceeded |
500 | Internal server error / processing failed |