Skip to main content
DevOps & CI/CDbitbucketsetupwebhooks

How to Connect Bitbucket to VERDiiiCT: Step-by-Step Guide

VERDiiiCT Team9 min read

Overview

VERDiiiCT integrates with Bitbucket Cloud (bitbucket.org) through an SCM connection (authenticated with an access token) and a webhook (which triggers reviews automatically when pull requests are created or updated).

Bitbucket has some unique differences from other providers — particularly around webhook secret validation. This guide covers everything you need to know.

The process takes about five minutes:

  1. Create an access token in Bitbucket
  2. Create an SCM connection in VERDiiiCT
  3. Register a webhook for your repository
  4. Configure the webhook in Bitbucket
  5. Understand how secret validation works

Prerequisites

  • A VERDiiiCT account with Owner or Admin role in your organization
  • A Bitbucket Cloud account with Admin access to the repository you want to connect
  • A Repository Access Token or Workspace Access Token (recommended over App Passwords)

Step 1: Create an Access Token in Bitbucket

VERDiiiCT supports Repository Access Tokens and Workspace Access Tokens, both using Bearer authentication.

Repository access tokens are scoped to a single repository — the most secure option.

  1. In your Bitbucket repository, go to Repository settingsAccess tokens
  1. Click Create Repository Access Token
  2. Configure the token:
    • Name: VERDiiiCT Code Review
    • Permissions:
      • Pull requests: Read and Write (to read PR metadata and post comments)
      • Repositories: Read (to read file diffs)
  1. Click Create and copy the token immediately

Using a Workspace Access Token (Alternative)

Workspace tokens cover all repositories in a workspace — useful if you want to connect multiple repos.

  1. Go to your Workspace settingsAccess tokens
  2. Click Create Workspace Access Token
  3. Select the same permissions as above: Pull requests (Read/Write), Repositories (Read)
  4. Click Create and copy the token

Security note: VERDiiiCT encrypts your access token at rest using AES-256-GCM. The plaintext token is never stored or logged. Repository Access Tokens are recommended because they follow the principle of least privilege.

Note on App Passwords: Bitbucket also supports App Passwords (Basic Auth with username:password), but VERDiiiCT uses Bearer token authentication. Use a Repository or Workspace Access Token instead.


Step 2: Create an SCM Connection in VERDiiiCT

An SCM connection links your Bitbucket workspace to VERDiiiCT.

  1. Log in to VERDiiiCT at app.verdiiict.com
  2. Navigate to Connections in the sidebar
  3. Click Add Connection
  1. Fill in the connection details:
    • Provider: Select Bitbucket
    • Display Name: A friendly name like My Bitbucket Workspace
    • Organization URL: Leave empty or enter https://api.bitbucket.org — not required for Bitbucket Cloud since the API base URL is always the same
    • Personal Access Token: Paste the access token you created in Step 1
    • Webhook Secret (optional): You can leave this blank — VERDiiiCT generates a unique secret per webhook registration automatically
  1. Click Create
  2. Use the Test Connection button to verify VERDiiiCT can authenticate with Bitbucket using your token

Step 3: Register a Webhook in VERDiiiCT

