DEV Community

Cover image for Cómo Usar la API de Etsy: Guía Completa de Integración (2026)
Roobia
Roobia

Posted on • Originally published at apidog.com

Cómo Usar la API de Etsy: Guía Completa de Integración (2026)

En resumen

La API de Etsy permite a los desarrolladores crear aplicaciones que interactúan con el marketplace de Etsy. Utiliza autenticación OAuth 2.0, puntos finales RESTful para tiendas, listados, pedidos y gestión de inventario, con límites de tasa de 10 llamadas por segundo por aplicación. Esta guía cubre la configuración de autenticación, los puntos finales principales, la integración de webhooks y las estrategias de despliegue en producción.

Prueba Apidog hoy mismo

Introducción

Etsy procesa más de $13 mil millones en ventas brutas anuales de mercancías en más de 230 países. Para los desarrolladores que crean herramientas de comercio electrónico, sistemas de gestión de inventario o plataformas de análisis, la integración de la API de Etsy no es opcional, es esencial.

Esta es la realidad: los vendedores que gestionan múltiples canales de venta pierden entre 15 y 20 horas semanales en la entrada manual de datos. Una sólida integración con la API de Etsy automatiza la sincronización de listados, el procesamiento de pedidos y las actualizaciones de inventario en todas las plataformas.

Esta guía le guiará a través de todo el proceso de integración de la API de Etsy. Aprenderá sobre la autenticación OAuth 2.0, la gestión de tiendas y listados, el procesamiento de pedidos, el manejo de webhooks y la resolución de problemas de errores. Al final, tendrá una integración de Etsy lista para producción.

💡 Apidog simplifica las pruebas de integración de API. Pruebe sus puntos finales de Etsy, valide flujos de OAuth, inspeccione cargas de webhook y depure problemas de autenticación en un solo espacio de trabajo. Importe especificaciones de API, respuestas simuladas y comparta escenarios de prueba con su equipo.

¿Qué es la API de Etsy?

Etsy proporciona una API RESTful para acceder a los datos del marketplace y gestionar las operaciones del vendedor. La API maneja:

  • Recuperación de información de la tienda y del perfil
  • Creación, actualización y gestión de inventario de listados
  • Procesamiento de pedidos y seguimiento de envíos
  • Acceso a datos de clientes y transacciones
  • Perfiles de envío y cálculos de impuestos
  • Gestión de carga de imágenes y medios

Características clave

Característica Descripción
Diseño RESTful Métodos HTTP estándar con respuestas JSON
OAuth 2.0 Autenticación segura con actualización de token de acceso
Webhooks Notificaciones en tiempo real para eventos de pedidos y listados
Limitación de Tasa 10 solicitudes por segundo por aplicación (con asignación de ráfaga)
Soporte de Sandbox Entorno de prueba para desarrollo sin datos reales

Visión general de la arquitectura de la API

Etsy utiliza una estructura de API REST versionada:

https://openapi.etsy.com/v3/application/
Enter fullscreen mode Exit fullscreen mode

La Versión 3 (v3) es el estándar actual, ofreciendo un soporte OAuth 2.0 mejorado y estructuras de puntos finales simplificadas en comparación con la v2.

Comparación de versiones de API

Versión Estado Autenticación Caso de Uso
V3 Actual OAuth 2.0 Todas las nuevas integraciones
V2 Obsoleta OAuth 1.0a Solo aplicaciones heredadas
V1 Retirada N/A No usar

Migre cualquier integración de V2 a V3 inmediatamente. Etsy anunció la obsolescencia de V2 con su retirada completa programada para finales de 2026.

Primeros pasos: Configuración de la autenticación

Paso 1: Cree su cuenta de desarrollador de Etsy

  1. Visite el Portal de Desarrolladores de Etsy
  2. Inicie sesión con su cuenta de Etsy (o cree una)
  3. Navegue a Sus Aplicaciones en el panel de control del desarrollador
  4. Haga clic en Crear una nueva aplicación

