REST · JSON · UTF-8

API de TiendaCloud

Conecta tu inventario con tu sitio web, ERP o cualquier sistema externo. Endpoints REST con autenticación por API key, paginación con cursor y límites de uso por llave. Sin SDKs propietarios — cualquier cliente HTTP estándar funciona.

Base URL

tiendacloud.app

Versión

v1

Cuota default

120 req/min

Autenticación

Bearer Token o x-api-key

Cada solicitud necesita una API key. Pasa la llave por uno de estos dos headers — el primero es el estándar moderno, el segundo existe por compatibilidad con clientes legacy.

bash
# Recomendado
Authorization: Bearer tcsk_live_…

# Alternativa
x-api-key: tcsk_live_…

Llaves de producción vs. de pruebas

Cuando creas una API key desde la app, eliges su modo. El prefijo identifica visualmente para qué sirve:

  • tcsk_live_…Para uso en producción. Conecta a tus datos reales y cuenta para tu cuota normal.
  • tcsk_test_…Para integraciones en desarrollo. Mismos datos, marcador para que tu equipo distinga.

Solo el propietario de la tienda puede crear y revocar llaves. Cada llave se muestra una sola vez en su creación — guárdala en un gestor de secretos. Si la pierdes, revócala y crea una nueva.

Cuotas

Rate limits y headers

La cuota por defecto es 120 solicitudes por minuto por llave. Cada respuesta incluye estos headers para que tu cliente pueda auto-regular:

HeaderSignificado
X-RateLimit-LimitMáximo permitido por minuto.
X-RateLimit-RemainingSolicitudes restantes en la ventana actual.
X-RateLimit-ResetUNIX timestamp en segundos cuando la ventana se reinicia.
Retry-AfterSolo en 429. Segundos a esperar antes de reintentar.

Si necesitas un cupo mayor, escríbenos: soporte@tiendacloud.app.

Errores

Envoltura consistente

Todos los errores devuelven una estructura predecible. El campo code es un enum estable que puedes usar para ramificar lógica; el request_id te sirve para abrir un caso de soporte si algo falla de nuestro lado.

json
{
  "error":      "Invalid or revoked API key.",
  "code":       "invalid_api_key",
  "request_id": "req_8K2pX9aB4cD6fH1jL"
}

Códigos de error

codeHTTPCausa
missing_api_key401No se envió ningún header de autenticación.
invalid_api_key401El API key no existe o fue revocado.
invalid_limit400El parámetro limit no es un número entre 1 y 500.
invalid_cursor400El cursor no tiene formato UUID.
rate_limited429Excediste el cupo. Incluye Retry-After: 60 segundos.
internal_error500Algo falló de nuestro lado. Reintenta o contáctanos con el request_id.

Endpoints

GET /api/public/v1/inventory

Devuelve los productos activos de tu tienda con el stock sumado entre todas tus sucursales.

Query params

ParámetroTipoDescripción
limitinteger · opcionalProductos por página. Entre 1 y 500. Por defecto 100.
cursoruuid · opcionalEl next_cursor de la respuesta anterior. Omítelo en la primera llamada.

Solicitud

bash
curl -X GET 'https://tiendacloud.app/api/public/v1/inventory?limit=100' \
  -H 'Authorization: Bearer tcsk_live_…' \
  -H 'Accept: application/json'
javascript
const response = await fetch(
  'https://tiendacloud.app/api/public/v1/inventory?limit=100',
  {
    headers: {
      'Authorization': `Bearer ${process.env.TIENDACLOUD_API_KEY}`,
      'Accept':        'application/json',
    },
  },
)

if (!response.ok) {
  const { error, code, request_id } = await response.json()
  throw new Error(`[${code}] ${error} (${request_id})`)
}

const { products, pagination } = await response.json()
console.log(`${products.length} productos · ${pagination.has_more ? 'hay más' : 'fin'}`)
python
import os, requests

resp = requests.get(
    "https://tiendacloud.app/api/public/v1/inventory",
    headers={"Authorization": f"Bearer {os.environ['TIENDACLOUD_API_KEY']}"},
    params={"limit": 100},
)
resp.raise_for_status()
data = resp.json()

print(f"{len(data['products'])} productos")

Respuesta

json
{
  "products": [
    {
      "id":       "0c8f2e6a-1234-5678-90ab-cdef01234567",
      "name":     "Cargador 25W",
      "sku":      "CGR-25W-01",
      "price":    950,
      "category": "Cargadores",
      "quantity": 12
    }
  ],
  "pagination": {
    "limit":       100,
    "next_cursor": null,
    "has_more":    false
  }
}

Los precios están en pesos dominicanos (RD$) como números — sin separadores de miles ni símbolo de moneda.

Paginación

Cursor-based

Cuando hay más resultados, la respuesta incluye pagination.next_cursor y has_more: true. Páralo cuando has_more sea false.

javascript
let cursor = null
do {
  const url = new URL('https://tiendacloud.app/api/public/v1/inventory')
  url.searchParams.set('limit', '100')
  if (cursor) url.searchParams.set('cursor', cursor)

  const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } })
  const { products, pagination } = await res.json()

  for (const p of products) handle(p)
  cursor = pagination.next_cursor
} while (cursor)

Especificación

OpenAPI 3.1

La descripción formal de la API está disponible en /api/openapi.json. Impórtala en Postman, Insomnia, o úsala con generadores de SDKs (openapi-generator, oazapfts, fern, etc.) para que tus clientes salgan tipados automáticamente.

Soporte

Contacto

¿Algo no funciona como esperas? Escribe a soporte@tiendacloud.app e incluye el request_id que devolvimos. Eso nos permite encontrar exactamente la solicitud que te dio problema en nuestros logs.