SendlySendly
API ReferenceMailboxes

Reply to a conversation

POST
/api/mailboxes/{id}/conversations/{conversationId}/reply

Answer the person who last wrote in, from the mailbox's own address, inside the same thread.

You cannot name the recipient or the sender. The recipient is the sender of the latest inbound message and the sender is the mailbox in the path. This is not sendMailboxMessage: that starts a new conversation with an address you name, under mailboxes:send; this one only ever answers someone who wrote first, under a separate scope, so holding one never implies the other.

Supply either a plain-text body or a structured React Email document. Sendly renders HTML and a matching plain-text alternative.

Refusals worth handling by name:

  • 422 UNPROCESSABLE — the thread has no inbound message to answer, or the mailbox is not provisioned.
  • 422 SEND_REFUSED — the recipient is suppressed or the project may not send.
  • 429 SENDING_LIMIT_REACHED — the project's sending limit.
  • 502 JMAP_SUBMISSION_FAILED — the mail server refused the submission. Nothing was sent.
  • 409 SEND_NOT_RECORDED — the reply WAS sent; Sendly could not write its record at that moment (error.details.submitted is true). Do not send it again.

A reply cannot be recalled once sent.

No existing API key can call this. The scope is opt-in only: a key or an OAuth connection holds it only if it was ticked by name when the credential was created or approved — the legacy full-access key and the "Full access" preset do not carry it.

Requires the mailbox-conversations:reply scope — Reply to conversations in your hosted mailboxes, from the mailbox's own address.

Authorization

AuthorizationBearer <token>

API key authentication. Use a sk_* (FULL) or pk_* (SENDING_ONLY) key as the bearer token. Public keys (pk_*) are restricted to the email-send endpoints and the self-serve list subscribe/unsubscribe pair; every other endpoint — event tracking included — answers 403 for them. In scope terms (used by /api/v1/* operations): FULL keys hold every scope; SENDING_ONLY keys hold only emails:send.

In: header

Path Parameters

id*string
conversationId*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/mailboxes/497f6eca-6276-4993-bfeb-53cbbbba6f08/conversations/497f6eca-6276-4993-bfeb-53cbbbba6f08/reply" \  -H "Content-Type: application/json" \  -d '{}'
{
  "success": true,
  "data": {
    "submitted": true,
    "status": "queued"
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}
{
  "success": false,
  "error": {
    "message": "string",
    "code": "string",
    "details": {
      "errors": [
        null
      ]
    }
  }
}