diff --git a/CHANGELOG.md b/CHANGELOG.md
index 75bf51d..d432f3b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+0.3.0
+==
+17 March 2024
+
+**Added:**
+* Webhooks support
+
+**Fixed:** 
+ * Export to Excel/CSV
+
 0.2.3
 ==
 27 Frb 2024
diff --git a/README.md b/README.md
index 2b6b2e4..0fab605 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# PHPForm - Lightweight Headless Form Builder and API
+# PHPForm - Open Source Headless Form Management Server
 
 Welcome to PHPForm, a fully open-source, headless form builder designed with simplicity, efficiency, and privacy in mind. 
 Built to be easily installed on any budget-friendly hosting solution or free cloud tiers, PHPForm is the perfect choice for 
 developers and businesses looking for a reliable and GDPR-compliant form management solution.
 
-<img src="./public/images/screen.png" width="100%">
+<img src="./public/images/screen.png" width="100%" alt="Screenshot">
 
 # Features
 
diff --git a/composer.json b/composer.json
index 754b181..bd87dfe 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,19 @@
 {
     "type": "project",
-    "license": "proprietary",
+    "name": "phpform-dev/phpform-server",
+    "description": "PHPForm - Open Source Headless Form Management Server",
+    "keywords": [
+        "phpform",
+        "form",
+        "server",
+        "headless",
+        "api",
+        "symfony",
+        "php"
+    ],
+    "homepage": "http://phpform.dev",
+    "license": "MIT",
+    "version": "0.3.0",
     "minimum-stability": "stable",
     "prefer-stable": true,
     "require": {
@@ -13,6 +26,7 @@
         "doctrine/doctrine-bundle": "^2.11",
         "doctrine/doctrine-migrations-bundle": "^3.3",
         "doctrine/orm": "^2.17",
+        "guzzlehttp/guzzle": "^7.0",
         "minishlink/web-push": "^8.0",
         "phpoffice/phpspreadsheet": "^1.29",
         "symfony/console": "7.0.*",
diff --git a/composer.lock b/composer.lock
index b267398..8929a39 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "5f0219bf9dab6d3e786bd5e6e4733198",
+    "content-hash": "2a82a505ffa984c64e2cc23ff3d0c295",
     "packages": [
         {
             "name": "brick/math",
diff --git a/src/Admin/Controller/FormWebhooksController.php b/src/Admin/Controller/FormWebhooksController.php
new file mode 100644
index 0000000..12990f6
--- /dev/null
+++ b/src/Admin/Controller/FormWebhooksController.php
@@ -0,0 +1,63 @@
+<?php
+namespace App\Admin\Controller;
+
+use App\Admin\Form\FormWebhookType;
+use App\Entity\Form;
+use App\Entity\FormWebhook;
+use App\Service\FormMenuCounterService;
+use App\Service\FormWebhookService;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class FormWebhooksController extends AbstractController
+{
+    public function __construct(
+        private readonly FormMenuCounterService $formMenuCounterService,
+        private readonly FormWebhookService $formWebhookService,
+    )
+    {
+    }
+
+    #[Route('/admin/forms/{id}/webhooks', name: 'admin_forms_webhooks', methods: ['GET', 'POST'])]
+    public function index(Request $request, Form $formEntity): Response
+    {
+        $form = $this->createForm(FormWebhookType::class, new FormWebhook());
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $webhook = $form->getData();
+            $webhook->setForm($formEntity);
+            $this->formWebhookService->save($webhook);
+
+            $this->addFlash('primary', 'Webhook added successfully.');
+
+            return $this->redirectToRoute('admin_forms_webhooks', ['id' => $formEntity->getId()]);
+        }
+
+        $webhooks = $this->formWebhookService->getAllByFormId($formEntity->getId());
+
+        return $this->render('@Admin/form-webhooks/index.html.twig', [
+            'formEntity' => $formEntity,
+            'form' => $form->createView(),
+            'menuCounts' => $this->formMenuCounterService->getAllCountsByFormId($formEntity->getId()),
+            'webhooks' => $webhooks,
+        ]);
+    }
+
+    #[Route('/admin/forms/{formId}/webhooks/{webhookId}/delete', name: 'admin_forms_webhook_delete', methods: ['GET'])]
+    public function delete(int $formId, int $webhookId): Response
+    {
+        $webhook = $this->formWebhookService->getOneByIdAndFormId($webhookId, $formId);
+        if (!$webhook) {
+            throw $this->createNotFoundException('Webhook not found.');
+        }
+
+        $this->formWebhookService->delete($webhook);
+
+        $this->addFlash('primary', 'Webhook deleted successfully.');
+
+        return $this->redirectToRoute('admin_forms_webhooks', ['id' => $formId]);
+    }
+}
\ No newline at end of file
diff --git a/src/Admin/Form/FormWebhookHeaderType.php b/src/Admin/Form/FormWebhookHeaderType.php
new file mode 100644
index 0000000..6445b1f
--- /dev/null
+++ b/src/Admin/Form/FormWebhookHeaderType.php
@@ -0,0 +1,31 @@
+<?php
+namespace App\Admin\Form;
+
+use App\Entity\FormWebhookHeader;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class FormWebhookHeaderType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options): void
+    {
+        $builder
+            ->add('name', TextType::class, [
+                'label' => 'Header Name',
+                'attr' => ['placeholder' => 'Content-Type'],
+            ])
+            ->add('value', TextType::class, [
+                'label' => 'Header Value',
+                'attr' => ['placeholder' => 'application/json'],
+            ]);
+    }
+
+    public function configureOptions(OptionsResolver $resolver): void
+    {
+        $resolver->setDefaults([
+            'data_class' => FormWebhookHeader::class,
+        ]);
+    }
+}
diff --git a/src/Admin/Form/FormWebhookType.php b/src/Admin/Form/FormWebhookType.php
new file mode 100644
index 0000000..cfc9060
--- /dev/null
+++ b/src/Admin/Form/FormWebhookType.php
@@ -0,0 +1,41 @@
+<?php
+namespace App\Admin\Form;
+
+use App\Entity\FormWebhookHeader;
+use App\Entity\FormWebhook;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\CollectionType;
+use Symfony\Component\Form\Extension\Core\Type\UrlType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class FormWebhookType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options): void
+    {
+        $builder
+            ->add('url', UrlType::class, [
+                'label' => 'Webhook URL',
+                'attr' => ['placeholder' => 'https://example.com/webhook'],
+            ])
+            ->add('headers', CollectionType::class, [
+                'entry_type' => FormWebhookHeaderType::class,
+                'entry_options' => ['label' => false],
+                'allow_add' => true,
+                'allow_delete' => true,
+                'by_reference' => false,
+                'label' => false,
+                'prototype' => true,
+                'attr' => [
+                    'class' => 'header-collection',
+                ],
+            ]);
+    }
+
+    public function configureOptions(OptionsResolver $resolver): void
+    {
+        $resolver->setDefaults([
+            'data_class' => FormWebhook::class,
+        ]);
+    }
+}
diff --git a/src/Admin/Resources/templates/form-webhooks/index.html.twig b/src/Admin/Resources/templates/form-webhooks/index.html.twig
new file mode 100644
index 0000000..47b9abf
--- /dev/null
+++ b/src/Admin/Resources/templates/form-webhooks/index.html.twig
@@ -0,0 +1,99 @@
+{% extends '@Admin/forms/page.html.twig' %}
+
+{% block title %}Webhooks / {{ formEntity.name }} / Forms{% endblock %}
+
+{% block section %}
+    {% if webhooks|length > 0  %}
+        <div>
+            {% for webhook in webhooks %}
+                <div class="box">
+                    <h6 class="has-text-weight-bold">URL:</h6>
+                    <div>
+                        {{ webhook.url }}
+                    </div>
+                    {% if webhook.headers|length > 0 %}
+                        <div class="mt-2">
+                            <h6 class="has-text-weight-bold mb-2">Headers:</h6>
+                            <div>
+                                {% for header in webhook.headers %}
+                                    <div class="mb-2">
+                                        <span class="tag is-light">
+                                            <strong>{{ header.name }}:</strong> {{ header.value }}
+                                        </span>
+                                    </div>
+                                {% endfor %}
+                            </div>
+                        </div>
+                    {% endif %}
+                    <div class="mt-3">
+                        <a class="tag is-rounded py-2 has-background-danger-light hoverable" href="{{ path('admin_forms_webhook_delete', { formId: formEntity.id, webhookId: webhook.id }) }}" title="Delete">
+                            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="width:16px; height: 16px;"><title/><path d="M21,6a1,1,0,0,1-1,1H4A1,1,0,0,1,4,5H9V4.5A1.5,1.5,0,0,1,10.5,3h3A1.5,1.5,0,0,1,15,4.5V5h5A1,1,0,0,1,21,6Z" fill="#464646"/><path d="M5.5,9v9.5A2.5,2.5,0,0,0,8,21h8a2.5,2.5,0,0,0,2.5-2.5V9ZM11,17a1,1,0,0,1-2,0V13a1,1,0,0,1,2,0Zm4,0a1,1,0,0,1-2,0V13a1,1,0,0,1,2,0Z" fill="#464646"/></svg>
+                        </a>
+                    </div>
+                </div>
+            {% endfor %}
+        </div>
+    {% endif %}
+    <div class="card mt-4" x-data="webhookForm()">
+        <header class="card-header">
+            <p class="card-header-title">
+                Add new Webhook
+            </p>
+        </header>
+        <div class="card-content">
+            <div class="content">
+                {{ form_start(form, {'attr': {'class': 'form'}}) }}
+                    <div class="field">
+                        {{ form_label(form.url, null, {'label_attr': {'class': 'label'}}) }}
+                        <div class="control">
+                            {{ form_widget(form.url, {'attr': {'class': 'input', 'placeholder': 'Webhook URL'}}) }}
+                        </div>
+                        {{ form_errors(form.url, {'attr': {'class': 'help is-danger'}}) }}
+                    </div>
+
+                    <div class="is-flex is-align-items-center is-justify-content-space-between mb-2">
+                        <h5>Headers</h5>
+                        <button type="button" class="button is-primary is-inverted" @click="addHeader()">Add Header</button>
+                    </div>
+
+                    <template x-for="(header, index) in headers" :key="index">
+                        <div class="mb-2 is-flex is-align-items-center">
+                            <div class="mr-3">
+                                <input type="text" :name="'form_webhook[headers][' + index + '][name]'" x-model="header.name" class="input" placeholder="Header Name" required minlength="1" maxlength="100">
+                            </div>
+                            <div class="mr-3">
+                                <input type="text" :name="'form_webhook[headers][' + index + '][value]'" x-model="header.value" class="input" placeholder="Header Value" required minlength="1" maxlength="255">
+                            </div>
+                            <div>
+                                <button type="button" class="button is-danger is-inverted" @click="removeHeader(index)">Remove</button>
+                            </div>
+                        </div>
+                    </template>
+
+                    <div class="field is-grouped mt-4">
+                        <div class="control">
+                            <button type="submit" class="button is-primary">Add Webhook</button>
+                        </div>
+                    </div>
+                {{ form_end(form) }}
+            </div>
+        </div>
+    </div>
+
+    <script>
+        function webhookForm() {
+            return {
+                headers: [{
+                    name: '',
+                    value: ''
+                }],
+                addHeader() {
+                    this.headers.push({ name: '', value: '' });
+                },
+                removeHeader(index) {
+                    this.headers.splice(index, 1);
+                }
+            };
+        }
+    </script>
+{% endblock %}
diff --git a/src/Admin/Resources/templates/forms/page.html.twig b/src/Admin/Resources/templates/forms/page.html.twig
index a6f8f3a..afe5c52 100644
--- a/src/Admin/Resources/templates/forms/page.html.twig
+++ b/src/Admin/Resources/templates/forms/page.html.twig
@@ -49,6 +49,28 @@
                     Settings
                 </p>
                 <ul class="menu-list">
