Skip to main content
The Sales endpoints let you retrieve your full transaction history from SmartPyme — including individual line items, customer details, and payment information — and create or update sales from external systems such as e-commerce sites, marketplaces, or POS integrations. Use them to build reporting dashboards, sync transactions bidirectionally, audit completed and pending records, or generate quotations programmatically. All requests must include your API key in the Authorization header.

GET /sales

Returns a paginated list of sales records. Apply query parameters to narrow results by date range, status, or sort order. Each record in the response includes the full sale object with its associated detalles line items.
curl --request GET \
  --url "https://api.smartpyme.site/api/external/v1/sales?fecha_inicio=2025-01-01&fecha_fin=2025-01-31&estado=Completada&per_page=50" \
  --header "Authorization: Bearer {api_key}"

Query parameters

fecha_inicio
string
Start date for filtering sales, in Y-m-d format (e.g. 2025-01-01). Used together with fecha_fin to define a date range.
fecha_fin
string
End date for filtering sales, in Y-m-d format (e.g. 2025-01-31). Used together with fecha_inicio to define a date range.
estado
string
Filter by sale status. Accepted values: Completada, Pendiente, Anulada, Cotizacion.
page
integer
Page number to retrieve. Defaults to 1.
per_page
integer
Number of records per page. Accepts values between 1 and 200. Defaults to 100.
order_by
string
Field to sort results by. Accepted values: fecha, total, correlativo, created_at.
order_direction
string
Sort direction. Accepted values: asc, desc.

Response example

{
  "success": true,
  "data": [
    {
      "id": 10421,
      "fecha": "2025-01-15",
      "correlativo": "FAC-002501",
      "estado": "Completada",
      "forma_pago": "Efectivo",
      "monto_pago": 200.00,
      "cambio": 20.00,
      "iva_percibido": 16.25,
      "iva_retenido": 0.00,
      "renta_retenida": 0.00,
      "iva": 16.25,
      "total_costo": 120.00,
      "descuento": 10.00,
      "sub_total": 163.75,
      "no_sujeta": 0.00,
      "exenta": 0.00,
      "gravada": 163.75,
      "cuenta_a_terceros": 0.00,
      "total": 180.00,
      "propina": 0.00,
      "observaciones": "Entrega en tienda",
      "recurrente": false,
      "cotizacion": false,
      "saldo": 0.00,
      "nombre_cliente": "María López",
      "nombre_usuario": "admin",
      "nombre_vendedor": "Carlos Díaz",
      "nombre_sucursal": "Sucursal Central",
      "nombre_canal": "Mostrador",
      "nombre_documento": "Factura",
      "created_at": "2025-01-15T10:35:00Z",
      "updated_at": "2025-01-15T10:35:00Z",
      "detalles": [
        {
          "nombre_producto": "Laptop Dell Inspiron 15",
          "codigo_producto": "LAP-DELL-015",
          "marca_producto": "Dell",
          "cantidad": 1,
          "precio": 163.75,
          "costo": 120.00,
          "descuento": 10.00,
          "total_costo": 120.00,
          "total": 163.75,
          "iva": 16.25
        }
      ]
    }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 50,
    "total": 120,
    "total_pages": 3,
    "has_next": true,
    "has_prev": false
  },
  "meta": {
    "empresa": "Mi Empresa S.A.",
    "timestamp": "2025-01-31T15:00:00Z",
    "filters_applied": {
      "fecha_inicio": "2025-01-01",
      "fecha_fin": "2025-01-31",
      "estado": "Completada"
    }
  }
}

Response fields

success
boolean
Indicates whether the request completed successfully.
data
array
Array of sale objects matching the applied filters.

POST /sales

Creates and processes a sale through the same invoicing logic the SmartPyme UI uses. Use this endpoint to push transactions into SmartPyme from external POS, e-commerce, or marketplace systems, or to generate quotations programmatically. The endpoint runs the full business pipeline — stock movements, tax breakdown, document correlatives, and document of sale generation — so the sale you create here is indistinguishable from one entered manually in the app.

When to use it

  • A confirmed sale needs to be registered immediately and marked as paid (Pagada or Completada).
  • A pending sale needs to be opened and finalized later from the SmartPyme UI (Pendiente).
  • A quotation needs to be created from an external quoting tool (Cotizacion).

Idempotency

