Authentication
The SendSeven API supports three authentication methods. Choose the one that fits your use case:
| Method | Use Case | Lifespan | X-Tenant-ID Required? |
|---|---|---|---|
| API Token | Your own scripts, automations, server-to-server | Up to 365 days | No (tenant is embedded in the token) |
| OAuth App | Third-party apps acting on behalf of a user | Access: 1 hour, Refresh: 30 days | No (tenant is embedded in the token) |
| Bearer Token (JWT) | SendSeven web/mobile app sessions | Short-lived | Yes |
For API integrations, use API Tokens. They are the simplest, most secure option and don't require the X-Tenant-ID header.
1. API Tokens (recommended)
API tokens are the primary authentication method for integrations, scripts, bots, and automation. Each token is scoped to a specific tenant and has fine-grained permissions.
Create tokens at: Settings > API Tokens
Token format
s7_api_<32 hexadecimal characters>
Example: s7_api_a1b2c3d4e5f6789012345678abcdef00
Creating a token
- Go to Settings > API Tokens
- Click Create Token
- Fill in:
- Name: A descriptive name (e.g., "CRM Integration", "Marketing Bot")
- Scopes: Select only the permissions this token needs
- Expiration: Choose a duration (up to 365 days)
- Click Create
- Copy the token immediately - it will only be displayed once
Using the token
Include the token in the Authorization header. No X-Tenant-ID is needed - the tenant is embedded in the token itself:
curl -X GET "https://api.sendseven.com/api/v1/contacts?page=1&page_size=20" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json"
Python
import requests
API_TOKEN = "s7_api_a1b2c3d4e5f6789012345678abcdef00"
BASE_URL = "https://api.sendseven.com/api/v1"
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json",
}
response = requests.get(f"{BASE_URL}/contacts", headers=headers)
data = response.json()
for contact in data["items"]:
print(contact["name"], contact["email"])
JavaScript (Node.js)
const API_TOKEN = "s7_api_a1b2c3d4e5f6789012345678abcdef00";
const BASE_URL = "https://api.sendseven.com/api/v1";
const response = await fetch(`${BASE_URL}/contacts`, {
headers: {
"Authorization": `Bearer ${API_TOKEN}`,
"Content-Type": "application/json",
},
});
const data = await response.json();
console.log(data.items);
Token scopes
Scopes control what actions a token can perform. Always select the minimum scopes needed.
Scopes follow the pattern resource:action:
| Pattern | Meaning |
|---|---|
resource:read | View/list resources |
resource:create | Create new resources |
resource:update | Modify existing resources |
resource:delete | Remove resources |
resource:manage | Full administrative access |
resource:* | All actions on a resource |
Common scope combinations
Send messages only:
messages:create, conversations:read, contacts:read
Read-only dashboard:
conversations:read, contacts:read, messages:read, campaigns:read
Marketing automation:
contacts:read, contacts:create, contacts:update, campaigns:read, campaigns:create, campaigns:update, lists:read, lists:update
Full CRM integration:
contacts:*, conversations:*, messages:*, tags:*, notes:*
Insufficient scope error
If your token lacks a required scope:
{
"detail": "Missing required scope: campaigns:create",
"error_code": "INSUFFICIENT_SCOPE"
}
The detail message tells you exactly which scope is missing. Create a new token with that scope, or edit the existing token's scopes.
2. OAuth Apps
OAuth apps allow third-party applications to act on behalf of a SendSeven user. Use this when building integrations that need to access multiple users' accounts (e.g., Zapier, Make.com, CRM connectors).
Manage OAuth apps at: Settings > OAuth Apps
How it differs from API tokens
| API Token | OAuth App | |
|---|---|---|
| Who creates it | The account owner, for their own use | A developer, for any user to authorize |
| Credentials | A single token string | Client ID + Client Secret |
| User interaction | None - token works immediately | User must authorize the app via a consent screen |
| Multi-tenant | Scoped to one tenant | Can be authorized by users across different tenants |
| Best for | Your own integrations | Apps you distribute to other SendSeven customers |
Setting up an OAuth App
- Go to Settings > OAuth Apps
- Click Create App
- Fill in:
- App Name: Your application name (shown on the consent screen)
- Redirect URIs: URLs where users will be redirected after authorization
- Scopes: Permissions your app will request
- Note your Client ID and Client Secret
Authorization Code Flow
Step 1: Redirect the user to the authorization endpoint:
https://api.sendseven.com/api/v1/oauth/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https://yourapp.com/callback&
scope=contacts:read messages:create&
state=random_state_value&
tenant_id=OPTIONAL_TENANT_ID
The optional tenant_id parameter pre-selects a specific workspace on the consent screen. This is useful when re-authorizing for a known tenant (e.g., after token expiry).
Step 2: User authorizes your application on the SendSeven consent screen.
Step 3: Receive the authorization code at your redirect URI:
https://yourapp.com/callback?code=AUTH_CODE&state=random_state_value
Step 4: Exchange the code for an access token:
curl -X POST "https://api.sendseven.com/api/v1/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code": "AUTH_CODE",
"redirect_uri": "https://yourapp.com/callback"
}'
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "v1.refresh.abc123...",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "contacts:read messages:create",
"tenant_id": "64f3a695-6ce7-4822-b3ae-dc20d2967c26",
"tenant_name": "My Company"
}
The tenant_id and tenant_name fields tell you which workspace was authorized. Use these to store tokens per-tenant when a user belongs to multiple workspaces. See the OAuth guide for details.
Step 5: Use the access token in API requests (no X-Tenant-ID needed):
curl -X GET "https://api.sendseven.com/api/v1/contacts" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json"
Refreshing tokens
Access tokens expire after 1 hour. Use the refresh token to get a new one:
curl -X POST "https://api.sendseven.com/api/v1/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"refresh_token": "v1.refresh.abc123..."
}'
3. Bearer Tokens (JWT)
Bearer tokens are short-lived JWT tokens issued by Auth0 for authenticated web and mobile app sessions. These are used internally by the SendSeven dashboard and mobile app.
You typically don't need this method for API integrations. Use API Tokens instead.
Bearer tokens are the only authentication method that requires the X-Tenant-ID header, because the JWT itself doesn't contain tenant information:
curl -X GET "https://api.sendseven.com/api/v1/contacts" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
-H "X-Tenant-ID: your_tenant_id" \
-H "Content-Type: application/json"
Only with Bearer (JWT) tokens. API Tokens and OAuth tokens have the tenant embedded, so no X-Tenant-ID header is required. If you're using API Tokens (recommended), you can ignore this header entirely.
Security Best Practices
- Store tokens in environment variables or a secrets manager
- Use the minimum scopes required for your integration
- Rotate tokens regularly
- Revoke tokens that are no longer in use
- Never embed tokens in client-side code
- Commit tokens to version control
- Share tokens via email or chat
- Grant tokens more scopes than necessary
Environment variable storage
# .env file (never commit this!)
SENDSEVEN_API_TOKEN=s7_api_a1b2c3d4e5f6789012345678abcdef00
import os
token = os.environ["SENDSEVEN_API_TOKEN"]
Troubleshooting
| Error | Cause | Solution |
|---|---|---|
401 INVALID_TOKEN | Token expired, revoked, or malformed | Verify format s7_api_<32hex>, check expiration |
403 INSUFFICIENT_SCOPE | Token lacks required scope | Add the missing scope or create a new token |
401 with no error code | Missing Authorization header | Include Authorization: Bearer <token> |
400 missing tenant | Using a JWT without X-Tenant-ID | Add X-Tenant-ID header, or switch to API Tokens |