Skip to main content
WEBHOOK
MessageHeld
{
  "message": {
    "id": 12350,
    "token": "hIj456KlM789",
    "direction": "outgoing",
    "message_id": "b4c5d6e7-f8a9-0123@rp.arkhq.io",
    "to": "user@example.com",
    "from": "hello@yourdomain.com",
    "subject": "Welcome to our service",
    "timestamp": 1704671990.345678,
    "spam_status": "Spam",
    "tag": "onboarding",
    "metadata": null
  },
  "status": "Held",
  "details": "Message held due to high spam score",
  "output": "",
  "sent_with_ssl": false,
  "timestamp": 1704672000.345678,
  "time": 0
}

Authorizations

Authorization
string
header
required

Use your API key from arkhq.io/org/credentials

Authorization: Bearer YOUR_API_KEY

Body

application/json

Webhook event payload sent to your configured endpoint.

The payload structure varies by event type:

  • Delivery events (MessageSent, MessageDelayed, MessageDeliveryFailed, MessageHeld): Include message, status, details, output, sent_with_ssl, timestamp, time
  • MessageBounced: Includes original_message and bounce (both are message objects)
  • Engagement events (MessageLoaded, MessageLinkClicked): Include message, ip_address, user_agent
  • DomainDNSError: Includes server, domain, uuid, dns_checked_at, and DNS status fields
  • SendLimit events: Include server, volume, limit

Bounce Classification: For MessageDelayed and MessageDeliveryFailed events, additional classification fields are included to help you understand why delivery failed:

  • classification - Category like invalid_recipient, mailbox_full, spam_block
  • classification_code - Numeric code (10-49, 99) for grouping related classifications
  • smtp_enhanced_code - RFC 3463 enhanced status code (e.g., "5.1.1")
  • remote_host - Hostname of the server that returned the error

Note: The event type is determined by which webhook events you subscribe to, not by a field in the payload. Use the status field to identify delivery event types: Sent, SoftFail, HardFail, Held.

message
object

Email message information included in webhook payloads

original_message
object

The original message that bounced (for MessageBounced events)

bounce
object

The bounce notification message (for MessageBounced events)

status
enum<string>

Delivery status. Values correspond to event types:

  • Sent (MessageSent)
  • SoftFail (MessageDelayed)
  • HardFail (MessageDeliveryFailed)
  • Held (MessageHeld)
Available options:
Sent,
SoftFail,
HardFail,
Held
Example:

"Sent"

details
string

Human-readable summary of the delivery attempt. Format varies by status:

  • Sent: Message for {recipient} accepted by {ip}:{port} ({hostname})
  • SoftFail/HardFail: {code} {classification}: Delivery to {recipient} failed at {ip}:{port} ({hostname})
  • Connection errors: Connection error: Could not connect to any mail server for {domain}
Example:

"Message for user@example.com accepted by 1.2.3.4:25 (mx.example.com)"

output
string

Raw SMTP response from the receiving server. Contains the full error message for failures.

Example:

"250 2.0.0 OK"

sent_with_ssl
boolean

Whether the message was delivered over a TLS connection

Example:

true

time
number<float>

Time taken to deliver in seconds

Example:

1.51

timestamp
number<float>

Unix timestamp of the delivery attempt (with microsecond precision)

Example:

1704672000.123456

classification
enum<string>

Bounce classification category explaining why delivery failed. Only present for MessageDelayed and MessageDeliveryFailed events.

Recipient Issues (10-19):

  • invalid_recipient - Mailbox doesn't exist (5.1.1)
  • inactive_mailbox - Account disabled or suspended
  • mailbox_full - Over quota (5.2.2)

Domain Issues (20-29):

  • invalid_domain - Domain doesn't exist
  • dns_failure - Temporary DNS resolution failure
  • routing_error - Relay denied or routing problems

Reputation/Policy (30-39):

  • spam_block - IP or domain blocklisted
  • spam_content - Content flagged as spam
  • policy_rejection - Rejected by policy (DMARC, etc.)

Technical (40-49):

  • connection_error - Connection timeout or refused
  • protocol_error - SMTP protocol issues
  • transient_failure - General temporary failure

Other:

  • unclassified - Could not classify the bounce
Available options:
invalid_recipient,
inactive_mailbox,
mailbox_full,
invalid_domain,
dns_failure,
routing_error,
spam_block,
spam_content,
policy_rejection,
connection_error,
protocol_error,
transient_failure,
unclassified
Example:

"invalid_recipient"

classification_code
enum<integer>

Numeric code for the bounce classification. Useful for grouping related classifications:

  • 10-19: Recipient issues
  • 20-29: Domain issues
  • 30-39: Reputation/policy issues
  • 40-49: Technical issues
  • 99: Unclassified

Only present when classification is present.

Available options:
10,
11,
12,
20,
21,
22,
30,
31,
32,
40,
41,
42,
99
Example:

10

smtp_enhanced_code
string | null

RFC 3463 enhanced SMTP status code from the receiving server (e.g., "5.1.1", "4.2.2"). Provides standardized bounce reason codes. Only present for delivery failures where the remote server provided an enhanced code.

Pattern: ^[245]\.[0-9]+\.[0-9]+$
Example:

"5.1.1"

remote_host
string | null

Hostname of the remote SMTP server that returned the error. Only present for delivery failures.

Example:

"mx1.gmail.com"

url
string

The URL that was clicked (for MessageLinkClicked events)

Example:

"https://yourdomain.com/welcome"

token
string

Unique token for the clicked link (for MessageLinkClicked events)

Example:

"abc123def456"

ip_address
string

IP address of the recipient (for MessageLoaded and MessageLinkClicked events)

Example:

"203.0.113.45"

user_agent
string

User agent of the recipient's email client (for MessageLoaded and MessageLinkClicked events)

Example:

"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"

server
object

Server information (for DomainDNSError and SendLimit events)

domain
string

Domain name with DNS issues (for DomainDNSError events)

Example:

"yourdomain.com"

uuid
string

Unique identifier for the domain (for DomainDNSError events)

Example:

"a1b2c3d4-e5f6-7890"

dns_checked_at
number<float>

Unix timestamp when DNS was checked (for DomainDNSError events)

Example:

1704672000.123456

spf_status
enum<string>

SPF record status (for DomainDNSError events)

Available options:
OK,
Missing,
Invalid
Example:

"Missing"

spf_error
string | null

SPF error message if status is not OK

Example:

"No SPF record exists for this domain"

dkim_status
enum<string>

DKIM record status (for DomainDNSError events)

Available options:
OK,
Missing,
Invalid
Example:

"OK"

dkim_error
string | null

DKIM error message if status is not OK

mx_status
enum<string>

MX record status (for DomainDNSError events)

Available options:
OK,
Missing,
Invalid
Example:

"OK"

mx_error
string | null

MX error message if status is not OK

return_path_status
enum<string>

Return path record status (for DomainDNSError events)

Available options:
OK,
Missing,
Invalid
Example:

"Missing"

return_path_error
string | null

Return path error message if status is not OK

Example:

"There is no return path record at rp.yourdomain.com"

volume
integer

Current send volume in the last hour (for SendLimit events)

Example:

950

limit
integer

Configured send limit per hour (for SendLimit events)

Example:

1000

Response

200

Webhook received successfully