diff --git a/lua/jira/api_client.lua b/lua/jira/api_client.lua
index 28bbf2a..9b64674 100644
--- a/lua/jira/api_client.lua
+++ b/lua/jira/api_client.lua
@@ -3,6 +3,7 @@ local config = require 'jira.config'
 local curl = require 'plenary.curl'
 
 local M = {}
+local transition_cache = {}
 
 local get_auth_headers = function()
   local jira_api_config = config.get_config().jira_api
@@ -25,16 +26,15 @@ M.get_issue = function(issue_id)
 end
 
 M.get_transitions = function(issue_id)
+  issue_id = utils.get_issue_id(issue_id)
+  assert(issue_id, 'Missing issue id')
+  if transition_cache[issue_id] then
+    return transition_cache[issue_id]
+  end
   local url = get_base_url() .. '/issue/' .. issue_id .. '/transitions'
-  return curl.get(url, {
+  local response = curl.get(url, {
     headers = get_auth_headers(),
   })
-end
-
--- Gets the transition id for the given transition name and then transitions the issue
--- Helpful for when you don't know the transition id
-M.transition_issue_name = function(issue_id, transition_name)
-  local response = M.get_transitions(issue_id)
   if response.exit ~= 0 then
     vim.print 'Error getting transitions'
   end
@@ -42,9 +42,17 @@ M.transition_issue_name = function(issue_id, transition_name)
     print('Error getting transitions: ' .. response.body)
     return
   end
-
   local result = vim.fn.json_decode(response.body)
-  local transitions = result.transitions
+  transition_cache[issue_id] = result.transitions
+  return result.transitions
+end
+
+-- Gets the transition id for the given transition name and then transitions the issue
+-- Helpful for when you don't know the transition id
+M.transition_issue_name = function(transition_name, issue_id)
+  assert(transition_name, 'Missing transition name')
+  issue_id = utils.get_issue_id(issue_id)
+  local transitions = M.get_transitions(issue_id)
   local transition_id
   for _, transition in ipairs(transitions) do
     if transition.name == transition_name then
@@ -53,13 +61,13 @@ M.transition_issue_name = function(issue_id, transition_name)
     end
   end
   assert(transition_id, 'Transition not found: ' .. transition_name)
-  return M.transition_issue(issue_id, transition_id)
+  return M.transition_issue(transition_id, issue_id)
 end
 
 -- Transitions the issue to the given transition id
-M.transition_issue = function(issue_id, transition_id)
-  assert(issue_id, 'Missing issue id')
-  assert(transition_id, 'Missing issue id')
+M.transition_issue = function(transition_id, issue_id)
+  assert(transition_id, 'Missing transition id')
+  issue_id = utils.get_issue_id(issue_id)
   local url = get_base_url() .. '/issue/' .. issue_id .. '/transitions'
   local body = vim.json.encode {
     transition = {
diff --git a/lua/jira/commands.lua b/lua/jira/commands.lua
index 61eccd2..0783f74 100644
--- a/lua/jira/commands.lua
+++ b/lua/jira/commands.lua
@@ -13,8 +13,8 @@ M.setup = function()
       view = function(issue_id)
         M.view_issue(issue_id)
       end,
-      transition = function(issue_id, transition_name)
-        M.transition_issue_name(issue_id, transition_name)
+      transition = function(transition_name, issue_id)
+        M.transition_issue_name(transition_name, issue_id)
       end,
     },
   }
@@ -88,15 +88,15 @@ end
 
 -- @param issue_id string - the id of the issue to transition
 -- @param transition_name string - the name of the transition to perform
-function M.transition_issue_name(issue_id, transition_name)
+function M.transition_issue_name(transition_name, issue_id)
+  transition_name = transition_name or vim.fn.input 'Transition to: '
   issue_id = issue_id or utils.get_issue_id()
   if not issue_id then
     print 'Missing issue id'
     return
   end
-  transition_name = transition_name or vim.fn.input 'Transition name: '
   transition_name = transition_name:gsub('_', ' ')
-  local response = api_client.transition_issue_name(issue_id, transition_name)
+  local response = api_client.transition_issue_name(transition_name, issue_id)
   if response and (response.exit ~= 0 or response.status ~= 204) then
     vim.print 'Error making request'
   end
diff --git a/lua/jira/pickers.lua b/lua/jira/pickers.lua
new file mode 100644
index 0000000..144724d
--- /dev/null
+++ b/lua/jira/pickers.lua
@@ -0,0 +1,41 @@
+local pickers = require 'telescope.pickers'
+local finders = require 'telescope.finders'
+local actions = require 'telescope.actions'
+local action_state = require 'telescope.actions.state'
+local conf = require('telescope.config').values
+local api_client = require 'jira.api_client'
+
+local M = {}
+
+local transitions = function(opts)
+  opts = opts or {}
+  local results = api_client.get_transitions()
+  pickers
+    .new(opts, {
+      prompt_title = 'Transitions',
+      finder = finders.new_table {
+        results = results,
+        entry_maker = function(entry)
+          return {
+            value = entry,
+            display = entry.name,
+            ordinal = entry.name,
+          }
+        end,
+      },
+      attach_mappings = function(prompt_bufnr, map)
+        actions.select_default:replace(function()
+          actions.close(prompt_bufnr)
+          local selection = action_state.get_selected_entry()
+          api_client.transition_issue(selection.value.id)
+        end)
+        return true
+      end,
+      sorter = conf.generic_sorter(opts),
+    })
+    :find()
+end
+
+M.transitions = transitions
+
+return M
diff --git a/lua/telescope/_extensions/jira.lua b/lua/telescope/_extensions/jira.lua
new file mode 100644
index 0000000..c126550
--- /dev/null
+++ b/lua/telescope/_extensions/jira.lua
@@ -0,0 +1,7 @@
+local transitions = require('jira.pickers').transitions
+
+return require('telescope').register_extension {
+  exports = {
+    transitions = transitions,
+  },
+}