Skip to main content
Pulsewave uses conventional HTTP response codes: 2xx for success, 4xx for an error caused by the request, and 5xx for an error on our end.

Error shape

Every error response has the same shape:
{
  "error": {
    "type": "validation_error",
    "code": "missing_required_field",
    "message": "The 'to' field is required for channel 'email'",
    "param": "to"
  }
}
FieldDescription
typeBroad category of error. Useful for switch statements in your error handling.
codeSpecific machine-readable reason. Stable across API versions.
messageHuman-readable description. Don’t parse this — use code instead.
paramThe request field that caused the error, if applicable, otherwise null.

HTTP status codes

StatusMeaning
200 / 201 / 202Success
400The request was malformed (invalid JSON, wrong types)
401Missing or invalid API key
404The resource doesn’t exist, or doesn’t belong to your account
409The request conflicts with the resource’s current state (e.g. cancelling a message that already sent)
422The request was well-formed but failed validation
429You’ve exceeded a rate limit
500 / 503Something went wrong on our end. Safe to retry.

Error types

TypeTypical statusMeaning
invalid_request400The request couldn’t be parsed
authentication_error401The API key is missing, invalid, or revoked
not_found404The resource doesn’t exist
validation_error422A field failed validation — check param
rate_limit_error429Too many requests — see Retry-After header
api_error500An unexpected error on Pulsewave’s side

Handling errors

try {
  await pulsewave.messages.send({ channel: 'email', to, from, subject, html });
} catch (err) {
  if (err.type === 'validation_error' && err.param === 'to') {
    // show a field-level error in your UI
  } else if (err.type === 'rate_limit_error') {
    // back off and retry, see Rate limits
  } else {
    throw err;
  }
}
5xx responses and network errors are safe to retry. Pulsewave’s official SDKs retry these automatically with exponential backoff.