Skip to main content
The Novu API uses conventional HTTP status codes to indicate the success or failure of a request. Codes in the 2xx range indicate success. Codes in the 4xx range indicate a request that failed given the information provided (for example, a required parameter was missing or validation failed). Codes in the 5xx range indicate an error on Novu’s servers and are rare. Every error response shares a consistent JSON shape, so you can handle errors the same way across all endpoints.

HTTP status codes

StatusMeaningWhen you see it
200 201 204SuccessThe request succeeded. 204 returns no body.
400 Bad RequestInvalid requestMalformed input, or schema/payload validation failed.
401 UnauthorizedAuthentication failedMissing, malformed, or invalid secret key. See Authentication.
402 Payment RequiredPlan limit reachedThe operation exceeds your current plan’s limit.
403 ForbiddenInsufficient permissionsThe credential cannot perform this action.
404 Not FoundResource missingThe requested resource does not exist in this environment.
409 ConflictRequest conflictA duplicate resource, or an idempotency key still being processed. See Idempotency.
413 Payload Too LargeBody too largeThe request body exceeds the limit. See Payload Limits.
422 Unprocessable EntityValidation errorThe request body failed field-level validation.
429 Too Many RequestsRate limitedYou exceeded the rate limit. See Rate Limiting.
500 Server ErrorInternal errorSomething went wrong on Novu’s end. Retry, then contact support with the errorId.

Error response shape

All errors return a JSON body with a consistent set of fields:
{
  "statusCode": 404,
  "timestamp": "2024-12-12T13:00:00Z",
  "path": "/v1/subscribers/does-not-exist",
  "message": "Subscriber not found"
}
FieldTypeDescription
statusCodenumberThe HTTP status code of the response.
timestampstringISO-8601 timestamp of when the error occurred.
pathstringThe request path that produced the error.
messagestring | string[]A human-readable description of the error.
errorsobject | arrayPresent on validation errors. Details which fields failed and why.
errorIdstringPresent on 500 responses only. A unique identifier to share with support.
Some errors include additional context fields (for example, currentCount and limit on a 402 plan-limit error). For backward compatibility, these context fields are flattened to the top level of the response body alongside the standard fields.

Validation errors

Validation errors describe exactly which fields were rejected. The format depends on where validation happens.
Most request body validation returns 422 Unprocessable Entity with an errors object keyed by field name. Each entry lists the failing messages and the rejected value:
{
  "statusCode": 422,
  "timestamp": "2024-12-12T13:00:00Z",
  "path": "/v1/subscribers",
  "message": "Validation Error",
  "errors": {
    "email": {
      "messages": ["email must be a valid email address"],
      "value": "not-an-email"
    },
    "subscriberId": {
      "messages": ["subscriberId should not be empty"],
      "value": ""
    }
  }
}
Use the errors keys to map each message back to the form field or parameter that caused it.

Server errors

500 responses include an errorId that uniquely identifies the failure in Novu’s monitoring systems:
{
  "statusCode": 500,
  "timestamp": "2024-12-12T13:00:00Z",
  "path": "/v1/events/trigger",
  "message": "Internal server error, contact support and provide them with the errorId",
  "errorId": "f1d2c3b4-a5e6-7890-1234-567890abcdef"
}
When contacting support, include the errorId so the team can locate the exact request.

Debugging requests

Beyond the error body, Novu gives you several ways to trace a request:

Handling errors

The server-side SDKs throw a typed error you can inspect. Check the statusCode to branch your logic, and read message or errors for details:
import { Novu } from '@novu/api';

const novu = new Novu({ secretKey: process.env.NOVU_SECRET_KEY });

try {
  await novu.trigger({
    workflowId: 'welcome',
    to: { subscriberId: 'subscriber-123' },
    payload: {},
  });
} catch (error) {
  switch (error.statusCode) {
    case 422:
      // Inspect error.errors to find which fields failed validation.
      console.error('Validation failed', error.errors);
      break;
    case 429:
      // Back off and retry. See the Rate Limiting guide.
      console.error('Rate limited, retry later');
      break;
    case 500:
      // Share error.errorId with support.
      console.error('Server error', error.errorId);
      break;
    default:
      console.error(error.message);
  }
}