Skip to main content

Authentication

Try signed requests in your browser at the API Sandbox — paste your API key and secret, and the playground signs requests automatically.
The SalesOS Integration API uses the P2S-SIGN-V1 signed-request scheme in the Authorization header. API Keys are scoped to a single tenant, hashed with bcrypt, and support rate limiting and IP allowlists.

Environments

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

Quick Start

1. Create an API Key

Go to Integrations > API Keys in the SalesOS Dashboard:
  1. Click Create API Key
  2. Name your key (e.g., “CRM Nightly Sync”, “Website Form Integration”)
  3. Select the scope: default:sync
  4. Click Create
  5. Copy both values immediately — they are only shown once:
    • API Key — public identifier, e.g. sk_live_a1b2c3d4...
    • API Key Secret — used to sign requests, never sent over the wire

2. Sign and Send a Request

For server-to-server calls, build the Authorization header as P2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE. The signature is hex HMAC-SHA256 of a 5-step derived-key chain:
  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 is Unix epoch seconds, valid for 30 seconds. PAYLOAD_SHA256_HEX is the lowercase hex SHA-256 of the raw request body (use the empty-string digest e3b0c4...b855 if there is no body).
Don’t want to write the signing code yet? The API Sandbox signs requests for you in the browser — paste your API key and secret, then click Try it out.

3. Check the Response

Success (200):
Invalid signature or expired timestamp (401):

API Key Properties


Key Formats

SalesOS uses two key prefixes to distinguish environments:
Use sk_test_ keys during development and integration testing. Switch to sk_live_ when you go to production.

Authentication Errors

Example: Missing Authorization header

Example: Signature mismatch

A signature that doesn’t match the server’s recomputation — usually caused by a body change after signing, a path-canonicalization mismatch, or an outdated key:

Example: Timestamp outside the 30s window

Example: Key without required scope

If your key only has leads:read but the endpoint requires default:sync:

Example: Rate limit exceeded

The retry_after field tells you how many seconds to wait. The rate limit window resets every hour.

Rate Limits

Each API key has an independent rate limit counter that resets hourly: How it works:
  1. Each successful request increments the counter
  2. When the counter reaches the limit, further requests return 429
  3. The counter resets to 0 one hour after the first request in the window
Handling rate limits in code:

Security Best Practices

Never expose API keys in client-side code. Browser JavaScript, mobile apps, and public repositories can all leak your key. Always call the SalesOS API from your backend server.
  • Use environment variables — Store SALESOS_API_KEY in env vars or a secrets manager, never in source code
  • Rotate keys periodically — Create a new key, update your integration, then revoke the old one
  • Use IP allowlists — If your integration runs from fixed IPs, restrict the key to those IPs only
  • Monitor usage — Check the API usage logs in the Dashboard for unexpected patterns
  • Use sk_test_ for development — Test keys isolate your dev environment from production
  • Revoke compromised keys immediately — Go to Dashboard > Admin > API Keys > Revoke

Key rotation example


Next Steps

Default Integration

Start sending activities to SalesOS

API Keys

Manage keys programmatically