Website | Documentation | Community Slack
## Svix is the enterprise ready webhook service
Svix makes it easy for developers to send webhooks. Developers make one API call, and Svix takes care of deliverability, retries, security, and more. For more information, please refer to the [Svix homepage](https://www.svix.com).
[)](https://search.maven.org/artifact/com.svix/svix)
[)](https://search.maven.org/artifact/com.svix.kotlin/svix-kotlin)
# Documentation
You can find general usage documentation at . For complete API documentation with code examples for each endpoint in all of our official client libraries head over to our API documentation site at .
# Support & Community
- [GitHub Issues](https://github.com/svix/svix-webhooks/issues) - report issues and make suggestions.
- [Community Forum](https://github.com/svix/svix-webhooks/discussions) - ask questions, and start discussions!
- [Slack](https://www.svix.com/slack/) - come and chat with us!
To stay up-to-date with new features and improvements be sure to watch our repo!
# Client Library Overview
## Trying out the CLI
The Svix CLI is published on npm as [`svix-cli`](https://www.npmjs.com/package/svix-cli). You can run it directly with `npx` without installing anything:
```sh
npx svix-cli --help
```
Or install it globally:
```sh
npm install -g svix-cli
svix-cli --help
```
# Running the server
There are multiple ways to get the Svix server up running. Docker is probably the most common one, but you can choose the one that works best for you.
The Svix server is written in Rust , which means you can compile it into a static library for a variety of targets. Please refer to the building from source section below for more information.
Please refer to the [server configuration](#server-configuration) section below for more information regarding the available settings.
## Deployment
### Docker
You can use the official Svix Docker image from [Docker Hub](https://hub.docker.com/r/svix/svix-server). You can either use the `latest` tag, or one of [the versioned tags](https://hub.docker.com/r/svix/svix-server/tags) instead.
You can either use the example [docker-compose.yml](./server/docker-compose.yml) file with `docker compose` (easiest), `docker swarm` (advanced), or run the container standalone.
#### With Docker Compose
This alternative is the easiest because it will also boot up and configure `redis` and `postgresql`.
This assumes you have Docker Compose v2 installed.
```
cd server
docker compose up
```
#### Standalone container
Running a standalone container is slightly more advanced, as it requires you to set some environment variables and have them pointing to your `redis` and `postgres` instances.
You can pass individual environment variables to docker using the `-e` flag, or just create a file like [development.env](./server/svix-server/development.env) and use the `--env-file` flag like in the example below:
```
docker run \
--name svix-server \
-p 8071:8071 \
--env-file development.env \
svix/svix-server
```
### Building from source
The Svix server is written in Rust and requires a Rust build environment.
If you already have one, you just need to run `cargo build`, otherwise, please please refer to the [Svix server README](./server/#readme) for more information about building the server from source.
## Runtime dependencies
The server requires the following runtime dependencies to work correctly:
- A PostgreSQL server - for the storage of events.
- An *optional* Redis server version 6.2.0 or higher - for the task queue and cache.
## Redis/Valkey Considerations
### Persistence
Please note that it's recommended to enable persistence in Redis so that tasks are persisted across Redis server restarts and upgrades.
### Eviction Policy
Please ensure that your Redis instances are configured to not evict keys without explicit `expire` policies set. This means that `maxmemory-policy` should be set to `noeviction` or to any of the available `volatile-` policies. See Redis/Valkey documentation for further information.
## Server configuration
There are three ways to configure `svix-server`: environment vars, `.env` file, and a configuration file.
### Configuration file
You can put a file called `config.toml` in the current working directory of `svix-server` and it will automatically pick it up.
You can take a look at the example file for more information and a full list of supported settings: [config.toml](./server/svix-server/config.default.toml).
Here's a quick example of the most important configurations:
```toml
# The JWT secret for authentication - should be secret and securely generated
jwt_secret = "8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW"
# The DSN for the database. Only postgres is currently supported.
db_dsn = "postgresql://postgres:postgres@pgbouncer/postgres"
# The DSN for redis (can be left empty if not using redis)
redis_dsn = "redis://redis:6379"
# What kind of message queue to use.
queue_type = "redis"
```
### Environment (variables or `.env`)
Alternatively, you can configure `svix-server` by setting the equivalent environment variables for each of the supported settings. The environment variables can either be passed directly or by setting them in a `.env` file.
The environment variables have the name name as the config names, but they are all upper case and are prefixed with `SVIX_`.
For example, the above example configuration would look like this if it was passed in the env:
```
# The JWT secret for authentication - should be secret and securely generated
SVIX_JWT_SECRET = "8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW"
# The DSN for the database. Only postgres is currently supported.
SVIX_DB_DSN = "postgresql://postgres:postgres@pgbouncer/postgres"
# The DSN for redis (can be left empty if not using redis)
SVIX_REDIS_DSN = "redis://redis:6379"
# What kind of message queue to use.
SVIX_QUEUE_TYPE = "redis"
```
### OpenTelemetry
You may send traces, metrics, and logs to the OpenTelemetry Collector which allows forwarding this data to a number of external applications/services such as DataDog, Jaeger, NewRelic, Prometheus, Sentry, Signoz, and Zipkin.
You can see more in [these instructions](./OpenTelemetry.md).
### Connection Pool Size
The `db_pool_max_size` configuration parameter controls the maximum allowed size of the connection pool for PostgreSQL. This value defaults to a max size of 100, but you can potentially increase application performance significantly by increasing this value. You may need to consider Postgres and PGBouncer configuration parameters as well when tuning these parameters.
The `redis_pool_max_size` parameter controls the maximum size of each Svix instance's Redis connection pool. Its default is 100. Note that only redis _queuing_ leverages connection pooling -- caching is fully asynchronous and so does not otherwise benefit from pooling. Therefore, you probably won't need to tune this parameter.
### SSRF Attacks and Internal IP Addresses
To prevent SSRF attacks, message dispatches to internal IP addresses are blocked by default. However we understand that this doesn't meet the needs of every user say, for example, the service can only be accessed internally. To bypass these restrictions, see the `whitelist_subnets` configuration option, which accepts an array of CIDR-notation subnets to allow messages to be dispatched to.
### Webhook signature scheme (symmetric vs asymmetric)
To ensure the security and integrity of messages, Svix signs all webhook messages prior to sending.
Svix supports two types of signature schemes: symmetric (pre-shared key) and asymmetric (public key).
Symmetric signatures are significantly faster (~50x for signing, and ~160x for verifying), and are much simpler (which makes verification easier for your customers), though they require the usage of a pre-shared key per endpoint (endpoint secret) in order to work. Asymmetric signatures on the other hand only require sharing a public key with your customers (not secret).
Because of the above, using symmetric keys is both recommended and the Svix default. Using them is documented in the [verifying signatures section of the docs](https://docs.svix.com/receiving/verifying-payloads/how-manual).
However, in some scenarios it may be beneficial to use asymmetric signatures, which is why they too are supported. For more information please refer to the [asymmetric signatures section](#asymmetric-signatures) below.
## Authentication
Use valid JWTs generated with the correct secret as `Bearer`.
E.g:
```
Authorization: Bearer
```
Either generate one using
```
svix-server jwt generate
```
Or if you are generating your own, make sure to use `org_23rb8YdGqMT0qIzpgGwdXfHirMu` as the `sub` field, and `H256` as the algorithm.
Example valid JWT for the secret `x` (so you can see the structure):
```js
// JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.USMuIPrqsZTSj3kyWupCzJO9eyQioBzh5alGlvRbrbA
// Structure (when decoded):
{
"iat": 1655140639,
"exp": 1970500639,
"nbf": 1655140639,
"iss": "svix-server",
"sub": "org_23rb8YdGqMT0qIzpgGwdXfHirMu"
}
```
### Using a different signing algorithm
As mentioned above, the default algorithm for signing JWTs is `HS256`. You can select a different algorithm by setting the `jwt_algorithm` confi