Every sprint starts with a board filled with tickets and a bunch that desires somewhere clean to art work. For companies operating client WordPress duties on two-week cycles, this means creating a staging setting in MyKinsta faster than the principle price tag is picked up.
This takes a few minutes, nevertheless it indisputably’s the kind of process that falls all the way through the cracks as it sounds as if to be like trivial.
The Kinsta API can remove that step. When a touch starts in Jira, you’ll organize a webhook that triggers an fit in middleware, which then reads the payload, maps it to a Kinsta internet website online, and calls the API to create a brand spanking new staging atmosphere.
Why companies should automate atmosphere provisioning
Rising an environment after you intend a touch method opening MyKinsta, finding the best client internet website online from a list of dozens, growing and naming an environment, and then returning to Jira. While this isn’t tricky, it does want to happen on the right kind time, every time, and for every client problem operating.
Skipping it method a bunch starts art work inside the ultimate sprint’s atmosphere. From there, changes accumulate on best possible of each other, and when there’s a malicious program, retaining aside it’s further like archaeology than debugging.
What you wish to have faster than you get began
To connect the Kinsta API and Jira, you wish to have a Kinsta account with at least one WordPress internet website online in an present atmosphere, a Jira Cloud account with administrator get right to use to configure webhooks, and Node.js installed locally.
To authenticate with the Kinsta API, navigate to [Your company] > Company settings > API Keys in MyKinsta and click on on Create API Key.

Next, give the essential factor a name, set an expiry length, and click on on Generate. The key is a one-time display, so remember it down faster than you move on.
You set this in a .env document at the problem root alongside your Kinsta company ID, which you’ll find underneath Company settings > Billing Details:
KINSTA_API_KEY=your_api_key_here
KINSTA_COMPANY_ID=your_company_id_here
Get your Jira and Kinsta internet website online IDs
You want the Kinsta internet website online ID for each and every client problem inside the automation. It is a UUID that Kinsta assigns at internet website online creation. Apparently inside the MyKinsta URL when you open a internet website online or by the use of polling GET /web pages title once your API key’s in place:
https://my.kinsta.com/web pages/details/fbab4927-e354-4044-b226-29ac0fbd20ca/…
On the Jira side, you wish to have the numerical board ID for each and every problem you wish to have to connect. Apparently inside the URL (appropriate right here as 2):
https://your-domain.atlassian.internet/jira/instrument/duties/SCRUM/boards/2
This is the same value Jira comprises inside the sprint_started webhook payload as originBoardId. The mapping of board IDs to internet website online IDs lives in your .env document:
BOARD_ID_CLIENT_A=2
SITE_ID_CLIENT_A=fbab4927-e354-4044-b226-29ac0fbd20ca
BOARD_ID_CLIENT_B=5
SITE_ID_CLIENT_B=44b5a6d1-c83f-4b0e-9a1c-2e7dbc903fa1
Moreover, for local development, Jira can’t reach localhost instantly. Ngrok can be used to expose an area port to the internet with a temporary public URL, which you’ll use as your webhook endpoint all over the place development. After getting a deployed middleware take care of, you’ll change it.
Simple find out how to automate sprint atmosphere provisioning with Jira and the Kinsta API
This integration runs all through two tactics. In Jira, a webhook fires when a touch starts and delivers the improvement payload in your middleware. For Kinsta, the middleware reads the board ID from the payload, resolves it to a internet website online ID using the config map, and calls the Kinsta API to create a easy staging atmosphere named after the sprint.
1. Test in a Jira webhook for sprint events
Jira Cloud provides you with two ways to test in a webhook. The easier selection for plenty of teams is all the way through the Jira UI. The Settings > Gadget selection is all through the most efficient right-hand menu:

From there, make a choice Complicated > WebHooks, then click on on Create a WebHook:

Proper right here, enter a name, paste in a middleware URL with /sprint appended (a dummy selection is ok for now), and underneath Events make a choice Sprint > started. This creates an admin webhook, which fires for every sprint_started fit all through all of your Jira instance.

The second selection is the REST API, using POST /rest/webhooks/1.0/webhook. This works smartly when webhook registration is part of a deployment script:
curl -X POST
https://your-domain.atlassian.internet/rest/webhooks/1.0/webhook
-u your-email@example.com:your-api-token
-H 'Content material material-Sort: device/json'
-d '{
"name": "Sprint provisioning webhook",
"url": "https://your-middleware-url.com/sprint",
"events": ["sprint_started"],
"filters": {},
"excludeBody": false
}'
Calling PUT /rest/webhooks/1.0/webhook/refresh supplies an extension to the 30-day time to expire for the webhook. When Jira fires sprint_started, the payload arrives at your endpoint as a JSON POST with the following development:
{
"timestamp": 1705431600000,
"webhookEvent": "sprint_started",
"sprint": {
"id": 15,
"self": "https://your-domain.atlassian.internet/rest/agile/1.0/sprint/15",
"state": "full of life",
"name": "Sprint 12",
"startDate": "2026-02-02T00:00:00.000Z",
"endDate": "2026-02-27T00:00:00.000Z",
"originBoardId": 2,
"goal": "Entire price processing improvements"
}
}
The middleware uses sprint.originBoardId to look up the Kinsta internet website online ID and sprint.name to name the new atmosphere: every sprint_started fit within your Jira instance reaches the endpoint. The board ID glance up inside the config map is what scopes the automation to the best client problem and ignores the whole thing else.
2. Assemble the middleware endpoint
With the webhook in place, you’ll have to next initialize a brand spanking new Node.js problem and arrange Categorical.js alongside dotenv:
npm init -y
npm arrange express dotenv
express handles the routing and request parsing, while dotenv so much your .env document. You want to create app.js to prepare the server. Proper right here’s all the document:
// app.js
const express = require('express');
const crypto = require('crypto');
require('dotenv').config();
const app = express();
// Raw body parser on the /sprint path allows HMAC signature verification
app.use('/sprint', express.raw({ sort: 'device/json' }));
app.use(express.json());
const KinstaAPIUrl = 'https://api.kinsta.com/v2';
const headers = {
'Content material material-Sort': 'device/json',
Authorization: `Bearer ${process.env.KINSTA_API_KEY}`
};
// Board ID to Kinsta internet website online ID config map
const siteConfig = {
[process.env.BOARD_ID_CLIENT_A]: process.env.SITE_ID_CLIENT_A,
[process.env.BOARD_ID_CLIENT_B]: process.env.SITE_ID_CLIENT_B,
};
function verifyJiraSignature(req)
app.submit('/sprint', async (req, res) => {
if (!verifyJiraSignature(req)) {
return res.status(401).json({ message: 'Invalid signature' });
}
const body = JSON.parse(req.body);
const { webhookEvent, sprint } = body;
if (webhookEvent !== 'sprint_started') {
return res.status(200).json({ message: 'Fit neglected' });
}
const boardId = String(sprint.originBoardId);
const siteId = siteConfig[boardId];
if (!siteId) {
console.log(`No internet website online configured for board ${boardId}`);
return res.status(200).json({ message: 'Board now not mapped' });
}
// Kinsta API calls added inside the steps beneath
res.status(200).json({ message: 'Gained' });
});
app.listen(3000, () => console.log('Middleware operating on port 3000'));
To protect the endpoint, you generate a secret key all over the place the webhook setup. Jira makes this not obligatory all over the place setup, nevertheless it indisputably’s nearly an important for a safe instance.
Endpoint protection
Jira signs each and every payload and comprises the result inside the X-Hub-Signature header as sha256=. You add the secret in your .env document alongside the other credentials:
JIRA_WEBHOOK_SECRET=your_webhook_secret_here
The verification function lives in app.js and uses Node’s built-in crypto module. It reads the signature from the request header, computes the predicted HMAC towards the raw request body, and uses timingSafeEqual to test them by some means that prevents timing attacks. Proper right here’s the comparable portion of app.js:
const crypto = require('crypto');
function verifyJiraSignature(req)
This function is the first thing known as inside the POST /sprint path handler. If verification fails, the middleware returns 401 right away, and now not anything runs:
app.submit('/sprint', async (req, res) => {
if (!verifyJiraSignature(req)) {
return res.status(401).json({ message: 'Invalid signature' });
}
const body = JSON.parse(req.body);
// …rest of the handler
});
The path uses express.raw() on the /sprint path because of verifyJiraSignature needs it to compute the HMAC. Once verification passes, JSON.parse(req.body) supplies the identical end result express.json() would have.
3. Authenticate with the Kinsta API and retrieve internet website online environments
All requests to the Kinsta API use Bearer token authentication: the headers constant in app.js handles that for every request inside the device. The require('dotenv').config() line on the most efficient promises the essential factor so much from .env faster than anything else runs, so it in no way turns out inside the provide code itself.
Kinsta uses atmosphere IDs reasonably than internet website online IDs for the provisioning endpoint, so that you’re going to need to add a getEnvironmentId function beneath the headers constant:
const getEnvironmentId = async (siteId) => {
const resp = look forward to fetch(
`${KinstaAPIUrl}/web pages/${siteId}/environments`,
{ approach: 'GET', headers }
);
const data = look forward to resp.json();
return data.internet website online.environments[0].id;
};
This calls GET /web pages/{siteId}/environments and returns the ID of the principle (i.e., live) atmosphere inside the response. If a internet website online uses a few environments and you wish to have to concentrate on a decided on one, have compatibility towards the environment name reasonably than taking the principle end result.
4. Create a easy staging atmosphere using the Kinsta API
With the internet website online and atmosphere IDs resolved, the middleware calls POST /web pages/{siteId}/environments/easy to create the sprint atmosphere. You do this through a createSprintEnvironment function beneath getEnvironmentId:
const createSprintEnvironment = async (siteId, sprintName) => {
const resp = look forward to fetch(
`${KinstaAPIUrl}/web pages/${siteId}/environments/easy`,
{
approach: 'POST',
headers,
body: JSON.stringify({
display_name: sprintName,
is_premium: false
})
}
);
const data = look forward to resp.json();
return data;
};
display_name turns out in MyKinsta, whilst using sprint.name from the Jira payload instantly method each and every atmosphere inside the dashboard fits the sprint it belongs to. The is_premium flag determines whether or not or now not Kinsta provisions this as an extraordinary or top rate staging setting. Setting it to false creates an extraordinary atmosphere.
When the request reaches Kinsta, it returns 202 Authorised with an operation_id reasonably than a completed atmosphere:
{
"operation_id": "environments:add-plain-54fb80af-576c-4fdc-ba4f-b596c83f15a1",
"message": "Together with easy atmosphere in enlargement",
"status": 202
}
Kinsta’s async processing avoids a blocked request thread while the provisioning completes. The operation_id is what you progress to the endpoint to track enlargement. Next, substitute the POST /sprint path to call every functions in assortment:
app.submit('/sprint', async (req, res) => {
if (!verifyJiraSignature(req)) {
return res.status(401).json({ message: 'Invalid signature' });
}
const body = JSON.parse(req.body);
const { webhookEvent, sprint } = body;
if (webhookEvent !== 'sprint_started') {
return res.status(200).json({ message: 'Fit neglected' });
}
const boardId = String(sprint.originBoardId);
const siteId = siteConfig[boardId];
if (!siteId) {
console.log(`No internet website online configured for board ${boardId}`);
return res.status(200).json({ message: 'Board now not mapped' });
}
take a look at {
const envId = look forward to getEnvironmentId(siteId);
const end result = look forward to createSprintEnvironment(siteId, sprint.name);
res.status(200).json(end result);
} catch (err) {
console.error(err);
res.status(500).json({ message: 'Setting creation failed' });
}
});
Using the take a look at block is cleaner than relying on a few if statements. Then again, keep the Jira signature verification on the most efficient of the document as it should run faster than some other code.
5. Poll the operation status and make sure provisioning
To track completion, poll GET /operations/{operation_id} until the status returns as 200 using a pollOperation function beneath createSprintEnvironment:
const pollOperation = async (operationId, intervalMs = 5000, maxAttempts = 12) => {
for (let try = 0; try setTimeout(resolve, intervalMs));
const resp = look forward to fetch(
`${KinstaAPIUrl}/operations/${operationId}`,
{ approach: 'GET', headers }
);
const data = look forward to resp.json();
if (data.status === 200) {
console.log(`Setting in a position: ${operationId}`);
return data;
}
if (data.status >= 400) {
throw new Error(`Operation failed: ${data.message}`);
}
}
throw new Error('Operation timed out after maximum makes an strive');
};
The loop waits 5 seconds between each and every try and covers up to a minute of provisioning time. While 200 indicators completion, any 4xx status indicates a failure to investigate.

If you run all of this with node app.js and get began a touch in Jira, the environment should appear in MyKinsta within a minute or two.
Keep your corporate ahead of the sprint
This integration provisions a clean, named easy staging atmosphere within MyKinsta based on starting a touch in Jira. The webhook fires, the middleware resolves the board ID to a internet website online, the Kinsta API handles the remainder, and the crowd alternatives up their tickets with an environment that is already taking a look forward to them.
When the middleware is in a position to move live, Sevalla is a simple deployment function. You push the problem to a Git provider, connect the repo, add the environment variables, and substitute the Jira webhook URL to the live take care of.
What’s further, Kinsta’s Company Spouse Program is highest for companies that arrange a few client duties. It’s going to come up with trustworthy beef up, co-marketing possible choices, and the kind of infrastructure partnership that is helping the automation layer you’re construction on best possible of the Kinsta API.
The submit Easy methods to automate dash setting provisioning with Jira and the Kinsta API seemed first on Kinsta®.


0 Comments