Saltar al contenido principal

Documentation Index

Fetch the complete documentation index at: https://docs.play2sell.com/llms.txt

Use this file to discover all available pages before exploring further.

Autenticación

Prueba peticiones firmadas en el navegador en el Sandbox de la API — pega tu API key y secret, y el playground firma las peticiones automáticamente.
La API de Integración de SalesOS usa el esquema de peticiones firmadas P2S-SIGN-V1 en el header Authorization. Las API Keys tienen alcance a un solo tenant, se hashean con bcrypt y soportan límites de tasa y listas de IPs permitidas.
EsquemaCuándo usarFormato
P2S-SIGN-V1Llamadas server-to-server — firmadas con el secret de la API keyP2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE

Entornos

URL Base: https://api.play2sell.comDashboard: https://dashboard.play2sell.comApp: https://app.play2sell.com

Inicio Rápido

1. Crear una API Key

Ve a Integraciones > API Keys en el Dashboard de SalesOS:
  1. Haz clic en Crear API Key
  2. Nombra tu clave (ej., “Sincronización Nocturna CRM”, “Integración Formulario Web”)
  3. Selecciona el alcance: default:sync
  4. Haz clic en Crear
  5. Copia los dos valores inmediatamente — solo se muestran una vez:
    • API Key — identificador público, ej. sk_live_a1b2c3d4...
    • API Key Secret — usado para firmar peticiones, nunca se envía por la red

2. Firma y Envía una Petición

Para llamadas server-to-server, construye el header Authorization como P2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE. La SIGNATURE es el HMAC-SHA256 hex de una cadena de claves derivadas en 5 pasos:
  1. k1 = HMAC_SHA256(key=API_KEY_SECRET, msg=API_KEY)
  2. k2 = HMAC_SHA256(key=k1, msg=TIMESTAMP)
  3. k3 = HMAC_SHA256(key=k2, msg=METHOD)
  4. k4 = HMAC_SHA256(key=k3, msg=PATH)
  5. SIG = HMAC_SHA256_HEX(key=k4, msg=PAYLOAD_SHA256_HEX)
TIMESTAMP es Unix epoch en segundos, válido por 30 segundos. PAYLOAD_SHA256_HEX es el SHA-256 hex en minúsculas del cuerpo bruto de la petición (usa el digest de la cadena vacía e3b0c4...b855 cuando no haya body).
import crypto from 'node:crypto';

const API_KEY = process.env.SALESOS_API_KEY;
const SECRET  = process.env.SALESOS_API_SECRET;

const hmac = (key, msg) =>
  crypto.createHmac('sha256', key).update(msg).digest();

async function signedRequest(method, path, body) {
  const ts          = Math.floor(Date.now() / 1000).toString();
  const bodyStr     = body ? JSON.stringify(body) : '';
  const payloadHash = crypto.createHash('sha256').update(bodyStr).digest('hex');

  const k1  = hmac(SECRET, API_KEY);
  const k2  = hmac(k1, ts);
  const k3  = hmac(k2, method);
  const k4  = hmac(k3, path);
  const sig = hmac(k4, payloadHash).toString('hex');

  const res = await fetch(`https://api.play2sell.com${path}`, {
    method,
    headers: {
      Authorization: `P2S-SIGN-V1 ${API_KEY}:${ts}:${sig}`,
      'Content-Type': 'application/json',
    },
    body: bodyStr || undefined,
  });
  return res.json();
}
¿No quieres escribir el código de firma todavía? El Sandbox de la API firma las peticiones por ti en el navegador — pega tu API key y secret, luego haz clic en Try it out.

3. Verificar la Respuesta

Éxito (200):
{
  "data": { "created": 1, "existing": 0, "errors": [], "total": 1 },
  "meta": { "request_id": "f47ac10b-...", "timestamp": "2026-03-17T10:30:00.000Z" }
}
Firma inválida o timestamp expirado (401):
{
  "error": { "code": "UNAUTHORIZED", "message": "Invalid signature for P2S-SIGN-V1 request" }
}

Propiedades de la API Key

PropiedadDetalles
Prefijosk_live_ (producción) o sk_test_ (pruebas)
Alcancedefault:sync — habilita sync_collaborators y sync_activities
Límite de tasaConfigurable por clave (por defecto: 1000 solicitudes/hora)
ExpiraciónOpcional — establece una fecha de vencimiento o déjala sin expirar
Lista de IPs permitidasOpcional — restringe a direcciones IP específicas
AlmacenamientoHasheada con bcrypt — la clave en texto plano nunca se almacena

Formatos de Clave

