Skip to content

Errors

5 min read

Every Kirisan API response is JSON. Successful calls include "status": true. Failures include "status": false and a human-readable "reason" when the whole request failed before channel delivery.

HTTP status codes

StatusWhen it happens
200Request parsed — check "status" in the body (send may return 200 with "status": false and channel details)
400Invalid JSON, missing fields, or validation error
401Missing or invalid Bearer token
403Bearer token valid but a channel key does not belong to your account
503Service temporarily unavailable

POST /v1/send usually returns HTTP 200 even when delivery fails — read "status" and "channels".

Top-level reason

These appear on the response root when the request never reached delivery, or when every channel failed in a blocking way:

Reason (examples)Meaning
missing api token / invalid api tokenFix Authorization: Bearer … — see Authentication
invalid JSONBody is not valid JSON
No channels configuredkeys is empty — include at least one channel token
content requiredNo content object with at least one channel
no sendable channels: content requires a matching keyYou set content.whatsapp but omitted keys.whatsapp, or similar
Invalid schedule: the time is in the past.context.timing.schedule must be a future Unix timestamp
whatsapp key does not belong to this accountChannel token belongs to another user (403)

Validation errors from message bodies are also returned as top-level "reason" before send — for example email inline message requires subject or waba message type must be text, interactive, image, video, or document.

Per-channel errors (channels)

On POST /v1/send, each channel you attempted has its own object under "channels":

{
  "status": false,
  "channels": {
    "whatsapp": {
      "status": false,
      "reason": "template is not approved for sending",
      "processing_time": "142ms"
    },
    "email": {
      "status": true,
      "processing_time": "891ms"
    }
  }
}
FieldMeaning
statustrue if that channel delivered (or was scheduled)
reasonPresent when status is false — quota, missing target, template inactive, provider error, etc. For email, SMTP and transport errors are summarized into short readable sentences (for example Recipient address does not exist). Raw provider text is kept in internal logs only. Unrecognized email failures return Email could not be delivered. Quota messages such as insufficient quota and paid plan expired are returned unchanged.
detailExtra provider payload on some channels (WhatsApp, Telegram, WABA)
processing_timeHow long the provider call took
scheduledtrue when the message was queued for context.timing.schedule
fallbacktrue when this channel sent as part of a fallback tier

When one channel fails and another succeeds (for example WhatsApp fails, email fallback succeeds), top-level "status" may still be true if any channel delivered.

Template errors on send

When content.<channel>.template points to a dashboard template that cannot send:

ReasonMeaning
template is not approved for sendingTemplate is still pending review or was rejected
template is inactiveTemplate exists but is turned off in the dashboard
WhatsApp template not foundWrong ID, wrong channel, or template belongs to another account

Create templates under Channel → channel → Templates and confirm they are Approved and Active before referencing their ID on send.

Email errors

These reasons appear on "channels.email.reason" (or on the root if email was the only channel that failed):

ReasonMeaningWhat to do
rate_limitedYou sent more than 2 requests per second of marketing or no-template email on the same domain. The response may include retry_after (seconds).Wait, then send again. Transactional templates do not use this cap.
queue_fullToo many marketing or no-template emails are still waiting for this domain.Wait until some send, then try again.
email_lane_blockedThat kind of email (transactional, marketing, or raw) is blocked on the domain.Open Channel → Email → Domains, read the label under Sending health, then Acknowledge.
email_domain_suspendedDomain health paused that kind of email.Open Channel → Email → Domains. The badge may show Suspended until …. Wait or acknowledge as shown.
not_in_email_poolA marketing template to an address that has not received email from this domain yet.Send a transactional or no-template email to that address first, or use an address you have already emailed.
email inline message requires subjectA no-template message is missing subject.Add subject.
email inline message requires message or htmlA no-template message has no body.Add message and/or html.
email inline message type must be textmessage.type is not text.Set type to "text".

SMTP delivery failures

When the email service rejects delivery to Gmail, Outlook, or Yahoo, channels.email.reason uses a stable code (not raw SMTP text). Full SMTP diagnostics remain in Kirisan logs (admin).

ReasonMeaningWhat to do
recipient_not_foundRecipient address does not exist or is invalid (hard bounce).Remove or fix the address; it is permanently suppressed.
recipient_temp_unavailableMailbox full or recipient temporarily unavailable (soft bounce).Retry later; address is suppressed for 24h (3× → permanent).
delivery_temporarily_unavailableTemporary deferral (greylist, busy server, timeout).Response may include retryable: true. Retry later.
rate_limited_by_providerProvider throttled the sender (IP/domain/reputation), not the recipient address.Slow down volume; fix auth/warmup. Do not remove the address from your list.
blocked_by_providerIP/domain on a provider block list (e.g. Outlook S3150).Fix reputation; request delisting if needed. Recipient address stays valid.
policy_rejectedAuth/policy failure (SPF, DMARC, content, Outlook SC-/DY-/OU-).Fix DNS auth or message content.
message_rejectedMessage size, format, or syntax rejected.Reduce attachments or fix format.

rate_limited (2 requests/second per domain) is separate from rate_limited_by_provider (Gmail/Outlook/Yahoo sender limits).

See the Send API for the three kinds of email, and Sending messages if a send is rejected or stuck.