API Reference
NorthRelay REST API overview, base URL, authentication, rate limits, error handling, and pagination.
API Reference
The NorthRelay API lets you send transactional and marketing emails, manage domains, templates, contacts, mailing-list subscriptions, suppressions, and retrieve analytics programmatically.
Base URL
All API requests use the following base URL:
https://app.northrelay.ca/api/v1/All requests must be made over HTTPS. Plain HTTP requests are rejected.
Authentication
Authenticate every request with a Bearer token in the Authorization header:
curl https://app.northrelay.ca/api/v1/emails/send \
-H "Authorization: Bearer nr_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ ... }'API keys use two prefixes:
| Prefix | Environment | Purpose |
|---|---|---|
nr_live_ | Production | Sends real emails |
nr_test_ | Accepted legacy prefix | Does not itself isolate delivery or quota; use a test environment with a mail sink |
Create and manage keys in Dashboard > Settings > API Keys. See the Authentication page for full details.
Rate Limits
Sending quotas are enforced per account based on your plan tier. They are expressed as recipients per calendar month and reset on the 1st:
| Tier | Monthly Quota | Price (CAD) |
|---|---|---|
| Free | 3,000 | Free |
| Starter | 5,000 | $5/mo |
| Micro | 20,000 | $12/mo |
| Pro | 50,000 | $29/mo |
| Scale | 150,000 | $79/mo |
When you exceed your monthly quota, the API returns a 429 status with the QUOTA_EXCEEDED error code and the date the counter resets. Upgrading raises the limit immediately.
API request rate limits (separate from email quotas):
| Endpoint | Limit |
|---|---|
POST /emails/send | 100 requests/second |
POST /emails/batch | 10 requests/second |
POST /emails/validate | 50 requests/second |
| All other endpoints | 200 requests/second |
Error Handling
Every error response follows a consistent JSON structure with four fields:
{
"code": "DOMAIN_NOT_FOUND",
"message": "The specified domain was not found",
"action": "Check the domain ID and try again",
"docs_url": "https://docs.northrelay.ca/domains/setup"
}| Field | Type | Description |
|---|---|---|
code | string | Machine-readable error code for programmatic handling |
message | string | Human-readable description of the problem |
action | string | Actionable instruction to resolve the issue |
docs_url | string | Link to relevant documentation |
HTTP Status Codes
| Status | Meaning |
|---|---|
200 | Success |
201 | Resource created |
400 | Validation error or bad request |
401 | Missing or invalid authentication |
403 | Insufficient permissions or tier |
404 | Resource not found |
429 | Rate limit exceeded |
500 | Internal server error |
503 | Service temporarily unavailable |
Error Codes Reference
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | No valid session or API key provided |
INVALID_CREDENTIALS | 401 | API key is malformed or revoked |
SESSION_EXPIRED | 401 | Session token has expired |
VERIFICATION_FAILED | 400 | Verification code is invalid |
VERIFICATION_EXPIRED | 400 | Verification code has expired |
RATE_LIMIT_EXCEEDED | 429 | Monthly quota or request rate exceeded |
DOMAIN_NOT_FOUND | 404 | Domain ID does not exist |
DOMAIN_ALREADY_EXISTS | 400 | Domain is already registered |
DNS_VERIFICATION_FAILED | 400 | Required DNS records not found |
DNS_RECORD_MISSING | 400 | Specific DNS record is missing |
DNS_LOOKUP_ERROR | 400 | Unable to query DNS for the domain |
API_KEY_NOT_FOUND | 404 | API key ID does not exist |
API_KEY_INVALID | 401 | API key is invalid or expired |
API_KEY_LIMIT_REACHED | 400 | Maximum number of API keys reached |
WEBHOOK_SIGNATURE_INVALID | 401 | Webhook signature verification failed |
WEBHOOK_PAYLOAD_INVALID | 400 | Webhook payload does not match schema |
WEBHOOK_EVENT_UNKNOWN | 400 | Unrecognized webhook event type |
VALIDATION_ERROR | 400 | Request body failed validation |
NOT_FOUND | 404 | Requested resource not found |
INTERNAL_ERROR | 500 | Unexpected server error |
SERVICE_UNAVAILABLE | 503 | Downstream service temporarily unavailable |
Pagination
List endpoints return paginated results. Control pagination with query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (1-indexed) |
limit | integer | 25 | Items per page (max 100) |
Every paginated response includes a pagination object:
{
"data": [ ... ],
"pagination": {
"page": 1,
"limit": 25,
"total": 142,
"totalPages": 6
}
}Versioning
The API is versioned via the URL path (/api/v1/). Breaking changes will be introduced under a new version prefix (e.g., /api/v2/). Non-breaking additions (new fields, new endpoints) are added to the current version without a version bump.
Content Type
All request bodies must be JSON with the Content-Type: application/json header. All responses are JSON.
Next Steps
- Authentication -- create and use API keys
- Sending -- send single, batch, and scheduled emails
- Domains -- add and verify custom sending domains
- Templates -- manage reusable email templates
- Webhooks -- receive delivery event notifications