Activities Integration
Examples below show the wire-format
Authorization: P2S-SIGN-V1 API_KEY:TIMESTAMP:SIGNATURE header. To compute the signature in your code, use the signedRequest helper in Authentication.How It Works
- You get an API Key from the SalesOS Dashboard (Admin > Integrations > API Keys)
- You sync your team — register collaborators (salespeople) so SalesOS knows who they are
- You send activities numbered 001-999 via a single REST endpoint
- Your admin maps each activity number to a SalesOS mission in the Dashboard
- SalesOS processes the activities as mission completions, awarding points and tracking progress
Activity codes are just numbers (001 through 999). The meaning of each code is defined by your team when mapping them to missions in the Dashboard. For example, “001” could mean “Phone call” and “002” could mean “Meeting scheduled”.
Quick Start
1
Get your API Key
Go to Admin > Integrations > API Keys in the SalesOS Dashboard. Create a new key with the
default:sync scope. Copy the key — it will only be shown once.Your key looks like: sk_live_a1b2c3d4e5f6g7h8i9j0...2
Register your sales team
Before sending activities, tell SalesOS who your salespeople are:Response:
3
Send activities from your CRM
Now send the activities your salespeople performed today:Response:Maria got 2 activities (two phone calls) and Joao got 1 (a meeting).
4
Map codes to missions in the Dashboard
In the Dashboard, go to Missions > Configure. Select “Activities” from the CRM dropdown. You will see activities 001 through 999. Map the ones you use:
Click Save. From now on, every activity “001” sent via API will count toward the “Ligacoes Realizadas” mission.
Authentication
All requests require an API Key in theAuthorization header:
Environments
- Production
- Staging
Base URL:
https://api.play2sell.comDashboard: https://dashboard.play2sell.comApp: https://app.play2sell.comEndpoint Reference
Base URL:action field: sync_collaborators and sync_activities.
Action: sync_collaborators
Register or update collaborators (salespeople) in SalesOS. Collaborators must exist before you can attribute activities to them.Request Schema
string
required
Must be
"sync_collaborators"array
required
Array of collaborator objects (max 500)
string
required
Unique ID in your system (max 255 chars)
string
required
Full name (max 255 chars)
string
required
Valid email — used to match activities later
string
Phone number (any format)
string
ID document like CPF (max 20 chars)
string
Team name (max 100 chars)
string
Role in your org (max 50 chars)
object
Any extra key-value data
Example: Sync a full team
Response (200 — Success)
created: 2— Maria and Joao were new, so they were createdexisting: 1— Ana already existed (matched by email), so she was updatederrors: []— no failures in this batch
Example: Partial failures in a batch
If some collaborators have invalid data, they fail individually without blocking the rest:Action: sync_activities
Send activity events attributed to collaborators. Each activity uses a 3-digit code (001-999) that you map to missions in the Dashboard.Request Schema
string
required
Must be
"sync_activities"array
required
Array of activity objects (max 1000)
string
required
3-digit code:
"001" through "999"string
required
Unique ID for deduplication (max 255 chars)
string
required
Email of the salesperson who did the activity
object
Any additional context (free-form)
string
When it happened (ISO 8601). Defaults to now.
Example: Send a day’s worth of activities
Response (200 — Success)
Response fields explained
integer
Activities successfully recorded
integer
Activities where the collaborator email was not found in SalesOS
integer
Activities with an
external_id that was already sent beforearray
Array of error messages for items that failed
integer
Total items received in the request
Example: Mixed results (some skipped, some duplicates)
If you re-send the same batch or include unknown emails:skipped: 1— one email was not registered viasync_collaboratorsduplicates: 2— two activities hadexternal_idvalues already in the system
Activity Codes (001-999)
Activity codes are abstract identifiers. Their meaning is entirely up to you. Example mapping for a real estate company:
Example mapping for a SaaS company:
Idempotency
Theexternal_id field guarantees idempotency. If you send the same activity twice with the same external_id, the second request reports it as a duplicate — it is not processed again.
First call — activity is processed:
external_id) — safely deduplicated:
Error Handling
Error Response Format
All errors follow a consistent structure:Error Codes Reference
400 — VALIDATION_ERROR
400 — VALIDATION_ERROR
Invalid body, missing fields, or bad activity code. Fix the request payload — check the
details array for field-level specifics.403 — FORBIDDEN
403 — FORBIDDEN
API key is valid but lacks the
default:sync scope. Edit the key in Dashboard and add the required scope.405 — METHOD_NOT_ALLOWED
405 — METHOD_NOT_ALLOWED
Used GET, PUT, etc. instead of POST. Change to
POST.429 — RATE_LIMITED
429 — RATE_LIMITED
Too many requests this hour. Wait
retry_after seconds, then retry. Consider reducing your sync frequency.500 — SERVER_ERROR
500 — SERVER_ERROR
Internal server error. Retry with exponential backoff (2s, 4s, 8s). Contact support if persistent.
Example: Validation error with details
index field tells you which item in the array has the problem. Item at index 2 (joao) was valid — only the invalid items are listed.
Example: Rate limit exceeded
Example: Invalid API key
Complete Code Examples
Best Practices
Sync Strategy
- Collaborators: Sync your full team nightly. The API is idempotent — existing users are updated, not duplicated.
- Activities: Sync every 5-15 minutes, or in real-time via webhooks from your CRM. Always use your CRM’s event ID as
external_id. - Batch size: Send up to 1000 activities per request. For large volumes, split into sequential batches.
Choosing external_id
Theexternal_id is your deduplication key. Pick something stable and unique from your source system:
Handling failures
- 400 errors: Fix the data and resend. Check the
detailsarray for field-level errors. - 429 errors: Wait
retry_afterseconds, then retry. Consider reducing your sync frequency. - 500 errors: Retry with exponential backoff (2s, 4s, 8s). Contact support if it persists.
- Network errors: Retry safely — idempotency via
external_idprevents duplicates.
Rate Limits
Each API key has a configurable rate limit (default: 1000 requests per hour). The counter resets every hour.Security
- API keys are hashed with bcrypt — never stored in plaintext
- Each key is scoped to a single tenant — no cross-tenant access
- IP allowlists can be configured per key
- All requests are logged for audit purposes
- Keys can be revoked instantly from the Dashboard
Next Steps
Authentication
Learn how to create and manage API Keys
Support
Need help? Contact our support team

