https://inkbox.ai/api/v1/whatsapp. Supply the selected agent_identity_id as a query parameter when needed by your credential.
Send a message
to for a direct message or an existing direct-message or group conversation_id, never both. The channel must have approved access and be ready. A new request returns 201 with a message object after acceptance; delivery happens asynchronously. A ready channel can still reject a quoted reply, reaction, group send, or gif_playback send with 409 whatsapp_capability_not_ready when that operation is unavailable. That rejection admits nothing; ordinary direct messages can remain available. Do not replace a rejected quote with an unquoted send.
All arrays, including singleton arrays, and comma-separated lists are rejected for
to. There is no fanout. A group conversation_id must identify an authorized existing group where the agent has received a message from another participant. No group creation or sending by group name is supported. Unknown request fields are rejected. WhatsApp has no send-style or partial-message reaction fields.
Group sends without the required incoming message return 409 whatsapp_group_reply_required. Group sends can also return 409 whatsapp_capability_not_ready when unavailable. Neither rejection admits a message; keep the same request and idempotency key when retrying after the prerequisite is met.
Use an authorized reply_to_message_id for a native quoted reply. If the quote is unavailable, the API rejects the request instead of silently sending an unquoted message.
In a direct conversation, before that recipient’s first WhatsApp reply, the initial policy permits up to three opening messages of at most 159 Unicode code points each. Links, phone numbers, media, and email addresses are not allowed by default. The server checks the current opening-message policy on every send and returns 422 when it rejects the draft.
to with conversation_id in raw requests, conversation_id in Python, or conversationId in TypeScript. The CLI accepts --conversation-id instead of --to.
Retry without duplicating
Use oneIdempotency-Key for each intended message and keep the same input on retry. Also send Prefer: idempotency-replay in raw requests; SDKs do this automatically. A replay returns the original accepted response, not the newest delivery state.
If you lose the response, use message-send lookup with sender_kind=whatsapp_identity, the agent’s UUID as sender_id, and operation=whatsapp.send. Lookup is read-only. A missing result is not permission to create a new key. Retain any media ID instead of uploading the file again.
Get a message
status_observed_at and status_refresh_pending; a pending refresh does not mean the latest remote state is already known.
An inaccessible or unknown message returns 404. A disabled channel does not transfer history to a different owner.
CLI
List messages
Returns a bare array, newest first, with a stable message-ID tie-break. Keep the same filters when advancing the offset. Message lists show stored state; they do not refresh every message’s delivery status.
CLI
Message object
Each recipient object has
remote_number, delivery_status, delivery_state, nullable error_code and error_detail, and nullable sent_at, delivered_at, and failed_at timestamps. Required response keys remain present when null. Arrays remain arrays, including when empty.
Send and delivery are separate
status: "sent" with delivery_state: "unknown" is not a failed send. Missing delivery confirmation does not justify automatic resend. A later delivery event can provide new evidence.
Date filters
Both message and conversation lists acceptstart_datetime, end_datetime, and tz. Bounds filter created_at; start and end instants are inclusive. A bare end date includes the entire calendar day. Zone-less values use the supplied IANA timezone, or UTC by default. Explicit-offset timestamps retain their own timezone. Filtering happens before pagination.
Quoted-reply fallback policy
plain_reply_fallback accepts only a boolean and defaults to true. It permits an
ordinary reply only when the selected target is known before sending not to
support a native quote. All currently supported WhatsApp message targets support
native quotes, so the current service does not use a plain fallback. This option
does not turn a missing, inaccessible, unsettled, or unavailable quote target into
an ordinary send. A rejected or uncertain quoted send is never retried as plain.
Use false to require native quoting explicitly; keep the original request and
idempotency key after uncertainty.
SDK spellings are plain_reply_fallback (Python/Rust) and plainReplyFallback
(TypeScript). The CLI option is --no-plain-reply-fallback.
