Authentication
The SalesOS Integration API uses the P2S-SIGN-V1 signed-request scheme in theAuthorization header. API Keys are scoped to a single tenant, hashed with bcrypt, and support rate limiting and IP allowlists.
Environments
- Production
- Staging
Base URL:
https://api.play2sell.comDashboard: https://dashboard.play2sell.comApp: https://app.play2sell.comQuick Start
1. Create an API Key
Go to Integrations > API Keys in the SalesOS Dashboard:- Click Create API Key
- Name your key (e.g., “CRM Nightly Sync”, “Website Form Integration”)
- Select the scope:
default:sync - Click Create
- 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
- API Key — public identifier, e.g.
2. Sign and Send a Request
For server-to-server calls, build theAuthorization header as P2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE. The signature is hex HMAC-SHA256 of a 5-step derived-key chain:
k1 = HMAC_SHA256(key=API_KEY_SECRET, msg=API_KEY)k2 = HMAC_SHA256(key=k1, msg=TIMESTAMP)k3 = HMAC_SHA256(key=k2, msg=METHOD)k4 = HMAC_SHA256(key=k3, msg=PATH)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).
- Node.js
- Python
- Bash
3. Check the Response
Success (200):API Key Properties
Key Formats
SalesOS uses two key prefixes to distinguish environments:Authentication Errors
Every rejection from the authentication layer has the same shape:error is a human-readable string and code is stable — branch on code, never on the text.
Example: Key without required scope
missing_scopes only appears in this case.
Rate Limits
Each API key has an independent rate limit counter that resets hourly:
How it works:
- Every authenticated and authorized request counts in the key’s window (authentication rejections do not count)
- The window is one hour from the first request
- Today the limit is measured but not enforced. Once enforcement is on, excess requests will get
429withcode: "rate_limited"and aRetry-Afterheader in seconds — handle it now
Security Best Practices
- Use environment variables — Store
SALESOS_API_KEYin 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

