API REFERENCE v1

RETENTION

Messages

The Message object

Emails NoChurn sends: the review queue, customers' replies and addresses never emailed again.

ATTRIBUTES

Show 21 more attributesHide 21 attributes

Schema: MessageDetail

THE MESSAGE OBJECT
{
  "object": "message",
  "id": "msg_jybJppHfErmGqPeU",
  "livemode": false,
  "channel": "email",
  "customer": {
    "id": "cst_a48iMM4Qwrzhi2DD",
    "name": "Lena",
    "email": "lena@globex.io"
  },
  "flow_run": null,
  "template_key": null,
  "locale": null,
  "from": "acme@mail.nochurn.sh",
  "from_name": "Acme",
  "reply_to": "reply@mail.nochurn.sh",
  "to": "lena@globex.io",
  "subject": "Pay now",
  "ai_generated": false,
  "review_state": "approved",
  "review_issues": ["Contains a number"],
  "reviewed_at": "2026-11-04T10:00:00Z",
  "status": "queued",
  "scheduled_for": "2026-11-04T10:00:00Z",
  "schedule_reasons": [],
  "sent_at": null,
  "delivered_at": null,
  "opened_at": null,
  "clicked_at": null,
  "bounced_at": null,
  "error": null,
  "created_at": "2026-11-04T10:00:00Z",
  "body_text": "Pay within 3 days",
  "body_html": null
}

One email, with its body

  • Secret key (nc_test_… or nc_live_…). Restricted keys need read access.
  • AI apps (OAuth): read scope.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

GET/v1/messages/{id}
curl https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW", {
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const message = await res.json();
import requests

res = requests.get(
    "https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
message = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message = JSON.parse(res.body)
RESPONSE 200
{
  "object": "message",
  "id": "msg_MVTSkdbxaUw5QLdW",
  "livemode": false,
  "channel": "email",
  "customer": {
    "id": "cst_ELRfdh1vS6cs1nLT",
    "name": null,
    "email": "lena@globex.io"
  },
  "flow_run": null,
  "template_key": null,
  "locale": null,
  "from": "acme@mail.nochurn.sh",
  "from_name": "Acme",
  "reply_to": "reply@mail.nochurn.sh",
  "to": "lena@globex.io",
  "subject": "Your payment failed",
  "ai_generated": false,
  "review_state": "auto_approved",
  "review_issues": [],
  "reviewed_at": null,
  "status": "queued",
  "scheduled_for": "2026-11-04T10:00:00Z",
  "schedule_reasons": [],
  "sent_at": null,
  "delivered_at": null,
  "opened_at": null,
  "clicked_at": null,
  "bounced_at": null,
  "error": null,
  "created_at": "2026-11-04T10:00:00Z",
  "body_text": "Hi",
  "body_html": null
}

Edit an email waiting for review

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

BODY PARAMETERS

RETURNS

PATCH/v1/messages/{id}
curl https://api.nochurn.sh/v1/messages/msg_RdxeWUzh1bU5G13D \
  -X PATCH \
  -H "Authorization: Bearer nc_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "body_text": "Please update your card when you can."
  }'
const res = await fetch("https://api.nochurn.sh/v1/messages/msg_RdxeWUzh1bU5G13D", {
  method: "PATCH",
  headers: {
    Authorization: "Bearer nc_test_…",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "body_text": "Please update your card when you can."
  }),
});
const message = await res.json();
import requests

res = requests.patch(
    "https://api.nochurn.sh/v1/messages/msg_RdxeWUzh1bU5G13D",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
    json={
      "body_text": "Please update your card when you can."
    },
)
message = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/messages/msg_RdxeWUzh1bU5G13D")
req = Net::HTTP::Patch.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
  "body_text" => "Please update your card when you can."
}.to_json

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message = JSON.parse(res.body)
RESPONSE 200
{
  "object": "message",
  "id": "msg_RdxeWUzh1bU5G13D",
  "livemode": false,
  "channel": "email",
  "customer": {
    "id": "cst_HP9WD9AFqWFQAYcW",
    "name": "Lena",
    "email": "lena@globex.io"
  },
  "flow_run": null,
  "template_key": null,
  "locale": null,
  "from": "acme@mail.nochurn.sh",
  "from_name": "Acme",
  "reply_to": "reply@mail.nochurn.sh",
  "to": "lena@globex.io",
  "subject": "Pay now",
  "ai_generated": false,
  "review_state": "needs_review",
  "review_issues": ["Contains a number"],
  "reviewed_at": null,
  "status": "queued",
  "scheduled_for": "2026-11-04T10:00:00Z",
  "schedule_reasons": [],
  "sent_at": null,
  "delivered_at": null,
  "opened_at": null,
  "clicked_at": null,
  "bounced_at": null,
  "error": null,
  "created_at": "2026-11-04T10:00:00Z",
  "body_text": "Please update your card when you can.",
  "body_html": "<p>Please update your card when you can.</p>"
}

