API Documentation

Complete guide to SSU Methods Transfer Analysis API

Version 1.0
# Upload CSV file
curl -X POST "http://service.ssumethods.com/api/csv-upload" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -F "csv_file=@/path/to/your/transfers.csv" \
  -F "description=Monthly transfer data"
// Upload CSV file function
const uploadCSV = async (file, description = '') => {
  try {
    const token = localStorage.getItem('api_token');
    
    if (!token) {
      throw new Error('No authentication token found');
    }

    const formData = new FormData();
    formData.append('csv_file', file);
    if (description) {
      formData.append('description', description);
    }

    const response = await fetch('http://service.ssumethods.com/api/csv-upload', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Accept': 'application/json'
        // Note: Don't set Content-Type for FormData, browser will set it automatically
      },
      body: formData
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log('Upload successful:', data);
    return data;
  } catch (error) {
    console.error('Upload error:', error);
    throw error;
  }
};

// Usage with file input
const handleFileUpload = (event) => {
  const file = event.target.files[0];
  if (file && file.type === 'text/csv') {
    uploadCSV(file, 'Uploaded via web interface')
      .then(result => {
        console.log('File uploaded successfully:', result);
      })
      .catch(error => {
        console.error('Upload failed:', error);
      });
  } else {
    console.error('Please select a CSV file');
  }
};

// Example usage
document.getElementById('csvFile').addEventListener('change', handleFileUpload);
import requests
import os
from typing import Optional, Dict, Any

class CSVUploadAPI:
    def __init__(self, base_url: str, token: str):
        self.base_url = base_url
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {token}',
            'Accept': 'application/json'
        })
    
    def upload_csv(self, file_path: str, description: Optional[str] = None) -> Dict[str, Any]:
        """Upload a CSV file to the API"""
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"File not found: {file_path}")
        
        if not file_path.lower().endswith('.csv'):
            raise ValueError("File must have .csv extension")
        
        try:
            with open(file_path, 'rb') as file:
                files = {
                    'csv_file': (os.path.basename(file_path), file, 'text/csv')
                }
                
                data = {}
                if description:
                    data['description'] = description
                
                response = self.session.post(
                    f'{self.base_url}/api/csv-upload',
                    files=files,
                    data=data,
                    timeout=60  # Longer timeout for file uploads
                )
                response.raise_for_status()
                
                return response.json()
        
        except requests.exceptions.RequestException as e:
            print(f"Upload error: {e}")
            raise
        except Exception as e:
            print(f"Unexpected error: {e}")
            raise

# Usage example
try:
    # Initialize API client with your token
    api = CSVUploadAPI('http://service.ssumethods.com', 'your_access_token_here')
    
    # Upload CSV file
    result = api.upload_csv(
        file_path='/path/to/your/transfers.csv',
        description='Monthly transfer data'
    )
    
    print("Upload successful!")
    print(f"Upload ID: {result['upload_id']}")
    print(f"Rows processed: {result['rows_processed']}")
    print(f"File size: {result['file_size']}")

except FileNotFoundError as e:
    print(f"File error: {e}")
except ValueError as e:
    print(f"Validation error: {e}")
except Exception as e:
    print(f"Upload failed: {e}")
<?php

class CSVUploadAPI {
    private $baseUrl;
    private $token;
    
    public function __construct($baseUrl, $token) {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->token = $token;
    }
    
    public function uploadCSV($filePath, $description = '') {
        if (!file_exists($filePath)) {
            throw new Exception("File not found: " . $filePath);
        }
        
        if (pathinfo($filePath, PATHINFO_EXTENSION) !== 'csv') {
            throw new Exception("File must be a CSV file");
        }
        
        $url = $this->baseUrl . '/api/csv-upload';
        
        $headers = [
            'Authorization: Bearer ' . $this->token,
            'Accept: application/json'
        ];
        
        $postFields = [
            'csv_file' => new CURLFile($filePath, 'text/csv', basename($filePath))
        ];
        
        if (!empty($description)) {
            $postFields['description'] = $description;
        }
        
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $postFields,
            CURLOPT_TIMEOUT => 60,
            CURLOPT_SSL_VERIFYPEER => false
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }
        
