npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ylazzari-correoargentino

v0.1.0

Published

API wrapper para el servicio de MiCorreo de Correo Argentino

Readme

ylazzari-correoargentino

API wrapper en TypeScript para la API MiCorreo de Correo Argentino.

Permite cotizar envíos, registrar usuarios, listar sucursales y crear órdenes de envío contra la plataforma MiCorreo. Maneja internamente el flujo HTTP Basic + JWT que exige la API.

Downloads

  • ✅ Soporte dual CommonJS + ESM
  • ✅ Tipos TypeScript completos
  • ✅ Validaciones client-side previas a cada request
  • ✅ Sin dependencias runtime (axios es peer dep)

Estado de Endpoints

  • 🟩 register [POST] — Registro de usuario en MiCorreo
  • 🟩 token [POST] — Obtención de token de autenticación
  • 🟩 users/validate [POST] — Validación y obtención de customerId
  • 🟩 rates [POST] — Cotización de envíos
  • 🟩 agencies [GET] — Consulta de sucursales por provincia
  • 🟩 shipping/import [POST] — Importación / alta de envíos (nuevo en v0.1.0)

Tabla de contenidos


Instalación

npm install ylazzari-correoargentino axios

axios es peerDependency — instalalo en tu proyecto. Funciona con cualquier versión ^1.x.

Requisitos

  • Node.js >= 14
  • Credenciales de MiCorreo (userToken, passwordToken, email, password)

Configuración inicial

Obtener credenciales

  1. Solicitar token de acceso vía el formulario de Correo Argentino.
  2. Referencias útiles:

Las credenciales son distintas por ambiente — pediselas a Correo para TEST y PROD por separado.


Inicio rápido

Modo 1: con email + password (obtiene customerId automáticamente)

import CorreoArgentinoApi from "ylazzari-correoargentino";
import { Environment } from "ylazzari-correoargentino/enums";

const api = new CorreoArgentinoApi();

await api.initializeAll({
  userToken: process.env.USER_TOKEN!,
  passwordToken: process.env.PASSWORD_TOKEN!,
  email: process.env.EMAIL!,
  password: process.env.PASSWORD!,
  environment: Environment.TEST,
});

const customerId = api.getVarCustomerId();

Modo 2: con customerId ya conocido (omite /users/validate)

import CorreoArgentinoApi from "ylazzari-correoargentino";
import { Environment } from "ylazzari-correoargentino/enums";

const api = new CorreoArgentinoApi();

await api.initializeWithCustomerId({
  userToken: process.env.USER_TOKEN!,
  passwordToken: process.env.PASSWORD_TOKEN!,
  customerId: "0090000025",
  environment: Environment.PROD,
});

Opciones del constructor

const api = new CorreoArgentinoApi({ debug: true });

| Opción | Tipo | Default | Descripción | |---------|-----------|---------|------------------------------------------------------------------------------------------| | debug | boolean | false | Si es true, imprime logs informativos (ambiente, customerId obtenido, payloads). |

⚠️ No actives debug en producción. Aunque la librería ya no logea el JWT, los payloads contienen PII (emails, direcciones).


Ambientes

| Ambiente | URL base | |----------------------|-------------------------------------------------------| | Environment.TEST | https://apitest.correoargentino.com.ar/micorreo/v1 | | Environment.PROD | https://api.correoargentino.com.ar/micorreo/v1 |


Referencia de la API

initializeAll(data)

Obtiene el JWT y el customerId a partir de email + password.

  • Parámetros: InitializeMiCorreo
  • Devuelve: Promise<void>
  • Flujo: setEnvironmentPOST /token (Basic auth) → POST /users/validate (Bearer).
await api.initializeAll({
  userToken: "...",
  passwordToken: "...",
  email: "[email protected]",
  password: "secret",
  environment: Environment.PROD,
});

initializeWithCustomerId(data)

Igual que initializeAll pero salta /users/validate porque ya conocés el customerId.

await api.initializeWithCustomerId({
  userToken: "...",
  passwordToken: "...",
  customerId: "0090000025",
  environment: Environment.PROD,
});

