---
title: "Send message"
method: POST
path: "/v1/inbox/conversations/{conversationId}/messages"
tags: ["Messages"]
---

# Send message

`POST /v1/inbox/conversations/{conversationId}/messages`

Send a message in a conversation. Supports text, attachments, quick replies,
buttons, templates, and message tags. Attachment and interactive message
support varies by platform.

WhatsApp per-recipient rate limit: WhatsApp caps how many messages you may
send to the same recipient in a short window and rejects the excess with
error code `131056` ("Too many messages sent to this recipient"). Pace
sends to a single recipient at roughly 10 per minute; bursts above that
return a `400` with code `131056`. Sends to other recipients are
unaffected, so parallelise across recipients rather than flooding one.

WhatsApp template messages: to send an approved template into this
conversation (required when the 24-hour customer-service window is
closed), use the `template` field with a single element carrying the
template reference: `{ "elements": [{ "name": ..., "language": ..., "components": [...] }] }`.
See the `template` field below for the exact shape. To send a template
to a phone number you have no conversation with yet, use the
create-conversation endpoint (POST /v1/inbox/conversations) instead.

Zernio resolves the exact APPROVED template name and language before any
WhatsApp template send. A failed lookup or missing exact definition sends
no message and returns code `platform_api_error`, type `platform_error`,
and platform `whatsapp`. Sanitized Meta code, message, and
`error_data.details` are returned in `platformError`; `details` identifies
`phase: template_lookup`, the query-free endpoint, upstream status, and
only safe provider usage or retry headers.

WhatsApp rich interactive messages (list, CTA URL, Flow, location request)
are available via the `interactive` field. Tap events are delivered through
the `message.received` webhook with WhatsApp-specific `metadata` fields
(`interactiveType`, `interactiveId`, `flowResponseJson`, `flowResponseData`).

**Idempotency:** send an `Idempotency-Key` header to make retries safe
(e.g. after a client-side timeout where delivery is unknown): same key +
same body replays the original response (with `Idempotent-Replayed: true`)
instead of sending the message a second time; same key + different body
returns 422; a key still in flight returns 409. Works for JSON and
multipart (file upload) requests alike. Keys are retained for 24 hours.

Only successful (2xx) responses are stored for replay: if the request
throws or returns a non-2xx status, the key is released so the same key
can be retried once the problem is fixed. The header therefore protects
the "request succeeded but the response was lost" case. For an ambiguous
failure (a 5xx or a network timeout), reconcile before retrying: a
failure after the platform already accepted the message also releases
the key, and a blind retry could send it twice. List the conversation's
messages first, and treat an empty result as inconclusive rather than
as proof nothing was sent, since a send that failed while being recorded
leaves no trace on our side.

## Path parameters

