Skip to main content

Authentication

Partner external integrations​

Use the X-API-Key header for partner external endpoints such as /api/partner/*.

X-API-Key: sk_live_your_api_key

Auth is API key only. Do not send X-API-Secret or x-api-secret.

Credentials​

  • An API key is created or regenerated once. Turning access on (enableApi) does not create a key. Regenerate returns { apiKey }. There is no apiSecret.
  • The webhook HMAC secret is shown once when the webhook is created. Changing webhookUrl in admin or settings updates the active webhook URL and does not rotate the secret. Clearing the URL deactivates active webhooks. The first webhook comes from approval or from creating it in the portal.
  • Store and deliver public HTTPS URLs only. Localhost, private networks, and metadata hosts are rejected. Delivery does not follow redirects.

Example​

curl -X GET "https://service-gateway.loscenotes.com/api/partner/cenotes" \
-H "X-API-Key: sk_live_your_api_key" \
-H "Content-Type: application/json"

Other auth models in the platform​

  • Partner portal and management endpoints use JWT
  • Some shared public endpoints do not require API key auth
  • Some operational endpoints, such as on-site checkout confirmation, require role-based authenticated access

Sandbox & WebSocket​

  • Sandbox keys (sk_test_) are for portal sandbox routes and for /api/partner-sandbox/* plus /api/partner/webhooks/simulator/*. They do not read or write production bookings.
  • sk_test_ cannot call /api/partner/* or other production partner routes. The response is 403 error.partner.sandbox_key_not_allowed_on_production_api. Use sk_live_ on every /api/partner/* example.
  • Realtime. Open a Socket.IO connection to https://service-gateway.loscenotes.com/partner/ws.
    • Portal user: handshake auth.token set to the JWT, or header Authorization: Bearer <jwt>.
    • API key: handshake auth.apiKey set to sk_live_.... sk_test_ is rejected.
    • Success emits connected with partnerId, authMode (jwt or api_key), and timestamp.
    • Send subscribe with { "events": ["*"] } or a list of event names. Until you subscribe, the socket stays up and does not deliver partner events. ping is answered with pong.
    • Failure emits error and the server closes the socket.

Error shape​

Current API errors are returned in the enhanced global format:

{
"success": false,
"message": "validation.invalid_data",
"error": "Bad Request",
"statusCode": 400,
"timestamp": "2026-03-10T18:00:00.000Z",
"path": "/api/partner/cenotes"
}