getCustomerId(email, password)

Valida credenciales contra POST /users/validate y devuelve el customerId.

Lo invoca automáticamente initializeAll. Llamarlo manualmente solo tiene sentido si querés re-validar o cambiar de usuario sin recrear la instancia.

const { customerId, createdAt } = await api.getCustomerId("[email protected]", "secret");

getRates(data)

Cotiza un envío contra POST /rates. Aceptás un array de productos con dimensiones individuales — la librería arma un contenedor virtual.

import { DeliveredType } from "ylazzari-correoargentino/enums";

const cotizacion = await api.getRates({
  customerId: api.getVarCustomerId(),
  postalCodeOrigin: "1757",
  postalCodeDestination: "1704",
  deliveredType: DeliveredType.D,
  dimensions: [
    { length: 30, width: 20, height: 10, weight: 1500, quantity: 1 },
    { length: 20, width: 15, height: 5, weight: 500, quantity: 2 },
  ],
});

console.log(cotizacion.rates);
// [{ deliveredType: "D", productType: "CP", productName: "Paq.ar Clásico", price: 498.06 }]

Cómo se calcula el contenedor virtual

Si pasás varios productos en dimensions, se combinan así:

| Campo | Fórmula | |----------|------------------------------------------------------------------| | weight | suma de weight × quantity de cada item | | length | máximo de length × quantity (caben en una sola fila por largo) | | width | máximo de width (no se multiplica por quantity) | | height | suma de height × quantity (items apilados verticalmente) |

Si tu modelo de empaquetado es otro, calculá las dimensiones en tu código y pasá un único ProductDimensions con los valores finales.

Cotizar ambas modalidades (D y S) en un mismo request

Omití deliveredType:

const cotizacion = await api.getRates({
  customerId: api.getVarCustomerId(),
  postalCodeOrigin: "1757",
  postalCodeDestination: "1704",
  // sin deliveredType → MiCorreo devuelve ambas
  dimensions: [{ length: 30, width: 20, height: 10, weight: 1500 }],
});

// cotizacion.rates contiene 2 entradas: una para "D" y otra para "S"

Límites de MiCorreo

| Atributo | Límite | |----------|--------------| | weight | 1 – 25000 g | | length | hasta 150 cm | | width | hasta 150 cm | | height | hasta 150 cm |


userRegister(dataUser)

Registra un nuevo usuario en MiCorreo vía POST /register.

Hay dos modos: consumidor final (DNI) y empresa/monotributista (CUIT).

import { DocumentType } from "ylazzari-correoargentino/enums";

const nuevoUsuario = await api.userRegister({
  firstName: "Juan",
  lastName: "Pérez",
  email: "[email protected]",
  password: "secret",
  documentType: DocumentType.DNI,
  documentId: "32471960",
  phone: "1165446544",
  cellPhone: "1165446544",
  address: {
    streetName: "Vicente Lopez",
    streetNumber: "448",
    floor: "1",
    apartment: "D",
    locality: "Monte Grande",
    city: "Esteban Echeverria",
    provinceCode: "B",
    postalCode: "B1842ZAB",
  },
});

console.log(nuevoUsuario.customerId); // "0090000024"

⚠️ MiCorreo no valida que el email sea real. Si el email ya existe, devuelve 402 "Email existente".


getAgencies(provinceCode)

Lista las sucursales de una provincia vía GET /agencies.

  • Parámetros: provinceCode: ProvinceCode (1 letra)
  • Devuelve: Promise<ResponseAgencies> (= Agency[])
import { ProvinceCode } from "ylazzari-correoargentino/enums";

const sucursales = await api.getAgencies(ProvinceCode["Provincia de Buenos Aires"]);

sucursales.forEach((suc) => {
  console.log(suc.code, suc.name, suc.location.address.postalCode);
});

⚠️ Breaking change en v0.1.0: el tipo ResponseAgencies ahora es Agency[] (antes { agencies: Agency[] }, que nunca coincidió con la respuesta real del server). Si tu código usaba response.agencies.map(...), cambialo a response.map(...).


