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

  1. Go to the MagicBell Dashboard.
  2. Select your project.
  3. Navigate to Settings > User Auth.
  4. 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.