", "receivedAt": "2026-04-04T09:21:35.218Z", "from": { "email": "john@gmail.com", "name": "John Snow" }, "to": [ { "email": "r_abcd1234@hook.echovalue.dev", "name": "Support Inbox" } ], "cc": [{ "email": "jane@gmail.com", "name": "Jane Doe" }], "subject": "Alert: Server down", "text": "Server #3 is not responding", "html": "Server #3 is not responding
", "headers": {}, "attachments": [], "provider": "mail", "url": "https://hook.echovalue.dev/r_abcd1234", "raw": { "messageId": "" } } ``` ## Fields [Section titled “Fields”](#fields) | Field | Type | Description | | ------------------- | ----------------- | -------------------------------------------------------- | | `externalMessageId` | string | Unique identifier for the email message | | `receivedAt` | string (ISO 8601) | When the email was received | | `from` | object | Sender: `email` and optional `name` | | `to` | array | Recipient list from the inbound email source | | `cc` | array | CC recipients: each item has `email` and optional `name` | | `subject` | string | Email subject line | | `text` | string | Plain text body | | `html` | string | HTML body (if present) | | `headers` | object | Raw email headers as key-value pairs | | `attachments` | array | Attachment metadata when available | | `url` | string | Mailbox URL when available | | `provider` | string | Inbound source identifier when available | | `raw` | object | Raw inbound payload details when available | The exact attachment object is source-dependent and may include additional fields. Caution Inbound email payloads are limited to 1 MiB after parsing, so large emails or attachment-heavy messages may be rejected or stripped before delivery depending on message size and the `includeAttachments` setting. ## Scheduled Webhook Payload [Section titled “Scheduled Webhook Payload”](#scheduled-webhook-payload) When a webhook is triggered by `schedule`, echoValue sends a scheduled-run payload instead of the inbound email payload: ```json { "type": "scheduled_webhook_run", "webhookId": "daily-sync", "scheduledFor": "2026-04-22T12:05:00Z", "executedAt": "2026-04-22T12:05:01Z", "walletHash": "a1b2c3d4e5f6..." } ``` | Field | Type | Description | | -------------- | ----------------- | ---------------------------------- | | `type` | string | Always `scheduled_webhook_run` | | `webhookId` | string | Public webhook identifier | | `scheduledFor` | string (ISO 8601) | Time this run was scheduled for | | `executedAt` | string (ISO 8601) | Time the webhook call actually ran | | `walletHash` | string | SHA256 hash of your token |
# Test Webhook
> Send a dummy payload to your configured webhook to verify it's working
`POST https://api.echovalue.dev/webhook//test` Sends a dummy payload to the specified webhook URL to verify it is working correctly. ## Request [Section titled “Request”](#request) **Headers:** | Header | Description | | --------- | -------------- | | `x-token` | Your API token | **Path parameters:** | Parameter | Type | Description | Required | | ----------- | ------ | --------------------------------- | -------- | | `webhookId` | string | Public webhook identifier to test | Yes | ## Notes [Section titled “Notes”](#notes) * Inbound email webhook: a dummy inbound email payload is sent. * Scheduled webhook: a dummy scheduled-run payload is sent. * The call reports delivery success or failure in the JSON body. ```sh curl 'https://api.echovalue.dev/webhook/slack/test' \ -H 'x-token: mytoken' \ -X POST ``` ## Response [Section titled “Response”](#response) `200 OK` — JSON object. ```json { "success": true, "message": "test webhook delivered" } ``` On failure: ```json { "success": false, "message": "webhook call failed: context deadline exceeded (Client.Timeout exceeded while awaiting headers)" } ``` | Field | Type | Description | | --------- | ------- | --------------------------------------------------- | | `success` | boolean | Whether the test webhook was successfully delivered | | `message` | string | Confirmation or error message | **Response headers:** | Header | Description | | ----------- | ------------------------------ | | `x-balance` | Wallet balance after this call | | `x-cost` | Credits consumed | See [Response Headers](/response-headers/) for details. ## Status Codes [Section titled “Status Codes”](#status-codes) | Status | Meaning | | ------ | -------------------- | | `200` | Test call processed | | `401` | Invalid token | | `402` | Insufficient credits | | `405` | Method not POST |
# Update Webhook
> Replace or patch an inbound email webhook or a scheduled webhook
`PUT https://api.echovalue.dev/webhook/` Replaces the full webhook document for the specified `webhookId`. `url` is required. `PATCH https://api.echovalue.dev/webhook/` Updates only the fields you provide. `webhookId` is a path parameter and is not allowed in the request body. ## Headers [Section titled “Headers”](#headers) | Header | Description | | -------------- | -------------------------- | | `x-token` | Your API token | | `Content-Type` | Must be `application/json` | ## Request [Section titled “Request”](#request) ## Replace With `PUT` [Section titled “Replace With PUT”](#replace-with-put) Use `PUT` when you want to send the full new configuration. ### Inbound Email Webhook [Section titled “Inbound Email Webhook”](#inbound-email-webhook) Replace the webhook with mailbox mode by sending mailbox-only fields and omitting `schedule`. ```json { "url": "https://hooks.slack.com/services/XXX/YYY/ZZZ", "format": "slack", "includeAttachments": false } ``` ### Scheduled Webhook [Section titled “Scheduled Webhook”](#scheduled-webhook) Replace the webhook with scheduled mode by sending `schedule` and omitting mailbox-only fields. ```json { "url": "https://example.com/hooks/daily-sync", "schedule": { "cron": "0 9 * * *", "timezone": "Europe/Rome", "active": true } } ``` ## Patch With `PATCH` [Section titled “Patch With PATCH”](#patch-with-patch) Use `PATCH` when you want to update only part of the configuration. ### Patch semantics [Section titled “Patch semantics”](#patch-semantics) | Field | Behavior | | -------------------- | ----------------------------------------------------------------------------------------------------- | | `url` | Replaced when provided | | `headers` | Replaces the full headers object. Use `{}` to clear it. | | `format` | Mailbox-only field. Replaced when provided. | | `template` | Mailbox-only field. Replaces the template. Use `null` to remove it. | | `options` | Mailbox-only field. Replaces the full options object. Use `{}` to clear it. | | `includeAttachments` | Mailbox-only field. Replaced when provided. | | `schedule` | Scheduled field. Updates only the provided schedule fields. Use `null` to remove scheduling entirely. | ### Patch an inbound email webhook [Section titled “Patch an inbound email webhook”](#patch-an-inbound-email-webhook) ```json { "headers": { "X-Source": "support-inbox" }, "includeAttachments": false } ``` ### Patch a scheduled webhook [Section titled “Patch a scheduled webhook”](#patch-a-scheduled-webhook) ```json { "schedule": { "active": false } } ``` ## Mode Rules [Section titled “Mode Rules”](#mode-rules) * Inbound email mode uses `format`, `template`, `options`, and `includeAttachments`. * Scheduled mode uses `schedule`. * Do not send mailbox-only fields together with a non-null `schedule` object in the same request. * Set `schedule: null` in `PATCH` to switch a scheduled webhook back to mailbox mode. Caution For scheduled webhooks, the next run must be within 30 days from the update and the interval between runs must never exceed 30 days. ## Response [Section titled “Response”](#response) Response body and response headers are the same as [Create Webhook](/webhook/create/). ## Notes [Section titled “Notes”](#notes) * Use `PUT` when you want to replace the full document. * Use `PATCH` when you want to update only specific fields. * `headers`, `options`, and `template` replace the full value when provided. ## Status Codes [Section titled “Status Codes”](#status-codes) | Status | Meaning | | ------ | ------------------------------------------------------------ | | `200` | Webhook updated | | `400` | Invalid URL, invalid field combination, or malformed request | | `401` | Invalid token | | `402` | Insufficient credits | | `404` | Webhook not found | | `500` | Internal server error | Caution Localhost and private IP addresses are not accepted.