- `conversationId` string, required

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `accountId` string, required — Account ID
  - `message` string — Message text
  - `attachmentUrl` string — URL of the attachment to send (image, video, audio, or file). The URL must be publicly accessible. For binary file uploads, use multipart/form-data instead. On WhatsApp, combining an image, video, or file with `buttons` renders the media as the header of one interactive reply-button message; audio cannot be combined with buttons.
  - `category` 'utility' — WhatsApp only (Meta Direct Send). Sends this message as a business-initiated UTILITY message without an approved template, for example outside the 24-hour customer service window; Meta matches or auto-creates a template asynchronously. The WhatsApp Business Account must be eligible for Direct Send, otherwise the send fails with an error telling you to use an approved message template instead. Supported only for text messages (link preview ok) and interactive messages (reply buttons, CTA URL buttons, voice-call button, header of text/image/video/document). Cannot be combined with template, attachments, location, or contacts. Utility messages only; marketing content is not allowed under this category. Accepted on the JSON body only, not on multipart requests.
  - `linkPreview` boolean — WhatsApp and iMessage. Set false to send the message without a link-preview thumbnail (WhatsApp: the first URL; iMessage: every link renders as plain text). Defaults to true, which is how every WhatsApp text has been sent to date. Ignored on other platforms. Accepted on the JSON body only, not on multipart requests.
  - `attachmentType` 'image' | 'video' | 'audio' | 'file' — Type of attachment. Defaults to file if not specified.
  - `attachmentName` string — WhatsApp only. Display name for a document sent via attachmentUrl with attachmentType: file (e.g. "Report.pdf"). Maps to the recipient's file name; without it WhatsApp derives the name from the URL and shows "Untitled". Ignored for image/video/audio and for binary uploads (which use the uploaded file's name).
  - `voiceNote` boolean — WhatsApp only. When `true` on an audio attachment, the message is sent as a voice message (PTT): the recipient sees the waveform + voice-note UI instead of a basic audio attachment. The audio file MUST be `.ogg` encoded with the OPUS codec (mono) per Meta's voice-message contract; other formats are rejected by WhatsApp. Ignored for non-audio attachments.
  - `subject` string — iMessage only (JSON body only). Bold title line rendered above the message text. Rejected with 400 on other platforms; ignored on voice-message sends.
  - `effect` 'slam' | 'loud' | 'gentle' | 'invisibleInk' | 'echo' | 'spotlight' | 'balloons' | 'confetti' | 'love' | 'lasers' | 'fireworks' | 'shootingStar' | 'celebration' — iMessage only (JSON body only). Apple screen/bubble animation played when the message arrives. Rejected with 400 on other platforms.
  - `contactCard` boolean — iMessage only (JSON body only). When `true`, attaches the sender's contact card (vCard) so the recipient can save the sender. Counts as message content on its own, so `message` becomes optional.
  - `channel` 'imessage' | 'sms' | 'rcs' | 'whatsapp' — iMessage only (JSON body only). Overrides the delivery channel for this one send; the provider otherwise picks it automatically. The sender must carry the matching add-on (SMS, RCS or WhatsApp), or the send fails. Not a default to set on every request. Rejected with 400 on other platforms.
  - `quickReplies` object[] — Quick reply buttons. Mutually exclusive with buttons. Max 13 items.
    - `title` string, required — Button label (max 20 chars)
    - `payload` string, required — Payload sent back on tap
    - `imageUrl` string — Optional icon URL (Meta only)
  - `buttons` object[] — Action buttons. Mutually exclusive with quickReplies. Max 3 items. Instagram / Facebook: also mutually exclusive with `template`. A Meta message carries one body shape, so sending both is a 400 rather than a silent drop of the buttons. WhatsApp: buttons always render as interactive reply buttons. Only `title` and `payload` are used; `type`, `url`, and `phone` are ignored (WhatsApp has no URL/phone button in this field; use the `interactive` field with `type: cta_url` for a link button). `payload` becomes the button reply ID delivered on the `message.received` webhook when the user taps. To send a simple reply-button message, provide `title` + `payload` and set `type: postback`, e.g. `{ "type": "postback", "title": "Yes", "payload": "yes" }`. Combine `buttons` with `attachmentUrl` and `attachmentType` `image`, `video`, or `file` to render one WhatsApp message with a media header, body text, and reply buttons. Audio is not a supported interactive header and returns 400 when combined with buttons.
    - `type` 'url' | 'postback' | 'phone', required — Button type. phone is Facebook only. Ignored on WhatsApp (buttons always render as reply buttons).
    - `title` string, required — Button label (max 20 chars)
    - `url` string — URL for url-type buttons (Facebook/Instagram only)
    - `payload` string — Payload for postback-type buttons. On WhatsApp, this is the reply ID returned on the message.received webhook when the button is tapped.
    - `phone` string — Phone number for phone-type buttons (Facebook only)
  - `template` object — Platform-dependent template payload. Ignored on Telegram. Instagram / Facebook: a generic template (carousel). Set `type: generic` and provide up to 10 `elements`, each with a `title` (required) and optional `subtitle`, `imageUrl`, and `buttons`. Mutually exclusive with the top-level `buttons` field (sending both is a 400); put the card's buttons on its `elements` instead. On Facebook, `imageAspectRatio` (`horizontal`, the default, or `square`) sets how Messenger renders the element images; Instagram has no such setting and rejects it. WhatsApp: sends an approved WhatsApp template message, the only message type WhatsApp accepts when the 24-hour customer-service window is closed. Provide exactly one element carrying the template reference: `{ "elements": [{ "name": "order_update", "language": "en_US", "components": [...] }] }` (`type` is ignored on WhatsApp). `components` is optional and is forwarded unchanged as the `template.components` array of Meta's Cloud API send payload; use it to fill body/header variables and button parameters, e.g. `[{ "type": "body", "parameters": [{ "type": "text", "text": "John" }] }]`. Templates with media headers (image, video, document) must include the header component with its media link here at send time. To send a template to a phone number with no existing conversation, or to have media headers filled in automatically from the template definition, use the create-conversation endpoint (POST /v1/inbox/conversations) instead.
    - `type` 'generic' — Template type. Required for Instagram/Facebook generic templates; ignored on WhatsApp.
    - `imageAspectRatio` 'horizontal' | 'square' — Facebook only. Aspect ratio Messenger renders element images at: horizontal (1.91:1, default) or square (1:1). A 400 on Instagram.
    - `elements` object[]
      - `title` string — Element title (max 80 chars). Required for Instagram/Facebook generic templates.
      - `subtitle` string — Element subtitle (Instagram/Facebook only)
      - `imageUrl` string — Element image URL (Instagram/Facebook only)
      - `buttons` object[] — Element buttons (Instagram/Facebook only)
        - `type` 'url' | 'postback'
        - `title` string
        - `url` string
        - `payload` string
      - `name` string — WhatsApp only. Name of the approved template to send.
      - `language` string — WhatsApp only. Template language code (e.g. en_US).
      - `components` object[] — WhatsApp only. Meta Cloud API send-shape components array, forwarded to Meta verbatim.
  - `interactive` object — WhatsApp-only. Rich interactive payload for list messages, CTA URL buttons, Flow prompts, location requests, voice-call buttons, and commerce messages (single product, product list, catalog, and carousel). When set, takes priority over `buttons` and `quickReplies`. The shape mirrors Meta's Cloud API `interactive` object for the types in the enum below. Use `buttons` / `quickReplies` for simple button replies (WhatsApp's `interactive.type: "button"`): the abstraction caps at 3 buttons and handles the auto-conversion for you. Use this field only for the types listed in the enum below. All interactive messages are session messages: they can only be sent inside the 24-hour customer service window opened by the user's last inbound message. Commerce types (`product`, `product_list`, `catalog_message`, and product carousels) require a Meta catalog connected to the WhatsApp Business Account in Commerce Manager. Media carousels (image/video cards) do not need a catalog. For `product`, `body` is optional (WhatsApp renders the product card itself) and `header` is not allowed (the product image is the header). For `product_list`, a `header` with `type: "text"` is required. For `carousel`, top-level `header`/`footer` are not supported; media goes on each card instead. For `voice_call`, the message renders WhatsApp's native call button; tapping it starts a voice call to your business number. Requires WhatsApp Business Calling to be enabled on the sending number. The optional `parameters.payload` string is echoed back on the `calls` webhook (as `cta_payload`) for attribution. For `location_request_message`, `action` may be omitted (we default it to `{ "name": "send_location" }`). WhatsApp renders a localized "Send location" button; the user's reply arrives as a regular location message in the conversation. For `request_contact_info`, `action` may be omitted (we default it to `{ "name": "request_contact_info" }`). WhatsApp renders a localized share button that cannot be relabelled, so put the reason for asking in `body.text`: this is a consent prompt, and a bare request converts badly. The reply arrives as an inbound `contacts` message with `metadata.contactsOrigin` set to `contact_request`, and we fold the shared number back into the contact automatically. A `contacts` message with origin `other` is a card the user picked from their address book and is NOT proof of their own number. For `catalog_message`, `action` may also be omitted (we default it to `{ "name": "catalog_message" }`). For `address_message`, `parameters.country` is required (Meta rejects the whole send without it); everything else in `parameters` (`values`, `saved_addresses`, `validation_errors`) is forwarded to Meta as-is. This is Meta's native structured shipping-address capture, generally available in India as of 2026-08; check Meta's documentation for current country availability before relying on it elsewhere. The submitted address arrives as an `nfm_reply` on the `message.received` webhook, same as a Flow submission, but with `metadata.nfmReplyName` set to `address_message` so you can tell the two apart. Tap events come back via the `message.received` webhook with `metadata.interactiveType` set to `list_reply` or `nfm_reply`. Carts submitted from commerce messages arrive as `metadata.order`; product inquiries arrive as `metadata.referredProduct`.
    - `type` 'list' | 'cta_url' | 'flow' | 'location_request_message' | 'request_contact_info' | 'voice_call' | 'product' | 'product_list' | 'catalog_message' | 'carousel' | 'address_message', required — Which interactive layout to render.
    - `header` object — Optional header shown above the body. Required with `type: "text"` for `product_list`; not allowed for `product` or `carousel`.
      - `type` 'text' | 'image' | 'video' | 'document'
      - `text` string — Required when header type is text.
      - `image` object
        - `link` string
      - `video` object
        - `link` string
      - `document` object
        - `link` string
    - `body` object — Required for every type except `product`, where it is optional.
      - `text` string, required — Main body text.
    - `footer` object — Optional footer shown below the action.
      - `text` string
    - `action` union
      - object — List action. `type` on the parent must be `list`.
        - `button` string, required — CTA label that opens the list (max ~20 chars).
        - `sections` object[], required — 1-10 sections. Total rows across all sections cannot exceed 10.
          - `title` string — Optional section header (max 24 chars).
          - `rows` object[], required
            - `id` string, required — Identifier returned in the webhook as metadata.interactiveId (max 200 chars).
            - `title` string, required — Row label (max 24 chars).
            - `description` string — Optional description below the title (max 72 chars).
      - object — CTA URL action. `type` on the parent must be `cta_url`.
        - `name` 'cta_url', required
        - `parameters` object, required
          - `display_text` string, required — Button label (max 20 chars).
          - `url` string, uri, required — Target URL opened when the user taps the button.
      - object — Voice-call action. `type` on the parent must be `voice_call`. Renders WhatsApp's native call button (requires Calling enabled on the sending number).
        - `name` 'voice_call', required
        - `parameters` object — All optional.
          - `display_text` string — Button label. Defaults to "Call Now".
          - `ttl_minutes` integer — How long the button stays tappable. Defaults to 10080 (7 days).
          - `payload` string — Arbitrary string echoed back as `cta_payload` on the `calls` webhook (connect/terminate) for attribution.
      - object — Flow action. `type` on the parent must be `flow`.
        - `name` 'flow', required
        - `parameters` object, required
          - `flow_message_version` '3' — Defaults to "3" when omitted.
          - `flow_token` string, required — Opaque token you choose to correlate Flow responses with your own state (max 200 chars).
          - `flow_id` string, required — Published Flow ID from Meta Business Manager.
          - `flow_cta` string, required — Button label that opens the Flow (max 20 chars).
          - `flow_action` 'navigate' | 'data_exchange', required — `navigate` sends the user to `flow_action_payload.screen`; `data_exchange` posts data to your Flow endpoint.
          - `flow_action_payload` object — Required when flow_action is `navigate`.
            - `screen` string — First screen to show.
            - `data` object — Optional pre-filled data passed to the screen.
          - `mode` 'draft' — Set to `draft` to test an unpublished Flow.
      - object — Location request action. `type` on the parent must be `location_request_message`. May be omitted entirely; it is defaulted.
        - `name` 'send_location', required
      - object — Contact-info request action. `type` on the parent must be `request_contact_info`. May be omitted entirely; it is defaulted.
        - `name` 'request_contact_info', required
      - object — Single-product action. `type` on the parent must be `product`. Requires a Meta catalog connected to the WhatsApp Business Account in Commerce Manager.
        - `catalog_id` string, required — Meta catalog ID connected to the WhatsApp Business Account.
        - `product_retailer_id` string, required — Retailer ID (SKU) of the product inside the catalog.
      - object — Multi-product action. `type` on the parent must be `product_list`. Requires a Meta catalog connected to the WhatsApp Business Account in Commerce Manager.
        - `catalog_id` string, required — Meta catalog ID connected to the WhatsApp Business Account.
        - `sections` object[], required — 1-10 sections. Total products across all sections cannot exceed 30.
          - `title` string — Optional section header.
          - `product_items` object[], required
            - `product_retailer_id` string, required — Retailer ID (SKU) of the product inside the catalog.
      - object — Catalog-message action. `type` on the parent must be `catalog_message`. May be omitted entirely; it is defaulted to `{ "name": "catalog_message" }`. Requires a Meta catalog connected to the WhatsApp Business Account in Commerce Manager.
        - `name` 'catalog_message', required
        - `parameters` object
          - `thumbnail_product_retailer_id` string — Optional product whose image is used as the message thumbnail. Falls back to the first catalog item when omitted.
      - object — Carousel action. `type` on the parent must be `carousel`. Carries 2-10 cards, either all product cards (`type: "product"`, all referencing the same `catalog_id`) or media cards (any other `type`, e.g. `cta_url`, with a required image/video `header` on each card). `card_index` (0-9, non-repeating) is auto-filled sequentially when omitted. Product carousels require a Meta catalog connected to the WhatsApp Business Account in Commerce Manager; media carousels do not.
        - `cards` object[], required
          - `card_index` integer — Card position. Auto-filled sequentially when omitted.
          - `type` string — `product` for a product card; media cards use `cta_url` or a quick-reply type.
          - `header` object — Media cards only, required. Carries the card's image or video.
          - `body` object — Optional card body text.
          - `action` object — Product cards: `{ catalog_id, product_retailer_id }` (required). Media cards: the card's button action (e.g. `cta_url` with `parameters.display_text` and `parameters.url`).
      - object — Address-request action. `type` on the parent must be `address_message`. Renders Meta's native structured address form in-chat (generally available in India as of 2026-08; check Meta's documentation for current country availability).
        - `name` 'address_message', required
        - `parameters` object, required
          - `country` string, required — ISO 3166-1 alpha-2 country code Meta should localize the address form for (e.g. IN). Required: Meta rejects the send without it.
          - `values` object — Optional pre-filled address field values.
          - `saved_addresses` object[] — Optional list of the recipient's previously saved addresses to offer as quick picks.
          - `validation_errors` object — Optional per-field error messages to show when re-prompting after a failed validation.
  - `replyMarkup` object — Telegram-native keyboard markup. Ignored on other platforms.
    - `type` 'inline_keyboard' | 'reply_keyboard' — Keyboard type
    - `keyboard` array[] — Array of rows, each row is an array of buttons
      - object[]
        - `text` string — Button text
        - `callbackData` string — Callback data (inline_keyboard only, max 64 bytes)
        - `url` string — URL to open (inline_keyboard only)
    - `oneTime` boolean — Hide keyboard after use (reply_keyboard only)
  - `messagingType` 'RESPONSE' | 'UPDATE' | 'MESSAGE_TAG' — Facebook messaging type. Required when using messageTag.
  - `messageTag` 'CONFIRMED_EVENT_UPDATE' | 'POST_PURCHASE_UPDATE' | 'ACCOUNT_UPDATE' | 'HUMAN_AGENT' — Facebook message tag for messaging outside 24h window. Requires messagingType MESSAGE_TAG. Instagram only supports HUMAN_AGENT.
  - `replyTo` string — Platform message ID to quote-reply to. For WhatsApp, pass the wamid; for Telegram, the Telegram message ID (delivered as message.platformMessageId on webhooks, and as `id` on each entry of the list-messages endpoint). On Slack it threads the reply (thread_ts) instead of quoting. Instagram and Facebook Messenger do not support send-side quote replies: the message is sent without a quote and the successful response includes a warnings entry with code ignored_field and param replyTo. Other platforms without send-side reply support ignore this field.
  - `location` object — WhatsApp and iMessage. Send a location pin (on iMessage it renders as a native map bubble).
    - `latitude` number, required — Latitude in decimal degrees.
    - `longitude` number, required — Longitude in decimal degrees.
    - `name` string — Optional location name.
    - `address` string — Optional street address.
  - `contacts` object[] — WhatsApp-only. Send one or more contact cards.
    - `name` object, required
      - `formatted_name` string, required — Full display name.
      - `first_name` string
      - `last_name` string
    - `phones` object[]
      - `phone` string
      - `type` string — e.g. CELL, WORK, HOME.
    - `emails` object[]
      - `email` string
      - `type` string