Paso 2: Registre su aplicación

Complete el formulario de registro de la aplicación:

  • Nombre de la Aplicación: Nombre claro y descriptivo (visible para los usuarios durante OAuth)
  • Descripción de la Aplicación: Explique qué hace su aplicación y quién la usa
  • URI de Redirección: Donde Etsy envía a los usuarios después de la autenticación (debe usar HTTPS)
  • Producción/Desarrollo: Comience con el modo de desarrollo para las pruebas

Después de la presentación, recibirá:

  • Cadena de Clave (Key String): Su identificador de API público
  • Secreto Compartido (Shared Secret): Su secreto de API privado (nunca lo exponga)

Nota de seguridad: Almacene las credenciales en variables de entorno, nunca en el código:

# .env file
ETSY_KEY_STRING="your_key_string_here"
ETSY_SHARED_SECRET="your_shared_secret_here"
ETSY_ACCESS_TOKEN="generated_via_oauth"
ETSY_REFRESH_TOKEN="generated_via_oauth"
Enter fullscreen mode Exit fullscreen mode

Paso 3: Comprenda el flujo de OAuth 2.0

Etsy utiliza OAuth 2.0 para la autenticación. Aquí está el flujo completo:

1. El usuario hace clic en "Conectar con Etsy" en su aplicación
2. Su aplicación redirige a la URL de autorización de Etsy
3. El usuario inicia sesión y otorga permisos
4. Etsy redirige de vuelta con el código de autorización
5. Su aplicación intercambia el código por un token de acceso
6. Su aplicación usa el token de acceso para las llamadas a la API
7. Actualice el token cuando el token de acceso expire (1 hora)
Enter fullscreen mode Exit fullscreen mode

Paso 4: Implementar la autorización OAuth

Genere la URL de autorización:

const generateAuthUrl = (clientId, redirectUri, state) => {
  const baseUrl = 'https://www.etsy.com/oauth/connect';
  const params = new URLSearchParams({
    client_id: clientId,
    redirect_uri: redirectUri,
    scope: 'listings_r listings_w orders_r orders_w shops_r',
    state: state, // Random string for CSRF protection
    response_type: 'code'
  });

  return `${baseUrl}?${params.toString()}`;
};

// Uso
const authUrl = generateAuthUrl(
  process.env.ETSY_KEY_STRING,
  'https://your-app.com/callback',
  crypto.randomBytes(16).toString('hex')
);

console.log(`Redirige al usuario a: ${authUrl}`);
Enter fullscreen mode Exit fullscreen mode

Ámbitos requeridos

Solicite solo los permisos que su aplicación necesita:

Ámbito Descripción Caso de Uso
listings_r Leer listados Mostrar productos, sincronizar inventario
listings_w Escribir listados Crear/actualizar productos
orders_r Leer pedidos Gestión de pedidos, cumplimiento
orders_w Escribir pedidos Actualizar estado de pedido, añadir seguimiento
shops_r Leer información de la tienda Mostrar perfil de la tienda, análisis
transactions_r Leer transacciones Informes financieros
email Acceder al correo electrónico del comprador Comunicación de pedidos

Paso 5: Intercambiar Código por Token de Acceso

Maneje la devolución de llamada de OAuth e intercambie el código de autorización:

const exchangeCodeForToken = async (code, redirectUri) => {
  const response = await fetch('https://api.etsy.com/v3/public/oauth/token', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: process.env.ETSY_KEY_STRING,
      client_secret: process.env.ETSY_SHARED_SECRET,
      redirect_uri: redirectUri,
      code: code
    })
  });

  const data = await response.json();

  // Almacene estos datos de forma segura en su base de datos
  return {
    access_token: data.access_token,
    refresh_token: data.refresh_token,
    expires_in: data.expires_in, // Normalmente 3600 segundos (1 hora)
    user_id: data.user_id,
    scope: data.scope
  };
};

