Upload CSV Files
curl --request POST \
--url https://api.example.com/api/upload-csv \
--header 'Content-Type: application/json' \
--data '{}'import requests
url = "https://api.example.com/api/upload-csv"
payload = {}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({})
};
fetch('https://api.example.com/api/upload-csv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/upload-csv",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/upload-csv"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/upload-csv")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/upload-csv")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"type": "<string>",
"percentage": 123,
"message": "<string>",
"stats": {
"transactions_inserted": 123,
"realized_gains_lots": 123,
"broker_verified_trades": 123
}
}Data Import
Upload CSV Files
Upload and process transaction history and realized gains CSV files from brokerage
POST
/
api
/
upload-csv
Upload CSV Files
curl --request POST \
--url https://api.example.com/api/upload-csv \
--header 'Content-Type: application/json' \
--data '{}'import requests
url = "https://api.example.com/api/upload-csv"
payload = {}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({})
};
fetch('https://api.example.com/api/upload-csv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/upload-csv",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/upload-csv"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/upload-csv")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/upload-csv")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"type": "<string>",
"percentage": 123,
"message": "<string>",
"stats": {
"transactions_inserted": 123,
"realized_gains_lots": 123,
"broker_verified_trades": 123
}
}Endpoint
POST /api/upload-csv
Authentication
Requires OAuth 2.0 authentication and user must have brokerage account number set in profile.Content Type
multipart/form-data
Parameters
file
required
Transaction history CSV file from your brokerage
file
required
Realized gains/losses CSV file from your brokerage
Response Format
The endpoint returns streaming JSON responses to provide real-time progress updates:{"type": "progress", "percentage": 25, "message": "Starting data processing..."}
{"type": "progress", "percentage": 40, "message": "Processing transaction history and realized gains..."}
{"type": "progress", "percentage": 60, "message": "Synchronizing with database..."}
{"type": "progress", "percentage": 80, "message": "Finalizing data import..."}
{"type": "success", "message": "Successfully processed files", "stats": {"transactions_inserted": 279, "realized_gains_lots": 713, "broker_verified_trades": 156}}
Success Response Fields
string
Response type: “progress”, “success”, or “error”
number
Progress percentage (0-100) for progress type responses
string
Human-readable status message
object
Example
const formData = new FormData();
formData.append('transaction_history_file', transactionFile);
formData.append('realized_gains_file', gainsFile);
const response = await fetch('/api/upload-csv', {
method: 'POST',
body: formData
});
// Handle streaming response
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split('\n').filter(l => l.trim());
for (const line of lines) {
const data = JSON.parse(line);
if (data.type === 'progress') {
console.log(`Progress: ${data.percentage}% - ${data.message}`);
} else if (data.type === 'success') {
console.log('Upload complete!', data.stats);
} else if (data.type === 'error') {
console.error('Upload failed:', data.message);
}
}
}
import requests
files = {
'transaction_history_file': open('transactions.csv', 'rb'),
'realized_gains_file': open('gains.csv', 'rb')
}
response = requests.post(
'https://performance.miningwood.com/api/upload-csv',
files=files,
stream=True
)
for line in response.iter_lines():
if line:
data = json.loads(line)
if data['type'] == 'progress':
print(f"Progress: {data['percentage']}%")
elif data['type'] == 'success':
print("Upload successful!", data['stats'])
curl -X POST https://performance.miningwood.com/api/upload-csv \
-H "Cookie: session=your_session_cookie" \
-F "transaction_history_file=@transactions.csv" \
-F "realized_gains_file=@realized_gains.csv"
Error Responses
{"type": "error", "message": "Both files must be CSV files"}
400 Bad Request
{"type": "error", "message": "Brokerage account number not set. Please update your profile."}
400 Bad Request
{"type": "error", "message": "Both transaction history and realized gains files are required"}
400 Bad Request
CSV File Requirements
Transaction History File
Should include columns such as:- Transaction date
- Symbol
- Action (Buy, Sell, etc.)
- Quantity/Shares
- Price
- Amount
- Account number
Realized Gains File
Should include columns such as:- Symbol
- Date acquired
- Date sold
- Proceeds
- Cost basis
- Gain/Loss
File format requirements may vary by brokerage. The system attempts to automatically detect and parse common formats.
Related Endpoints
Upload History
View history of previous uploads
CSV Upload Feature
Learn more about CSV upload functionality
Was this page helpful?