Get Started →

    On this page

    How to Integrate OpenClaw with Jira (Cloud + Server)

    Jira is the project management tool that developers love to complain about and organizations refuse to abandon. The platform is genuinely powerful — deep customization, flexible workflows, enterprise-grade permissions — and genuinely frustrating — slow UI, overly complex configuration, and an API that reflects 20 years of accumulated decisions.

    Integrating OpenClaw with Jira is worth the effort. Issue triage, sprint planning queries, and standup digests become significantly less painful with an AI layer in front of Jira’s UI. But there are things to know before you start.

    API Token Setup: Cloud vs. Server

    Jira comes in two flavors with different auth models.

    Jira Cloud

    Cloud instances live at yourcompany.atlassian.net. Authentication uses an API token plus your email address (not a standalone token like most modern APIs).

    Generate an API token:

    1. Go to id.atlassian.com/manage-profile/security/api-tokens
    2. Click Create API token
    3. Name it “OpenClaw”
    4. Copy the token immediately

    The credentials are your Atlassian email and the token, combined as Basic Auth:

    # OpenClaw config for Jira Cloud
    jira_cloud:
      base_url: "https://yourcompany.atlassian.net"
      email: "[email protected]"
      api_token: "ATATT3xFf..."
    

    All API requests use Basic Auth:

    Authorization: Basic base64(email:token)
    

    Jira Server / Data Center

    On-premise instances use a different auth path. Jira Server still supports basic auth with username/password, but the recommended approach is Personal Access Tokens (PATs), introduced in Jira 8.14.

    Generate a PAT on Jira Server:

    1. Go to your Jira instance → Profile → Personal Access Tokens
    2. Create a token with appropriate permissions
    3. Copy it
    # OpenClaw config for Jira Server
    jira_server:
      base_url: "https://jira.yourcompany.internal"
      personal_access_token: "your-PAT-here"
    

    Server PAT auth uses a Bearer token:

    Authorization: Bearer your-PAT-here
    

    The version matters: If your Jira Server is older than 8.14, you’re using basic auth with username/password. Check your version at: Administration → System → System Info.

    OAuth 2.0 (For Multi-User Setups)

    If you’re building a shared OpenClaw setup where multiple team members authenticate with their own Jira credentials, you need OAuth 2.0. This requires registering an application in Atlassian’s developer console and handling the OAuth flow. For personal use, skip OAuth and use API tokens.

    Understanding Jira’s REST API

    Jira’s API base URL for Cloud: https://yourcompany.atlassian.net/rest/api/3/

    Jira Server: https://yourjira.internal/rest/api/2/

    Note the version difference. Cloud uses API v3; Server is typically v2. Some field shapes differ between versions — if you’re copying API examples, verify which version applies.

    Core endpoints:

    GET  /rest/api/3/issue/{issueKey}          # Get issue
    POST /rest/api/3/issue                      # Create issue
    PUT  /rest/api/3/issue/{issueKey}           # Update issue
    GET  /rest/api/3/search?jql={jql}          # JQL search
    POST /rest/api/3/issue/{issueKey}/comment  # Add comment
    GET  /rest/api/3/project/{projectKey}      # Get project
    GET  /rest/api/3/myself                    # Verify auth
    

    Test your credentials:

    @openclaw check jira connection
    

    Internally: GET /rest/api/3/myself — returns your account info if auth is correct.

    JQL: The Query Language That Makes Jira Useful

    JQL (Jira Query Language) is Jira’s search syntax. Mastering it — or letting OpenClaw translate natural language into JQL — is the key to useful automation.

    Natural Language → JQL

    @openclaw show me high-priority bugs in the PLATFORM project assigned to me, unresolved, updated in the last 7 days
    

    OpenClaw constructs:

    project = PLATFORM 
    AND issuetype = Bug 
    AND priority in (High, Highest) 
    AND assignee = currentUser() 
    AND resolution = Unresolved 
    AND updated >= -7d
    ORDER BY updated DESC
    

    And queries:

    GET /rest/api/3/search?jql=[encoded_jql]&fields=summary,status,priority,assignee,updated&maxResults=50
    

    Common JQL Patterns

    Sprint planning:

    project = ENG 
    AND sprint = "Sprint 42" 
    AND status != Done
    ORDER BY priority DESC
    

    Overdue issues:

    project = ENG 
    AND due <= now() 
    AND status != Done 
    AND resolution = Unresolved
    ORDER BY due ASC
    

    Recently created in triage:

    project = ENG 
    AND status = "Backlog" 
    AND created >= -24h
    ORDER BY created DESC
    

    Blocked issues:

    project = ENG 
    AND labels = blocked 
    AND status != Done
    

    Issues by epic:

    "Epic Link" = ENG-100
    

    Issues without epic (orphaned work):

    project = ENG 
    AND "Epic Link" is EMPTY 
    AND issuetype != Epic 
    AND status != Done
    

    JQL Date Functions

    Jira’s date functions are powerful for automation:

    • -7d = 7 days ago
    • -1w = 1 week ago
    • startOfWeek() = start of current week
    • endOfSprint() = end of current sprint
    • now() = current time
    @openclaw what work was completed in the current sprint so far?
    
    project = ENG 
    AND sprint in openSprints() 
    AND status = Done 
    AND resolutiondate >= startOfWeek()
    

    Sprint Planning Automation

    Velocity Analysis

    @openclaw what's the Engineering team's average velocity for the last 5 sprints?
    

    OpenClaw queries completed sprints via the Agile API:

    GET /rest/agile/1.0/board/{boardId}/sprint?state=closed
    

    Fetches story points completed per sprint and calculates average, trend, and variability.

    Sprint Capacity Check

    @openclaw is the current sprint overcommitted?
    

    OpenClaw:

    1. Fetches all issues in the active sprint with story points
    2. Sums committed points
    3. Compares against the team’s average velocity
    4. Flags if committed > velocity × 1.1 (10% buffer threshold)

    Backlog Refinement Suggestions

    @openclaw suggest backlog issues for the next sprint given our velocity of 45 points
    

    OpenClaw:

    1. Fetches prioritized, unassigned backlog issues sorted by priority
    2. Filters for issues with story points estimated
    3. Suggests a combination that totals near 45 points
    4. Prioritizes issues by dependency (checks if they block other issues)

    Issue Triage Automation

    The Triage Problem in Jira

    Jira’s “Backlog” state fills up fast. Without regular triage, you end up with hundreds of unestimated, uncategorized issues that nobody looks at. OpenClaw can systematically work through the backlog.

    @openclaw triage the last 30 days of new backlog issues in PLATFORM project
    

    For each untriaged issue, OpenClaw:

    1. Reads title and description
    2. Classifies issue type (if not set): Bug, Story, Task, Improvement
    3. Suggests priority based on content keywords
    4. Adds appropriate labels
    5. Posts a triage comment explaining the classification

    Triage comment template:

    ? OpenClaw Triage
    
    Type: Bug (detected: "error", "not working")
    Suggested priority: High
    Labels: backend, payments
    
    Reasoning: Mentions payment processing failure in production environment.
    Recommended for: Next sprint or immediate escalation if customer-facing.
    
    Review and adjust as needed.
    

    The comment makes the automation auditable — you can review OpenClaw’s reasoning and override where it’s wrong.

    The “Why Jira Webhooks Are Flaky” Workaround

    Jira webhooks exist, but they have a reputation for unreliability. Here’s why and what to do about it.

    The Problem

    Jira Cloud webhooks are generally reliable but have issues:

    1. Delivery lag: Webhook payloads can be delayed by 30+ seconds during high-traffic periods
    2. Duplicate delivery: Jira occasionally delivers the same event twice
    3. No delivery guarantee: Jira doesn’t retry on failure (unlike Stripe, GitHub)
    4. Missing event types: Some field changes don’t trigger webhooks despite the documentation claiming they do

    Jira Server webhooks have all of the above plus:

    1. Firewall issues: Server instances behind corporate firewalls can’t reach external webhook receivers
    2. Self-signed certificates: If your webhook receiver uses HTTPS with a self-signed cert, Jira Server rejects it
    3. No webhook logs: Server gives you no visibility into webhook delivery status

    The Workaround: Polling + Idempotent Updates

    Instead of relying on webhooks, use a polling approach:

    # Poll every 5 minutes for recent changes
    last_check = datetime.now() - timedelta(minutes=5)
    jql = f'updated >= "{last_check.strftime("%Y-%m-%d %H:%M")}" ORDER BY updated DESC'
    

    This is less elegant than real-time webhooks but more reliable. For most automation use cases (triage, standup digest, sprint planning), a 5-minute polling interval is perfectly adequate.

    The idempotency requirement: When polling, you’ll sometimes process the same issue multiple times (if it was updated before your last poll but you process it again). Build automations to be idempotent — check if the action was already performed before doing it again.

    For triage: before adding labels, check if labels already exist. Before adding a triage comment, check if one is already present (search comments for your bot’s signature).

    # Idempotency check in triage
    if "? OpenClaw Triage" in existing_comments:
        skip this issue  # already triaged
    

    If You Do Use Webhooks

    Register webhooks in Jira Cloud: Settings → System → WebHooks → Create a WebHook

    Configure only the events you need — each unnecessary event type adds noise and processing load.

    Handle duplicates: Store a cache of processed event IDs for 1 hour. If you see the same event ID twice, skip it.

    Add a health check: Periodically verify your webhook receiver is getting events by checking the last received timestamp. If it’s been more than 30 minutes with no events, fall back to polling.

    PaioClaw’s Jira integration uses polling by default with optional webhook support, handling the deduplication and fallback automatically.

    Creating and Updating Issues

    Create an Issue

    @openclaw create a bug in PLATFORM project: Users getting 500 error on checkout, priority High, label: payments
    
    POST /rest/api/3/issue
    {
      "fields": {
        "project": { "key": "PLATFORM" },
        "issuetype": { "name": "Bug" },
        "summary": "Users getting 500 error on checkout",
        "priority": { "name": "High" },
        "labels": ["payments"],
        "description": {
          "type": "doc",
          "version": 1,
          "content": [
            {
              "type": "paragraph",
              "content": [{ "type": "text", "text": "Users getting 500 error on checkout" }]
            }
          ]
        }
      }
    }
    

    Note the description format: Jira Cloud API v3 uses Atlassian Document Format (ADF) for rich text — not plain text, not markdown, not HTML. It’s a JSON document tree. OpenClaw handles the conversion from natural language to ADF, but if you write custom skills, account for this.

    Jira Server API v2 still accepts plain text or wiki markup in descriptions. Cloud does not.

    Transition Issue Status

    Changing an issue’s status in Jira isn’t as simple as status = "In Progress". You have to trigger a transition — a workflow step — by its transition ID.

    Get available transitions for an issue:

    GET /rest/api/3/issue/{issueKey}/transitions
    

    Returns the list of available transitions from the issue’s current state. Each has an ID.

    Perform the transition:

    POST /rest/api/3/issue/{issueKey}/transitions
    { "transition": { "id": "21" } }
    

    The gotcha: Transition IDs are workflow-specific and different for every Jira instance. There’s no universal “start progress” transition ID. OpenClaw fetches available transitions dynamically and matches your natural language command to the right transition.

    @openclaw move PLATFORM-341 to In Progress
    

    OpenClaw gets available transitions → finds one named “In Progress” or “Start Progress” → triggers it.

    Standup Digest

    @openclaw generate my Jira standup for today
    

    Output:

    ? Jira Standup — Tuesday, May 19, 2026
    
    ✅ COMPLETED YESTERDAY
    • PLATFORM-287: Fixed checkout 500 error — resolved, in QA
    • ENG-341: Updated API rate limiting docs — done
    
    ? IN PROGRESS
    • PLATFORM-301: Payment provider migration — blocked on legal review
    • ENG-355: Mobile API endpoints — 70% complete
    
    ⏳ BLOCKED
    • PLATFORM-301: Waiting on legal to review provider contract
    
    ? DUE THIS SPRINT
    • ENG-371: Database migration (due May 22)
    • PLATFORM-310: Security audit findings (due May 24)
    

    Permissions and the Issues They Create

    Jira’s permission model is granular. Your API token operates with the same permissions as your Jira account. If your account can’t see a project in the UI, the API returns 403 or simply excludes those issues from search results.

    Common permission issues:

    • Issues from restricted projects don’t appear in JQL search results (no error, just missing data)
    • Creating issues in a project requires “Create Issues” project permission
    • Transitioning issues may require specific workflow permissions
    • Some custom fields are only visible to certain groups

    If OpenClaw’s queries are returning fewer results than expected, check your Jira permissions for the relevant projects.

    Performance Considerations

    Jira’s API can be slow, especially on Cloud during peak hours and on Server with large datasets.

    Pagination is mandatory: JQL search returns a maximum of 100 results per request. For queries returning more, paginate with startAt and maxResults:

    GET /rest/api/3/search?jql=...&startAt=0&maxResults=100
    GET /rest/api/3/search?jql=...&startAt=100&maxResults=100
    

    Use fields parameter: Fetching all fields is slow. Specify only what you need:

    GET /rest/api/3/search?jql=...&fields=summary,status,priority,assignee
    

    Rate limits: Jira Cloud has rate limits (undocumented but approximately 10 requests/second). Server limits depend on your instance configuration. Add delays between bulk operations.

    PaioClaw vs. Self-Hosted

    Self-hosting the Jira integration works well for personal use on Cloud. Where complexity grows:

    Server/Data Center behind VPNs: API calls from an external server fail if your Jira instance isn’t publicly accessible. You’d need OpenClaw running inside the network. PaioClaw supports on-premise agents that run inside your network and relay to PaioClaw’s cloud layer.

    Atlassian Document Format: Writing back to Jira with rich formatting requires ADF. Building ADF serialization into custom skills is annoying work that PaioClaw handles for you.

    Webhook reliability: As described above, Jira webhooks are unreliable enough that you need a robust fallback. PaioClaw’s polling + webhook hybrid approach is battle-tested.

    Plans start free, Smart at $15/mo, Genius at $25/mo.

    Summary

    Jira’s integration complexity is real but manageable. The key points: Cloud uses email+API token with Basic Auth, Server uses PAT with Bearer; the description field on Cloud requires Atlassian Document Format (not plain text); status transitions require fetching available transitions dynamically rather than assuming IDs; and webhooks are unreliable enough that polling should be your primary data retrieval strategy.

    The automation that delivers the most value fastest is JQL-powered querying via natural language — removing the friction of remembering Jira’s query syntax makes the tool significantly more useful in daily work. Standup digest and sprint velocity reporting are the next most valuable automations, and both are straightforward to set up once the JQL integration is working.

    Join Our Community

    Connect with other PaioClaw users, share tips, and stay up to date.