Saltar al contenido
Menú de documentos

API REST

Clientes

Listar clientes comerciales, leer los descuentos, precios acordados y compradores de un cliente, y crear o actualizar clientes.

Un cliente es una cuenta comercial: una empresa a la que vende, con un código de cuenta, un descuento de cuenta opcional y las personas (compradores) que pueden iniciar sesión para realizar pedidos por su cuenta.

El objeto clienteEnlace a esta sección#

json
{
  "id": "7d2e4f0a-1b3c-4d5e-8f90-a1b2c3d4e5f6",
  "accountCode": "OAK01",
  "name": "Oakfield Joinery",
  "legalName": "Oakfield Joinery Ltd",
  "email": "accounts@oakfieldjoinery.co.uk",
  "discountBp": 500,
  "active": true,
  "newsOptOut": false,
  "catalogueScope": "all",
  "createdAt": "2026-07-02T10:12:44.000Z"
}
CampoTipoDescripción
idstringIdentificador del cliente.
accountCodestringSu código de cuenta. Único en el espacio de trabajo, ignorando mayúsculas. Puede cambiarse en la aplicación, por lo que conserve el id para cualquier cosa de largo plazo.
namestringNombre comercial.
legalNamestring o nuloNombre registrado, cuando es diferente.
emailstring o nuloCorreo electrónico principal, en minúsculas.
discountBpentero o nuloEl porcentaje propio del cliente sobre el listado completo, en puntos básicos. null para ninguno.
adjustmentstringdiscount (eliminado de la lista) o markup (añadido). Los clientes existentes son discount.
activebooleanoLos clientes inactivos no pueden iniciar sesión ni realizar pedidos.
newsOptOutbooleanoEl cliente desactivó las ofertas y correos electrónicos de noticias. Los correos electrónicos de cambios de precio aún se envían.
catalogueScopestringall (ve todo el catálogo) o approved (ve y ordena solo su lista aprobada). Se establece en la página del cliente; de solo lectura en la API.
createdAtstringCuando se agregó al cliente.

En cualquier lugar donde la API tome un cliente, puede usar el id o el accountCode.

Listar clientesEnlace a esta sección#

GET/api/v1/customers

Todos los clientes, ordenados por nombre.

