# From app/constants.pyKEY_TYPE_NORMAL = "normal" # Live API keyKEY_TYPE_TEAM = "team" # Team/guest list onlyKEY_TYPE_TEST = "test" # Simulated sending
# From app/authentication/auth.py# JWT must include:{ "iss": "service-id-uuid", # Your service ID (issuer) "iat": 1709467800 # Unix timestamp (issued at)}# Signed with:- Algorithm: HS256- Secret: Your API key secret# Validation rules:- Token must be signed with valid API key secret- iat (issued at) must be within 30 seconds of current time- Service must exist and be active- API key must not be expired
Clock Synchronization RequiredYour system clock must be accurate within 30 seconds. Notify rejects tokens with iat timestamps more than 30 seconds in the past or future.
# Error message if clock is wrong:"Error: Your system clock must be accurate to within 30 seconds"
from notifications_python_client.notifications import NotificationsAPIClient# Client handles JWT creation automaticallynotifications_client = NotificationsAPIClient(api_key)# JWT is created and included in Authorization header for younotifications_client.send_email_notification( email_address="[email protected]", template_id="template-id",)
Manual JWT creation (not recommended):
import jwtimport timeimport uuid# Your API key detailsservice_id = "your-service-id-uuid"api_key_secret = "your-api-key-secret"# Create JWTtoken = jwt.encode( { "iss": service_id, "iat": int(time.time()) }, api_key_secret, algorithm="HS256")# Use in requestheaders = { "Authorization": f"Bearer {token}", "Content-Type": "application/json"}
# From app/authentication/auth.py - AuthError responses# 401 Unauthorized"Unauthorized: authentication token must be provided"# Cause: No Authorization header"Unauthorized: authentication bearer scheme must be used"# Cause: Authorization header doesn't start with "Bearer "# 403 Forbidden"Invalid token: service id is not the right data type"# Cause: iss claim is not a valid UUID"Invalid token: service not found"# Cause: Service ID in iss claim doesn't exist"Invalid token: service has no API keys"# Cause: Service exists but has no API keys"Invalid token: service is archived"# Cause: Service has been deactivated"Invalid token: API key not found"# Cause: JWT signature doesn't match any API key"Invalid token: API key revoked"# Cause: API key has an expiry_date set"Error: Your system clock must be accurate to within 30 seconds"# Cause: iat timestamp is too old or too far in future"Invalid token: algorithm used is not HS256"# Cause: JWT signed with wrong algorithm"Invalid token: iss field not provided"# Cause: JWT missing iss claim
# From app/authentication/auth.pycurrent_app.logger.info( "API authorised for service %(service_id)s with api key %(api_key_id)s, " "using issuer %(issuer)s for URL: %(url)s", extra={ "service_id": service_id, "api_key_id": api_key.id, "issuer": request.headers.get("User-Agent"), "url": request.base_url, })