Authentication
The SIPSIM API uses OAuth 2.0 with the Client Credentials flow for authentication. This is a simple server-to-server authentication that doesn't require user interaction.
Overview
The Client Credentials flow works as follows:
Get an Access Token
Exchange your client credentials for an access token.
Scope Parameter
The scope parameter allows you to request specific permissions for your access token. You can request multiple scopes by separating them with spaces. Available scopes include:
| Scope | Description |
|---|---|
account.read | Read account information |
calls.read | Read call history and details |
calls.write | Initiate and manage calls |
phones.read | Read phone numbers |
phones.write | Manage phone numbers |
tags.read | Read tags |
tags.write | Manage tags |
Only request the scopes you actually need. This follows the principle of least privilege and improves security.
- cURL
- Python
- JavaScript
- Ruby
curl -X POST https://app.sipsim.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=account.read calls.read phones.read"
import requests
response = requests.post(
'https://app.sipsim.com/oauth/token',
data={
'grant_type': 'client_credentials',
'client_id': 'YOUR_CLIENT_ID',
'client_secret': 'YOUR_CLIENT_SECRET',
'scope': 'account.read calls.read phones.read'
}
)
tokens = response.json()
access_token = tokens['access_token']
print(f"Access Token: {access_token}")
const response = await fetch('https://app.sipsim.com/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
scope: 'account.read calls.read phones.read'
})
});
const tokens = await response.json();
console.log('Access Token:', tokens.access_token);
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://app.sipsim.com/oauth/token')
response = Net::HTTP.post_form(uri, {
'grant_type' => 'client_credentials',
'client_id' => 'YOUR_CLIENT_ID',
'client_secret' => 'YOUR_CLIENT_SECRET',
'scope' => 'account.read calls.read phones.read'
})
tokens = JSON.parse(response.body)
puts "Access Token: #{tokens['access_token']}"
Token Response
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 7200,
"scope": "account.read calls.read phones.read",
"created_at": 1705312200
}
| Field | Description |
|---|---|
access_token | Token to use in API requests |
token_type | Always Bearer |
expires_in | Token lifetime in seconds (2 hours) |
scope | Granted scopes |
created_at | Unix timestamp of token creation |
Use the Access Token
Include the access token in the Authorization header of all API requests:
curl https://app.sipsim.com/api/v2/account \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Token Expiration and Refresh
Access tokens expire after 2 hours. When your token expires, simply request a new one using the same client credentials:
import requests
import time
class SipsimClient:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.access_token = None
self.token_expires_at = 0
def get_access_token(self):
"""Get a valid access token, refreshing if needed."""
if self.access_token and time.time() < self.token_expires_at - 60:
return self.access_token
response = requests.post(
'https://app.sipsim.com/oauth/token',
data={
'grant_type': 'client_credentials',
'client_id': self.client_id,
'client_secret': self.client_secret,
'scope': 'account.read calls.read phones.read'
}
)
tokens = response.json()
self.access_token = tokens['access_token']
self.token_expires_at = time.time() + tokens['expires_in']
return self.access_token
def api_request(self, endpoint, method='GET', **kwargs):
"""Make an authenticated API request."""
headers = {'Authorization': f'Bearer {self.get_access_token()}'}
return requests.request(
method,
f'https://app.sipsim.com/api/v2{endpoint}',
headers=headers,
**kwargs
)
# Usage
client = SipsimClient('YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET')
response = client.api_request('/account')
print(response.json())
Error Handling
Common Authentication Errors
| Error | Description | Solution |
|---|---|---|
invalid_client | Invalid client credentials | Check your Client ID and Secret |
invalid_scope | Requested scope not allowed | Request only scopes configured in your integration |
unauthorized_client | Client not authorized for this grant type | Ensure your integration is properly configured |
Error Response Format
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
Security Best Practices
- Never expose your Client Secret in client-side code (JavaScript, mobile apps)
- Always use HTTPS — Never make API calls over plain HTTP
- Store credentials securely — Use environment variables or a secrets manager
- Cache tokens — Don't request a new token for every API call
- Request minimal scopes — Only request the scopes you actually need
Environment Variables Example
# Set credentials as environment variables
export SIPSIM_CLIENT_ID="your_client_id"
export SIPSIM_CLIENT_SECRET="your_client_secret"
import os
client_id = os.environ['SIPSIM_CLIENT_ID']
client_secret = os.environ['SIPSIM_CLIENT_SECRET']
Next Steps
Now that you're authenticated, learn how to make API calls:
- Make Your First API Call — Understand the API structure
- Working with Calls — Access call history
- API Reference — Explore all endpoints