Interactive example
GitLab push event lab
The identifiers and signature are synthetic. Use them to validate parsing, never cryptographic authenticity.
- Content-Type
- application/json
- X-Gitlab-Event
- Push Hook
- X-Gitlab-Event-UUID
- 9cebe914-4827-408f-b014-cfa23a47a35f
- Idempotency-Key
- 3a427872-00df-429c-9bc9-a9475de2efe4
- webhook-id
- 3a427872-00df-429c-9bc9-a9475de2efe4
- webhook-timestamp
- 1785758400
- webhook-signature
- v1,SYNTHETIC-NOT-A-VALID-SIGNATURE
{
"object_kind": "push",
"event_name": "push",
"before": "95790bf891e76fee5e1746a589903a6a1f80f22",
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"ref": "refs/heads/main",
"checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"user_name": "Test Maintainer",
"project": {
"id": 4242,
"name": "sample-service",
"web_url": "https://gitlab.example.test/team/sample-service"
},
"commits": [{
"id": "da15608",
"message": "Test deployment hook",
"title": "Test deployment hook"
}],
"total_commits_count": 1
}Configured response
200 OK
Content-Type: application/json
{"received":true,"source":"gitlab-test"}Synthetic data only. Never paste production tokens, signing secrets, personal data, or payment information into a public test endpoint.
One-click test setup
Creates a temporary bucket and applies this guide's expected response. You can inspect and delete it from the dashboard.
Create a Synthetic Delivery Boundary
GitLab can test configured project and group webhooks, but a temporary endpoint makes the complete outbound request easy to inspect before your real receiver exists. Use a test project and synthetic commit data. Do not send private repository content, access tokens, signing tokens, or real user email addresses.
Paste the generated endpoint into a test webhook, select only the event under development, and use GitLab’s test action. The capture should show POST, JSON, the GitLab event header, delivery identifiers, and the exact payload produced by your installed GitLab version.
Route by Event and Payload Type
X-Gitlab-Event identifies the high-level hook, while object_kind or event_name provides a payload-level discriminator. Check both. Different events have different nested objects, and even a push event can contain an empty commits array when a branch changes without new commits.
The lab uses a compact push fixture with a main-branch ref and one synthetic commit. Compare the raw body with your decoder before testing a large real payload. A permissive decoder should tolerate fields your current code does not use.
- Use X-Gitlab-Event for the first routing decision
- Validate object_kind before reading event-specific fields
- Treat event UUID and idempotency values as delivery correlation signals
- Keep decoders forward-compatible with additional JSON fields
Understand Current Signing Headers
Current GitLab documentation recommends signing tokens for new hooks and describes Standard Webhooks headers: webhook-id, webhook-timestamp, and webhook-signature. The signature is HMAC-SHA256 over message ID, timestamp, and the raw body. The lab value is intentionally not valid.
Older or transitional configurations may also send X-Gitlab-Token as plain text. Never place that real secret in a public bucket. During a migration, your private receiver can verify the signature when present and use the legacy token only as a temporary fallback.
Return Quickly and Deduplicate Deliveries
The one-click endpoint returns 200 immediately. A production receiver should authenticate, validate, persist a delivery claim, and acknowledge before slow work. Use a durable unique key so a retry does not deploy, notify, or mutate state twice.
GitLab includes delivery identifiers that make logs and retries easier to correlate. Record only the identifiers you need, apply retention controls, and avoid treating header presence alone as proof of authenticity.
Diagnose GitLab Delivery Failures
Use the webhook request history to compare the request and response. A 404 usually points to a stale destination path. A 401 or 403 points to authentication logic. A timeout means the receiver should acknowledge sooner or move work to a queue.
Repeated failures can cause automatic webhook disabling, and GitLab.com also applies webhook rate limits at the top-level namespace. Fix the receiver contract before repeatedly retesting, then verify one successful delivery and delete the temporary endpoint.
- No delivery: confirm the selected trigger and project permissions
- Wrong parser branch: inspect X-Gitlab-Event and object_kind together
- Invalid signature: preserve the exact raw bytes used for HMAC verification
- Duplicate side effects: claim the event or delivery identifier atomically
Common questions
Frequently asked questions
- Which header identifies a GitLab webhook event?
- GitLab sends X-Gitlab-Event with values such as Push Hook or Merge Request Hook. Use it for routing, but still validate the JSON object_kind and the configured authentication mechanism.
- Should I use a GitLab secret token or signing token?
- Current GitLab documentation recommends signing tokens for new webhooks because they add HMAC-SHA256 integrity. Legacy secret tokens are sent as plain text in X-Gitlab-Token and provide weaker guarantees.
- Can this page verify a real GitLab signature?
- No. The displayed signature is deliberately invalid. Verify a real webhook-signature in your own trusted receiver using the raw request body and protected signing token.
Primary sources
Official references
Try it with a real request
Turn the guide into a test.
Open a temporary endpoint, send your payload, and inspect exactly what arrived.
Open the tester