Authentication
Secure your API requests and manage user authentication
Samva uses two authentication methods:
- API Keys for server-to-server communication
- Better Auth for dashboard and user authentication
Security First: All API requests must be authenticated. We use industry-standard security practices to protect your data.
API Key Authentication
Creating API Keys
- Log in to the Samva Dashboard
- Navigate to Developers → API Keys
- Click Create API Key
- Set permissions and expiry (optional)
- Copy the key immediately - it won't be shown again
Using API Keys
Include your API key in the X-API-Key header:
// TypeScript SDK
import { createSamvaClient } from 'samva';
const samva = createSamvaClient({
apiKey: 'sk_live_your_api_key_here'
});# REST API
curl -H "X-API-Key: sk_live_your_api_key_here" \
https://samva.app/api/v1/messagesAPI Key Types
| Type | Prefix | Usage | Rate Limits |
|---|---|---|---|
| Live | sk_live_ | Production use | Standard limits |
| Test | sk_test_ | Development & testing | Reduced limits |
| Restricted | sk_restricted_ | Limited permissions | Based on config |
Best Practices
Use Environment Variables
Never hardcode API keys in your source code
Rotate Keys Regularly
Update your API keys every 90 days
Use Restricted Keys
Create keys with minimal required permissions
Monitor Usage
Track API key usage in the dashboard
User Authentication (Better Auth)
Overview
The Samva Dashboard uses Better Auth with:
- Email/Password authentication
- Multi-factor authentication (MFA)
- Organization-based multi-tenancy
Sign Up Flow
// Sign up with email and password
const response = await fetch('/api/auth/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'user@example.com',
password: 'secure_password',
name: 'John Doe',
organization: 'Acme Corp'
})
});
// Verify email
await fetch('/api/auth/verify-email', {
method: 'POST',
body: JSON.stringify({
token: 'verification_token_from_email'
})
});Login Flow
// Login with email/password
const response = await fetch('/api/auth/login', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'user@example.com',
password: 'your_password'
})
});Session Management
// Check current session
const session = await fetch('/api/auth/session', {
credentials: 'include'
});
// Logout
await fetch('/api/auth/logout', {
method: 'POST',
credentials: 'include'
});Organization & Multi-Tenancy
Organization Structure
Each Samva account belongs to an organization:
interface Organization {
id: string;
name: string;
credits: number; // Prepaid credits
settings: {
default_sender_ids: Record<string, string>;
webhook_url?: string;
ip_whitelist?: string[];
};
}Team Management
Team members can be invited through the dashboard:
- Navigate to Settings → Team
- Click Invite Member
- Enter their email and select a role (Admin, Developer, or Viewer)
- The invited user receives an email with an invitation link
Security Features
Rate Limiting
API requests are rate-limited per API key:
| Plan | Requests/Second | Requests/Hour | Requests/Day |
|---|---|---|---|
| Free | 10 | 1,000 | 10,000 |
| Starter | 50 | 10,000 | 100,000 |
| Business | 100 | 50,000 | 1,000,000 |
| Enterprise | Custom | Custom | Custom |
Rate limit headers in responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200IP Whitelisting
Restrict API access to specific IP addresses:
- Navigate to Settings → Organization → Security
- Enable IP Whitelisting
- Add allowed IP addresses or CIDR ranges
Example whitelist:
- 203.0.113.0/24
- 198.51.100.42Webhook Signatures
Verify webhook authenticity:
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
// In your webhook handler
app.post('/webhooks/samva', (req, res) => {
const signature = req.headers['x-samva-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process webhook...
});Error Handling
Authentication Errors
| Error Code | Description | Solution |
|---|---|---|
401 | Invalid or missing API key | Check your API key |
403 | Insufficient permissions | Use a key with required permissions |
429 | Rate limit exceeded | Reduce request frequency |
498 | Token expired | Refresh your session |
Common Issues
Invalid API Key Format
{
"error": "INVALID_API_KEY",
"message": "API key must start with sk_live_ or sk_test_"
}Organization Not Found
{
"error": "ORG_NOT_FOUND",
"message": "No organization associated with this API key"
}