{"openapi":"3.1.0","info":{"title":"API de clientes de Acme Distribuidora","version":"1.0.0","description":"API de solo lectura para los clientes de Acme Distribuidora, mayorista de abarrotes, bebidas, lácteos, botanas, limpieza y cuidado personal para tiendas en México. Cada credencial pertenece a un cliente y solo da acceso a sus propios pedidos, facturas, saldo y envíos. Importes en pesos mexicanos (MXN), fechas en hora de Ciudad de México. Empresa y datos ficticios, para demostrar Grostify Connect.","contact":{"name":"Acme Distribuidora (demo)","url":"https://acme.grostify.com"}},"servers":[{"url":"https://acme.grostify.com/v1","description":"Producción"}],"security":[{"apiKey":[]},{"oauth2":["openid","offline_access"]}],"tags":[{"name":"Cuenta","description":"Datos del cliente y su crédito."},{"name":"Pedidos","description":"Pedidos hechos a Acme y su estado."},{"name":"Facturas","description":"Facturas CFDI, pagos y vencimientos."},{"name":"Envíos","description":"Seguimiento de entregas."},{"name":"Catálogo","description":"Productos, precios del cliente, existencias y promociones."}],"paths":{"/me":{"get":{"operationId":"getMyAccount","tags":["Cuenta"],"summary":"Ver mi cuenta","description":"Devuelve los datos del cliente dueño de la credencial: nombre, empresa, RFC, lista de precios, descuento, plazo de pago en días, límite de crédito, direcciones de entrega y su ejecutivo de ventas. Úsala para saber quién es el usuario o a qué sucursales se le entrega.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/balance":{"get":{"operationId":"getAccountBalance","tags":["Cuenta"],"summary":"Ver saldo y crédito disponible","description":"Estado de cuenta del cliente: saldo pendiente de pago, importe vencido, crédito disponible, pedidos aún sin facturar, próxima factura por vencer y último pago recibido. Úsala para preguntas como cuánto debo, cuánto crédito me queda o cuándo vence mi próximo pago.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/orders":{"get":{"operationId":"listOrders","tags":["Pedidos"],"summary":"Listar mis pedidos","description":"Lista los pedidos del cliente de los últimos 120 días, del más reciente al más antiguo, con su estado, total, número de guía y factura asociada. No incluye las líneas del pedido: para ver productos y cantidades usa el detalle del pedido.","parameters":[{"name":"status","in":"query","required":false,"description":"Filtra por estado: processing (en preparación), in_transit (en camino), delivered (entregado) o cancelled (cancelado).","schema":{"type":"string","enum":["processing","in_transit","delivered","cancelled"]}},{"name":"from","in":"query","required":false,"description":"Solo pedidos hechos desde esta fecha, inclusive (AAAA-MM-DD).","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"description":"Solo pedidos hechos hasta esta fecha, inclusive (AAAA-MM-DD).","schema":{"type":"string","format":"date"}},{"name":"page","in":"query","required":false,"description":"Página de resultados, empieza en 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Resultados por página, entre 1 y 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","page","limit","total","has_more"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OrderSummary"}},"page":{"type":"integer","description":"Página devuelta."},"limit":{"type":"integer","description":"Resultados por página."},"total":{"type":"integer","description":"Total de resultados con los filtros aplicados."},"has_more":{"type":"boolean","description":"Si hay más páginas después de esta."}}}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createOrder","tags":["Pedidos"],"summary":"Crear un pedido","description":"Crea un pedido nuevo. No disponible en la demo, que es de solo lectura.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["lines"],"properties":{"address_id":{"type":"string","description":"Dirección de entrega del cliente."},"lines":{"type":"array","items":{"type":"object","required":["sku","quantity"],"properties":{"sku":{"type":"string"},"quantity":{"type":"integer","minimum":1}}}}}}}}},"responses":{"201":{"description":"Pedido creado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"No disponible en la demo.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/orders/{order_id}":{"get":{"operationId":"getOrder","tags":["Pedidos"],"summary":"Ver el detalle de un pedido","description":"Detalle completo de un pedido del cliente: productos, cantidades, precios, impuestos, dirección de entrega, fecha estimada de entrega, número de guía y factura. Si el pedido no es del cliente responde 404.","parameters":[{"name":"order_id","in":"path","required":true,"description":"Número de pedido, por ejemplo PED-104512.","schema":{"type":"string","pattern":"^PED-[0-9]+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No existe o no es de este cliente.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices":{"get":{"operationId":"listInvoices","tags":["Facturas"],"summary":"Listar mis facturas","description":"Lista las facturas del cliente, de la más reciente a la más antigua, con importe, fecha de vencimiento, lo pagado y lo que falta por pagar. Filtra por estado para ver solo las pendientes o las vencidas.","parameters":[{"name":"status","in":"query","required":false,"description":"Filtra por estado: pending (pendiente de pago y aún no vencida), paid (pagada) u overdue (vencida sin pagar).","schema":{"type":"string","enum":["pending","paid","overdue"]}},{"name":"from","in":"query","required":false,"description":"Solo facturas emitidas desde esta fecha, inclusive (AAAA-MM-DD).","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"description":"Solo facturas emitidas hasta esta fecha, inclusive (AAAA-MM-DD).","schema":{"type":"string","format":"date"}},{"name":"page","in":"query","required":false,"description":"Página de resultados, empieza en 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Resultados por página, entre 1 y 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","page","limit","total","has_more"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"page":{"type":"integer","description":"Página devuelta."},"limit":{"type":"integer","description":"Resultados por página."},"total":{"type":"integer","description":"Total de resultados con los filtros aplicados."},"has_more":{"type":"boolean","description":"Si hay más páginas después de esta."}}}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices/{invoice_id}":{"get":{"operationId":"getInvoice","tags":["Facturas"],"summary":"Ver una factura","description":"Detalle de una factura del cliente: pedido asociado, fechas de emisión y vencimiento, importes, pago y folio fiscal (UUID del CFDI).","parameters":[{"name":"invoice_id","in":"path","required":true,"description":"Folio de la factura, por ejemplo FAC-A-41235.","schema":{"type":"string","pattern":"^FAC-A-[0-9]+$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No existe o no es de este cliente.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/shipments/{tracking_number}":{"get":{"operationId":"trackShipment","tags":["Envíos"],"summary":"Rastrear un envío","description":"Seguimiento de un envío por su número de guía: estado, fecha estimada de entrega, chofer, quién recibió y el historial de eventos del más reciente al más antiguo. El número de guía sale del pedido (tracking_number).","parameters":[{"name":"tracking_number","in":"path","required":true,"description":"Número de guía, por ejemplo ACM4820193746.","schema":{"type":"string","pattern":"^ACM[0-9]{10}$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No existe o no es de este cliente.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/products":{"get":{"operationId":"searchProducts","tags":["Catálogo"],"summary":"Buscar productos","description":"Busca en el catálogo de Acme y devuelve, por producto, el precio de lista, el precio del cliente con su descuento, el IVA, las existencias del día en el CEDIS y la promoción vigente si la hay. Precios por empaque (caja, paquete o bulto) antes de IVA.","parameters":[{"name":"q","in":"query","required":false,"description":"Texto a buscar en nombre, marca, SKU o categoría, sin distinguir acentos. Por ejemplo: leche, aceite, ABR-003.","schema":{"type":"string","maxLength":100}},{"name":"category","in":"query","required":false,"description":"Categoría: abarrotes, bebidas, lacteos, botanas, limpieza o cuidado_personal.","schema":{"type":"string","enum":["abarrotes","bebidas","lacteos","botanas","limpieza","cuidado_personal"]}},{"name":"in_stock","in":"query","required":false,"description":"true para ver solo productos con existencias, false para ver solo los agotados.","schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"description":"Página de resultados, empieza en 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Resultados por página, entre 1 y 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","required":["data","page","limit","total","has_more"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"page":{"type":"integer","description":"Página devuelta."},"limit":{"type":"integer","description":"Resultados por página."},"total":{"type":"integer","description":"Total de resultados con los filtros aplicados."},"has_more":{"type":"boolean","description":"Si hay más páginas después de esta."}}}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/products/{sku}":{"get":{"operationId":"getProduct","tags":["Catálogo"],"summary":"Ver un producto","description":"Ficha de un producto por su SKU con precio del cliente, existencias del día, fecha de resurtido si está agotado y promoción vigente.","parameters":[{"name":"sku","in":"path","required":true,"description":"SKU del producto, por ejemplo LAC-001.","schema":{"type":"string","pattern":"^[A-Z]{3}-[0-9]{3}$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No existe.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/promotions":{"get":{"operationId":"listPromotions","tags":["Catálogo"],"summary":"Ver promociones de la semana","description":"Promociones vigentes esta semana (de lunes a domingo): producto, porcentaje de descuento y cantidad mínima.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Promotion"}}}}}}},"400":{"description":"Algún parámetro no es válido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Falta la credencial o no es válida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key personal del cliente. Empieza por acme_live_ y se genera en https://acme.grostify.com/account/api-keys."},"oauth2":{"type":"oauth2","description":"OAuth 2.0 con authorization code y PKCE S256. OpenID Connect disponible en /.well-known/openid-configuration.","flows":{"authorizationCode":{"authorizationUrl":"https://acme.grostify.com/oauth/authorize","tokenUrl":"https://acme.grostify.com/oauth/token","refreshUrl":"https://acme.grostify.com/oauth/token","scopes":{"openid":"Identidad del cliente","profile":"Nombre y empresa","email":"Correo","offline_access":"Refresh token"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código del error."},"message":{"type":"string","description":"Explicación legible."}}}}},"Address":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string","description":"Nombre de la sucursal o dirección."},"street":{"type":"string"},"neighborhood":{"type":"string","description":"Colonia."},"city":{"type":"string"},"state":{"type":"string"},"zip":{"type":"string","description":"Código postal."}}},"Account":{"type":"object","properties":{"id":{"type":"string","description":"Id del cliente."},"name":{"type":"string","description":"Nombre de la persona."},"email":{"type":"string"},"company":{"type":"string","description":"Razón comercial de la tienda."},"tax_id":{"type":"string","description":"RFC."},"price_list":{"type":"string","enum":["mayoreo","medio_mayoreo","distribuidor"],"description":"Lista de precios asignada."},"discount_pct":{"type":"integer","description":"Descuento sobre el precio de lista, en porcentaje."},"payment_terms_days":{"type":"integer","description":"Días de crédito para pagar cada factura."},"credit_limit":{"type":"number","description":"Límite de crédito. En MXN."},"currency":{"type":"string"},"addresses":{"type":"array","items":{"$ref":"#/components/schemas/Address"}},"sales_rep":{"type":"object","description":"Ejecutivo de ventas asignado.","properties":{"name":{"type":"string"},"email":{"type":"string"}}}}},"Balance":{"type":"object","properties":{"currency":{"type":"string"},"credit_limit":{"type":"number","description":"Límite de crédito. En MXN."},"balance_due":{"type":"number","description":"Total pendiente de pago, vencido o no. En MXN."},"overdue_amount":{"type":"number","description":"Parte del saldo ya vencida. En MXN."},"pending_orders_amount":{"type":"number","description":"Pedidos en preparación que aún no se facturan. En MXN."},"available_credit":{"type":"number","description":"Crédito disponible para nuevos pedidos. En MXN."},"payment_terms_days":{"type":"integer"},"open_invoices":{"type":"integer","description":"Facturas sin pagar."},"overdue_invoices":{"type":"integer","description":"Facturas vencidas."},"next_due":{"type":["object","null"],"description":"Próxima factura por vencer.","properties":{"invoice_id":{"type":"string"},"due_date":{"type":"string","format":"date"},"amount":{"type":"number"}}},"last_payment":{"type":["object","null"],"description":"Último pago recibido.","properties":{"invoice_id":{"type":"string"},"paid_at":{"type":"string","format":"date-time"},"amount":{"type":"number"},"method":{"type":["string","null"]}}}}},"OrderSummary":{"type":"object","properties":{"id":{"type":"string","description":"Número de pedido."},"created_at":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["processing","in_transit","delivered","cancelled"]},"status_label":{"type":"string","description":"Estado en español."},"currency":{"type":"string"},"items_count":{"type":"integer","description":"Número de productos distintos."},"subtotal":{"type":"number","description":"Antes de IVA. En MXN."},"tax":{"type":"number","description":"IVA. En MXN."},"total":{"type":"number","description":"Total con IVA. En MXN."},"tracking_number":{"type":["string","null"],"description":"Número de guía si ya salió."},"invoice_id":{"type":["string","null"],"description":"Factura del pedido si ya se emitió."},"estimated_delivery":{"type":["string","null"],"format":"date","description":"Entrega estimada si aún no llega."},"delivered_at":{"type":["string","null"],"format":"date-time"}}},"Order":{"allOf":[{"$ref":"#/components/schemas/OrderSummary"},{"type":"object","properties":{"shipping_address":{"$ref":"#/components/schemas/Address"},"lines":{"type":"array","items":{"type":"object","properties":{"sku":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer","description":"Empaques pedidos."},"pack":{"type":"string","description":"caja, paquete o bulto."},"unit_price":{"type":"number","description":"Precio por empaque del cliente, antes de IVA. En MXN."},"tax_rate":{"type":"number","description":"0 o 0.16."},"subtotal":{"type":"number","description":"Cantidad por precio, antes de IVA. En MXN."}}}},"cancellation_reason":{"type":["string","null"]}}}]},"Invoice":{"type":"object","properties":{"id":{"type":"string","description":"Folio."},"order_id":{"type":"string"},"issued_at":{"type":"string","format":"date"},"due_date":{"type":"string","format":"date"},"status":{"type":"string","enum":["pending","paid","overdue"]},"status_label":{"type":"string"},"currency":{"type":"string"},"subtotal":{"type":"number","description":"Antes de IVA. En MXN."},"tax":{"type":"number","description":"IVA. En MXN."},"total":{"type":"number","description":"Total facturado. En MXN."},"amount_paid":{"type":"number","description":"Pagado. En MXN."},"amount_due":{"type":"number","description":"Por pagar. En MXN."},"days_overdue":{"type":"integer","description":"Días de atraso, 0 si no está vencida."},"paid_at":{"type":["string","null"],"format":"date-time"},"payment_method":{"type":["string","null"]},"cfdi_uuid":{"type":"string","description":"Folio fiscal del CFDI."}}},"Shipment":{"type":"object","properties":{"tracking_number":{"type":"string"},"order_id":{"type":"string"},"carrier":{"type":"string"},"status":{"type":"string","enum":["in_transit","delivered"]},"status_label":{"type":"string"},"estimated_delivery":{"type":["string","null"],"format":"date"},"delivered_at":{"type":["string","null"],"format":"date-time"},"driver":{"type":"string","description":"Chofer asignado."},"received_by":{"type":["string","null"]},"destination":{"type":"string"},"events":{"type":"array","description":"Del más reciente al más antiguo.","items":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"status":{"type":"string"},"description":{"type":"string"},"location":{"type":"string"}}}}}},"Product":{"type":"object","properties":{"sku":{"type":"string"},"name":{"type":"string"},"brand":{"type":"string"},"category":{"type":"string"},"category_label":{"type":"string"},"pack":{"type":"string"},"units_per_pack":{"type":"integer"},"currency":{"type":"string"},"list_price":{"type":"number","description":"Precio de lista por empaque, antes de IVA. En MXN."},"your_price":{"type":"number","description":"Precio del cliente con su descuento, antes de IVA. En MXN."},"tax_rate":{"type":"number"},"stock":{"type":"object","properties":{"available":{"type":"integer","description":"Empaques disponibles hoy."},"status":{"type":"string","enum":["in_stock","low_stock","out_of_stock"]},"restock_date":{"type":["string","null"],"format":"date","description":"Fecha estimada de resurtido si está agotado."}}},"promotion":{"type":["object","null"],"description":"Promoción vigente del producto."}}},"Promotion":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"sku":{"type":"string"},"product_name":{"type":"string"},"discount_pct":{"type":"integer"},"min_quantity":{"type":"integer","description":"Empaques mínimos para aplicar."},"valid_from":{"type":"string","format":"date"},"valid_until":{"type":"string","format":"date"}}}}}}