shippingImport(data)

Crea (importa) un envío en MiCorreo vía POST /shipping/import. Este es el endpoint que cierra el flujo de operación.

Envío a domicilio

import { DeliveredType } from "ylazzari-correoargentino/enums";

const envio = await api.shippingImport({
  customerId: api.getVarCustomerId(),
  extOrderId: "ORDER-12345",
  orderNumber: "102",
  recipient: {
    name: "María González",
    email: "[email protected]",
    phone: "1144556677",
    cellPhone: "1144556677",
  },
  shipping: {
    deliveryType: DeliveredType.D,
    address: {
      streetName: "Av. Corrientes",
      streetNumber: "1234",
      floor: "5",
      apartment: "B",
      city: "Buenos Aires",
      provinceCode: "B",
      postalCode: "1425",
    },
    weight: 1000,
    declaredValue: 500.0,
    height: 20,
    length: 40,
    width: 20,
  },
});

console.log(envio.createdAt); // "2022-06-07T16:15:04.996-03:00"

Envío a sucursal

const envio = await api.shippingImport({
  customerId: api.getVarCustomerId(),
  extOrderId: "ORDER-12346",
  recipient: {
    name: "María González",
    email: "[email protected]",
  },
  shipping: {
    deliveryType: DeliveredType.S,
    agency: "B0107", // código obtenido vía getAgencies
    weight: 1000,
    declaredValue: 500.0,
    height: 20,
    length: 40,
    width: 20,
  },
});

Validaciones client-side aplicadas

Antes de pegarle al server, la librería valida:

  • customerId, extOrderId, recipient.name, recipient.email, shipping.deliveryType → obligatorios.
  • Si deliveryType === "S"shipping.agency obligatorio.
  • Si deliveryType === "D"shipping.address con streetName, streetNumber, city, provinceCode, postalCode obligatorios.

Si algo falla, se tira Error con el campo faltante antes de hacer el roundtrip al server.

Idempotencia

extOrderId debe ser único. MiCorreo rechaza con "La orden ya fue importada con anterioridad" si lo repetís. Usá un identificador propio (UUID, ID de tu DB, etc.) y persistilo de tu lado.

sender opcional

Si no pasás sender, MiCorreo usa los datos del perfil de tu customerId. Pasalo solo si necesitás overridear el remitente para un envío puntual.


setEnvironment(environment)

Cambia el ambiente y recrea la instancia axios interna.

  • Parámetros: environment: Environment (PROD o TEST)
  • Devuelve: void
api.setEnvironment(Environment.TEST);

⚠️ Llamarlo después de inicializar resetea el JWT. Vas a tener que re-inicializar antes de hacer más llamadas. Se invoca automáticamente desde initializeAll / initializeWithCustomerId.


Getters

Métodos para inspeccionar el estado interno. Todos devuelven string.

| Método | Descripción | |------------------------|------------------------------------------------------------------| | getVarCustomerId() | El customerId cargado actualmente. | | getVarToken() | El JWT actualmente cargado. ⚠️ NO lo loguees. | | getVarEmail() | El email con el que se inicializó la instancia. | | getVarPassword() | El password en plano. ⚠️ Deprecado, no lo uses. | | getVarUserToken() | El userToken con el que se inicializó. | | getVarPasswordToken()| El passwordToken con el que se inicializó. | | getVarEnvironment() | El ambiente actual ("PROD" o "TEST"). |


Tipos

Disponibles vía ylazzari-correoargentino/interfaces:

import type {
  CorreoArgentinoOptions,
  InitializeMiCorreo,
  InitializeMiCorreoWithCustomerId,
  ProductRates,
  ProductDimensions,
  ResponseRates,
  Rate,
  UserRegister,
  Address,
  ResponseUserRegister,
  ResponseAgencies,
  Agency,
  ShippingImport,
  ShippingAddress,
  ShippingInfo,
  Sender,
  Recipient,
  ResponseShippingImport,
  ResponseCustomerId,
  ResponseAuthToken,
} from "ylazzari-correoargentino/interfaces";

