Documentation Index
Fetch the complete documentation index at: https://orbit-docs.devotel.io/llms.txt
Use this file to discover all available pages before exploring further.
Security Best Practices
Protect your Orbit integration with proper API key management, webhook signature verification, and security hardening.
API Key Management
Key Types
Orbit uses three types of API keys:
| Key Type | Prefix | Usage | Permissions |
|---|
| Live Secret Key | dv_live_sk_ | Server-side only | Full API access |
| Test Secret Key | dv_test_sk_ | Server-side testing | Sandbox only |
| Public Key | dv_live_pk_ | Client-side (web SDK) | Limited read-only |
Key Security Rules
- Never expose secret keys in client-side code. Secret keys (
sk_) should only be used in server-side environments.
❌ Client-side JavaScript
const orbit = new Devotel({ apiKey: 'dv_live_sk_xxxx' }) // NEVER
✅ Server-side only
// Node.js backend, Python server, etc.
const orbit = new Devotel({ apiKey: process.env.DEVOTEL_API_KEY })
- Use environment variables. Never hardcode keys in source code.
# .env (never commit this file)
DEVOTEL_API_KEY=dv_live_sk_your_key_here
-
Rotate keys regularly. Generate new keys quarterly and revoke old ones.
-
Use separate keys per environment. Use test keys (
dv_test_sk_) for development.
-
Restrict key permissions. Create keys with minimum required scopes in the dashboard under Settings > API Keys.
Revoking a Compromised Key
If a key is exposed:
- Go to Settings > API Keys in the Orbit dashboard
- Click Revoke on the compromised key
- Generate a new key
- Update your application configuration immediately
Revoking a key is immediate and irreversible. All requests using the revoked key will return 401 INVALID_API_KEY.
Webhook Verification
Every webhook from Orbit includes an HMAC-SHA256 signature in the X-Devotel-Signature header. Always verify this signature before processing webhook payloads.
How Verification Works
- Orbit signs the raw request body using your webhook secret
- The signature is sent in the
X-Devotel-Signature header
- Your server recomputes the signature and compares it
Implementation
Node.js
import crypto from 'node:crypto'
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
)
}
app.post('/webhooks/orbit', (req, res) => {
const signature = req.headers['x-devotel-signature']
const isValid = verifyWebhookSignature(
req.rawBody,
signature,
'whsec_your_secret',
)
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' })
}
// Process the webhook
const event = req.body
res.status(200).json({ received: true })
})
Python
import hmac
import hashlib
def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode("utf-8"),
payload,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(signature, expected)
@app.route("/webhooks/orbit", methods=["POST"])
def handle_webhook():
signature = request.headers.get("X-Devotel-Signature")
if not verify_webhook_signature(request.data, signature, "whsec_your_secret"):
return jsonify({"error": "Invalid signature"}), 401
event = request.get_json()
return jsonify({"received": True}), 200
func verifyWebhookSignature(payload []byte, signature, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(payload)
expected := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(signature), []byte(expected))
}
Webhook Security Checklist
Transport Security
HTTPS Required
All Orbit API endpoints require HTTPS (https://orbit-api.devotel.io). HTTP requests are rejected.
TLS Requirements
- Minimum TLS 1.2
- TLS 1.3 recommended
- Weak cipher suites are not supported
Webhook Endpoint Requirements
Your webhook endpoints must:
- Use HTTPS with a valid SSL certificate (not self-signed)
- Support TLS 1.2 or higher
- Respond within 30 seconds
- Return a
2xx status code to acknowledge receipt
IP Allowlisting
If your firewall restricts inbound traffic, allowlist Orbit’s webhook delivery IPs:
34.141.0.0/16 (europe-west1 — primary)
35.195.0.0/16 (europe-west1 — secondary)
IP ranges may change. Subscribe to the Orbit status page for notifications about infrastructure changes.
Data Security
PII Handling
- Orbit masks phone numbers in logs (
+1415555****)
- API responses include full data; mask PII in your own logs
- Use metadata fields for internal identifiers instead of PII
Data Retention
| Data Type | Retention | Notes |
|---|
| Message content | 90 days | Configurable per account |
| Call recordings | 30 days | Configurable; auto-deleted after |
| Webhook delivery logs | 30 days | Available in dashboard |
| API access logs | 1 year | Includes request IDs |
Encryption
- In transit: TLS 1.2+ for all API and webhook traffic
- At rest: AES-256 encryption for all stored data
- Recordings: Encrypted at rest with per-tenant keys
RBAC (Role-Based Access Control)
Orbit supports five roles with increasing permissions:
| Role | API Keys | Send Messages | Manage Agents | Billing | Team |
|---|
viewer | Read only | No | No | No | No |
developer | Create/manage | Yes | Yes | No | No |
admin | Full access | Yes | Yes | View | Invite |
billing | No | No | No | Full | No |
owner | Full access | Yes | Yes | Full | Full |
Assign the minimum role needed for each team member.
Orbit API responses include security headers:
| Header | Value |
|---|
X-Request-Id | Unique request identifier for tracing |
Strict-Transport-Security | max-age=31536000; includeSubDomains |
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Found a security vulnerability? Report it to security@devotel.io. We take all reports seriously and respond within 24 hours.