Skip to main content

Introduction

Torn is built on FastAPI, a modern, high-performance Python web framework. The API follows REST principles and provides comprehensive endpoints for managing electronic invoicing operations for SII Chile.

Base Information

Title
string
Torn - Facturador Electrónico
Description
string
Sistema de facturación electrónica para el SII de Chile
Version
string
0.1.0
Base URL
string
https://api.torn.cl (production) or http://localhost:8000 (development)

API Architecture

Multi-Tenant Design

Torn uses a multi-tenant SaaS architecture where:
  • Global Level: User authentication and tenant management
  • Tenant Level: Business operations (customers, products, sales, etc.)
  • Schema Isolation: Each tenant has a dedicated PostgreSQL schema for data isolation

Router Organization

The API is organized into functional routers defined in app/main.py:42:
# Global/SaaS Level
app.include_router(saas.router)      # Tenant management
app.include_router(auth.router)       # Authentication
app.include_router(health.router)     # Health checks

# Tenant-Scoped Resources
app.include_router(customers.router)   # Customer management
app.include_router(products.router)    # Product catalog
app.include_router(brands.router)      # Brand management
app.include_router(sales.router)       # Sales & invoicing
app.include_router(inventory.router)   # Inventory tracking
app.include_router(cash.router)        # Cash register
app.include_router(reports.router)     # Reports generation
app.include_router(providers.router)   # Supplier management
app.include_router(purchases.router)   # Purchase orders
app.include_router(stats.router)       # Statistics
app.include_router(users.router)       # User management
app.include_router(config.router)      # Configuration
app.include_router(roles.router)       # Role management
app.include_router(price_lists.router) # Price lists
app.include_router(folios.router)      # DTE folios
app.include_router(issuer.router)      # Issuer config

Common Patterns

Request Headers

All tenant-scoped endpoints require these headers:
Authorization: Bearer <access_token>
X-Tenant-Id: <tenant_id>
Content-Type: application/json
Global endpoints (like /auth/login) only require the Authorization header after initial login.

Response Format

All endpoints return JSON responses. Successful responses return the requested data directly:
{
  "id": 1,
  "name": "Example Resource",
  "created_at": "2026-03-08T10:30:00Z"
}
List endpoints return an array:
[
  {"id": 1, "name": "Resource 1"},
  {"id": 2, "name": "Resource 2"}
]

Pagination

While not universally implemented, endpoints that support pagination typically use query parameters:
GET /resources?skip=0&limit=100
Most list endpoints currently return all results. Pagination will be added to high-volume endpoints as needed.

Filtering

Search and filter endpoints use query parameters. Example from app/routers/customers.py:55:
GET /customers/search?q=ACME
Common filter patterns:
  • Text search: ?q=search_term
  • Date range: ?from_date=2026-01-01&to_date=2026-03-08
  • Status filter: ?is_active=true

Sorting

Results are typically sorted by a logical default field:
  • Customers: Alphabetically by razon_social
  • Products: By ID descending (newest first)
  • Sales: By date descending (newest first)

Standard HTTP Methods

The API follows REST conventions:
MethodPurposeExample
GETRetrieve resource(s)GET /customers
POSTCreate new resourcePOST /customers
PUTUpdate existing resourcePUT /customers/{id}
DELETEDelete resourceDELETE /customers/{id}

Error Handling

The API uses standard HTTP status codes and returns detailed error messages.

Success Codes

200 OK
status
Request successful, resource returned
201 Created
status
Resource successfully created
204 No Content
status
Resource successfully deleted

Error Codes

400 Bad Request
status
Invalid request data or parameters
401 Unauthorized
status
Missing or invalid authentication token
403 Forbidden
status
Authenticated but insufficient permissions
404 Not Found
status
Resource does not exist
409 Conflict
status
Resource conflict (e.g., duplicate RUT)
422 Unprocessable Entity
status
Validation error in request body
500 Internal Server Error
status
Server error

Error Response Format

