> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/internal-developer-portal/use-idp/software-catalog/create-entity/catalog-discovery/custom-integrations/jenkins.md).

# Jenkins using Custom Integrations

Send Jenkins build data into Harness IDP with a Custom Integration and show it on your catalog entities, using the built-in Jenkins source.

You can bring Jenkins build data into Harness IDP with a [Custom Integration](/internal-developer-portal/use-idp/software-catalog/create-entity/catalog-discovery/custom-integrations.md). You create the integration that uses the **Build** schema, push a record from your Jenkins pipeline after each run, and the data appears on a dedicated tab on the matching catalog entity.

![Jenkins build data on a catalog entity](https://1305598861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1bzrz9ybUGCcYdvS4u0z%2Fuploads%2Fgit-blob-810d54eb6a8e925933d7ea2b1cddc0e081bf5a3c%2Fjenkins-catalog-tab.png?alt=media)

***

## Before you begin

* The **`IDP_INTEGRATIONS`** and **`IDP_CUSTOM_INTEGRATION`** feature flags must be enabled for your account. Contact [Harness Support](https://www.harness.io/support) to enable them.
* You need permissions to create and edit integrations at the scope where you are working.
* You need a Harness [Service Account Token (SAT)](https://developer.harness.io/harness-platform/use-harness-platform/platform-access-control/add-and-manage-service-account) or [Personal Access Token (PAT)](https://developer.harness.io/harness-platform/use-harness-platform/automation/api/add-and-manage-api-keys#create-personal-api-keys-and-tokens), that your pipeline uses to authenticate.
* You need a catalog entity to attach the build data to.

***

## Step 1: Create the integration

To create the integration, complete the following steps:

1. In Harness IDP, go to **Configure** → **Integrations**.
2. Select **Custom Integrations** at the top right, then select **+ New Custom Integration**.

   ![Custom Integrations tab and New Custom Integration button](https://1305598861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1bzrz9ybUGCcYdvS4u0z%2Fuploads%2Fgit-blob-bbc0f87d6b8cff5ca4550e947cec159cc493b9d5%2Fjenkins-new-custom-integration.png?alt=media)
3. In **Setup & Identity**, enter a name in **Integration Name**. The **ID** is generated from this name and becomes part of the endpoint URL, so it cannot be changed later.

***

## Step 2: Configure the integration

To configure the integration, complete the following steps:

1. Under **Integration Configuration**, select the **API** card. Jenkins will push data to Harness from a pipeline step.
2. Set **Data schema** to **Build**. The prefilled Build schema covers the fields produced by a Jenkins run, so a custom schema is not required.
3. Set **Source** to **Jenkins**.

   ![Data schema set to Build and Source set to Jenkins](https://1305598861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1bzrz9ybUGCcYdvS4u0z%2Fuploads%2Fgit-blob-2ff6fb41a148e3f670ed788678c2ab2f6553cc2b%2Fjenkins-source-select.png?alt=media)
4. (Optional) Under **Correlation Mapping**, map a payload field to a catalog attribute if you are not sending `entity_ref` in the payload. For example, map `service` to `metadata.name`. Go to [Configure Correlation Mapping](/internal-developer-portal/use-idp/software-catalog/create-entity/catalog-discovery/custom-integrations/create-custom-integration.md#step-5-configure-correlation-mapping-optional) to set up the mapping.
5. Select **Confirm & Enable**.

***

## Step 3: Know the endpoint

To find the endpoint, complete the following steps:

1. Open the integration you created, and go to its **Overview** tab.
2. Copy the **Upsert Endpoint**. It has this shape:

```http
POST https://app.harness.io/gateway/integration/api/v1/accounts/{accountId}/integrations/{integrationId}/data/build
```

![Overview tab showing the Upsert endpoint and Build schema](https://1305598861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1bzrz9ybUGCcYdvS4u0z%2Fuploads%2Fgit-blob-f6dba17ec3645dd928325cf6fa80973683c90d8a%2Fjenkins-overview-endpoint.png?alt=media)

Authentication uses your SAT or PAT, passed in the `x-api-key` header. Go to [Ingest data](/internal-developer-portal/use-idp/software-catalog/create-entity/catalog-discovery/custom-integrations/ingest-data.md) to review the full header and payload details.

***

## Step 4: Push build data from Jenkins

You can have a step at the end of your Jenkins pipeline that sends a build record to the Upsert endpoint. The authentication method and the schema to be passed to the endpoint are shown on the same page.

{% hint style="info" %}
`identifier` is the record's key. Reuse the same value across a run to update the record in place, for example pushing `RUNNING` when the build starts and `SUCCESS` when it finishes. Use a genuinely unique value per build, such as the Jenkins build number.
{% endhint %}

The following is a sample curl request:

```sh
curl \
--location 'https://app.harness.io/gateway/integration/api/v1/accounts/<ACCOUNT_ID>/integrations/<INTEGRATION_ID>/data/build' \
--header 'Content-Type: application/json' \
--header 'x-api-key: <HARNESS_TOKEN>' \
--header 'Harness-Account: <ACCOUNT_ID>' \
--data '{
  "records": [
    {
      "identifier": "run-10001",
      "name": "petclinic-build #10001",
      "entity_ref": "component:account/petclinicdemo",
      "service": "petclinicdemo",
      "timestamp": "2026-09-15T14:08:00Z",
      "status": "SUCCESS",
      "branch": "main",
      "sha": "a1b2c3d",
      "repositoryUrl": "https://github.com/harness/petclinic-backend",
      "buildNumber": 10001,
      "durationInSec": 245,
      "url": "https://jenkins.example.com/job/petclinic/10001",
      "customData": { "tests": { "passed": 100, "skipped": 10, "total": 110 } }
    }
  ]
}'
```

Store your Harness Token as a Jenkins credential [secret](https://developer.harness.io/harness-platform/use-harness-platform/secrets/secrets-management/harness-secret-manager-overview) rather than hardcoding it. Confirm the push landed on the integration's **Events** tab. Go to [Monitor ingestion](/internal-developer-portal/use-idp/software-catalog/create-entity/catalog-discovery/custom-integrations/ingest-data.md#monitor-ingestion-with-the-events-tab) to track each push.

***

## Step 5: Add the Jenkins tab to your entity layout

You can surface the ingested data by adding a tab to the entity layout. This is a one-time step per entity kind and type.

1. Go to **Configure** → **Layout** → **Catalog Entities**.
2. Edit the layout for the entity kind and type that your builds correlate to, for example kind `Component`, type `Service`.
3. In the YAML editor, add a Jenkins tab. Unlike a plain Custom Integration tab, the Jenkins tab sets `source: jenkins` and uses a `config.columns` block (as shown in the below YAML snippet) to lay out the columns, including a **Tests** column driven by `customData`:

   ```yaml
       - name: Jenkins
         path: /jenkins
         title: Jenkins
         contents:
           - component: CustomIntegrationTab
             specs:
               props:
                 type: build
                 source: jenkins
                 config:
                   columns:
                     - name: Source
                       accessorKey: spec.branch
                     - name: Build
                       accessorKey: spec.name
                     - name: Tests
                       accessorKey: tests
                       passedPath: spec.customData.tests.passed
                       totalPath: spec.customData.tests.total
                       skippedPath: spec.customData.tests.skipped
                     - name: Status
                       accessorKey: spec.status
                     - name: Last Run Duration
                       accessorKey: spec.durationInSec
                     - name: Timestamp
                       accessorKey: spec.timestamp
                     - name: Actions
                       accessorKey: spec.url
   ```

   ![Layout for Jenkins tab](https://1305598861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1bzrz9ybUGCcYdvS4u0z%2Fuploads%2Fgit-blob-fb7f58f039551ead393514108ddc82721d1dd328%2Fjenkins-tab-layout.png?alt=media)
4. Click **Save**.

Go to [View data in the catalog](/internal-developer-portal/use-idp/software-catalog/create-entity/catalog-discovery/custom-integrations/view-data-in-catalog.md#configure-the-layout) to review the general layout mechanics.

***

## Step 6: View the data

Open the entity in the **Catalog** and select the **Jenkins** tab, or the tab name you configured in the layout.

Each build appears as a row with its source branch, build name, test summary, status, duration, and timestamp. Select a row to open the full record.

![Jenkins tab with build rows, filters, and record details](https://1305598861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1bzrz9ybUGCcYdvS4u0z%2Fuploads%2Fgit-blob-b19a4417e7c68a8dfb42f3ae876603ae5198b258%2Fjenkins-catalog-result.png?alt=media)

Two dropdowns above the table let you filter the builds:

* **Integration**: Lists the Jenkins Custom Integration(s) contributing to this entity, so you can view builds from one integration at a time. This tab shows builds from Jenkins-source integrations, and not from other build tools.
* **Status**: Filters by build status.

The **Tests** column shows the number of passed, skipped, and total tests for each record.

![Rendered Records](https://1305598861-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1bzrz9ybUGCcYdvS4u0z%2Fuploads%2Fgit-blob-59b58af419d4cf4e9babee0a5ad88a1bb72add07%2Fjenkins-result-render.png?alt=media)

Assume the below upserted values to check how data is displayed in the **Tests** column of Jenkins tab:

| `passed` |    `skipped` |      `total` | **Tests** column shows        |
| -------: | -----------: | -----------: | ----------------------------- |
|      100 |           10 |          110 | `100/110 Passed (10 Skipped)` |
|      100 |            0 |          110 | `100/110 Passed`              |
|      100 | Not provided | Not provided | `100 Passed`                  |