InitializeMiCorreo

interface InitializeMiCorreo {
  userToken: string;
  passwordToken: string;
  email: string;
  password: string;
  environment: Environment.PROD | Environment.TEST;
}

InitializeMiCorreoWithCustomerId

interface InitializeMiCorreoWithCustomerId {
  userToken: string;
  passwordToken: string;
  customerId: string;
  environment: Environment.PROD | Environment.TEST;
}

ProductRates

interface ProductRates {
  customerId: string;
  postalCodeOrigin: string;
  postalCodeDestination: string;
  deliveredType?: DeliveredType.D | DeliveredType.S; // opcional desde v0.1.0
  dimensions: ProductDimensions[];
}

ProductDimensions

interface ProductDimensions {
  weight: number;   // gramos (1–25000)
  height: number;   // cm (≤150)
  width: number;    // cm (≤150)
  length: number;   // cm (≤150)
  quantity?: number;
}

ResponseRates

interface ResponseRates {
  message?: string;     // opcional, no siempre presente
  customerId: string;
  validTo: string;      // ISO 8601, ej: "2022-06-07T10:31:27.881-03:00"
  rates: Rate[];
}

Rate

interface Rate {
  deliveredType: "D" | "S";
  productType: "CP" | "EP";
  productName: string;
  price: number;
  deliveryTimeMin: string;
  deliveryTimeMax: string;
}

UserRegister

interface UserRegister {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  documentType: "DNI" | "CUIT";
  documentId: string;
  phone: string;
  cellPhone: string;
  address: Address;
}

Address

interface Address {
  streetName: string;
  streetNumber: string;
  floor: string;
  apartment: string;
  locality: string;
  city: string;
  provinceCode: string;
  postalCode: string;
}

ResponseUserRegister

interface ResponseUserRegister {
  customerId: string;
  createdAt: string;
}

ResponseAgencies

type ResponseAgencies = Agency[];

interface Agency {
  code: string;
  name: string;
  manager: string;
  email: string;
  phone: string;
  services: { packageReception: boolean; pickupAvailability: boolean };
  location: { address: Address; latitude: string; longitude: string };
  hours: WeeklySchedule;
  status: "ACTIVE" | "INACTIVE";
}

ShippingImport

interface ShippingImport {
  customerId: string;
  extOrderId: string;            // único — idempotencia
  orderNumber?: string;          // identificador visible en panel MiCorreo
  sender?: Sender;               // opcional; default = perfil del customerId
  recipient: Recipient;          // requerido
  shipping: ShippingInfo;        // requerido
}

Sender

interface Sender {
  name?: string | null;
  phone?: string | null;
  cellPhone?: string | null;
  email?: string | null;
  originAddress?: Partial<ShippingAddress> | null;
}

Recipient

interface Recipient {
  name: string;     // requerido
  email: string;    // requerido
  phone?: string;
  cellPhone?: string;
}

ShippingInfo

interface ShippingInfo {
  deliveryType: "D" | "S";       // requerido
  agency?: string | null;        // requerido si deliveryType = "S"
  address?: ShippingAddress | null; // requerido si deliveryType = "D"
  weight: number;                // gramos (entero)
  declaredValue: number;
  height: number;                // cm (entero, ≤255)
  length: number;                // cm (entero, ≤255)
  width: number;                 // cm (entero, ≤255)
}

ShippingAddress

interface ShippingAddress {
  streetName: string;
  streetNumber: string;
  floor?: string;
  apartment?: string;
  city: string;
  provinceCode: string;
  postalCode: string;
}

⚠️ Esta interfaz NO incluye locality (diferencia con Address). MiCorreo no la requiere en /shipping/import.

ResponseShippingImport

interface ResponseShippingImport {
  createdAt: string; // ISO 8601, ej: "2022-06-07T16:15:04.996-03:00"
}

ResponseCustomerId

interface ResponseCustomerId {
  customerId: string;
  createdAt: string;
}