## Response `200`

Message sent

- object
  - `success` boolean
  - `warnings` object[] — Present when a successful send ignored replyTo on Instagram or Facebook Messenger. The message was sent without a quote; do not retry it to apply the reply.
    - `code` 'ignored_field', required
    - `param` 'replyTo', required
    - `message` string, required — Human-readable explanation of the ignored field.
  - `data` object
    - `messageId` string — Platform id of the sent message (not returned for Reddit). For WhatsApp this is the raw Meta wamid, the same id delivered as message.platformMessageId on webhooks and delivery-status updates, and the value to pass as replyTo to quote-reply.
    - `conversationId` string — Zernio conversation id, echoed so the thread can be read back or replied to. It equals the id the list-conversations endpoint returns for Telegram, WhatsApp, SMS and Slack; for Facebook, Instagram, Bluesky and Reddit that endpoint returns the platform thread id instead, so do not correlate the two by equality. For X, when the request addressed the conversation by its Twitter dm_conversation_id, that platform id is echoed back instead. Omitted when the send succeeded but the conversation could not be resolved to a stored record.
    - `attachments` object[] — Echo of the sent attachment with its resolved public URL, when one is available (Facebook, Instagram, Telegram, WhatsApp).
      - `type` string
      - `url` string
    - `messageIds` string[] — Facebook/Instagram only. Present when an attachment and text were both requested: Meta has no single body shape for both, so the send is two Meta messages under the hood. First element === messageId (the attachment); second is the follow-up text.
    - `partialFailure` object — Facebook/Instagram only. The attachment was delivered but the follow-up text message was rejected by Meta and was not stored; the response is still a 200 because the attachment send succeeded.
      - `part` 'text'
      - `error` string
      - `platformError` object — Meta's own diagnostic fields for the rejected follow-up, same shape as the 400 response's platformError.
        - `code` integer — Meta error code
        - `subcode` integer — Meta error_subcode
        - `fbtraceId` string — Meta fbtrace_id, quote this in a Meta bug report
        - `type` string — Meta error type (e.g. OAuthException)

