Pydantic Schemas Used in Securo API for Validation: Complete Reference Guide

The Securo API uses over 20 purpose-built Pydantic schemas located in backend/app/schemas/ to validate requests and serialize responses across user management, transactions, workspaces, assets, and financial data domains.

Securo Finance's backend architecture relies extensively on Pydantic for runtime data validation and API documentation generation. Every incoming request body passes through a strictly typed schema before reaching business logic, ensuring type safety and automatic OpenAPI schema generation. This article maps every validation schema in the codebase, tracing their file locations, dependencies, and usage patterns in FastAPI routes.


Core Schema Architecture

The Securo project organizes Pydantic models hierarchically under backend/app/schemas/. Each domain receives its own module, following single-responsibility principles for maintainable validation logic.


backend/app/schemas/
├── __init__.py
├── workspace.py
├── user.py
├── two_factor.py
├── passkey.py
├── account.py
├── transaction.py
├── transaction_split.py
├── transaction_calendar.py
├── recurring_transaction.py
├── transaction_group_settlement.py
├── payee.py
├── category.py
├── category_group.py
├── budget.py
├── goal.py
├── asset.py
├── asset_group.py
├── asset_import.py
├── bank_connection.py
├── attachment.py
├── export.py
├── import_log.py
├── admin.py
├── rule.py
├── report.py
├── dashboard.py
└── collection.py

All schemas inherit from pydantic.BaseModel and leverage Pydantic v2 features including field_validator, model_validator, and ConfigDict for strict type enforcement.


User Authentication & Security Schemas

Securo handles sensitive financial data, requiring robust validation for authentication flows, multi-factor authentication, and modern passkey credentials.

User Schema (backend/app/schemas/user.py)

The foundational identity model validates user registration, profile updates, and public user representations. It typically includes:

  • email: EmailStr with DNS validation
  • password: SecretStr for write operations, excluded from responses
  • full_name: constrained str with length limits
  • is_active, is_verified: boolean flags for account state

# backend/app/schemas/user.py

from pydantic import BaseModel, EmailStr, Field, SecretStr

class UserBase(BaseModel):
    email: EmailStr
    full_name: str = Field(..., min_length=1, max_length=128)

class UserCreate(UserBase):
    password: SecretStr = Field(..., min_length=12)

class User(UserBase):
    id: int
    is_active: bool
    is_verified: bool

    model_config = {"from_attributes": True}

Two-Factor Authentication (backend/app/schemas/two_factor.py)

Validates TOTP enrollment, backup code generation, and verification requests. Critical fields include totp_secret, backup_codes, and verified_at timestamps.

Passkey Schema (backend/app/schemas/passkey.py)

Supports WebAuthn credential registration and authentication with fields for credential_id, public_key, sign_count, and device attestation metadata.


Workspace & Account Management Schemas

Financial applications require strict isolation between organizational boundaries. Securo implements this through workspace-scoped validation.

Workspace Schema (backend/app/schemas/workspace.py)

Validates organizational creation, billing tier selection, and member invitation flows. Key fields:

  • name: unique workspace identifier
  • slug: URL-safe normalized name
  • billing_tier: enum-constrained subscription level
  • fiscal_year_start: month-day pair for reporting cycles

Account Schema (backend/app/schemas/account.py)

Represents financial accounts within a workspace, validating:

  • institution_name: connected bank or manual entry
  • account_type: checking, savings, credit, investment enum
  • currency_code: ISO 4217 three-letter code with custom validator
  • initial_balance: Decimal precision for monetary values
  • connection_id: optional foreign key to BankConnection

Transaction Validation Schemas

The transaction domain contains the most complex validation logic, with six specialized schemas handling different financial record types.

Base Transaction Schema (backend/app/schemas/transaction.py)

Core model for single financial transactions with extensive custom validators:


# backend/app/schemas/transaction.py

from datetime import datetime
from decimal import Decimal
from pydantic import BaseModel, field_validator, Field

