Upload, manage, and process CSV data files for use in document generation and email campaigns.
---
https://app.datapublisher.io/api/csv
---
All endpoints require JWT authentication via Authorization: Bearer header.
---
The CSV Upload API allows you to:
Supported File Types:
File Size Limit: 50 MB
---
Upload a CSV file for processing and storage.
Endpoint: POST /upload
Headers:
Authorization: Bearer
Content-Type: multipart/form-data
Form Data:
csvFile (file, required): CSV file to upload
description (string, optional): File description
tags (JSON array, optional): Tags for categorization
createdBy (string, optional): Creator name
Response (200 OK):
{
"success": true,
"file": {
"id": "uuid",
"originalFilename": "customers.csv",
"fileName": "abc123-def456.csv",
"fileSize": 125000,
"description": "Customer contact list",
"tags": ["customers", "contacts"],
"status": "processing"
}
}
Notes:
processing to completed when analysis finishes
---
Get all uploaded CSV files with optional filtering.
Endpoint: GET /
Headers:
Authorization: Bearer
Query Parameters:
status (string): Filter by status (processing, completed, error)
dateFrom (ISO date): Filter from date
dateTo (ISO date): Filter to date
tags (JSON array): Filter by tags
Response (200 OK):
[
{
"id": "uuid",
"originalFilename": "customers.csv",
"fileName": "abc123.csv",
"fileSize": 125000,
"description": "Customer contact list",
"tags": ["customers", "contacts"],
"status": "completed",
"rowCount": 1500,
"columnCount": 12,
"relationships": [
{
"relatedFileId": "uuid-2",
"relatedFileName": "orders.csv",
"relationshipType": "one-to-many"
}
],
"createdAt": "2026-02-01T10:00:00Z",
"updatedAt": "2026-02-01T10:05:00Z"
}
]
---
Retrieve detailed metadata for a specific CSV file.
Endpoint: GET /:id
Headers:
Authorization: Bearer
Response (200 OK):
{
"id": "uuid",
"userId": "user-uuid",
"originalFilename": "customers.csv",
"fileName": "abc123.csv",
"filePath": "/uploads/user-uuid/uploads/abc123.csv",
"fileSize": 125000,
"description": "Customer contact list",
"tags": ["customers", "contacts"],
"status": "completed",
"rowCount": 1500,
"columnCount": 12,
"columns": [
{
"name": "CustomerID",
"type": "number",
"nullable": false
},
{
"name": "CompanyName",
"type": "string",
"nullable": false
},
{
"name": "ContactEmail",
"type": "string",
"nullable": true
},
{
"name": "TotalSales",
"type": "number",
"nullable": true
}
],
"createdAt": "2026-02-01T10:00:00Z",
"updatedAt": "2026-02-01T10:05:00Z"
}
---
Retrieve CSV data with pagination and filtering.
Endpoint: GET /:id/data
Headers:
Authorization: Bearer
Query Parameters:
limit (number): Number of rows to return (default: 100, max: 1000)
offset (number): Number of rows to skip (default: 0)
filterColumn (string): Column name to filter
filterValue (string): Value to match in filterColumn
Response (200 OK):
{
"success": true,
"headers": ["CustomerID", "CompanyName", "ContactEmail", "TotalSales"],
"data": [
{
"CustomerID": "1001",
"CompanyName": "Acme Corp",
"ContactEmail": "contact@acme.com",
"TotalSales": "45000"
},
{
"CustomerID": "1002",
"CompanyName": "TechStart Inc",
"ContactEmail": "info@techstart.com",
"TotalSales": "32000"
}
],
"metadata": {
"totalRows": 1500,
"returnedRows": 2,
"offset": 0,
"limit": 100
}
}
Performance Notes:
---
Get list of column names from a CSV file.
Endpoint: GET /:id/columns
Headers:
Authorization: Bearer
Response (200 OK):
{
"success": true,
"columns": [
"CustomerID",
"CompanyName",
"ContactEmail",
"TotalSales",
"Region",
"SignupDate"
]
}
---
Process CSV file with custom filtering and options.
Endpoint: POST /:id/process
Headers:
Authorization: Bearer
Content-Type: application/json
Request Body:
{
"filterColumn": "Region",
"filterValue": "West",
"limit": 500,
"offset": 0
}
Response (200 OK):
{
"success": true,
"summary": {
"totalRows": 1500,
"processedRows": 450,
"matchedRows": 450
},
"results": [
{
"CustomerID": "1005",
"CompanyName": "West Coast Co",
"Region": "West"
}
],
"metadata": {
"totalRows": 1500,
"processedRows": 450
}
}
Use Cases:
---
Permanently delete a CSV file and its data.
Endpoint: DELETE /:id
Headers:
Authorization: Bearer
Response (200 OK):
{
"success": true,
"message": "CSV file deleted successfully"
}
Error Responses:
404 Not Found:
{
"success": false,
"message": "File not found or access denied"
}
---
The API automatically detects relationships between CSV files based on:
Relationship Types:
one-to-many: One record relates to many records in another file
many-to-one: Many records relate to one record in another file
many-to-many: Complex relationships through junction tables
Example Use Case:
customers.csv (CustomerID) has one-to-many relationship with orders.csv (CustomerID)
---
The API automatically detects data types:
| Type | Detection Logic |
|------|----------------|
| number | Numeric values (integers, decimals) |
| string | Text values |
| date | ISO date formats, common date patterns |
| boolean | true/false, yes/no, 1/0 |
| email | Email address patterns |
| url | URL patterns |
---
---
| Status Code | Description |
|-------------|-------------|
| 400 | Invalid file type or format |
| 401 | Unauthorized - missing or invalid JWT token |
| 404 | File not found or access denied |
| 413 | File too large (>50 MB) |
| 429 | Too many requests - rate limit exceeded |
| 500 | Internal server error |
---
// Upload CSV
const formData = new FormData();
formData.append('csvFile', fileInput.files[0]);
formData.append('description', 'Customer contact list');
formData.append('tags', JSON.stringify(['customers', 'contacts']));
const uploadResponse = await fetch('https://app.datapublisher.io/api/csv/upload', {
method: 'POST',
headers: {
'Authorization': Bearer ${jwtToken}
},
body: formData
});
const uploaded = await uploadResponse.json();
console.log('File uploaded:', uploaded.file.id);
// Get CSV data with pagination
const dataResponse = await fetch(
https://app.datapublisher.io/api/csv/${fileId}/data?limit=100&offset=0,
{
headers: {
'Authorization': Bearer ${jwtToken}
}
}
);
const csvData = await dataResponse.json();
console.log('Rows:', csvData.data.length);
// Get columns
const columnsResponse = await fetch(
https://app.datapublisher.io/api/csv/${fileId}/columns,
{
headers: {
'Authorization': Bearer ${jwtToken}
}
}
);
const columns = await columnsResponse.json();
console.log('Columns:', columns.columns);
import requests
API_URL = 'https://app.datapublisher.io/api/csv'
headers = {'Authorization': f'Bearer {jwt_token}'}
Upload CSV
with open('customers.csv', 'rb') as f:
files = {'csvFile': f}
data = {
'description': 'Customer contact list',
'tags': '["customers", "contacts"]'
}
response = requests.post(f'{API_URL}/upload', files=files, data=data, headers=headers)
uploaded = response.json()
file_id = uploaded['file']['id']
print(f"File uploaded: {file_id}")
Get CSV data with filtering
params = {
'limit': 100,
'offset': 0,
'filterColumn': 'Region',
'filterValue': 'West'
}
response = requests.get(f'{API_URL}/{file_id}/data', params=params, headers=headers)
csv_data = response.json()
print(f"Returned {len(csv_data['data'])} rows")
Get columns
response = requests.get(f'{API_URL}/{file_id}/columns', headers=headers)
columns = response.json()
print(f"Columns: {columns['columns']}")
Upload CSV
curl -X POST https://app.datapublisher.io/api/csv/upload \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-F "csvFile=@customers.csv" \
-F "description=Customer contact list" \
-F 'tags=["customers","contacts"]'
List files
curl -X GET "https://app.datapublisher.io/api/csv" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Get CSV data
curl -X GET "https://app.datapublisher.io/api/csv/FILE_ID/data?limit=100&offset=0" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Get columns
curl -X GET "https://app.datapublisher.io/api/csv/FILE_ID/columns" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
---
processing status with polling or webhooks
---
Valid CSV:
CustomerID,CompanyName,ContactEmail,TotalSales
1001,Acme Corp,contact@acme.com,45000
1002,TechStart Inc,info@techstart.com,32000
Requirements:
"Company, Inc."
---