# How Securo Handles Data Import and Export via API: A Complete Technical Guide

> Learn how Securo handles data import and export via API with its three-step workflow. Ensure safe, auditable bulk data operations using dedicated endpoints for transactions and assets.

- Repository: [securo-finance/securo](https://github.com/securo-finance/securo)
- Tags: how-to-guide
- Published: 2026-08-28

---

**Securo's FastAPI backend implements a three-step import/export workflow—template download, preview validation, and commit—that ensures safe, auditable bulk data operations through dedicated endpoints for transactions and assets.**

The Securo platform provides robust **data import and export via API** capabilities for financial records. Built on FastAPI, its architecture separates read-only validation from destructive writes, giving clients confidence before committing changes. This guide examines the implementation details, source files, and practical usage patterns drawn directly from the securo-finance/securo repository.

## Three-Step Import Workflow Design

Securo's **data import API** follows a consistent pattern across all entity types. The workflow protects production data by forcing explicit preview validation before any database mutation.

| Step | Endpoint Pattern | Purpose | Write Safety |
|------|----------------|---------|--------------|
| **Template** | `GET /api/{entity}/import/template` | Download CSV structure with headers and sample data | Read-only |
| **Preview** | `POST /api/{entity}/import/preview` | Validate payload, return row-level results without persisting | Read-only |
| **Commit** | `POST /api/{entity}/import` | Execute actual insert/update operations inside transaction | Writes enabled |

This design appears in both [`backend/app/api/import_transactions.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/import_transactions.py) and [`backend/app/api/assets.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/assets.py), ensuring uniform behavior regardless of data type.

## Core API Endpoints for Data Import

### Transaction Import Endpoints

The transaction router in [`backend/app/api/import_transactions.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/import_transactions.py) exposes the full import surface:

```python

# Conceptual router structure based on implementation patterns

router.get("/import/template")      # Returns CSV template

router.post("/import/preview")      # Dry-run validation

router.post("/import")              # Actual import execution

```

### Asset Import Endpoints

Asset imports mirror the transaction pattern in [`backend/app/api/assets.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/assets.py):

```python

# Parallel implementation for asset entities

router.get("/import/template")
router.post("/import/preview")
router.post("/import")

```

Both modules delegate to the shared `ImportService` class, eliminating code duplication and guaranteeing consistent validation logic.

## The ImportService: Central Processing Engine

Located at [`backend/app/services/import_service.py`](https://github.com/securo-finance/securo/blob/main/backend/app/services/import_service.py), the **ImportService** orchestrates all **data import and export via API** operations. It handles:

- **Format parsing**: CSV and JSON deserialization with configurable delimiters and encodings
- **Field validation**: Date formatting, numeric ranges, foreign key existence checks
- **Row mapping**: Transformation from flat import format to normalized SQLAlchemy models
- **Preview generation**: Construction of `ImportPreview` objects showing create/update/reject counts
- **Transactional writes**: ACID-guarded commit operations with rollback on failure

The service uses identical code paths for preview and commit phases, ensuring that validation results accurately predict commit behavior.

## Step-by-Step API Usage

### Step 1: Obtain Import Template

Download the canonical CSV structure to ensure column alignment:

```bash
curl -H "Authorization: Bearer ${SECURO_JWT}" \
     https://api.securo.finance/api/transactions/import/template \
     -o transaction_template.csv

```

The template endpoint in [`backend/app/api/import_transactions.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/import_transactions.py) generates headers dynamically from the `Transaction` model definition, guaranteeing schema currency.

### Step 2: Preview Before Committing

Validate your data without side effects:

```bash
curl -X POST \
     -H "Authorization: Bearer ${SECURO_JWT}" \
     -H "Content-Type: text/csv" \
     --data-binary @populated_transactions.csv \
     https://api.securo.finance/api/transactions/import/preview

```

Example response structure:

```json
{
  "imported": 25,
  "updated": 0,
  "rejected": 3,
  "errors": [
    {"row": 14, "field": "date", "message": "Invalid date format"},
    {"row": 18, "field": "amount", "message": "Negative amount not allowed"}
  ]
}

```

The preview endpoint is tested in [`backend/tests/test_write_permission_gate.py`](https://github.com/securo-finance/securo/blob/main/backend/tests/test_write_permission_gate.py) to verify zero database mutations occur during this phase.

### Step 3: Execute Import

After preview approval, trigger persistent changes:

```bash
curl -X POST \
     -H "Authorization: Bearer ${SECURO_JWT}" \
     -H "Content-Type: text/csv" \
     --data-binary @populated_transactions.csv \
     https://api.securo.finance/api/transactions/import

```

Success response includes audit reference:

```json
{
  "import_log_id": "2f9c8e12-5b4a-4b9d-9a37-1c2e5d8f7a1d",
  "imported": 25,
  "updated": 0,
  "rejected": 0
}

```

## Security and Permission Architecture

### Authentication and Authorization

All **data import and export via API** endpoints require valid JWT authentication. The permission model distinguishes:

- **Preview access**: Granted to users with read permissions on the target entity
- **Commit access**: Restricted to users with explicit write permissions

This enforcement occurs through FastAPI dependency injection in [`backend/app/api/import_transactions.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/import_transactions.py) and [`backend/app/api/assets.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/assets.py).

### Audit Logging

Every successful import creates an `ImportLog` record defined in [`backend/app/models/import_log.py`](https://github.com/securo-finance/securo/blob/main/backend/app/models/import_log.py). The log captures:

- Original filename and checksum
- Row counts (processed, created, updated, rejected)
- Validation warnings
- Timestamp and user attribution
- Reference to import batch for reconciliation

Retrieve logs via:

```bash
curl -H "Authorization: Bearer ${SECURO_JWT}" \
     https://api.securo.finance/api/imports/${IMPORT_LOG_ID}

```

## Testing and Quality Assurance

The repository includes comprehensive test coverage for import functionality:

| Test File | Purpose |
|-----------|---------|
| [`backend/tests/test_import_api.py`](https://github.com/securo-finance/securo/blob/main/backend/tests/test_import_api.py) | End-to-end validation of preview and commit workflows |
| [`backend/tests/test_write_permission_gate.py`](https://github.com/securo-finance/securo/blob/main/backend/tests/test_write_permission_gate.py) | Verifies preview endpoints never perform writes |

These tests assert that `ImportService.preview()` and `ImportService.import_data()` produce identical validation results while differing only in persistence behavior.

## Summary

Securo's **data import and export via API** implementation prioritizes safety and auditability through:

- **Unified ImportService** ([`backend/app/services/import_service.py`](https://github.com/securo-finance/securo/blob/main/backend/app/services/import_service.py)) providing consistent parsing and validation
- **Three-phase workflow** (template → preview → commit) preventing accidental data corruption
- **Strict permission separation** between read-only preview and destructive commit operations
- **Comprehensive audit logging** via `ImportLog` model for regulatory compliance
- **Shared endpoint patterns** across transactions ([`backend/app/api/import_transactions.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/import_transactions.py)) and assets ([`backend/app/api/assets.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/assets.py))

## Frequently Asked Questions

### What file formats does Securo's import API support?

Securo accepts **CSV and JSON** payloads for import operations. The `ImportService` in [`backend/app/services/import_service.py`](https://github.com/securo-finance/securo/blob/main/backend/app/services/import_service.py) detects format from Content-Type headers and applies appropriate parsers. CSV is recommended for bulk operations due to streaming efficiency with large datasets.

### Why does Securo require a preview step before importing?

The preview endpoint provides **dry-run validation** that surfaces row-level errors without database mutation. As enforced by tests in [`backend/tests/test_write_permission_gate.py`](https://github.com/securo-finance/securo/blob/main/backend/tests/test_write_permission_gate.py), this design allows clients to fix data issues before attempting actual commits, preventing partial imports and data inconsistency.

### How does Securo handle import failures during commit?

The commit endpoint in [`backend/app/api/import_transactions.py`](https://github.com/securo-finance/securo/blob/main/backend/app/api/import_transactions.py) wraps import operations in database transactions. If any row fails validation during the commit phase—after passing preview—the entire batch rolls back. This atomic behavior ensures the database remains consistent, with error details returned to the caller for remediation.