class Transaction(BaseModel):
    amount: Decimal = Field(..., decimal_places=2, max_digits=15)
    currency: str = Field(..., min_length=3, max_length=3)
    description: str = Field(..., max_length=512)
    posted_at: datetime
    category_id: int | None = None
    payee_id: int | None = None

    @field_validator("currency")
    @classmethod
    def validate_supported_currency(cls, v: str) -> str:
        supported = {"USD", "BRL", "EUR", "GBP", "JPY", "CAD"}
        if v.upper() not in supported:
            raise ValueError(f"Currency {v} not supported. Use: {', '.join(sorted(supported))}")
        return v.upper()

    @field_validator("amount")
    @classmethod
    def validate_non_zero(cls, v: Decimal) -> Decimal:
        if v == 0:
            raise ValueError("Transaction amount cannot be zero")
        return v

Transaction Split Schema (backend/app/schemas/transaction_split.py)

Validates division of single transactions across multiple categories or payees. Enforces that split percentages sum to 100% or split amounts sum to parent transaction total via model_validator.

Transaction Calendar Schema (backend/app/schemas/transaction_calendar.py)

Schedules future or recurring transactions with fields for frequency (daily, weekly, monthly, yearly), interval multiplier, occurrences limit, and end_date termination.

Recurring Transaction Schema (backend/app/schemas/recurring_transaction.py)

Similar to calendar schema but for automatically generated transactions, including next_occurrence prediction and last_generated tracking.

Transaction Group Settlement (backend/app/schemas/transaction_group_settlement.py)

Validates multi-party settlement workflows for shared expenses, tracking payer_splits, ower_splits, and settlement status.


Classification & Budgeting Schemas

Financial organization requires structured categorization and goal tracking.

Category & CategoryGroup Schemas (backend/app/schemas/category.py, backend/app/schemas/category_group.py)

  • Category: Individual classification with name, color, icon, parent_id for hierarchies, and is_system flag for protected categories
  • CategoryGroup: Container for related categories with sort_order and budget rollup configuration

Budget Schema (backend/app/schemas/budget.py)

Validates spending limits with period-aware validation:

  • amount: periodic spending ceiling
  • period: enum of weekly, monthly, quarterly, yearly
  • category_ids or category_group_ids: scope specification
  • rollover_enabled: boolean for unused amount carryover

Goal Schema (backend/app/schemas/goal.py)

Tracks financial targets with target_amount, current_amount, deadline, and goal_type (savings, debt reduction, purchase target). Includes progress calculation validators.


Asset Management Schemas

Investment and physical asset tracking uses nested validation for complex portfolio structures.

Asset Schema (backend/app/schemas/asset.py)

Validates individual holdings:

  • asset_class: equity, fixed_income, real_estate, commodity, crypto enum
  • symbol: ticker or identifier with format validation per asset class
  • quantity: Decimal with precision appropriate to asset type
  • cost_basis: purchase price tracking for gain/loss calculation
  • current_price: optional live price with last_price_update timestamp

AssetGroup Schema (backend/app/schemas/asset_group.py)

Portfolio-level validation with allocation_targets dictionary mapping asset classes to target percentages, enforced by model_validator summing to 100%.

AssetImport Schema (backend/app/schemas/asset_import.py)

Validates bulk import operations from CSV brokerage files, including column mapping validation and duplicate detection rules.


Financial Connection Schemas

Third-party integrations require specialized validation for credentials and connection state.

BankConnection Schema (backend/app/schemas/bank_connection.py)

Validates open banking and screen-scraping connections:

  • provider_id: supported institution identifier
  • connection_type: oauth, credentials, api_key enum
  • credentials: SecretStr fields conditionally required by type
  • sync_frequency: timedelta with minimum bounds
  • last_sync_at, last_sync_status: operational metadata

Auxiliary Schemas

Supporting functionality validates file attachments, data exports, and administrative operations.

Attachment Schema (backend/app/schemas/attachment.py)

