diff --git a/.env.example b/.env.example
index 02eca6123..42547ffc6 100644
--- a/.env.example
+++ b/.env.example
@@ -173,6 +173,16 @@ WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
 WEBHOOK_EVENTS_ERRORS=false
 WEBHOOK_EVENTS_ERRORS_WEBHOOK=
 
+# Webhook timeout and retry configuration
+WEBHOOK_REQUEST_TIMEOUT_MS=60000 
+WEBHOOK_RETRY_MAX_ATTEMPTS=10
+WEBHOOK_RETRY_INITIAL_DELAY_SECONDS=5
+WEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF=true
+WEBHOOK_RETRY_MAX_DELAY_SECONDS=300
+WEBHOOK_RETRY_JITTER_FACTOR=0.2
+# Comma separated list of HTTP status codes that should not trigger retries
+WEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES=400,401,403,404,422
+
 # Name that will be displayed on smartphone connection
 CONFIG_SESSION_PHONE_CLIENT=Evolution API
 # Browser Name = Chrome | Firefox | Edge | Opera | Safari
diff --git a/src/api/integrations/event/webhook/webhook.controller.ts b/src/api/integrations/event/webhook/webhook.controller.ts
index ce709c3d4..49d858240 100644
--- a/src/api/integrations/event/webhook/webhook.controller.ts
+++ b/src/api/integrations/event/webhook/webhook.controller.ts
@@ -115,6 +115,7 @@ export class WebhookController extends EventController implements EventControlle
             const httpService = axios.create({
               baseURL,
               headers: webhookHeaders as Record<string, string> | undefined,
+              timeout: webhookConfig.REQUEST?.TIMEOUT_MS ?? 30000,
             });
 
             await this.retryWebhookRequest(httpService, webhookData, `${origin}.sendData-Webhook`, baseURL, serverUrl);
