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.

POST /api/v1/notifications Bearer token
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 a data (or variables) object in the request with matching keys.

Your app does not send SMTP mail itself. Instead:

  1. You create a project in the Nexus dashboard
  2. Nexus gives you an API key
  3. You put that key in your backend project
  4. Your app sends a short JSON request
  5. 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.

  1. Sign in to the Nexus dashboard
  2. Open Projects
  3. Click Add Project
  4. Enter a clear name, such as My App - Production or My App - Staging
  5. Fill in the contact email and any from-address details
  6. 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:

  1. Open the projects
  2. Find the API Key section
  3. Click Regenerate API Key
  4. 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")

VariablePurposeRequiredExample / default
NEXUS_API_KEYClient API key from the dashboardyesnexus_...
NEXUS_BASE_URLAPI base URL (no trailing slash)yeshttps://nexuszm.com/api/v1
NEXUS_APP_URLPublic site URL for links inside emailsnohttps://your-app.example.com

6. Create templates

Before your app can send mail, create templates in the dashboard.

  1. Open Templates
  2. Choose the client you just created
  3. Click Create template
  4. Set the Name to the exact value your app will send (for example password_reset)
  5. Write the subject and body
  6. 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}"

StatusMeaning
queuedAccepted and waiting to send
sentDelivered successfully
failedDelivery 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>

FieldTypeDescription
templatestringRequired. Exact template name from the dashboard
tostringRequired. Recipient email address
dataobjectPlaceholder values. Keys must match {{variable}} names in the template
typestringOptional. 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.

TemplatePurposeRecipientWhen triggered
user_createdSend login credentials when an admin creates a userNew userAfter creating a user
password_resetSend a temporary password after an admin resetUserAfter resetting a password
admin_createdNotify a new admin that their account was createdNew admin emailAfter 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.

PlaceholderMeaningFrom request data
{{user_name}}Username or display nameuser_name
{{email}}Recipient email addressemail
{{password}}Generated temporary passwordpassword
{{role}}Assigned rolerole

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.

PlaceholderMeaningFrom request data
{{user_name}}Username or display nameuser_name
{{email}}Recipient email addressemail
{{password}}New temporary passwordpassword

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.

PlaceholderMeaningFrom request data
{{user_name}}Username or display nameuser_name
{{email}}Recipient email addressemail
{{password}}Generated passwordpassword
{{role}}Assigned rolerole

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.

EnvironmentRecommended storage
Local development.env file (gitignored)
DockerCompose env from host secrets
Bare metal / systemdEnvironmentFile with 600 permissions
GitHub ActionsRepository Secrets
Cloud platformsPlatform 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 data keys

  • [ ] Send a test notification with curl

In your project

  • [ ] Add NEXUS_API_KEY and NEXUS_BASE_URL to .env or server secrets

  • [ ] Confirm .env is 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:

  1. Immediately on the HTTP response when the request is rejected
  2. 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 / statusErrorMeaningFix
401Invalid or missing API keyNo Bearer token, wrong key, or regenerated keyCopy the current API key from the client page and update env
400Missing or invalid 'template'template is missing or emptySend a non-empty template string
400Missing or invalid 'to' (recipient email)No recipient email was providedSend to as a valid email, or set the client contact email
400Only 'email' type is supportedtype was something other than emailOmit type, or set type to email
402Request quota exceededThe client plan quota is used upUpgrade the plan or wait for the quota period to reset
404Notification not foundWrong request_id, or it belongs to another clientUse a request_id from your own POST response
404(no JSON / not found page)Wrong base URL or pathUse https://nexuszm.com/api/v1/notifications
500Failed to queue notificationServer could not enqueue the jobRetry 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 / statusMeaningFix
Template not foundNo template with that name for this clientCreate the template under the same client, or fix the template name
status: failedSMTP or provider delivery failedCheck Dashboard → Settings (SMTP) and Delivery logs
status: queuedStill waiting to sendWait a moment, then poll status again
Blank {{placeholders}}data keys do not match template placeholdersAlign 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 to is 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.