Slokoto API
Build custom integrations with the Slokoto REST API and Webhooks. Manage leads programmatically, receive real-time events, and extend Slokoto to fit your workflow.
Authentication
OAuth2 client credentials flow with short-lived bearer tokens.
REST Endpoints
Full CRUD operations for leads with pagination and filtering.
Webhooks
Real-time event notifications with HMAC-SHA256 signatures.
https://slokoto.com/api/v1Authentication
Slokoto uses OAuth2 Client Credentials for API authentication. Generate your credentials in Integrations → Custom → REST API in your Slokoto dashboard.
Step 1: Get an Access Token
Exchange your client_id and client_secret for a short-lived bearer token (1 hour).
curl -X POST https://slokoto.com/api/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "slk_ci_your_client_id",
"client_secret": "slk_cs_your_client_secret"
}'{
"data": {
"access_token": "slk_at_...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "leads.read leads.write"
}
}Step 2: Use the Token
Include the token in the Authorization header of all API requests.
curl https://slokoto.com/api/v1/leads \
-H "Authorization: Bearer slk_at_your_access_token"const response = await fetch('https://slokoto.com/api/v1/leads', {
headers: {
'Authorization': 'Bearer slk_at_your_access_token',
},
});
const { data, meta } = await response.json();import requests
response = requests.get(
'https://slokoto.com/api/v1/leads',
headers={'Authorization': 'Bearer slk_at_your_access_token'},
)
data = response.json()REST Endpoints
All endpoints are workspace-scoped. Your API client can only access leads within its workspace.
Webhooks
Configure webhook endpoints in Integrations → Custom → Webhooks to receive real-time HTTP POST notifications when events occur in your workspace.
Event Types
| Event | Description |
|---|---|
lead.created | A new lead was created |
lead.updated | A lead's fields were modified |
lead.status_changed | A lead's status changed (active, won, lost, archived) |
lead.assigned | A lead was assigned to a team member |
lead.stage_changed | A lead moved to a different pipeline stage |
lead.deleted | A lead was permanently deleted |
Payload Format
{
"event": "lead.created",
"created_at": "2026-03-19T14:30:00Z",
"data": {
"lead": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john@acme.com",
"name": "John Smith",
"company": "Acme Corp",
"status": "active",
...
}
}
}Headers
| Header | Description |
|---|---|
X-Slokoto-Signature | HMAC-SHA256 signature for payload verification |
X-Slokoto-Event | The event type (e.g., lead.created) |
X-Slokoto-Delivery | Unique delivery ID for deduplication |
Content-Type | Always application/json |
Verifying Signatures
Every webhook request includes an X-Slokoto-Signature header with the format t=timestamp,v1=hex_signature. Verify it to ensure the request is genuine.
const crypto = require('crypto');
function verifyWebhook(payload, signatureHeader, secret) {
const parts = signatureHeader.split(',');
const timestamp = parts.find(p => p.startsWith('t=')).slice(2);
const signature = parts.find(p => p.startsWith('v1=')).slice(3);
// Check timestamp is within 5 minutes
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) {
throw new Error('Webhook timestamp too old');
}
// Compute expected signature
const signedContent = timestamp + '.' + payload;
const expected = crypto
.createHmac('sha256', secret)
.update(signedContent)
.digest('hex');
// Timing-safe comparison
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex'),
);
}import hmac
import hashlib
import time
def verify_webhook(payload: str, signature_header: str, secret: str) -> bool:
parts = dict(p.split('=', 1) for p in signature_header.split(','))
timestamp = parts['t']
signature = parts['v1']
# Check timestamp tolerance
if abs(time.time() - int(timestamp)) > 300:
raise ValueError('Webhook timestamp too old')
# Compute expected
signed = f"{timestamp}.{payload}"
expected = hmac.new(
secret.encode(), signed.encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Retry Policy
If your endpoint returns a non-2xx status code or times out (10 seconds), Slokoto retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry (final) | 12 hours |
Rate Limits
API requests are rate-limited to 60 requests per minute per API client. Rate limit information is included in response headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window (60) |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
When rate limited, the API returns 429 Too Many Requests. Wait until the reset time before retrying.
Error Handling
All errors follow a consistent format:
{
"error": {
"code": "not_found",
"message": "Lead not found"
}
}Error Codes
| HTTP | Code | Description |
|---|---|---|
| 400 | invalid_request | Malformed request body or parameters |
| 401 | unauthorized | Missing or invalid access token |
| 403 | forbidden | Token lacks required scope |
| 404 | not_found | Resource does not exist or is not in your workspace |
| 409 | duplicate_lead | A lead with this email already exists |
| 422 | validation_error | Request body fails validation |
| 429 | rate_limited | Too many requests — slow down |
| 500 | server_error | Internal server error — retry or contact support |
| 502 | ai_error | AI provider error (ai-update endpoint only) |