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

Ashley Innocent

Ashley Innocent

20 March 2026

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

Apidog para empresas

Despliegue local

SSO & RBAC

Conforme con SOC 2

Explorar Apidog Enterprise

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.

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:

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/

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

Antes de acceder a la API, necesita una cuenta de desarrollador:

  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

Rellene el formulario de registro de la aplicación:

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

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"

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)

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()}`;
};

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

console.log(`Redirect user to: ${authUrl}`);

Á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();

  // Store these securely in your database
  return {
    access_token: data.access_token,
    refresh_token: data.refresh_token,
    expires_in: data.expires_in, // Typically 3600 seconds (1 hour)
    user_id: data.user_id,
    scope: data.scope
  };
};

// Handle callback route
app.get('/callback', async (req, res) => {
  const { code, state } = req.query;

  // Verify state matches what you sent (CSRF protection)
  if (state !== req.session.oauthState) {
    return res.status(400).send('Invalid state parameter');
  }

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

    // Store tokens in database associated with user
    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('Token exchange failed:', error);
    res.status(500).send('Authentication failed');
  }
});

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();

  // Update stored tokens
  return {
    access_token: data.access_token,
    refresh_token: data.refresh_token, // Always save the new refresh token
    expires_in: data.expires_in
  };
};

// Middleware to ensure valid token before API calls
const ensureValidToken = async (userId) => {
  const user = await db.users.findById(userId);

  // Check if token expires within 5 minutes
  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;
};

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();
};

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;
};

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

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"
}

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;
};

// Example response
{
  "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
    }
  ]
}

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(), // Must be string
    quantity: listingData.quantity,
    sku: listingData.sku || [],
    tags: listingData.tags.slice(0, 13), // Max 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 for craft supplies
    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 || [] // Max 2 styles
  };

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

  return response;
};

// Usage example
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'
});

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) => {
  // Read image file as 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' // For accessibility
  };

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

  return response;
};

// Upload multiple images
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;
};

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs