Webhooks

Webhooks are automated notifications to defined URLs that inform about events in real time. They are useful because they enable an immediate response to specific events without the need for continuous polling. Webhooks help keep systems efficient and responsive.

Your webhooks are called immediately when an event occurs. If we cannot reach your URL or it responds with an error status, we retry the delivery on a fixed schedule and additionally monitor over several days whether the receiver is permanently failing. The full behavior is documented under Delivery & retries.


Delivery & retries

When we retry a webhook

A webhook is only re-delivered when the response from your server indicates a temporary failure:

  • Name
    HTTP 429
    Type
    rate limit
    Description

    Your endpoint signals that it is currently receiving too many requests.

  • Name
    HTTP 5xx
    Type
    server error
    Description

    Specifically 500, 502, 503 and 504.

  • Name
    Connection errors
    Type
    network
    Description

    Timeouts, DNS resolution failures, TLS/handshake errors or a connection that is dropped during the request.

All other responses are treated as final and do not trigger another delivery attempt. This includes 4xx codes such as 400, 401, 403 and 404, since these usually point to a configuration issue on the receiver side that cannot be fixed by simply retrying. Responses in the 2xx and 3xx range count as successful.

Request timeout

Each individual delivery attempt has a timeout of 5 seconds. If your server does not respond within this window we treat the attempt as failed and schedule a retry according to the plan below.

Retry schedule

If an attempt fails, the next one is scheduled after a fixed, increasing delay. We make a total of up to 14 attempts; after that the job is dropped. The whole delivery window therefore spans roughly 3.5 days.

AttemptDelay since previous attempt
1 (initial)immediately
21 minute
35 minutes
430 minutes
560 minutes
62 hours
7 to 1410 hours each

Automatic disabling on persistent failures

In addition to per-message retries, we continuously monitor the daily failure rate per webhook. A webhook is flagged as "problematic" once, on a given day,

  • the daily failure rate is above 80 %, and
  • at least 10 failures have occurred that day.

From that point on the webhook is observed over several days. If the situation does not improve, the system escalates step by step:

DayThreshold (rolling failure rate)Action
1above 80 %Warning email level 1
3above 85 %Warning email level 2
5above 90 %Warning email level 3
7above 95 %Webhook is automatically disabled, audit-log entry written and disable email

Day counters start from the day the problem is first detected.

After auto-disable

A webhook that has been disabled automatically stays inactive until you re-enable it manually in the dashboard. After re-activation the statistics start fresh.

What counts as "successful"?

For the failure-rate monitor, every response that is not a retry trigger counts as "ok". In particular, 2xx, 3xx and even 4xx responses (except 429) are treated as successful, because from the delivery system's perspective they are an unambiguous, final answer.


Security

Check source IP

All webhooks originate from our IPv4 195.201.160.143 or from the IPv6 2a01:4f8:13a:8e7::2. Should this change, you will find all further details in our Changelog.

Check signature

All webhooks to your server are signed with the signing key of your account. You can use this data to validate the authenticity of the requests from us for each webhook received and avoid duplication or fraudulent requests. To do this, check the signature as described on the Signing page.

We send you the following headers in every webhook:

  • Name
    X-Signature
    Type
    string
    Description

    The signature generated by us

  • Name
    X-Timestamp
    Type
    integer
    Description

    Timestamp at which the signature was created by us

  • Name
    X-Nonce
    Type
    string
    Description

    Randomly generated string with 32 characters


Examples as JSON payload

SMS

Incoming SMS (sms_mo)

{
  "data": {
    "id": "681590",
    "sender": "SMS",
    "system": "491771783130",
    "text": "Hello World",
    "time": "1605878104",
    "message_type": "SMS"
  },
  "webhook_event": "sms_mo",
  "webhook_timestamp": "2020-12-02 11:55:44"
}

SMS status change (dlr)

{
  "data": {
    "msg_id": "77149843739",
    "status": "TRANSMITTED",
    "timestamp": "2021-08-24 08:08:00.000000"
  },
  "webhook_event": "dlr",
  "webhook_timestamp": "2021-08-24T08:08:00+02:00"
}

Performance Tracking (tracking)

{
    "webhook_event": "tracking",
    "webhook_timestamp": "2022-07-27T07:38:18+02:00",
    "data": {
        "sms_id": "77182424125",
        "sms_label": null,
        "tracking_url": "https://svn.me/7oz",
        "final_url": "https://www.google.com",
        "type": "click",
        "total_clicks": 5,
        "total_views": 3
    }
}

Voice

Voice message status change (voice_status)

{
  "data": {
    "callerId": "49176123456789",
    "duration": "4",
    "id": "284195",
    "pricePerMinute": 0.075,
    "recipient": "4943160049851",
    "status": "completed",
    "timestamp": 1629786769
  },
  "webhook_event": "voice_status",
  "webhook_timestamp": "2021-08-24T08:32:50+02:00"
}

Incoming voice call (voice_call)

{
  "webhook_event": "voice_call",
  "webhook_timestamp": "2024-08-02T07:28:59+02:00",
  "data": {
    "id": 0,
    "caller": "4943160049851",
    "time": 1722576539,
    "system": "4915170517246"
  }
}

DTMF signal (voice_dtmf)

{
  "webhook_event": "voice_dtmf",
  "webhook_timestamp": "2024-08-02T07:28:59+02:00",
  "data": {
    "id": 0,
    "callerId": "4943160049851",
    "recipient": "4943160049851",
    "status": "completed",
    "system": "4915170517246",
    "timestamp": 1722576539,
    "duration": 2.76,
    "pricePerMinute": 0.045,
    "dtmf_digit": 9,
    "total_price": 0.045
  }
}

RCS

Message has been delivered

{
  "webhook_event": "rcs",
  "webhook_timestamp": "2024-03-08T10:01:07+01:00",
  "data":
  {
    "msg_id": "77233699836",
    "status": "DELIVERED",
    "timestamp": "1709888466.254410",
    "foreign_id": null,
    "agent_id": "myfancyagent"
  }
}

Message has been read

{
    "webhook_event": "rcs",
    "webhook_timestamp": "2024-03-08T10:01:09+01:00",
    "data":
    {
      "msg_id": "77233699836",
      "status": "READ",
      "timestamp": "1709888468.065783",
      "foreign_id": null,
      "agent_id": "myfancyagent"
    }
  }

Status report of a sent message

{
  "webhook_event": "rcs",
  "webhook_timestamp": "2024-03-08T10:00:18+01:00",
  "data":
  {
    "sender": "4915153952979",
    "status": "IS_TYPING",
    "agent_id": "myfancyagent"
  }
}

A text message has been sent

{
  "webhook_event": "rcs",
  "webhook_timestamp": "2024-03-08T09:47:12+01:00",
  "data": {
    "id": 1871353,
    "sender": "4915153952979",
    "time": "1709870553",
    "message_type": "RCS",
    "content_type": "text",
    "text": "Hello",
    "agent_id": "myfancyagent"
  }
}

A suggested answer has been selected

{
  "webhook_event": "rcs",
  "webhook_timestamp": "2024-03-08T05:59:33+01:00",
  "data": {
    "id": 1870983,
    "sender": "4915153952979",
    "time": "1709870129",
    "message_type": "RCS",
    "content_type": "suggestion_response",
    "suggestion_response": {
      "postbackData": "suggestion_2",
      "text": "Suggestion #2",
      "type": "REPLY"
    },
    "agent_id": "myfancyagent"
  }
}

An image has been sent

{
  "webhook_event": "rcs",
  "webhook_timestamp": "2024-03-08T08:58:20+01:00",
  "data": {
    "id": 1871195,
    "sender": "4915153952979",
    "time": "1709870556",
    "message_type": "RCS",
    "content_type": "user_file",
    "user_file": {
      "thumbnail": {
        "mimeType": "image/jpeg",
        "fileSizeBytes": 10166,
        "fileUri": "https://static.seven.io/uploads/rbm/61513d3d/6176746a5177553d/4f36357145416a773452537737696e495a366a68454a42344639574937716e62704156765358664d486e42776730337334675a76522b6d4f574b6e32626632546842493d.jpeg"
      },
      "payload": {
        "mimeType": "image/jpeg",
        "fileSizeBytes": 611314,
        "fileName": "IMG_20240308_050231_01.jpg",
        "fileUri": "https://static.seven.io/uploads/rbm/61513d3d/6176746a5177553d/4f76746e45515768746866717653444e6166336a513852375249614d753637656f414a6f4758624d5358417269306e767331493645372b47446654325a66764b3168453d.jpeg"
      }
    },
    "agent_id": "myfancyagent"
  }
}

A file has been sent

{
  "webhook_event": "rcs",
  "webhook_timestamp": "2024-03-08T11:07:51+01:00",
  "data": {
    "id": 1871485,
    "sender": "4915153952979",
    "time": "1709892233",
    "message_type": "RCS",
    "content_type": "user_file",
    "user_file": {
      "payload": {
        "mimeType": "application/pdf",
        "fileSizeBytes": 18810,
        "fileName": "sample (1).pdf",
        "fileUri": "https://static.seven.io/uploads/rbm/61513d3d/617678715267303d/4f616c675256696b73524c6c75337a4b5a66336a51705570464e665a752f6d4e70464d37546e504b5458423730556a7337314e70514c3241436650304d616e4b3078493d.pdf"
      }
    },
    "agent_id": "myfancyagent"
  }
}

A location has been shared

{
  "webhook_event": "rcs",
  "webhook_timestamp": "2024-03-08T11:07:51+01:00",
  "data": {
    "id": 1871485,
    "sender": "4915153952979",
    "time": 1709892233,
    "message_type": "RCS",
    "content_type": "location",
    "location": {
        "latitude": 54.3216562,
        "longitude": 10.1350767
    },
    "agent_id": "myfancyagent"
  }
}
Last updated: 2 weeks ago