Repository: ctreminiom/go-atlassian
Pull request #144 (2022-09-16 18:17:01)

♻️ Refactor the Agile Module


Patch:
diff --git a/jira/agile/api_client_impl.go b/jira/agile/api_client_impl.go
index 8fb8616..2b838bd 100644
--- a/jira/agile/api_client_impl.go
+++ b/jira/agile/api_client_impl.go
@@ -4,10 +4,8 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
-	"errors"
 	"github.com/ctreminiom/go-atlassian/jira/agile/internal"
 	"github.com/ctreminiom/go-atlassian/pkg/infra/models"
-	"github.com/ctreminiom/go-atlassian/service/agile"
 	"github.com/ctreminiom/go-atlassian/service/common"
 	"io"
 	"io/ioutil"
@@ -64,9 +62,9 @@ type Client struct {
 	HTTP   common.HttpClient
 	Site   *url.URL
 	Auth   common.Authentication
-	Board  agile.Board
-	Epic   agile.Epic
-	Sprint agile.Sprint
+	Board  *internal.BoardService
+	Epic   *internal.EpicService
+	Sprint *internal.SprintService
 }
 
 func (c *Client) NewFormRequest(ctx context.Context, method, apiEndpoint, contentType string, payload io.Reader) (*http.Request, error) {
@@ -107,11 +105,15 @@ func (c *Client) NewRequest(ctx context.Context, method, apiEndpoint string, pay
 func (c *Client) Call(request *http.Request, structure interface{}) (*models.ResponseScheme, error) {
 
 	response, err := c.HTTP.Do(request)
-
 	if err != nil {
 		return nil, err
 	}
 
+	return c.TransformTheHTTPResponse(response, structure)
+}
+
+func (c *Client) TransformTheHTTPResponse(response *http.Response, structure interface{}) (*models.ResponseScheme, error) {
+
 	responseTransformed := &models.ResponseScheme{
 		Response: response,
 		Code:     response.StatusCode,
@@ -119,49 +121,16 @@ func (c *Client) Call(request *http.Request, structure interface{}) (*models.Res
 		Method:   response.Request.Method,
 	}
 
-	if !(response.StatusCode >= 200 && response.StatusCode < 300) {
-		return responseTransformed, models.ErrInvalidStatusCodeError
-	}
-
 	responseAsBytes, err := ioutil.ReadAll(response.Body)
 	if err != nil {
 		return responseTransformed, err
 	}
 
-	if structure != nil {
-		if err = json.Unmarshal(responseAsBytes, &structure); err != nil {
-			return responseTransformed, err
-		}
-	}
-
-	_, err = responseTransformed.Bytes.Write(responseAsBytes)
-	if err != nil {
-		return nil, err
-	}
-
-	return responseTransformed, nil
-}
-
-func (c *Client) TransformTheHTTPResponse(response *http.Response, structure interface{}) (*models.ResponseScheme, error) {
-
-	if response == nil {
-		return nil, errors.New("validation failed, please provide a http.Response pointer")
-	}
-
-	responseTransformed := &models.ResponseScheme{}
-	responseTransformed.Code = response.StatusCode
-	responseTransformed.Endpoint = response.Request.URL.String()
-	responseTransformed.Method = response.Request.Method
+	responseTransformed.Bytes.Write(responseAsBytes)
 
 	var wasSuccess = response.StatusCode >= 200 && response.StatusCode < 300
 	if !wasSuccess {
-
-		return responseTransformed, errors.New("TODO")
-	}
-
-	responseAsBytes, err := ioutil.ReadAll(response.Body)
-	if err != nil {
-		return responseTransformed, err
+		return responseTransformed, models.ErrInvalidStatusCodeError
 	}
 
 	if structure != nil {
@@ -170,7 +139,6 @@ func (c *Client) TransformTheHTTPResponse(response *http.Response, structure int
 		}
 	}
 
-	responseTransformed.Bytes.Write(responseAsBytes)
 	return responseTransformed, nil
 }
 
diff --git a/jira/agile/internal/board_impl.go b/jira/agile/internal/board_impl.go
index 6dcee30..0b5e6ea 100644
--- a/jira/agile/internal/board_impl.go
+++ b/jira/agile/internal/board_impl.go
@@ -12,68 +12,288 @@ import (
 	"strings"
 )
 
-func NewBoardService(client service.Client, version string) (agile.Board, error) {
+func NewBoardService(client service.Client, version string) (*BoardService, error) {
 
 	if version == "" {
 		return nil, model.ErrNoVersionProvided
 	}
 
-	return &BoardService{client, version}, nil
+	return &BoardService{
+		internalClient: &internalBoardImpl{c: client, version: version},
+	}, nil
 }
 
 type BoardService struct {
+	internalClient agile.BoardConnector
+}
+
+// Get returns the board for the given board ID.
+// This board will only be returned if the user has permission to view it.
+//
+//
+// Admins without the view permission will see the board as a private one,
+//
+// so will see only a subset of the board's data (board location for instance).
+//
+// GET /rest/agile/1.0/board/{boardId}
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-board
+func (b *BoardService) Get(ctx context.Context, boardID int) (*model.BoardScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Get(ctx, boardID)
+}
+
+// Create creates a new board. Board name, type and filter ID is required.
+//
+// POST /rest/agile/1.0/board
+//
+// Docs: https://docs.go-atlassian.io/jira-agile/boards#create-board
+func (b *BoardService) Create(ctx context.Context, payload *model.BoardPayloadScheme) (*model.BoardScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Create(ctx, payload)
+}
+
+// Filter returns any boards which use the provided filter id.
+//
+// This method can be executed by users without a valid software license in order
+//
+// to find which boards are using a particular filter.
+//
+// GET /rest/agile/1.0/board/filter/{filterId}
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-board-by-filter-id
+func (b *BoardService) Filter(ctx context.Context, filterID, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Filter(ctx, filterID, startAt, maxResults)
+}
+
+// Backlog returns all issues from the board's backlog, for the given board ID.
+//
+// This only includes issues that the user has permission to view.
+//
+// The backlog contains incomplete issues that are not assigned to any future or active sprint.
+//
+// Note, if the user does not have permission to view the board, no issues will be returned at all.
+//
+// Issues returned from this resource include Agile fields, like sprint, closedSprints, flagged, and epic.
+//
+// By default, the returned issues are ordered by rank.
+//
+// GET /rest/agile/1.0/board/{boardId}/backlog
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-issues-for-backlog
+func (b *BoardService) Backlog(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Backlog(ctx, boardID, opts, startAt, maxResults)
+}
+
+// Configuration get the board configuration.
+//
+// GET /rest/agile/1.0/board/{boardId}/configuration
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-configuration
+func (b *BoardService) Configuration(ctx context.Context, boardID int) (*model.BoardConfigurationScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Configuration(ctx, boardID)
+}
+
+// Epics returns all epics from the board, for the given board ID.
+//
+// This only includes epics that the user has permission to view.
+//
+// Note, if the user does not have permission to view the board, no epics will be returned at all.
+//
+// GET /rest/agile/1.0/board/{boardId}/epic
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-epics
+func (b *BoardService) Epics(ctx context.Context, boardID, startAt, maxResults int, done bool) (*model.BoardEpicPageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Epics(ctx, boardID, startAt, maxResults, done)
+}
+
+// IssuesWithoutEpic returns all issues that do not belong to any epic on a board, for a given board ID.
+//
+// This only includes issues that the user has permission to view.
+//
+// Issues returned from this resource include Agile fields, like sprint, closedSprints, flagged, and epic.
+//
+// By default, the returned issues are ordered by rank.
+//
+// GET /rest/agile/1.0/board/{boardId}/epic/none/issue
+//
+// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-issues-without-epic-for-board
+func (b *BoardService) IssuesWithoutEpic(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.IssuesWithoutEpic(ctx, boardID, opts, startAt, maxResults)
+}
+
+// IssuesByEpic returns all issues that belong to an epic on the board, for the given epic ID and the board ID.
+//
+// This only includes issues that the user has permission to view.
+//
+// Issues returned from this resource include Agile fields, like sprint, closedSprints,
+//
+// flagged, and epic. By default, the returned issues are ordered by rank.
+//
+// GET /rest/agile/1.0/board/{boardId}/epic/none/issue
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-board-issues-for-epic
+func (b *BoardService) IssuesByEpic(ctx context.Context, boardID, epicID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.IssuesByEpic(ctx, boardID, epicID, opts, startAt, maxResults)
+}
+
+// Issues returns all issues from a board, for a given board ID.
+//
+// This only includes issues that the user has permission to view.
+//
+// An issue belongs to the board if its status is mapped to the board's column.
+//
+// Epic issues do not belong to the scrum boards. Note, if the user does not have permission to view the board,
+//
+// no issues will be returned at all.
+//
+// Issues returned from this resource include Agile fields, like sprint, closedSprints, flagged, and epic.
+//
+// By default, the returned issues are ordered by rank.
+//
+// GET /rest/agile/1.0/board/{boardId}/issue
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-issues-for-board
+func (b *BoardService) Issues(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Issues(ctx, boardID, opts, startAt, maxResults)
+}
+
+// Move issues from the backlog to the board (if they are already in the backlog of that board).
+//
+// This operation either moves an issue(s) onto a board from the backlog (by adding it to the issueList for the board)
+//
+// Or transitions the issue(s) to the first column for a kanban board with backlog.
+//
+// At most 50 issues may be moved at once.
+//
+// POST /rest/agile/1.0/board/{boardId}/issue
+//
+// https://docs.go-atlassian.io/jira-agile/boards#move-issues-to-backlog-for-board
+func (b *BoardService) Move(ctx context.Context, boardID int, payload *model.BoardMovementPayloadScheme) (*model.ResponseScheme, error) {
+	return b.internalClient.Move(ctx, boardID, payload)
+}
+
+// Projects returns all projects that are associated with the board, for the given board ID.
+//
+// If the user does not have permission to view the board, no projects will be returned at all.
+//
+// Returned projects are ordered by the name.
+//
+// GET /rest/agile/1.0/board/{boardId}/project
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-projects
+func (b *BoardService) Projects(ctx context.Context, boardID, startAt, maxResults int) (*model.BoardProjectPageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Projects(ctx, boardID, startAt, maxResults)
+}
+
+// Sprints returns all sprints from a board, for a given board ID.
+//
+// This only includes sprints that the user has permission to view.
+//
+// GET /rest/agile/1.0/board/{boardId}/sprint
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-all-sprints
+func (b *BoardService) Sprints(ctx context.Context, boardID, startAt, maxResults int, states []string) (*model.BoardSprintPageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Sprints(ctx, boardID, startAt, maxResults, states)
+}
+
+// IssuesBySprint get all issues you have access to that belong to the sprint from the board.
+//
+// Issue returned from this resource contains additional fields like: sprint, closedSprints, flagged and epic.
+//
+// Issues are returned ordered by rank. JQL order has higher priority than default rank.
+//
+// GET /rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-board-issues-for-sprint
+func (b *BoardService) IssuesBySprint(ctx context.Context, boardID, sprintID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.IssuesBySprint(ctx, boardID, sprintID, opts, startAt, maxResults)
+}
+
+// Versions returns all versions from a board, for a given board ID.
+//
+// This only includes versions that the user has permission to view.
+//
+// Note, if the user does not have permission to view the board, no versions will be returned at all.
+//
+// Returned versions are ordered by the name of the project from which they belong and then by sequence defined by user.
+//
+// GET /rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-all-versions
+func (b *BoardService) Versions(ctx context.Context, boardID, startAt, maxResults int, released bool) (*model.BoardVersionPageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Versions(ctx, boardID, startAt, maxResults, released)
+}
+
+// Delete deletes the board. Admin without the view permission can still remove the board.
+//
+// DELETE /rest/agile/1.0/board/{boardId}
+//
+// https://docs.go-atlassian.io/jira-agile/boards#delete-board
+func (b *BoardService) Delete(ctx context.Context, boardID int) (*model.ResponseScheme, error) {
+	return b.internalClient.Delete(ctx, boardID)
+}
+
+// Gets returns all boards. This only includes boards that the user has permission to view.
+//
+// GET /rest/agile/1.0/board
+//
+// https://docs.go-atlassian.io/jira-agile/boards#get-boards
+func (b *BoardService) Gets(ctx context.Context, opts *model.GetBoardsOptions, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error) {
+	return b.internalClient.Gets(ctx, opts, startAt, maxResults)
+}
+
+type internalBoardImpl struct {
 	c       service.Client
 	version string
 }
 
-func (b BoardService) Get(ctx context.Context, boardId int) (*model.BoardScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Get(ctx context.Context, boardID int) (*model.BoardScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v", b.version, boardId)
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v", i.version, boardID)
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var boards model.BoardScheme
-	response, err := b.c.Call(request, &boards)
+	boards := new(model.BoardScheme)
+	response, err := i.c.Call(request, boards)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &boards, response, nil
+	return boards, response, nil
 }
 
-func (b BoardService) Create(ctx context.Context, payload *model.BoardPayloadScheme) (*model.BoardScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Create(ctx context.Context, payload *model.BoardPayloadScheme) (*model.BoardScheme, *model.ResponseScheme, error) {
 
-	reader, err := b.c.TransformStructToReader(payload)
+	reader, err := i.c.TransformStructToReader(payload)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board", b.version)
+	endpoint := fmt.Sprintf("rest/agile/%v/board", i.version)
 
-	request, err := b.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var board model.BoardScheme
-	response, err := b.c.Call(request, &board)
+	board := new(model.BoardScheme)
+	response, err := i.c.Call(request, board)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &board, response, nil
+	return board, response, nil
 }
 
-func (b BoardService) Filter(ctx context.Context, filterId, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Filter(ctx context.Context, filterID, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error) {
 
-	if filterId == 0 {
+	if filterID == 0 {
 		return nil, nil, model.ErrNoFilterIDError
 	}
 
@@ -81,25 +301,25 @@ func (b BoardService) Filter(ctx context.Context, filterId, startAt, maxResults
 	params.Add("startAt", strconv.Itoa(startAt))
 	params.Add("maxResults", strconv.Itoa(maxResults))
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/filter/%v?%v", b.version, filterId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/filter/%v?%v", i.version, filterID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var page model.BoardPageScheme
-	response, err := b.c.Call(request, &page)
+	page := new(model.BoardPageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &page, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) Backlog(ctx context.Context, boardId, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Backlog(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
@@ -109,13 +329,9 @@ func (b BoardService) Backlog(ctx context.Context, boardId, startAt, maxResults
 
 	if opts != nil {
 
-		if !opts.ValidateQuery {
-			params.Add("validateQuery", "false")
-		} else {
-			params.Add("validateQuery", "true")
-		}
+		params.Add("validateQuery", fmt.Sprintf("%v", opts.ValidateQuery))
 
-		if len(opts.JQL) != 0 {
+		if opts.JQL != "" {
 			params.Add("jql", opts.JQL)
 		}
 
@@ -128,47 +344,47 @@ func (b BoardService) Backlog(ctx context.Context, boardId, startAt, maxResults
 		}
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/backlog?%v", b.version, boardId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/backlog?%v", i.version, boardID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var issues model.BoardIssuePageScheme
-	response, err := b.c.Call(request, &issues)
+	issues := new(model.BoardIssuePageScheme)
+	response, err := i.c.Call(request, issues)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &issues, response, nil
+	return issues, response, nil
 }
 
-func (b BoardService) Configuration(ctx context.Context, boardId int) (*model.BoardConfigurationScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Configuration(ctx context.Context, boardID int) (*model.BoardConfigurationScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/configuration", b.version, boardId)
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/configuration", i.version, boardID)
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var configuration model.BoardConfigurationScheme
-	response, err := b.c.Call(request, &configuration)
+	configuration := new(model.BoardConfigurationScheme)
+	response, err := i.c.Call(request, configuration)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &configuration, response, nil
+	return configuration, response, nil
 }
 
-func (b BoardService) Epics(ctx context.Context, boardId, startAt, maxResults int, done bool) (*model.BoardEpicPageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Epics(ctx context.Context, boardID, startAt, maxResults int, done bool) (*model.BoardEpicPageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
@@ -177,25 +393,25 @@ func (b BoardService) Epics(ctx context.Context, boardId, startAt, maxResults in
 	params.Add("maxResults", strconv.Itoa(maxResults))
 	params.Add("done", fmt.Sprintf("%t", done))
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/epic?%v", b.version, boardId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/epic?%v", i.version, boardID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var epics model.BoardEpicPageScheme
-	response, err := b.c.Call(request, &epics)
+	epics := new(model.BoardEpicPageScheme)
+	response, err := i.c.Call(request, epics)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &epics, response, nil
+	return epics, response, nil
 }
 
-func (b BoardService) IssuesWithoutEpic(ctx context.Context, boardId, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) IssuesWithoutEpic(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
@@ -222,29 +438,29 @@ func (b BoardService) IssuesWithoutEpic(ctx context.Context, boardId, startAt, m
 		}
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/epic/none/issue?%v", b.version, boardId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/epic/none/issue?%v", i.version, boardID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var issues model.BoardIssuePageScheme
-	response, err := b.c.Call(request, &issues)
+	page := new(model.BoardIssuePageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &issues, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) IssuesByEpic(ctx context.Context, boardId, epicId, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) IssuesByEpic(ctx context.Context, boardID, epicID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
-	if epicId == 0 {
+	if epicID == 0 {
 		return nil, nil, model.ErrNoEpicIDError
 	}
 
@@ -255,7 +471,7 @@ func (b BoardService) IssuesByEpic(ctx context.Context, boardId, epicId, startAt
 	if opts != nil {
 
 		if !opts.ValidateQuery {
-			params.Add("validateQuery ", "false")
+			params.Add("validateQuery", "false")
 		}
 
 		if len(opts.JQL) != 0 {
@@ -271,25 +487,25 @@ func (b BoardService) IssuesByEpic(ctx context.Context, boardId, epicId, startAt
 		}
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/epic/%v/issue?%v", b.version, boardId, epicId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/epic/%v/issue?%v", i.version, boardID, epicID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var issues model.BoardIssuePageScheme
-	response, err := b.c.Call(request, &issues)
+	page := new(model.BoardIssuePageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &issues, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) Issues(ctx context.Context, boardId, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Issues(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
@@ -317,41 +533,41 @@ func (b BoardService) Issues(ctx context.Context, boardId, startAt, maxResults i
 
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/issue?%v", b.version, boardId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/issue?%v", i.version, boardID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var issues model.BoardIssuePageScheme
-	response, err := b.c.Call(request, &issues)
+	page := new(model.BoardIssuePageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &issues, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) Move(ctx context.Context, boardId int, payload *model.BoardMovementPayloadScheme) (*model.ResponseScheme, error) {
+func (i *internalBoardImpl) Move(ctx context.Context, boardID int, payload *model.BoardMovementPayloadScheme) (*model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, model.ErrNoBoardIDError
 	}
 
-	reader, err := b.c.TransformStructToReader(payload)
+	reader, err := i.c.TransformStructToReader(payload)
 	if err != nil {
 		return nil, err
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/issue", b.version, boardId)
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/issue", i.version, boardID)
 
-	request, err := b.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
 	if err != nil {
 		return nil, err
 	}
 
-	response, err := b.c.Call(request, nil)
+	response, err := i.c.Call(request, nil)
 	if err != nil {
 		return response, err
 	}
@@ -359,9 +575,9 @@ func (b BoardService) Move(ctx context.Context, boardId int, payload *model.Boar
 	return response, nil
 }
 
-func (b BoardService) Projects(ctx context.Context, boardId, startAt, maxResults int) (*model.BoardProjectPageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Projects(ctx context.Context, boardID, startAt, maxResults int) (*model.BoardProjectPageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
@@ -369,25 +585,25 @@ func (b BoardService) Projects(ctx context.Context, boardId, startAt, maxResults
 	params.Add("startAt", strconv.Itoa(startAt))
 	params.Add("maxResults", strconv.Itoa(maxResults))
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/project?%v", b.version, boardId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/project?%v", i.version, boardID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var projects model.BoardProjectPageScheme
-	response, err := b.c.Call(request, &projects)
+	page := new(model.BoardProjectPageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &projects, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) Sprints(ctx context.Context, boardId, startAt, maxResults int, states []string) (*model.BoardSprintPageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Sprints(ctx context.Context, boardID, startAt, maxResults int, states []string) (*model.BoardSprintPageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
@@ -396,29 +612,29 @@ func (b BoardService) Sprints(ctx context.Context, boardId, startAt, maxResults
 	params.Add("maxResults", strconv.Itoa(maxResults))
 	params.Add("state", strings.Join(states, ","))
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/sprint?%v", b.version, boardId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/sprint?%v", i.version, boardID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var sprints model.BoardSprintPageScheme
-	response, err := b.c.Call(request, &sprints)
+	page := new(model.BoardSprintPageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &sprints, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) IssuesBySprint(ctx context.Context, boardId, sprintId, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) IssuesBySprint(ctx context.Context, boardID, sprintID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
-	if sprintId == 0 {
+	if sprintID == 0 {
 		return nil, nil, model.ErrNoSprintIDError
 	}
 
@@ -429,7 +645,7 @@ func (b BoardService) IssuesBySprint(ctx context.Context, boardId, sprintId, sta
 	if opts != nil {
 
 		if !opts.ValidateQuery {
-			params.Add("validateQuery ", "false")
+			params.Add("validateQuery", "false")
 		}
 
 		if len(opts.JQL) != 0 {
@@ -445,25 +661,25 @@ func (b BoardService) IssuesBySprint(ctx context.Context, boardId, sprintId, sta
 		}
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/sprint/%v/issue?%v", b.version, boardId, sprintId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/sprint/%v/issue?%v", i.version, boardID, sprintID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var issues model.BoardIssuePageScheme
-	response, err := b.c.Call(request, &issues)
+	page := new(model.BoardIssuePageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &issues, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) Versions(ctx context.Context, boardId, startAt, maxResults int, released bool) (*model.BoardVersionPageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Versions(ctx context.Context, boardID, startAt, maxResults int, released bool) (*model.BoardVersionPageScheme, *model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, nil, model.ErrNoBoardIDError
 	}
 
@@ -472,36 +688,36 @@ func (b BoardService) Versions(ctx context.Context, boardId, startAt, maxResults
 	params.Add("maxResults", strconv.Itoa(maxResults))
 	params.Add("released", fmt.Sprintf("%t", released))
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v/version?%v", b.version, boardId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v/version?%v", i.version, boardID, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var versions model.BoardVersionPageScheme
-	response, err := b.c.Call(request, &versions)
+	page := new(model.BoardVersionPageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &versions, response, nil
+	return page, response, nil
 }
 
-func (b BoardService) Delete(ctx context.Context, boardId int) (*model.ResponseScheme, error) {
+func (i *internalBoardImpl) Delete(ctx context.Context, boardID int) (*model.ResponseScheme, error) {
 
-	if boardId == 0 {
+	if boardID == 0 {
 		return nil, model.ErrNoBoardIDError
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board/%v", b.version, boardId)
+	endpoint := fmt.Sprintf("rest/agile/%v/board/%v", i.version, boardID)
 
-	request, err := b.c.NewRequest(ctx, http.MethodDelete, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodDelete, endpoint, nil)
 	if err != nil {
 		return nil, err
 	}
 
-	response, err := b.c.Call(request, nil)
+	response, err := i.c.Call(request, nil)
 	if err != nil {
 		return response, err
 	}
@@ -509,7 +725,7 @@ func (b BoardService) Delete(ctx context.Context, boardId int) (*model.ResponseS
 	return response, nil
 }
 
-func (b BoardService) Gets(ctx context.Context, opts *model.GetBoardsOptions, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error) {
+func (i *internalBoardImpl) Gets(ctx context.Context, opts *model.GetBoardsOptions, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error) {
 
 	params := url.Values{}
 	params.Add("startAt", strconv.Itoa(startAt))
@@ -558,18 +774,18 @@ func (b BoardService) Gets(ctx context.Context, opts *model.GetBoardsOptions, st
 		}
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/board?%v", b.version, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/board?%v", i.version, params.Encode())
 
-	request, err := b.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var boards model.BoardPageScheme
-	response, err := b.c.Call(request, &boards)
+	page := new(model.BoardPageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &boards, response, nil
+	return page, response, nil
 }
diff --git a/jira/agile/internal/epic_impl.go b/jira/agile/internal/epic_impl.go
index dd03637..5f8214c 100644
--- a/jira/agile/internal/epic_impl.go
+++ b/jira/agile/internal/epic_impl.go
@@ -12,43 +12,93 @@ import (
 	"strings"
 )
 
-func NewEpicService(client service.Client, version string) (agile.Epic, error) {
+func NewEpicService(client service.Client, version string) (*EpicService, error) {
 
 	if version == "" {
 		return nil, model.ErrNoVersionProvided
 	}
 
-	return &EpicService{client, version}, nil
+	return &EpicService{
+		internalClient: &internalEpicImpl{c: client, version: version},
+	}, nil
 }
 
 type EpicService struct {
+	internalClient agile.EpicConnector
+}
+
+// Get returns the epic for a given epic ID.
+//
+// This epic will only be returned if the user has permission to view it.
+//
+// Note: This operation does not work for epics in next-gen projects.
+//
+// GET /rest/agile/1.0/epic/{epicIdOrKey}
+//
+// https://docs.go-atlassian.io/jira-agile/epics#get-epic
+func (e *EpicService) Get(ctx context.Context, epicIdOrKey string) (*model.EpicScheme, *model.ResponseScheme, error) {
+	return e.internalClient.Get(ctx, epicIdOrKey)
+}
+
+// Issues returns all issues that belong to the epic, for the given epic ID.
+//
+// This only includes issues that the user has permission to view.
+//
+// Issues returned from this resource include Agile fields, like sprint, closedSprints,  flagged, and epic.
+//
+// By default, the returned issues are ordered by rank.
+//
+// GET /rest/agile/1.0/epic/{epicIdOrKey}/issue
+//
+// https://docs.go-atlassian.io/jira-agile/epics#get-issues-for-epic
+func (e *EpicService) Issues(ctx context.Context, epicIdOrKey string, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+	return e.internalClient.Issues(ctx, epicIdOrKey, opts, startAt, maxResults)
+}
+
+// Move moves issues to an epic, for a given epic id.
+//
+// Issues can be only in a single epic at the same time.
+// That means that already assigned issues to an epic, will not be assigned to the previous epic anymore.
+//
+// The user needs to have the edit issue permission for all issue they want to move and to the epic.
+//
+// The maximum number of issues that can be moved in one operation is 50.
+//
+// POST /rest/agile/1.0/epic/{epicIdOrKey}/issue
+//
+// https://docs.go-atlassian.io/jira-agile/epics#move-issues-to-epic
+func (e *EpicService) Move(ctx context.Context, epicIdOrKey string, issues []string) (*model.ResponseScheme, error) {
+	return e.internalClient.Move(ctx, epicIdOrKey, issues)
+}
+
+type internalEpicImpl struct {
 	c       service.Client
 	version string
 }
 
-func (e EpicService) Get(ctx context.Context, epicIdOrKey string) (*model.EpicScheme, *model.ResponseScheme, error) {
+func (i *internalEpicImpl) Get(ctx context.Context, epicIdOrKey string) (*model.EpicScheme, *model.ResponseScheme, error) {
 
 	if epicIdOrKey == "" {
 		return nil, nil, model.ErrNoEpicIDError
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/epic/%v", e.version, epicIdOrKey)
+	endpoint := fmt.Sprintf("rest/agile/%v/epic/%v", i.version, epicIdOrKey)
 
-	request, err := e.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var epic model.EpicScheme
-	response, err := e.c.Call(request, &epic)
+	epic := new(model.EpicScheme)
+	response, err := i.c.Call(request, epic)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &epic, response, nil
+	return epic, response, nil
 }
 
-func (e EpicService) Issues(ctx context.Context, epicIdOrKey string, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
+func (i *internalEpicImpl) Issues(ctx context.Context, epicIdOrKey string, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error) {
 
 	if epicIdOrKey == "" {
 		return nil, nil, model.ErrNoEpicIDError
@@ -75,44 +125,39 @@ func (e EpicService) Issues(ctx context.Context, epicIdOrKey string, startAt, ma
 		}
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/epic/%v/issue?%v", e.version, epicIdOrKey, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/epic/%v/issue?%v", i.version, epicIdOrKey, params.Encode())
 
-	request, err := e.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var issues model.BoardIssuePageScheme
-	response, err := e.c.Call(request, &issues)
+	page := new(model.BoardIssuePageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &issues, response, nil
+	return page, response, nil
 }
 
-func (e EpicService) Move(ctx context.Context, epicIdOrKey string, issues []string) (*model.ResponseScheme, error) {
+func (i *internalEpicImpl) Move(ctx context.Context, epicIdOrKey string, issues []string) (*model.ResponseScheme, error) {
 
 	if epicIdOrKey == "" {
 		return nil, model.ErrNoEpicIDError
 	}
 
-	reader, err := e.c.TransformStructToReader(map[string]interface{}{"issues": issues})
+	reader, err := i.c.TransformStructToReader(map[string]interface{}{"issues": issues})
 	if err != nil {
 		return nil, err
 	}
 
-	endpoint := fmt.Sprintf("/rest/agile/%v/epic/%v/issue", e.version, epicIdOrKey)
+	endpoint := fmt.Sprintf("rest/agile/%v/epic/%v/issue", i.version, epicIdOrKey)
 
-	request, err := e.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
 	if err != nil {
 		return nil, err
 	}
 
-	response, err := e.c.Call(request, nil)
-	if err != nil {
-		return response, err
-	}
-
-	return response, nil
+	return i.c.Call(request, nil)
 }
diff --git a/jira/agile/internal/sprint_impl.go b/jira/agile/internal/sprint_impl.go
index b7ada2d..2942320 100644
--- a/jira/agile/internal/sprint_impl.go
+++ b/jira/agile/internal/sprint_impl.go
@@ -12,139 +12,236 @@ import (
 	"strings"
 )
 
-func NewSprintService(client service.Client, version string) (agile.Sprint, error) {
+func NewSprintService(client service.Client, version string) (*SprintService, error) {
 
 	if version == "" {
 		return nil, model.ErrNoVersionProvided
 	}
 
-	return &SprintService{client, version}, nil
+	return &SprintService{
+		internalClient: &internalSprintImpl{c: client, version: version},
+	}, nil
 }
 
 type SprintService struct {
+	internalClient agile.SprintConnector
+}
+
+// Get Returns the sprint for a given sprint ID.
+//
+// The sprint will only be returned if the user can view the board that the sprint was created on,
+//
+// or view at least one of the issues in the sprint.
+//
+// GET /rest/agile/1.0/sprint/{sprintId}
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#get-sprint
+func (s *SprintService) Get(ctx context.Context, sprintID int) (*model.SprintScheme, *model.ResponseScheme, error) {
+	return s.internalClient.Get(ctx, sprintID)
+}
+
+// Create creates a future sprint.
+//
+// Sprint name and origin board id are required.
+//
+// Start date, end date, and goal are optional.
+//
+// POST /rest/agile/1.0/sprint
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#create-print
+func (s *SprintService) Create(ctx context.Context, payload *model.SprintPayloadScheme) (*model.SprintScheme, *model.ResponseScheme, error) {
+	return s.internalClient.Create(ctx, payload)
+}
+
+// Update Performs a full update of a sprint.
+//
+// A full update means that the result will be exactly the same as the request body.
+//
+// Any fields not present in the request JSON will be set to null.
+//
+// PUT /rest/agile/1.0/sprint/{sprintId}
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#update-sprint
+func (s *SprintService) Update(ctx context.Context, sprintID int, payload *model.SprintPayloadScheme) (*model.SprintScheme, *model.ResponseScheme, error) {
+	return s.internalClient.Update(ctx, sprintID, payload)
+}
+
+// Path Performs a partial update of a sprint.
+//
+// A partial update means that fields not present in the request JSON will not be updated.
+//
+// POST /rest/agile/1.0/sprint/{sprintId}
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#partially-update-sprint
+func (s *SprintService) Path(ctx context.Context, sprintID int, payload *model.SprintPayloadScheme) (*model.SprintScheme, *model.ResponseScheme, error) {
+	return s.internalClient.Path(ctx, sprintID, payload)
+}
+
+// Delete deletes a sprint.
+//
+// Once a sprint is deleted, all open issues in the sprint will be moved to the backlog.
+//
+// DELETE /rest/agile/1.0/sprint/{sprintId}
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#delete-sprint
+func (s *SprintService) Delete(ctx context.Context, sprintID int) (*model.ResponseScheme, error) {
+	return s.internalClient.Delete(ctx, sprintID)
+}
+
+// Issues returns all issues in a sprint, for a given sprint ID.
+//
+// This only includes issues that the user has permission to view.
+//
+// By default, the returned issues are ordered by rank.
+//
+// GET /rest/agile/1.0/sprint/{sprintId}/issue
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#get-issues-for-sprint
+func (s *SprintService) Issues(ctx context.Context, sprintID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.SprintIssuePageScheme, *model.ResponseScheme, error) {
+	return s.internalClient.Issues(ctx, sprintID, opts, startAt, maxResults)
+}
+
+// Start initiate the Sprint
+//
+// PUT /rest/agile/1.0/sprint/{sprintId}
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#start-sprint
+func (s *SprintService) Start(ctx context.Context, sprintID int) (*model.ResponseScheme, error) {
+	return s.internalClient.Start(ctx, sprintID)
+}
+
+// Close closes the Sprint
+//
+// PUT /rest/agile/1.0/sprint/{sprintId}
+//
+// https://docs.go-atlassian.io/jira-agile/sprints#close-sprint
+func (s *SprintService) Close(ctx context.Context, sprintID int) (*model.ResponseScheme, error) {
+	return s.internalClient.Close(ctx, sprintID)
+}
+
+type internalSprintImpl struct {
 	c       service.Client
 	version string
 }
 
-func (s SprintService) Get(ctx context.Context, sprintId int) (*model.SprintScheme, *model.ResponseScheme, error) {
+func (i *internalSprintImpl) Get(ctx context.Context, sprintID int) (*model.SprintScheme, *model.ResponseScheme, error) {
 
-	if sprintId == 0 {
+	if sprintID == 0 {
 		return nil, nil, model.ErrNoSprintIDError
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", s.version, sprintId)
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", i.version, sprintID)
 
-	request, err := s.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var sprint model.SprintScheme
-	response, err := s.c.Call(request, &sprint)
+	sprint := new(model.SprintScheme)
+	response, err := i.c.Call(request, sprint)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &sprint, response, nil
+	return sprint, response, nil
 }
 
-func (s SprintService) Create(ctx context.Context, payload *model.SprintPayloadScheme) (*model.SprintScheme, *model.ResponseScheme,
-	error) {
+func (i *internalSprintImpl) Create(ctx context.Context, payload *model.SprintPayloadScheme) (*model.SprintScheme, *model.ResponseScheme, error) {
 
-	reader, err := s.c.TransformStructToReader(payload)
+	reader, err := i.c.TransformStructToReader(payload)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint", s.version)
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint", i.version)
 
-	request, err := s.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var sprint model.SprintScheme
-	response, err := s.c.Call(request, &sprint)
+	sprint := new(model.SprintScheme)
+	response, err := i.c.Call(request, sprint)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &sprint, response, nil
+	return sprint, response, nil
 }
 
-func (s SprintService) Update(ctx context.Context, sprintId int, payload *model.SprintPayloadScheme) (*model.SprintScheme,
-	*model.ResponseScheme, error) {
+func (i *internalSprintImpl) Update(ctx context.Context, sprintID int, payload *model.SprintPayloadScheme) (*model.SprintScheme, *model.ResponseScheme, error) {
+
+	if sprintID == 0 {
+		return nil, nil, model.ErrNoSprintIDError
+	}
 
-	reader, err := s.c.TransformStructToReader(payload)
+	reader, err := i.c.TransformStructToReader(payload)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", s.version, sprintId)
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", i.version, sprintID)
 
-	request, err := s.c.NewRequest(ctx, http.MethodPut, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPut, endpoint, reader)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var sprint model.SprintScheme
-	response, err := s.c.Call(request, &sprint)
+	sprint := new(model.SprintScheme)
+	response, err := i.c.Call(request, sprint)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &sprint, response, nil
+	return sprint, response, nil
 }
 
-func (s SprintService) Path(ctx context.Context, sprintId int, payload *model.SprintPayloadScheme) (*model.SprintScheme,
-	*model.ResponseScheme, error) {
+func (i *internalSprintImpl) Path(ctx context.Context, sprintID int, payload *model.SprintPayloadScheme) (*model.SprintScheme, *model.ResponseScheme, error) {
 
-	reader, err := s.c.TransformStructToReader(payload)
+	if sprintID == 0 {
+		return nil, nil, model.ErrNoSprintIDError
+	}
+
+	reader, err := i.c.TransformStructToReader(payload)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", s.version, sprintId)
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", i.version, sprintID)
 
-	request, err := s.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var sprint model.SprintScheme
-	response, err := s.c.Call(request, &sprint)
+	sprint := new(model.SprintScheme)
+	response, err := i.c.Call(request, sprint)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &sprint, response, nil
+	return sprint, response, nil
 }
 
-func (s SprintService) Delete(ctx context.Context, sprintId int) (*model.ResponseScheme, error) {
+func (i *internalSprintImpl) Delete(ctx context.Context, sprintID int) (*model.ResponseScheme, error) {
 
-	if sprintId == 0 {
+	if sprintID == 0 {
 		return nil, model.ErrNoSprintIDError
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", s.version, sprintId)
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", i.version, sprintID)
 
-	request, err := s.c.NewRequest(ctx, http.MethodDelete, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodDelete, endpoint, nil)
 	if err != nil {
 		return nil, err
 	}
 
-	response, err := s.c.Call(request, nil)
-	if err != nil {
-		return response, err
-	}
-
-	return response, nil
+	return i.c.Call(request, nil)
 }
 
-func (s SprintService) Issues(ctx context.Context, sprintId int, opts *model.IssueOptionScheme, startAt, maxResults int) (
-	*model.SprintIssuePageScheme, *model.ResponseScheme, error) {
+func (i *internalSprintImpl) Issues(ctx context.Context, sprintID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.SprintIssuePageScheme, *model.ResponseScheme, error) {
 
-	if sprintId == 0 {
+	if sprintID == 0 {
 		return nil, nil, model.ErrNoSprintIDError
 	}
 
@@ -155,7 +252,7 @@ func (s SprintService) Issues(ctx context.Context, sprintId int, opts *model.Iss
 	if opts != nil {
 
 		if !opts.ValidateQuery {
-			params.Add("validateQuery ", "false")
+			params.Add("validateQuery", "false")
 		}
 
 		if len(opts.JQL) != 0 {
@@ -171,25 +268,25 @@ func (s SprintService) Issues(ctx context.Context, sprintId int, opts *model.Iss
 		}
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v/issue?%v", s.version, sprintId, params.Encode())
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v/issue?%v", i.version, sprintID, params.Encode())
 
-	request, err := s.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var issues model.SprintIssuePageScheme
-	response, err := s.c.Call(request, &issues)
+	page := new(model.SprintIssuePageScheme)
+	response, err := i.c.Call(request, page)
 	if err != nil {
 		return nil, response, err
 	}
 
-	return &issues, response, nil
+	return page, response, nil
 }
 
-func (s SprintService) Start(ctx context.Context, sprintId int) (*model.ResponseScheme, error) {
+func (i *internalSprintImpl) Start(ctx context.Context, sprintID int) (*model.ResponseScheme, error) {
 
-	if sprintId == 0 {
+	if sprintID == 0 {
 		return nil, model.ErrNoSprintIDError
 	}
 
@@ -197,29 +294,24 @@ func (s SprintService) Start(ctx context.Context, sprintId int) (*model.Response
 		State: "Active",
 	}
 
-	reader, err := s.c.TransformStructToReader(payload)
+	reader, err := i.c.TransformStructToReader(payload)
 	if err != nil {
 		return nil, err
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", s.version, sprintId)
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", i.version, sprintID)
 
-	request, err := s.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
 	if err != nil {
 		return nil, err
 	}
 
-	response, err := s.c.Call(request, nil)
-	if err != nil {
-		return response, err
-	}
-
-	return response, nil
+	return i.c.Call(request, nil)
 }
 
-func (s SprintService) Close(ctx context.Context, sprintId int) (*model.ResponseScheme, error) {
+func (i *internalSprintImpl) Close(ctx context.Context, sprintID int) (*model.ResponseScheme, error) {
 
-	if sprintId == 0 {
+	if sprintID == 0 {
 		return nil, model.ErrNoSprintIDError
 	}
 
@@ -227,22 +319,17 @@ func (s SprintService) Close(ctx context.Context, sprintId int) (*model.Response
 		State: "Closed",
 	}
 
-	reader, err := s.c.TransformStructToReader(payload)
+	reader, err := i.c.TransformStructToReader(payload)
 	if err != nil {
 		return nil, err
 	}
 
-	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", s.version, sprintId)
+	endpoint := fmt.Sprintf("rest/agile/%v/sprint/%v", i.version, sprintID)
 
-	request, err := s.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, reader)
 	if err != nil {
 		return nil, err
 	}
 
-	response, err := s.c.Call(request, nil)
-	if err != nil {
-		return response, err
-	}
-
-	return response, nil
+	return i.c.Call(request, nil)
 }
diff --git a/jira/v2/api_client_impl.go b/jira/v2/api_client_impl.go
index b8c5059..43489f1 100644
--- a/jira/v2/api_client_impl.go
+++ b/jira/v2/api_client_impl.go
@@ -4,11 +4,9 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
-	"errors"
 	"github.com/ctreminiom/go-atlassian/jira/internal"
 	"github.com/ctreminiom/go-atlassian/pkg/infra/models"
 	"github.com/ctreminiom/go-atlassian/service/common"
-	"github.com/ctreminiom/go-atlassian/service/jira"
 	"io"
 	"io/ioutil"
 	"net/http"
@@ -355,10 +353,10 @@ func New(httpClient common.HttpClient, site string) (*Client, error) {
 
 type Client struct {
 	HTTP       common.HttpClient
-	Site       *url.URL
 	Auth       common.Authentication
-	Role       jira.AppRoleConnector
-	Dashboard  jira.DashboardConnector
+	Site       *url.URL
+	Role       *internal.ApplicationRoleService
+	Dashboard  *internal.DashboardService
 	Filter     *internal.FilterService
 	Group      *internal.GroupService
 	Issue      *internal.IssueRichTextService
@@ -435,11 +433,15 @@ func (c *Client) NewRequest(ctx context.Context, method, apiEndpoint string, pay
 func (c *Client) Call(request *http.Request, structure interface{}) (*models.ResponseScheme, error) {
 
 	response, err := c.HTTP.Do(request)
-
 	if err != nil {
 		return nil, err
 	}
 
+	return c.TransformTheHTTPResponse(response, structure)
+}
+
+func (c *Client) TransformTheHTTPResponse(response *http.Response, structure interface{}) (*models.ResponseScheme, error) {
+
 	responseTransformed := &models.ResponseScheme{
 		Response: response,
 		Code:     response.StatusCode,
@@ -447,49 +449,16 @@ func (c *Client) Call(request *http.Request, structure interface{}) (*models.Res
 		Method:   response.Request.Method,
 	}
 
-	if !(response.StatusCode >= 200 && response.StatusCode < 300) {
-		return responseTransformed, models.ErrInvalidStatusCodeError
-	}
-
 	responseAsBytes, err := ioutil.ReadAll(response.Body)
 	if err != nil {
 		return responseTransformed, err
 	}
 
-	if structure != nil {
-		if err = json.Unmarshal(responseAsBytes, &structure); err != nil {
-			return responseTransformed, err
-		}
-	}
-
-	_, err = responseTransformed.Bytes.Write(responseAsBytes)
-	if err != nil {
-		return nil, err
-	}
-
-	return responseTransformed, nil
-}
-
-func (c *Client) TransformTheHTTPResponse(response *http.Response, structure interface{}) (*models.ResponseScheme, error) {
-
-	if response == nil {
-		return nil, errors.New("validation failed, please provide a http.Response pointer")
-	}
-
-	responseTransformed := &models.ResponseScheme{}
-	responseTransformed.Code = response.StatusCode
-	responseTransformed.Endpoint = response.Request.URL.String()
-	responseTransformed.Method = response.Request.Method
+	responseTransformed.Bytes.Write(responseAsBytes)
 
 	var wasSuccess = response.StatusCode >= 200 && response.StatusCode < 300
 	if !wasSuccess {
-
-		return responseTransformed, errors.New("TODO")
-	}
-
-	responseAsBytes, err := ioutil.ReadAll(response.Body)
-	if err != nil {
-		return responseTransformed, err
+		return responseTransformed, models.ErrInvalidStatusCodeError
 	}
 
 	if structure != nil {
@@ -498,7 +467,6 @@ func (c *Client) TransformTheHTTPResponse(response *http.Response, structure int
 		}
 	}
 
-	responseTransformed.Bytes.Write(responseAsBytes)
 	return responseTransformed, nil
 }
 
diff --git a/jira/v3/api_client_impl.go b/jira/v3/api_client_impl.go
index 7c40575..7b1ccb3 100644
--- a/jira/v3/api_client_impl.go
+++ b/jira/v3/api_client_impl.go
@@ -4,11 +4,9 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
-	"errors"
 	"github.com/ctreminiom/go-atlassian/jira/internal"
 	"github.com/ctreminiom/go-atlassian/pkg/infra/models"
 	"github.com/ctreminiom/go-atlassian/service/common"
-	"github.com/ctreminiom/go-atlassian/service/jira"
 	"io"
 	"io/ioutil"
 	"net/http"
@@ -355,10 +353,10 @@ func New(httpClient common.HttpClient, site string) (*Client, error) {
 
 type Client struct {
 	HTTP       common.HttpClient
-	Site       *url.URL
 	Auth       common.Authentication
-	Role       jira.AppRoleConnector
-	Dashboard  jira.DashboardConnector
+	Site       *url.URL
+	Role       *internal.ApplicationRoleService
+	Dashboard  *internal.DashboardService
 	Filter     *internal.FilterService
 	Group      *internal.GroupService
 	Issue      *internal.IssueADFService
@@ -435,11 +433,15 @@ func (c *Client) NewRequest(ctx context.Context, method, apiEndpoint string, pay
 func (c *Client) Call(request *http.Request, structure interface{}) (*models.ResponseScheme, error) {
 
 	response, err := c.HTTP.Do(request)
-
 	if err != nil {
 		return nil, err
 	}
 
+	return c.TransformTheHTTPResponse(response, structure)
+}
+
+func (c *Client) TransformTheHTTPResponse(response *http.Response, structure interface{}) (*models.ResponseScheme, error) {
+
 	responseTransformed := &models.ResponseScheme{
 		Response: response,
 		Code:     response.StatusCode,
@@ -447,49 +449,16 @@ func (c *Client) Call(request *http.Request, structure interface{}) (*models.Res
 		Method:   response.Request.Method,
 	}
 
-	if !(response.StatusCode >= 200 && response.StatusCode < 300) {
-		return responseTransformed, models.ErrInvalidStatusCodeError
-	}
-
 	responseAsBytes, err := ioutil.ReadAll(response.Body)
 	if err != nil {
 		return responseTransformed, err
 	}
 
-	if structure != nil {
-		if err = json.Unmarshal(responseAsBytes, &structure); err != nil {
-			return responseTransformed, err
-		}
-	}
-
-	_, err = responseTransformed.Bytes.Write(responseAsBytes)
-	if err != nil {
-		return nil, err
-	}
-
-	return responseTransformed, nil
-}
-
-func (c *Client) TransformTheHTTPResponse(response *http.Response, structure interface{}) (*models.ResponseScheme, error) {
-
-	if response == nil {
-		return nil, errors.New("validation failed, please provide a http.Response pointer")
-	}
-
-	responseTransformed := &models.ResponseScheme{}
-	responseTransformed.Code = response.StatusCode
-	responseTransformed.Endpoint = response.Request.URL.String()
-	responseTransformed.Method = response.Request.Method
+	responseTransformed.Bytes.Write(responseAsBytes)
 
 	var wasSuccess = response.StatusCode >= 200 && response.StatusCode < 300
 	if !wasSuccess {
-
-		return responseTransformed, errors.New("TODO")
-	}
-
-	responseAsBytes, err := ioutil.ReadAll(response.Body)
-	if err != nil {
-		return responseTransformed, err
+		return responseTransformed, models.ErrInvalidStatusCodeError
 	}
 
 	if structure != nil {
@@ -498,7 +467,6 @@ func (c *Client) TransformTheHTTPResponse(response *http.Response, structure int
 		}
 	}
 
-	responseTransformed.Bytes.Write(responseAsBytes)
 	return responseTransformed, nil
 }
 
diff --git a/service/agile/board.go b/service/agile/board.go
index c55479e..6623a3f 100644
--- a/service/agile/board.go
+++ b/service/agile/board.go
@@ -5,112 +5,196 @@ import (
 	model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
 )
 
-type Board interface {
+// BoardConnector represents the Jira boards.
+// Use it to search, get, create, delete, and change boards.
+type BoardConnector interface {
 
 	// Get returns the board for the given board ID.
 	// This board will only be returned if the user has permission to view it.
+	//
+	//
 	// Admins without the view permission will see the board as a private one,
+	//
 	// so will see only a subset of the board's data (board location for instance).
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-board
-	Get(ctx context.Context, boardId int) (*model.BoardScheme, *model.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/board/{boardId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-board
+	Get(ctx context.Context, boardID int) (*model.BoardScheme, *model.ResponseScheme, error)
 
 	// Create creates a new board. Board name, type and filter ID is required.
+	//
+	// POST /rest/agile/1.0/board
+	//
 	// Docs: https://docs.go-atlassian.io/jira-agile/boards#create-board
 	Create(ctx context.Context, payload *model.BoardPayloadScheme) (*model.BoardScheme, *model.ResponseScheme, error)
 
 	// Filter returns any boards which use the provided filter id.
+	//
 	// This method can be executed by users without a valid software license in order
+	//
 	// to find which boards are using a particular filter.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-board-by-filter-id
-	Filter(ctx context.Context, filterId, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/board/filter/{filterId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-board-by-filter-id
+	Filter(ctx context.Context, filterID, startAt, maxResults int) (*model.BoardPageScheme, *model.ResponseScheme, error)
 
 	// Backlog returns all issues from the board's backlog, for the given board ID.
+	//
 	// This only includes issues that the user has permission to view.
+	//
 	// The backlog contains incomplete issues that are not assigned to any future or active sprint.
+	//
 	// Note, if the user does not have permission to view the board, no issues will be returned at all.
+	//
 	// Issues returned from this resource include Agile fields, like sprint, closedSprints, flagged, and epic.
+	//
 	// By default, the returned issues are ordered by rank.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-issues-for-backlog
-	Backlog(ctx context.Context, boardId, startAt, maxResults int, opts *model.IssueOptionScheme) (
-		*model.BoardIssuePageScheme, *model.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/board/{boardId}/backlog
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-issues-for-backlog
+	Backlog(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme, *model.ResponseScheme, error)
 
 	// Configuration get the board configuration.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-configuration
-	Configuration(ctx context.Context, boardId int) (*model.BoardConfigurationScheme, *model.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/board/{boardId}/configuration
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-configuration
+	Configuration(ctx context.Context, boardID int) (*model.BoardConfigurationScheme, *model.ResponseScheme, error)
 
 	// Epics returns all epics from the board, for the given board ID.
+	//
 	// This only includes epics that the user has permission to view.
+	//
 	// Note, if the user does not have permission to view the board, no epics will be returned at all.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-epics
-	Epics(ctx context.Context, boardId, startAt, maxResults int, done bool) (*model.BoardEpicPageScheme, *model.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/board/{boardId}/epic
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-epics
+	Epics(ctx context.Context, boardID, startAt, maxResults int, done bool) (*model.BoardEpicPageScheme, *model.ResponseScheme, error)
 
 	// IssuesWithoutEpic returns all issues that do not belong to any epic on a board, for a given board ID.
+	//
 	// This only includes issues that the user has permission to view.
+	//
 	// Issues returned from this resource include Agile fields, like sprint, closedSprints, flagged, and epic.
+	//
 	// By default, the returned issues are ordered by rank.
+	//
+	// GET /rest/agile/1.0/board/{boardId}/epic/none/issue
+	//
 	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-issues-without-epic-for-board
-	IssuesWithoutEpic(ctx context.Context, boardId, startAt, maxResults int, opts *model.IssueOptionScheme) (
+	IssuesWithoutEpic(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (
 		*model.BoardIssuePageScheme, *model.ResponseScheme, error)
 
 	// IssuesByEpic returns all issues that belong to an epic on the board, for the given epic ID and the board ID.
+	//
 	// This only includes issues that the user has permission to view.
+	//
 	// Issues returned from this resource include Agile fields, like sprint, closedSprints,
+	//
 	// flagged, and epic. By default, the returned issues are ordered by rank.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-board-issues-for-epic
-	IssuesByEpic(ctx context.Context, boardId, epicId, startAt, maxResults int, opts *model.IssueOptionScheme) (
+	//
+	// GET /rest/agile/1.0/board/{boardId}/epic/none/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-board-issues-for-epic
+	IssuesByEpic(ctx context.Context, boardID, epicID int, opts *model.IssueOptionScheme, startAt, maxResults int) (
 		*model.BoardIssuePageScheme, *model.ResponseScheme, error)
 
 	// Issues returns all issues from a board, for a given board ID.
+	//
 	// This only includes issues that the user has permission to view.
+	//
 	// An issue belongs to the board if its status is mapped to the board's column.
+	//
 	// Epic issues do not belong to the scrum boards. Note, if the user does not have permission to view the board,
+	//
 	// no issues will be returned at all.
+	//
 	// Issues returned from this resource include Agile fields, like sprint, closedSprints, flagged, and epic.
+	//
 	// By default, the returned issues are ordered by rank.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-issues-for-board
-	Issues(ctx context.Context, boardId, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme,
+	//
+	// GET /rest/agile/1.0/board/{boardId}/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-issues-for-board
+	Issues(ctx context.Context, boardID int, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme,
 		*model.ResponseScheme, error)
 
 	// Move issues from the backlog to the board (if they are already in the backlog of that board).
+	//
 	// This operation either moves an issue(s) onto a board from the backlog (by adding it to the issueList for the board)
+	//
 	// Or transitions the issue(s) to the first column for a kanban board with backlog.
+	//
 	// At most 50 issues may be moved at once.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#move-issues-to-backlog-for-board
-	Move(ctx context.Context, boardId int, payload *model.BoardMovementPayloadScheme) (*model.ResponseScheme, error)
+	//
+	// POST /rest/agile/1.0/board/{boardId}/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#move-issues-to-backlog-for-board
+	Move(ctx context.Context, boardID int, payload *model.BoardMovementPayloadScheme) (*model.ResponseScheme, error)
 
 	// Projects returns all projects that are associated with the board, for the given board ID.
+	//
 	// If the user does not have permission to view the board, no projects will be returned at all.
+	//
 	// Returned projects are ordered by the name.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-projects
-	Projects(ctx context.Context, boardId, startAt, maxResults int) (*model.BoardProjectPageScheme, *model.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/board/{boardId}/project
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-projects
+	Projects(ctx context.Context, boardID, startAt, maxResults int) (*model.BoardProjectPageScheme, *model.ResponseScheme, error)
 
 	// Sprints returns all sprints from a board, for a given board ID.
+	//
 	// This only includes sprints that the user has permission to view.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-all-sprints
-	Sprints(ctx context.Context, boardId, startAt, maxResults int, states []string) (*model.BoardSprintPageScheme,
+	//
+	// GET /rest/agile/1.0/board/{boardId}/sprint
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-all-sprints
+	Sprints(ctx context.Context, boardID, startAt, maxResults int, states []string) (*model.BoardSprintPageScheme,
 		*model.ResponseScheme, error)
 
 	// IssuesBySprint get all issues you have access to that belong to the sprint from the board.
+	//
 	// Issue returned from this resource contains additional fields like: sprint, closedSprints, flagged and epic.
+	//
 	// Issues are returned ordered by rank. JQL order has higher priority than default rank.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-board-issues-for-sprint
-	IssuesBySprint(ctx context.Context, boardId, sprintId, startAt, maxResults int, opts *model.IssueOptionScheme) (
+	//
+	// GET /rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-board-issues-for-sprint
+	IssuesBySprint(ctx context.Context, boardID, sprintID int, opts *model.IssueOptionScheme, startAt, maxResults int) (
 		*model.BoardIssuePageScheme, *model.ResponseScheme, error)
 
 	// Versions returns all versions from a board, for a given board ID.
+	//
 	// This only includes versions that the user has permission to view.
+	//
 	// Note, if the user does not have permission to view the board, no versions will be returned at all.
+	//
 	// Returned versions are ordered by the name of the project from which they belong and then by sequence defined by user.
-	// Docs: https://docs.go-atlassian.io/jira-agile/boards#get-all-versions
-	Versions(ctx context.Context, boardId, startAt, maxResults int, released bool) (*model.BoardVersionPageScheme,
+	//
+	// GET /rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-all-versions
+	Versions(ctx context.Context, boardID, startAt, maxResults int, released bool) (*model.BoardVersionPageScheme,
 		*model.ResponseScheme, error)
 
 	// Delete deletes the board. Admin without the view permission can still remove the board.
-	// Docs: N/A
-	Delete(ctx context.Context, boardId int) (*model.ResponseScheme, error)
+	//
+	// DELETE /rest/agile/1.0/board/{boardId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#delete-board
+	Delete(ctx context.Context, boardID int) (*model.ResponseScheme, error)
 
 	// Gets returns all boards. This only includes boards that the user has permission to view.
-	// Docs: N/A
+	//
+	// GET /rest/agile/1.0/board
+	//
+	// https://docs.go-atlassian.io/jira-agile/boards#get-boards
 	Gets(ctx context.Context, opts *model.GetBoardsOptions, startAt, maxResults int) (*model.BoardPageScheme,
 		*model.ResponseScheme, error)
 }
diff --git a/service/agile/epic.go b/service/agile/epic.go
index 6fc6d00..1d3f14d 100644
--- a/service/agile/epic.go
+++ b/service/agile/epic.go
@@ -5,28 +5,44 @@ import (
 	model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
 )
 
-type Epic interface {
+type EpicConnector interface {
 
 	// Get returns the epic for a given epic ID.
+	//
 	// This epic will only be returned if the user has permission to view it.
+	//
 	// Note: This operation does not work for epics in next-gen projects.
-	// Docs: https://docs.go-atlassian.io/jira-agile/epics#get-epic
+	//
+	// GET /rest/agile/1.0/epic/{epicIdOrKey}
+	//
+	// https://docs.go-atlassian.io/jira-agile/epics#get-epic
 	Get(ctx context.Context, epicIdOrKey string) (*model.EpicScheme, *model.ResponseScheme, error)
 
 	// Issues returns all issues that belong to the epic, for the given epic ID.
+	//
 	// This only includes issues that the user has permission to view.
-	// Issues returned from this resource include Agile fields, like sprint, closedSprints,
-	// flagged, and epic.
+	//
+	// Issues returned from this resource include Agile fields, like sprint, closedSprints,  flagged, and epic.
+	//
 	// By default, the returned issues are ordered by rank.
-	// Docs: https://docs.go-atlassian.io/jira-agile/epics#get-issues-for-epic
-	Issues(ctx context.Context, epicIdOrKey string, startAt, maxResults int, opts *model.IssueOptionScheme) (*model.BoardIssuePageScheme,
+	//
+	// GET /rest/agile/1.0/epic/{epicIdOrKey}/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/epics#get-issues-for-epic
+	Issues(ctx context.Context, epicIdOrKey string, opts *model.IssueOptionScheme, startAt, maxResults int) (*model.BoardIssuePageScheme,
 		*model.ResponseScheme, error)
 
 	// Move moves issues to an epic, for a given epic id.
+	//
 	// Issues can be only in a single epic at the same time.
 	// That means that already assigned issues to an epic, will not be assigned to the previous epic anymore.
+	//
 	// The user needs to have the edit issue permission for all issue they want to move and to the epic.
+	//
 	// The maximum number of issues that can be moved in one operation is 50.
-	// Docs: TODO: The documentation needs to be created, raise a ticket here: https://github.com/ctreminiom/go-atlassian/issues
+	//
+	// POST /rest/agile/1.0/epic/{epicIdOrKey}/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/epics#move-issues-to-epic
 	Move(ctx context.Context, epicIdOrKey string, issues []string) (*model.ResponseScheme, error)
 }
diff --git a/service/agile/sprint.go b/service/agile/sprint.go
index 7607e85..e80d585 100644
--- a/service/agile/sprint.go
+++ b/service/agile/sprint.go
@@ -5,49 +5,81 @@ import (
 	"github.com/ctreminiom/go-atlassian/pkg/infra/models"
 )
 
-type Sprint interface {
+type SprintConnector interface {
 
 	// Get Returns the sprint for a given sprint ID.
+	//
 	// The sprint will only be returned if the user can view the board that the sprint was created on,
+	//
 	// or view at least one of the issues in the sprint.
-	// Docs: https://docs.go-atlassian.io/jira-agile/sprints#get-sprint
-	Get(ctx context.Context, sprintId int) (*models.SprintScheme, *models.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/sprint/{sprintId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#get-sprint
+	Get(ctx context.Context, sprintID int) (*models.SprintScheme, *models.ResponseScheme, error)
 
 	// Create creates a future sprint.
+	//
 	// Sprint name and origin board id are required.
+	//
 	// Start date, end date, and goal are optional.
-	// Docs: https://docs.go-atlassian.io/jira-agile/sprints#create-print
+	//
+	// POST /rest/agile/1.0/sprint
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#create-print
 	Create(ctx context.Context, payload *models.SprintPayloadScheme) (*models.SprintScheme, *models.ResponseScheme, error)
 
 	// Update Performs a full update of a sprint.
+	//
 	// A full update means that the result will be exactly the same as the request body.
+	//
 	// Any fields not present in the request JSON will be set to null.
-	// Docs: https://docs.go-atlassian.io/jira-agile/sprints#update-sprint
-	Update(ctx context.Context, sprintId int, payload *models.SprintPayloadScheme) (*models.SprintScheme, *models.ResponseScheme,
-		error)
+	//
+	// PUT /rest/agile/1.0/sprint/{sprintId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#update-sprint
+	Update(ctx context.Context, sprintID int, payload *models.SprintPayloadScheme) (*models.SprintScheme, *models.ResponseScheme, error)
 
 	// Path Performs a partial update of a sprint.
+	//
 	// A partial update means that fields not present in the request JSON will not be updated.
-	// Docs: https://docs.go-atlassian.io/jira-agile/sprints#partially-update-sprint
-	Path(ctx context.Context, sprintId int, payload *models.SprintPayloadScheme) (*models.SprintScheme, *models.ResponseScheme,
-		error)
+	//
+	// POST /rest/agile/1.0/sprint/{sprintId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#partially-update-sprint
+	Path(ctx context.Context, sprintID int, payload *models.SprintPayloadScheme) (*models.SprintScheme, *models.ResponseScheme, error)
 
 	// Delete deletes a sprint.
+	//
 	// Once a sprint is deleted, all open issues in the sprint will be moved to the backlog.
-	Delete(ctx context.Context, sprintId int) (*models.ResponseScheme, error)
+	//
+	// DELETE /rest/agile/1.0/sprint/{sprintId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#delete-sprint
+	Delete(ctx context.Context, sprintID int) (*models.ResponseScheme, error)
 
 	// Issues returns all issues in a sprint, for a given sprint ID.
+	//
 	// This only includes issues that the user has permission to view.
+	//
 	// By default, the returned issues are ordered by rank.
-	// Docs: https://docs.go-atlassian.io/jira-agile/sprints#get-issues-for-sprint
-	Issues(ctx context.Context, sprintId int, opts *models.IssueOptionScheme, startAt, maxResults int) (*models.SprintIssuePageScheme,
-		*models.ResponseScheme, error)
+	//
+	// GET /rest/agile/1.0/sprint/{sprintId}/issue
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#get-issues-for-sprint
+	Issues(ctx context.Context, sprintID int, opts *models.IssueOptionScheme, startAt, maxResults int) (*models.SprintIssuePageScheme, *models.ResponseScheme, error)
 
 	// Start initiate the Sprint
-	// Docs: https://docs.go-atlassian.io/jira-agile/sprints#start-sprint
-	Start(ctx context.Context, sprintId int) (*models.ResponseScheme, error)
+	//
+	// PUT /rest/agile/1.0/sprint/{sprintId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#start-sprint
+	Start(ctx context.Context, sprintID int) (*models.ResponseScheme, error)
 
 	// Close closes the Sprint
-	// Docs: https://docs.go-atlassian.io/jira-agile/sprints#close-sprint
-	Close(ctx context.Context, sprintId int) (*models.ResponseScheme, error)
+	//
+	// PUT /rest/agile/1.0/sprint/{sprintId}
+	//
+	// https://docs.go-atlassian.io/jira-agile/sprints#close-sprint
+	Close(ctx context.Context, sprintID int) (*models.ResponseScheme, error)
 }


Test patch:
diff --git a/jira/agile/api_client_impl_test.go b/jira/agile/api_client_impl_test.go
index 5a8dd5d..1952a51 100644
--- a/jira/agile/api_client_impl_test.go
+++ b/jira/agile/api_client_impl_test.go
@@ -4,8 +4,8 @@ import (
 	"bytes"
 	"encoding/json"
 	"errors"
+	"github.com/ctreminiom/go-atlassian/jira/agile/internal"
 	"github.com/ctreminiom/go-atlassian/pkg/infra/models"
-	"github.com/ctreminiom/go-atlassian/service/agile"
 	"github.com/ctreminiom/go-atlassian/service/common"
 	"github.com/ctreminiom/go-atlassian/service/mocks"
 	"github.com/stretchr/testify/assert"
@@ -41,9 +41,9 @@ func TestClient_Call(t *testing.T) {
 		HTTP           common.HttpClient
 		Site           *url.URL
 		Authentication common.Authentication
-		Board          agile.Board
-		Epic           agile.Epic
-		Sprint         agile.Sprint
+		Board          *internal.BoardService
+		Epic           *internal.EpicService
+		Sprint         *internal.SprintService
 	}
 
 	type args struct {
@@ -253,9 +253,9 @@ func TestClient_TransformTheHTTPResponse(t *testing.T) {
 		HTTP           common.HttpClient
 		Site           *url.URL
 		Authentication common.Authentication
-		Board          agile.Board
-		Epic           agile.Epic
-		Sprint         agile.Sprint
+		Board          *internal.BoardService
+		Epic           *internal.EpicService
+		Sprint         *internal.SprintService
 	}
 
 	type args struct {
@@ -321,7 +321,7 @@ func TestClient_TransformTheHTTPResponse(t *testing.T) {
 func TestClient_TransformStructToReader(t *testing.T) {
 
 	expectedBytes, err := json.Marshal(&models.BoardScheme{
-		Name: "Board Sample",
+		Name: "BoardConnector Sample",
 		Type: "Scrum",
 	})
 
@@ -333,9 +333,9 @@ func TestClient_TransformStructToReader(t *testing.T) {
 		HTTP           common.HttpClient
 		Site           *url.URL
 		Authentication common.Authentication
-		Board          agile.Board
-		Epic           agile.Epic
-		Sprint         agile.Sprint
+		Board          *internal.BoardService
+		Epic           *internal.EpicService
+		Sprint         *internal.SprintService
 	}
 
 	type args struct {
@@ -354,7 +354,7 @@ func TestClient_TransformStructToReader(t *testing.T) {
 			name: "when the parameters are correct",
 			args: args{
 				structure: &models.BoardScheme{
-					Name: "Board Sample",
+					Name: "BoardConnector Sample",
 					Type: "Scrum",
 				},
 			},
@@ -366,7 +366,7 @@ func TestClient_TransformStructToReader(t *testing.T) {
 			name: "when the payload provided is not a pointer",
 			args: args{
 				structure: models.BoardScheme{
-					Name: "Board Sample",
+					Name: "BoardConnector Sample",
 					Type: "Scrum",
 				},
 			},
diff --git a/jira/agile/internal/board_impl_test.go b/jira/agile/internal/board_impl_test.go
index dade08d..2a7caf2 100644
--- a/jira/agile/internal/board_impl_test.go
+++ b/jira/agile/internal/board_impl_test.go
@@ -6,11 +6,9 @@ import (
 	"errors"
 	model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
 	"github.com/ctreminiom/go-atlassian/service"
-	"github.com/ctreminiom/go-atlassian/service/agile"
 	"github.com/ctreminiom/go-atlassian/service/mocks"
 	"github.com/stretchr/testify/assert"
 	"net/http"
-	"reflect"
 	"testing"
 )
 
@@ -46,7 +44,7 @@ func Test_BoardService_Get(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1",
+					"rest/agile/1.0/board/1",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -72,7 +70,7 @@ func Test_BoardService_Get(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1",
+					"rest/agile/1.0/board/1",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -100,7 +98,7 @@ func Test_BoardService_Get(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1",
+					"rest/agile/1.0/board/1",
 					nil).
 					Return(&http.Request{}, errors.New("unable to create the http request"))
 
@@ -179,7 +177,7 @@ func Test_BoardService_Create(t *testing.T) {
 			args: args{
 				ctx: context.Background(),
 				payload: &model.BoardPayloadScheme{
-					Name:     "Board Name Sample",
+					Name:     "BoardConnector Name Sample",
 					Type:     "scrum",
 					FilterID: 1002,
 				},
@@ -190,7 +188,7 @@ func Test_BoardService_Create(t *testing.T) {
 
 				client.On("TransformStructToReader",
 					&model.BoardPayloadScheme{
-						Name:     "Board Name Sample",
+						Name:     "BoardConnector Name Sample",
 						Type:     "scrum",
 						FilterID: 1002,
 					}).
@@ -199,7 +197,7 @@ func Test_BoardService_Create(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/board",
+					"rest/agile/1.0/board",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, nil)
 
@@ -217,7 +215,7 @@ func Test_BoardService_Create(t *testing.T) {
 			args: args{
 				ctx: context.Background(),
 				payload: &model.BoardPayloadScheme{
-					Name:     "Board Name Sample",
+					Name:     "BoardConnector Name Sample",
 					Type:     "scrum",
 					FilterID: 1002,
 				},
@@ -228,7 +226,7 @@ func Test_BoardService_Create(t *testing.T) {
 
 				client.On("TransformStructToReader",
 					&model.BoardPayloadScheme{
-						Name:     "Board Name Sample",
+						Name:     "BoardConnector Name Sample",
 						Type:     "scrum",
 						FilterID: 1002,
 					}).
@@ -237,7 +235,7 @@ func Test_BoardService_Create(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/board",
+					"rest/agile/1.0/board",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, nil)
 
@@ -257,7 +255,7 @@ func Test_BoardService_Create(t *testing.T) {
 			args: args{
 				ctx: context.Background(),
 				payload: &model.BoardPayloadScheme{
-					Name:     "Board Name Sample",
+					Name:     "BoardConnector Name Sample",
 					Type:     "scrum",
 					FilterID: 1002,
 				},
@@ -268,7 +266,7 @@ func Test_BoardService_Create(t *testing.T) {
 
 				client.On("TransformStructToReader",
 					&model.BoardPayloadScheme{
-						Name:     "Board Name Sample",
+						Name:     "BoardConnector Name Sample",
 						Type:     "scrum",
 						FilterID: 1002,
 					}).
@@ -277,7 +275,7 @@ func Test_BoardService_Create(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/board",
+					"rest/agile/1.0/board",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, errors.New("unable to create the http request"))
 
@@ -381,7 +379,7 @@ func Test_BoardService_Backlog(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/backlog?expand=changelogs+&fields=status%2Cdescription&jql=project+%3D+ACA&maxResults=50&startAt=0&validateQuery=true",
+					"rest/agile/1.0/board/1001/backlog?expand=changelogs+&fields=status%2Cdescription&jql=project+%3D+ACA&maxResults=50&startAt=0&validateQuery=true",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -415,7 +413,7 @@ func Test_BoardService_Backlog(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/backlog?expand=changelogs+&fields=status%2Cdescription&jql=project+%3D+ACA&maxResults=50&startAt=0&validateQuery=true",
+					"rest/agile/1.0/board/1001/backlog?expand=changelogs+&fields=status%2Cdescription&jql=project+%3D+ACA&maxResults=50&startAt=0&validateQuery=true",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -451,7 +449,7 @@ func Test_BoardService_Backlog(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/backlog?expand=changelogs+&fields=status%2Cdescription&jql=project+%3D+ACA&maxResults=50&startAt=0&validateQuery=true",
+					"rest/agile/1.0/board/1001/backlog?expand=changelogs+&fields=status%2Cdescription&jql=project+%3D+ACA&maxResults=50&startAt=0&validateQuery=true",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -492,8 +490,8 @@ func Test_BoardService_Backlog(t *testing.T) {
 			service, err := NewBoardService(testCase.fields.c, "1.0")
 			assert.NoError(t, err)
 
-			gotResult, gotResponse, err := service.Backlog(testCase.args.ctx, testCase.args.boardId, testCase.args.startAt,
-				testCase.args.maxResults, testCase.args.opts)
+			gotResult, gotResponse, err := service.Backlog(testCase.args.ctx, testCase.args.boardId, testCase.args.opts, testCase.args.startAt,
+				testCase.args.maxResults)
 
 			if testCase.wantErr {
 
@@ -544,7 +542,7 @@ func Test_BoardService_Configuration(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/configuration",
+					"rest/agile/1.0/board/1001/configuration",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -570,7 +568,7 @@ func Test_BoardService_Configuration(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/configuration",
+					"rest/agile/1.0/board/1001/configuration",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -598,7 +596,7 @@ func Test_BoardService_Configuration(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/configuration",
+					"rest/agile/1.0/board/1001/configuration",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -689,7 +687,7 @@ func Test_BoardService_Epics(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/epic?done=false&maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1001/epic?done=false&maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -718,7 +716,7 @@ func Test_BoardService_Epics(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/epic?done=false&maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1001/epic?done=false&maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -749,7 +747,7 @@ func Test_BoardService_Epics(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1001/epic?done=false&maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1001/epic?done=false&maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -835,7 +833,7 @@ func Test_BoardService_Delete(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodDelete,
-					"/rest/agile/1.0/board/1001",
+					"rest/agile/1.0/board/1001",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -861,7 +859,7 @@ func Test_BoardService_Delete(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodDelete,
-					"/rest/agile/1.0/board/1001",
+					"rest/agile/1.0/board/1001",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -889,7 +887,7 @@ func Test_BoardService_Delete(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodDelete,
-					"/rest/agile/1.0/board/1001",
+					"rest/agile/1.0/board/1001",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -977,7 +975,7 @@ func Test_BoardService_Filter(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/filter/1001?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/filter/1001?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1005,7 +1003,7 @@ func Test_BoardService_Filter(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/filter/1001?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/filter/1001?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1035,7 +1033,7 @@ func Test_BoardService_Filter(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/filter/1001?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/filter/1001?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -1124,7 +1122,7 @@ func Test_BoardService_Gets(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board?maxResults=50&startAt=0",
+					"rest/agile/1.0/board?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1163,7 +1161,7 @@ func Test_BoardService_Gets(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board?accountIdLocation=uuid-sample&expand=issues&filterId=100&includePrivate=true&"+
+					"rest/agile/1.0/board?accountIdLocation=uuid-sample&expand=issues&filterId=100&includePrivate=true&"+
 						"maxResults=50&name=Sample+Name&negateLocationFiltering=true&orderBy=issues&projectKeyOrId=DUMMY&proj"+
 						"ectLocation=uuid-sample&startAt=0&type=scrum",
 					nil).
@@ -1192,7 +1190,7 @@ func Test_BoardService_Gets(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board?maxResults=50&startAt=0",
+					"rest/agile/1.0/board?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1221,7 +1219,7 @@ func Test_BoardService_Gets(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board?maxResults=50&startAt=0",
+					"rest/agile/1.0/board?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -1300,7 +1298,7 @@ func Test_BoardService_Issues(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1334,7 +1332,7 @@ func Test_BoardService_Issues(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1362,7 +1360,7 @@ func Test_BoardService_Issues(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1392,7 +1390,7 @@ func Test_BoardService_Issues(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -1427,8 +1425,8 @@ func Test_BoardService_Issues(t *testing.T) {
 			service, err := NewBoardService(testCase.fields.c, "1.0")
 			assert.NoError(t, err)
 
-			gotResult, gotResponse, err := service.Issues(testCase.args.ctx, testCase.args.boardId, testCase.args.startAt,
-				testCase.args.maxResults, testCase.args.opts)
+			gotResult, gotResponse, err := service.Issues(testCase.args.ctx, testCase.args.boardId, testCase.args.opts,
+				testCase.args.startAt, testCase.args.maxResults)
 
 			if testCase.wantErr {
 
@@ -1487,7 +1485,7 @@ func Test_BoardService_IssuesByEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/102/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/epic/102/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1522,7 +1520,7 @@ func Test_BoardService_IssuesByEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/102/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/epic/102/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1551,7 +1549,7 @@ func Test_BoardService_IssuesByEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/102/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/epic/102/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1582,7 +1580,7 @@ func Test_BoardService_IssuesByEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/102/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/epic/102/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -1633,8 +1631,7 @@ func Test_BoardService_IssuesByEpic(t *testing.T) {
 			assert.NoError(t, err)
 
 			gotResult, gotResponse, err := service.IssuesByEpic(testCase.args.ctx, testCase.args.boardId, testCase.args.epicId,
-				testCase.args.startAt,
-				testCase.args.maxResults, testCase.args.opts)
+				testCase.args.opts, testCase.args.startAt, testCase.args.maxResults)
 
 			if testCase.wantErr {
 
@@ -1693,7 +1690,7 @@ func Test_BoardService_IssuesBySprint(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/sprint/102/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/sprint/102/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1728,7 +1725,7 @@ func Test_BoardService_IssuesBySprint(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/sprint/102/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0&validateQuery+=false",
+					"rest/agile/1.0/board/1000/sprint/102/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0&validateQuery=false",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1757,7 +1754,7 @@ func Test_BoardService_IssuesBySprint(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/sprint/102/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/sprint/102/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1788,7 +1785,7 @@ func Test_BoardService_IssuesBySprint(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/sprint/102/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/sprint/102/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -1839,8 +1836,7 @@ func Test_BoardService_IssuesBySprint(t *testing.T) {
 			assert.NoError(t, err)
 
 			gotResult, gotResponse, err := service.IssuesBySprint(testCase.args.ctx, testCase.args.boardId, testCase.args.sprintId,
-				testCase.args.startAt,
-				testCase.args.maxResults, testCase.args.opts)
+				testCase.args.opts, testCase.args.startAt, testCase.args.maxResults)
 
 			if testCase.wantErr {
 
@@ -1897,7 +1893,7 @@ func Test_BoardService_IssuesWithoutEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/none/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/epic/none/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1931,7 +1927,7 @@ func Test_BoardService_IssuesWithoutEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/none/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0&validateQuery=false",
+					"rest/agile/1.0/board/1000/epic/none/issue?expand=orders&fields=fields&jql=project+%3D+DUMMY&maxResults=50&startAt=0&validateQuery=false",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1959,7 +1955,7 @@ func Test_BoardService_IssuesWithoutEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/none/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/epic/none/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -1989,7 +1985,7 @@ func Test_BoardService_IssuesWithoutEpic(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/epic/none/issue?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/epic/none/issue?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -2024,8 +2020,8 @@ func Test_BoardService_IssuesWithoutEpic(t *testing.T) {
 			service, err := NewBoardService(testCase.fields.c, "1.0")
 			assert.NoError(t, err)
 
-			gotResult, gotResponse, err := service.IssuesWithoutEpic(testCase.args.ctx, testCase.args.boardId, testCase.args.startAt,
-				testCase.args.maxResults, testCase.args.opts)
+			gotResult, gotResponse, err := service.IssuesWithoutEpic(testCase.args.ctx, testCase.args.boardId, testCase.args.opts,
+				testCase.args.startAt, testCase.args.maxResults)
 
 			if testCase.wantErr {
 
@@ -2090,7 +2086,7 @@ func Test_BoardService_Move(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/board/1000/issue",
+					"rest/agile/1.0/board/1000/issue",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, nil)
 
@@ -2128,7 +2124,7 @@ func Test_BoardService_Move(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/board/1000/issue",
+					"rest/agile/1.0/board/1000/issue",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, nil)
 
@@ -2168,7 +2164,7 @@ func Test_BoardService_Move(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/board/1000/issue",
+					"rest/agile/1.0/board/1000/issue",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -2260,7 +2256,7 @@ func Test_BoardService_Projects(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/project?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/project?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -2288,7 +2284,7 @@ func Test_BoardService_Projects(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/project?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/project?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -2318,7 +2314,7 @@ func Test_BoardService_Projects(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/project?maxResults=50&startAt=0",
+					"rest/agile/1.0/board/1000/project?maxResults=50&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -2410,7 +2406,7 @@ func Test_BoardService_Sprints(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/sprint?maxResults=50&startAt=0&state=active",
+					"rest/agile/1.0/board/1000/sprint?maxResults=50&startAt=0&state=active",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -2439,7 +2435,7 @@ func Test_BoardService_Sprints(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/sprint?maxResults=50&startAt=0&state=active",
+					"rest/agile/1.0/board/1000/sprint?maxResults=50&startAt=0&state=active",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -2470,7 +2466,7 @@ func Test_BoardService_Sprints(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/sprint?maxResults=50&startAt=0&state=active",
+					"rest/agile/1.0/board/1000/sprint?maxResults=50&startAt=0&state=active",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -2562,7 +2558,7 @@ func Test_BoardService_Versions(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/version?maxResults=50&released=true&startAt=0",
+					"rest/agile/1.0/board/1000/version?maxResults=50&released=true&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -2591,7 +2587,7 @@ func Test_BoardService_Versions(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/version?maxResults=50&released=false&startAt=0",
+					"rest/agile/1.0/board/1000/version?maxResults=50&released=false&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -2620,7 +2616,7 @@ func Test_BoardService_Versions(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/version?maxResults=50&released=true&startAt=0",
+					"rest/agile/1.0/board/1000/version?maxResults=50&released=true&startAt=0",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -2651,7 +2647,7 @@ func Test_BoardService_Versions(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/board/1000/version?maxResults=50&released=true&startAt=0",
+					"rest/agile/1.0/board/1000/version?maxResults=50&released=true&startAt=0",
 					nil).
 					Return(&http.Request{}, errors.New("client: no http request created"))
 
@@ -2706,44 +2702,3 @@ func Test_BoardService_Versions(t *testing.T) {
 		})
 	}
 }
-
-func TestNewBoardService(t *testing.T) {
-
-	type args struct {
-		client  service.Client
-		version string
-	}
-
-	testCases := []struct {
-		name    string
-		args    args
-		want    agile.Board
-		wantErr bool
-	}{
-		{
-			name: "when the agile version is not provided",
-			args: args{
-				client:  mocks.NewClient(t),
-				version: "",
-			},
-			want:    nil,
-			wantErr: true,
-		},
-	}
-
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-
-			got, err := NewBoardService(testCase.args.client, testCase.args.version)
-
-			if (err != nil) != testCase.wantErr {
-				t.Errorf("NewBoardService() error = %v, wantErr %v", err, testCase.wantErr)
-				return
-			}
-
-			if !reflect.DeepEqual(got, testCase.want) {
-				t.Errorf("NewBoardService() got = %v, want %v", got, testCase.want)
-			}
-		})
-	}
-}
diff --git a/jira/agile/internal/epic_impl_test.go b/jira/agile/internal/epic_impl_test.go
index 29be121..1c4a2b5 100644
--- a/jira/agile/internal/epic_impl_test.go
+++ b/jira/agile/internal/epic_impl_test.go
@@ -6,11 +6,9 @@ import (
 	"errors"
 	model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
 	"github.com/ctreminiom/go-atlassian/service"
-	"github.com/ctreminiom/go-atlassian/service/agile"
 	"github.com/ctreminiom/go-atlassian/service/mocks"
 	"github.com/stretchr/testify/assert"
 	"net/http"
-	"reflect"
 	"testing"
 )
 
@@ -46,7 +44,7 @@ func Test_EpicService_Get(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/epic/EPIC-1",
+					"rest/agile/1.0/epic/EPIC-1",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -72,7 +70,7 @@ func Test_EpicService_Get(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/epic/EPIC-1",
+					"rest/agile/1.0/epic/EPIC-1",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -100,7 +98,7 @@ func Test_EpicService_Get(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/epic/EPIC-1",
+					"rest/agile/1.0/epic/EPIC-1",
 					nil).
 					Return(&http.Request{}, errors.New("unable to create the http request"))
 
@@ -198,7 +196,7 @@ func Test_EpicService_Issues(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/epic/EPIC-1/issue?expand=changelogs&fields=status%2Csummary&jql=project+%3D+EPIC&maxResults=50&startAt=10&validateQuery=true",
+					"rest/agile/1.0/epic/EPIC-1/issue?expand=changelogs&fields=status%2Csummary&jql=project+%3D+EPIC&maxResults=50&startAt=10&validateQuery=true",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -232,7 +230,7 @@ func Test_EpicService_Issues(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/epic/EPIC-1/issue?expand=changelogs&fields=status%2Csummary&jql=project+%3D+EPIC&maxResults=50&startAt=10&validateQuery=true",
+					"rest/agile/1.0/epic/EPIC-1/issue?expand=changelogs&fields=status%2Csummary&jql=project+%3D+EPIC&maxResults=50&startAt=10&validateQuery=true",
 					nil).
 					Return(&http.Request{}, nil)
 
@@ -268,7 +266,7 @@ func Test_EpicService_Issues(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodGet,
-					"/rest/agile/1.0/epic/EPIC-1/issue?expand=changelogs&fields=status%2Csummary&jql=project+%3D+EPIC&maxResults=50&startAt=10&validateQuery=true",
+					"rest/agile/1.0/epic/EPIC-1/issue?expand=changelogs&fields=status%2Csummary&jql=project+%3D+EPIC&maxResults=50&startAt=10&validateQuery=true",
 					nil).
 					Return(&http.Request{}, errors.New("unable to create the http request"))
 
@@ -303,8 +301,8 @@ func Test_EpicService_Issues(t *testing.T) {
 			service, err := NewEpicService(testCase.fields.c, "1.0")
 			assert.NoError(t, err)
 
-			gotResult, gotResponse, err := service.Issues(testCase.args.ctx, testCase.args.epicIdOrKey, testCase.args.startAt,
-				testCase.args.maxResults, testCase.args.opts)
+			gotResult, gotResponse, err := service.Issues(testCase.args.ctx, testCase.args.epicIdOrKey, testCase.args.opts,
+				testCase.args.startAt, testCase.args.maxResults)
 
 			if testCase.wantErr {
 
@@ -362,7 +360,7 @@ func Test_EpicService_Move(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/epic/EPIC-1/issue",
+					"rest/agile/1.0/epic/EPIC-1/issue",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, nil)
 
@@ -393,7 +391,7 @@ func Test_EpicService_Move(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/epic/EPIC-1/issue",
+					"rest/agile/1.0/epic/EPIC-1/issue",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, nil)
 
@@ -426,7 +424,7 @@ func Test_EpicService_Move(t *testing.T) {
 				client.On("NewRequest",
 					context.Background(),
 					http.MethodPost,
-					"/rest/agile/1.0/epic/EPIC-1/issue",
+					"rest/agile/1.0/epic/EPIC-1/issue",
 					bytes.NewReader([]byte{})).
 					Return(&http.Request{}, errors.New("unable to create the http request"))
 
@@ -479,44 +477,3 @@ func Test_EpicService_Move(t *testing.T) {
 		})
 	}
 }
-
-func TestNewEpicService(t *testing.T) {
-
-	type args struct {
-		client  service.Client
-		version string
-	}
-
-	testCases := []struct {
-		name    string
-		args    args
-		want    agile.Epic
-		wantErr bool
-	}{
-		{
-			name: "when the agile version is not provided",
-			args: args{
-				client:  mocks.NewClient(t),
-				version: "",
-			},
-			want:    nil,
-			wantErr: true,
-		},
-	}
-
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-
-			got, err := NewEpicService(testCase.args.client, testCase.args.version)
-
-			if (err != nil) != testCase.wantErr {
-				t.Errorf("NewBoardService() error = %v, wantErr %v", err, testCase.wantErr)
-				return
-			}
-
-			if !reflect.DeepEqual(got, testCase.want) {
-				t.Errorf("NewBoardService() got = %v, want %v", got, testCase.want)
-			}
-		})
-	}
-}
diff --git a/jira/v2/api_client_impl_test.go b/jira/v2/api_client_impl_test.go
index 6571dc0..1ea3a70 100644
--- a/jira/v2/api_client_impl_test.go
+++ b/jira/v2/api_client_impl_test.go
@@ -279,17 +279,6 @@ func TestClient_TransformTheHTTPResponse(t *testing.T) {
 			},
 			wantErr: false,
 		},
-
-		{
-			name:   "when the payload is not provided",
-			fields: fields{},
-			args: args{
-				response:  nil,
-				structure: models.BoardScheme{},
-			},
-			wantErr: true,
-			Err:     errors.New("validation failed, please provide a http.Response pointer"),
-		},
 	}
 
 	for _, testCase := range testCases {
diff --git a/jira/v3/api_client_impl_test.go b/jira/v3/api_client_impl_test.go
index aded8d5..d07802a 100644
--- a/jira/v3/api_client_impl_test.go
+++ b/jira/v3/api_client_impl_test.go
@@ -279,17 +279,6 @@ func TestClient_TransformTheHTTPResponse(t *testing.T) {
 			},
 			wantErr: false,
 		},
-
-		{
-			name:   "when the payload is not provided",
-			fields: fields{},
-			args: args{
-				response:  nil,
-				structure: models.BoardScheme{},
-			},
-			wantErr: true,
-			Err:     errors.New("validation failed, please provide a http.Response pointer"),
-		},
 	}
 
 	for _, testCase := range testCases {