API reference

Send

Post a message with a send key or an API token.

Send a message

POST/v1/send

Sends a message to one of your sources. Use the source's send key, in the Authorization header or as ?key= in the address; the key decides where the message goes. An API token can send too, to the source you name in source or to Inbox.

A plain-text body becomes the message text. Send JSON when you want a title, a thread, a link, an alert or a sound. Use thread to collect related updates under one title within the source. Leave out alert to use the source's default alert, or standard if it has none. Leave out sound to play the source's sound, or the account's if the source has none.

AuthSend keyorKey in the addressorAPI token

Headers

  • Idempotency-Keystring

    A key you choose so that retrying a send can't create a duplicate. For 24 hours, the same key with the same message to the same source returns the original response instead of saving a new message. Ripple compares messages after its usual cleanup, such as trimming whitespace. The same key with a different message returns 409 idempotency_mismatch. After 24 hours the key can save a new message. A blank key is ignored.

Body

  • titlestring

    A title shown above the message in Ripple and in notifications. Without one, the body's first line with text becomes the title, as plain text and shortened to 120 characters at a word with an ellipsis. Leave it out when you use thread. A title longer than 120 characters is shortened without splitting a character or emoji, and the response includes a title_truncated warning.

  • bodystring · up to 64,000 characters

    The main text of the message, shown in full when someone opens it. Up to 64,000 characters.

  • linkstring · URL · up to 2,048 characters · starts with https://

    An https:// link to open from the message. It can be up to 2,048 characters, both as you send it and after Ripple URL-encodes it.

  • linkTitlestring · up to 64 characters

    A label for the link's button, up to 64 characters. Needs link.

  • alertstring

    quietstandardimportant

    How strongly the message alerts. Leave it out to use the source's default alert, or standard if the source has none.

  • soundstring

    hoparcadeclinkdropechoglowknockliftsparkleswooptickwave

    The sound this message plays when it alerts with a sound. Leave it out to play the source's sound, or the account's if the source has none. A sound never makes a message alert more strongly.

  • sourcestring · starts with src_

    The ID of the source to send to when you use an API token. Leave it out to send to Inbox. A send key already decides its source, so with a key, leave this out or give that same source's ID.

  • threadstring · 1–120 characters

    Collects this message with earlier ones under one title, such as Production deploy. Messages with the same thread in the same source join one thread, shown under this title. Ripple trims the ends, turns runs of whitespace into one space and ignores case when matching, and keeps the title as it was first sent. Punctuation and wording still count, so Deploy and Deploy! are different threads.

Or send text/plain

The message text, with leading and trailing whitespace trimmed. A form-encoded body (application/x-www-form-urlencoded, which curl -d sends by default) is read the same way, but a JSON object sent as form data returns 400 invalid_payload.

Responses

  • 202

    Ripple saved the message to its source. This doesn't mean a device has shown it yet.

    Response fields
    • statusstringRequired

      accepted

    • messageIdstringRequired
    • sourceobjectRequired

      The source a message belongs to. Inbox is the built-in system source; sources you create are custom.

      Fields
      • kindstringRequired

        systemcustom

      • idstring · starts with src_Required
      • labelstringRequired
    • receivedAtstring · date and timeRequired
    • warningslist of objects

      Present when Ripple saved the message but changed something in it, such as shortening a long title.

      Fields
      • codestringRequired

        title_truncated

      • messagestringRequired
    • threadobject
      Fields
      • idstring · starts with thr_Required
      • titlestring · up to 120 charactersRequired
      • createdbooleanRequired

        true when this send started a new thread, because the source had no thread with this title outside Trash. A replayed send returns the original value.

      • messageNumberinteger · at least 1Required

        This message's place in the thread, counting from 1 in the order Ripple received the messages.

  • 400

    Ripple couldn't take the message. The source isn't this key's source or isn't on this account (invalid_source). The message has no title or body, or a message in a thread has no body (missing_content). It has a field Ripple doesn't know (unsupported_field) or a field with a value that isn't allowed (invalid_payload), or its JSON can't be parsed (invalid_json).

  • 401

    The key isn't valid, an API token was put in the address, or a key was sent in both the header and the address (invalid_credential)

  • 403

    The source is disabled (source_disabled) or deleted (source_deleted), or the API token is read-only (read_only_token)

  • 409

    This Idempotency-Key was already used for a different message (idempotency_mismatch)

  • 413

    The request is larger than Ripple accepts (payload_too_large)

  • 415

    The content type isn't JSON, plain text or form data (unsupported_media_type)

  • 429

    Too many sends. An account can send 60 new messages in any 60 seconds (account_rate_limited), and a source can send 20 (source_rate_limited). A source that goes over its limit is paused for 15 minutes. A replayed send with the same Idempotency-Key doesn't count toward either limit. Retry-After says how many seconds until the account can send again, or until the source's pause ends.

  • 500

    Something went wrong on Ripple's side (internal_error), and the response leaves out the details. You can't tell whether the message was saved, so retry with the same Idempotency-Key and message: if the first try was saved, you get its original response instead of a duplicate.

  • 503

    Ripple is busy right now (database_busy). Wait the number of seconds in Retry-After, then retry with the same Idempotency-Key and message.

Example
curl https://api.ripplepush.com/v1/send \
  -H "Authorization: Bearer $RIPPLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hello from Ripple"
  }'
Send toYour sources…
{
  "status": "accepted",
  "messageId": "msg_426dd54d815b4bfaaf0940b606cd0806",
  "source": {
    "kind": "system",
    "id": "src_9fddbdcb785848c6b10b068facd32d87",
    "label": "Inbox"
  },
  "receivedAt": "2026-10-02T12:00:01.000Z"
}