// Manejo de la ruta de callback
app.get('/callback', async (req, res) => {
  const { code, state } = req.query;

  // Verifique que el state coincida (protección CSRF)
  if (state !== req.session.oauthState) {
    return res.status(400).send('Parámetro state inválido');
  }

  try {
    const tokens = await exchangeCodeForToken(code, 'https://your-app.com/callback');

    // Almacene los tokens en la base de datos asociados al usuario
    await db.users.update(req.session.userId, {
      etsy_access_token: tokens.access_token,
      etsy_refresh_token: tokens.refresh_token,
      etsy_token_expires: Date.now() + (tokens.expires_in * 1000),
      etsy_user_id: tokens.user_id
    });

    res.redirect('/dashboard');
  } catch (error) {
    console.error('Intercambio de token fallido:', error);
    res.status(500).send('Fallo en la autenticación');
  }
});
Enter fullscreen mode Exit fullscreen mode

Paso 6: Implementar la actualización del token

Los tokens de acceso expiran después de 1 hora. Implemente la actualización automática:

const refreshAccessToken = async (refreshToken) => {
  const response = await fetch('https://api.etsy.com/v3/public/oauth/token', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      client_id: process.env.ETSY_KEY_STRING,
      client_secret: process.env.ETSY_SHARED_SECRET,
      refresh_token: refreshToken
    })
  });

  const data = await response.json();

  // Actualice los tokens almacenados
  return {
    access_token: data.access_token,
    refresh_token: data.refresh_token, // Guarde siempre el nuevo refresh token
    expires_in: data.expires_in
  };
};

// Middleware para asegurar token válido antes de llamadas API
const ensureValidToken = async (userId) => {
  const user = await db.users.findById(userId);

  // ¿El token expira en menos de 5 minutos?
  if (user.etsy_token_expires < Date.now() + 300000) {
    const newTokens = await refreshAccessToken(user.etsy_refresh_token);

    await db.users.update(userId, {
      etsy_access_token: newTokens.access_token,
      etsy_refresh_token: newTokens.refresh_token,
      etsy_token_expires: Date.now() + (newTokens.expires_in * 1000)
    });

    return newTokens.access_token;
  }

  return user.etsy_access_token;
};
Enter fullscreen mode Exit fullscreen mode

Paso 7: Realizar llamadas a la API autenticadas

Incluya el token de acceso en cada solicitud:

