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.
# 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:
| Header | Significado |
|---|---|
| X-RateLimit-Limit | Máximo permitido por minuto. |
| X-RateLimit-Remaining | Solicitudes restantes en la ventana actual. |
| X-RateLimit-Reset | UNIX timestamp en segundos cuando la ventana se reinicia. |
| Retry-After | Solo 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.
{
"error": "Invalid or revoked API key.",
"code": "invalid_api_key",
"request_id": "req_8K2pX9aB4cD6fH1jL"
}Códigos de error
| code | HTTP | Causa |
|---|---|---|
| missing_api_key | 401 | No se envió ningún header de autenticación. |
| invalid_api_key | 401 | El API key no existe o fue revocado. |
| invalid_limit | 400 | El parámetro limit no es un número entre 1 y 500. |
| invalid_cursor | 400 | El cursor no tiene formato UUID. |
| rate_limited | 429 | Excediste el cupo. Incluye Retry-After: 60 segundos. |
| internal_error | 500 | Algo 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ámetro | Tipo | Descripción |
|---|---|---|
| limit | integer · opcional | Productos por página. Entre 1 y 500. Por defecto 100. |
| cursor | uuid · opcional | El next_cursor de la respuesta anterior. Omítelo en la primera llamada. |
Solicitud
curl -X GET 'https://tiendacloud.app/api/public/v1/inventory?limit=100' \
-H 'Authorization: Bearer tcsk_live_…' \
-H 'Accept: application/json'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'}`)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
{
"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.
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.