SalesOS usa dos prefijos de clave para distinguir ambientes:
PrefijoAmbienteCaso de uso
sk_live_ProducciónDatos reales, misiones reales, puntos reales
sk_test_PruebasSeguro para usar durante desarrollo — sin impacto en producción
Usa claves sk_test_ durante el desarrollo y las pruebas de integración. Cambia a sk_live_ cuando pases a producción.

Errores de Autenticación

Estado HTTPCódigo de ErrorSignificadoQué hacer
401UNAUTHORIZEDLa clave falta, es inválida o expiróVerifica el header Authorization. Confirma la clave en el Dashboard.
403FORBIDDENLa clave es válida pero no tiene el alcance requeridoEdita la clave y agrega el alcance default:sync
429RATE_LIMITEDDemasiadas solicitudes en esta horaEspera retry_after segundos, luego reintenta

Ejemplo: Header Authorization faltante

curl -X POST https://api.play2sell.com/functions/v1/default-integration \
  -H "Content-Type: application/json" \
  -d '{"action": "sync_collaborators", "collaborators": [...]}'
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Missing or malformed Authorization header"
  }
}

Ejemplo: Firma inválida

Una firma que no coincide con la que recalcula el servidor — generalmente causada por un cambio en el body después de firmar, una divergencia en la canonicalización del path, o una clave desactualizada:
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid signature for P2S-SIGN-V1 request"
  }
}

Ejemplo: Timestamp fuera de la ventana de 30s

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Request timestamp is outside the 30-second validity window"
  }
}

Ejemplo: Clave sin el alcance requerido

Si tu clave solo tiene leads:read pero el endpoint requiere default:sync:
{
  "error": {
    "code": "FORBIDDEN",
    "message": "API key missing required scopes: default:sync"
  }
}

Ejemplo: Límite de tasa excedido

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded",
    "retry_after": 1847
  }
}
El campo retry_after indica cuántos segundos debes esperar. La ventana de límite de tasa se reinicia cada hora.

Límites de Tasa

Cada API key tiene un contador de límite de tasa independiente que se reinicia cada hora:
ConfiguraciónPor defectoRango
Solicitudes por hora10001 — 100,000
Cómo funciona:
  1. Cada solicitud exitosa incrementa el contador
  2. Cuando el contador alcanza el límite, las solicitudes siguientes retornan 429
  3. El contador se reinicia a 0 una hora después de la primera solicitud en la ventana
Manejo de límites de tasa en código:
// signedRequest() es el helper del Inicio Rápido de arriba.
async function callWithRetry(method, path, body) {
  const response = await signedRequest(method, path, body);

  if (response.status === 429) {
    const { error } = await response.json();
    const waitSeconds = error.retry_after || 60;
    console.log(`Rate limited. Retrying in ${waitSeconds}s...`);
    await new Promise(r => setTimeout(r, waitSeconds * 1000));
    return callWithRetry(method, path, body); // retry
  }

  return response.json();
}

Mejores Prácticas de Seguridad

Nunca expongas API keys en código del lado del cliente. JavaScript en el navegador, aplicaciones móviles y repositorios públicos pueden filtrar tu clave. Siempre llama a la API de SalesOS desde tu servidor backend.
  • Usa variables de entorno — Almacena SALESOS_API_KEY en variables de entorno o un gestor de secretos, nunca en el código fuente
  • Rota las claves periódicamente — Crea una nueva clave, actualiza tu integración, luego revoca la anterior
  • Usa listas de IPs permitidas — Si tu integración se ejecuta desde IPs fijas, restringe la clave solo a esas IPs
  • Monitorea el uso — Revisa los logs de uso de la API en el Dashboard para detectar patrones inesperados
  • Usa sk_test_ para desarrollo — Las claves de prueba aíslan tu ambiente de desarrollo de producción
  • Revoca claves comprometidas inmediatamente — Ve a Dashboard > Admin > API Keys > Revocar

Ejemplo de rotación de claves

# 1. Crea una nueva clave en el Dashboard → copia ambos valores:
#    - SALESOS_API_KEY=sk_live_NEW_KEY
#    - SALESOS_API_SECRET=NEW_SECRET
# 2. Actualiza ambas variables de entorno en tu deployment.
# 3. Verifica que funciona usando el helper de petición firmada del Inicio
#    Rápido (Node, Python o Bash). Payload de ejemplo:
#    { "action": "sync_collaborators",
#      "collaborators": [{"external_id":"test","name":"Test","email":"test@co.com"}] }
# 4. Revoca la clave antigua en el Dashboard.

Proximos Pasos

Integracion por Defecto

Comienza a enviar actividades a SalesOS

API Keys

Gestiona claves programaticamente