## Other responses

- `400` — Bad request (e.g., attachment not supported for platform, validation error, category combined with a template or attachment, category used on a non-WhatsApp account, or the WhatsApp Business Account is not eligible for Direct Send). Meta rejections (e.g. sending outside the messaging window) arrive with code platform_api_error, type platform_error, and platform + platformError set.
- `401` — Unauthorized
- `403` — Inbox addon required, or Meta rejected the send outside the messaging window (type platform_error, code platform_api_error, platform, platformError with code/subcode/fbtraceId/type)
- `409` — Same Idempotency-Key still processing; retry after a short backoff
- `422` — Idempotency-Key reused with a different request
- `429` — Meta rejected the WhatsApp template-definition lookup. No message was sent.
- `500` — The platform rejected or failed the send. Zernio does NOT retry a send internally: a message send is not idempotent, and an opaque upstream failure (for example WhatsApp 131000) does not say whether the message was delivered. Retrying this request may deliver the message twice. Retry only if your use case tolerates a duplicate. Meta 5xx failures also arrive as a platform_error envelope (code platform_api_error, with platform and platformError set).
- `502` — The exact approved WhatsApp template definition is unavailable, or the platform returned an upstream failure. No WhatsApp template message is sent when definition lookup fails.
- `503` — An upstream service or database is temporarily unavailable. Retry after the indicated delay. A timed-out write may have completed upstream; check its outcome before resubmitting.
- `default` — Meta rejected the WhatsApp template-definition lookup with another upstream status. No message was sent.

## Changes

- **2026-09-21** `339f59df69dd` — 4 info
  - added the new optional request property `channel`
  - added the new optional request property `contactCard`
  - added the new optional request property `effect`
  - added the new optional request property `subject`
- **2026-09-16** `3e6ddf2a99ea` — 3 info
  - added the optional property `anyOf[#/components/schemas/ErrorResponse]/details/budgetScope` to the response with the `502` status
  - added the optional property `details/budgetScope` to the response with the `403` status
  - added the optional property `details/budgetScope` to the response with the `503` status
- **2026-09-15** `0dba7d004d75` — 6 info
  - added the optional property `anyOf[#/components/schemas/ErrorResponse]/details/quotaExhausted` to the response with the `502` status
  - added the optional property `anyOf[#/components/schemas/ErrorResponse]/details/quotaScope` to the response with the `502` status
  - added the optional property `details/quotaExhausted` to the response with the `403` status
  - added the optional property `details/quotaExhausted` to the response with the `503` status
  - …2 more
- …earlier changes not shown

[Full history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/inbox/conversations/:conversationId/messages/post.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/339f59df69dd?raw)
