--- date: "2016-12-01T16:00:00+02:00" slug: "webhooks" sidebar_position: 30 aliases: - /en-us/webhooks - /webhooks --- # Webhooks Gitea can send outbound webhooks for repository activity. Repository webhooks are configured at `/:username/:reponame/settings/hooks` by a repository admin. Equivalent webhook pages also exist for organizations, users, and system administration. Webhook configuration is available at four scopes: - `Repository webhooks`: Trigger only for activity in one repository. - `Organization webhooks`: Trigger for activity in repositories owned by that organization. - `User webhooks`: Trigger for activity in repositories owned by that user. - `System webhooks`: Trigger for all eligible activity on the instance. Gitea also supports admin-defined `default webhooks`. These are not an extra delivery scope. Instead, they are copied into newly created repositories and then behave like ordinary repository webhooks. Gitea supports these outgoing webhook integrations: - Gitea - Gogs - Slack - Discord - Dingtalk - Telegram - Microsoft Teams - Feishu - Matrix - Wechatwork - Packagist The `Gitea` and `Gogs` webhook types send generic webhook payloads. The chat and service integrations listed above transform the same internal event into a service-specific request body. ## Configuration This section covers the webhook settings you choose when creating or editing a webhook. ### Configuring a webhook When creating a webhook, the main options are: - `Target URL`: The endpoint that receives the delivery. - `HTTP Method`: Usually `POST` for generic webhooks. - `POST Content Type`: `application/json` or `application/x-www-form-urlencoded` for generic webhooks. - `Secret`: Used to sign the raw request body with HMAC. - `Authorization Header`: Optional custom `Authorization` header to send with each request. - `Branch Filter`: Optional glob filter for branch and tag related events. - `Trigger On`: `Push Events`, `All Events`, or a custom event selection. - `Active`: Whether the webhook is enabled. :::note Older examples may still show a `secret` field inside the JSON payload. Current Gitea versions do not send the webhook secret in the payload body. Always verify the request by checking the signature headers instead. ::: ### Branch filters The branch filter uses glob syntax compatible with [`github.com/gobwas/glob`](https://pkg.go.dev/github.com/gobwas/glob#Compile). - Empty, `*`, or `**` matches everything. - A plain branch name such as `main` matches that branch. - Full refs such as `refs/tags/v*` are also supported. - Brace expressions such as `{main,release/*}` are supported. - The filter only applies to events that carry a git ref, such as `create`, `delete`, and `push`. - Events without a ref, such as issues or releases, ignore the branch filter. Examples: - `main` - `{main,feature/*}` - `{refs/heads/feature/*,refs/tags/release/*}` ### Authorization header Gitea can be configured to send a custom [Authorization header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) with each webhook delivery. This is independent from the webhook secret: - Use the secret to verify integrity with HMAC. - Use the `Authorization` header when the receiving endpoint requires application-level authentication. ## Delivery This section describes how Gitea sends webhook deliveries and how receivers can identify and verify them. ### Delivery behavior - Webhooks are delivered asynchronously over HTTP. - Generic `Gitea` and `Gogs` webhooks support `POST` and `GET`; `POST` is the normal choice. - For `POST` requests, the payload can be sent either as JSON (`application/json`) or as a form field named `payload` (`application/x-www-form-urlencoded`). - Provider-specific integrations may use the HTTP method and body format required by that provider. ### Delivery headers Every delivery includes a unique delivery ID and event headers. For GitHub-compatible integrations, Gitea also sends the corresponding GitHub and Gogs header names. | Header | Description | | --- | --- | | `X-Gitea-Delivery` | Unique delivery UUID for this attempt. | | `X-Gitea-Event` | Normalized event name, such as `push`, `issues`, or `pull_request`. | | `X-Gitea-Event-Type` | More specific event type, such as `issue_assign` or `pull_request_review_comment`. | | `X-Gitea-Signature` | Hex-encoded HMAC-SHA256 of the raw request body, without a prefix. | | `X-Gitea-Hook-Installation-Target-Type` | Where the webhook is defined: typically `repository`, `organization`, `user`, or `system`. Default webhooks are copied into repositories before delivery, so they are typically delivered as `repository`. | | `X-Gogs-Delivery`, `X-Gogs-Event`, `X-Gogs-Event-Type`, `X-Gogs-Signature` | Compatibility headers with the same values as the Gitea variants. | | `X-GitHub-Delivery`, `X-GitHub-Event`, `X-GitHub-Event-Type` | GitHub-style compatibility headers. | | `X-GitHub-Hook-Installation-Target-Type` | GitHub-style compatibility header for the webhook scope. | | `X-Hub-Signature` | GitHub-compatible HMAC-SHA1 header in the form `sha1=`. | | `X-Hub-Signature-256` | GitHub-compatible HMAC-SHA256 header in the form `sha256=`. | If no secret is configured, the signature headers are still present, but their digest values are empty. #### `Event` versus `Event-Type` Some Gitea webhook subscriptions are grouped together under one normalized event name. For example, an issue assignment delivery uses the issue event group: ```http X-Gitea-Event: issues X-Gitea-Event-Type: issue_assign X-GitHub-Event: issues X-GitHub-Event-Type: issue_assign ``` Use `X-Gitea-Event-Type` when you need the exact trigger that fired the webhook. #### Validating deliveries Gitea signs the raw request body with your webhook secret. To validate a delivery: 1. Read the request body exactly as it was received. 2. Compute the HMAC-SHA256 digest with your webhook secret. 3. Compare the result with `X-Gitea-Signature` or with the GitHub-compatible `X-Hub-Signature-256` header. 4. Use a constant-time comparison when possible. Important details: - `X-Gitea-Signature` contains only the lowercase hexadecimal SHA-256 digest. - `X-Hub-Signature-256` contains the same digest with a `sha256=` prefix. - `X-Hub-Signature` is also sent for compatibility and uses SHA-1. - The body must be verified before JSON parsing or any other modification. ##### PHP example The following example verifies a generic `Gitea` webhook sent as `application/json`. ```php