Policies & help › Developers
Webhooks
Indo Mail has no webhooks yet. This page describes the planned design (events, payload, HMAC-SHA256 signatures, retries and idempotency) and what developers can use today instead.
1. Status
Webhooks are planned and are not live. You cannot register a webhook address with Indo Mail today, and no calls are made to any address you own. This page sets out how webhooks are intended to work so that developers can plan, and so that the design can be criticised before it is built. Details may change before release.
A webhook is a message that Indo Mail sends to a web address you control when something happens in an account that has allowed it. It saves you from asking the API again and again whether anything is new.
2. Planned design principles
- Opt-in only. Webhooks will work only for accounts that have connected your app and approved the matching permission (see the OAuth Authentication document). A webhook is never created without the account owner's consent.
- Minimum data. Events will carry identifiers and a short summary, not whole messages. To read a message, your app calls the API with its own permission.
- No message content in events by default. Subject lines and bodies will not be included unless the app holds a permission that allows reading them.
- HTTPS only. Addresses must begin with https:// and use a valid certificate. We will not call private network addresses.
- Per-account control. Owners can see and remove connected webhooks in Settings, and business administrators can turn them off for the whole company.
3. Planned events
| Event | Sent when | Needs scope |
|---|---|---|
| mail.received | A message arrives in the inbox | mail.readonly |
| mail.sent | A message has been handed over for delivery | mail.readonly |
| mail.bounced | A message to an outside address could not be delivered | mail.readonly |
| mail.labelled | A label is added to or removed from a conversation | mail.readonly |
| mail.spam_reported | The user reports a message as spam or as scam | mail.readonly |
| drive.file_created | A file or folder is created in Drive | drive.readonly |
| drive.file_shared | A share link is created or removed | drive.readonly |
| wallet.request_paid | The user marks a UPI payment request as paid | wallet.request |
| ads.lead_received | A Local Services Ads enquiry arrives for an advertiser | ads.read |
| ads.creative_reviewed | An ad was approved or rejected | ads.read |
| domain.verified | A business domain passed its DNS check | admin |
| domain.check_failed | A DNS check found that a required record is missing | admin |
| user.signed_in_new_device | A sign-in from a device not seen before | admin |
The wallet event reports only what the user has recorded. Indo Mail does not hold money and cannot confirm a UPI payment itself.
4. Planned payload
Every call will be an HTTP POST with a JSON body in this shape:
id: a unique event ID such asevt_01J9Q4Z7M3.type: the event name, such asmail.received.created: the time the event happened, in UTC, in ISO 8601 form.account: an opaque account ID, not the email address.data: the details, for example{ "messageId": 4812, "threadId": "t_9021", "folder": "inbox", "hasAttachments": true }.attempt: the delivery attempt number, starting at 1.
Headers will include Content-Type: application/json, User-Agent: IndoMail-Webhooks/1, Indo-Event-Id, Indo-Timestamp and Indo-Signature.
5. Planned signatures (HMAC-SHA256)
Anyone can send a web request to your address, so you must check that a call really came from Indo Mail. Each webhook will have its own signing secret, shown once when you create it. For each call we will compute an HMAC-SHA256 of the text timestamp + "." + raw request body, using that secret as the key, and send it as Indo-Signature: v1=<hex digest>.
To verify a call: read the raw body (before any JSON parsing), take the Indo-Timestamp header, compute the same HMAC with your secret, compare the result to the header using a constant-time comparison, and reject the call if the timestamp is more than five minutes old. This stops attackers from replaying an old call.
You will be able to rotate a secret at any time. During rotation both the old and the new secret are valid for 24 hours, and calls carry two signatures.
6. Planned delivery and retries
| Rule | Planned behaviour |
|---|---|
| Success | Your server replies with any 2xx status within 10 seconds. |
| Failure | Any other status, a timeout or a connection error counts as a failure. |
| Retries | We retry with growing gaps (about 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours) until 24 hours after the first attempt. |
| Giving up | After 24 hours without success, the event is dropped and recorded as failed in the webhook log. |
| Disabling | If a webhook keeps failing for 3 days in a row, we disable it and email the account owner and the developer. |
| Ordering | Order is not guaranteed. Use the created time to sort. |
| Redirects | Redirects are not followed. |
Reply quickly and do the heavy work later. Put the event in a queue, answer with 200, and process it in the background.
7. Planned idempotency
Because of retries, your server may receive the same event more than once. Each event has a fixed id, and the Indo-Event-Id header carries the same value. Store the IDs that you have handled for at least 7 days. If an ID arrives a second time, reply with 200 and do nothing. This makes your handler idempotent, which means that doing it twice has the same effect as doing it once.
The same idea applies to calls that you make to us. The versioned API is planned to accept an Idempotency-Key header on actions such as sending a message, so that a retry after a network failure does not send the message twice.
8. What you can use today
Until webhooks are available, these live features give you near real-time information without polling in a tight loop.
| Option | How it works | Good for |
|---|---|---|
| Web Push | Browsers can subscribe at POST /api/push/subscribe and receive an encrypted notification for each new inbox message. The public key is at GET /api/push/key. Delivery goes through the browser's push service (Google, Mozilla, Apple or Microsoft), which sees only encrypted data. | Notifying a person on a phone or laptop. |
| Live stream | Call POST /api/mail/events-ticket for a ticket that lasts 60 seconds, then open GET /api/mail/events with it. The server pushes an event whenever mail arrives or changes. | A running app or dashboard that is signed in. |
| Android device polling | The Android app registers a device and checks for new mail in the background about every 15 minutes. | Our own Android app. |
| Regular API check | Call GET /api/mail/counts or GET /api/mail/messages on a schedule of no more than once a minute, with a token. | Simple scripts and cron jobs. |
All of these work only for your own signed-in account. None of them lets a third party watch another person's mail.
9. Security promise
When webhooks launch, we will publish the full specification, a test tool that sends sample events, and a changelog. We will give at least 12 months' notice before removing any event or field. We will never sell webhook data, never send it to advertisers, and never use it to train AI models.
10. Contact
To tell us which events you need, or to join the early-access list: contact@indoemail.in with the subject "Developer access".
INDO CHATS PRIVATE LIMITED, 168, GT Rd, near Aloka Cinema, Shibpur, Howrah, West Bengal 711102, India.