Authentication

The SalonBookIt API uses two authentication methods: API Keys to identify your business and JWT to authenticate customers.

Overview

Public

API Key

Identifies your business in each request. Required for all endpoints.

  • Obtained from the Dashboard
  • Sent in the header X-API-Key
  • Prefix hh_pub_ (pública) o hh_sec_ (privada)
Authenticated

JWT Token

Authenticates a specific customer. Required for private endpoints.

  • Obtained via /api/v1/auth/login/
  • Sent in the header Authorization
  • Expires in 24 hours

API Keys

Your API Key identifies your business and must be included in all API requests.

Get your API Key

  1. Log in to your Dashboard
  2. Go to Configuration → Integrations
  3. Click on Generate New API Key
  4. Asigna un nombre descriptivo (ej: "Widget Web", "App Móvil")
  5. Copy and save the API Key securely

Use the API Key

Include your API Key in the header X-API-Key of each request:

cURL
curl -X GET "https://app.salonbookit.com/api/v1/negocio/" \
  -H "X-API-Key: hh_pub_live_abc123def456..."
JavaScript
const response = await fetch('https://app.salonbookit.com/api/v1/servicios/', {
    headers: {
        'X-API-Key': 'hh_pub_live_abc123def456...'
    }
});
const data = await response.json();
Python
import requests

response = requests.get(
    'https://app.salonbookit.com/api/v1/servicios/',
    headers={'X-API-Key': 'hh_pub_live_abc123def456...'}
)
data = response.json()
PHP
$ch = curl_init('https://app.salonbookit.com/api/v1/servicios/');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: hh_pub_live_abc123def456...'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);

API Key types

Las API Keys tienen dos dimensiones: tipo (pública/privada) y entorno (producción/pruebas).

Por tipo

Prefix Type Usage
hh_pub_ Pública Para widgets y frontend. Permisos limitados a lectura y crear reservas.
hh_sec_ Privada Para backend. No exponer en código cliente.

Por entorno

Sufijo Environment Usage
_live_ Production Real data, real transactions
_test_ Testing Test data, no real charges

Ejemplos de formatos completos:

  • hh_pub_live_... - Pública de producción (para widgets en producción)
  • hh_pub_test_... - Pública de pruebas (para desarrollo de widgets)
  • hh_sec_live_... - Privada de producción (para tu backend)
  • hh_sec_test_... - Privada de pruebas (para desarrollo backend)
API Key security

Never include your API Key in client-side code that is publicly visible. For the widget, we use an API Key with limited permissions that only allows read operations and booking creation.

JWT Authentication

Endpoints requiring customer authentication use JWT tokens. These endpoints include:

  • View customer bookings
  • View/modify customer profile
  • Check loyalty points
  • View order history

Get a JWT token

POST /api/v1/auth/login/

Request

cURL
curl -X POST "https://app.salonbookit.com/api/v1/auth/login/" \
  -H "X-API-Key: hh_pub_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "cliente@ejemplo.com",
    "password": "contraseña123"
  }'

Response (200 OK) - Customer

JSON
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "tipo": "cliente",
    "cliente": {
      "id": 123,
      "nombre": "Juan",
      "apellido": "García",
      "email": "cliente@ejemplo.com",
      "telefono": "+34612345678",
      "puntos": 150,
      "nivel": "gold"
    }
  }
}

Response (200 OK) - Staff

Si las credenciales corresponden a un miembro del staff:

JSON
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "tipo": "staff",
    "staff": {
      "id": 1,
      "nombre": "María",
      "apellido": "López",
      "email": "maria@salon.com",
      "telefono": "+34612345678",
      "rol": "admin",
      "permisos": {
        "puede_ver_reservas": true,
        "puede_crear_reservas": true,
        "puede_ver_clientes": true
      }
    }
  }
}

Use the JWT token

Include the token in the header Authorization with the prefix Bearer:

cURL
curl -X GET "https://app.salonbookit.com/api/v1/cliente/reservas/" \
  -H "X-API-Key: hh_pub_live_abc123..." \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Renew the token

Tokens expire in 24 hours. Use the refresh endpoint to get a new one:

POST /api/v1/auth/refresh/
cURL
curl -X POST "https://app.salonbookit.com/api/v1/auth/refresh/" \
  -H "X-API-Key: hh_pub_live_abc123..." \
  -H "Authorization: Bearer TOKEN_ACTUAL"

Rate Limiting

The API has request limits to ensure stable service:

Limit Window Description
120 requests 1 minute General limit per API Key
20 attempts 15 minutes Login (by IP)
10 attempts 1 hour Registration (by IP)

Rate Limit Headers

Each response includes informational headers:

Headers
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 115
X-RateLimit-Reset: 1704067200
Header Description
X-RateLimit-Limit Maximum number of allowed requests
X-RateLimit-Remaining Remaining requests in the current window
X-RateLimit-Reset Unix timestamp when the counter resets

Error 429: Too Many Requests

If you exceed the limit, you'll receive a 429 error:

JSON
{
  "success": false,
  "error": "You have exceeded the request limit. Try again in 45 seconds.",
  "code": "RATE_LIMIT_EXCEEDED"
}

Authentication errors

Code HTTP Status Description
MISSING_API_KEY 401 X-API-Key header was not included
INVALID_API_KEY 401 Invalid or not found API Key
API_KEY_DISABLED 403 API Key has been disabled
API_KEY_EXPIRED 403 API Key has expired
INVALID_TOKEN 401 Invalid or malformed JWT Token
TOKEN_EXPIRED 401 Expired JWT Token
INVALID_CREDENTIALS 401 Incorrect email or password