> ## Documentation Index
> Fetch the complete documentation index at: https://docs.katilyst.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrating to JIRA

> Award credit automatically when a champion closes a vulnerability ticket.

This guide connects JIRA to Katilyst with no code. When a champion completes a piece of security work in JIRA, JIRA posts the event to Katilyst and the champion earns credit.

The pattern applies to any work item that reaches a completed state. How you recognize that state, how you tell security work apart from everything else, and how you identify the champion all depend on how your organization models this in JIRA, so treat the specifics below as a worked example rather than a template.

## Prerequisites

* **A Katilyst API key.** An Account Admin generates one from the Admin Portal. Have it in hand before you start (keys are shown once when generated, and a lost key cannot be recovered.)
* **Permission to create automation rules** in the JIRA space you are working in.
* **A decision on the three mappings below.**

## Decide your three mappings

Every organization runs JIRA differently, and these three choices determine how your rule is built. Work them out before you open the automation editor.

| What you are deciding | Common approaches | Where it lands in the rule |
| - | - | - |
| **What signals the work is complete** | A transition to Done, Resolved, or Closed; a resolution being set; a custom status like Remediated or Verified | The trigger |
| **What marks the work as security work** | A dedicated work item type such as Vulnerability; a Bug carrying a security label; a component, a security-specific project, or a custom field | The conditions |
| **Who earns the credit** | The assignee; the reporter; a Security Champion custom field; a team or owner field | The `userEmail` value in the request body |

The third one deserves the most thought. Credit goes to whoever your program intends to recognize, and the person who closes a ticket is sometimes an administrator rather than the engineer who did the work. If your program recognizes the fixer, the assignee is usually right. If it recognizes whoever championed the work through to completion, a dedicated field serves you better.

Whatever you choose has to produce an email address that matches a User in your Katilyst Project.

## Configure the action in Katilyst

**1. Create an Available Action**

In Katilyst, create an Instance action named something recognizable, such as **JIRA — Vulnerability Remediated**. Set the Attribute it changes, the amount, and any frequency limit.

This is program configuration rather than integration work, and it is what lets you retune the reward later without touching JIRA.

> [!TIP]
>
> Instance actions award credit every time they are logged, which is what you want for ticket closures. See [Core concepts](https://docs.katilyst.com/core-concepts.md) for how this differs from State actions.

**2. Find your project ID**

Call [List projects](https://docs.katilyst.com/api-reference/v1/list-projects.md) and note the `id` of the program you are integrating with.

```bash theme={null}
curl https://api.katilyst.com/v1/projects \
  -H "Authorization: API-Key your_key_here"
```

**3. Find your action ID**

Call [List a project's available actions](https://docs.katilyst.com/api-reference/v1/list-a-projects-available-actions.md) for that project and note the `id` of the action you just created.

```bash theme={null}
curl https://api.katilyst.com/v1/projects/{projectId}/available-actions \
  -H "Authorization: API-Key your_key_here"
```

> [!TIP]
>
> You only do these two lookups once, by hand. Paste both IDs somewhere safe before moving to JIRA.

## Build the automation rule

The steps below use one common setup as a worked example: a Vulnerability work item type, a transition to Done, and a Security Champion custom field. Substitute your own mappings as you go.

**1. Create the rule**

In the JIRA space holding your security work, go to **Space settings → Automation → Create rule**. Older Jira versions label this **Project settings**.

**2. Set the trigger**

Choose **Work item transitioned**, and set the destination to the status that means the work is finished in your workflow.

In the worked example that is **Done**. Your workflow may use Resolved, Closed, Remediated, or a status specific to your security process. If more than one status counts as finished, list them all — the trigger accepts several.

> [!TIP]
>
> If your workflow sets a resolution rather than moving to a distinct status, **Work item resolved** is the cleaner trigger and saves you maintaining a list of statuses.

**3. Set the conditions**

Conditions are where you control what counts. Without them, every completed work item of any kind earns credit.

You need enough conditions to isolate security work and to confirm there is someone to credit. In the worked example that is a pair:

* Work item type is **Vulnerability**
* The **Security Champion** field is not empty

Your equivalent might instead be a Bug carrying a `security` label, anything in a particular component, or every item in a dedicated security space. Match whatever your teams already do rather than asking them to change for this rule — an automation that depends on a new convention stops working the moment someone forgets it.

Add a condition confirming the field you are crediting is populated, whichever field that is. It costs nothing and it prevents calls that fail validation.

> [!WARNING]
>
> Frequency limits configured on an Available Action do not apply to actions logged through the API, so your conditions are the only thing limiting how often this rule awards credit. A bulk transition closing fifty tickets at once will log fifty actions. If that is a realistic scenario in your workflow, constrain the rule here rather than relying on the limit set in Katilyst.

**4. Add the web request action**

Choose **Then: Add an action → Send web request**. It sits under the **Notifications** category, which is easy to scroll past when you are looking for something network-shaped.

![JIRA SS 1](https://mintcdn.com/katilyst/M-0XxNzKIPczQ0v4/images/JIRA-SS-1.png?fit=max\&auto=format\&n=M-0XxNzKIPczQ0v4\&q=85\&s=19e95430dd1a7642a622ea5a9fa87ef7)

Send web request, under the Notifications category in the action picker

Set the request itself:

| Field | Value |
| - | - |
| Web request URL | `https://api.katilyst.com/v1/logged-actions` |
| HTTP method | `POST` |
| Web request body | Custom data |

Then add two headers. These are key and value pairs, added one at a time rather than pasted in together.

| Key | Value |
| - | - |
| `Authorization` | `API-Key ` followed by your key |
| `Content-Type` | `application/json` |

> [!WARNING]
>
> The `API-Key` prefix is part of the header value, with a space after it. Pasting the token on its own returns a `401`, and it is the most common setup mistake on this integration.

Your API key is stored in the rule configuration, where anyone who can edit automation rules in this space can read it. Treat edit access accordingly, and check whether your version of Jira offers a hidden or secret option on header values.

> [!NOTE]
>
> Screenshots in this guide show JIRA Cloud as of October 2026. Atlassian moves things occasionally, so the labels matter more than the exact layout.

**5. Build the request body**

```json theme={null}
{
  "userEmail": "{{issue.assignee.emailAddress}}",
  "availableActionId": "1111-2222-3333-action-id",
  "creator": "JIRA Automation",
  "details": "{{issue.key}} — {{issue.summary}}"
}
```

Only `userEmail` and `availableActionId` are required. `creator` appears in the champion's action log, so make it recognizable.

`{{issue.assignee.emailAddress}}` reflects the worked example. Swap it for the smart value matching the field you decided to credit — `{{issue.reporter.emailAddress}}` for the reporter, or `{{issue.customfield_XXXXX.emailAddress}}` for a user picker field, where the ID comes from your JIRA custom field configuration.

> [!WARNING]
>
> Test the smart value before you rely on it. A custom field that holds free text rather than a JIRA user returns the raw string, and a field left empty returns nothing at all — both produce a `400` from Katilyst.

> [!TIP]
>
> `dateTime` is left out on purpose. The field is optional, and Katilyst stamps the action when it receives the call. Because the rule fires the moment the ticket transitions, those two times are the same for practical purposes.
>
> Add it if you ever point this rule at historical tickets, where the moment of receipt and the moment of the work would differ by weeks or months.

![JIRA SS 2](https://mintcdn.com/katilyst/M-0XxNzKIPczQ0v4/images/JIRA-SS-2.png?fit=max\&auto=format\&n=M-0XxNzKIPczQ0v4\&q=85\&s=7fb54ff4a5f1844c604719423a1aaaa3)

The configured web request, with Custom data selected and the body filled in

Leave **Delay execution** and **Validate response** at their defaults.

## Verify

Create a test work item that satisfies your conditions, populate the field you are crediting, and move it to your completed status.

1. Check the rule's **Audit log** in JIRA for a successful run.
2. Call [List a user's logged actions](https://docs.katilyst.com/api-reference/v1/list-a-users-logged-actions.md) and confirm the award landed.

```bash theme={null}
curl "https://api.katilyst.com/v1/projects/{projectId}/users/{userId}/logged-actions" \
  -H "Authorization: API-Key your_key_here"
```

Read the `status` field on the result. `APPROVED` means the reward applied.

![Screenshot 2026 10 07 102602](https://mintcdn.com/katilyst/M-0XxNzKIPczQ0v4/images/Screenshot-2026-10-07-102602.png?fit=max\&auto=format\&n=M-0XxNzKIPczQ0v4\&q=85\&s=a500ba75b0017cec2351e1c710b08eaa)

A successful run in the JIRA audit log

## Troubleshooting

* **The rule runs and no reward appears.** Check `status` on the logged action. `PENDING` means the Available Action requires admin approval and is waiting for it, which is program configuration rather than an integration fault. If you see `LIMIT_EXCEEDED_TIMEFRAME`, that action was submitted inside the platform rather than by your rule — frequency limits do not apply to API calls.
* **A `409` response.** The champion is not eligible for that Available Action, usually because a condition on it was not satisfied. The request was well formed and the program's own rules declined it.
* **A `400` response.** Usually the email does not match a User in that Katilyst Project, or the smart value resolved to something that is not an email address. Check what the audit log shows the rule actually sent, then call [List a project's users](https://docs.katilyst.com/api-reference/v1/list-a-projects-users.md) to see what Katilyst has on file.
* **A `401` response.** The key is invalid, missing, or was pasted without the `API-Key` prefix on the header value. An invalid key is the most common cause — confirm it has not been rotated or revoked since the rule was built.
* **Nothing in the audit log.** The trigger or conditions did not match. This is the most common outcome on a first attempt, and it almost always means one of the three mappings is off. Strip the rule back to the trigger alone, confirm it fires, then add conditions one at a time.

> [!WARNING]
>
> Email addresses have to match. If your JIRA accounts use a different domain than your Katilyst roster, map them before building this rule.

## Related

> **[Core concepts](https://docs.katilyst.com/core-concepts.md)**
>
> Instance versus State actions, guardrails, and how rewards are decided.

> **[Log an action](https://docs.katilyst.com/api-reference/v1/log-an-action.md)**
>
> Full reference for the endpoint this guide calls.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.