Authentication
MagicBell uses two types of JWT tokens to authenticate requests:
Token Type | Scope | Generated By | Usage Context |
---|---|---|---|
Project JWT | Project-wide | MagicBell UI | Project endpoints, server auth |
User JWT | Per user | Your backend | User endpoints, (in-app inbox) |
The endpoints in the API reference (and the OpenAPI spec) show the token type necessary for the endpoint.
Using the Token
Once you have your JWT (either Project or User), include it in the Authorization
header of your HTTP requests:
Authorization: Bearer <jwt>
Example
POST /broadcasts HTTP/1.1
Host: api.magicbell.com
Authorization: Bearer eyJhbGciOi...
All MagicBell SDKs and libraries handle this for you if you pass the token.
Generating the JWT
You generate it using the Secret Key and the API Key from your project.
Where to Find Keys
- Go to the MagicBell Dashboard.
- Select your project.
- Navigate to Settings > User Auth.
- You’ll see both the API Key and the Secret Key.

You’ll need both the API Key and the Secret Key to generate a User JWT.
User JWT Payload
Here’s what the payload typically looks like:
{
"user_email": "person@example.com",
"user_external_id": "usr_l70vln",
"api_key": "pk_JJUxO8amaaK21G08w9q0_218239574"
}
You must specify either user_email
or user_external_id
, or both.
Key | Description |
---|---|
user_email |
The email address of the user. Required when no user_external_id is provided. |
user_external_id |
A unique identifier for the user in your system. Required when no user_email is provided. |
api_key |
The API key for your MagicBell project. Obtained via our dashboard |
Signing the User JWT
User JWTs must be signed with your project's Secret Key using the HS256
algorithm. The secret is known only to your backend and MagicBell. It proves the authenticity of the token. The secret key can be obtained from the User Auth page on our Dashboard.
Generating a User JWT
The JWT is generated on your backend. Never expose your secret key to the public by attempting to sign client side.
TypeScript
import jwt from 'jsonwebtoken';
const secret = 'your-secret-key';
const payload = {
user_email: null,
user_external_id: 'your-user-id',
api_key: 'your-api-key',
};
const token = jwt.sign(payload, secret, {
algorithm: 'HS256',
expiresIn: '1y',
});
console.log(token);
Go
package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
func main() {
secret := []byte("your-secret-key")
claims := jwt.MapClaims{
"user_email": "",
"user_external_id": "your-user-id",
"api_key": "your-api-key",
"exp": time.Now().AddDate(1, 0, 0).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signed, err := token.SignedString(secret)
if err != nil {
panic(err)
}
fmt.Println(signed)
}
Debugging Tokens
You can use jwt.io to inspect and debug your JWTs. It shows the token's header, payload, and signature, and verifies whether it's correctly signed (if you provide the secret key).
Never paste production secrets into online tools. Only use jwt.io
with non-sensitive test data.