ResponseAuthToken

interface ResponseAuthToken {
  token: string;
  expires: string;
}

Enums

Disponibles vía ylazzari-correoargentino/enums:

import {
  Environment,
  DeliveredType,
  ProductType,
  DocumentType,
  AgencyStatus,
  ProvinceCode,
} from "ylazzari-correoargentino/enums";

Environment

enum Environment {
  PROD = "PROD",
  TEST = "TEST",
}

DeliveredType

enum DeliveredType {
  D = "D", // Entrega a domicilio
  S = "S", // Entrega en sucursal
}

ProductType

enum ProductType {
  CP = "CP", // Paq.ar Clásico
  EP = "EP", // Paq.ar Express
}

DocumentType

enum DocumentType {
  DNI = "DNI",
  CUIT = "CUIT",
}

AgencyStatus

enum AgencyStatus {
  ACTIVE = "ACTIVE",
  INACTIVE = "INACTIVE",
}

ProvinceCode

Ver Códigos de provincia.


Manejo de errores

Todos los métodos tiran Error con un mensaje del formato:

🔴 Error en {method}: {code} - {message}

code y message vienen del response del server cuando está disponible. Si el server no respondió o el payload no es JSON, se usan los campos del objeto error de axios como fallback.

try {
  await api.shippingImport(envio);
} catch (err) {
  console.error(err.message);
  // "🔴 Error en shippingImport: 402 - La orden ya fue importada con anterioridad."
}

Códigos HTTP típicos

| Código | Significado | |--------|--------------------------------------------------------------------------| | 200 | OK | | 400 | Falta un parámetro obligatorio | | 401 | Token JWT inválido o no provisto | | 402 | Los parámetros son válidos pero la solicitud falló (regla de negocio) | | 403 | Tu cuenta no tiene permisos | | 404 | Recurso inexistente | | 409 | Conflicto (ej: idempotency key repetida) | | 429 | Rate limit (aplicá backoff exponencial) | | 5xx | Error del lado de Correo |

Mensajes de error frecuentes en shippingImport

  • La orden ya fue importada con anterioridadextOrderId duplicado.
  • Peso no valido / El peso debe ser mayor a 0 / El peso excede el maximo permitido para el producto
  • Tipo de entrega invalido
  • Verifique la sucursal de destino — código de agency inexistente.
  • El codigo Postal del emisor debe tener valor — falta data en el perfil del customerId.
  • La provincia es invalida.
  • El alto/ancho/largo debe estar entre 0 y 255.

Códigos de provincia

| Código | Provincia | |--------|--------------------------------------| | A | Salta | | B | Provincia de Buenos Aires | | C | Ciudad Autónoma de Buenos Aires | | D | San Luis | | E | Entre Ríos | | F | La Rioja | | G | Santiago del Estero | | H | Chaco | | J | San Juan | | K | Catamarca | | L | La Pampa | | M | Mendoza | | N | Misiones | | P | Formosa | | Q | Neuquén | | R | Río Negro | | S | Santa Fe | | T | Tucumán | | U | Chubut | | V | Tierra del Fuego | | W | Corrientes | | X | Córdoba | | Y | Jujuy | | Z | Santa Cruz |

Acceso programático:

import { ProvinceCode } from "ylazzari-correoargentino/enums";

ProvinceCode["Provincia de Buenos Aires"]; // "B"
ProvinceCode["Ciudad Autónoma de Buenos Aires"]; // "C"

ESM vs CommonJS

La librería se publica como dual package: funciona en ambos sistemas de módulos sin cambios de tu lado.

CommonJS

const { CorreoArgentinoApi } = require("ylazzari-correoargentino");
const { Environment } = require("ylazzari-correoargentino/enums");

ESM

import CorreoArgentinoApi from "ylazzari-correoargentino";
import { Environment } from "ylazzari-correoargentino/enums";

Los exports del package.json declaran ambas variantes con condiciones "import" y "require", y un dist/esm/package.json interno con "type": "module" para que Node interprete los archivos .js de esa carpeta como ESM.