Errors return a consistent structure:
{
  "detail": "Error message describing what went wrong"
}
Validation errors (422) provide detailed field information:
{
  "detail": [
    {
      "loc": ["body", "email"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

Example Error Handling

From app/routers/customers.py:32:
# 409 Conflict - Duplicate resource
existing = db.query(Customer).filter(Customer.rut == customer.rut).first()
if existing:
    raise HTTPException(
        status_code=status.HTTP_409_CONFLICT,
        detail=f"Ya existe un cliente con RUT {customer.rut}",
    )
From app/routers/customers.py:88:
# 404 Not Found - Resource doesn't exist
customer = db.query(Customer).filter(Customer.rut == rut).first()
if not customer:
    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail=f"No se encontró un cliente con RUT {rut}",
    )

CORS Configuration

The API is configured to accept requests from local development origins defined in app/main.py:19:
allow_origins=[
    "http://localhost:3000",
    "http://127.0.0.1:3000",
    "http://localhost:3001",
    "http://127.0.0.1:3001",
    "http://localhost:3002",
    "http://127.0.0.1:3002",
    "http://localhost:8000",
    "http://127.0.0.1:8000",
]
In production, configure CORS to only allow your application’s domain.

Resource Patterns

List Resources

Retrieve all resources of a type:
GET /customers
Authorization: Bearer <token>
X-Tenant-Id: 1

Get Single Resource

Retrieve a specific resource by identifier:
GET /customers/{rut}
Authorization: Bearer <token>
X-Tenant-Id: 1

Create Resource

Create a new resource:
POST /customers
Authorization: Bearer <token>
X-Tenant-Id: 1
Content-Type: application/json

{
  "rut": "12345678-9",
  "razon_social": "ACME Corp",
  "email": "[email protected]"
}

Update Resource

Update an existing resource (partial update):
PUT /customers/{rut}
Authorization: Bearer <token>
X-Tenant-Id: 1
Content-Type: application/json

{
  "email": "[email protected]",
  "razon_social": "ACME Corporation"
}
Updates are partial - only include fields you want to change.

Delete Resource

Delete a resource:
DELETE /customers/{rut}
Authorization: Bearer <token>
X-Tenant-Id: 1
Many resources use soft deletion (marked as deleted but not removed from database):
# From app/routers/products.py:234
product.is_deleted = True
product.is_active = False

Auto-Generation Features

Several resources support automatic ID/code generation:

Product SKU

From app/routers/products.py:24:
def generate_sku(db: Session, prefix: str = "PROD") -> str:
    """Genera un SKU único auto-incremental.
    
    Formato: PROD-00001, PROD-00002, etc.
    """
If you don’t provide a codigo_interno when creating a product, one is generated automatically.

EAN-13 Barcodes

From app/routers/products.py:49:
def generate_ean13(product_id: int) -> str:
    """Genera un código EAN-13 para uso interno.
    
    Usa el prefijo GS1 '200' (reservado para uso interno/in-store).
    Formato: 200 + 9 dígitos del ID (con padding) + 1 dígito verificador.
    """
Barcodes are auto-generated after product creation if not provided.

Interactive Documentation

FastAPI provides automatic interactive API documentation:
  • Swagger UI: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc
  • OpenAPI Schema: http://localhost:8000/openapi.json
These interfaces allow you to:
  • Explore all available endpoints
  • View request/response schemas
  • Test endpoints directly from the browser
  • See detailed validation rules

Health Check

Check API availability:
GET /health
Response:
{
  "status": "healthy",
  "timestamp": "2026-03-08T10:30:00Z"
}

Root Endpoint

Basic API info from app/main.py:68:
GET /
Response:
{
  "message": "Sistema Torn Online"
}

Next Steps

Authentication

Learn about JWT authentication and tenant access

Customers API

Manage customer records and contacts

Products API

Create and manage product catalog

Sales API

Generate invoices and sales documents

Build docs developers (and LLMs) love