Tools Connect: Jenkins

Tools Connect: Jenkins


Allstacks pulls data about triggered build runs, and what, if any, processes triggered them so you can identify potential bottlenecks.

For Jenkins, the supported integration method is Custom CI/CD.

Instead of Allstacks pulling data from Jenkins, Jenkins sends build events directly to Allstacks using a secure webhook.

This approach is:

  • Reliable

  • Fast

  • Works with any Jenkins setup

  • Avoids timeout and polling issues


How it works

  1. Jenkins runs a job

  2. Jenkins sends job data to Allstacks

  3. Allstacks records the job and updates metrics

No polling is required.


Prerequisites

Before connecting Jenkins to Allstacks, make sure the following are completed.


1. Create a Custom CI/CD Service

A Custom CI/CD service must already exist in your Allstacks organization.

To create one:

  1. Go to your organization’s Tools page in Allstacks

  2. Click Tool

    image-20260123-203039.png
  3. Search for Custom CI/CD

  4. Select it and name it Jenkins

  5. Click Add Tool

    image-20260123-203100.png

 

This service will be used to route your Jenkins build data into Allstacks.


2. Create a Personal Access Token (PAT)

A Personal Access Token (PAT) is required to authenticate requests sent from Jenkins to Allstacks.

To create a PAT:

  1. Open the org menu (top-right corner, click org name)

  2. Go to Personal Access Tokens

    image-20260123-203039.png
  3. Click Create PAT

  4. Enter:

  • Jenkins for the Token name

  • Select Webhook Token

  • An expiration date (optional)

  • Click Submit

    image-20260123-203640.png

Save the token securely

You will use this token in your webhook requests as a Bearer token in the Authorization header.


Webhook Endpoint

Send data using the following endpoint:

POST

https://app.allstacks.com/webhook/company/<company_id>/cicd_job

Authentication

Each request must include these headers:

Authorization: Bearer <token> Content-Type: application/json

Required Fields

These fields must be included in every request:

Field

Type

Description

Field

Type

Description

job_id

String

Your job’s ID (does not need to be globally unique)

commit_sha

String

Full commit SHA (40 or 64 chars)

service_id

Integer

Custom CD Service ID in Allstacks

job_start_time

Integer

Start time (epoch seconds)

job_duration

Integer

Job length (seconds)

status

String

Succeeded, Failed, or On Hold

repo_id or repo_name

String

One is required


Optional Fields

Field

Type

Default

Field

Type

Default

triggered_by

String

Custom CD Agent

job_type

String

CUSTOM_CD_JOB

You may include up to 20 additional properties to enrich your job data.

Format:

{ "key": "environment", "value": "production", "type": "string" }

Supported types:

  • string

  • integer

  • float

  • duration (seconds)

  • timestamp (epoch seconds)

Values may be single or lists (maximum 20 items).


Example: curl (Linux / macOS)

curl -X POST https://app.allstacks.com/webhook/company/<company_id>/cicd_job \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "job_id": "jenkins-42", "commit_sha": "a3f5c9d8e7b6a1c2d3e4f5a6b7c8d9e0f1a2b3c4", "service_id": 1234, "job_start_time": 1737645600, "job_duration": 180, "status": "Succeeded", "repo_name": "payments-service", "triggered_by": "ci@company.com", "job_type": "DEPLOY", "properties": [ { "key": "environment", "value": "production", "type": "string" } ] }'

Example: Groovy (Windows / Jenkins Pipeline)

import groovy.json.JsonOutput def payload = [ job_id: "jenkins-${env.BUILD_NUMBER}", commit_sha: env.GIT_COMMIT, service_id: 1234, job_start_time: (System.currentTimeMillis() / 1000).toLong(), job_duration: 180, status: currentBuild.currentResult, repo_name: "payments-service", triggered_by: "Custom CD Agent", job_type: "CUSTOM_CD_JOB" ] def conn = new URL("https://app.allstacks.com/webhook/company/<company_id>/cicd_job").openConnection() conn.setRequestMethod("POST") conn.setRequestProperty("Authorization", "Bearer <token>") conn.setRequestProperty("Content-Type", "application/json") conn.setDoOutput(true) conn.outputStream.withWriter("UTF-8") { it.write(JsonOutput.toJson(payload)) } println "Response: ${conn.responseCode}"

Pre-Flight Checklist

Before testing your integration:

  • Endpoint URL is correct

  • Authorization header is set

  • Token is valid

  • All required fields are included

  • Timestamps are in epoch seconds

  • Jenkins can reach app.allstacks.com over HTTPS (port 443)

  • A test request is sent using curl or Postman


Troubleshooting

401 Unauthorized

Authentication token is missing or invalid
→ Verify Authorization header and token

400 Bad Request

Payload is missing required fields or contains invalid values
→ Validate required fields and formats

Job not appearing in Allstacks

→ Verify service_id
→ Confirm repo_name or repo_id
→ Log the response code from Jenkins

Network errors

→ Ensure outbound HTTPS (443) access to app.allstacks.com


Mini FAQ

  • Is this the recommended Jenkins integration?
    Yes. This is the supported and intended method.

 

  • Do I need a Jenkins API token?
    No. Only an Allstacks bearer token is required.

 

  • Does this work behind a firewall or VPN?
    Yes. Jenkins only needs outbound HTTPS access.

 

  • How many optional properties can I send?
    Up to 20.

 

  • What time format should I use?
    Epoch seconds.

 

  • What happens if triggered_by is missing?
    It defaults to Custom CD Agent.