Troubleshooting

Error: Token no disponible. Llamá initializeAll o initializeWithCustomerId primero.

Estás llamando un método antes de inicializar. Hacé await api.initializeAll(...) (o initializeWithCustomerId) antes de cualquier otra cosa.

Error en authToken: 401 - Unauthorized

userToken y/o passwordToken incorrectos para el ambiente. Recordá que las credenciales son distintas por ambiente (TEST vs PROD).

Error en agencies: 402 - Customer ID no valido

El customerId no existe en el ambiente que estás usando. Si estás en TEST, asegurate de haber registrado al usuario en TEST. Si en PROD, en PROD.

Error en shippingImport: 402 - no se encontro datos de remitente

Tu perfil de MiCorreo no tiene datos de remitente cargados. Cargalos en el panel de MiCorreo o pasá sender explícito en el request.

Error en shippingImport: 402 - La orden ya fue importada con anterioridad.

Estás reusando un extOrderId. Usá un identificador único por orden.

Logs ruidosos en consola

Asegurate de NO pasar debug: true en el constructor. Por default está desactivado.


Changelog

v0.1.0 — current

Nuevas funcionalidades

  • shippingImport(data) — implementación del endpoint POST /shipping/import que faltaba. Cierra el flujo: ahora se pueden crear envíos, no solo cotizarlos.
  • CorreoArgentinoOptions — el constructor acepta { debug?: boolean } para activar/desactivar logs.
  • Validaciones client-side para shippingImport que evitan el roundtrip al server cuando faltan campos.

Breaking changes

  • ResponseAgencies ahora es Agency[] (antes { agencies: Agency[] }, que nunca coincidió con el shape real de la respuesta de MiCorreo). Reemplazá response.agencies por response.
  • ResponseAuthToken.expires, ResponseCustomerId.createdAt y ResponseRates.validTo cambian de Date a string — JSON nunca devolvió Date, el tipo previo era incorrecto.
  • ResponseRates.message pasa a ser opcional (no siempre viene en la respuesta).
  • ProductRates.deliveredType pasa a ser opcional — omitiéndolo MiCorreo devuelve cotización para D y S simultáneamente.
  • Eliminados los console.log no-condicionales (incluyendo el que imprimía el JWT). Reactivables vía new CorreoArgentinoApi({ debug: true }).

Bug fixes

  • getAgencies armaba la URL con / en vez de ? para la query string — siempre devolvía 404.
  • Header HTTP inválido Basic: ... eliminado de los requests (no es un header estándar, se confundía con Authorization: Basic ...).
  • errorCapture cambió su return type de void a never para que TS infiera correctamente que el path nunca retorna.
  • Build script ahora compila CJS y ESM correctamente; antes el output ESM nunca se generaba en prepare.

Mejoras internas

  • api: AxiosInstance (antes any).
  • package.json: eliminado bloque compilerOptions inválido (era ignorado por npm).
  • dotenv movido de peerDependencies a devDependencies (la lib no lo usa, solo el ejemplo).
  • Documentación JSDoc completa en todos los métodos públicos.

v0.0.7

Soporte inicial de dual ESM/CommonJS (incompleto, arreglado en v0.1.0).


Playground interactivo

El repo incluye un playground local con HTML interactivo para probar todos los métodos contra MiCorreo TEST sin escribir código:

npm install
# renombrá env.example.txt → .env y completalo con tus credenciales
npm run playground
# abrí http://localhost:3000

Tenés forms para cada método y un toggle de "dry run" para validar payloads de shippingImport sin generar envíos reales en MiCorreo. Guía completa: doc/playground.md.

Solo es útil para development local — no se publica con el paquete a npm.

Ejemplos visuales

doc/ejemplos.html — documentación HTML autocontenida con casos de uso paso a paso. Abrila con doble click o serviéndola desde el playground en http://localhost:3000/doc/ejemplos.html.

Contribución

Las contribuciones son bienvenidas. Por favor abrí un issue antes para discutir los cambios.

Licencia

MITYamil Lazzari