---
title: "Jira Connector"
description: "Complete Jira Cloud integration guide for syncing issues, projects, and team activity data with Brevo via Tajo."
url: https://tajo.io/docs/connectors/custom/jira/
markdown: https://tajo.io/docs/connectors/custom/jira.md
lang: en-US
robots: noindex
---

# Jira Connector

Connector status: Planned Not built yet. Tajo does not run this connector today.

| Source field | Destination field | Sample value |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

Connect your Jira Cloud instance to Brevo for customer-facing issue tracking, support ticket visibility, and project milestone notifications through Tajo.

## Overview

| Property | Value |
| --- | --- |
| **Platform** | Jira Cloud |
| **Category** | Custom |
| **Setup Complexity** | Moderate |
| **Official Integration** | No |
| **Data Synced** | Issues, Projects, Users, Events |
| **API Type** | REST API v3 |
| **Authentication** | OAuth 2.0 (3LO) / API Token (Basic Auth) |
| **Base URL** | `https://your-domain.atlassian.net/rest/api/3/` |

## Features

- **Issue event sync** - Forward issue create, update, and resolve events to Brevo contact timelines
- **Customer ticket tracking** - Link Jira issues to Brevo contacts for support visibility
- **Project milestone alerts** - Trigger Brevo campaigns on version releases and sprint completions
- **Team capacity data** - Sync workload metrics for operational dashboards
- **Status change events** - Track issue workflow transitions as Brevo events
- **Comment sync** - Forward customer-facing comments to Brevo activity logs

## Prerequisites

Before you begin, ensure you have:

1. A Jira Cloud instance (Jira Software, Jira Service Management, or Jira Work Management)
2. Admin access to create OAuth apps or generate API tokens
3. The Atlassian account email associated with your API token
4. A Brevo account with API access
5. A Tajo account with an active subscription

## Authentication

Jira Cloud supports multiple authentication methods.

### Option 1: OAuth 2.0 (3LO) - Recommended

1. Go to [developer.atlassian.com](https://developer.atlassian.com/console/myapps/)
2. Click **Create** > **OAuth 2.0 integration**
3. Configure callback URL: `https://app.tajo.io/callbacks/jira`
4. Add these scopes:

```
read:jira-work
read:jira-user
write:jira-work
read:me
```

The API URL structure for OAuth 2.0:

```
https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/{resource}
```

### Option 2: API Token (Basic Auth)

1. Go to [id.atlassian.com/manage/api-tokens](https://id.atlassian.com/manage/api-tokens)
2. Click **Create API token**
3. Name it “Tajo Integration”

```bash
# Basic Auth: email as username, API token as password
curl -X GET "https://your-domain.atlassian.net/rest/api/3/myself" \
  -u "email@example.com:$JIRA_API_TOKEN" \
  -H "Accept: application/json"
```

API Token Limitations

API tokens are tied to individual user accounts. If the user is deactivated, the integration breaks. Use OAuth 2.0 for production deployments.

### Connecting to Tajo

```bash
# Using OAuth 2.0
tajo connectors install jira \
  --client-id $JIRA_CLIENT_ID \
  --client-secret $JIRA_CLIENT_SECRET \
  --cloud-id $JIRA_CLOUD_ID

# Using API Token
tajo connectors install jira \
  --site-url your-domain.atlassian.net \
  --email admin@example.com \
  --api-token $JIRA_API_TOKEN
```

## Configuration

### Basic Setup

```yaml
connectors:
  jira:
    enabled: true
    site_url: "your-domain.atlassian.net"
    auth_type: "oauth2"  # or "basic"

    sync:
      issues: true
      projects: true
      users: true
      comments: true
      worklogs: false

    projects:
      - key: "SUPPORT"
        sync_to_list: 22
      - key: "PRODUCT"
        sync_to_list: 23

    issue_types:
      - Bug
      - Story
      - Task
      - Support Request
```

### Field Mapping

Map Jira issue and user fields to Brevo attributes:

```yaml
field_mapping:
  # User fields
  accountId: JIRA_ACCOUNT_ID
  emailAddress: email
  displayName: FIRSTNAME

  # Issue fields mapped to contact events
  issue_key: LAST_TICKET_KEY
  issue_status: LAST_TICKET_STATUS
  issue_priority: LAST_TICKET_PRIORITY
  issue_created: LAST_TICKET_DATE
  resolution: LAST_TICKET_RESOLUTION
```

## API Endpoints

Tajo integrates with the following Jira Cloud REST API v3 endpoints:

| Endpoint | Method | Purpose |
| --- | --- | --- |
| `/rest/api/3/search` | POST | Search issues using JQL |
| `/rest/api/3/issue/{issueIdOrKey}` | GET | Get issue details |
| `/rest/api/3/issue` | POST | Create an issue |
| `/rest/api/3/project` | GET | List all projects |
| `/rest/api/3/project/{projectIdOrKey}` | GET | Get project details |
| `/rest/api/3/user/search` | GET | Search users |
| `/rest/api/3/myself` | GET | Get current user |
| `/rest/api/3/issue/{issueIdOrKey}/comment` | GET | Get issue comments |
| `/rest/api/3/webhook` | POST | Register webhooks |
| `/rest/api/3/status` | GET | Get all statuses |
| `/rest/api/3/priority` | GET | Get all priorities |

## Code Examples

### Initialize Connector

```javascript
import { TajoClient } from '@tajo/sdk';

const tajo = new TajoClient({
  apiKey: process.env.TAJO_API_KEY,
  brevoApiKey: process.env.BREVO_API_KEY
});

await tajo.connectors.connect('jira', {
  clientId: process.env.JIRA_CLIENT_ID,
  clientSecret: process.env.JIRA_CLIENT_SECRET,
  cloudId: process.env.JIRA_CLOUD_ID
});
```

### Sync Support Issues

```javascript
// Sync Jira support issues to Brevo contacts
await tajo.connectors.sync('jira', {
  type: 'incremental',
  resources: ['issues'],
  jql: 'project = SUPPORT AND updated >= -24h',
  batchSize: 50
});

const status = await tajo.connectors.status('jira');
console.log(status);
// {
//   connected: true,
//   lastSync: '2024-03-15T12:00:00Z',
//   issuesTracked: 4560,
//   projectsMonitored: 3,
//   usersLinked: 890
// }
```

### Handle Jira Webhooks

```javascript
app.post('/webhooks/jira', async (req, res) => {
  const event = req.body;

  await tajo.connectors.handleWebhook('jira', {
    event: event.webhookEvent,
    payload: {
      issueKey: event.issue?.key,
      issueType: event.issue?.fields?.issuetype?.name,
      status: event.issue?.fields?.status?.name,
      reporter: event.issue?.fields?.reporter?.emailAddress,
      assignee: event.issue?.fields?.assignee?.emailAddress
    }
  });

  res.status(200).send('OK');
});
```

### Search Issues by Customer

```javascript
// Find all issues reported by a specific customer
const issues = await tajo.connectors.query('jira', {
  jql: 'reporter = "customer@example.com" ORDER BY created DESC',
  maxResults: 20,
  fields: ['summary', 'status', 'priority', 'created']
});
```

## Rate Limits

Jira Cloud enforces rate limits to ensure platform stability:

| Context | Rate Limit |
| --- | --- |
| **REST API** | ~100 requests per 10 seconds per user |
| **Concurrent requests** | 10 concurrent long-running requests |
| **Bulk operations** | Varies by endpoint |

Pagination

Jira uses offset-based pagination with `startAt` and `maxResults` parameters. The default page size is 50, maximum is 100. Tajo handles pagination automatically.

Jira returns a `429 Too Many Requests` response when rate limits are exceeded, with a `Retry-After` header indicating when to retry.

## Troubleshooting

### Common Issues

| Issue | Cause | Solution |
| --- | --- | --- |
| 401 Unauthorized | Invalid token or expired OAuth | Refresh OAuth token or regenerate API token |
| 403 Forbidden | Insufficient permissions | Check user has access to requested project |
| JQL errors | Invalid query syntax | Validate JQL in Jira’s issue search first |
| Webhook not received | Firewall blocking | Ensure webhook URL is publicly accessible |
| Missing fields | Field not in response | Add field to `fields` parameter or use `expand` |

### Debug Mode

```yaml
connectors:
  jira:
    debug: true
    log_level: verbose
    log_api_calls: true
```

### Test Connection

```bash
tajo connectors test jira
# ✓ API authentication successful
# ✓ Project access verified
# ✓ Issue search operational
# ✓ User lookup available
# ✓ Webhook registration active
```

## Best Practices

1. **Use OAuth 2.0 for production** - Avoids dependency on individual user accounts
2. **Filter with JQL** - Only sync relevant issues to reduce API calls
3. **Use webhooks for real-time** - Avoid polling; register webhooks for issue changes
4. **Respect ADF format** - Jira v3 uses Atlassian Document Format for rich text fields
5. **Map project-to-list** - Create separate Brevo lists per Jira project
6. **Handle pagination** - Always iterate through all pages for complete data

## Security

- **OAuth 2.0 (3LO)** - Secure token-based authentication with refresh tokens
- **API Token + Basic Auth** - Base64-encoded credentials over HTTPS
- **HTTPS Only** - All API communication encrypted via TLS 1.2+
- **Scoped Access** - OAuth scopes limit API access to required resources
- **Atlassian Cloud Security** - SOC 2 Type II certified infrastructure
- **Encrypted Storage** - Credentials encrypted at rest in Tajo

## Related Resources

- [GitHub Connector](https://tajo.io/docs/connectors/custom/github)
- [Linear Connector](https://tajo.io/docs/connectors/custom/linear)
- [Gorgias Connector](https://tajo.io/docs/connectors/support/gorgias)
- [Brevo Contacts API](https://tajo.io/docs/contact-management)

## Open-Source Implementation Map

No official open-source repository was found in the current Tajo connector catalog for Jira. Keep this page focused on the verified public API contract and vendor documentation until an official schema, SDK, MCP server, or public integration repository is available.

### Tajo Revamp Checklist

- Verify authentication and scope requirements against the vendor documentation before each connector release.
- Document primary sync objects, external IDs, pagination strategy, and rate limits explicitly.
- Add smoke tests from public API examples rather than undocumented behavior.
- Capture webhook signature verification and replay protection when the vendor supports webhooks.
- Record gaps where no official public repository or schema exists so future maintainers know what still needs source-backed validation.