@@ -156,7 +157,10 @@ export class WebhookController extends EventController implements EventControlle
 
         try {
           if (isURL(globalURL)) {
-            const httpService = axios.create({ baseURL: globalURL });
+            const httpService = axios.create({
+              baseURL: globalURL,
+              timeout: webhookConfig.REQUEST?.TIMEOUT_MS ?? 30000,
+            });
 
             await this.retryWebhookRequest(
               httpService,
@@ -190,12 +194,21 @@ export class WebhookController extends EventController implements EventControlle
     origin: string,
     baseURL: string,
     serverUrl: string,
-    maxRetries = 10,
-    delaySeconds = 30,
+    maxRetries?: number,
+    delaySeconds?: number,
   ): Promise<void> {
+    // Obter configurações de retry das variáveis de ambiente
+    const webhookConfig = configService.get<Webhook>('WEBHOOK');
+    const maxRetryAttempts = maxRetries ?? webhookConfig.RETRY?.MAX_ATTEMPTS ?? 10;
+    const initialDelay = delaySeconds ?? webhookConfig.RETRY?.INITIAL_DELAY_SECONDS ?? 5;
+    const useExponentialBackoff = webhookConfig.RETRY?.USE_EXPONENTIAL_BACKOFF ?? true;
+    const maxDelay = webhookConfig.RETRY?.MAX_DELAY_SECONDS ?? 300;
+    const jitterFactor = webhookConfig.RETRY?.JITTER_FACTOR ?? 0.2;
+    const nonRetryableStatusCodes = webhookConfig.RETRY?.NON_RETRYABLE_STATUS_CODES ?? [400, 401, 403, 404, 422];
+
     let attempts = 0;
 
-    while (attempts < maxRetries) {
+    while (attempts < maxRetryAttempts) {
       try {
         await httpService.post('', webhookData);
         if (attempts > 0) {
@@ -209,12 +222,29 @@ export class WebhookController extends EventController implements EventControlle
       } catch (error) {
         attempts++;
 
+        // Verificar se é um erro de timeout
+        const isTimeout = error.code === 'ECONNABORTED';
+
+        // Verificar se o erro não deve gerar retry com base no status code
+        if (error?.response?.status && nonRetryableStatusCodes.includes(error.response.status)) {
+          this.logger.error({
+            local: `${origin}`,
+            message: `Erro não recuperável (${error.response.status}): ${error?.message}. Cancelando retentativas.`,
+            statusCode: error?.response?.status,
+            url: baseURL,
+            server_url: serverUrl,
+          });
+          throw error;
+        }
+
         this.logger.error({
           local: `${origin}`,
-          message: `Tentativa ${attempts}/${maxRetries} falhou: ${error?.message}`,
+          message: `Tentativa ${attempts}/${maxRetryAttempts} falhou: ${isTimeout ? 'Timeout da requisição' : error?.message}`,
           hostName: error?.hostname,
           syscall: error?.syscall,
           code: error?.code,
+          isTimeout,
+          statusCode: error?.response?.status,
           error: error?.errno,
           stack: error?.stack,
           name: error?.name,
@@ -222,11 +252,28 @@ export class WebhookController extends EventController implements EventControlle
           server_url: serverUrl,
         });
 
-        if (attempts === maxRetries) {
+        if (attempts === maxRetryAttempts) {
           throw error;
         }
 
-        await new Promise((resolve) => setTimeout(resolve, delaySeconds * 1000));
+        // Cálculo do delay com backoff exponencial e jitter
+        let nextDelay = initialDelay;
+        if (useExponentialBackoff) {
+          // Fórmula: initialDelay * (2^attempts) com limite máximo
+          nextDelay = Math.min(initialDelay * Math.pow(2, attempts - 1), maxDelay);
+
+          // Adicionar jitter para evitar "thundering herd"
+          const jitter = nextDelay * jitterFactor * (Math.random() * 2 - 1);
+          nextDelay = Math.max(initialDelay, nextDelay + jitter);
+        }
+
+        this.logger.log({
+          local: `${origin}`,
+          message: `Aguardando ${nextDelay.toFixed(1)} segundos antes da próxima tentativa`,
+          url: baseURL,
+        });
+
+        await new Promise((resolve) => setTimeout(resolve, nextDelay * 1000));
       }
     }
   }
diff --git a/src/config/env.config.ts b/src/config/env.config.ts
index 78ca891cd..7e58d50d1 100644
--- a/src/config/env.config.ts
+++ b/src/config/env.config.ts
@@ -220,7 +220,21 @@ export type CacheConfLocal = {
   TTL: number;
 };
 export type SslConf = { PRIVKEY: string; FULLCHAIN: string };
-export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook };
+export type Webhook = {
+  GLOBAL?: GlobalWebhook;
+  EVENTS: EventsWebhook;
+  REQUEST?: {
+    TIMEOUT_MS?: number;
+  };
+  RETRY?: {
+    MAX_ATTEMPTS?: number;
+    INITIAL_DELAY_SECONDS?: number;
+    USE_EXPONENTIAL_BACKOFF?: boolean;
+    MAX_DELAY_SECONDS?: number;
+    JITTER_FACTOR?: number;
+    NON_RETRYABLE_STATUS_CODES?: number[];
+  };
+};
 export type Pusher = { ENABLED: boolean; GLOBAL?: GlobalPusher; EVENTS: EventsPusher };
 export type ConfigSessionPhone = { CLIENT: string; NAME: string; VERSION: string };
 export type QrCode = { LIMIT: number; COLOR: string };
@@ -497,6 +511,19 @@ export class ConfigService {
           ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true',
           ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '',
         },
+        REQUEST: {
+          TIMEOUT_MS: Number.parseInt(process.env?.WEBHOOK_REQUEST_TIMEOUT_MS) || 30000,
+        },
+        RETRY: {
+          MAX_ATTEMPTS: Number.parseInt(process.env?.WEBHOOK_RETRY_MAX_ATTEMPTS) || 10,
+          INITIAL_DELAY_SECONDS: Number.parseInt(process.env?.WEBHOOK_RETRY_INITIAL_DELAY_SECONDS) || 5,
+          USE_EXPONENTIAL_BACKOFF: process.env?.WEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF !== 'false',
+          MAX_DELAY_SECONDS: Number.parseInt(process.env?.WEBHOOK_RETRY_MAX_DELAY_SECONDS) || 300,
+          JITTER_FACTOR: Number.parseFloat(process.env?.WEBHOOK_RETRY_JITTER_FACTOR) || 0.2,
+          NON_RETRYABLE_STATUS_CODES: process.env?.WEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES?.split(',').map(Number) || [
+            400, 401, 403, 404, 422,
+          ],
+        },
       },
       CONFIG_SESSION_PHONE: {
         CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API',