Pass an external identifier through referencia_externa (or referencia) to make the request idempotent. If a sale with the same referencia already exists for your company, the API returns the existing record with HTTP 200 and meta.idempotent: true instead of creating a duplicate. New sales return HTTP 201. Always set this field when retrying requests or syncing from systems that may resend the same transaction.
curl --request POST \
  --url "https://api.smartpyme.site/api/external/v1/sales" \
  --header "Authorization: Bearer {api_key}" \
  --header "Content-Type: application/json" \
  --data '{
    "referencia_externa": "ORDER-9001",
    "fecha": "2025-01-15",
    "estado": "Pagada",
    "id_sucursal": 3,
    "id_bodega": 7,
    "id_documento": 12,
    "id_canal": 2,
    "id_cliente": 45,
    "forma_pago": "Efectivo",
    "monto_pago": 180.00,
    "cambio": 20.00,
    "observaciones": "Pedido web",
    "detalles": [
      {
        "id_producto": 312,
        "cantidad": 1,
        "precio": 163.75,
        "descuento": 10.00,
        "porcentaje_impuesto": 13
      }
    ]
  }'

Body parameters

referencia_externa
string
External identifier from your system. When provided, the endpoint becomes idempotent for this value (see Idempotency). Alias: referencia. Maximum 255 characters.
fecha
string
required
Sale date, in Y-m-d format (e.g. 2025-01-15).
estado
string
required
Initial state of the sale. Accepted values: Pagada, Completada, Pendiente, Cotizacion. Use Pendiente for sales that will be finalized later; Pendiente requires id_cliente. Cotizacion creates a quotation rather than a confirmed sale.
id_sucursal
integer
Branch identifier. Required if sucursal is not provided.
sucursal
string
Branch name. Resolved server-side to the matching id_sucursal. Required if id_sucursal is not provided.
id_bodega
integer
required
Warehouse identifier that stock movements will be applied to. Must belong to your company.
id_documento
integer
required
Sales document type identifier (e.g. invoice, ticket). The correlativo is taken from this document.
id_canal
integer
Sales channel identifier (e.g. counter, online). Required unless estado is Cotizacion.
id_cliente
integer
Customer identifier. Required when estado is Pendiente. Optional for other states.
forma_pago
string
Payment method (e.g. Efectivo, Tarjeta, Transferencia). Defaults to Efectivo. Maximum 100 characters.
monto_pago
number
Amount tendered by the customer. Defaults to the sale total when estado is Pagada.
cambio
number
Change returned to the customer. Defaults to 0.
fecha_expiracion
string
Expiration date for the sale or quotation, in Y-m-d format.
observaciones
string
Free-text notes recorded on the sale. Maximum 1000 characters.
cotizacion
boolean
Marks the sale as a quotation. Automatically set to true when estado is Cotizacion.
detalles
array
required
Line items for the sale. Must contain at least 1 and at most 100 entries.

Response

On success, the response wraps the full Sale object under data — identical to the structure returned by GET /sales. The meta.idempotent flag indicates whether the record was newly created or returned from a prior request:
  • 201 Created — a new sale was created (meta.idempotent: false).
  • 200 OK — the request matched an existing referencia and the previously created sale is returned (meta.idempotent: true).
{
  "success": true,
  "data": {
    "id": 10422,
    "fecha": "2025-01-15",
    "correlativo": "FAC-002502",
    "estado": "Completada",
    "total": 180.00,
    "detalles": [ /* ... */ ]
  },
  "meta": {
    "empresa": "Mi Empresa S.A.",
    "timestamp": "2025-01-15T10:42:00Z",
    "idempotent": false
  }
}
Validation or business-rule failures return the standard error envelope with HTTP 422 and a details object listing the failing fields.

GET /sales/{id}

Retrieves a single sale record by its numeric ID. The response returns the same full Sale object described above, including the detalles array of line items.

Path parameter

id
integer
required
The unique numeric identifier of the sale you want to retrieve.
curl --request GET \
  --url "https://api.smartpyme.site/api/external/v1/sales/10421" \
  --header "Authorization: Bearer {api_key}"
The response wraps the Sale object under a data key with "success": true. All fields, including detalles, are identical to the structure documented in the GET /sales response above.

PUT /sales/{id}

Updates an existing sale or quotation that has not yet been finalized. Use this endpoint to adjust line items, change the customer, switch the branch or warehouse, or transition a quotation into a confirmed sale.

