Documentation
Email notification API
The Nexus notification service sends emails (and optionally SMS) on behalf of your applications. Use this documentation to understand the API contract and how to integrate your backend with Nexus.
On this page
1. Overview
The Nexus notification service sends emails (and optionally SMS) on behalf of your applications. Use this documentation to understand the API contract and how to integrate your backend with Nexus.
Works with any language. The Nexus API is a standard HTTP API that accepts JSON. You can call it from Node.js, Python, Ruby, PHP, Go, Java, C#, Elixir, or any language that can send HTTP requests — no SDK required. The same endpoint and request format apply everywhere; only the syntax of your HTTP call changes.
-
Endpoint:
POST /api/v1/notifications -
Auth:
Authorization: Bearer <client_api_key> -
Email body and subject support placeholders:
{{variable_name}}. Replace them by sending adata(orvariables) object in the request with matching keys.
Your app does not send SMTP mail itself. Instead:
- You create a project in the Nexus dashboard
- Nexus gives you an API key
- You put that key in your backend project
- Your app sends a short JSON request
- Nexus fills in a template and delivers the email
Example payload:
{
"template": "password_reset",
"to": "user@example.com",
"data": {
"user_name": "Jane",
"email": "user@example.com",
"password": "TempPass123"
}
}
2. Before you start
Sign in to the Nexus dashboard and have a backend project ready. Store your API key on the server only — never in a browser or mobile app.
3. Create a Project
A project is one application or environment that will send email through Nexus.
- Sign in to the Nexus dashboard
- Open Projects
- Click Add Project
-
Enter a clear name, such as
My App - ProductionorMy App - Staging - Fill in the contact email and any from-address details
- Save the client
Create a separate project for each environment. That keeps API keys and templates from mixing.
Examples:
-
My App - Production -
My App - Staging
4. Generate an API key
When you create a project, Nexus generates an API key automatically. Copy it immediately — it may not be shown again in full.
To get a new key later:
- Open the projects
- Find the API Key section
- Click Regenerate API Key
- Copy the new key and update your project
Treat the key like a password:
-
Do not put it in frontend code
-
Do not commit it to git
-
Do not share it in chat or screenshots
5. Add the key to your project
Store the key in server-side environment variables. Never hard-code it in source files.
Create or edit a .env file in your project root (and keep that file gitignored):
NEXUS_API_KEY=your-secret-key
NEXUS_BASE_URL=https://nexuszm.com/api/v1
NEXUS_APP_URL=https://your-app.example.com
Then read those values in your app:
Node.js
const apiKey = process.env.NEXUS_API_KEY;
const baseUrl = process.env.NEXUS_BASE_URL;
Python
import os
api_key = os.environ["NEXUS_API_KEY"]
base_url = os.environ["NEXUS_BASE_URL"]
PHP
$apiKey = getenv('NEXUS_API_KEY');
$baseUrl = getenv('NEXUS_BASE_URL');
Elixir
api_key = System.get_env("NEXUS_API_KEY")
base_url = System.get_env("NEXUS_BASE_URL")
| Variable | Purpose | Required | Example / default |
|---|---|---|---|
| NEXUS_API_KEY | Client API key from the dashboard | yes | nexus_... |
| NEXUS_BASE_URL | API base URL (no trailing slash) | yes | https://nexuszm.com/api/v1 |
| NEXUS_APP_URL | Public site URL for links inside emails | no | https://your-app.example.com |
6. Create templates
Before your app can send mail, create templates in the dashboard.
- Open Templates
- Choose the client you just created
- Click Create template
-
Set the Name to the exact value your app will send (for example
password_reset) - Write the subject and body
-
Use placeholders that match the keys in your JSON
data
Copy the full subject and body examples from Example templates below. A short password_reset body looks like this:
Hello {{user_name}},
An administrator has reset your password.
Your new temporary password: {{password}}
If your request sends:
{
"data": {
"user_name": "Jane",
"email": "user@example.com",
"password": "TempPass123"
}
}
then the template must use those exact names.
Template names are case-sensitive. password_reset is not the same as Password_Reset.
7. Test with curl
Test from your terminal before writing application code.
export NEXUS_API_KEY="your-secret-key"
export NEXUS_BASE_URL="https://nexuszm.com/api/v1"
curl -X POST "${NEXUS_BASE_URL}/notifications" \
-H "Authorization: Bearer ${NEXUS_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"template": "password_reset",
"to": "user@example.com",
"data": {
"user_name": "Jane",
"email": "user@example.com",
"password": "TempPass123"
}
}'
A successful response looks like:
{
"id": 12,
"request_id": "abc123xyz",
"status": "queued",
"message": "Notification queued for delivery"
}
HTTP 202 means Nexus accepted the request. Then check Delivery logs in the dashboard, or poll the status endpoint below.
8. Check delivery status
Use the request_id from the POST response:
curl -X GET "${NEXUS_BASE_URL}/notifications/REQUEST_ID_HERE" \
-H "Authorization: Bearer ${NEXUS_API_KEY}"
| Status | Meaning |
|---|---|
| queued | Accepted and waiting to send |
| sent | Delivered successfully |
| failed | Delivery failed — check error_message or Delivery logs |
You can also open Delivery logs and API logs in the dashboard.
9. Send from your app
Endpoint: POST /api/v1/notifications
Auth: Authorization: Bearer <client_api_key>
| Field | Type | Description |
|---|---|---|
| template | string | Required. Exact template name from the dashboard |
| to | string | Required. Recipient email address |
| data | object | Placeholder values. Keys must match {{variable}} names in the template |
| type | string | Optional. Defaults to email |
You can send variables instead of data. Both are accepted.
9.1 Node.js
const response = await fetch(`${process.env.NEXUS_BASE_URL}/notifications`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NEXUS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
template: "password_reset",
to: "user@example.com",
data: {
user_name: "Jane",
email: "user@example.com",
password: "TempPass123",
},
}),
});
if (response.status === 202) {
const body = await response.json();
console.log("request_id:", body.request_id);
}
9.2 Python
import os
import requests
response = requests.post(
os.environ["NEXUS_BASE_URL"].rstrip("/") + "/notifications",
headers={
"Authorization": f"Bearer {os.environ['NEXUS_API_KEY']}",
"Content-Type": "application/json",
},
json={
"template": "password_reset",
"to": "user@example.com",
"data": {
"user_name": "Jane",
"email": "user@example.com",
"password": "TempPass123",
},
},
timeout=15,
)
print(response.json())
9.3 Other languages
Use your language's HTTP client (PHP curl, Go net/http, Java HttpClient, C# HttpClient, Elixir Req) and send the same headers and JSON. The API contract does not change.
10. Example templates
These examples show common templates. For each one, copy the name, subject, and body into Templates in the dashboard. Then send the same template name and data keys from your backend.
| Template | Purpose | Recipient | When triggered |
|---|---|---|---|
| user_created | Send login credentials when an admin creates a user | New user | After creating a user |
| password_reset | Send a temporary password after an admin reset | User | After resetting a password |
| admin_created | Notify a new admin that their account was created | New admin email | After creating an admin user |
The HTTP contract stays the same for any other notification you add later — only the name and placeholders change.
11. user_created
Use this when your app creates a user and needs to email them their temporary password. Some deployments send this as Account_creation — the template name in the dashboard must match what your app sends.
Create this in the dashboard
-
Name:
user_created -
Subject:
Your account – temporary password
Body:
Hello {{user_name}},
An administrator has created an account for you.
Email: {{email}}
Role: {{role}}
Your temporary password: {{password}}
You will be required to change this password when you first sign in.
Sign in at your application URL and use the above password, then set a new one.
| Placeholder | Meaning | From request data |
|---|---|---|
| {{user_name}} | Username or display name | user_name |
| {{email}} | Recipient email address | |
| {{password}} | Generated temporary password | password |
| {{role}} | Assigned role | role |
Example request:
{
"template": "user_created",
"to": "user@example.com",
"data": {
"user_name": "Jane",
"email": "user@example.com",
"password": "TempPass123",
"role": "user"
}
}
12. password_reset
Use this when an admin resets a user’s password.
Create this in the dashboard
-
Name:
password_reset -
Subject:
Your password has been reset
Body:
Hello {{user_name}},
An administrator has reset your password.
Email: {{email}}
Your new temporary password: {{password}}
You will be required to change this password when you next sign in.
Sign in at your application URL and set a new password when prompted.
| Placeholder | Meaning | From request data |
|---|---|---|
| {{user_name}} | Username or display name | user_name |
| {{email}} | Recipient email address | |
| {{password}} | New temporary password | password |
Example request:
{
"template": "password_reset",
"to": "user@example.com",
"data": {
"user_name": "Jane",
"email": "user@example.com",
"password": "TempPass123"
}
}
13. admin_created
Use this when notifying a new admin that their account was created.
Create this in the dashboard
-
Name:
admin_created -
Subject:
Your admin account has been created
Body:
Hello {{user_name}},
An administrator has created an admin account for you.
Email: {{email}}
Role: {{role}}
Your temporary password: {{password}}
Sign in at your application URL and change this password when prompted.
| Placeholder | Meaning | From request data |
|---|---|---|
| {{user_name}} | Username or display name | user_name |
| {{email}} | Recipient email address | |
| {{password}} | Generated password | password |
| {{role}} | Assigned role | role |
Example request:
{
"template": "admin_created",
"to": "user@example.com",
"data": {
"user_name": "Jane",
"email": "user@example.com",
"password": "theGeneratedPasswordFromYourSystem",
"role": "admin"
}
}
14. Where to store the key
Always keep the key on the server only.
| Environment | Recommended storage |
|---|---|
| Local development | .env file (gitignored) |
| Docker | Compose env from host secrets |
| Bare metal / systemd | EnvironmentFile with 600 permissions |
| GitHub Actions | Repository Secrets |
| Cloud platforms | Platform secret manager / env UI |
Never put the key in:
-
Frontend JavaScript
-
Mobile app source code
-
Public git repositories
-
Query strings or cookies
15. Common mistakes
Wrong template name
The name in JSON must match the dashboard exactly. If it does not, the request may still return 202, then fail later with Template not found.
"template": "password_reset" yes
"template": "Password Reset" no
"template": "PASSWORD_RESET" no
Template not found
Create the template under the same client whose API key you are using. A template on another client will not match.
Placeholder mismatch
If the template uses {{user_name}} but your payload sends username, that field stays blank. Match the keys exactly.
Missing or invalid API key
A missing or wrong key returns 401 with Invalid or missing API key. Regenerate the key in the client page and update your environment variables.
Wrong URL
A wrong base URL returns 404. The send path is:
https://nexuszm.com/api/v1/notifications
16. Onboarding checklist
In Nexus
-
[ ] Log in to the dashboard
-
[ ] Create a client
-
[ ] Copy the API key and store it securely
-
[ ] Create the required templates
-
[ ] Confirm placeholder names match your
datakeys -
[ ] Send a test notification with curl
In your project
-
[ ] Add
NEXUS_API_KEYandNEXUS_BASE_URLto.envor server secrets -
[ ] Confirm
.envis in.gitignore -
[ ] Read both values from environment variables
-
[ ] Send a test POST to
/notifications -
[ ] Confirm the email arrives (or status becomes
sent)
17. Common errors
Nexus returns errors in two places:
- Immediately on the HTTP response when the request is rejected
- Later in delivery status when the request was accepted (202) but sending failed
Always check both the HTTP response and Delivery logs (or GET /notifications/{request_id}).
HTTP errors (request rejected)
| HTTP / status | Error | Meaning | Fix |
|---|---|---|---|
| 401 | Invalid or missing API key | No Bearer token, wrong key, or regenerated key | Copy the current API key from the client page and update env |
| 400 | Missing or invalid 'template' | template is missing or empty | Send a non-empty template string |
| 400 | Missing or invalid 'to' (recipient email) | No recipient email was provided | Send to as a valid email, or set the client contact email |
| 400 | Only 'email' type is supported | type was something other than email | Omit type, or set type to email |
| 402 | Request quota exceeded | The client plan quota is used up | Upgrade the plan or wait for the quota period to reset |
| 404 | Notification not found | Wrong request_id, or it belongs to another client | Use a request_id from your own POST response |
| 404 | (no JSON / not found page) | Wrong base URL or path | Use https://nexuszm.com/api/v1/notifications |
| 500 | Failed to queue notification | Server could not enqueue the job | Retry later; check API logs if it continues |
Example error body:
{
"error": "Invalid or missing API key"
}
Delivery errors (after HTTP 202)
A 202 response means Nexus queued the notification. It can still fail while rendering or sending.
| Error / status | Meaning | Fix |
|---|---|---|
| Template not found | No template with that name for this client | Create the template under the same client, or fix the template name |
| status: failed | SMTP or provider delivery failed | Check Dashboard → Settings (SMTP) and Delivery logs |
| status: queued | Still waiting to send | Wait a moment, then poll status again |
| Blank {{placeholders}} | data keys do not match template placeholders | Align data keys with {{variable}} names in the template |
Example status response after a failed send:
{
"id": 42,
"status": "failed",
"error_message": "Template not found",
"template": "password_reset"
}
Quick checks when something fails
-
Confirm the Authorization header is
Bearer <api_key> -
Confirm the template name matches the dashboard exactly
-
Confirm the template belongs to the same client as the API key
-
Confirm
tois a valid email string -
Open Delivery logs and API logs in the dashboard
18. FAQ
Can I call Nexus from the browser or a mobile app?
No. The API key would be exposed. Always call Nexus from your backend.
Are template names case-sensitive?
Yes. Use the exact name from the dashboard.
Must all data values be strings?
Yes for best compatibility. Send "15" instead of 15.
What does HTTP 202 mean?
Nexus queued the email. It can still fail later (for example Template not found). Check delivery with GET /notifications/{request_id} or in Delivery logs.
Do I need a separate API key per environment?
Yes. Create one client for staging and another for production.
Does Nexus support attachments?
This API uses template + data only. Check with your Nexus admin for extra features.