Skip to content
Norbelys
Esc
↑↓navigate↵open⌘Jpreview

Release a message's holds.

A recipient is held when evidence about this message said its mailbox was full, its server asked to come back later, or its domain had no mail route: mail to the address waits until a later success of the message lifts the hold, the hold’s time runs out, or a person who knows better releases it here. Every open hold of the message is resolved as manual, so mail to those addresses flows again, and the evidence is kept in the workspace’s audit log. A message without open holds is answered as it is.

POST/v1/messages/{id}/release_holds
Authorization
AuthorizationBearer token · headerrequired

An API key (nb_live_…, nb_test_…), a workspace token (nbs_…) or a CLI token (nbc_…).

Path parameters
idId_Messagerequired

The message id (msg_…).

matches ^msg_[0-9a-f]{32}$
Header parameters
Idempotency-Keystringrequired

A stable key for this logical request; reuse it when retrying.

min length 1 · max length 128 · matches ^[!-~]+$
Request body
requiredapplication/json
evidencestringrequired

What shows the holds no longer apply, for the record: what the person checked. At most 2,000 characters.

Responses
200

The message, its holds released.

attemptsAttemptsrequired

A message's latest attempts.

Show properties
dataAttemptObject[]required

At most 20, newest first.

max items 20
Show properties
Array of AttemptObject
categorystring | null
claimed_atTimestamprequired
connection_idId_Connectionrequired
matches ^con_[0-9a-f]{32}$
diagnosticstring | null

The provider's words, bounded and redacted.

enhanced_statusstring | null
finished_atTimestamp | null
Show properties
One of:
Timestamp
Timestamp
null
null
idId_Attemptrequired
matches ^att_[0-9a-f]{32}$
numberinteger<int32>required

1 for the message's first attempt.

outcomestring | null

accepted, transient, permanent, uncertain, released, suppressed or skipped; null while the attempt runs. New values may be added.

phasestring | null

Where it ended: connect, auth, mail_from, rcpt_to, data or api. New values may be added.

provider_message_idstring | null

The provider's id of the accepted message, when it returns one.

recipient_countinteger<int32>required
smtp_codeinteger<int32> | null
started_atTimestamp | null
Show properties
One of:
Timestamp
Timestamp
null
null
has_morebooleanrequired

More attempts exist than data shows; read them through an export.

attempts_countinteger<int64>required

Every attempt it had.

bccstring[]required
campaign_idId_Campaign | null
Show properties
One of:
Id_Campaign
string
null
null
ccstring[]required
connection_idId_Connectionrequired
matches ^con_[0-9a-f]{32}$
created_atTimestamprequired
enrollment_idId_Enrollment | null
Show properties
One of:
Id_Enrollment
string
null
null
eventsEventsrequired

A message's first delivery events.

Show properties
dataDeliveryEventObject[]required

At most 20, in the order they were observed.

max items 20
Show properties
Array of DeliveryEventObject
actionstring | null

The RFC 3464 action, for a delivery status notification.

attempt_numberinteger<int32> | null

The attempt it comes from, when its source is an attempt.

categorystringrequired
confidencestringrequired

authenticated, corroborated, inferred or human_text. New values may be added.

diagnosticstring | null
enhanced_statusstring | null
idId_DeliveryEventrequired
matches ^dev_[0-9a-f]{32}$
kindstringrequired

accepted, deferred, delivered, bounced, rejected, complaint, unsubscribed, address_changed or reported. New values may be added.

message_idId_Message | null
Show properties
One of:
Id_Message
string
null
null
observed_atTimestamprequired

When the source observed it.

phasestring | null
processed_atTimestamprequired

When Norbelys recorded it.

received_atTimestamprequired

When Norbelys received it.

recipientstring | null

The recipient it concerns; null when the evidence names none.

recipient_refstringrequired

Why the recipient is known: named, single_envelope or unknown. New values may be added.

sourcestringrequired

smtp, provider_api, provider_webhook, dsn, arf, inbound_notice, preflight, unsubscribe, manual or sent_folder. New values may be added.

thread_idId_Thread | null
Show properties
One of:
Id_Thread
Id_Thread
null
null
has_morebooleanrequired

More events exist; url lists them all.

urlstringrequired

The delivery event list of this message.

expires_atTimestamp | null
Show properties
One of:
Timestamp
string<date-time>
null
null
fromAddressrequired

An address and its display name.

Show properties
emailstringrequired
namestring | null
holdsHoldObject[]required

One per held recipient: at most the 150 addresses of the envelope.

max items 150
Show properties
Array of HoldObject
emailstringrequired
observed_atTimestamprequired
reasonstringrequired

