API Response Warnings

Sometimes an API request succeeds, but the outcome differs from what you asked for — a parameter was ignored, an optional flow was skipped, or a record was changed in a way you may not have intended. Instead of failing the request or staying silent, the Broadcast API explains the difference in a warnings array included in the response.

This is a cross-cutting convention: any endpoint that accepts input may include warnings in its response.

When warnings appear

A warning is added whenever the API accepts your request but the result diverges from the input. The most common situations:

  1. A parameter was not recognized — for example, a misspelled field, or a parameter placed at the wrong nesting level. The API processes the rest of the request and tells you which parameters it ignored.
  2. A requested flow was skipped — for example, requesting double opt-in for a subscriber who is already confirmed. The request succeeds, but no confirmation email is sent.
  3. A side effect you may not have intended — for example, creating a subscriber that already exists reactivates the existing record.
  4. A better-suited endpoint exists for what you appear to be doing — for example, updating a subscriber with is_active: false deactivates the record, but only the dedicated unsubscribe endpoint records an unsubscribe date and adds the address to the suppression list.

Warnings apply to update endpoints exactly as they do to create endpoints: an unrecognized or misplaced parameter in a PATCH/PUT request is ignored and reported the same way.

If everything in your request was applied exactly as sent, the warnings key is absent from the response.

Response format

Warnings appear as a top-level warnings array alongside the normal response body. Each warning has a machine-readable code, a human-readable message, and — where relevant — the param it refers to:

{
  "id": 123,
  "email": "jane@example.com",
  "is_active": true,
  "confirmed_at": "2026-01-10T09:30:00Z",
  "warnings": [
    {
      "code": "double_opt_in_skipped",
      "message": "Subscriber is already confirmed; no confirmation email was sent."
    }
  ]
}

A warning never changes the HTTP status code. A 200/201 with warnings is still a success — the warnings only describe how the outcome differs from the request.

Warnings appear only on successful (2xx) responses. A failed request performs no work, so there is no divergence to report — the error/errors key is the explanation.

A small number of endpoints respond with an empty body (for example, adding or removing a sequence subscriber) — those responses cannot carry warnings.

List endpoints can warn too: an unusable filter value (for example, a created_after date that cannot be parsed) is reported with parameter_ignored while the rest of the query is answered normally.

Warnings describe what happened during this request. Retrying an identical request may return different warnings — or none — because the first request changed state. For example, a create that reactivates an inactive subscriber warns subscriber_reactivated; the identical retry finds an already-active subscriber and raises no warning.

Warning codes

Code Meaning
unrecognized_parameter A parameter in your request was not recognized and was ignored. The param field names it. Check the spelling and nesting level against the endpoint’s documentation.
double_opt_in_skipped Double opt-in was requested, but the subscriber is already confirmed, so the confirmation step was skipped. On subscriber creation no confirmation email is sent; on transactional sends the email is sent normally without a confirmation step.
subscriber_reactivated The create call matched an existing inactive or unsubscribed subscriber, and that record was reactivated.
use_dedicated_endpoint The update was applied, but a dedicated endpoint exists for this operation with additional behavior you likely want. The message names it.
parameter_ignored A recognized parameter was not applied in this context — for example, a value only used by another flow, a field that cannot change in the record’s current state, or a filter value that could not be interpreted. The message explains why.
parameter_overridden The server applied a different value than the one you sent — for example, creating a subscriber always activates it, even if you pass is_active: false. The response body shows the value actually applied.

The set of codes will grow over time as more endpoints adopt richer warnings. Treat unknown codes as informational: log them, but do not fail on them.

Stability guarantees

  • code values are stable. Codes are append-only: new codes may be added, but existing codes are never renamed or removed. Branch your logic on code.
  • message text is not stable. Messages are written for humans and may be reworded at any time — never parse or match on them.
  • param uses dot-path notation relative to the request body or query string, e.g. subscriber.double_opt_in — including keys inside option hashes, e.g. double_opt_in.replyto for a misspelled reply_to. It names the parameter only; submitted values are never echoed back.
  • Tolerate the unknown. Your client must accept responses with no warnings key, warnings with codes it has not seen, and warnings with additional fields added later.

Example: misplaced parameter

A common mistake is nesting flow-level options inside the subscriber object. Flow options such as double_opt_in and confirmation_template_id are top-level parameters (see Subscribers API):

POST /api/v1/subscribers

{
  "subscriber": {
    "email": "jane@example.com",
    "double_opt_in": true
  }
}

The subscriber is created, but double_opt_in is not a subscriber attribute, so no confirmation flow runs. The response makes that visible:

{
  "id": 124,
  "email": "jane@example.com",
  "warnings": [
    {
      "code": "unrecognized_parameter",
      "param": "subscriber.double_opt_in",
      "message": "double_opt_in is not a subscriber attribute and was ignored. Pass it as a top-level parameter instead."
    }
  ]
}

Example: deactivating instead of unsubscribing

Update endpoints raise warnings the same way. Here, setting is_active: false via the generic update succeeds, but unsubscribing through the dedicated endpoint is almost always what you want — it also records the unsubscribe date and adds the address to the channel’s suppression list:

PATCH /api/v1/subscribers?email=jane@example.com

{
  "subscriber": {
    "is_active": false
  }
}
{
  "id": 123,
  "email": "jane@example.com",
  "is_active": false,
  "unsubscribed_at": null,
  "warnings": [
    {
      "code": "use_dedicated_endpoint",
      "param": "subscriber.is_active",
      "message": "Subscriber was deactivated, but no unsubscribe date or suppression entry was recorded. To unsubscribe a subscriber, use POST /api/v1/subscribers/unsubscribe instead."
    }
  ]
}

Handling warnings in your integration

  • Log them. Warnings are the fastest way to spot an integration bug — a typo’d field name or misplaced parameter shows up immediately instead of failing silently.
  • Do not treat them as errors. The request succeeded, and the response body reflects the actual state. Warnings are advisory context, not a signal to retry.
  • Ignore unknown keys and codes. Your client should tolerate both the warnings key being absent and warning codes it has not seen before.

Backwards compatibility

The warnings array is additive and optional:

  • No existing response fields change — names, types, and values stay the same.
  • HTTP status codes are unchanged.
  • The key is only present when at least one warning was raised.

Clients that read specific fields from responses (the common case, including the official Ruby SDK) are unaffected. If you validate responses against a strict schema, allow additional properties — per standard REST evolution rules, the API may add new response fields over time.

Was this page helpful?

Thanks for your feedback!

Thanks for letting us know. We'll work on improving this page.