const makeEtsyRequest = async (endpoint, options = {}) => {
  const accessToken = await ensureValidToken(options.userId);

  const response = await fetch(`https://openapi.etsy.com/v3/application${endpoint}`, {
    ...options,
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'x-api-key': process.env.ETSY_KEY_STRING,
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      ...options.headers
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Etsy API Error: ${error.message}`);
  }

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

Puntos finales de gestión de la tienda

Recuperación de información de la tienda

Obtenga los detalles de la tienda, políticas y configuraciones:

const getShopInfo = async (shopId) => {
  const response = await makeEtsyRequest(`/shops/${shopId}`, {
    method: 'GET'
  });

  return response;
};

// Uso
const shop = await getShopInfo(12345678);
console.log(`Shop: ${shop.title}`);
console.log(`Currency: ${shop.currency_code}`);
console.log(`Listings count: ${shop.num_listings_active}`);
Enter fullscreen mode Exit fullscreen mode

Respuesta esperada de la tienda

{
  "shop_id": 12345678,
  "shop_name": "MyHandmadeShop",
  "title": "Handmade Jewelry & Accessories",
  "announcement": "Welcome! Free shipping on orders over $50",
  "currency_code": "USD",
  "is_vacation": false,
  "vacation_message": null,
  "sale_message": "Thank you for supporting small businesses!",
  "digital_sale_message": null,
  "created_timestamp": 1609459200,
  "updated_timestamp": 1710950400,
  "num_listings_active": 127,
  "num_listings_sold": 1543,
  "gaussian_alphas": {
    "overall": 4.8,
    "last_30_days": 4.9
  },
  "vacation_autoreply": null,
  "url": "https://www.etsy.com/shop/MyHandmadeShop",
  "image_url_760x100": "https://i.etsystatic.com/.../banner_760x100.jpg"
}
Enter fullscreen mode Exit fullscreen mode

Recuperación de secciones de la tienda

Organice los listados por secciones:

const getShopSections = async (shopId) => {
  const response = await makeEtsyRequest(`/shops/${shopId}/sections`, {
    method: 'GET'
  });

  return response;
};

// Ejemplo de respuesta
{
  "count": 5,
  "results": [
    {
      "shop_section_id": 12345,
      "title": "Necklaces",
      "rank": 1,
      "num_listings": 23
    },
    {
      "shop_section_id": 12346,
      "title": "Earrings",
      "rank": 2,
      "num_listings": 45
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Gestión de listados

Creación de un nuevo listado

Cree un listado de producto con imágenes y variaciones:

const createListing = async (shopId, listingData) => {
  const payload = {
    title: listingData.title,
    description: listingData.description,
    price: listingData.price.toString(), // Debe ser string
    quantity: listingData.quantity,
    sku: listingData.sku || [],
    tags: listingData.tags.slice(0, 13), // Máx 13 tags
    category_id: listingData.categoryId,
    shop_section_id: listingData.sectionId,
    state: listingData.state || 'active', // active, inactive, draft
    who_made: listingData.whoMade, // i_did, someone_else, collective
    when_made: listingData.whenMade, // 2020_2026, 2010_2019, etc.
    is_supply: listingData.isSupply, // true para insumos de manualidades
    item_weight: listingData.weight || null,
    item_weight_unit: listingData.weightUnit || 'g',
    item_length: listingData.length || null,
    item_width: listingData.width || null,
    item_height: listingData.height || null,
    item_dimensions_unit: listingData.dimensionsUnit || 'mm',
    is_private: listingData.isPrivate || false,
    recipient: listingData.recipient || null, // men, women, unisex, etc.
    occasion: listingData.occasion || null, // birthday, wedding, etc.
    style: listingData.style || [] // Máx 2 estilos
  };

  const response = await makeEtsyRequest(`/shops/${shopId}/listings`, {
    method: 'POST',
    body: JSON.stringify(payload)
  });

  return response;
};

// Ejemplo de uso
const listing = await createListing(12345678, {
  title: 'Sterling Silver Moon Phase Necklace',
  description: 'Handcrafted sterling silver necklace featuring moon phases...',
  price: 89.99,
  quantity: 15,
  sku: ['MOON-NECKLACE-001'],
  tags: ['moon necklace', 'sterling silver', 'moon phase', 'celestial jewelry'],
  categoryId: 10623, // Jewelry > Necklaces
  sectionId: 12345,
  state: 'active',
  whoMade: 'i_did',
  whenMade: 'made_to_order',
  isSupply: false,
  weight: 25,
  weightUnit: 'g'
});
Enter fullscreen mode Exit fullscreen mode

Subir imágenes de listado

Las imágenes se cargan por separado después de la creación del listado:

const uploadListingImage = async (listingId, imagePath, imagePosition = 1) => {
  // Leer archivo de imagen como base64
  const fs = require('fs');
  const imageBuffer = fs.readFileSync(imagePath);
  const base64Image = imageBuffer.toString('base64');

  const payload = {
    image: base64Image,
    listing_image_id: null,
    position: imagePosition,
    is_watermarked: false,
    alt_text: 'Handcrafted sterling silver moon phase necklace' // Para accesibilidad
  };

  const response = await makeEtsyRequest(`/listings/${listingId}/images`, {
    method: 'POST',
    body: JSON.stringify(payload)
  });

  return response;
};

// Subir múltiples imágenes
const uploadListingImages = async (listingId, imagePaths) => {
  const results = [];

  for (let i = 0; i < imagePaths.length; i++) {
    const result = await uploadListingImage(listingId, imagePaths[i], i + 1);
    results.push(result);
  }

  return results;
};
Enter fullscreen mode Exit fullscreen mode

Top comments (0)