Access the Jira Cloud API with managed OAuth authentication. Search issues with JQL, create and manage issues, and automate workflows.
CLI:
maton jira issue search 'project = PROJ AND status = "In Progress"' --cloud-id abc-123
maton api '/jira/ex/jira/{cloudId}/rest/api/3/search/jql?jql=project%3DKEY&maxResults=10'
Python:
# First, get your cloud ID
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/jira/oauth/token/accessible-resources')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
# Then search issues
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/jira/ex/jira/{cloudId}/rest/api/3/search/jql?jql=project%3DKEY&maxResults=10')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/jira/{native-api-path}
Maton proxies requests to api.atlassian.com and automatically injects your OAuth token.
Jira Cloud requires a cloud ID. Get it first:
GET /jira/oauth/token/accessible-resources
Example:
maton jira cloud list
Response:
[{
"id": "62909843-b784-4c35-b770-e4e2a26f024b",
"url": "https://yoursite.atlassian.net",
"name": "yoursite"
}]
NPM:
npm install -g @maton-ai/cli
Homebrew:
brew install maton-ai/cli/maton
CLI:
maton login # Opens browser for API key
maton login --interactive # Skip browser, paste API key directly
maton whoami # Show current auth state
Manual:
MATON_API_KEY:export MATON_API_KEY="YOUR_API_KEY"
Manage your Jira OAuth connections at https://api.maton.ai.
CLI:
maton connection list jira --status ACTIVE
maton api -X GET /connections -f app=jira -f status=ACTIVE
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=jira&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
CLI:
maton connection create jira
maton api /connections -f app=jira
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'jira'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
CLI:
maton connection view {connection_id}
maton api /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "jira",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
CLI:
maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple Jira connections, specify which one to use:
CLI:
maton jira project list --cloud-id abc-123 --connection {connection_id}
maton api /jira/ex/jira/{cloudId}/rest/api/3/project --connection {connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/jira/ex/jira/{cloudId}/rest/api/3/project')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always specify the connection to ensure requests go to the intended account.
GET /jira/ex/jira/{cloudId}/rest/api/3/project
Example:
maton jira project list --cloud-id abc-123
GET /jira/ex/jira/{cloudId}/rest/api/3/project/{projectKeyOrId}
Example:
maton jira project view PROJ --cloud-id abc-123
GET /jira/ex/jira/{cloudId}/rest/api/3/search/jql?jql=project%3DPROJ%20order%20by%20created%20DESC&maxResults=20&fields=summary,status,assignee
Example:
maton jira issue search 'project = PROJ order by created DESC' --cloud-id abc-123 --limit 20 --fields summary,status,assignee
GET /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}
Example:
maton jira issue view PROJ-123 --cloud-id abc-123
POST /jira/ex/jira/{cloudId}/rest/api/3/issue
Content-Type: application/json
{
"fields": {
"project": {"key": "PROJ"},
"summary": "Fix login",
"issuetype": {"name": "Task"}
}
}
Example:
maton jira issue create --cloud-id abc-123 --project PROJ --summary 'Fix login' --type Task
PUT /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}
Content-Type: application/json
{
"fields": {
"summary": "Updated summary"
}
}
Example:
maton jira issue update PROJ-123 --cloud-id abc-123 --summary 'Updated summary'
DELETE /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}
Example:
maton jira issue delete PROJ-123 --cloud-id abc-123
PUT /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/assignee
Content-Type: application/json
{
"accountId": "712020:5aff718e-6fe0-4548-82f4-f44ec481e5e7"
}
Example:
maton jira issue update PROJ-123 --cloud-id abc-123 --assignee 712020:5aff718e-6fe0-4548-82f4-f44ec481e5e7
GET /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/transitions
Example:
maton jira transition list PROJ-123 --cloud-id abc-123
POST /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/transitions
Content-Type: application/json
{
"transition": {"id": "31"}
}
Example:
maton jira transition apply PROJ-123 --cloud-id abc-123 --id 31
GET /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/comment
Example:
maton jira comment list PROJ-123 --cloud-id abc-123
POST /jira/ex/jira/{cloudId}/rest/api/3/issue/{issueIdOrKey}/comment
Content-Type: application/json
{
"body": {
"type": "doc",
"version": 1,
"content": [{"type": "paragraph", "content": [{"type": "text", "text": "Comment text"}]}]
}
}
Example:
maton jira comment add PROJ-123 --cloud-id abc-123 --body 'Comment text'
GET /jira/ex/jira/{cloudId}/rest/api/3/myself
Example:
maton jira whoami --cloud-id abc-123
GET /jira/ex/jira/{cloudId}/rest/api/3/user/search?query=john
Example:
maton jira user search john --cloud-id abc-123
GET /jira/ex/jira/{cloudId}/rest/api/3/issuetype
Example:
maton jira issuetype list --cloud-id abc-123
GET /jira/ex/jira/{cloudId}/rest/api/3/priority
Example:
maton jira priority list --cloud-id abc-123
GET /jira/ex/jira/{cloudId}/rest/api/3/status
Example:
maton jira status list --cloud-id abc-123
# Discover accessible Jira Cloud resources
maton jira cloud list
# Search issues with JQL
maton jira issue search 'project = PROJ AND status = "In Progress"' --cloud-id abc-123
# Filter with jq
maton jira issue search 'project = PROJ' --cloud-id abc-123 \
--json --jq '.issues | map(select(.fields.status.name == "In Progress"))'
# Create an issue
maton jira issue create --cloud-id abc-123 --project PROJ --summary 'Fix login'
// Get cloud ID first
const resources = await fetch(
'https://api.maton.ai/jira/oauth/token/accessible-resources',
{ headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } }
).then(r => r.json());
const cloudId = resources[0].id;
// Search issues
const issues = await fetch(
`https://api.maton.ai/jira/ex/jira/${cloudId}/rest/api/3/search/jql?jql=project=KEY`,
{ headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } }
).then(r => r.json());
import os
import requests
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
# Get cloud ID
resources = requests.get(
'https://api.maton.ai/jira/oauth/token/accessible-resources',
headers=headers
).json()
cloud_id = resources[0]['id']
# Search issues
issues = requests.get(
f'https://api.maton.ai/jira/ex/jira/{cloud_id}/rest/api/3/search/jql',
headers=headers,
params={'jql': 'project=KEY', 'maxResults': 10}
).json()
/oauth/token/accessible-resourcesproject=KEY)curl -g when URLs contain brackets (fields[], sort[], records[]) to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.| Status | Meaning |
|---|---|
| -------- | --------- |
| 400 | Missing Jira connection or invalid JQL |
| 401 | Invalid or missing Maton API key |
| 429 | Rate limited (10 req/sec per account) |
| 4xx/5xx | Passthrough error from Jira API |
CLI:
maton whoami
maton connection list
Manual:
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
jira. For example:https://api.maton.ai/jira/ex/jira/{cloudId}/rest/api/3/projecthttps://api.maton.ai/ex/jira/{cloudId}/rest/api/3/project共 3 个版本