Skip to main content

Authentication

The SendSeven API supports three authentication methods. Choose the one that fits your use case:

MethodUse CaseLifespanX-Tenant-ID Required?
API TokenYour own scripts, automations, server-to-serverUp to 365 daysNo (tenant is embedded in the token)
OAuth AppThird-party apps acting on behalf of a userAccess: 1 hour, Refresh: 30 daysNo (tenant is embedded in the token)
Bearer Token (JWT)SendSeven web/mobile app sessionsShort-livedYes

For API integrations, use API Tokens. They are the simplest, most secure option and don't require the X-Tenant-ID header.


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

  1. Go to Settings > API Tokens
  2. Click Create Token
  3. 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)
  4. Click Create
  5. 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:

PatternMeaning
resource:readView/list resources
resource:createCreate new resources
resource:updateModify existing resources
resource:deleteRemove resources
resource:manageFull 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 TokenOAuth App
Who creates itThe account owner, for their own useA developer, for any user to authorize
CredentialsA single token stringClient ID + Client Secret
User interactionNone - token works immediatelyUser must authorize the app via a consent screen
Multi-tenantScoped to one tenantCan be authorized by users across different tenants
Best forYour own integrationsApps you distribute to other SendSeven customers

Setting up an OAuth App

  1. Go to Settings > OAuth Apps
  2. Click Create App
  3. 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
  4. 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"
When is X-Tenant-ID needed?

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

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
Never Do
  • 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

ErrorCauseSolution
401 INVALID_TOKENToken expired, revoked, or malformedVerify format s7_api_<32hex>, check expiration
403 INSUFFICIENT_SCOPEToken lacks required scopeAdd the missing scope or create a new token
401 with no error codeMissing Authorization headerInclude Authorization: Bearer <token>
400 missing tenantUsing a JWT without X-Tenant-IDAdd X-Tenant-ID header, or switch to API Tokens