NUACOM API

Getting started

Errors

The API reports failure with an HTTP status code and a JSON body. The status tells you what kind of problem it is; the body tells you which. This page lists the statuses you will meet, the body shapes behind them with one example each, the numeric and named codes some operations add, and how to handle each kind. Rate limiting has its own page, Rate limits.

Status codes

Status When Body
400 A request the API understood but cannot act on: an unknown filter[…] or sort field, an input a domain check refused, a payment the card provider declined {"message": …}, with error_code on payments
401 The Authorization header is missing, or the token is invalid, expired or disabled, or the user behind it has no active account The string "Unauthorized". From login: {"code", "error", "requirements"}
402 An SMS or WhatsApp send with no credit left {"message", "error_code": 6001, "error": "SMS_ERROR"}
403 The endpoint needs an account admin, a feature NUACOM enables per account, or access to a resource the user may not see The string "Forbidden" from the admin check; {"message": …} otherwise
404 No route at that path, or no resource with that id visible to the caller {"message": "Resource not found!", "trace": null}
405 The path exists but the method is not supported there {"message": …}
422 Validation failed, or a domain rule stopped the operation (an SMS code, a closed WhatsApp window) {"message", "errors"} for validation; a code shape for domain rules
429 Too many requests, see Rate limits {"message": "Too Many Attempts."}
5xx Something failed on NUACOM's side {"message": "Server Error"} or {"message": "An error occurred", "trace": null}

Body shapes

Plain strings. Two checks answer a bare JSON string, not an object: 401 "Unauthorized" from the token check and 403 "Forbidden" from the account-admin check. Parse the body as JSON and test for a string before reading keys.

message only. The default shape for everything that stops before the endpoint runs: unknown routes, wrong methods, unknown filters, per-account feature checks and most access checks. A trace key is sometimes present; it is always null. A 403 from a feature check has an empty message; other 403s say why.

{"message": "Requested filter(s) `city` are not allowed. Allowed filter(s) are `contact_ids, search, group, …`."}

Validation, 422. errors maps each failing input to a list of messages. Nested inputs use dot keys (metadata.template_id, phones.0). Most endpoints add message, the first error plus a count; a few older ones send errors alone. Read errors, not message.

{
  "message": "The email field must be a valid email address. (and 1 more error)",
  "errors": {
    "email": ["The email field must be a valid email address."],
    "first_name": ["The first name field is required when last name is not present."]
  },
  "trace": null
}

Domain errors with a code. Operations that fail for a business reason keep a 4xx status and add a code. The key that carries it depends on the endpoint:

Where Status Shape
Payments and purchases (top-ups, add-ons, extensions) 400 {"message": …, "error_code": "PAYMENT-DECLINED"}, or {"message": …, "error_code": "PAYMENT-INCOMPLETE", "incomplete_payment": {"client_secret": …, "payment_method": …, "payment_method_types": […]}}
POST /v2/sms/send 422 {"code": 6001, "error": "Insufficient credit"}; code is an SMS code from the table below
POST /v2/conversations 402 for 6001, otherwise 422 {"message": …, "error_code": 6001, "error": "SMS_ERROR"}. A bulk send that failed for every recipient adds success_count, failed_count and total_count, with error_code 6009 (422) or 6001 (402); a partial failure answers 201 with warning_code 6008 and warning
POST /v2/conversations/{conversation}/messages 400, or 402 for 6001 {"message": …, "error_code": 6003, "resultCode": null, "error": "SMS_ERROR"}
Other SMS endpoints 422 {"message": …, "result_code": 6004}

WhatsApp window. A free-form WhatsApp message outside the 24-hour customer-service window is refused with 422: on POST /v2/conversations as {"message": "The Customer Service Window is closed…", "error": "WHATSAPP_CSW_CLOSED"}, on POST /v2/conversations/{conversation}/messages as a validation error on metadata.template_id. Send an approved template instead; see Conversations / WhatsApp.

Login. POST /v2/auth/login answers 401 with its own shape, {"code": 4001, "error": "…", "requirements": […]}. requirements is empty except for 4001, where it lists the account's password policy.

Code reference

Login (code in a 401 from POST /v2/auth/login)

code Meaning
401 Wrong email or password, an invalid or expired two-factor code, or too many failed attempts from this IP address (five in five minutes)
4001 The password has expired; requirements lists the policy. Change it and log in again
4002 Password login is disabled for this account (single sign-on only)
4004 Logins are not allowed from this IP address

SMS and MMS (code, error_code or result_code, see the table above)

Code Meaning
6001 Insufficient credit
6002 No valid recipient
6003 Invalid sender: the account has no active sender name
6004 The sender name is not approved for Irish numbers
6005 The US campaign is not approved
6006 Delivery failed
6007 Scheduling error
6008 Part of a bulk send failed (warning_code on a 201)
6009 The whole bulk send failed
6010 Draft not found
6011 Message limit reached
6012 Too many requests
6013 Auto top-up failed; the draft is kept so you can retry after fixing the card
6014 The send failed after a successful auto top-up; the draft is kept
6101 MMS is not enabled for the account
6102 MMS is not supported for the destination country (US, CA and AU only)
6103 Too many media files (10 per message)
6104 Media not found
6105 Media not approved yet, or rejected by moderation
6106 The toll-free number is not verified for US recipients

Payments (error_code in a 400)

error_code Meaning
PAYMENT-DECLINED The card was declined; message carries the card provider's reason
PAYMENT-INCOMPLETE The payment needs 3-D Secure confirmation. incomplete_payment.client_secret identifies the payment to confirm; the NUACOM portal completes it in the browser

Handling errors

  1. Branch on the status first, then on the code key, never on message text: messages are for humans and can change.
  2. 401 from an endpoint: stop and fix the token; retrying does not help. 401 from login counts toward the per-IP lockout, five failures in five minutes.
  3. 403: a role or feature problem. Check the group guide's Roles and access section.
  4. 422 with errors: fix the inputs named in errors and resend. 422, 402 or 400 with an SMS code: act on the code (top up, approve the sender, pick a template) rather than resending.
  5. 429: wait Retry-After seconds, then repeat the same request.
  6. 5xx: retry once or twice with an increasing delay; if it persists, contact support with the time, the method and the path.