Baserow and GitLab: Webhooks and REST API for CI/CD

Engineering teams live in GitLab and product or operations teams live in Baserow, and the bridge between them runs on a Baserow database token plus a GitLab personal access token, a webhook that kicks off a pipeline from a table row, and a REST API call the pipeline uses to write its status back into that same row - this guide walks through both sides of the setup plus a lower-code fallback through a third-party automation tool.

Why Connect Baserow and GitLab

GitLab owns the technical execution - source control, CI/CD pipelines, builds, and deploys. Baserow owns the business visibility - sprint priorities, client deliverables, release notes, approvals, and launch communications. Without a bridge between the two, stakeholders keep pinging engineers for status updates while engineers waste time updating tracking tickets by hand.

The integration is typically used to automate issue tracking, keep CI/CD data in sync, or give non-technical users a friendly interface over repository data.

Integration Methods

Method A: low-code automation. The most common way to sync data between the two platforms through a third-party no-code tool: a trigger (“new row in Baserow” or “new issue in GitLab”) fires an action that maps the data and sends it to the other app. Authentication needs a Baserow database token and a GitLab personal access token (PAT).

Method B: native webhooks. Best for lightweight, one-way notifications without an intermediary tool. From Baserow to GitLab, a Baserow webhook pings a GitLab “Trigger Token” URL to start a pipeline. From GitLab to Baserow, a GitLab webhook (system-wide or project-level) posts event data to a Baserow webhook URL.

Common Use Cases

  • External issue intake. Non-technical stakeholders submit a bug through a Baserow form view, which automatically creates a GitLab issue.
  • Release management. Deployment status lives in a Baserow table, and marking a row “Ready to Deploy” triggers the GitLab pipeline.
  • Pipeline history. Every successful GitLab pipeline run gets recorded in a Baserow table for long-term reporting.
AreaIn GitLabIn Baserow
Release managementPipelines deploy code to staging and production based on tags (for example v2.4.0)Release managers plan the contents of v2.4.0, track approvals from legal and marketing, and build the changelog
Incident responseDevelopers close the issues tied to a production outageThe SRE team keeps an incident log in Baserow: time to resolution, impact analysis, post-mortem notes
Feature flagsEngineers implement flags in code to toggle functionalityProduct teams control the rollout percentage in Baserow; a webhook syncs the “Rollout %” field into the application config
ComplianceGitLab holds the commit history and pipeline logsBaserow holds the change-request forms auditors expect, linking specific GitLab commits to business approvals

Closed Loop: Baserow Row - GitLab Pipeline - Baserow Row

The most reliable way to wire the two tools together is to tie a Baserow row ID to a GitLab pipeline run:

  1. Trigger: Baserow sends a webhook containing a Row ID to GitLab.
  2. Context: GitLab accepts that ID and stores it as a variable for the pipeline’s duration.
  3. Feedback: once the pipeline finishes, pass or fail, GitLab uses that same ID to write the status back into the specific Baserow row.

What follows is that bridge: a “listener” job added to the GitLab pipeline and a “dispatcher” webhook added to the Baserow table, without replacing any existing scripts.

Prerequisites

  • GitLab: a project with CI/CD enabled and Maintainer access.
  • Baserow: a database (API) token with write permissions.

Step 1: Set Up Authentication

Both tools need permission to talk to each other.

  1. In Baserow, go to Settings → Database Tokens, create a new token with Write permissions, and copy it.
  2. In GitLab, go to Settings → CI/CD → Variables.
  3. Add a variable named BASEROW_TOKEN.
  4. Paste the Baserow token as its value.
  5. Check “Mask variable” to keep it out of the logs.

Step 2: The GitLab Listener

Add a trigger job to the existing .gitlab-ci.yml file - it only runs when Baserow calls it, and it wraps the scripts that already exist:

baserow_trigger_job:
  stage: deploy
  image: badouralix/curl-jq
  rules:
    # Only run this job when triggered via the API (for example, a Baserow webhook)
    - if: $CI_PIPELINE_SOURCE == "trigger"
  script:
    # 1. READ: capture the Row ID sent by Baserow
    - export ROW_ID=$(cat $TRIGGER_PAYLOAD | jq -r '.items[0].id')

    # 2. WRITE: tell Baserow the job has started
    # Replace [YOUR_TABLE_ID] with the ID from the table's URL
    - |
      curl -X PATCH \
        -H "Authorization: Token ${BASEROW_TOKEN}" \
        -H "Content-Type: application/json" \
        -d '{"Status": "In Progress", "GitLab Job ID": "'"$CI_PIPELINE_ID"'"}' \
        "https://api.baserow.io/api/database/rows/table/[YOUR_TABLE_ID]/${ROW_ID}/?user_field_names=true"

    # 3. RUN: existing deployment or test scripts go here
    - echo "Running existing workflows..."
    - ./your_deploy_script.sh

    # 4. FINISH: tell Baserow the job is done
    - |
      curl -X PATCH \
        -H "Authorization: Token ${BASEROW_TOKEN}" \
        -H "Content-Type: application/json" \
        -d '{"Status": "Done", "Deploy Link": "'"$CI_PIPELINE_URL"'"}' \
        "https://api.baserow.io/api/database/rows/table/[YOUR_TABLE_ID]/${ROW_ID}/?user_field_names=true"

The exact JSON structure Baserow sends can be inspected under the webhook’s “Last Trigger” tab.

How the logic works: $TRIGGER_PAYLOAD is where GitLab stores the row data Baserow sent when it called the pipeline; jq pulls the triggering row’s id out of it. curl -X PATCH is the universal way to update a row through the Baserow REST API - the captured ROW_ID guarantees the update lands on the exact record that requested the build.

Step 3: Configure Baserow

With GitLab ready to listen, the last piece is telling Baserow where to send the request.

  1. Generate a trigger token in GitLab: go to Settings → CI/CD → Pipeline triggers, add a trigger (for example, “Baserow”), and copy the generated webhook URL (it looks like https://gitlab.com/api/...token=TOKEN).
  2. Create the webhook in Baserow: open the target table, select Webhooks from the table menu, paste the GitLab URL into the URL field, set the method to POST, and choose the triggering event (for example “Row Created” or “Row Updated”).

For the mechanics of webhooks in general, see Webhooks in Baserow .

Applying the Pattern Anywhere

This works regardless of a table’s specific column names - just map the fields in the curl command to the actual columns.

Use caseBaserow triggerGitLab action
Release managementA row is created in the “Releases” tableRun deploy_prod.sh and set the Baserow status to “Live”
Report generationStatus changes to “Generate Report”A Python script builds a PDF and posts the link back to Baserow
Employee provisioningA “New Employee” row is addedA script creates accounts and pastes a temporary password back into Baserow

Handling Failures

Add an after_script to the GitLab job - it runs even when the main script fails, and it can push a {"Status": "Failed"} update back to Baserow so the team notices right away:

after_script:
    - |
      if [ "$CI_JOB_STATUS" != "success" ]; then
        curl -X PATCH -H "Authorization: Token ${BASEROW_TOKEN}" \
        -H "Content-Type: application/json" \
        -d '{"Status": "Failed"}' \
        "https://api.baserow.io/api/database/rows/table/[YOUR_TABLE_ID]/${ROW_ID}/?user_field_names=true"
      fi

Frequently Asked Questions

Can several columns be updated in one call? Yes - the curl -d body can include as many field-value pairs as needed, for example {"Status": "Done", "deployed_at": "2024-01-01"}.

How can I confirm Baserow’s request actually reached GitLab? Check the webhook’s “Last Trigger” tab in Baserow - it shows the response code and the exact request body that was sent to GitLab.

Do the status names in the examples have to match exactly? No, the status names, field names, and variables in the examples are placeholders - use whatever column names the table already has and drop them into the curl request body.

Related reading: Baserow database (API) tokens for issuing keys with the right permissions, and the Baserow REST API overview for direct calls without webhooks.

Reviewed by OpenNix LLC · Last updated on