You can choose to receive notification events about your SMS messaging by registering webhooks. This is a step-by-step guide to registering a webhook to receive notification events when a message is sent, finalized, or received.
\uD83D\uDCD8 Instructions
First, ensure that you have access to the data necessary for utilizing the Volt GraphQL API:
Have your Volt GraphQL API access token readily available. If you are unsure of where to locate your API token, contact api@textvolt.com.
In order to receive webhooks, you will need a publicly accessible HTTP server capable of listening for
POST
requests. We recommend implementing HTTPS for securely receiving webhook events.
If you register a webhook URL, notification events will be sent to that URL for any phone number belonging to your organization. Any routing based on the sending or receiving phone number, or any other information relating to a message, should be handled as needed within the server that handles the webhook events.
To register a URL for receiving webhook notification events, use the Volt GraphQL API:
Set the
Authorization
header to the valueBearer <token>
, replacing<token>
with the API access token belonging to your organization.Construct a GraphQL query using the
registerWebhook
mutation:mutation registerWebhook ($url: String!) { registerWebhook (url: $url) { id url createdAt lastUpdatedAt } }
Construct a JSON object containing the GraphQL variables for the query created in the previous step:
{ "url": "https://example.com/webhooks" }
Send a
POST
request tohttps://api.respondflow.com/graphql
with the GraphQL query and variables in the request body. We recommend using a GraphQL client library in the language of your choice to construct and send GraphQL API requests.
For example, to send the above GraphQL request using curl:curl --location --request POST 'https://api.respondflow.com/graphql' \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data-raw '{"query":"mutation registerWebhook ($url: String!) {\n registerWebhook (url: $url) {\n id\n url\n createdAt\n lastUpdatedAt\n }\n}","variables":{"url":"https://example.com/webhooks"}}'
Once a webhook is registered, you should receivePOST
requests containing webhook notification event data related to your SMS messages.
🛠 Example webhook payloads
Webhook payloads of all types are sent to each registered webhook URL. In order to differentiate between different types of webhook notification events, you can inspect the event_type
property of the payload
object contained within the webhook payload.
When a message is received
{ "type": "messaging", "id": "rfw_6962ccb5_80d23dc13c024d38873534471681379c", "payload": { "message_app_id": "c7fdc0ba-f3df-4e30-a7fc-397940a6f675", "id": null, "to_number": "+15555550123", "from_number": "+15555550145", "valid_until": null, "type": "SMS", "text": "Replying to message from handset", "sent_at": null, "received_at": "2022-04-07T22:21:04.259+00:00", "status": "webhook_delivered", "parts": 1, "messaging_profile_id": "40017bf5-8809-4640-9925-da5c732667b7", "media": [], "encoding": "GSM-7", "direction": "inbound", "completed_at": null, "occurred_at": "2022-04-07T22:21:04.397+00:00", "event_type": "message.received" }, "time": 1649370064 }
When a message is sent to carrier
{ "type": "messaging", "id": "rfw_6962ccb5_e41a61024d9a4a61817e7220fbcbf6b4", "payload": { "message_app_id": "40318006-1cae-4997-acbc-fe9a4aadb7dd", "id": "rf_o6aDxhawR227gt5wgZ2I", "to_number": "+15555550123", "from_number": "+15555550145", "valid_until": "2022-04-07T23:19:44.718+00:00", "type": "SMS", "text": "Sending a message to myself to demonstrate using the GraphQL API", "sent_at": "2022-04-07T22:19:44.985+00:00", "received_at": "2022-04-07T22:19:44.718+00:00", "status": "sent", "parts": 1, "messaging_profile_id": "40017bf5-8809-4640-9925-da5c732667b7", "media": [], "encoding": "GSM-7", "direction": "outbound", "completed_at": null, "occurred_at": "2022-04-07T22:19:44.985+00:00", "event_type": "message.sent" }, "time": 1649369985 }
When a message is finalized
A message is finalized whenever it has been received by the handset or has failed to deliver. Both cases will be delivered with an event_type
of message.finalized
. Delivered and failed messages can be differentiated by inspecting the status
property of the payload
object contained within the webhook payload.
A message may fail to deliver for several reasons, including timeout, spam blocking, receiver opt out, and others.
When a message is delivered
{ "type": "messaging", "id": "rfw_6962ccb5_eb7654690ec04a0593cc645fd2353995", "payload": { "message_app_id": "40318006-1cae-4997-acbc-fe9a4aadb7dd", "id": "rf_o6aDxhawR227gt5wgZ2I", "to_number": "+15555550123", "from_number": "+15555550145", "valid_until": "2022-04-07T23:19:44.718+00:00", "type": "SMS", "text": "Sending a message to myself to demonstrate using the GraphQL API", "sent_at": "2022-04-07T22:19:44.985+00:00", "received_at": "2022-04-07T22:19:44.718+00:00", "status": "delivered", "parts": 1, "messaging_profile_id": "40017bf5-8809-4640-9925-da5c732667b7", "media": [], "encoding": "GSM-7", "direction": "outbound", "completed_at": "2022-04-07T22:19:46.119+00:00", "occurred_at": "2022-04-07T22:19:46.119+00:00", "event_type": "message.finalized" }, "time": 1649369986 }
When a message fails to deliver
{ "type": "messaging", "id": "rfw_6962ccb5_eb7654690ec04a0593cc645fd2353995", "payload": { "message_app_id": "40318006-1cae-4997-acbc-fe9a4aadb7dd", "id": "rf_o6aDxhawR227gt5wgZ2I", "to_number": "+15555550123", "from_number": "+15555550145", "valid_until": "2022-04-07T23:19:44.718+00:00", "type": "SMS", "text": "Sending a message to myself to demonstrate using the GraphQL API", "sent_at": "2022-04-07T22:19:44.985+00:00", "received_at": null, "provider_error_code": "40002", "provider_error_detail": "The message was flagged by a SPAM filter and was not delivered. This is a temporary condition.", "provider_error_title": "Blocked as spam - temporary", "carrier_name": "T-MOBILE USA, INC.", "error_code": "702", "status": "failed", "parts": 1, "messaging_profile_id": "40017bf5-8809-4640-9925-da5c732667b7", "media": [], "encoding": "GSM-7", "direction": "outbound", "completed_at": "2022-04-07T22:19:46.119+00:00", "occurred_at": "2022-04-07T22:19:46.119+00:00", "event_type": "message.finalized" }, "time": 1649369986 }
🔐 Validating webhooks
Each Volt webhook notification event that we send you will include a cryptographic signature in the X-Respond-Flow-Signature
header. The signature allows you to validate that webhooks were not sent by a third-party.
When validating the RSA signature included with each webhook notification event request, it is recommended to use an established cryptographic library in the language of your choice. The entire webhook request payload should be used as the message in the RSA signature validation.
Our RSA public key is available at https://callbacks.respondflow.com/id_rsa.pub, which can be used to validate the signature sent with each request using a standard cryptographic library in your language of choice.