A webhook is an HTTPS callback that specifies how your agent should respond to messages and events. Once you configure your endpoint to accept webhooks, you can start receiving messages and events.

Vibes RBM service sends each RCS event/message as a single HTTP POST request. They will follow this general format:

POST / HTTP/1.1
Content-Type: application/json
X-Vibes-Eventclass: {{eventClass}}
X-Vibes-Signature: {{signature}}

{{requestBody}}

Below is a table defining a few of these attributes:

ElementDefinition
X-Vibes-EventclassAn HTTP header that indicates what type of event class the callback is. Options areServerEvent, UserEvent, or UserMessage.
X-Vibes-SignatureAn HTTP header that contains a BASE64 encoded HMAC SHA512 signature.
{{requestBody}}An HTTP POST body that contains event data serialized in JSON format.

Event Classes

ServerEvent

An event that occurred server side that is related to a conversation between an agent and a user. The {{requestBody}} will be formatted as follows:

{
  "phoneNumber": string,
  "agentId": string,
  "messageId": string,
  "eventType": enum ("SENT", "FAILED", "TTL_EXPIRATION_REVOKED", "TTL_EXPIRATION_REVOKE_FAILED", "EVENT_TYPE_UNSPECIFIED"),
  "eventId": string,
  "sendTime": string
}

Example

Below is an example of aSENTevent. The signature was created usingsuper-secret-value as a callback secret:

POST / HTTP/1.1
Content-Type: application/json
X-Vibes-Eventclass: ServerEvent
X-Vibes-Signature: xZJCklJ8V7zSGvi5+d5Da3eiXkxECumAvnHtKH/buGsLoxkRp0kZrr7jxP/qzDYUke7y8H3XuUFVAs07g7hrmw==

{
   "phoneNumber":"+12223334444",
   "messageId":"be0ed04a-ff3c-4a1a-8c64-9235fb4f9073",
   "eventType":"SENT",
   "eventId":"75078f52-5ed0-4d95-95d8-0cb5a7c7dede",
   "sendTime":"2025-01-01T00:00:00.000000000Z",
   "agentId":"example_agent"
}

UserEvent

An event coming from an end user's RCS client in conversation with your RCS agent. This could be a delivery message, a notification that the end user is typing, or a read receipt. The {{requestBody}} will be formatted as follows:

{
  "senderPhoneNumber": string,
  "eventType": enum ("DELIVERED", "IS_TYPING", "READ", "EVENT_TYPE_UNSPECIFIED"),
  "eventId": string,
  "messageId": string,
  "sendTime": string,
  "agentId": string
}

Example

Below is an example of a DELIVERED event signature created using super-secret-value as a callback secret:

POST / HTTP/1.1
Content-Type: application/json
X-Vibes-Eventclass: UserEvent
X-Vibes-Signature: QJyAq25GodhDIIV5drikYKoTLDUdT/Mt12QCJpuFMxD88CKv2BbFFHxb/Jt1yOXw/6e4CfCWOgjr2ehq088iwA==

{
   "senderPhoneNumber":"+12223334444",
   "eventType":"DELIVERED",
   "eventId":"MxkiHGGOfhSvSi3xIsj-26MQ",
   "messageId":"be0ed04a-ff3c-4a1a-8c64-9235fb4f9073",
   "sendTime":"2025-01-01T00:00:00.000000Z",
   "agentId":"example_agent"
}

UserMessage

The end user has sent a message to your RCS agent. The {{requestBody}} will be formatted as follows:

{
  "senderPhoneNumber": string,
  "messageId": string,
  "sendTime": string,
  "agentId": string,

  // Union field content can be only one of the following:
  "text": string,
  "userFile": { object (UserFile) },
  "location": { object (LatLng) },
  "suggestionResponse": { object (SuggestionResponse) }
  // End of list of possible types for union field content.
}

Example

Below is an example of a UserMessage event. The signature was created using super-secret-value as a callback secret:

POST / HTTP/1.1
Content-Type: application/json
X-Vibes-Eventclass: UserMessage
X-Vibes-Signature: 4o4VhglRySPjZsAA2P9y4A8bq68GaI7JE7GEtXf7EHnGvX7BDujfAekIA589H4+JJcT0wE06/DiiEInVTNtdcg==

{
   "senderPhoneNumber":"+12223334444",
   "messageId":"MxZIMfKVnURVm7GEMvpbaIng",
   "sendTime":"2025-01-01T00:00:00.000000Z",
   "text":"some user response",
   "agentId":"example_agent"
}

Security

To ensure the security and authenticity of webhooks sent from our API, we sign each webhook request using a SHA-512 HMAC. This allows you to verify that incoming requests are indeed from our API and have not been tampered with.

Each webhook request sent to your endpoint includes an X-Vibes-Signature header. This header contains the SHA-512 HMAC signature of the request body, generated using the webhook token provided by our support team as the secret key.

Header information

  • Header Key: X-Vibes-Signature
  • Signature Algorithm: HMAC SHA-512
  • Secret Key: Your provided webhook token

Verifying the Webhook Signature

  1. Using your webhook token as a key, create a SHA-512 HMAC of the bytes of the message payload and base64-encode the result.
  2. Compare the X-Vibes-Signature header with your computed HMAC.
    1. If the hashes match, you've confirmed that Vibes sent the message and can proceed with processing the webhook.
    2. If the hashes don't match, reject the request as it may not be authentic.

Sample Code for verifying signature

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class WebhookVerifier {
    public static boolean verifySignature(String payload, String signature, String secret) throws Exception {
        Mac sha512Hmac = Mac.getInstance("HmacSHA512");
        SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA512");
        sha512Hmac.init(keySpec);
        byte[] rawHmac = sha512Hmac.doFinal(payload.getBytes());
        String computedSignature = Base64.getEncoder().encodeToString(rawHmac);
        return computedSignature.equals(signature);
    }
}
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
    const hmac = crypto.createHmac('sha512', secret);
    hmac.update(payload);
    const computedSignature = hmac.digest('base64');
    return computedSignature === signature;
}
import hmac
import hashlib
import base64
def verify_signature(payload, signature, secret):
    computed_signature = base64.b64encode(hmac.new(secret.encode(), payload.encode(), hashlib.sha512).digest())
    return computed_signature.decode() == signature
package main
import (
    "crypto/hmac"
    "crypto/sha512"
    "encoding/base64"
)
func verifySignature(payload, signature, secret string) bool {
    h := hmac.New(sha512.New, []byte(secret))
    h.Write([]byte(payload))
    computedSignature := base64.StdEncoding.EncodeToString(h.Sum(nil))
    return computedSignature == signature
}

HTTP responses

It is the receiver's responsibility to ensure processing and to return the appropriate error codes. Depending on the error code, Vibes will attempt to redeliver the events up to the maximum number of tries. It is important that the callback endpoint not return errors when no retry attempts are desired. In that case, simply accepting the message with a 2XX response is sufficient.

Developers must be mindful that sending messages at high rates will generate webhook notifications at high rates and must design their code to ensure they can consume notifications at the expected rate. It is important that developers consider situations that may cause failure responses - including 500 responses from their web container, timeouts or upstream failures. Thing to consider include:

  • Ensure your DDoS protections are configured to handle the expected rate of webhook notifications.
  • Ensure resources such as database connection pools don't run out and produce timeouts or 500 responses.
  • Below is a chart of the HTTP response codes that your endpoint should return, depending on the situation.

HTTP Response

Description

2XX OK

Message was accepted and processed successfully.

4XX

Permanent event specific error conditions that should not be retried. It will immediately put the event in a failure queue and notify the customer for resolution.

3XX OR 5XX

Temporary error conditions that indicate a transient failure. These events will be retried based on the configured retry scheme, and then, if still failing, it will put the event in a failure queue and notify the customer for resolution. These can also trigger downed states within a URL that may suspend additional delivery attempts for short periods of time to avoid saturating a down (or slow) service.