Webhooks send Deskgram events to an address you specify: a CRM, automation service or your own application. These are outbound Deskgram notifications. They do not configure a Telegram Bot API webhook or create an incoming command channel for the program.
Checked against the implementation on 24 October 2026.
Before you start: Deskgram must be running, and the receiver must be reachable from the computer running the program. Delivery currently uses POST with JSON. Interrupted deliveries are not automatically recovered after restarting the program.
You do not need to write code to configure delivery in the interface. Receiver developers and local HTTP API users can use the API reference.
Quick setup
- Obtain the receiving system's incoming webhook URL. Prepare its secret or token if required.
- In Deskgram, open Settings → Integrations.
- Select New, enter a name and Webhook URL.
- Under Which actions to send, select events.
- Under From which modules, keep All modules or choose specific ones.
- Under What the request contains, select a format. For initial setup, standard Deskgram JSON is useful if your receiver accepts it.
- Add a shared secret and additional headers when required.
- Check Enable webhook after saving, then select Create webhook.
- Select Test, then open History and inspect delivery details.
- Perform a short real action matching a selected event and check the result at the receiver.
Test uses saved settings. After changing the URL, secret, event selection or fields, save the endpoint before testing. You can create several webhooks with different receivers, subscriptions and formats.
Connecting a CRM
Enter the CRM's incoming webhook URL, rather than the URL of its homepage or dashboard. An incoming address for a compatible Deskgram channel might look like this:
https://crm.example.com/api/v1/channel-webhooks/deskgram/123The domain and channel number are fictional. Use the complete address supplied by your CRM.
| Setting | What to use |
|---|---|
| Name | A recognizable name, such as “CRM: messaging events” |
| Webhook URL | Complete incoming address from the CRM |
| CRM secret | Secret for that particular channel, if required |
| Format | Start with standard JSON for a compatible Deskgram channel |
| Module | spam_pm for its messaging events |
| Events | Sent messages, sending failures and lead replies as needed |
| Enabled | Required for automatic delivery |
Deskgram recognizes addresses containing /channel-webhooks/deskgram/{id} and displays the CRM secret field. The secret is transmitted in the x-secret header. The CRM supplies the URL and secret separately; a URL alone does not reveal the secret.
For other CRMs, check the expected JSON structure and authentication. CRM lead is not a universal adapter: field names still need to match the receiving system's contract.
For n8n, Make, Zapier or your own API, use the same approach: copy the receiving step's URL and configure the expected fields. The receiving workflow must be enabled and accessible.
Choosing events
| Event | When it is produced |
|---|---|
task.completed | Task processing has finished |
task.failed | Task reached a final error status |
task.cancelled | Task was stopped or cancelled |
message.sent | A supported sent-message event was recorded in spam_pm |
message.failed | A supported message-delivery failure was recorded in spam_pm |
lead.reply_received | An incoming lead reply was recorded in spam_pm |
To transfer individual messages to a CRM, select message events. Task completed alone does not create a separate webhook for every sent message.
A completed task does not prove every action inside it succeeded. Result counters and errors depend on the module. A skipped message or recipient-resolution failure does not necessarily produce message.failed; skip events are not currently included.
For lead replies, Deskgram must actually receive the incoming message through an active reply handler. Creating a webhook does not enable continuous account listening or guarantee collection after the task ends.
Selection buttons:
- Task results selects the three final task events.
- All available selects all six supported events.
- Clear removes the selection; select the events you need before saving.
Module filters
The module filter determines which tasks can supply the selected events.
- All modules does not restrict delivery to a particular module.
- Select modules limits it to chosen sections.
For example, task.completed with spampm means a private-message task finished; message.sent with spampm means an individual message was sent by that task.
Selecting a module does not give it new event types. Live message and reply events are currently integrated with spam_pm. Choosing another module for message.sent does not enable message delivery events for that module.
Choosing request data
| Format | Purpose |
|---|---|
| Standard Deskgram JSON | Full event with nested task, lead or message data |
| Short result | Editable fields for status, contact, message and error |
| CRM lead | Editable flat lead and message fields |
| Custom schema | Your field names and selected Deskgram sources |
The exact request depends on the event and the saved field list. Inspect the preview, then compare it with the actual sent data in delivery details.
Custom fields
For each row, enter the receiver's field name on the left, select its Deskgram source on the right, and enable or disable the field using its switch.
For example, a CRM may expect:
| Receiver field | Deskgram source |
|---|---|
contact.telegram_id | lead.telegramuserid |
contact.username | lead.username |
comment | message.text |
A fictional message event could produce:
{ "contact": { "telegram_id": "123456789", "username": "example_client" }, "comment": "Hello!"}Dots in target field names create nested objects. Missing source values are omitted. A phone number may be absent, for example: a webhook does not expose a hidden phone number.
If you disable or remove every field, the result is {}; the full event is not substituted. The preview is an example rather than a future recipient's actual data, so a real request may contain fewer fields.
The field builder selects and renames data. It does not execute JavaScript, calculate expressions, look up CRM values or run a chain of HTTP requests.
Additional settings
| Field | When it is needed |
|---|---|
| Signature secret | Receiver requires a shared secret or HMAC verification |
| Headers JSON | Receiver needs extra headers, such as Authorization |
| Timeout, seconds | Network response timeout; default 15, interface range 3–60 |
Example additional headers:
{ "Authorization": "Bearer YOUR_RECEIVER_TOKEN"}YOURRECEIVERTOKEN denotes the receiving system's token, not your Deskgram license key.
When editing in the interface, leaving the saved-secret field blank retains the previous secret. Its value is not displayed again. The REST API has different explicit clearing rules, documented in the reference.
With a secret configured, Deskgram sends x-secret, X-Deskgram-Webhook-Secret and X-Deskgram-Signature. The signature allows the receiver to verify the request body. The shared secret is also sent in headers, so use HTTPS and avoid logging those values. See the API reference for a verification example.
Testing the connection
Test sends a special webhook.test event to the selected receiver, even if the endpoint is disabled. It checks HTTP connectivity and handling of a test request. It does not launch a Telegram task.
A test contains no task, lead, account or message. Your custom mapping still applies; lead-only fields will be missing and can produce an empty object. A receiver should explicitly support test events. Rejection of a test without a lead may reflect CRM business validation; inspect the response code and body.
Only HTTP 200–299 counts as successful delivery. A 302 is not success: redirects are not followed. Specify the final receiving address.
HTTP 200 confirms acceptance at the HTTP layer, not creation of a lead or message. Inspect the CRM response and the corresponding record there.
History and retrying delivery
History displays recent deliveries. Select an endpoint and status, then refresh the list using History.
| Status | Meaning |
|---|---|
pending | A record exists but no final result has been recorded |
retrying | Delivery failed and an automatic retry is in progress |
success | Receiver returned HTTP 200–299 |
error | Attempts were exhausted or sending ended with an error |
Details include sent data, the original event for new deliveries, receiver response, error, attempt count and timestamps. History is not a complete trace of every HTTP exchange.
Automatic attempts
There are up to three attempts per delivery. Pauses before the second and third are approximately 2 and 4 seconds, excluding network waiting. HTTP 4xx and 5xx failures are also retried.
All automatic attempts for one delivery use the same X-Deskgram-Delivery-Id. The receiver should deduplicate the identifier within the relevant sender's scope so a repeated request does not repeat an action already performed.
Manual retry
- Open a failed delivery.
- Correct its endpoint URL, secret or fields if needed.
- Save the endpoint.
- Return to the failed record and select Retry delivery.
- Inspect the new history record and the receiver's result.
Manual retry is available only for error. It creates a new delivery with a new ID, retaining the original record.
For new-format history, retry uses the original event and current field mapping. For old records without an original event, the saved JSON is resent without mapping it again. Current URL, secret and headers apply in both cases.
If the receiver processed a request but its response was lost, retry can duplicate a business action. Because manual retry has a new delivery ID, the CRM also needs business-level deduplication.
Disabling an endpoint stops selection for new automatic events but does not cancel an ongoing request. Explicit Test and Retry can send to a disabled endpoint. Deleting an endpoint retains history, but makes retry impossible.
Practical workflows
Transfer private-message events to a CRM
Select spampm and message.sent, message.failed, lead.replyreceived. For a compatible Deskgram channel, use standard JSON and the channel secret.
Send one message to your own test account, reply to it, and check both deliveries and both records at the receiver. This tests real events separately from a connectivity test.
Run automation after a task finishes
Select task.completed and the required module. Send standard JSON or a short result. Add task.failed and task.cancelled if the workflow should also handle unsuccessful or stopped runs.
Receive events in your own application
Provide an incoming URL, agree field names, set a secret and save. The application should accept POST JSON, verify the signature and return 2xx after reliably storing or queuing the event. Perform lengthy processing separately.
Full HTTP details and HMAC verification are in the developer reference.
Troubleshooting
| Symptom | Check |
|---|---|
| No new records during messaging | Saved/enabled endpoint, message event selection, spam_pm filter, refreshed history |
| Only final task event arrives | Add message events instead of relying only on task.completed |
| No lead reply | Active reply handler actually received it; lead.reply_received selected |
| Test unavailable | New endpoint not yet saved, or another test is running |
| HTTP 401/403 | Channel secret, Authorization and receiver permissions |
| HTTP 404 | Complete incoming path and channel ID |
| HTTP 301/302 | Final URL without redirects |
| Receiver HTTP 400/422 | Compare sent JSON and response with receiver requirements |
| Success but no lead | CRM response; test/task events may lack lead-creation data |
| Empty JSON | No enabled fields or selected sources absent in this event |
| Old format arrives | Unsaved settings, or old delivery lacks source_payload |
| Connection failure/timeout | Reachability from this computer, DNS, certificate, network and timeout |
| Retry unavailable | Status not error, endpoint deleted, or retry already running |
| Agent rejects localhost/HTTP | MCP-managed endpoints require public HTTPS |
Managing webhooks through an AI agent
Separate MCP tools can manage webhooks when the user enables permission in Settings → MCP. They differ from ordinary interface and REST operations:
- Creation defaults to dry-run; a new endpoint defaults to disabled.
- A public HTTPS URL is required. Localhost, LAN and HTTP are unsupported.
- Creating, editing, enabling, testing or retrying through an applicable real MCP action retains protected network rules for future sends.
- Ordinary interface edits or turning MCP off do not remove those rules.
- Read tools do not expose saved secrets, header values or full delivery bodies to the agent.
Reading, dry-run, disabling and deletion have separate rules and do not by themselves put an old endpoint under the new policy. Connection setup is covered in the MCP overview.
Limitations
- These are outbound event notifications, not a way to remotely launch arbitrary Deskgram actions or receive a permanent CRM command channel.
- Database history is not a durable automatic queue: delivery interrupted by closing the program does not automatically resume after restart.
- Only POST JSON is configurable, not GET, multipart or arbitrary text bodies.
- Delivery is not guaranteed exactly once or in order across different events.
- Task results depend on the module. Receivers should handle missing fields.
- Payloads can contain contacts, message text, task parameters and results. Choose the receiver and fields knowing those values leave the program.