List emails sent or queued

  • Secret key (nc_test_… or nc_live_…). Restricted keys need read access.
  • AI apps (OAuth): read scope.

QUERY PARAMETERS

RETURNS

GET/v1/messages
curl https://api.nochurn.sh/v1/messages \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/messages", {
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const page = await res.json();
import requests

res = requests.get(
    "https://api.nochurn.sh/v1/messages",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
page = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/messages")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
page = JSON.parse(res.body)
RESPONSE 200
{
  "object": "list",
  "data": [
    {
      "object": "message",
      "id": "msg_7mAdYE7eDfM14gmf",
      "livemode": false,
      "channel": "email",
      "customer": {
        "id": "cst_6VxAaGbvxB6kQ3DU",
        "name": null,
        "email": "lena@globex.io"
      },
      "flow_run": null,
      "template_key": null,
      "locale": null,
      "from": "acme@mail.nochurn.sh",
      "from_name": "Acme",
      "reply_to": "reply@mail.nochurn.sh",
      "to": "lena@globex.io",
      "subject": "Your payment failed",
      "ai_generated": false,
      "review_state": "auto_approved",
      "review_issues": [],
      "reviewed_at": null,
      "status": "queued",
      "scheduled_for": "2026-11-04T10:00:00Z",
      "schedule_reasons": [],
      "sent_at": null,
      "delivered_at": null,
      "opened_at": null,
      "clicked_at": null,
      "bounced_at": null,
      "error": null,
      "created_at": "2026-11-04T10:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

One reply

  • Secret key (nc_test_… or nc_live_…). Restricted keys need read access.
  • AI apps (OAuth): read scope.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

ERRORS

GET/v1/replies/{id}
curl https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq", {
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const messageReply = await res.json();
import requests

res = requests.get(
    "https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
message_reply = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message_reply = JSON.parse(res.body)
RESPONSE 200
{
  "object": "message_reply",
  "id": "rpl_QvzvaP4p8DDp6VTq",
  "message": "msg_EBNrBPU9L5SuTsjj",
  "customer": "cst_mz3wQqTbGGtZ36N6",
  "customer_email": "ana@example.test",
  "customer_name": null,
  "flow_run": null,
  "flow": null,
  "from": "ana@example.test",
  "subject": "Re: Hi",
  "text": "Thanks?",
  "category": "question",
  "summary": null,
  "needs_human": true,
  "status": "open",
  "handled_at": null,
  "answer_message": null,
  "received_at": "2026-11-04T10:00:00Z",
  "livemode": false
}

Approve an email waiting for review

It is sent at its slot in the customer's send window, or now if that slot has passed.

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

ERRORS

POST/v1/messages/{id}/approve
curl https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/approve \
  -X POST \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/approve", {
  method: "POST",
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const message = await res.json();
import requests

res = requests.post(
    "https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/approve",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
message = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/approve")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message = JSON.parse(res.body)
RESPONSE 200
{
  "object": "message",
  "id": "msg_jybJppHfErmGqPeU",
  "livemode": false,
  "channel": "email",
  "customer": {
    "id": "cst_a48iMM4Qwrzhi2DD",
    "name": "Lena",
    "email": "lena@globex.io"
  },
  "flow_run": null,
  "template_key": null,
  "locale": null,
  "from": "acme@mail.nochurn.sh",
  "from_name": "Acme",
  "reply_to": "reply@mail.nochurn.sh",
  "to": "lena@globex.io",
  "subject": "Pay now",
  "ai_generated": false,
  "review_state": "approved",
  "review_issues": ["Contains a number"],
  "reviewed_at": "2026-11-04T10:00:00Z",
  "status": "queued",
  "scheduled_for": "2026-11-04T10:00:00Z",
  "schedule_reasons": [],
  "sent_at": null,
  "delivered_at": null,
  "opened_at": null,
  "clicked_at": null,
  "bounced_at": null,
  "error": null,
  "created_at": "2026-11-04T10:00:00Z",
  "body_text": "Pay within 3 days",
  "body_html": null
}

Reject an email: it is never sent

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

POST/v1/messages/{id}/reject
curl https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reject \
  -X POST \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reject", {
  method: "POST",
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const message = await res.json();
import requests

res = requests.post(
    "https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reject",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
message = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reject")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message = JSON.parse(res.body)
RESPONSE 200
{
  "object": "message",
  "id": "msg_vQ671Sb9uijrVEbZ",
  "livemode": false,
  "channel": "email",
  "customer": {
    "id": "cst_Z3cG1aZVjNGdxEqx",
    "name": "Lena",
    "email": "lena@globex.io"
  },
  "flow_run": null,
  "template_key": null,
  "locale": null,
  "from": "acme@mail.nochurn.sh",
  "from_name": "Acme",
  "reply_to": "reply@mail.nochurn.sh",
  "to": "lena@globex.io",
  "subject": "Pay now",
  "ai_generated": false,
  "review_state": "rejected",
  "review_issues": ["Contains a number"],
  "reviewed_at": "2026-11-04T10:00:00Z",
  "status": "cancelled",
  "scheduled_for": "2026-11-04T10:00:00Z",
  "schedule_reasons": [],
  "sent_at": null,
  "delivered_at": null,
  "opened_at": null,
  "clicked_at": null,
  "bounced_at": null,
  "error": null,
  "created_at": "2026-11-04T10:00:00Z",
  "body_text": "Pay within 3 days",
  "body_html": null
}

Addresses never emailed again

  • Secret key (nc_test_… or nc_live_…). Restricted keys need read access.
  • AI apps (OAuth): read scope.

QUERY PARAMETERS

RETURNS

GET/v1/email_suppressions
curl https://api.nochurn.sh/v1/email_suppressions \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/email_suppressions", {
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const page = await res.json();
import requests

res = requests.get(
    "https://api.nochurn.sh/v1/email_suppressions",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
page = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/email_suppressions")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
page = JSON.parse(res.body)
RESPONSE 200
{
  "object": "list",
  "data": [
    {
      "object": "email_suppression",
      "id": "sup_ivHvxoZM6AmGv9EH",
      "livemode": false,
      "email": "x@y.com",
      "reason": "bounced",
      "scope": "all",
      "message": null,
      "created_at": "2026-11-04T10:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Never email this address again

Emails still queued to this address are cancelled.

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

BODY PARAMETERS

RETURNS

POST/v1/email_suppressions
curl https://api.nochurn.sh/v1/email_suppressions \
  -H "Authorization: Bearer nc_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "Lena@globex.io"
  }'
const res = await fetch("https://api.nochurn.sh/v1/email_suppressions", {
  method: "POST",
  headers: {
    Authorization: "Bearer nc_test_…",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "email": "Lena@globex.io"
  }),
});
const emailSuppression = await res.json();
import requests

res = requests.post(
    "https://api.nochurn.sh/v1/email_suppressions",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
    json={
      "email": "Lena@globex.io"
    },
)
email_suppression = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/email_suppressions")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
  "email" => "Lena@globex.io"
}.to_json

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
email_suppression = JSON.parse(res.body)
RESPONSE 201
{
  "object": "email_suppression",
  "id": "sup_TVZJJc1oa5NXcNFX",
  "livemode": false,
  "email": "lena@globex.io",
  "reason": "manual",
  "scope": "all",
  "message": null,
  "created_at": "2026-11-04T10:00:00Z"
}

Email this address again

Unsubscribes, spam complaints and GDPR erasures cannot be removed: only the customer can opt back in.

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

  • 204 removed

ERRORS

DELETE/v1/email_suppressions/{id}
curl https://api.nochurn.sh/v1/email_suppressions/sup_ivHvxoZM6AmGv9EH \
  -X DELETE \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/email_suppressions/sup_ivHvxoZM6AmGv9EH", {
  method: "DELETE",
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
console.log(res.status); // 204
import requests

res = requests.delete(
    "https://api.nochurn.sh/v1/email_suppressions/sup_ivHvxoZM6AmGv9EH",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
print(res.status_code)  # 204
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/email_suppressions/sup_ivHvxoZM6AmGv9EH")
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.code # 204
RESPONSE 204
// No content

Replies to NoChurn emails (To do)

Sorted by the AI (or keyword rules). text is the customer's: display it as text.

  • Secret key (nc_test_… or nc_live_…). Restricted keys need read access.
  • AI apps (OAuth): read scope.

QUERY PARAMETERS

  • status enum
    • open
    • handled
    • ignored
  • category enum
    • wants_to_return
    • question
    • not_interested
    • unsubscribe
    • out_of_office
    • other
  • customer string

RETURNS

GET/v1/replies
curl https://api.nochurn.sh/v1/replies \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/replies", {
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const page = await res.json();
import requests

res = requests.get(
    "https://api.nochurn.sh/v1/replies",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
page = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/replies")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
page = JSON.parse(res.body)
RESPONSE 200
{
  "object": "list",
  "data": [
    {
      "object": "message_reply",
      "id": "rpl_xW5HbqtzKvVVfCqt",
      "message": "msg_LS2QZwJVaaT8F3Ah",
      "customer": "cst_Fm54HKouWUM3Uyyq",
      "customer_email": "lena@globex.io",
      "customer_name": "Lena",
      "flow_run": null,
      "flow": null,
      "from": "lena@globex.io",
      "subject": "Re: We miss you",
      "text": "Do you have a cheaper plan?",
      "category": "question",
      "summary": null,
      "needs_human": true,
      "status": "open",
      "handled_at": null,
      "answer_message": null,
      "received_at": "2026-11-04T10:00:00Z",
      "livemode": false
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "open_count": 1
}

Ignore a reply

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

POST/v1/replies/{id}/ignore
curl https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/ignore \
  -X POST \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/ignore", {
  method: "POST",
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const messageReply = await res.json();
import requests

res = requests.post(
    "https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/ignore",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
message_reply = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/ignore")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message_reply = JSON.parse(res.body)
RESPONSE 200
{
  "object": "message_reply",
  "id": "rpl_5wxJp3DCg4vPhrHg",
  "message": "msg_vFR7ofzoUzQuc5aW",
  "customer": "cst_dEdhnVf8D1pgPcDU",
  "customer_email": "lena@globex.io",
  "customer_name": "Lena",
  "flow_run": null,
  "flow": null,
  "from": "lena@globex.io",
  "subject": "Re: We miss you",
  "text": "Do you have a cheaper plan?",
  "category": "question",
  "summary": null,
  "needs_human": true,
  "status": "ignored",
  "handled_at": "2026-11-04T10:00:00Z",
  "answer_message": null,
  "received_at": "2026-11-04T10:00:00Z",
  "livemode": false
}

Mark a reply handled

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

POST/v1/replies/{id}/handle
curl https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/handle \
  -X POST \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/handle", {
  method: "POST",
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const messageReply = await res.json();
import requests

res = requests.post(
    "https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/handle",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
message_reply = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/replies/rpl_QvzvaP4p8DDp6VTq/handle")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message_reply = JSON.parse(res.body)
RESPONSE 200
{
  "object": "message_reply",
  "id": "rpl_J7ZecZZmYhhFcKHF",
  "message": "msg_MwzQ5iciTQXVwc3Q",
  "customer": "cst_SyJ5a4KUH3XNYBMZ",
  "customer_email": "lena@globex.io",
  "customer_name": "Lena",
  "flow_run": null,
  "flow": null,
  "from": "lena@globex.io",
  "subject": "Re: We miss you",
  "text": "Do you have a cheaper plan?",
  "category": "question",
  "summary": null,
  "needs_human": true,
  "status": "handled",
  "handled_at": "2026-11-04T10:00:00Z",
  "answer_message": null,
  "received_at": "2026-11-04T10:00:00Z",
  "livemode": false
}

Answer the customer

Sent now (it answers the customer: no send window), from the same sender, "Re:" the original subject. The open replies to this email are marked handled.

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

BODY PARAMETERS

  • text string REQUIRED

RETURNS

ERRORS

POST/v1/messages/{id}/reply
curl https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reply \
  -H "Authorization: Bearer nc_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Yes: the Starter plan is 19 €/month."
  }'
const res = await fetch("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reply", {
  method: "POST",
  headers: {
    Authorization: "Bearer nc_test_…",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "text": "Yes: the Starter plan is 19 €/month."
  }),
});
const message = await res.json();
import requests

res = requests.post(
    "https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reply",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
    json={
      "text": "Yes: the Starter plan is 19 €/month."
    },
)
message = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/messages/msg_MVTSkdbxaUw5QLdW/reply")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
  "text" => "Yes: the Starter plan is 19 €/month."
}.to_json

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
message = JSON.parse(res.body)
RESPONSE 201
{
  "object": "message",
  "id": "msg_kevJoAGQTaFsNwmx",
  "livemode": false,
  "channel": "email",
  "customer": {
    "id": "cst_dsRbczhJGFgyjPTc",
    "name": "Lena",
    "email": "lena@globex.io"
  },
  "flow_run": null,
  "template_key": "reply.human",
  "locale": null,
  "from": "account1@mail.nochurn.sh",
  "from_name": "Account 1",
  "reply_to": "reply@mail.nochurn.sh",
  "to": "lena@globex.io",
  "subject": "Re: We miss you",
  "ai_generated": false,
  "review_state": "auto_approved",
  "review_issues": [],
  "reviewed_at": null,
  "status": "queued",
  "scheduled_for": "2026-11-04T10:00:00Z",
  "schedule_reasons": [],
  "sent_at": null,
  "delivered_at": null,
  "opened_at": null,
  "clicked_at": null,
  "bounced_at": null,
  "error": null,
  "created_at": "2026-11-04T10:00:00Z",
  "body_text": "Yes: the Starter plan is 19 €/month.",
  "body_html": null
}