NombreTipoRequeridoDescripción
limitenterono1 a 100. Valor predeterminado 100.
offsetenteronoFilas a omitir. Valor predeterminado 0.
bash
curl "https://tradecatalog.app/api/v1/customers?limit=100" \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const res = await fetch('https://tradecatalog.app/api/v1/customers?limit=100', {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: customers, nextOffset } = await res.json()
json
{
  "data": [
    {
      "id": "7d2e4f0a-1b3c-4d5e-8f90-a1b2c3d4e5f6",
      "accountCode": "OAK01",
      "name": "Oakfield Joinery",
      "legalName": "Oakfield Joinery Ltd",
      "email": "accounts@oakfieldjoinery.co.uk",
      "discountBp": 500,
      "active": true,
      "newsOptOut": false,
      "catalogueScope": "all",
      "createdAt": "2026-07-02T10:12:44.000Z"
    }
  ],
  "nextOffset": null
}

Obtener un clienteEnlace a esta sección#

GET/api/v1/customers/{id}

El cliente más todo lo que afecta a sus precios, y quién puede iniciar sesión por ellos.

NombreEnTipoRequeridoDescripción
idrutastringsíIdentificador del cliente o código de cuenta.
bash
curl https://tradecatalog.app/api/v1/customers/OAK01 \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
js
const res = await fetch('https://tradecatalog.app/api/v1/customers/OAK01', {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: customer } = await res.json()
json
{
  "data": {
    "id": "7d2e4f0a-1b3c-4d5e-8f90-a1b2c3d4e5f6",
    "accountCode": "OAK01",
    "name": "Oakfield Joinery",
    "legalName": "Oakfield Joinery Ltd",
    "email": "accounts@oakfieldjoinery.co.uk",
    "discountBp": 500,
    "priceListId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "priceList": "Standard",
    "active": true,
    "newsOptOut": false,
    "createdAt": "2026-07-02T10:12:44.000Z",
    "discountRules": [
      {
        "id": "d0e1f2a3-4b5c-4d6e-9f7a-8b9c0d1e2f3a",
        "scope": "product",
        "discountBp": 2000,
        "productId": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
        "sku": "HX-8510",
        "target": "Hex bolt M10 x 50 zinc",
        "list": 2280,
        "unit": 1824
      },
      {
        "id": "e1f2a3b4-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
        "scope": "brand",
        "discountBp": 1500,
        "productId": null,
        "sku": null,
        "target": "Northgate",
        "list": null,
        "unit": null
      },
      {
        "id": "f2a3b4c5-6d7e-4f80-9a1b-2c3d4e5f6a7b",
        "scope": "category",
        "discountBp": 1250,
        "productId": null,
        "sku": null,
        "target": "Hinges",
        "list": null,
        "unit": null
      }
    ],
    "agreedPrices": [
      {
        "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
        "productId": "6c7d8e9f-0a1b-4c2d-9e3f-4a5b6c7d8e9f",
        "price": 1450,
        "note": "Contract price to March 2027",
        "noteVisible": true,
        "internalNote": "Agreed with their buyer",
        "sku": "HX-8512",
        "name": "Hex bolt M12 x 50 zinc",
        "list": 1980,
        "unit": 1450
      }
    ],
    "buyers": [{ "name": "Sam Patel", "email": "sam@oakfieldjoinery.co.uk" }],
    "pendingInvitations": [{ "email": "orders@oakfieldjoinery.co.uk" }]
  },
  "currency": "GBP"
}
CampoDescripción
priceListNombre de la lista de precios de la que compra este cliente. priceListId es el id de esa lista. Un producto sin precio en la lista tiene precio bajo petición.
discountRulesPorcentajes de producto, categoría y marca. scope es product, category o brand; adjustment es discount o markup; target es su nombre. Las reglas de producto también proporcionan sku, list y unit (lo que pagan).
agreedPricesPrecios acordados (fijos) válidos ahora, por SKU, en unidades menores, con el precio list actual y el precio unit que pagan. note es el comentario; noteVisible indica si ese cliente lo ve. internalNote es solo para personal y nunca se muestra al cliente.
buyersPersonas que pueden iniciar sesión y realizar pedidos por este cliente.
pendingInvitationsInvitaciones enviadas pero no aceptadas, y no caducadas.

Vea cómo se calculan los precios para ver cómo se combinan.

Crear o actualizar clientesEnlace a esta sección#

PUT/api/v1/customersescribir clave

Envíe hasta 100 clientes por llamada. Cada fila se compara con un cliente existente de la siguiente manera:

  1. Si se establece accountCode, por código de cuenta. Sin coincidencia significa un nuevo cliente con ese código.
  2. De lo contrario, si se establece email, por correo electrónico. Sin coincidencia significa un nuevo cliente.
  3. De lo contrario por nombre, ignorando mayúsculas.

Los nuevos clientes sin código de cuenta reciben uno generado a partir de su nombre.

CuerpoEnlace a esta sección#

CampoTipoRequeridoDescripción
customersmatrizsí1 a 100 clientes. Los códigos de cuenta deben ser únicos dentro de la llamada.
customers[].accountCodecadena o nulosíMáximo 50 caracteres. null para coincidir por correo electrónico o nombre.
customers[].namecadenasíNombre comercial, máximo 160 caracteres.
customers[].emailcadena o nulosíCorreo electrónico principal de contacto. null lo borra.
customers[].discountBpentero o nulosíPorcentaje de lista completa, 0 a 10.000, para un descuento o recargo. null lo borra.
customers[].adjustmentdiscount o markupnoLa forma en que discountBp mueve el precio. Omita para dejar la dirección actual. Los nuevos clientes tienen como predeterminado discount.
customers[].priceListcadena o nulonoNombre de una lista de precios existente. Omita para dejar la lista sin cambios. null coloca al cliente en Standard. Un nombre desconocido se rechaza.
customers[].regioncadena o nulonoNombre de una región existente. Omita para dejar la región sin cambios. null la borra. Un nombre desconocido se rechaza.
customers[].repcadena o nulonoCorreo electrónico o nombre de usuario de un miembro del personal asignado a este cliente. Omita para dejar al representante sin cambios. null lo borra. Un correo electrónico o nombre de usuario desconocido se rechaza.

accountCode, name, email y discountBp son obligatorios y se escriben como se envían: null borra email y discountBp. De esta forma, un campo faltante en su código no puede dejar en silencio un porcentaje antiguo en su lugar. adjustment y priceList son opcionales: deje adjustment fuera para mantener un recargo o un descuento como está.

La hoja de cálculo del cliente tiene la misma opción. Junto con el descuento % puede tener una columna de ajuste (discount o markup), una columna de lista de precios y una columna de representante de ventas. La celda del representante es el correo electrónico de esa persona, o su nombre de usuario cuando se inicia sesión sin correo electrónico. Una celda en blanco deja ese campo como está. Un nombre de lista desconocido o un representante es un error en esa fila.

Actualizar un cliente no envía correos electrónicos ni invita a compradores. Invite a compradores desde la página del cliente en la aplicación. El nombre registrado, el estado activo, las reglas de descuento y los precios acordados también se cambian en la aplicación.

bash
curl -X PUT https://tradecatalog.app/api/v1/customers \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customers": [
      {
        "accountCode": "OAK01",
        "name": "Oakfield Joinery",
        "email": "accounts@oakfieldjoinery.co.uk",
        "discountBp": 500
      },
      {
        "accountCode": "BRK07",
        "name": "Brookside Builders",
        "email": null,
        "discountBp": null
      }
    ]
  }'
js
const res = await fetch('https://tradecatalog.app/api/v1/customers', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ customers }),
})
const { data } = await res.json()
console.log(`${data.created} new, ${data.updated} updated`)
json
{
  "data": { "created": 1, "updated": 1 }
}

El cambio aparece en el registro de actividad como el nombre de la clave.