When to use it

  • Edit a Pendiente, Cotizacion, or Pre-venta record before it is finalized — for example, to add or remove items, fix the customer, or update the payment method.
  • Convert a quotation into a sale by sending estado: "Pagada" or "Completada" together with the final line items.

Restrictions

  • Only sales in state Pendiente, Cotizacion, or Pre-venta can be updated. Attempting to update a sale in any other state returns HTTP 422.
  • Sales that already have a fiscal document emitted cannot be updated and return HTTP 422.
  • Annulled sales (Anulada) cannot be updated and return HTTP 422.
  • The same 100-line maximum applies to the detalles array.

Path parameter

id
integer
required
The numeric identifier of the sale to update.

Body parameters

All body fields are optional. Send only the fields you want to change; omitted fields keep their current value. If detalles is omitted, the existing line items are preserved.
fecha
string
Sale date, in Y-m-d format.
estado
string
New state for the sale. Accepted values: Pagada, Completada, Pendiente, Cotizacion, Pre-venta.
id_sucursal
integer
Branch identifier.
sucursal
string
Branch name. Resolved server-side to the matching id_sucursal.
id_bodega
integer
Warehouse identifier.
id_documento
integer
Sales document type identifier.
id_canal
integer
Sales channel identifier.
id_cliente
integer
Customer identifier. Required when transitioning the sale to Pendiente.
forma_pago
string
Payment method.
monto_pago
number
Amount tendered by the customer.
cambio
number
Change returned to the customer.
fecha_expiracion
string
Expiration date, in Y-m-d format.
observaciones
string
Free-text notes. Maximum 1000 characters.
cotizacion
boolean
Marks the sale as a quotation.
detalles
array
Replacement line items. When provided, must contain between 1 and 100 entries. Pass an existing line’s id to update it in place; omit the id to add a new line. Lines not included in the new array are removed.
curl --request PUT \
  --url "https://api.smartpyme.site/api/external/v1/sales/10422" \
  --header "Authorization: Bearer {api_key}" \
  --header "Content-Type: application/json" \
  --data '{
    "estado": "Pagada",
    "forma_pago": "Tarjeta",
    "detalles": [
      { "id_producto": 312, "cantidad": 2, "precio": 163.75 }
    ]
  }'
On success, the endpoint returns HTTP 200 and the updated Sale object under data, using the same structure as GET /sales.

GET /sales/summary

Returns aggregate statistics for your sales data over an optional date range. Use this endpoint to build high-level reporting widgets — total revenue, average transaction value, tax collected, and a breakdown of transaction counts and totals by status.
curl --request GET \
  --url "https://api.smartpyme.site/api/external/v1/sales/summary?fecha_inicio=2025-01-01&fecha_fin=2025-01-31" \
  --header "Authorization: Bearer {api_key}"

Query parameters

fecha_inicio
string
Start date for the summary period, in Y-m-d format. Omit to include all records from the beginning.
fecha_fin
string
End date for the summary period, in Y-m-d format. Omit to include all records up to the current date.
estado
string
Limit the summary to a specific sale status. Accepted values: Completada, Pendiente, Anulada, Cotizacion.

Response example

{
  "success": true,
  "data": {
    "cantidad_ventas": 125,
    "total_ventas": 18750.50,
    "total_iva": 1687.55,
    "total_descuentos": 250.00,
    "promedio_venta": 150.00,
    "ventas_por_estado": [
      { "estado": "Completada", "cantidad": 120, "total": 18000.00 },
      { "estado": "Anulada",    "cantidad": 5,   "total": 750.50   }
    ]
  },
  "meta": {
    "empresa": "Mi Empresa S.A.",
    "timestamp": "2025-01-31T23:59:00Z",
    "filters_applied": {
      "fecha_inicio": "2025-01-01",
      "fecha_fin": "2025-01-31"
    }
  }
}

Response fields

data.cantidad_ventas
integer
Total number of sale records within the requested period.
data.total_ventas
number
Gross revenue across all sales in the period.
data.total_iva
number
Total tax collected across all sales in the period.
data.total_descuentos
number
Total discount amount applied across all sales in the period.
data.promedio_venta
number
Average sale value for the period, calculated as total_ventas / cantidad_ventas.
data.ventas_por_estado
array
Breakdown of sales count and total revenue grouped by status.
meta.empresa
string
Display name of the company associated with your API key.
meta.timestamp
string
ISO 8601 timestamp indicating when the summary was generated.
meta.filters_applied
object
Echo of the filters used to compute the summary, useful for confirming the request parameters.