C
Cotizera Docs

Settings

Settings API

Endpoints for managing tenant-level business configuration, including company info, tax settings, PDF branding, and logo.


Get Settings

GET /api/settings

Permission: config:manage (Owner only)

Retrieve the current tenant's settings. The logoUrl is returned as a presigned S3 URL (temporary, valid for a limited time).

Response 200 OK:

{
  "data": {
    "id": "clxyz...",
    "companyName": "Acme Solutions S.A. de C.V.",
    "email": "contacto@acme.mx",
    "phone": "+52 55 1234 5678",
    "address": "Av. Reforma 222, Col. Juárez, CDMX",
    "logoUrl": "https://s3.amazonaws.com/...presigned...",
    "bankInfo": {
      "bankName": "BBVA México",
      "clabe": "012345678901234567"
    },
    "defaultNotes": "Cotización válida por 15 días",
    "taxRate": "0.16",
    "quoteValidityDays": 15,
    "currency": "MXN",
    "pdfBranding": {
      "primaryColor": "#1A56DB",
      "accentColor": "#c96b3c",
      "fontFamily": "Helvetica",
      "headerLayout": "left",
      "footerText": "Gracias por su preferencia"
    },
    "reminderDaysBefore": 3
  }
}

Errors:

Status Error When
403 "Sin permisos" Role lacks config:manage
404 "Negocio no encontrado" Tenant not found

Update Settings

PUT /api/settings

Permission: config:manage (Owner only)

Update one or more tenant settings. All fields are optional — only include fields you want to change.

Request Body:

{
  "companyName": "Acme Solutions S.A. de C.V.",
  "phone": "+52 55 1234 5678",
  "email": "nuevo@acme.mx",
  "address": "Av. Reforma 222, Col. Juárez, CDMX",
  "taxRate": 0.16,
  "quoteValidityDays": 30,
  "currency": "MXN",
  "defaultNotes": "Precios sujetos a cambio sin previo aviso",
  "bankInfo": {
    "bankName": "BBVA México",
    "clabe": "012345678901234567"
  },
  "pdfBranding": {
    "primaryColor": "#1A56DB",
    "accentColor": "#c96b3c",
    "fontFamily": "Helvetica",
    "headerLayout": "left",
    "footerText": "Gracias por su preferencia"
  },
  "reminderDaysBefore": 5
}
Field Type Required Description
companyName string No Company name (min 2 characters)
phone string No Phone number
email string No Valid email
address string No Business address
taxRate number No Tax rate between 0 and 1 (e.g., 0.16 = 16%)
quoteValidityDays integer No Default quote validity in days (1–365)
currency string No 3-letter currency code (e.g., MXN, USD, COP)
defaultNotes string No Default notes for new quotes
bankInfo object | null No Bank details (bankName, clabe). Set to null to remove.
pdfBranding object | null No PDF styling options. Set to null to reset.
pdfBranding.primaryColor string No Hex color (e.g., #1A56DB)
pdfBranding.accentColor string No Hex color (e.g., #c96b3c)
pdfBranding.fontFamily string No Helvetica, Times, or Courier
pdfBranding.headerLayout string No left, center, or right
pdfBranding.footerText string No Footer text (max 200 characters)
reminderDaysBefore integer No Days before expiry to send reminder (1–30)

Response 200 OK:

{
  "data": { ...updated tenant settings... }
}

Side Effects:

  • Triggers onboarding step company_info completion
  • Logs audit entry with action update

Permission: config:manage (Owner only)

Upload a company logo via multipart form data. The image is stored in S3 and the tenant's logoUrl is updated.

Request: multipart/form-data

Field Type Required Description
logo File Yes Image file (PNG, JPG, WebP, or SVG). Max 2MB.

cURL Example:

curl -X POST "https://cotizera.com/api/settings/logo" \
  -H "Cookie: next-auth.session-token=YOUR_TOKEN" \
  -F "logo=@/path/to/logo.png"

Response 200 OK:

{
  "logoUrl": "https://s3.amazonaws.com/...presigned...",
  "s3Key": "logos/tenant-id/logo.png"
}

Errors:

Status Error When
400 "No se proporcionó un archivo" Missing logo field
400 "Tipo de archivo no permitido. Use PNG, JPG, WebP o SVG." Invalid file type
400 "El archivo excede el tamaño máximo de 2MB" File too large
© 2026 Cotizera. All rights reserved.