+                    {% if app.user.isSuperUser %}
+                        <li>
+                            <a
+                                    {% if current_path == 'admin_forms_edit' %}
+                                        class="is-active"
+                                    {% endif %}
+                                    href="{{ path('admin_forms_edit', {'id': formEntity.id}) }}"
+                            >
+                                General
+                            </a>
+                        </li>
+                        <li>
+                            <a
+                                    {% if current_path starts with 'admin_forms_fields' %}
+                                        class="is-active"
+                                    {% endif %}
+                                    href="{{ path('admin_forms_fields', {'id': formEntity.id}) }}"
+                            >
+                                Fields ({{ menuCounts.fields }})
+                            </a>
+                        </li>
+                    {% endif %}
                     <li>
                         <a
                             {% if current_path == 'admin_forms_info' %}
@@ -70,16 +92,6 @@
                         </a>
                     </li>
                     {% if app.user.isSuperUser %}
-                        <li>
-                            <a
-                                {% if current_path == 'admin_forms_edit' %}
-                                    class="is-active"
-                                {% endif %}
-                                href="{{ path('admin_forms_edit', {'id': formEntity.id}) }}"
-                            >
-                                Edit
-                            </a>
-                        </li>
                         <li>
                             <a
                                 {% if current_path == 'admin_forms_captcha' %}
@@ -102,12 +114,12 @@
                         </li>
                         <li>
                             <a
-                                {% if current_path starts with 'admin_forms_fields' %}
-                                    class="is-active"
-                                {% endif %}
-                                href="{{ path('admin_forms_fields', {'id': formEntity.id}) }}"
+                                    {% if current_path == 'admin_forms_webhooks' %}
+                                        class="is-active"
+                                    {% endif %}
+                                    href="{{ path('admin_forms_webhooks', {'id': formEntity.id}) }}"
                             >
-                                Fields ({{ menuCounts.fields }})
+                                Webhooks ({{ menuCounts.webhooks }})
                             </a>
                         </li>
                         <li>
diff --git a/src/Entity/Form.php b/src/Entity/Form.php
index b234ac8..d0b68aa 100644
--- a/src/Entity/Form.php
+++ b/src/Entity/Form.php
@@ -44,6 +44,9 @@ class Form implements JsonSerializable
     #[ORM\OneToMany(mappedBy: 'form_id', targetEntity: FormField::class, orphanRemoval: true)]
     private Collection $fields;
 
+    #[ORM\OneToMany(mappedBy: 'form_id', targetEntity: FormWebhook::class, orphanRemoval: true)]
+    private Collection $webhooks;
+
     /**
      * @deprecated version 0.2.2 Use captcha_token instead
      */
@@ -169,28 +172,6 @@ public function getFields(): Collection
         return $this->fields;
     }
 
-    public function addField(FormField $field): static
-    {
-        if (!$this->fields->contains($field)) {
-            $this->fields->add($field);
-            $field->setForm($this);
-        }
-
-        return $this;
-    }
-
-    public function removeField(FormField $field): static
-    {
-        if ($this->fields->removeElement($field)) {
-            // set the owning side to null (unless already changed)
-            if ($field->getForm() === $this) {
-                $field->setForm(null);
-            }
-        }
-
-        return $this;
-    }
-
     /**
      * @deprecated version 0.2.2 Use getCaptchaToken instead
      */
@@ -271,6 +252,11 @@ public function isTokenEnabled(): bool
         return $this->getSecret() !== null && strlen($this->getSecret()) > 0;
     }
 
+    public function getWebhooks(): Collection
+    {
+        return $this->webhooks;
+    }
+
     private function generateHash(): string
     {
         return md5(uniqid((string) rand(), true));
diff --git a/src/Entity/FormWebhook.php b/src/Entity/FormWebhook.php
new file mode 100644
index 0000000..2c70189
--- /dev/null
+++ b/src/Entity/FormWebhook.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\FormWebhookRepository;
+use Doctrine\ORM\Mapping as ORM;
+use JsonSerializable;
+use Symfony\Component\Validator\Constraints as Assert;
+
+#[ORM\Entity(repositoryClass: FormWebhookRepository::class)]
+#[ORM\Table(name: 'form_webhooks')]
+#[ORM\Index(columns: ['form_id'], name: 'form_webhooks_form_id_idx')]
+class FormWebhook implements JsonSerializable
+{
+    #[ORM\Id]
+    #[ORM\GeneratedValue]
+    #[ORM\Column]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'webhooks')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?Form $form = null;
+
+    #[ORM\Column(length: 255)]
+    #[Assert\NotBlank]
+    #[Assert\Length(min: 1, max: 255)]
+    private ?string $url = null;
+
+    /**
+     * @var FormWebhookHeader[]|null $headers
+     */
+    #[ORM\Column(type: 'json', nullable: true)]
+    #[Assert\All(constraints: [
+        new Assert\Collection(
+            fields: [
+                'name' => [new Assert\NotBlank(), new Assert\Length(min: 1, max: 255)],
+                'value' => [new Assert\NotBlank(), new Assert\Length(min: 1, max: 255)],
+            ]
+        )
+    ])]
+    private ?array $headers = null;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getForm(): ?Form
+    {
+        return $this->form;
+    }
+
+    public function setForm(?Form $form): static
+    {
+        $this->form = $form;
+
+        return $this;
+    }
+
+    public function getUrl(): ?string
+    {
+        return $this->url;
+    }
+
+    public function setUrl(?string $url): static
+    {
+        $this->url = $url;
+
+        return $this;
+    }
+
+    /**
+     * @return FormWebhookHeader[]|null
+     */
+    public function getHeaders(): ?array
+    {
+        return array_map(fn(array $header) => (new FormWebhookHeader())->setName($header['name'])->setValue($header['value']), $this->headers ?? []);
+    }
+
+    /**
+     * @param FormWebhookHeader[]|null $headers
+     */
+
+    public function setHeaders(?array $headers): static
+    {
+        $this->headers = array_map(fn(FormWebhookHeader $header) => $header->jsonSerialize(), $headers);
+
+        return $this;
+    }
+
+    public function jsonSerialize(): array
+    {
+        return [
+            'id' => $this->id,
+            'url' => $this->url,
+            'headers' => array_map(fn(FormWebhookHeader $header) => $header->jsonSerialize(), $this->headers ?? []),
+        ];
+    }
+}
\ No newline at end of file
diff --git a/src/Entity/FormWebhookHeader.php b/src/Entity/FormWebhookHeader.php
new file mode 100644
index 0000000..90eac91
--- /dev/null
+++ b/src/Entity/FormWebhookHeader.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Entity;
+
+use JsonSerializable;
+use Symfony\Component\Validator\Constraints as Assert;
+
+class FormWebhookHeader implements JsonSerializable
+{
+    #[Assert\NotBlank]
+    #[Assert\Length(min: 1, max: 255)]
+    private string $name;
+
+    #[Assert\NotBlank]
+    #[Assert\Length(min: 1, max: 255)]
+    private string $value;
+
+    public function getName(): string
+    {
+        return $this->name;
+    }
+
+    public function setName(string $name): static
+    {
+        $this->name = $name;
+
+        return $this;
+    }
+
+    public function getValue(): string
+    {
+        return $this->value;
+    }
+
+    public function setValue(string $value): static
+    {
+        $this->value = $value;
+
+        return $this;
+    }
+
+    public function jsonSerialize(): array
+    {
+        return [
+            'name' => $this->name,
+            'value' => $this->value,
+        ];
+    }
+}
\ No newline at end of file
diff --git a/src/EventSubscriber/SubmissionSubscriber.php b/src/EventSubscriber/SubmissionSubscriber.php
index c7385a8..629f8c7 100644
--- a/src/EventSubscriber/SubmissionSubscriber.php
+++ b/src/EventSubscriber/SubmissionSubscriber.php
@@ -3,12 +3,14 @@
 
 use App\Event\NewSubmissionEvent;
 use App\Service\FormNotificationService;
+use App\Service\FormWebhookService;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 class SubmissionSubscriber implements EventSubscriberInterface
 {
     public function __construct(
         private readonly FormNotificationService $formNotificationService,
+        private readonly FormWebhookService $formWebhookService,
     )
     {
     }
@@ -23,6 +25,8 @@ public static function getSubscribedEvents(): array
     public function onNewSubmission(NewSubmissionEvent $event): void
     {
         $submission = $event->getSubmission();
-        $this->formNotificationService->sendAllByFormId($submission->getForm()->getId());
+        $form = $submission->getForm();
+        $this->formNotificationService->sendAllByFormId($form->getId());
+        $this->formWebhookService->callAllWebhooks($form, $submission);
     }
 }
diff --git a/src/Repository/FormWebhookRepository.php b/src/Repository/FormWebhookRepository.php
new file mode 100644
index 0000000..23dacf3
--- /dev/null
+++ b/src/Repository/FormWebhookRepository.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\FormWebhook;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @method FormWebhook|null find($id, $lockMode = null, $lockVersion = null)
+ * @method FormWebhook|null findOneBy(array $criteria, array $orderBy = null)
+ * @method FormWebhook[]    findAll()
+ * @method FormWebhook[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ */
+class FormWebhookRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, FormWebhook::class);
+    }
+
+    // Add custom repository methods here
+    public function findByFormId(int $formId): array
+    {
+        return $this->createQueryBuilder('w')
+            ->andWhere('w.form = :formId')
+            ->setParameter('formId', $formId)
+            ->getQuery()
+            ->getResult();
+    }
+
+    public function countByFormId(int $formId): int
+    {
+        return $this->createQueryBuilder('w')
+            ->select('count(w.id)')
+            ->andWhere('w.form = :formId')
+            ->setParameter('formId', $formId)
+            ->getQuery()
+            ->getSingleScalarResult();
+    }
+
+    public function save(FormWebhook $formWebhook): void
+    {
+        $this->_em->persist($formWebhook);
+        $this->_em->flush();
+    }
+
+    public function delete(FormWebhook $formWebhook): void
+    {
+        $this->_em->remove($formWebhook);
+        $this->_em->flush();
+    }
+}
diff --git a/src/Service/FormMenuCounterService.php b/src/Service/FormMenuCounterService.php
index 8134685..9ac92cb 100644
--- a/src/Service/FormMenuCounterService.php
+++ b/src/Service/FormMenuCounterService.php
@@ -5,6 +5,7 @@ class FormMenuCounterService {
     public function __construct(
         private readonly FormFieldService $formFieldService,
         private readonly FormSubmissionService $formSubmissionService,
+        private readonly FormWebhookService $formWebhookService,
     )
     {
     }
@@ -18,7 +19,8 @@ public function getAllCountsByFormId(int $formId): array
                 'new' => $this->getNewSubmissionCount($formId),
                 'flagged' => $this->getFlaggedSubmissionCount($formId),
                 'deleted' => $this->getDeletedSubmissionCount($formId),
-            ]
+            ],
+            'webhooks' => $this->formWebhookService->getCountByFormId($formId),
         ];
     }
 
diff --git a/src/Service/FormSubmissionService.php b/src/Service/FormSubmissionService.php
index daed301..481acea 100644
--- a/src/Service/FormSubmissionService.php
+++ b/src/Service/FormSubmissionService.php
@@ -1,6 +1,7 @@
 <?php
 namespace App\Service;
 
+use App\Entity\Submission;
 use App\Event\NewSubmissionEvent;
 use App\Repository\SubmissionRepository;
 use PhpOffice\PhpSpreadsheet\IOFactory;
@@ -140,11 +141,12 @@ public function export(int $id, string $status, string $type): IWriter
         $additionalHeaders = [];
 
         foreach ($submissions as $submission) {
-            foreach ($submission['answers'] as $answer) {
-                if (isset($additionalHeaders[$answer['field']])) {
+            /** @var Submission $submission */
+            foreach ($submission->getAnswers() as $field => $answer) {
+                if (isset($additionalHeaders[$field])) {
                     continue;
                 }
-                $additionalHeaders[$answer['field']] = ucfirst($answer['field']);
+                $additionalHeaders[$field] = ucfirst($field);
             }
         }
 
@@ -161,12 +163,11 @@ public function export(int $id, string $status, string $type): IWriter
 
             $rowAnswers = [];
             foreach ($additionalHeaders as $key => $header) {
-                $answer = array_filter($submission['answers'], fn($answer) => $answer['field'] === $key);
-                if (count($answer) === 0) {
+                $answer = $submission->getAnswers()[$key] ?? '';
+                if (empty($answer)) {
                     $rowAnswers[] = '';
                     continue;
                 }
-                $answer = array_values($answer)[0]['answer'];
                 if (is_array($answer)) {
                     $answer = implode(', ', $answer);
                 }
@@ -174,11 +175,11 @@ public function export(int $id, string $status, string $type): IWriter
             }
 
             $row = [
-                $submission['id'],
-                $submission['createdAt'],
-                $submission['isRead'] ? 'Yes' : 'No',
-                $submission['isFlagged'] ? 'Yes' : 'No',
-                $submission['isDeleted'] ? 'Yes' : 'No',
+                $submission->getId(),
+                $submission->getCreatedAt()->format('Y-m-d H:i:s'),
+                $submission->isRead() ? 'Yes' : 'No',
+                $submission->isFlagged() ? 'Yes' : 'No',
+                $submission->isDeleted() ? 'Yes' : 'No',
                 ...$rowAnswers,
             ];
 
diff --git a/src/Service/FormWebhookService.php b/src/Service/FormWebhookService.php
new file mode 100644
index 0000000..206113c
--- /dev/null
+++ b/src/Service/FormWebhookService.php
@@ -0,0 +1,79 @@
+<?php
+namespace App\Service;
+
+use App\Entity\Form;
+use App\Entity\FormWebhook;
+use App\Entity\Submission;
+use App\Repository\FormWebhookRepository;
+use GuzzleHttp\Client;
+
+class FormWebhookService
+{
+    public function __construct(
+        private readonly FormWebhookRepository $formWebhookRepository,
+        private readonly FormFieldService $formFieldService,
+    )
+    {
+    }
+
+    public function getAllByFormId(int $formId): array
+    {
+        return $this->formWebhookRepository->findByFormId($formId);
+    }
+
+    public function getCountByFormId(int $formId): int
+    {
+        return $this->formWebhookRepository->countByFormId($formId);
+    }
+
+    public function save(FormWebhook $formWebhook): void
+    {
+        $this->formWebhookRepository->save($formWebhook);
+    }
+
+    public function getOneByIdAndFormId(int $webhookId, int $formId): ?FormWebhook
+    {
+        return $this->formWebhookRepository->findOneBy(['id' => $webhookId, 'form' => $formId]);
+    }
+
+    public function delete(FormWebhook $formWebhook): void
+    {
+        $this->formWebhookRepository->delete($formWebhook);
+    }
+
+    public function callAllWebhooks(Form $form, Submission $submission): void
+    {
+        $webhooks = $this->getAllByFormId($form->getId());
+        $formFields = $this->formFieldService->getAllByFormId($form->getId());
+
+        foreach ($webhooks as $webhook) {
+            $payload = [
+                'form' => [
+                    'id' => $form->getId(),
+                    'name' => $form->getName(),
+                    'fields' => array_map(fn($formField) => [
+                        'id' => $formField->getId(),
+                        'name' => $formField->getName(),
+                        'type' => $formField->getType(),
+                        'label' => $formField->getLabel(),
+                        'hint' => $formField->getHint(),
+                        'is_required' => $formField->getIsRequired(),
+                    ], $formFields),
+                ],
+                'data' => $submission,
+            ];
+
+            $headers = [];
+            foreach($webhook->getHeaders() as $header) {
+                $headers[$header->getName()] = $header->getValue();
+            }
+            $headers['Content-Type'] = 'application/json';
+
+            $client = new Client();
+            $client->request('POST', $webhook->getUrl(), [
+                'json' => $payload,
+                'headers' => $headers,
+            ]);
+        }
+    }
+}