Validates file metadata with content-type restriction and size limits:

  • filename: sanitized string with extension validation
  • content_type: allowlist of image/*, application/pdf, text/csv
  • size_bytes: maximum 10MB default
  • checksum: SHA-256 for integrity verification

Export Schema (backend/app/schemas/export.py)

Validates data export requests with format (CSV, JSON, OFX, QIF), date_range bounds, included_accounts, and include_attachments flag.

ImportLog Schema (backend/app/schemas/import_log.py)

Tracks asynchronous import job status with source_type, file_checksum, records_processed, records_failed, and error_details array.

Admin Schema (backend/app/schemas/admin.py)

Validates privileged operations with enhanced secret handling. Uses SecretStr for sensitive configuration and includes audit_reason fields for compliance logging.

Rule Schema (backend/app/schemas/rule.py)

Validates automated transaction categorization with conditions (field, operator, value triples) and actions (set_category, set_payee, flag_for_review).

Report, Dashboard, Collection Schemas

  • Report: Scheduled or on-demand analytics with metric_selections, grouping_dimensions, filter_criteria
  • Dashboard: Widget layout validation with position coordinates and refresh intervals
  • Collection: Saved filter combinations for quick data access

Integration with FastAPI Routes

Pydantic schemas integrate directly into route definitions for automatic validation and documentation:


# backend/app/api/payees.py

from fastapi import APIRouter, Depends
from app.schemas.payee import Payee, PayeeCreate
from app.api.dependencies import get_current_user, get_db_session

router = APIRouter(prefix="/payees", tags=["payees"])

@router.post("/", response_model=Payee, status_code=201)
async def create_payee(
    payee: PayeeCreate,  # ← Pydantic validation applied automatically

    session=Depends(get_db_session),
    current_user=Depends(get_current_user)
):
    """Create a new payee with validated tax ID and source information."""
    return await payee_service.create(session, current_user.workspace_id, payee)

The PayeeCreate schema validates incoming JSON, returning 422 Unprocessable Entity for type mismatches or validation failures before the service layer executes.


Configuration via Pydantic-Settings

Beyond request validation, Securo uses pydantic-settings for environment-based configuration in backend/app/core/config.py:


# backend/app/core/config.py

from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import SecretStr, PostgresDsn, RedisDsn

class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env", extra="ignore")
    
    DATABASE_URL: PostgresDsn
    REDIS_URL: RedisDsn
    SECRET_KEY: SecretStr
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
    SUPPORTED_CURRENCIES: list[str] = ["USD", "BRL", "EUR"]
    
    @property
    def async_database_url(self) -> str:
        return str(self.DATABASE_URL).replace("postgresql://", "postgresql+asyncpg://")

settings = Settings()

This pattern separates runtime configuration (secrets, URLs) from request validation schemas while maintaining Pydantic's validation guarantees.


Summary

  • 20+ specialized schemas in backend/app/schemas/ cover all API validation needs
  • Hierarchical organization by domain (user, transaction, asset, etc.) enables maintainable code
  • Pydantic v2 features employed: field_validator, model_validator, ConfigDict, SecretStr
  • Custom validators enforce business rules like currency support, split totaling, and allocation balancing
  • FastAPI integration provides automatic request validation, serialization, and OpenAPI documentation
  • Pydantic-Settings handles environment configuration with identical validation rigor

Frequently Asked Questions

How does Securo ensure currency values are validated correctly?

The base Transaction schema in backend/app/schemas/transaction.py implements a @field_validator("currency") that checks against a supported set of ISO 4217 codes. Invalid currencies trigger a descriptive error listing all supported options. Monetary amounts use Decimal with explicit decimal_places=2 to prevent floating-point errors.

What prevents split transactions from having invalid totals?

The TransactionSplit schema in backend/app/schemas/transaction_split.py uses a @model_validator(mode="after") that executes after individual field validation. This validator sums all split amounts or percentages and compares against the parent transaction total, raising ValueError if the difference exceeds a configurable epsilon.

Are password hashes exposed in API responses?

No. The User schema hierarchy separates UserCreate (input, contains SecretStr password) from User (response model). The response model never includes password fields. Additionally, SecretStr automatically masks values in logs and serialization, and model_config = {"from_attributes": True} ensures proper ORM mapping without accidental field leakage.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →