> ## Documentation Index
> Fetch the complete documentation index at: https://sequinstream.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Get started with webhooks

> Learn how to create real-time API hooks from Postgres changes in minutes. Use Sequin to trigger automated workflows, build audit logs, and more.

In this quickstart, you'll create a real-time data pipeline that streams changes from a Postgres database to a webhook endpoint. You'll:

* Boot Sequin
* Connect to a sample playground database
* Create a webhook that receives database changes
* See your changes flow in real-time

By the end, you'll have hands-on experience setting up Postgres change data capture (CDC) with Sequin. This same pattern can be used to setup your own Postgres CDC pipeline with a webhook endpoint.

<Tip>
  This is the quickstart for streaming Postgres to webhooks. See the [how-to guide](/how-to/stream-postgres-to-a-webhook-endpoint) for an explanation of how to use the webhook sink or the [reference](/reference/sinks/webhooks) for details on all configuration options.
</Tip>

<Steps titleSize="h2">
  <Step title="Run Sequin" icon="server">
    The easiest way to get started with Sequin is with our [Docker Compose file](https://github.com/sequinstream/sequin/blob/main/docker/docker-compose.yaml). This file starts a Postgres database, Redis instance, and Sequin server.

    <Steps>
      <Step title="Create directory and start services">
        1. Download [sequin-docker-compose.zip](https://github.com/sequinstream/sequin/releases/latest/download/sequin-docker-compose.zip).
        2. Unzip the file.
        3. Navigate to the unzipped directory and start the services:

        ```bash theme={null}
        cd sequin-docker-compose && docker compose up -d
        ```

        <AccordionGroup>
          <Accordion title="Alternative: Download with curl">
            ```bash theme={null}
            curl -L https://github.com/sequinstream/sequin/releases/latest/download/sequin-docker-compose.zip -o sequin-docker-compose.zip \
              && unzip sequin-docker-compose.zip && rm sequin-docker-compose.zip
            cd sequin-docker-compose && docker compose up -d
            ```
          </Accordion>

          <Accordion title="Alternative: Clone the repository">
            ```bash theme={null}
            git clone git@github.com:sequinstream/sequin.git
            cd sequin/docker
            docker compose up -d
            ```
          </Accordion>
        </AccordionGroup>
      </Step>

      <Step title="Verify services are running">
        Check that Sequin is running using `docker ps`:

        ```bash theme={null}
        docker ps
        ```

        You should see output like the following:

        ```
        CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS                    PORTS                              NAMES
        bd5c458cabde   sequin/sequin:latest            "/scripts/start_comm…"   11 seconds ago   Up 9 seconds              4000/tcp, 0.0.0.0:7376->7376/tcp   sequin-sequin-1
        3bacd89765e7   grafana/grafana                 "/run.sh"                11 seconds ago   Up 11 seconds             0.0.0.0:3000->3000/tcp             sequin-sequin_grafana-1
        3ad41319a66c   postgres:16                     "docker-entrypoint.s…"   11 seconds ago   Up 11 seconds (healthy)   0.0.0.0:7377->5432/tcp             sequin-sequin_postgres-1
        6139a5fc4e80   redis:7                         "docker-entrypoint.s…"   11 seconds ago   Up 11 seconds             0.0.0.0:7378->6379/tcp             sequin-sequin_redis-1
        7e07a5b052de   prom/prometheus                 "/bin/prometheus --c…"   11 seconds ago   Up 11 seconds             0.0.0.0:9090->9090/tcp             sequin-sequin_prometheus-1
        ```

        <Check>
          Sequin, Postgres, Redis, Prometheus, and Grafana should be up and running (status: `Up`).
        </Check>
      </Step>
    </Steps>
  </Step>

  <Step title="Login" icon="key">
    The Docker Compose file automatically configures Sequin with an admin user and a playground database.

    Let's log in to the Sequin web console:

    <Steps>
      <Step title="Open the web console">
        After starting the Docker Compose services, open the Sequin web console at [http://localhost:7376](http://localhost:7376):

        <Frame>
          <img src="https://mintcdn.com/sequinstream/drUA755uMUeIaCSH/images/quickstart/login-page.png?fit=max&auto=format&n=drUA755uMUeIaCSH&q=85&s=c5d90b34f56560570696a71370f7e39b" alt="Sequin login page, allowing login with default credentials" width="2070" height="1696" data-path="images/quickstart/login-page.png" />
        </Frame>
      </Step>

      <Step title="Login with default credentials">
        Use the following default credentials to login:

        * Email:

        ```
        admin@sequinstream.com
        ```

        * Password:

        ```
        sequinpassword!
        ```
      </Step>
    </Steps>
  </Step>

  <Step title="View the playground database" icon="database">
    To get you started quickly, Sequin's Docker Compose file creates a logical database called `sequin_playground` with a sample dataset in the `public.products` table.

    Let's take a look:

    <Steps>
      <Step title="Navigate to Databases">
        In the Sequin web console, click **Databases** in the sidebar.
      </Step>

      <Step title="Select playground database">
        Click on the pre-configured `sequin-playground` database:

        <Frame>
          <img src="https://mintcdn.com/sequinstream/drUA755uMUeIaCSH/images/quickstart/playground-database.png?fit=max&auto=format&n=drUA755uMUeIaCSH&q=85&s=01ac1cbf4506cad22c270adb66c0b171" alt="Playground database" width="3376" height="2020" data-path="images/quickstart/playground-database.png" />
        </Frame>

        <Check>
          The database "Health" should be green.
        </Check>
      </Step>

      <Step title="View contents of the products table">
        Let's get a sense of what's in the `products` table. Run the following command:

        ```bash theme={null}
        docker exec -i sequin-sequin_postgres-1 \
          psql -U postgres -d sequin_playground -c \
          "select id, name, price from products;"
        ```

        <Info>
          This command connects to the running Postgres container and runs a `psql` command.
        </Info>

        You should see a list of the rows in the `products` table:

        ```
          id |         name          | price 
        ----+-----------------------+-------
          1 | Avocados (3 pack)     |  5.99
          2 | Flank Steak (1 lb)    |  8.99
          3 | Salmon Fillet (12 oz) | 14.99
          4 | Baby Spinach (16 oz)  |  4.99
          5 | Sourdough Bread       |  6.99
          6 | Blueberries (6 oz)    |  3.99
        (6 rows)
        ```

        We'll make modifications to this table in a bit.
      </Step>
    </Steps>
  </Step>

  <Step title="Create a Webhook Sink" icon="plug">
    With the playground database connected, you can create a [sink](/reference/sinks/overview). This sink will send changes to the `products` table to an HTTP endpoint:

    <Steps>
      <Step title="Navigate to Sinks">
        Click "Sinks" in the sidebar navigation, then click "Create Sink".
      </Step>

      <Step title="Select sink type">
        Select "Webhook" as the sink type and click "Continue".
      </Step>

      <Step title="Note &#x22;Source&#x22; configuration">
        In the "Source" card, note that the `sequin-playground` database is selected and all schemas and tables are included. Leave these defaults:

        <Frame>
          <img style={{ maxWidth: '500px' }} src="https://mintcdn.com/sequinstream/I2Yx_f_pmUFGglUP/images/quickstart/source-card.png?fit=max&auto=format&n=I2Yx_f_pmUFGglUP&q=85&s=a1ba47d0e4698d439d64db0d582f0951" alt="Source card showing the sequin_playground database and products table" width="1640" height="778" data-path="images/quickstart/source-card.png" />
        </Frame>
      </Step>

      <Step title="Setup a backfill">
        In the `Inital backfill` card, select the `public.products` table to initate a backfill when the sink is created.

        <Frame>
          <img style={{ maxWidth: '700px' }} src="https://mintcdn.com/sequinstream/drUA755uMUeIaCSH/images/quickstart/backfill-card.png?fit=max&auto=format&n=drUA755uMUeIaCSH&q=85&s=2a41931bc2d650f7467f3c7ae92b5b0a" alt="Initial backfill card with public.products table selected" width="1606" height="570" data-path="images/quickstart/backfill-card.png" />
        </Frame>
      </Step>

      <Step title="Configure &#x22;HTTP Endpoint&#x22;">
        In the "HTTP Endpoint" card, click the dropdown "New HTTP Endpoint" and select "Create webhook.site endpoint".

        This will provision a test endpoint on Webhook.site for you to use:

        <Frame>
          <img style={{ maxWidth: '700px' }} src="https://mintcdn.com/sequinstream/I2Yx_f_pmUFGglUP/images/quickstart/webhooks/http-endpoint-card.png?fit=max&auto=format&n=I2Yx_f_pmUFGglUP&q=85&s=0316e20c4efd8f1aa15b7d06a7ad43be" alt="Clicking to create a new Webhook.site endpoint" width="1585" height="480" data-path="images/quickstart/webhooks/http-endpoint-card.png" />
        </Frame>
      </Step>

      <Step title="Create the sink">
        You can leave the rest of the defaults. As configured, the webhook endpoint will first receive a backfill of all rows currently in the `products` table. Then, it will receive all changes to the `products` table in real-time.

        Click "Create Sink" to finish setting up your webhook.
      </Step>
    </Steps>
  </Step>

  <Step title="See changes flow to the webhook endpoint" icon="waveform-lines">
    On the new sink's overview page, you should see the "Health" status turn green, indicating data is flowing to the webhook endpoint.

    Let's confirm messages are flowing, both on Sequin and on Webhook.site:

    <Steps>
      <Step title="Messages tab">
        Click the "Messages" tab. You'll see a list of the recently delivered messages:

        <Frame>
          <img style={{ maxWidth: '700px' }} src="https://mintcdn.com/sequinstream/I2Yx_f_pmUFGglUP/images/quickstart/webhooks/messages-tab.png?fit=max&auto=format&n=I2Yx_f_pmUFGglUP&q=85&s=42f4ea4f21b1ded7d34060e128e7ea92" alt="List of recently delivered messages" width="1822" height="948" data-path="images/quickstart/webhooks/messages-tab.png" />
        </Frame>

        <Check>
          Sequin indicates it backfilled the `products` table to our webhook endpoint.
        </Check>
      </Step>

      <Step title="View on Webhook.site">
        Navigate back to the "Overview" tab. On the "HTTP Endpoint" card, click "View on Webhook.site".

        This opens a new tab with the webhook endpoint's request log. You should see the most recently received message displayed:

        <Frame>
          <img style={{ maxWidth: '700px' }} src="https://mintcdn.com/sequinstream/I2Yx_f_pmUFGglUP/images/quickstart/webhooks/webhook-site-messages.png?fit=max&auto=format&n=I2Yx_f_pmUFGglUP&q=85&s=8c0bc91176118bdfd6e0cbcdbdac5782" alt="Webhook.site request log" width="1994" height="1506" data-path="images/quickstart/webhooks/webhook-site-messages.png" />
        </Frame>

        This message is a [`read` event](/reference/messages) for a row in the `products` table. A `read` event indicates the event came from a Sequin backfill.

        <Check>
          Messages are flowing from Sequin to the webhook endpoint.
        </Check>
      </Step>

      <Step title="Make some changes">
        Let's make some changes to the `products` table and see them flow to the webhook endpoint.

        In your terminal, run the following command to insert a new row into the `products` table:

        ```bash theme={null}
        docker exec -i sequin-sequin_postgres-1 \
          psql -U postgres -d sequin_playground -c \
          "insert into products (name, price) values ('Organic Honey (16 oz)', 12.99);"
        ```

        Back on Webhook.site, you should see a new message appear in the request log:

        <Frame>
          <img style={{ maxWidth: '700px' }} src="https://mintcdn.com/sequinstream/I2Yx_f_pmUFGglUP/images/quickstart/webhooks/webhook-site-inserted-message.png?fit=max&auto=format&n=I2Yx_f_pmUFGglUP&q=85&s=a2ee5b3a6d401f16d9757e80847c4dbe" alt="Recently inserted message on Webhook.site" width="1614" height="968" data-path="images/quickstart/webhooks/webhook-site-inserted-message.png" />
        </Frame>

        Feel free to try other changes:

        <AccordionGroup>
          <Accordion title="Update a product's price">
            ```bash theme={null}
            docker exec -i sequin-sequin_postgres-1 \
              psql -U postgres -d sequin_playground -c \
              "update products set price = 7.99 where name = 'Avocados (3 pack)';"
            ```
          </Accordion>

          <Accordion title="Change a product's name">
            ```bash theme={null}
            docker exec -i sequin-sequin_postgres-1 \
              psql -U postgres -d sequin_playground -c \
              "update products set name = 'Organic Avocados (3 pack)' where name = 'Avocados (3 pack)';"
            ```
          </Accordion>

          <Accordion title="Delete a product">
            ```bash theme={null}
            docker exec -i sequin-sequin_postgres-1 \
              psql -U postgres -d sequin_playground -c \
              "delete from products where name = 'Blueberries (6 oz)';"
            ```
          </Accordion>
        </AccordionGroup>

        Each change will appear in Webhook.site within a few seconds.
      </Step>
    </Steps>
  </Step>
</Steps>

<Check>
  Great work!
</Check>

You've successfully:

* Set up a complete Postgres change data capture pipeline
* Loaded existing data through a backfill
* Made changes to the `products` table
* Verified changes are flowing to your webhook endpoint

## Ready to stream

Now you're ready to connect your own database to Sequin and start streaming changes:

<CardGroup cols={2}>
  <Card title="Guide: Connect Postgres" icon="elephant" href="/connect-postgres">
    Connect your Postgres database to Sequin.
  </Card>

  <Card title="Guide: Setting up a webhook sink" icon="webhook" href="/how-to/stream-postgres-to-a-webhook-endpoint">
    Setup a webhook sink to send changes to an HTTP endpoint.
  </Card>
</CardGroup>