A webhook registration tells VERDiiiCT which repository to watch and generates a unique callback URL.

  1. Open the connection you just created
  2. Navigate to the Webhooks tab
  3. Click Register Webhook
  1. Fill in:

    • Repository ID: The repository UUID from Bitbucket (found in the repository's API response at https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug} — the uuid field, formatted as {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})
    • Repository Name: The repository name, e.g. my-api
    • Events (optional): Defaults to pull_request.created and pull_request.updated. Leave as default.
  2. Click Register

VERDiiiCT returns a Webhook URL with the secret embedded as a query parameter. For Bitbucket, the URL looks like this:

https://api.verdiiict.com/api/webhooks/bitbucket/{registration-id}?secret={token}

Why is the secret in the URL? Bitbucket Cloud does not support HMAC signature headers or token headers like GitHub, Gitea, and GitLab do. The secret must be embedded in the webhook URL instead. See Step 5 for details.

Important: Copy the full Webhook URL (including the ?secret= query parameter). This is the complete URL you'll paste into Bitbucket.


Step 4: Configure the Webhook in Bitbucket

  1. In your Bitbucket repository, go to Repository settingsWebhooks
  1. Click Add webhook
  2. Configure the webhook:
    • Title: VERDiiiCT Code Review
    • URL: Paste the full Webhook URL from VERDiiiCT (including the ?secret= query parameter)
  1. Under Triggers, select Choose from a full list of triggers
  2. Under Pull Request, check:
    • Created
    • Updated
  3. Uncheck all other triggers
  1. Click Save

Tip: Bitbucket sends a X-Event-Key header with each webhook payload (e.g., pullrequest:created, pullrequest:updated). VERDiiiCT uses this header to determine the event type.


Step 5: How Secret Validation Works for Bitbucket

Bitbucket Cloud handles webhook secrets differently from every other provider VERDiiiCT supports. Understanding this difference is important.

Why Bitbucket Is Different

| Provider | Secret Validation Method | |----------|------------------------| | GitHub | HMAC-SHA256 hash in X-Hub-Signature-256 header | | Gitea | HMAC-SHA256 hash in X-Gitea-Signature header | | GitLab | Plain token in X-Gitlab-Token header | | Azure DevOps | Base64-encoded token in Authorization header | | Bitbucket | No signature or token header — secret must be embedded in URL |

Bitbucket Cloud does not send any signature header or secret token header with webhook payloads. This means the traditional approaches used by other providers don't work.

The Query Parameter Approach

VERDiiiCT works around this by embedding the secret token as a query parameter in the webhook URL:

https://api.verdiiict.com/api/webhooks/bitbucket/{id}?secret={64-char-hex-token}

When a webhook payload arrives, VERDiiiCT:

  1. Extracts the secret query parameter from the request URL
  2. Compares it against the stored secret token
  3. Uses constant-time comparison to prevent timing attacks
// Simplified validation logic
var query = HttpContext.Request.Query;
if (!query.TryGetValue("secret", out var receivedSecret))
    return false;
 
return CryptographicOperations.FixedTimeEquals(
    Encoding.UTF8.GetBytes(secretToken),
    Encoding.UTF8.GetBytes(receivedSecret.ToString()));

Security Implications

The query parameter approach is less ideal than HMAC signatures because:

  • The secret is visible in the URL (though transmitted over HTTPS, so encrypted in transit)
  • URL parameters may appear in server logs

However, it's the standard workaround for Bitbucket Cloud and is used by many integration providers. VERDiiiCT mitigates the risk by:

  • Generating a cryptographically random 32-byte (64 hex character) secret per registration
  • Using unpredictable GUIDs as registration IDs
  • Validating with constant-time comparison

Security note: Ensure your webhook URL is only shared with Bitbucket. Do not post it publicly or include it in client-side code.


The Complete Flow

Once everything is configured, here's what happens automatically:

Developer opens or updates a Pull Request in Bitbucket
        ↓
Bitbucket fires the webhook (HTTP POST with X-Event-Key header)
        ↓
VERDiiiCT receives the payload at /api/webhooks/bitbucket/{id}?secret={token}
        ↓
VERDiiiCT validates the secret from the query parameter
        ↓
VERDiiiCT checks the X-Event-Key header:
  - "pullrequest:created" → new PR, triggers review
  - "pullrequest:updated" → updated PR, triggers review
  - Other events → ignored
        ↓
VERDiiiCT fetches the PR diffs via Bitbucket API using the stored token
        ↓
AI (Claude or GPT) reviews the code changes
        ↓
VERDiiiCT posts inline comments and a verdict
(Approved / Needs Work / Rejected) on the pull request

No manual steps required. Every pull request gets reviewed within minutes.


Troubleshooting

Webhook returns 401

  • The secret in the URL doesn't match. Copy the full webhook URL from VERDiiiCT again (including the ?secret= parameter) and update it in Bitbucket
  • Ensure the URL wasn't truncated when pasting

Webhook returns 404

  • The webhook URL is incorrect or the registration was deleted in VERDiiiCT
  • Verify the registration ID in the URL matches an active registration

Webhook returns 200 but no review appears

  • VERDiiiCT only processes pullrequest:created and pullrequest:updated events. Other events (e.g., pullrequest:fulfilled, pullrequest:rejected) are accepted but ignored
  • Verify your access token has Pull requests Read/Write and Repositories Read permissions
  • Check that the token hasn't been revoked

Reviews don't post inline comments

  • Ensure the access token has Pull requests Write permission
  • For Repository Access Tokens, verify the token has access to the specific repository

Rate limiting errors

  • Bitbucket Cloud has rate limits based on token type. Workspace Access Tokens generally have higher limits than Repository Access Tokens
  • If you're hitting rate limits, check Bitbucket's rate limit documentation for your token type

Bitbucket-Specific Notes

Bitbucket Cloud vs Bitbucket Data Center

This integration supports Bitbucket Cloud (bitbucket.org) only. Bitbucket Data Center (formerly Bitbucket Server) has a completely different REST API (/rest/api/1.0/). Data Center support may be added in the future.

Diff Retrieval

Bitbucket's diff API differs from GitHub/Gitea:

  • Diffstat (JSON): Returns file-level metadata (status, paths, lines changed) — no actual diff content
  • Raw diff (plain text): Returns the full unified diff for the entire PR

VERDiiiCT fetches both endpoints and combines them to get per-file diffs with change metadata.

Event Header

Unlike other providers that embed the event type in the payload body, Bitbucket sends it in the X-Event-Key header:

  • pullrequest:created — new PR
  • pullrequest:updated — commits pushed to an existing PR
  • pullrequest:fulfilled — PR merged (ignored)
  • pullrequest:rejected — PR declined (ignored)

Jira Integration

Many Bitbucket teams use Jira for issue tracking (referenced as PROJ-123 in PR descriptions). VERDiiiCT currently scans for #123-style issue references in the Bitbucket issue tracker. Jira integration for enriched review context is planned for a future release.


What's Next

Share

Try VERDiiiCT Free

Automate your code reviews with AI. Set up in under 5 minutes — no credit card required.