        $decodedResponse = json_decode($response, true);
        
        if ($httpCode >= 400) {
            $message = isset($decodedResponse['message']) ? $decodedResponse['message'] : 'Unknown error';
            throw new Exception("HTTP Error $httpCode: " . $message);
        }
        
        return $decodedResponse;
    }
}

// Usage example
try {
    $api = new CSVUploadAPI('http://service.ssumethods.com', 'your_access_token_here');
    
    $result = $api->uploadCSV(
        '/path/to/your/transfers.csv',
        'Monthly transfer data'
    );
    
    echo "Upload successful!\n";
    echo "Upload ID: " . $result['upload_id'] . "\n";
    echo "Rows processed: " . $result['rows_processed'] . "\n";
    echo "File size: " . $result['file_size'] . "\n";
    
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

?>
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.time.Duration;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;

public class CSVUploadAPI {
    private final String baseUrl;
    private final String token;
    private final HttpClient httpClient;
    private final ObjectMapper objectMapper;
    
    public CSVUploadAPI(String baseUrl, String token) {
        this.baseUrl = baseUrl.replaceAll("/$", "");
        this.token = token;
        this.httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(30))
            .build();
        this.objectMapper = new ObjectMapper();
    }
    
    public JsonNode uploadCSV(String filePath, String description) throws IOException, InterruptedException {
        File file = new File(filePath);
        
        if (!file.exists()) {
            throw new IOException("File not found: " + filePath);
        }
        
        if (!filePath.toLowerCase().endsWith(".csv")) {
            throw new IllegalArgumentException("File must be a CSV file");
        }
        
        // Create multipart form data
        String boundary = "----CSVUploadBoundary" + System.currentTimeMillis();
        String multipartBody = createMultipartBody(file, description, boundary);
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(this.baseUrl + "/api/csv-upload"))
            .header("Authorization", "Bearer " + this.token)
            .header("Accept", "application/json")
            .header("Content-Type", "multipart/form-data; boundary=" + boundary)
            .POST(HttpRequest.BodyPublishers.ofString(multipartBody))
            .timeout(Duration.ofSeconds(60))
            .build();
        
        HttpResponse<String> response = httpClient.send(
            request, 
            HttpResponse.BodyHandlers.ofString()
        );
        
        if (response.statusCode() != 200) {
            throw new RuntimeException("Upload failed with HTTP " + response.statusCode() + 
                                     ": " + response.body());
        }
        
        return objectMapper.readTree(response.body());
    }
    
    private String createMultipartBody(File file, String description, String boundary) throws IOException {
        StringBuilder body = new StringBuilder();
        
        // Add CSV file
        body.append("--").append(boundary).append("\r\n");
        body.append("Content-Disposition: form-data; name=\"csv_file\"; filename=\"")
            .append(file.getName()).append("\"\r\n");
        body.append("Content-Type: text/csv\r\n\r\n");
        body.append(Files.readString(file.toPath()));
        body.append("\r\n");
        
        // Add description if provided
        if (description != null && !description.isEmpty()) {
            body.append("--").append(boundary).append("\r\n");
            body.append("Content-Disposition: form-data; name=\"description\"\r\n\r\n");
            body.append(description);
            body.append("\r\n");
        }
        
        body.append("--").append(boundary).append("--\r\n");
        
        return body.toString();
    }
    
    public static void main(String[] args) {
        try {
            CSVUploadAPI api = new CSVUploadAPI(
                "http://service.ssumethods.com", 
                "your_access_token_here"
            );
            
            JsonNode result = api.uploadCSV(
                "/path/to/your/transfers.csv",
                "Monthly transfer data"
            );
            
            System.out.println("Upload successful!");
            System.out.println("Upload ID: " + result.get("upload_id").asText());
            System.out.println("Rows processed: " + result.get("rows_processed").asInt());
            System.out.println("File size: " + result.get("file_size").asText());
            
        } catch (Exception e) {
            System.err.println("Upload failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "os"
    "path/filepath"
    "strings"
    "time"
)

type CSVUploadAPI struct {
    BaseURL string
    Token   string
    Client  *http.Client
}

type UploadResponse struct {
    Message       string `json:"message"`
    UploadID      string `json:"upload_id"`
    FileName      string `json:"file_name"`
    FileSize      string `json:"file_size"`
    RowsProcessed int    `json:"rows_processed"`
    UploadDate    string `json:"upload_date"`
    Status        string `json:"status"`
}

func NewCSVUploadAPI(baseURL, token string) *CSVUploadAPI {
    return &CSVUploadAPI{
        BaseURL: strings.TrimSuffix(baseURL, "/"),
        Token:   token,
        Client: &http.Client{
            Timeout: 60 * time.Second,
        },
    }
}

func (api *CSVUploadAPI) UploadCSV(filePath, description string) (*UploadResponse, error) {
    // Check if file exists and is CSV
    if _, err := os.Stat(filePath); os.IsNotExist(err) {
        return nil, fmt.Errorf("file not found: %s", filePath)
    }
    
    if !strings.HasSuffix(strings.ToLower(filePath), ".csv") {
        return nil, fmt.Errorf("file must be a CSV file")
    }
    
    // Create multipart form
    var buf bytes.Buffer
    writer := multipart.NewWriter(&buf)
    
    // Add CSV file
    file, err := os.Open(filePath)
    if err != nil {
        return nil, fmt.Errorf("opening file: %w", err)
    }
    defer file.Close()
    
    part, err := writer.CreateFormFile("csv_file", filepath.Base(filePath))
    if err != nil {
        return nil, fmt.Errorf("creating form file: %w", err)
    }
    
    if _, err := io.Copy(part, file); err != nil {
        return nil, fmt.Errorf("copying file content: %w", err)
    }
    
    // Add description if provided
    if description != "" {
        if err := writer.WriteField("description", description); err != nil {
            return nil, fmt.Errorf("writing description field: %w", err)
        }
    }
    
    if err := writer.Close(); err != nil {
        return nil, fmt.Errorf("closing multipart writer: %w", err)
    }
    
    // Create request
    req, err := http.NewRequest("POST", api.BaseURL+"/api/csv-upload", &buf)
    if err != nil {
        return nil, fmt.Errorf("creating request: %w", err)
    }
    
    req.Header.Set("Authorization", "Bearer "+api.Token)
    req.Header.Set("Accept", "application/json")
    req.Header.Set("Content-Type", writer.FormDataContentType())
    
    // Send request
    resp, err := api.Client.Do(req)
    if err != nil {
        return nil, fmt.Errorf("making request: %w", err)
    }
    defer resp.Body.Close()
    
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("reading response: %w", err)
    }
    
    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("upload failed with status %d: %s", resp.StatusCode, string(body))
    }
    
    var uploadResp UploadResponse
    if err := json.Unmarshal(body, &uploadResp); err != nil {
        return nil, fmt.Errorf("parsing response: %w", err)
    }
    
    return &uploadResp, nil
}

func main() {
    api := NewCSVUploadAPI("http://service.ssumethods.com", "your_access_token_here")
    
    result, err := api.UploadCSV("/path/to/your/transfers.csv", "Monthly transfer data")
    if err != nil {
        fmt.Printf("Upload error: %v\n", err)
        return
    }
    
    fmt.Println("Upload successful!")
    fmt.Printf("Upload ID: %s\n", result.UploadID)
    fmt.Printf("Rows processed: %d\n", result.RowsProcessed)
    fmt.Printf("File size: %s\n", result.FileSize)
}