mailbox_full, greylisted, no_route or invalid_recipient (a reported invalid address waiting for a person's review). New values may be added.

resolutionstring | null

delivered, expired, suppressed or manual. New values may be added.

resolved_atTimestamp | null
Show properties
One of:
Timestamp
string<date-time>
null
null
review_afterTimestamprequired

When the hold is checked again.

idId_Messagerequired
matches ^msg_[0-9a-f]{32}$
in_reply_tostring | null

The Message-ID it answers.

internet_message_idstringrequired

The Message-ID header.

kindstringrequired

campaign, direct, reply or transactional. New values may be added.

person_idId_Person | null
Show properties
One of:
Id_Person
string
null
null
reply_tostring | null
send_atTimestamprequired

When it is due.

sender_identity_idId_SenderIdentityrequired
matches ^sid_[0-9a-f]{32}$
sent_atTimestamp | null
Show properties
One of:
Timestamp
string<date-time>
null
null
snippets_fallbackstring | null

For a campaign step message whose step asks for personalisation snippets that were not written: why (deadline, over_budget, provider, refused, off, …); its template's defaults were used instead. null otherwise. New values may be added.

statestringrequired

queued, claimed, in_flight, sent, failed, cancelled, uncertain or suppressed. New values may be added.

status_detailstring | null

Why it is in its state, when that needs words.

step_idId_Step | null
Show properties
One of:
Id_Step
string
null
null
subjectstringrequired

The subject as sent.

thread_idId_Thread | null
Show properties
One of:
Id_Thread
string
null
null
tostring[]required
trackingTrackingrequired

What a message tracks, frozen when it was created.

Show properties
clicksbooleanrequired

Its links lead through click links.

hostnamestring | null

The campaign's own tracking host, when it has one; the platform's otherwise.

opensbooleanrequired

An open pixel is added to its HTML.

updated_atTimestamprequired
variant_idId_Variant | null
Show properties
One of:
Id_Variant
string
null
null
400

No Idempotency-Key, or malformed JSON.

codestringrequired

The code from the closed registry; programs branch on it, never on the text. New codes may be added.

detailstringrequired

What went wrong, for a person; never an internal cause.

errorsFieldError[]

With validation_failed only: every invalid field.

Show properties
Array of FieldError
codestringrequired

What is wrong (required, range, length, format, invalid, …).

detailstringrequired

A safe, human-readable explanation.

pointerstringrequired

RFC 6901 pointer into the body, or ?name for a query parameter.

instancestringrequired

The request's path.

request_idstringrequired

The request's id, also in X-Request-Id: what support needs to find the request.

retry_afterinteger<int64> | null

With 429 and 503: the seconds to wait, as in Retry-After.

min 0
statusinteger<int32>required

The HTTP status.

min 0
titlestringrequired

Fixed per code.

typestringrequired

https://docs.norbelys.com/errors/<code>, a page that explains the code.

401

No valid credential.

codestringrequired

The code from the closed registry; programs branch on it, never on the text. New codes may be added.

detailstringrequired

What went wrong, for a person; never an internal cause.

errorsFieldError[]

With validation_failed only: every invalid field.

Show properties
Array of FieldError
codestringrequired

What is wrong (required, range, length, format, invalid, …).

detailstringrequired

A safe, human-readable explanation.

pointerstringrequired

RFC 6901 pointer into the body, or ?name for a query parameter.

instancestringrequired

The request's path.

request_idstringrequired

The request's id, also in X-Request-Id: what support needs to find the request.

retry_afterinteger<int64> | null

With 429 and 503: the seconds to wait, as in Retry-After.

min 0
statusinteger<int32>required

The HTTP status.

min 0
titlestringrequired

Fixed per code.

typestringrequired

https://docs.norbelys.com/errors/<code>, a page that explains the code.

403

The credential lacks messages:send.

codestringrequired

The code from the closed registry; programs branch on it, never on the text. New codes may be added.

detailstringrequired

What went wrong, for a person; never an internal cause.

errorsFieldError[]

With validation_failed only: every invalid field.

Show properties
Array of FieldError
codestringrequired

What is wrong (required, range, length, format, invalid, …).

detailstringrequired

A safe, human-readable explanation.

pointerstringrequired

RFC 6901 pointer into the body, or ?name for a query parameter.

instancestringrequired

The request's path.

request_idstringrequired

The request's id, also in X-Request-Id: what support needs to find the request.

retry_afterinteger<int64> | null

With 429 and 503: the seconds to wait, as in Retry-After.

min 0
statusinteger<int32>required

The HTTP status.

min 0
titlestringrequired

Fixed per code.

typestringrequired

https://docs.norbelys.com/errors/<code>, a page that explains the code.

404

No such message in this workspace.

codestringrequired

The code from the closed registry; programs branch on it, never on the text. New codes may be added.

detailstringrequired

What went wrong, for a person; never an internal cause.

errorsFieldError[]

With validation_failed only: every invalid field.

Show properties
Array of FieldError
codestringrequired

What is wrong (required, range, length, format, invalid, …).

detailstringrequired

A safe, human-readable explanation.

pointerstringrequired

RFC 6901 pointer into the body, or ?name for a query parameter.

instancestringrequired

The request's path.

request_idstringrequired

The request's id, also in X-Request-Id: what support needs to find the request.

retry_afterinteger<int64> | null

With 429 and 503: the seconds to wait, as in Retry-After.

min 0
statusinteger<int32>required

The HTTP status.

min 0
titlestringrequired

Fixed per code.

typestringrequired

https://docs.norbelys.com/errors/<code>, a page that explains the code.

422

The body is invalid (validation_failed).

codestringrequired

The code from the closed registry; programs branch on it, never on the text. New codes may be added.

detailstringrequired

What went wrong, for a person; never an internal cause.

errorsFieldError[]

With validation_failed only: every invalid field.

Show properties
Array of FieldError
codestringrequired

What is wrong (required, range, length, format, invalid, …).

detailstringrequired

A safe, human-readable explanation.

pointerstringrequired

RFC 6901 pointer into the body, or ?name for a query parameter.

instancestringrequired

The request's path.

request_idstringrequired

The request's id, also in X-Request-Id: what support needs to find the request.

retry_afterinteger<int64> | null

With 429 and 503: the seconds to wait, as in Retry-After.

min 0
statusinteger<int32>required

The HTTP status.

min 0
titlestringrequired

Fixed per code.

typestringrequired

https://docs.norbelys.com/errors/<code>, a page that explains the code.

Try it
Server
Authorization
Parameters
Bodyapplication/json
Request
curl -X POST 'https://api.norbelys.com/v1/messages/msg_0190f8a2b4c87a10b6d2e4f6a8c0e2f4/release_holds' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Idempotency-Key: string' \
  -H 'Content-Type: application/json' \
  -d '{
  "evidence": "The recipient confirmed by phone that their mailbox has room again."
}'
Response
{
  "attempts": {
    "data": [
      {
        "category": "string",
        "claimed_at": "2019-08-24T14:15:22Z",
        "connection_id": "con_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
        "diagnostic": "string",
        "enhanced_status": "string",
        "finished_at": "2019-08-24T14:15:22Z",
        "id": "att_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
        "number": 0,
        "outcome": "string",
        "phase": "string",
        "provider_message_id": "string",
        "recipient_count": 0,
        "smtp_code": 0,
        "started_at": "2019-08-24T14:15:22Z"
      }
    ],
    "has_more": true
  },
  "attempts_count": 0,
  "bcc": [
    "string"
  ],
  "campaign_id": "cmp_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "cc": [
    "string"
  ],
  "connection_id": "con_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "created_at": "2019-08-24T14:15:22Z",
  "enrollment_id": "enr_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "events": {
    "data": [
      {
        "action": "string",
        "attempt_number": 0,
        "category": "string",
        "confidence": "string",
        "diagnostic": "string",
        "enhanced_status": "string",
        "id": "dev_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
        "kind": "string",
        "message_id": "msg_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
        "observed_at": "2019-08-24T14:15:22Z",
        "phase": "string",
        "processed_at": "2019-08-24T14:15:22Z",
        "received_at": "2019-08-24T14:15:22Z",
        "recipient": "string",
        "recipient_ref": "string",
        "source": "string",
        "thread_id": "thr_0190f8a2b4c87a10b6d2e4f6a8c0e2f4"
      }
    ],
    "has_more": true,
    "url": "string"
  },
  "expires_at": "2019-08-24T14:15:22Z",
  "from": {
    "email": "string",
    "name": "string"
  },
  "holds": [
    {
      "email": "string",
      "observed_at": "2019-08-24T14:15:22Z",
      "reason": "string",
      "resolution": "string",
      "resolved_at": "2019-08-24T14:15:22Z",
      "review_after": "2019-08-24T14:15:22Z"
    }
  ],
  "id": "msg_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "in_reply_to": "string",
  "internet_message_id": "string",
  "kind": "string",
  "person_id": "per_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "reply_to": "string",
  "send_at": "2019-08-24T14:15:22Z",
  "sender_identity_id": "sid_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "sent_at": "2019-08-24T14:15:22Z",
  "snippets_fallback": "string",
  "state": "string",
  "status_detail": "string",
  "step_id": "stp_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "subject": "string",
  "thread_id": "thr_0190f8a2b4c87a10b6d2e4f6a8c0e2f4",
  "to": [
    "string"
  ],
  "tracking": {
    "clicks": true,
    "hostname": "string",
    "opens": true
  },
  "updated_at": "2019-08-24T14:15:22Z",
  "variant_id": "var_0190f8a2b4c87a10b6d2e4f6a8c0e2f4"
}