You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ra...@apache.org on 2021/02/15 19:57:57 UTC

[trafficcontrol] branch master updated: Add Traffic Ops Client Minor Fallback (#5430)

This is an automated email from the ASF dual-hosted git repository.

rawlin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 8e76707  Add Traffic Ops Client Minor Fallback (#5430)
8e76707 is described below

commit 8e76707ebf4fec8df63198973d8b35db25147f76
Author: Robert O Butts <ro...@users.noreply.github.com>
AuthorDate: Mon Feb 15 12:57:45 2021 -0700

    Add Traffic Ops Client Minor Fallback (#5430)
    
    * Refactor TO Go client internals
    
    * Add toclient minor fallback option
    
    * Changed TO client path const to %d
    
    Per PR review.
    
    * Removed TO client unnecessary declaration
    
    * Remove TO client unnecessary cast
    
    * Fix TO client error spelling
    
    * Change TO client APIBase() to use APIVersion()
    
    * Remove TO client getBytesWithTTL
    
    Removes getByteswithTTL and getBytes,
    by changing the CRConfig funcs to use the standard to.get(),
    and changing the standard makeRequestWithHeader to return
    the un-parsed bytes if the passed response is a *[]byte.
    
    * Remove TO client unused var
    
    * Remove TO client unused cache symbols.
    
    Also adds deprecation notices to unused public cache-related symbols.
    
    Co-authored-by: Rawlin Peters <ra...@apache.org>
---
 CHANGELOG.md                                       |   1 +
 traffic_ops/v3-client/about.go                     |   6 +-
 traffic_ops/v3-client/api_capability.go            |   2 +-
 traffic_ops/v3-client/asn.go                       |  11 +-
 traffic_ops/v3-client/cachegroup.go                |  21 +-
 traffic_ops/v3-client/cachegroup_parameters.go     |  13 +-
 traffic_ops/v3-client/capability.go                |   7 +-
 traffic_ops/v3-client/cdn.go                       |  17 +-
 traffic_ops/v3-client/cdn_domains.go               |   2 +-
 traffic_ops/v3-client/cdnfederations.go            |  12 +-
 traffic_ops/v3-client/coordinate.go                |  15 +-
 traffic_ops/v3-client/crconfig.go                  |  17 +-
 traffic_ops/v3-client/deliveryservice.go           |  91 +++--
 traffic_ops/v3-client/deliveryservice_regexes.go   |   9 +-
 .../v3-client/deliveryservice_request_comments.go  |  13 +-
 traffic_ops/v3-client/deliveryservice_requests.go  |  15 +-
 .../deliveryservices_required_capabilities.go      |   9 +-
 traffic_ops/v3-client/deliveryserviceserver.go     |  11 +-
 traffic_ops/v3-client/division.go                  |  15 +-
 traffic_ops/v3-client/dsuser.go                    |   4 +-
 traffic_ops/v3-client/endpoints.go                 |  37 ++
 traffic_ops/v3-client/federation.go                |  27 +-
 .../v3-client/federation_federation_resolver.go    |   4 +-
 traffic_ops/v3-client/federation_resolver.go       |   6 +-
 traffic_ops/v3-client/iso.go                       |   5 +-
 traffic_ops/v3-client/job.go                       |  10 +-
 traffic_ops/v3-client/log.go                       |   7 +-
 traffic_ops/v3-client/origin.go                    |  13 +-
 traffic_ops/v3-client/parameter.go                 |  29 +-
 traffic_ops/v3-client/phys_location.go             |  15 +-
 traffic_ops/v3-client/ping.go                      |   5 +-
 traffic_ops/v3-client/profile.go                   |  36 +-
 traffic_ops/v3-client/profile_parameter.go         |  15 +-
 traffic_ops/v3-client/region.go                    |  21 +-
 traffic_ops/v3-client/role.go                      |  17 +-
 traffic_ops/v3-client/server.go                    |  27 +-
 .../v3-client/server_server_capabilities.go        |   9 +-
 traffic_ops/v3-client/server_update_status.go      |   6 +-
 traffic_ops/v3-client/servercapability.go          |  11 +-
 traffic_ops/v3-client/servercheck.go               |   8 +-
 traffic_ops/v3-client/servercheckextensions.go     |   9 +-
 traffic_ops/v3-client/serviceCategory.go           |  11 +-
 traffic_ops/v3-client/session.go                   | 399 ++++++++++++++-------
 traffic_ops/v3-client/staticdnsentry.go            |  15 +-
 traffic_ops/v3-client/stats_summary.go             |  12 +-
 traffic_ops/v3-client/status.go                    |  15 +-
 traffic_ops/v3-client/steering.go                  |   2 +-
 traffic_ops/v3-client/steeringtarget.go            |   8 +-
 traffic_ops/v3-client/tenant.go                    |  19 +-
 traffic_ops/v3-client/topology.go                  |  11 +-
 traffic_ops/v3-client/topology_queue_updates.go    |   2 +-
 traffic_ops/v3-client/traffic_monitor.go           |   6 +-
 traffic_ops/v3-client/traffic_stats.go             |   2 +-
 traffic_ops/v3-client/type.go                      |  15 +-
 traffic_ops/v3-client/user.go                      |  21 +-
 55 files changed, 753 insertions(+), 393 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f869d3..3d9f4e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 - Added API endpoints for ACME accounts
 - Traffic Ops: Added validation to ensure that the cachegroups of a delivery services' assigned ORG servers are present in the topology
 - Traffic Ops: Added validation to ensure that the `weight` parameter of `parent.config` is a float
+- Traffic Ops Client: New Login function with more options, including falling back to previous minor versions. See traffic_ops/v3-client documentation for details.
 - Added license files to the RPMs
 - Added ACME certificate renewals and ACME account registration using external account binding
 
diff --git a/traffic_ops/v3-client/about.go b/traffic_ops/v3-client/about.go
index ea883c8..c8d479d 100644
--- a/traffic_ops/v3-client/about.go
+++ b/traffic_ops/v3-client/about.go
@@ -21,13 +21,15 @@ package client
 */
 
 const (
+	// API_ABOUT is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_ABOUT = apiBase + "/about"
+
+	APIAbout = "/about"
 )
 
 // GetAbout gets data about the TO instance.
 func (to *Session) GetAbout() (map[string]string, ReqInf, error) {
-	route := API_ABOUT
 	var data map[string]string
-	reqInf, err := to.get(route, nil, &data)
+	reqInf, err := to.get(APIAbout, nil, &data)
 	return data, reqInf, err
 }
diff --git a/traffic_ops/v3-client/api_capability.go b/traffic_ops/v3-client/api_capability.go
index 51045f2..7168cfc 100644
--- a/traffic_ops/v3-client/api_capability.go
+++ b/traffic_ops/v3-client/api_capability.go
@@ -27,7 +27,7 @@ import (
 func (to *Session) GetAPICapabilities(capability string, order string) (tc.APICapabilityResponse, ReqInf, error) {
 	var (
 		vals   = url.Values{}
-		path   = fmt.Sprintf("%s/api_capabilities", apiBase)
+		path   = "/api_capabilities"
 		reqInf = ReqInf{CacheHitStatus: CacheHitStatusMiss}
 		resp   tc.APICapabilityResponse
 	)
diff --git a/traffic_ops/v3-client/asn.go b/traffic_ops/v3-client/asn.go
index 790a23d..75b2e31 100644
--- a/traffic_ops/v3-client/asn.go
+++ b/traffic_ops/v3-client/asn.go
@@ -24,19 +24,22 @@ import (
 )
 
 const (
+	// API_ASNS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_ASNS = apiBase + "/asns"
+
+	APIASNs = "/asns"
 )
 
 // CreateASN creates a ASN
 func (to *Session) CreateASN(entity tc.ASN) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_ASNS, entity, nil, &alerts)
+	reqInf, err := to.post(APIASNs, entity, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // UpdateASNByID updates a ASN by ID
 func (to *Session) UpdateASNByID(id int, entity tc.ASN) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_ASNS, id)
+	route := fmt.Sprintf("%s?id=%d", APIASNs, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, entity, nil, &alerts)
 	return alerts, reqInf, err
@@ -44,7 +47,7 @@ func (to *Session) UpdateASNByID(id int, entity tc.ASN) (tc.Alerts, ReqInf, erro
 
 // GetASNsWithHeader Returns a list of ASNs matching query params
 func (to *Session) GetASNsWithHeader(params *url.Values, header http.Header) ([]tc.ASN, ReqInf, error) {
-	route := fmt.Sprintf("%s?%s", API_ASNS, params.Encode())
+	route := fmt.Sprintf("%s?%s", APIASNs, params.Encode())
 	var data tc.ASNsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -52,7 +55,7 @@ func (to *Session) GetASNsWithHeader(params *url.Values, header http.Header) ([]
 
 // DeleteASNByASN deletes an ASN by asn number
 func (to *Session) DeleteASNByASN(asn int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_ASNS, asn)
+	route := fmt.Sprintf("%s?id=%d", APIASNs, asn)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/cachegroup.go b/traffic_ops/v3-client/cachegroup.go
index dc24382..fe43c00 100644
--- a/traffic_ops/v3-client/cachegroup.go
+++ b/traffic_ops/v3-client/cachegroup.go
@@ -26,7 +26,10 @@ import (
 )
 
 const (
+	// DEPRECATED: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_CACHEGROUPS = apiBase + "/cachegroups"
+
+	APICachegroups = "/cachegroups"
 )
 
 // Create a CacheGroup.
@@ -65,12 +68,12 @@ func (to *Session) CreateCacheGroupNullable(cachegroup tc.CacheGroupNullable) (*
 	}
 
 	var cachegroupResp tc.CacheGroupDetailResponse
-	reqInf, err := to.post(API_CACHEGROUPS, cachegroup, nil, &cachegroupResp)
+	reqInf, err := to.post(APICachegroups, cachegroup, nil, &cachegroupResp)
 	return &cachegroupResp, reqInf, err
 }
 
 func (to *Session) UpdateCacheGroupNullableByIDWithHdr(id int, cachegroup tc.CacheGroupNullable, h http.Header) (*tc.CacheGroupDetailResponse, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_CACHEGROUPS, id)
+	route := fmt.Sprintf("%s/%d", APICachegroups, id)
 	var cachegroupResp tc.CacheGroupDetailResponse
 	reqInf, err := to.put(route, cachegroup, h, &cachegroupResp)
 	return &cachegroupResp, reqInf, err
@@ -84,7 +87,7 @@ func (to *Session) UpdateCacheGroupNullableByID(id int, cachegroup tc.CacheGroup
 
 func (to *Session) GetCacheGroupsNullableWithHdr(header http.Header) ([]tc.CacheGroupNullable, ReqInf, error) {
 	var data tc.CacheGroupsNullableResponse
-	reqInf, err := to.get(API_CACHEGROUPS, header, &data)
+	reqInf, err := to.get(APICachegroups, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -95,7 +98,7 @@ func (to *Session) GetCacheGroupsNullable() ([]tc.CacheGroupNullable, ReqInf, er
 }
 
 func (to *Session) GetCacheGroupNullableByIDWithHdr(id int, header http.Header) ([]tc.CacheGroupNullable, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%v", API_CACHEGROUPS, id)
+	route := fmt.Sprintf("%s?id=%v", APICachegroups, id)
 	var data tc.CacheGroupsNullableResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -108,7 +111,7 @@ func (to *Session) GetCacheGroupNullableByID(id int) ([]tc.CacheGroupNullable, R
 }
 
 func (to *Session) GetCacheGroupNullableByNameWithHdr(name string, header http.Header) ([]tc.CacheGroupNullable, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_CACHEGROUPS, url.QueryEscape(name))
+	route := fmt.Sprintf("%s?name=%s", APICachegroups, url.QueryEscape(name))
 	var data tc.CacheGroupsNullableResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -121,7 +124,7 @@ func (to *Session) GetCacheGroupNullableByName(name string) ([]tc.CacheGroupNull
 }
 
 func (to *Session) GetCacheGroupNullableByShortNameWithHdr(shortName string, header http.Header) ([]tc.CacheGroupNullable, ReqInf, error) {
-	route := fmt.Sprintf("%s?shortName=%s", API_CACHEGROUPS, url.QueryEscape(shortName))
+	route := fmt.Sprintf("%s?shortName=%s", APICachegroups, url.QueryEscape(shortName))
 	var data tc.CacheGroupsNullableResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -135,7 +138,7 @@ func (to *Session) GetCacheGroupNullableByShortName(shortName string) ([]tc.Cach
 
 // DELETE a CacheGroup by ID.
 func (to *Session) DeleteCacheGroupByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_CACHEGROUPS, id)
+	route := fmt.Sprintf("%s/%d", APICachegroups, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
@@ -148,7 +151,7 @@ func (to *Session) GetCacheGroupsByQueryParams(qparams url.Values) ([]tc.CacheGr
 }
 
 func (to *Session) GetCacheGroupsByQueryParamsWithHdr(qparams url.Values, header http.Header) ([]tc.CacheGroupNullable, ReqInf, error) {
-	route := API_CACHEGROUPS
+	route := APICachegroups
 	if len(qparams) > 0 {
 		route += "?" + qparams.Encode()
 	}
@@ -158,7 +161,7 @@ func (to *Session) GetCacheGroupsByQueryParamsWithHdr(qparams url.Values, header
 }
 
 func (to *Session) SetCachegroupDeliveryServices(cgID int, dsIDs []int) (tc.CacheGroupPostDSRespResponse, ReqInf, error) {
-	uri := apiBase + `/cachegroups/` + strconv.Itoa(cgID) + `/deliveryservices`
+	uri := `/cachegroups/` + strconv.Itoa(cgID) + `/deliveryservices`
 	req := tc.CachegroupPostDSReq{DeliveryServices: dsIDs}
 	resp := tc.CacheGroupPostDSRespResponse{}
 	reqInf, err := to.post(uri, req, nil, &resp)
diff --git a/traffic_ops/v3-client/cachegroup_parameters.go b/traffic_ops/v3-client/cachegroup_parameters.go
index fe70383..687112a 100644
--- a/traffic_ops/v3-client/cachegroup_parameters.go
+++ b/traffic_ops/v3-client/cachegroup_parameters.go
@@ -23,11 +23,14 @@ import (
 )
 
 const (
+	// API_CACHEGROUPPARAMETERS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_CACHEGROUPPARAMETERS = apiBase + "/cachegroupparameters"
+
+	APICachegroupParameters = "/cachegroupparameters"
 )
 
 func (to *Session) GetCacheGroupParametersWithHdr(cacheGroupID int, header http.Header) ([]tc.CacheGroupParameter, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d/parameters", API_CACHEGROUPS, cacheGroupID)
+	route := fmt.Sprintf("%s/%d/parameters", APICachegroups, cacheGroupID)
 	return to.getCacheGroupParameters(route, "", header)
 }
 
@@ -38,7 +41,7 @@ func (to *Session) GetCacheGroupParameters(cacheGroupID int) ([]tc.CacheGroupPar
 }
 
 func (to *Session) GetCacheGroupParametersByQueryParamsWithHdr(cacheGroupID int, queryParams string, header http.Header) ([]tc.CacheGroupParameter, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d/parameters", API_CACHEGROUPS, cacheGroupID)
+	route := fmt.Sprintf("%s/%d/parameters", APICachegroups, cacheGroupID)
 	return to.getCacheGroupParameters(route, queryParams, header)
 }
 
@@ -56,7 +59,7 @@ func (to *Session) getCacheGroupParameters(route, queryParams string, header htt
 }
 
 func (to *Session) GetAllCacheGroupParametersWithHdr(header http.Header) ([]tc.CacheGroupParametersResponseNullable, ReqInf, error) {
-	route := fmt.Sprintf("%s/", API_CACHEGROUPPARAMETERS)
+	route := fmt.Sprintf("%s/", APICachegroupParameters)
 	var data tc.AllCacheGroupParametersResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response.CacheGroupParameters, reqInf, err
@@ -70,7 +73,7 @@ func (to *Session) GetAllCacheGroupParameters() ([]tc.CacheGroupParametersRespon
 
 // DeleteCacheGroupParameter Deassociates a Parameter with a Cache Group
 func (to *Session) DeleteCacheGroupParameter(cacheGroupID, parameterID int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d/%d", API_CACHEGROUPPARAMETERS, cacheGroupID, parameterID)
+	route := fmt.Sprintf("%s/%d/%d", APICachegroupParameters, cacheGroupID, parameterID)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
@@ -83,6 +86,6 @@ func (to *Session) CreateCacheGroupParameter(cacheGroupID, parameterID int) (*tc
 		ParameterID:  parameterID,
 	}
 	var data tc.CacheGroupParametersPostResponse
-	reqInf, err := to.post(API_CACHEGROUPPARAMETERS, cacheGroupParameterReq, nil, &data)
+	reqInf, err := to.post(APICachegroupParameters, cacheGroupParameterReq, nil, &data)
 	return &data, reqInf, err
 }
diff --git a/traffic_ops/v3-client/capability.go b/traffic_ops/v3-client/capability.go
index fbebe12..5728bf4 100644
--- a/traffic_ops/v3-client/capability.go
+++ b/traffic_ops/v3-client/capability.go
@@ -20,11 +20,14 @@ import "net/url"
 
 import "github.com/apache/trafficcontrol/lib/go-tc"
 
+// API_CAPABILITIES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const API_CAPABILITIES = apiBase + "/capabilities"
 
+const APICapabilities = "/capabilities"
+
 func (to *Session) GetCapabilitiesWithHdr(header http.Header) ([]tc.Capability, ReqInf, error) {
 	var data tc.CapabilitiesResponse
-	reqInf, err := to.get(API_CAPABILITIES, header, &data)
+	reqInf, err := to.get(APICapabilities, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -37,7 +40,7 @@ func (to *Session) GetCapabilities() ([]tc.Capability, ReqInf, error) {
 func (to *Session) GetCapabilityWithHdr(c string, header http.Header) (tc.Capability, ReqInf, error) {
 	v := url.Values{}
 	v.Add("name", c)
-	endpoint := API_CAPABILITIES + "?" + v.Encode()
+	endpoint := APICapabilities + "?" + v.Encode()
 	var data tc.CapabilitiesResponse
 	reqInf, err := to.get(endpoint, header, &data)
 	if err != nil {
diff --git a/traffic_ops/v3-client/cdn.go b/traffic_ops/v3-client/cdn.go
index ce56522..d73186b 100644
--- a/traffic_ops/v3-client/cdn.go
+++ b/traffic_ops/v3-client/cdn.go
@@ -24,18 +24,21 @@ import (
 )
 
 const (
+	// API_CDNS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_CDNS = apiBase + "/cdns"
+
+	APICDNs = "/cdns"
 )
 
 // CreateCDN creates a CDN.
 func (to *Session) CreateCDN(cdn tc.CDN) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_CDNS, cdn, nil, &alerts)
+	reqInf, err := to.post(APICDNs, cdn, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateCDNByIDWithHdr(id int, cdn tc.CDN, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_CDNS, id)
+	route := fmt.Sprintf("%s/%d", APICDNs, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, cdn, header, &alerts)
 	return alerts, reqInf, err
@@ -49,7 +52,7 @@ func (to *Session) UpdateCDNByID(id int, cdn tc.CDN) (tc.Alerts, ReqInf, error)
 
 func (to *Session) GetCDNsWithHdr(header http.Header) ([]tc.CDN, ReqInf, error) {
 	var data tc.CDNsResponse
-	reqInf, err := to.get(API_CDNS, header, &data)
+	reqInf, err := to.get(APICDNs, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -60,7 +63,7 @@ func (to *Session) GetCDNs() ([]tc.CDN, ReqInf, error) {
 }
 
 func (to *Session) GetCDNByIDWithHdr(id int, header http.Header) ([]tc.CDN, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%v", API_CDNS, id)
+	route := fmt.Sprintf("%s?id=%v", APICDNs, id)
 	var data tc.CDNsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -73,7 +76,7 @@ func (to *Session) GetCDNByID(id int) ([]tc.CDN, ReqInf, error) {
 }
 
 func (to *Session) GetCDNByNameWithHdr(name string, header http.Header) ([]tc.CDN, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_CDNS, url.QueryEscape(name))
+	route := fmt.Sprintf("%s?name=%s", APICDNs, url.QueryEscape(name))
 	var data tc.CDNsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -87,14 +90,14 @@ func (to *Session) GetCDNByName(name string) ([]tc.CDN, ReqInf, error) {
 
 // DeleteCDNByID deletes a CDN by ID.
 func (to *Session) DeleteCDNByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_CDNS, id)
+	route := fmt.Sprintf("%s/%d", APICDNs, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) GetCDNSSLKeysWithHdr(name string, header http.Header) ([]tc.CDNSSLKeys, ReqInf, error) {
-	route := fmt.Sprintf("%s/name/%s/sslkeys", API_CDNS, name)
+	route := fmt.Sprintf("%s/name/%s/sslkeys", APICDNs, name)
 	var data tc.CDNSSLKeysResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
diff --git a/traffic_ops/v3-client/cdn_domains.go b/traffic_ops/v3-client/cdn_domains.go
index a3cdc3b..bdb66da 100644
--- a/traffic_ops/v3-client/cdn_domains.go
+++ b/traffic_ops/v3-client/cdn_domains.go
@@ -23,7 +23,7 @@ import (
 
 func (to *Session) GetDomainsWithHdr(header http.Header) ([]tc.Domain, ReqInf, error) {
 	var data tc.DomainsResponse
-	inf, err := to.get(apiBase+"/cdns/domains", header, &data)
+	inf, err := to.get("/cdns/domains", header, &data)
 	return data.Response, inf, err
 }
 
diff --git a/traffic_ops/v3-client/cdnfederations.go b/traffic_ops/v3-client/cdnfederations.go
index bf5ade8..4743d54 100644
--- a/traffic_ops/v3-client/cdnfederations.go
+++ b/traffic_ops/v3-client/cdnfederations.go
@@ -30,14 +30,14 @@ import (
 
 func (to *Session) CreateCDNFederationByName(f tc.CDNFederation, CDNName string) (*tc.CreateCDNFederationResponse, ReqInf, error) {
 	data := tc.CreateCDNFederationResponse{}
-	route := fmt.Sprintf("%s/cdns/%s/federations", apiBase, url.QueryEscape(CDNName))
+	route := fmt.Sprintf("/cdns/%s/federations", url.QueryEscape(CDNName))
 	inf, err := to.post(route, f, nil, &data)
 	return &data, inf, err
 }
 
 func (to *Session) GetCDNFederationsByNameWithHdr(CDNName string, header http.Header) (*tc.CDNFederationResponse, ReqInf, error) {
 	data := tc.CDNFederationResponse{}
-	route := fmt.Sprintf("%s/cdns/%s/federations", apiBase, url.QueryEscape(CDNName))
+	route := fmt.Sprintf("/cdns/%s/federations", url.QueryEscape(CDNName))
 	inf, err := to.get(route, header, &data)
 	return &data, inf, err
 }
@@ -48,7 +48,7 @@ func (to *Session) GetCDNFederationsByName(CDNName string) (*tc.CDNFederationRes
 }
 
 func (to *Session) GetCDNFederationsByNameWithHdrReturnList(CDNName string, header http.Header) ([]tc.CDNFederation, ReqInf, error) {
-	route := fmt.Sprintf("%s/cdns/%s/federations", apiBase, url.QueryEscape(CDNName))
+	route := fmt.Sprintf("/cdns/%s/federations", url.QueryEscape(CDNName))
 	resp := struct {
 		Response []tc.CDNFederation `json:"response"`
 	}{}
@@ -58,7 +58,7 @@ func (to *Session) GetCDNFederationsByNameWithHdrReturnList(CDNName string, head
 
 func (to *Session) GetCDNFederationsByIDWithHdr(CDNName string, ID int, header http.Header) (*tc.CDNFederationResponse, ReqInf, error) {
 	data := tc.CDNFederationResponse{}
-	route := fmt.Sprintf("%s/cdns/%s/federations?id=%v", apiBase, url.QueryEscape(CDNName), ID)
+	route := fmt.Sprintf("/cdns/%s/federations?id=%v", url.QueryEscape(CDNName), ID)
 	inf, err := to.get(route, header, &data)
 	return &data, inf, err
 }
@@ -70,7 +70,7 @@ func (to *Session) GetCDNFederationsByID(CDNName string, ID int) (*tc.CDNFederat
 
 func (to *Session) UpdateCDNFederationsByIDWithHdr(f tc.CDNFederation, CDNName string, ID int, h http.Header) (*tc.UpdateCDNFederationResponse, ReqInf, error) {
 	data := tc.UpdateCDNFederationResponse{}
-	route := fmt.Sprintf("%s/cdns/%s/federations/%d", apiBase, url.QueryEscape(CDNName), ID)
+	route := fmt.Sprintf("/cdns/%s/federations/%d", url.QueryEscape(CDNName), ID)
 	inf, err := to.put(route, f, h, &data)
 	return &data, inf, err
 }
@@ -82,7 +82,7 @@ func (to *Session) UpdateCDNFederationsByID(f tc.CDNFederation, CDNName string,
 
 func (to *Session) DeleteCDNFederationByID(CDNName string, ID int) (*tc.DeleteCDNFederationResponse, ReqInf, error) {
 	data := tc.DeleteCDNFederationResponse{}
-	route := fmt.Sprintf("%s/cdns/%s/federations/%d", apiBase, url.QueryEscape(CDNName), ID)
+	route := fmt.Sprintf("/cdns/%s/federations/%d", url.QueryEscape(CDNName), ID)
 	inf, err := to.del(route, nil, &data)
 	return &data, inf, err
 }
diff --git a/traffic_ops/v3-client/coordinate.go b/traffic_ops/v3-client/coordinate.go
index 971234f..ace00c7 100644
--- a/traffic_ops/v3-client/coordinate.go
+++ b/traffic_ops/v3-client/coordinate.go
@@ -23,18 +23,21 @@ import (
 )
 
 const (
+	// API_COORDINATES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_COORDINATES = apiBase + "/coordinates"
+
+	APICoordinates = "/coordinates"
 )
 
 // Create a Coordinate
 func (to *Session) CreateCoordinate(coordinate tc.Coordinate) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_COORDINATES, coordinate, nil, &alerts)
+	reqInf, err := to.post(APICoordinates, coordinate, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateCoordinateByIDWithHdr(id int, coordinate tc.Coordinate, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_COORDINATES, id)
+	route := fmt.Sprintf("%s?id=%d", APICoordinates, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, coordinate, header, &alerts)
 	return alerts, reqInf, err
@@ -48,7 +51,7 @@ func (to *Session) UpdateCoordinateByID(id int, coordinate tc.Coordinate) (tc.Al
 
 func (to *Session) GetCoordinatesWithHdr(header http.Header) ([]tc.Coordinate, ReqInf, error) {
 	var data tc.CoordinatesResponse
-	reqInf, err := to.get(API_COORDINATES, header, &data)
+	reqInf, err := to.get(APICoordinates, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -59,7 +62,7 @@ func (to *Session) GetCoordinates() ([]tc.Coordinate, ReqInf, error) {
 }
 
 func (to *Session) GetCoordinateByIDWithHdr(id int, header http.Header) ([]tc.Coordinate, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_COORDINATES, id)
+	route := fmt.Sprintf("%s?id=%d", APICoordinates, id)
 	var data tc.CoordinatesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -78,7 +81,7 @@ func (to *Session) GetCoordinateByName(name string) ([]tc.Coordinate, ReqInf, er
 }
 
 func (to *Session) GetCoordinateByNameWithHdr(name string, header http.Header) ([]tc.Coordinate, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_COORDINATES, name)
+	route := fmt.Sprintf("%s?name=%s", APICoordinates, name)
 	var data tc.CoordinatesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -86,7 +89,7 @@ func (to *Session) GetCoordinateByNameWithHdr(name string, header http.Header) (
 
 // DELETE a Coordinate by ID
 func (to *Session) DeleteCoordinateByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_COORDINATES, id)
+	route := fmt.Sprintf("%s?id=%d", APICoordinates, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/crconfig.go b/traffic_ops/v3-client/crconfig.go
index 6c9006f..6003212 100644
--- a/traffic_ops/v3-client/crconfig.go
+++ b/traffic_ops/v3-client/crconfig.go
@@ -25,7 +25,10 @@ import (
 )
 
 const (
+	// API_SNAPSHOT is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_SNAPSHOT = apiBase + "/snapshot"
+
+	APISnapshot = "/snapshot"
 )
 
 type OuterResponse struct {
@@ -34,8 +37,9 @@ type OuterResponse struct {
 
 // GetCRConfig returns the raw JSON bytes of the CRConfig from Traffic Ops, and whether the bytes were from the client's internal cache.
 func (to *Session) GetCRConfig(cdn string) ([]byte, ReqInf, error) {
-	uri := apiBase + `/cdns/` + cdn + `/snapshot`
-	bts, reqInf, err := to.getBytesWithTTL(uri, tmPollingInterval)
+	uri := `/cdns/` + cdn + `/snapshot`
+	bts := []byte{}
+	reqInf, err := to.get(uri, nil, &bts)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -48,7 +52,7 @@ func (to *Session) GetCRConfig(cdn string) ([]byte, ReqInf, error) {
 }
 
 func (to *Session) SnapshotCRConfigWithHdr(cdn string, header http.Header) (ReqInf, error) {
-	uri := fmt.Sprintf("%s?cdn=%s", API_SNAPSHOT, url.QueryEscape(cdn))
+	uri := fmt.Sprintf("%s?cdn=%s", APISnapshot, url.QueryEscape(cdn))
 	resp := OuterResponse{}
 	reqInf, err := to.put(uri, nil, header, &resp)
 	return reqInf, err
@@ -56,8 +60,9 @@ func (to *Session) SnapshotCRConfigWithHdr(cdn string, header http.Header) (ReqI
 
 // GetCRConfigNew returns the raw JSON bytes of the latest CRConfig from Traffic Ops, and whether the bytes were from the client's internal cache.
 func (to *Session) GetCRConfigNew(cdn string) ([]byte, ReqInf, error) {
-	uri := apiBase + `/cdns/` + cdn + `/snapshot/new`
-	bts, reqInf, err := to.getBytesWithTTL(uri, tmPollingInterval)
+	uri := `/cdns/` + cdn + `/snapshot/new`
+	bts := []byte{}
+	reqInf, err := to.get(uri, nil, &bts)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -77,7 +82,7 @@ func (to *Session) SnapshotCRConfig(cdn string) (ReqInf, error) {
 
 // SnapshotCDNByID snapshots a CDN by ID.
 func (to *Session) SnapshotCRConfigByID(id int) (tc.Alerts, ReqInf, error) {
-	url := fmt.Sprintf("%s?cdnID=%d", API_SNAPSHOT, id)
+	url := fmt.Sprintf("%s?cdnID=%d", APISnapshot, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(url, nil, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/deliveryservice.go b/traffic_ops/v3-client/deliveryservice.go
index 36ecea7..589863f 100644
--- a/traffic_ops/v3-client/deliveryservice.go
+++ b/traffic_ops/v3-client/deliveryservice.go
@@ -32,6 +32,8 @@ const (
 	// API_DELIVERY_SERVICES is the API path on which Traffic Ops serves Delivery Service
 	// information. More specific information is typically found on sub-paths of this.
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICES = apiBase + "/deliveryservices"
 
 	// API_DELIVERY_SERVICE_ID is the API path on which Traffic Ops serves information about
@@ -39,6 +41,8 @@ const (
 	// intended to be used with fmt.Sprintf to insert its required path parameter (namely the ID
 	// of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_id.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_ID = API_DELIVERY_SERVICES + "/%v"
 
 	// API_DELIVERY_SERVICE_HEALTH is the API path on which Traffic Ops serves information about
@@ -46,6 +50,8 @@ const (
 	// intended to be used with fmt.Sprintf to insert its required path parameter (namely the ID
 	// of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_id_health.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_HEALTH = API_DELIVERY_SERVICE_ID + "/health"
 
 	// API_DELIVERY_SERVICE_CAPACITY is the API path on which Traffic Ops serves information about
@@ -53,6 +59,8 @@ const (
 	// intended to be used with fmt.Sprintf to insert its required path parameter (namely the ID
 	// of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_id_capacity.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_CAPACITY = API_DELIVERY_SERVICE_ID + "/capacity"
 
 	// API_DELIVERY_SERVICE_ELIGIBLE_SERVERS is the API path on which Traffic Ops serves information about
@@ -60,6 +68,8 @@ const (
 	// unique identifier. It is intended to be used with fmt.Sprintf to insert its required path parameter
 	// (namely the ID of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_id_servers_eligible.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_ELIGIBLE_SERVERS = API_DELIVERY_SERVICE_ID + "/servers/eligible"
 
 	// API_DELIVERY_SERVICES_SAFE_UPDATE is the API path on which Traffic Ops provides the functionality to
@@ -67,6 +77,8 @@ const (
 	// identifer. It is intended to be used with fmt.Sprintf to insert its required path parameter
 	// (namely the ID of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_id_safe.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICES_SAFE_UPDATE = API_DELIVERY_SERVICE_ID + "/safe"
 
 	// API_DELIVERY_SERVICE_XMLID_SSL_KEYS is the API path on which Traffic Ops serves information about
@@ -74,10 +86,14 @@ const (
 	// intended to be used with fmt.Sprintf to insert its required path parameter (namely the XMLID
 	// of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_xmlid_xmlid_sslkeys.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_XMLID_SSL_KEYS = API_DELIVERY_SERVICES + "/xmlId/%s/sslkeys"
 
 	// API_DELIVERY_SERVICE_GENERATE_SSL_KEYS is the API path on which Traffic Ops will generate new SSL keys
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_sslkeys_generate.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_GENERATE_SSL_KEYS = API_DELIVERY_SERVICES + "/sslkeys/generate"
 
 	// API_DELIVERY_SERVICE_URI_SIGNING_KEYS is the API path on which Traffic Ops serves information
@@ -85,6 +101,8 @@ const (
 	// by its XMLID. It is intended to be used with fmt.Sprintf to insert its required path parameter
 	// (namely the XMLID of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_xmlid_urisignkeys.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICES_URI_SIGNING_KEYS = API_DELIVERY_SERVICES + "/%s/urisignkeys"
 
 	// API_DELIVERY_SERVICES_URL_SIGNING_KEYS is the API path on which Traffic Ops serves information
@@ -92,11 +110,15 @@ const (
 	// by its XMLID. It is intended to be used with fmt.Sprintf to insert its required path parameter
 	// (namely the XMLID of the Delivery Service of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_xmlid_xmlid_urlkeys.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICES_URL_SIGNING_KEYS = API_DELIVERY_SERVICES + "/xmlid/%s/urlkeys"
 
 	// API_DELIVERY_SERVICES_REGEXES is the API path on which Traffic Ops serves Delivery Service
 	// 'regex' (Regular Expression) information.
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_regexes.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICES_REGEXES = apiBase + "/deliveryservices_regexes"
 
 	// API_SERVER_DELIVERY_SERVICES is the API path on which Traffic Ops serves functionality
@@ -104,22 +126,43 @@ const (
 	// intended to be used with fmt.Sprintf to insert its required path parameter (namely the ID
 	// of the server of interest).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/servers_id_deliveryservices.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_SERVER_DELIVERY_SERVICES = apiBase + "/servers/%d/deliveryservices"
 
 	// API_DELIVERY_SERVICE_SERVER is the API path on which Traffic Ops serves functionality related
 	// to the associations between Delivery Services and their assigned Server(s).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryserviceserver.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_SERVER = apiBase + "/deliveryserviceserver"
 
 	// API_DELIVERY_SERVICES_SERVERS is the API path on which Traffic Ops serves functionality related
 	// to the associations between a Delivery Service and its assigned Server(s).
 	// See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_xmlid_servers.html
+	//
+	// Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICES_SERVERS = apiBase + "/deliveryservices/%s/servers"
+
+	APIDeliveryServices               = "/deliveryservices"
+	APIDeliveryServiceId              = APIDeliveryServices + "/%v"
+	APIDeliveryServiceHealth          = APIDeliveryServiceId + "/health"
+	APIDeliveryServiceCapacity        = APIDeliveryServiceId + "/capacity"
+	APIDeliveryServiceEligibleServers = APIDeliveryServiceId + "/servers/eligible"
+	APIDeliveryServicesSafeUpdate     = APIDeliveryServiceId + "/safe"
+	APIDeliveryServiceXmlidSslKeys    = APIDeliveryServices + "/xmlId/%s/sslkeys"
+	APIDeliveryServiceGenerateSslKeys = APIDeliveryServices + "/sslkeys/generate"
+	APIDeliveryServicesUriSigningKeys = APIDeliveryServices + "/%s/urisignkeys"
+	APIDeliveryServicesUrlSigningKeys = APIDeliveryServices + "/xmlid/%s/urlkeys"
+	APIDeliveryServicesRegexes        = "/deliveryservices_regexes"
+	APIServerDeliveryServices         = "/servers/%d/deliveryservices"
+	APIDeliveryServiceServer          = "/deliveryserviceserver"
+	APIDeliveryServicesServers        = "/deliveryservices/%s/servers"
 )
 
 func (to *Session) GetDeliveryServicesByServerV30WithHdr(id int, header http.Header) ([]tc.DeliveryServiceNullableV30, ReqInf, error) {
 	var data tc.DeliveryServicesResponseV30
-	reqInf, err := to.get(fmt.Sprintf(API_SERVER_DELIVERY_SERVICES, id), header, &data)
+	reqInf, err := to.get(fmt.Sprintf(APIServerDeliveryServices, id), header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -138,7 +181,7 @@ func (to *Session) GetDeliveryServicesByServer(id int) ([]tc.DeliveryServiceNull
 func (to *Session) GetDeliveryServicesByServerWithHdr(id int, header http.Header) ([]tc.DeliveryServiceNullable, ReqInf, error) {
 	var data tc.DeliveryServicesNullableResponse
 
-	reqInf, err := to.get(fmt.Sprintf(API_SERVER_DELIVERY_SERVICES, id), header, &data)
+	reqInf, err := to.get(fmt.Sprintf(APIServerDeliveryServices, id), header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -146,7 +189,7 @@ func (to *Session) GetDeliveryServicesByServerWithHdr(id int, header http.Header
 // satisfy the passed query string parameters. See the API documentation for
 // information on the available parameters.
 func (to *Session) GetDeliveryServicesV30WithHdr(header http.Header, params url.Values) ([]tc.DeliveryServiceNullableV30, ReqInf, error) {
-	uri := API_DELIVERY_SERVICES
+	uri := APIDeliveryServices
 	if params != nil {
 		uri += "?" + params.Encode()
 	}
@@ -159,7 +202,7 @@ func (to *Session) GetDeliveryServicesNullableWithHdr(header http.Header) ([]tc.
 	data := struct {
 		Response []tc.DeliveryServiceNullable `json:"response"`
 	}{}
-	reqInf, err := to.get(API_DELIVERY_SERVICES, header, &data)
+	reqInf, err := to.get(APIDeliveryServices, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -178,7 +221,7 @@ func (to *Session) GetDeliveryServicesByCDNIDWithHdr(cdnID int, header http.Head
 	data := struct {
 		Response []tc.DeliveryServiceNullable `json:"response"`
 	}{}
-	reqInf, err := to.get(API_DELIVERY_SERVICES+"?cdn="+strconv.Itoa(cdnID), header, &data)
+	reqInf, err := to.get(APIDeliveryServices+"?cdn="+strconv.Itoa(cdnID), header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -199,7 +242,7 @@ func (to *Session) GetDeliveryServiceNullableWithHdr(id string, header http.Head
 	data := struct {
 		Response []tc.DeliveryServiceNullableV30 `json:"response"`
 	}{}
-	route := fmt.Sprintf("%s?id=%s", API_DELIVERY_SERVICES, id)
+	route := fmt.Sprintf("%s?id=%s", APIDeliveryServices, id)
 	reqInf, err := to.get(route, header, &data)
 	if err != nil {
 		return nil, reqInf, err
@@ -222,7 +265,7 @@ func (to *Session) GetDeliveryServiceNullable(id string) (*tc.DeliveryServiceNul
 	data := struct {
 		Response []tc.DeliveryServiceNullable `json:"response"`
 	}{}
-	reqInf, err := to.get(API_DELIVERY_SERVICES+"?id="+url.QueryEscape(id), nil, &data)
+	reqInf, err := to.get(APIDeliveryServices+"?id="+url.QueryEscape(id), nil, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -236,7 +279,7 @@ func (to *Session) GetDeliveryServiceNullable(id string) (*tc.DeliveryServiceNul
 // the given XMLID.
 func (to *Session) GetDeliveryServiceByXMLIDNullableWithHdr(XMLID string, header http.Header) ([]tc.DeliveryServiceNullableV30, ReqInf, error) {
 	var data tc.DeliveryServicesResponseV30
-	reqInf, err := to.get(API_DELIVERY_SERVICES+"?xmlId="+url.QueryEscape(XMLID), header, &data)
+	reqInf, err := to.get(APIDeliveryServices+"?xmlId="+url.QueryEscape(XMLID), header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -306,7 +349,7 @@ func (to *Session) CreateDeliveryServiceV30(ds tc.DeliveryServiceNullableV30) (t
 	}
 
 	var data tc.DeliveryServicesResponseV30
-	reqInf, err := to.post(API_DELIVERY_SERVICES, ds, nil, &data)
+	reqInf, err := to.post(APIDeliveryServices, ds, nil, &data)
 	if err != nil {
 		return tc.DeliveryServiceNullableV30{}, reqInf, err
 	}
@@ -368,7 +411,7 @@ func (to *Session) CreateDeliveryServiceNullable(ds *tc.DeliveryServiceNullable)
 	}
 
 	var data tc.CreateDeliveryServiceNullableResponse
-	_, err := to.post(API_DELIVERY_SERVICES, ds, nil, &data)
+	_, err := to.post(APIDeliveryServices, ds, nil, &data)
 	if err != nil {
 		return nil, err
 	}
@@ -380,7 +423,7 @@ func (to *Session) CreateDeliveryServiceNullable(ds *tc.DeliveryServiceNullable)
 // integral, unique identifier 'id' with the one it's passed.
 func (to *Session) UpdateDeliveryServiceV30WithHdr(id int, ds tc.DeliveryServiceNullableV30, header http.Header) (tc.DeliveryServiceNullableV30, ReqInf, error) {
 	var data tc.DeliveryServicesResponseV30
-	reqInf, err := to.put(fmt.Sprintf(API_DELIVERY_SERVICE_ID, id), ds, header, &data)
+	reqInf, err := to.put(fmt.Sprintf(APIDeliveryServiceId, id), ds, header, &data)
 	if err != nil {
 		return tc.DeliveryServiceNullableV30{}, reqInf, err
 	}
@@ -406,7 +449,7 @@ func (to *Session) UpdateDeliveryServiceNullable(id string, ds *tc.DeliveryServi
 
 func (to *Session) UpdateDeliveryServiceNullableWithHdr(id string, ds *tc.DeliveryServiceNullable, header http.Header) (*tc.UpdateDeliveryServiceNullableResponse, error) {
 	var data tc.UpdateDeliveryServiceNullableResponse
-	_, err := to.put(fmt.Sprintf(API_DELIVERY_SERVICE_ID, id), ds, header, &data)
+	_, err := to.put(fmt.Sprintf(APIDeliveryServiceId, id), ds, header, &data)
 	if err != nil {
 		return nil, err
 	}
@@ -416,7 +459,7 @@ func (to *Session) UpdateDeliveryServiceNullableWithHdr(id string, ds *tc.Delive
 // DeleteDeliveryService deletes the DeliveryService matching the ID it's passed.
 func (to *Session) DeleteDeliveryService(id string) (*tc.DeleteDeliveryServiceResponse, error) {
 	var data tc.DeleteDeliveryServiceResponse
-	_, err := to.del(fmt.Sprintf(API_DELIVERY_SERVICE_ID, id), nil, &data)
+	_, err := to.del(fmt.Sprintf(APIDeliveryServiceId, id), nil, &data)
 	if err != nil {
 		return nil, err
 	}
@@ -425,7 +468,7 @@ func (to *Session) DeleteDeliveryService(id string) (*tc.DeleteDeliveryServiceRe
 
 func (to *Session) GetDeliveryServiceHealthWithHdr(id string, header http.Header) (*tc.DeliveryServiceHealth, ReqInf, error) {
 	var data tc.DeliveryServiceHealthResponse
-	reqInf, err := to.get(fmt.Sprintf(API_DELIVERY_SERVICE_HEALTH, id), nil, &data)
+	reqInf, err := to.get(fmt.Sprintf(APIDeliveryServiceHealth, id), nil, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -442,7 +485,7 @@ func (to *Session) GetDeliveryServiceHealth(id string) (*tc.DeliveryServiceHealt
 
 func (to *Session) GetDeliveryServiceCapacityWithHdr(id string, header http.Header) (*tc.DeliveryServiceCapacity, ReqInf, error) {
 	var data tc.DeliveryServiceCapacityResponse
-	reqInf, err := to.get(fmt.Sprintf(API_DELIVERY_SERVICE_CAPACITY, id), header, &data)
+	reqInf, err := to.get(fmt.Sprintf(APIDeliveryServiceCapacity, id), header, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -474,7 +517,7 @@ func (to *Session) GenerateSSLKeysForDS(XMLID string, CDNName string, sslFields
 	response := struct {
 		Response string `json:"response"`
 	}{}
-	reqInf, err := to.post(API_DELIVERY_SERVICE_GENERATE_SSL_KEYS, request, nil, &response)
+	reqInf, err := to.post(APIDeliveryServiceGenerateSslKeys, request, nil, &response)
 	if err != nil {
 		return "", reqInf, err
 	}
@@ -485,7 +528,7 @@ func (to *Session) DeleteDeliveryServiceSSLKeysByID(XMLID string) (string, ReqIn
 	resp := struct {
 		Response string `json:"response"`
 	}{}
-	reqInf, err := to.del(fmt.Sprintf(API_DELIVERY_SERVICE_XMLID_SSL_KEYS, url.QueryEscape(XMLID)), nil, &resp)
+	reqInf, err := to.del(fmt.Sprintf(APIDeliveryServiceXmlidSslKeys, url.QueryEscape(XMLID)), nil, &resp)
 	return resp.Response, reqInf, err
 }
 
@@ -498,7 +541,7 @@ func (to *Session) GetDeliveryServiceSSLKeysByID(XMLID string) (*tc.DeliveryServ
 
 func (to *Session) GetDeliveryServiceSSLKeysByIDWithHdr(XMLID string, header http.Header) (*tc.DeliveryServiceSSLKeys, ReqInf, error) {
 	var data tc.DeliveryServiceSSLKeysResponse
-	reqInf, err := to.get(fmt.Sprintf(API_DELIVERY_SERVICE_XMLID_SSL_KEYS, url.QueryEscape(XMLID)), header, &data)
+	reqInf, err := to.get(fmt.Sprintf(APIDeliveryServiceXmlidSslKeys, url.QueryEscape(XMLID)), header, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -510,7 +553,7 @@ func (to *Session) GetDeliveryServicesEligibleWithHdr(dsID int, header http.Head
 		Response []tc.DSServer `json:"response"`
 	}{Response: []tc.DSServer{}}
 
-	reqInf, err := to.get(fmt.Sprintf(API_DELIVERY_SERVICE_ELIGIBLE_SERVERS, dsID), header, &resp)
+	reqInf, err := to.get(fmt.Sprintf(APIDeliveryServiceEligibleServers, dsID), header, &resp)
 	return resp.Response, reqInf, err
 }
 
@@ -533,7 +576,7 @@ func (to *Session) GetDeliveryServiceURLSigKeysWithHdr(dsName string, header htt
 		Response tc.URLSigKeys `json:"response"`
 	}{}
 
-	reqInf, err := to.get(fmt.Sprintf(API_DELIVERY_SERVICES_URL_SIGNING_KEYS, dsName), header, &data)
+	reqInf, err := to.get(fmt.Sprintf(APIDeliveryServicesUrlSigningKeys, dsName), header, &data)
 	if err != nil {
 		return tc.URLSigKeys{}, reqInf, err
 	}
@@ -549,7 +592,7 @@ func (to *Session) GetDeliveryServiceURISigningKeys(dsName string) ([]byte, ReqI
 // identified by the XMLID 'dsName'. The result is not parsed.
 func (to *Session) GetDeliveryServiceURISigningKeysWithHdr(dsName string, header http.Header) ([]byte, ReqInf, error) {
 	data := json.RawMessage{}
-	reqInf, err := to.get(fmt.Sprintf(API_DELIVERY_SERVICES_URI_SIGNING_KEYS, url.QueryEscape(dsName)), header, &data)
+	reqInf, err := to.get(fmt.Sprintf(APIDeliveryServicesUriSigningKeys, url.QueryEscape(dsName)), header, &data)
 	if err != nil {
 		return []byte{}, reqInf, err
 	}
@@ -560,7 +603,7 @@ func (to *Session) GetDeliveryServiceURISigningKeysWithHdr(dsName string, header
 // Service identified by the integral, unique identifier 'id'.
 func (to *Session) SafeDeliveryServiceUpdateV30WithHdr(id int, r tc.DeliveryServiceSafeUpdateRequest, header http.Header) (tc.DeliveryServiceNullableV30, ReqInf, error) {
 	var data tc.DeliveryServiceSafeUpdateResponseV30
-	reqInf, err := to.put(fmt.Sprintf(API_DELIVERY_SERVICES_SAFE_UPDATE, id), r, header, &data)
+	reqInf, err := to.put(fmt.Sprintf(APIDeliveryServicesSafeUpdate, id), r, header, &data)
 	if err != nil {
 		return tc.DeliveryServiceNullableV30{}, reqInf, err
 	}
@@ -579,7 +622,7 @@ func (to *Session) SafeDeliveryServiceUpdateV30WithHdr(id int, r tc.DeliveryServ
 // SafeDeliveryServiceUpdateV30WithHdr.
 func (to *Session) UpdateDeliveryServiceSafe(id int, ds tc.DeliveryServiceSafeUpdateRequest) ([]tc.DeliveryServiceNullable, ReqInf, error) {
 	var resp tc.DeliveryServiceSafeUpdateResponse
-	reqInf, err := to.put(fmt.Sprintf(API_DELIVERY_SERVICES_SAFE_UPDATE, id), ds, nil, &resp)
+	reqInf, err := to.put(fmt.Sprintf(APIDeliveryServicesSafeUpdate, id), ds, nil, &resp)
 	if err != nil {
 		return resp.Response, reqInf, err
 	}
@@ -600,6 +643,6 @@ func (to *Session) UpdateDeliveryServiceSafe(id int, ds tc.DeliveryServiceSafeUp
 // GetDeliveryServicesV30WithHdr.
 func (to *Session) GetAccessibleDeliveryServicesByTenant(tenantId int) ([]tc.DeliveryServiceNullable, ReqInf, error) {
 	data := tc.DeliveryServicesNullableResponse{}
-	reqInf, err := to.get(fmt.Sprintf("%s?accessibleTo=%d", API_DELIVERY_SERVICES, tenantId), nil, &data)
+	reqInf, err := to.get(fmt.Sprintf("%s?accessibleTo=%d", APIDeliveryServices, tenantId), nil, &data)
 	return data.Response, reqInf, err
 }
diff --git a/traffic_ops/v3-client/deliveryservice_regexes.go b/traffic_ops/v3-client/deliveryservice_regexes.go
index ec5e7bd..752074a 100644
--- a/traffic_ops/v3-client/deliveryservice_regexes.go
+++ b/traffic_ops/v3-client/deliveryservice_regexes.go
@@ -23,8 +23,11 @@ import (
 )
 
 const (
+	// API_DS_REGEXES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	// See: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/deliveryservices_id_regexes.html
 	API_DS_REGEXES = apiBase + "/deliveryservices/%d/regexes"
+
+	APIDSRegexes = "/deliveryservices/%d/regexes"
 )
 
 // GetDeliveryServiceRegexesByDSID gets DeliveryServiceRegexes by a DS id
@@ -33,7 +36,7 @@ func (to *Session) GetDeliveryServiceRegexesByDSID(dsID int, params map[string]s
 	response := struct {
 		Response []tc.DeliveryServiceIDRegex `json:"response"`
 	}{}
-	reqInf, err := to.get(fmt.Sprintf(API_DS_REGEXES, dsID)+mapToQueryParameters(params), nil, &response)
+	reqInf, err := to.get(fmt.Sprintf(APIDSRegexes, dsID)+mapToQueryParameters(params), nil, &response)
 	return response.Response, reqInf, err
 }
 
@@ -46,13 +49,13 @@ func (to *Session) GetDeliveryServiceRegexes() ([]tc.DeliveryServiceRegexes, Req
 
 func (to *Session) GetDeliveryServiceRegexesWithHdr(header http.Header) ([]tc.DeliveryServiceRegexes, ReqInf, error) {
 	var data tc.DeliveryServiceRegexResponse
-	reqInf, err := to.get(API_DELIVERY_SERVICES_REGEXES, header, &data)
+	reqInf, err := to.get(APIDeliveryServicesRegexes, header, &data)
 	return data.Response, reqInf, err
 }
 
 func (to *Session) PostDeliveryServiceRegexesByDSID(dsID int, regex tc.DeliveryServiceRegexPost) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	route := fmt.Sprintf(API_DS_REGEXES, dsID)
+	route := fmt.Sprintf(APIDSRegexes, dsID)
 	reqInf, err := to.post(route, regex, nil, &alerts)
 	return alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/deliveryservice_request_comments.go b/traffic_ops/v3-client/deliveryservice_request_comments.go
index 64c49f6..09a544a 100644
--- a/traffic_ops/v3-client/deliveryservice_request_comments.go
+++ b/traffic_ops/v3-client/deliveryservice_request_comments.go
@@ -24,18 +24,21 @@ import (
 )
 
 const (
+	// API_DELIVERY_SERVICE_REQUEST_COMMENTS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICE_REQUEST_COMMENTS = apiBase + "/deliveryservice_request_comments"
+
+	APIDeliveryServiceRequestComments = "/deliveryservice_request_comments"
 )
 
 // Create a delivery service request comment
 func (to *Session) CreateDeliveryServiceRequestComment(comment tc.DeliveryServiceRequestComment) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_DELIVERY_SERVICE_REQUEST_COMMENTS, comment, nil, &alerts)
+	reqInf, err := to.post(APIDeliveryServiceRequestComments, comment, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateDeliveryServiceRequestCommentByIDWithHdr(id int, comment tc.DeliveryServiceRequestComment, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_DELIVERY_SERVICE_REQUEST_COMMENTS, id)
+	route := fmt.Sprintf("%s?id=%d", APIDeliveryServiceRequestComments, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, comment, header, &alerts)
 	return alerts, reqInf, err
@@ -49,7 +52,7 @@ func (to *Session) UpdateDeliveryServiceRequestCommentByID(id int, comment tc.De
 
 func (to *Session) GetDeliveryServiceRequestCommentsWithHdr(header http.Header) ([]tc.DeliveryServiceRequestComment, ReqInf, error) {
 	var data tc.DeliveryServiceRequestCommentsResponse
-	reqInf, err := to.get(API_DELIVERY_SERVICE_REQUEST_COMMENTS, header, &data)
+	reqInf, err := to.get(APIDeliveryServiceRequestComments, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -60,7 +63,7 @@ func (to *Session) GetDeliveryServiceRequestComments() ([]tc.DeliveryServiceRequ
 }
 
 func (to *Session) GetDeliveryServiceRequestCommentByIDWithHdr(id int, header http.Header) ([]tc.DeliveryServiceRequestComment, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_DELIVERY_SERVICE_REQUEST_COMMENTS, id)
+	route := fmt.Sprintf("%s?id=%d", APIDeliveryServiceRequestComments, id)
 	var data tc.DeliveryServiceRequestCommentsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -74,7 +77,7 @@ func (to *Session) GetDeliveryServiceRequestCommentByID(id int) ([]tc.DeliverySe
 
 // DELETE a delivery service request comment by ID
 func (to *Session) DeleteDeliveryServiceRequestCommentByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_DELIVERY_SERVICE_REQUEST_COMMENTS, id)
+	route := fmt.Sprintf("%s?id=%d", APIDeliveryServiceRequestComments, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/deliveryservice_requests.go b/traffic_ops/v3-client/deliveryservice_requests.go
index 9997bfc..a849e34 100644
--- a/traffic_ops/v3-client/deliveryservice_requests.go
+++ b/traffic_ops/v3-client/deliveryservice_requests.go
@@ -25,7 +25,10 @@ import (
 )
 
 const (
+	// API_DS_REQUESTS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DS_REQUESTS = apiBase + "/deliveryservice_requests"
+
+	APIDSRequests = "/deliveryservice_requests"
 )
 
 // CreateDeliveryServiceRequest creates a Delivery Service Request.
@@ -85,7 +88,7 @@ func (to *Session) CreateDeliveryServiceRequest(dsr tc.DeliveryServiceRequest) (
 		dsr.DeliveryService.TenantID = ten.ID
 	}
 
-	reqInf, err := to.post(API_DS_REQUESTS, dsr, nil, &alerts)
+	reqInf, err := to.post(APIDSRequests, dsr, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -93,7 +96,7 @@ func (to *Session) GetDeliveryServiceRequestsWithHdr(header http.Header) ([]tc.D
 	data := struct {
 		Response []tc.DeliveryServiceRequest `json:"response"`
 	}{}
-	reqInf, err := to.get(API_DS_REQUESTS, header, &data)
+	reqInf, err := to.get(APIDSRequests, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -104,7 +107,7 @@ func (to *Session) GetDeliveryServiceRequests() ([]tc.DeliveryServiceRequest, Re
 }
 
 func (to *Session) GetDeliveryServiceRequestByXMLIDWithHdr(XMLID string, header http.Header) ([]tc.DeliveryServiceRequest, ReqInf, error) {
-	route := fmt.Sprintf("%s?xmlId=%s", API_DS_REQUESTS, url.QueryEscape(XMLID))
+	route := fmt.Sprintf("%s?xmlId=%s", APIDSRequests, url.QueryEscape(XMLID))
 	data := struct {
 		Response []tc.DeliveryServiceRequest `json:"response"`
 	}{}
@@ -119,7 +122,7 @@ func (to *Session) GetDeliveryServiceRequestByXMLID(XMLID string) ([]tc.Delivery
 }
 
 func (to *Session) GetDeliveryServiceRequestByIDWithHdr(id int, header http.Header) ([]tc.DeliveryServiceRequest, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_DS_REQUESTS, id)
+	route := fmt.Sprintf("%s?id=%d", APIDSRequests, id)
 	data := struct {
 		Response []tc.DeliveryServiceRequest `json:"response"`
 	}{}
@@ -134,7 +137,7 @@ func (to *Session) GetDeliveryServiceRequestByID(id int) ([]tc.DeliveryServiceRe
 }
 
 func (to *Session) UpdateDeliveryServiceRequestByIDWithHdr(id int, dsr tc.DeliveryServiceRequest, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_DS_REQUESTS, id)
+	route := fmt.Sprintf("%s?id=%d", APIDSRequests, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, dsr, header, &alerts)
 	return alerts, reqInf, err
@@ -148,7 +151,7 @@ func (to *Session) UpdateDeliveryServiceRequestByID(id int, dsr tc.DeliveryServi
 
 // DELETE a DeliveryServiceRequest by DeliveryServiceRequest assignee
 func (to *Session) DeleteDeliveryServiceRequestByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_DS_REQUESTS, id)
+	route := fmt.Sprintf("%s?id=%d", APIDSRequests, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/deliveryservices_required_capabilities.go b/traffic_ops/v3-client/deliveryservices_required_capabilities.go
index 792e2bd..172860a 100644
--- a/traffic_ops/v3-client/deliveryservices_required_capabilities.go
+++ b/traffic_ops/v3-client/deliveryservices_required_capabilities.go
@@ -25,13 +25,16 @@ import (
 )
 
 const (
+	// API_DELIVERY_SERVICES_REQUIRED_CAPABILITIES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DELIVERY_SERVICES_REQUIRED_CAPABILITIES = apiBase + "/deliveryservices_required_capabilities"
+
+	APIDeliveryServicesRequiredCapabilities = "/deliveryservices_required_capabilities"
 )
 
 // CreateDeliveryServicesRequiredCapability assigns a Required Capability to a Delivery Service
 func (to *Session) CreateDeliveryServicesRequiredCapability(capability tc.DeliveryServicesRequiredCapability) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_DELIVERY_SERVICES_REQUIRED_CAPABILITIES, capability, nil, &alerts)
+	reqInf, err := to.post(APIDeliveryServicesRequiredCapabilities, capability, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -41,7 +44,7 @@ func (to *Session) DeleteDeliveryServicesRequiredCapability(deliveryserviceID in
 	param := url.Values{}
 	param.Add("deliveryServiceID", strconv.Itoa(deliveryserviceID))
 	param.Add("requiredCapability", capability)
-	route := fmt.Sprintf("%s?%s", API_DELIVERY_SERVICES_REQUIRED_CAPABILITIES, param.Encode())
+	route := fmt.Sprintf("%s?%s", APIDeliveryServicesRequiredCapabilities, param.Encode())
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
 }
@@ -58,7 +61,7 @@ func (to *Session) GetDeliveryServicesRequiredCapabilitiesWithHdr(deliveryServic
 		param.Add("requiredCapability", *capability)
 	}
 
-	route := API_DELIVERY_SERVICES_REQUIRED_CAPABILITIES
+	route := APIDeliveryServicesRequiredCapabilities
 	if len(param) > 0 {
 		route = fmt.Sprintf("%s?%s", route, param.Encode())
 	}
diff --git a/traffic_ops/v3-client/deliveryserviceserver.go b/traffic_ops/v3-client/deliveryserviceserver.go
index 9f13e95..86099dc 100644
--- a/traffic_ops/v3-client/deliveryserviceserver.go
+++ b/traffic_ops/v3-client/deliveryserviceserver.go
@@ -28,7 +28,6 @@ import (
 
 // CreateDeliveryServiceServers associates the given servers with the given delivery services. If replace is true, it deletes any existing associations for the given delivery service.
 func (to *Session) CreateDeliveryServiceServers(dsID int, serverIDs []int, replace bool) (*tc.DSServerIDs, ReqInf, error) {
-	path := API_DELIVERY_SERVICE_SERVER
 	req := tc.DSServerIDs{
 		DeliveryServiceID: util.IntPtr(dsID),
 		ServerIDs:         serverIDs,
@@ -37,7 +36,7 @@ func (to *Session) CreateDeliveryServiceServers(dsID int, serverIDs []int, repla
 	resp := struct {
 		Response tc.DSServerIDs `json:"response"`
 	}{}
-	reqInf, err := to.post(path, req, nil, &resp)
+	reqInf, err := to.post(APIDeliveryServiceServer, req, nil, &resp)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -45,7 +44,7 @@ func (to *Session) CreateDeliveryServiceServers(dsID int, serverIDs []int, repla
 }
 
 func (to *Session) DeleteDeliveryServiceServer(dsID int, serverID int) (tc.Alerts, ReqInf, error) {
-	route := apiBase + `/deliveryserviceserver/` + strconv.Itoa(dsID) + "/" + strconv.Itoa(serverID)
+	route := `/deliveryserviceserver/` + strconv.Itoa(dsID) + "/" + strconv.Itoa(serverID)
 	resp := tc.Alerts{}
 	reqInf, err := to.del(route, nil, &resp)
 	return resp, reqInf, err
@@ -53,7 +52,7 @@ func (to *Session) DeleteDeliveryServiceServer(dsID int, serverID int) (tc.Alert
 
 // AssignServersToDeliveryService assigns the given list of servers to the delivery service with the given xmlId.
 func (to *Session) AssignServersToDeliveryService(servers []string, xmlId string) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf(API_DELIVERY_SERVICES_SERVERS, url.QueryEscape(xmlId))
+	route := fmt.Sprintf(APIDeliveryServicesServers, url.QueryEscape(xmlId))
 	dss := tc.DeliveryServiceServers{ServerNames: servers, XmlId: xmlId}
 	resp := tc.Alerts{}
 	reqInf, err := to.post(route, dss, nil, &resp)
@@ -70,7 +69,7 @@ func (to *Session) GetDeliveryServiceServer(page, limit string) ([]tc.DeliverySe
 func (to *Session) GetDeliveryServiceServerWithHdr(page, limit string, header http.Header) ([]tc.DeliveryServiceServer, ReqInf, error) {
 	var data tc.DeliveryServiceServerResponse
 	// TODO: page and limit should be integers not strings
-	reqInf, err := to.get(API_DELIVERY_SERVICE_SERVER+"?page="+url.QueryEscape(page)+"&limit="+url.QueryEscape(limit), header, &data)
+	reqInf, err := to.get(APIDeliveryServiceServer+"?page="+url.QueryEscape(page)+"&limit="+url.QueryEscape(limit), header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -127,7 +126,7 @@ func (to *Session) GetDeliveryServiceServersWithLimits(limit int, deliveryServic
 }
 
 func (to *Session) getDeliveryServiceServers(urlQuery url.Values, h http.Header) (tc.DeliveryServiceServerResponse, ReqInf, error) {
-	route := API_DELIVERY_SERVICE_SERVER
+	route := APIDeliveryServiceServer
 	if qry := urlQuery.Encode(); qry != "" {
 		route += `?` + qry
 	}
diff --git a/traffic_ops/v3-client/division.go b/traffic_ops/v3-client/division.go
index aadda2a..24feed6 100644
--- a/traffic_ops/v3-client/division.go
+++ b/traffic_ops/v3-client/division.go
@@ -24,18 +24,21 @@ import (
 )
 
 const (
+	// API_DIVISIONS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_DIVISIONS = apiBase + "/divisions"
+
+	APIDivisions = "/divisions"
 )
 
 // Create a Division
 func (to *Session) CreateDivision(division tc.Division) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_DIVISIONS, division, nil, &alerts)
+	reqInf, err := to.post(APIDivisions, division, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateDivisionByIDWithHdr(id int, division tc.Division, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_DIVISIONS, id)
+	route := fmt.Sprintf("%s/%d", APIDivisions, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, division, header, &alerts)
 	return alerts, reqInf, err
@@ -49,7 +52,7 @@ func (to *Session) UpdateDivisionByID(id int, division tc.Division) (tc.Alerts,
 
 func (to *Session) GetDivisionsWithHdr(header http.Header) ([]tc.Division, ReqInf, error) {
 	var data tc.DivisionsResponse
-	reqInf, err := to.get(API_DIVISIONS, header, &data)
+	reqInf, err := to.get(APIDivisions, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -60,7 +63,7 @@ func (to *Session) GetDivisions() ([]tc.Division, ReqInf, error) {
 }
 
 func (to *Session) GetDivisionByIDWithHdr(id int, header http.Header) ([]tc.Division, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_DIVISIONS, id)
+	route := fmt.Sprintf("%s?id=%d", APIDivisions, id)
 	var data tc.DivisionsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -73,7 +76,7 @@ func (to *Session) GetDivisionByID(id int) ([]tc.Division, ReqInf, error) {
 }
 
 func (to *Session) GetDivisionByNameWithHdr(name string, header http.Header) ([]tc.Division, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_DIVISIONS, url.QueryEscape(name))
+	route := fmt.Sprintf("%s?name=%s", APIDivisions, url.QueryEscape(name))
 	var data tc.DivisionsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -87,7 +90,7 @@ func (to *Session) GetDivisionByName(name string) ([]tc.Division, ReqInf, error)
 
 // DELETE a Division by Division id
 func (to *Session) DeleteDivisionByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_DIVISIONS, id)
+	route := fmt.Sprintf("%s/%d", APIDivisions, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/dsuser.go b/traffic_ops/v3-client/dsuser.go
index e8ca524..d18b586 100644
--- a/traffic_ops/v3-client/dsuser.go
+++ b/traffic_ops/v3-client/dsuser.go
@@ -23,7 +23,7 @@ import (
 
 // SetUserDeliveryService associates the given delivery services with the given user.
 func (to *Session) SetDeliveryServiceUser(userID int, dses []int, replace bool) (*tc.UserDeliveryServicePostResponse, error) {
-	uri := apiBase + `/deliveryservice_user`
+	uri := `/deliveryservice_user`
 	ds := tc.DeliveryServiceUserPost{UserID: &userID, DeliveryServices: &dses, Replace: &replace}
 	resp := tc.UserDeliveryServicePostResponse{}
 	_, err := to.post(uri, ds, nil, &resp)
@@ -35,7 +35,7 @@ func (to *Session) SetDeliveryServiceUser(userID int, dses []int, replace bool)
 
 // DeleteDeliveryServiceUser deletes the association between the given delivery service and user
 func (to *Session) DeleteDeliveryServiceUser(userID int, dsID int) (*tc.UserDeliveryServiceDeleteResponse, error) {
-	uri := apiBase + `/deliveryservice_user/` + strconv.Itoa(dsID) + `/` + strconv.Itoa(userID)
+	uri := `/deliveryservice_user/` + strconv.Itoa(dsID) + `/` + strconv.Itoa(userID)
 	resp := tc.UserDeliveryServiceDeleteResponse{}
 	if _, err := to.del(uri, nil, &resp); err != nil {
 		return nil, err
diff --git a/traffic_ops/v3-client/endpoints.go b/traffic_ops/v3-client/endpoints.go
index 161f252..cba5bc8 100644
--- a/traffic_ops/v3-client/endpoints.go
+++ b/traffic_ops/v3-client/endpoints.go
@@ -15,4 +15,41 @@
 
 package client
 
+// DEPRECATED: All new code should us Session.APIBase().
+// This isn't public, but only exists for deprecated public constants. It should be removed when they are.
 const apiBase = "/api/3.1"
+
+const apiBaseStr = "/api/"
+
+// apiVersions is the list of minor API versions in this client's major version.
+// This should be all minor versions from 0 up to the latest minor in Traffic Control
+// as of this client code.
+//
+// Versions are ordered latest-first.
+func apiVersions() []string {
+	return []string{
+		"3.1",
+		"3.0",
+	}
+}
+
+// APIBase returns the base API string for HTTP requests, such as /api/3.1.
+func (sn *Session) APIBase() string {
+	return apiBaseStr + sn.APIVersion()
+}
+
+// APIVersion is the version of the Traffic Ops API this client will use for requests.
+// If the client was created with any function except Login, or with UseLatestSupportedAPI false,
+// this will be LatestAPIVersion().
+// Otherwise, it will be the version dynamically determined to be the latest the Traffic Ops Server supports.
+func (sn *Session) APIVersion() string {
+	if sn.latestSupportedAPI != "" {
+		return sn.latestSupportedAPI
+	}
+	return sn.LatestAPIVersion()
+}
+
+// LatestAPIVersion returns the latest Traffic Ops API version this client supports.
+func (sn *Session) LatestAPIVersion() string {
+	return apiVersions()[0]
+}
diff --git a/traffic_ops/v3-client/federation.go b/traffic_ops/v3-client/federation.go
index e16d375..bbba996 100644
--- a/traffic_ops/v3-client/federation.go
+++ b/traffic_ops/v3-client/federation.go
@@ -26,14 +26,17 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 )
 
+// APIFederations is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const APIFederations = apiBase + "/federations"
 
+const APIFederationsPath = "/federations"
+
 func (to *Session) FederationsWithHdr(header http.Header) ([]tc.AllDeliveryServiceFederationsMapping, ReqInf, error) {
 	type FederationResponse struct {
 		Response []tc.AllDeliveryServiceFederationsMapping `json:"response"`
 	}
 	data := FederationResponse{}
-	inf, err := to.get(APIFederations, header, &data)
+	inf, err := to.get(APIFederationsPath, header, &data)
 	return data.Response, inf, err
 }
 
@@ -47,7 +50,7 @@ func (to *Session) AllFederationsWithHdr(header http.Header) ([]tc.AllDeliverySe
 		Response []tc.AllDeliveryServiceFederationsMapping `json:"response"`
 	}
 	data := FederationResponse{}
-	inf, err := to.get(apiBase+"/federations/all", header, &data)
+	inf, err := to.get("/federations/all", header, &data)
 	return data.Response, inf, err
 }
 
@@ -62,7 +65,7 @@ func (to *Session) AllFederationsForCDNWithHdr(cdnName string, header http.Heade
 		Response []json.RawMessage `json:"response"`
 	}
 	data := FederationResponse{}
-	inf, err := to.get(apiBase+"/federations/all?cdnName="+url.QueryEscape(cdnName), header, &data)
+	inf, err := to.get("/federations/all?cdnName="+url.QueryEscape(cdnName), header, &data)
 	if err != nil {
 		return nil, inf, err
 	}
@@ -90,7 +93,7 @@ func (to *Session) AllFederationsForCDN(cdnName string) ([]tc.AllDeliveryService
 func (to *Session) CreateFederationDeliveryServices(federationID int, deliveryServiceIDs []int, replace bool) (ReqInf, error) {
 	req := tc.FederationDSPost{DSIDs: deliveryServiceIDs, Replace: &replace}
 	resp := map[string]interface{}{}
-	inf, err := to.post(apiBase+`/federations/`+strconv.Itoa(federationID)+`/deliveryservices`, req, nil, &resp)
+	inf, err := to.post(`/federations/`+strconv.Itoa(federationID)+`/deliveryservices`, req, nil, &resp)
 	return inf, err
 }
 
@@ -99,7 +102,7 @@ func (to *Session) GetFederationDeliveryServicesWithHdr(federationID int, header
 		Response []tc.FederationDeliveryServiceNullable `json:"response"`
 	}
 	data := FederationDSesResponse{}
-	inf, err := to.get(fmt.Sprintf("%s/federations/%d/deliveryservices", apiBase, federationID), header, &data)
+	inf, err := to.get(fmt.Sprintf("/federations/%d/deliveryservices", federationID), header, &data)
 	return data.Response, inf, err
 }
 
@@ -111,7 +114,7 @@ func (to *Session) GetFederationDeliveryServices(federationID int) ([]tc.Federat
 
 // DeleteFederationDeliveryService Deletes a given Delivery Service from a Federation
 func (to *Session) DeleteFederationDeliveryService(federationID, deliveryServiceID int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/federations/%d/deliveryservices/%d", apiBase, federationID, deliveryServiceID)
+	route := fmt.Sprintf("/federations/%d/deliveryservices/%d", federationID, deliveryServiceID)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
@@ -121,7 +124,7 @@ func (to *Session) DeleteFederationDeliveryService(federationID, deliveryService
 func (to *Session) CreateFederationUsers(federationID int, userIDs []int, replace bool) (tc.Alerts, ReqInf, error) {
 	req := tc.FederationUserPost{IDs: userIDs, Replace: &replace}
 	var alerts tc.Alerts
-	inf, err := to.post(fmt.Sprintf("%s/federations/%d/users", apiBase, federationID), req, nil, &alerts)
+	inf, err := to.post(fmt.Sprintf("/federations/%d/users", federationID), req, nil, &alerts)
 	return alerts, inf, err
 }
 
@@ -130,7 +133,7 @@ func (to *Session) GetFederationUsersWithHdr(federationID int, header http.Heade
 		Response []tc.FederationUser `json:"response"`
 	}
 	data := FederationUsersResponse{}
-	inf, err := to.get(fmt.Sprintf("%s/federations/%d/users", apiBase, federationID), header, &data)
+	inf, err := to.get(fmt.Sprintf("/federations/%d/users", federationID), header, &data)
 	return data.Response, inf, err
 }
 
@@ -142,7 +145,7 @@ func (to *Session) GetFederationUsers(federationID int) ([]tc.FederationUser, Re
 
 // DeleteFederationUser Deletes a given User from a Federation
 func (to *Session) DeleteFederationUser(federationID, userID int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/federations/%d/users/%d", apiBase, federationID, userID)
+	route := fmt.Sprintf("/federations/%d/users/%d", federationID, userID)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
@@ -152,7 +155,7 @@ func (to *Session) DeleteFederationUser(federationID, userID int) (tc.Alerts, Re
 // Delivery Services for the current user.
 func (to *Session) AddFederationResolverMappingsForCurrentUser(mappings tc.DeliveryServiceFederationResolverMappingRequest) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(APIFederations, mappings, nil, &alerts)
+	reqInf, err := to.post(APIFederationsPath, mappings, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -161,7 +164,7 @@ func (to *Session) AddFederationResolverMappingsForCurrentUser(mappings tc.Deliv
 // Federation Resolvers themselves.
 func (to *Session) DeleteFederationResolverMappingsForCurrentUser() (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.del(APIFederations, nil, &alerts)
+	reqInf, err := to.del(APIFederationsPath, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -173,6 +176,6 @@ func (to *Session) DeleteFederationResolverMappingsForCurrentUser() (tc.Alerts,
 // AddFederationResolverMappingsForCurrentUser .
 func (to *Session) ReplaceFederationResolverMappingsForCurrentUser(mappings tc.DeliveryServiceFederationResolverMappingRequest) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.put(APIFederations, mappings, nil, &alerts)
+	reqInf, err := to.put(APIFederationsPath, mappings, nil, &alerts)
 	return alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/federation_federation_resolver.go b/traffic_ops/v3-client/federation_federation_resolver.go
index 198c778..f559c75 100644
--- a/traffic_ops/v3-client/federation_federation_resolver.go
+++ b/traffic_ops/v3-client/federation_federation_resolver.go
@@ -21,7 +21,7 @@ import (
 
 // GetFederationFederationResolversByID retrieves all Federation Resolvers belonging to Federation of ID.
 func (to *Session) GetFederationFederationResolversByID(id int) (tc.FederationFederationResolversResponse, ReqInf, error) {
-	path := fmt.Sprintf("%s/federations/%d/federation_resolvers", apiBase, id)
+	path := fmt.Sprintf("/federations/%d/federation_resolvers", id)
 	resp := tc.FederationFederationResolversResponse{}
 	reqInf, err := to.get(path, nil, &resp)
 	return resp, reqInf, err
@@ -29,7 +29,7 @@ func (to *Session) GetFederationFederationResolversByID(id int) (tc.FederationFe
 
 // AssignFederationFederationResolver creates the Federation Resolver 'fr'.
 func (to *Session) AssignFederationFederationResolver(fedID int, resolverIDs []int, replace bool) (tc.AssignFederationFederationResolversResponse, ReqInf, error) {
-	path := fmt.Sprintf("%s/federations/%d/federation_resolvers", apiBase, fedID)
+	path := fmt.Sprintf("/federations/%d/federation_resolvers", fedID)
 	req := tc.AssignFederationResolversRequest{
 		Replace:        replace,
 		FedResolverIDs: resolverIDs,
diff --git a/traffic_ops/v3-client/federation_resolver.go b/traffic_ops/v3-client/federation_resolver.go
index db4bc5c..2d3c986 100644
--- a/traffic_ops/v3-client/federation_resolver.go
+++ b/traffic_ops/v3-client/federation_resolver.go
@@ -33,7 +33,7 @@ func (to *Session) getFederationResolvers(id *uint, ip *string, t *string, heade
 		vals.Set("type", *t)
 	}
 
-	var path = apiBase + "/federation_resolvers"
+	path := "/federation_resolvers"
 	if len(vals) > 0 {
 		path = fmt.Sprintf("%s?%s", path, vals.Encode())
 	}
@@ -99,14 +99,14 @@ func (to *Session) GetFederationResolversByType(t string) ([]tc.FederationResolv
 // CreateFederationResolver creates the Federation Resolver 'fr'.
 func (to *Session) CreateFederationResolver(fr tc.FederationResolver) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(apiBase+"/federation_resolvers", fr, nil, &alerts)
+	reqInf, err := to.post("/federation_resolvers", fr, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // DeleteFederationResolver deletes the Federation Resolver identified by 'id'.
 func (to *Session) DeleteFederationResolver(id uint) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	path := fmt.Sprintf("%s/federation_resolvers?id=%d", apiBase, id)
+	path := fmt.Sprintf("/federation_resolvers?id=%d", id)
 	reqInf, err := to.del(path, nil, &alerts)
 	return alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/iso.go b/traffic_ops/v3-client/iso.go
index d10a8c8..7bc473c 100644
--- a/traffic_ops/v3-client/iso.go
+++ b/traffic_ops/v3-client/iso.go
@@ -24,7 +24,10 @@ import (
 )
 
 const (
+	// API_OSVERSIONS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_OSVERSIONS = apiBase + "/osversions"
+
+	APIOSVersions = "/osversions"
 )
 
 // GetOSVersions GETs all available Operating System (OS) versions for ISO generation,
@@ -36,6 +39,6 @@ func (to *Session) GetOSVersions() (map[string]string, ReqInf, error) {
 	var data struct {
 		Versions tc.OSVersionsResponse `json:"response"`
 	}
-	reqInf, err := to.get(API_OSVERSIONS, nil, &data)
+	reqInf, err := to.get(APIOSVersions, nil, &data)
 	return data.Versions, reqInf, err
 }
diff --git a/traffic_ops/v3-client/job.go b/traffic_ops/v3-client/job.go
index 9076a84..b8ea02a 100644
--- a/traffic_ops/v3-client/job.go
+++ b/traffic_ops/v3-client/job.go
@@ -27,14 +27,14 @@ import (
 // Creates a new Content Invalidation Job
 func (to *Session) CreateInvalidationJob(job tc.InvalidationJobInput) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(apiBase+`/jobs`, job, nil, &alerts)
+	reqInf, err := to.post(`/jobs`, job, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // Deletes a Content Invalidation Job
 func (to *Session) DeleteInvalidationJob(jobID uint64) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.del(fmt.Sprintf("%s/jobs?id=%d", apiBase, jobID), nil, &alerts)
+	reqInf, err := to.del(fmt.Sprintf("/jobs?id=%d", jobID), nil, &alerts)
 	return alerts, reqInf, err
 
 }
@@ -42,7 +42,7 @@ func (to *Session) DeleteInvalidationJob(jobID uint64) (tc.Alerts, ReqInf, error
 // Updates a Content Invalidation Job
 func (to *Session) UpdateInvalidationJob(job tc.InvalidationJob) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.put(fmt.Sprintf(`%s/jobs?id=%d`, apiBase, *job.ID), job, nil, &alerts)
+	reqInf, err := to.put(fmt.Sprintf(`/jobs?id=%d`, *job.ID), job, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -59,7 +59,7 @@ func (to *Session) GetJobs(deliveryServiceID *int, userID *int) ([]tc.Job, ReqIn
 	if userID != nil {
 		params.Add("userId", strconv.Itoa(*userID))
 	}
-	path := apiBase + "/jobs?" + params.Encode()
+	path := "/jobs?" + params.Encode()
 	data := struct {
 		Response []tc.Job `json:"response"`
 	}{}
@@ -143,7 +143,7 @@ func (to *Session) GetInvalidationJobs(ds *interface{}, user *interface{}) ([]tc
 			return nil, ReqInf{}, fmt.Errorf("invalid type for argument 'user': %T*", t)
 		}
 	}
-	path := apiBase + "/jobs"
+	path := "/jobs"
 	if len(params) > 0 {
 		path += "?" + params.Encode()
 	}
diff --git a/traffic_ops/v3-client/log.go b/traffic_ops/v3-client/log.go
index 3290cf3..2a57489 100644
--- a/traffic_ops/v3-client/log.go
+++ b/traffic_ops/v3-client/log.go
@@ -22,14 +22,17 @@ import (
 )
 
 const (
+	// DEPRECATED: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_LOGS = apiBase + "/logs"
+
+	APILogs = "/logs"
 )
 
 // GetLogsByQueryParams gets a list of logs filtered by query params.
 func (to *Session) GetLogsByQueryParams(queryParams string) ([]tc.Log, ReqInf, error) {
-	URI := API_LOGS + queryParams
+	uri := APILogs + queryParams
 	var data tc.LogsResponse
-	reqInf, err := to.get(URI, nil, &data)
+	reqInf, err := to.get(uri, nil, &data)
 	return data.Response, reqInf, err
 }
 
diff --git a/traffic_ops/v3-client/origin.go b/traffic_ops/v3-client/origin.go
index 668c4aa..3489c38 100644
--- a/traffic_ops/v3-client/origin.go
+++ b/traffic_ops/v3-client/origin.go
@@ -26,7 +26,10 @@ import (
 )
 
 const (
+	// API_ORIGINS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_ORIGINS = apiBase + "/origins"
+
+	APIOrigins = "/origins"
 )
 
 func originIDs(to *Session, origin *tc.Origin) error {
@@ -95,7 +98,7 @@ func (to *Session) CreateOrigin(origin tc.Origin) (*tc.OriginDetailResponse, Req
 		return nil, reqInf, err
 	}
 	var originResp tc.OriginDetailResponse
-	reqInf, err = to.post(API_ORIGINS, origin, nil, &originResp)
+	reqInf, err = to.post(APIOrigins, origin, nil, &originResp)
 	return &originResp, reqInf, err
 }
 
@@ -107,7 +110,7 @@ func (to *Session) UpdateOriginByIDWithHdr(id int, origin tc.Origin, header http
 	if err != nil {
 		return nil, reqInf, err
 	}
-	route := fmt.Sprintf("%s?id=%d", API_ORIGINS, id)
+	route := fmt.Sprintf("%s?id=%d", APIOrigins, id)
 	var originResp tc.OriginDetailResponse
 	reqInf, err = to.put(route, origin, header, &originResp)
 	return &originResp, reqInf, err
@@ -121,9 +124,9 @@ func (to *Session) UpdateOriginByID(id int, origin tc.Origin) (*tc.OriginDetailR
 
 // GET a list of Origins by a query parameter string
 func (to *Session) GetOriginsByQueryParams(queryParams string) ([]tc.Origin, ReqInf, error) {
-	URI := API_ORIGINS + queryParams
+	uri := APIOrigins + queryParams
 	var data tc.OriginsResponse
-	reqInf, err := to.get(URI, nil, &data)
+	reqInf, err := to.get(uri, nil, &data)
 	return data.Response, reqInf, err
 }
 
@@ -149,7 +152,7 @@ func (to *Session) GetOriginsByDeliveryServiceID(id int) ([]tc.Origin, ReqInf, e
 
 // DELETE an Origin by ID
 func (to *Session) DeleteOriginByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_ORIGINS, id)
+	route := fmt.Sprintf("%s?id=%d", APIOrigins, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/parameter.go b/traffic_ops/v3-client/parameter.go
index 4a80acc..7dd4927 100644
--- a/traffic_ops/v3-client/parameter.go
+++ b/traffic_ops/v3-client/parameter.go
@@ -24,25 +24,28 @@ import (
 )
 
 const (
+	// API_PARAMETERS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_PARAMETERS = apiBase + "/parameters"
+
+	APIParameters = "/parameters"
 )
 
 // CreateParameter performs a POST to create a Parameter.
 func (to *Session) CreateParameter(pl tc.Parameter) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_PARAMETERS, pl, nil, &alerts)
+	reqInf, err := to.post(APIParameters, pl, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // CreateMultipleParameters performs a POST to create multiple Parameters at once.
 func (to *Session) CreateMultipleParameters(pls []tc.Parameter) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_PARAMETERS, pls, nil, &alerts)
+	reqInf, err := to.post(APIParameters, pls, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateParameterByIDWithHdr(id int, pl tc.Parameter, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_PARAMETERS, id)
+	route := fmt.Sprintf("%s/%d", APIParameters, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, pl, header, &alerts)
 	return alerts, reqInf, err
@@ -56,7 +59,7 @@ func (to *Session) UpdateParameterByID(id int, pl tc.Parameter) (tc.Alerts, ReqI
 
 func (to *Session) GetParametersWithHdr(header http.Header) ([]tc.Parameter, ReqInf, error) {
 	var data tc.ParametersResponse
-	reqInf, err := to.get(API_PARAMETERS, header, &data)
+	reqInf, err := to.get(APIParameters, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -67,7 +70,7 @@ func (to *Session) GetParameters() ([]tc.Parameter, ReqInf, error) {
 }
 
 func (to *Session) GetParameterByIDWithHdr(id int, header http.Header) ([]tc.Parameter, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_PARAMETERS, id)
+	route := fmt.Sprintf("%s?id=%d", APIParameters, id)
 	var data tc.ParametersResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -80,9 +83,9 @@ func (to *Session) GetParameterByID(id int) ([]tc.Parameter, ReqInf, error) {
 }
 
 func (to *Session) GetParameterByNameWithHdr(name string, header http.Header) ([]tc.Parameter, ReqInf, error) {
-	URI := API_PARAMETERS + "?name=" + url.QueryEscape(name)
+	uri := APIParameters + "?name=" + url.QueryEscape(name)
 	var data tc.ParametersResponse
-	reqInf, err := to.get(URI, header, &data)
+	reqInf, err := to.get(uri, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -93,9 +96,9 @@ func (to *Session) GetParameterByName(name string) ([]tc.Parameter, ReqInf, erro
 }
 
 func (to *Session) GetParameterByConfigFileWithHdr(configFile string, header http.Header) ([]tc.Parameter, ReqInf, error) {
-	URI := API_PARAMETERS + "?configFile=" + url.QueryEscape(configFile)
+	uri := APIParameters + "?configFile=" + url.QueryEscape(configFile)
 	var data tc.ParametersResponse
-	reqInf, err := to.get(URI, header, &data)
+	reqInf, err := to.get(uri, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -106,9 +109,9 @@ func (to *Session) GetParameterByConfigFile(configFile string) ([]tc.Parameter,
 }
 
 func (to *Session) GetParameterByNameAndConfigFileWithHdr(name string, configFile string, header http.Header) ([]tc.Parameter, ReqInf, error) {
-	URI := fmt.Sprintf("%s?name=%s&configFile=%s", API_PARAMETERS, url.QueryEscape(name), url.QueryEscape(configFile))
+	uri := fmt.Sprintf("%s?name=%s&configFile=%s", APIParameters, url.QueryEscape(name), url.QueryEscape(configFile))
 	var data tc.ParametersResponse
-	reqInf, err := to.get(URI, header, &data)
+	reqInf, err := to.get(uri, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -144,8 +147,8 @@ func (to *Session) GetParameterByNameAndConfigFileAndValue(name, configFile, val
 
 // DeleteParameterByID DELETEs a Parameter by ID.
 func (to *Session) DeleteParameterByID(id int) (tc.Alerts, ReqInf, error) {
-	URI := fmt.Sprintf("%s/%d", API_PARAMETERS, id)
+	uri := fmt.Sprintf("%s/%d", APIParameters, id)
 	var alerts tc.Alerts
-	reqInf, err := to.del(URI, nil, &alerts)
+	reqInf, err := to.del(uri, nil, &alerts)
 	return alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/phys_location.go b/traffic_ops/v3-client/phys_location.go
index fad0bb3..8e3987c 100644
--- a/traffic_ops/v3-client/phys_location.go
+++ b/traffic_ops/v3-client/phys_location.go
@@ -25,7 +25,10 @@ import (
 )
 
 const (
+	// API_PHYS_LOCATIONS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_PHYS_LOCATIONS = apiBase + "/phys_locations"
+
+	APIPhysLocations = "/phys_locations"
 )
 
 // CreatePhysLocation creates a PhysLocation.
@@ -41,12 +44,12 @@ func (to *Session) CreatePhysLocation(pl tc.PhysLocation) (tc.Alerts, ReqInf, er
 		pl.RegionID = regions[0].ID
 	}
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_PHYS_LOCATIONS, pl, nil, &alerts)
+	reqInf, err := to.post(APIPhysLocations, pl, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdatePhysLocationByIDWithHdr(id int, pl tc.PhysLocation, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_PHYS_LOCATIONS, id)
+	route := fmt.Sprintf("%s/%d", APIPhysLocations, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, pl, header, &alerts)
 	return alerts, reqInf, err
@@ -59,7 +62,7 @@ func (to *Session) UpdatePhysLocationByID(id int, pl tc.PhysLocation) (tc.Alerts
 }
 
 func (to *Session) GetPhysLocationsWithHdr(params map[string]string, header http.Header) ([]tc.PhysLocation, ReqInf, error) {
-	path := API_PHYS_LOCATIONS + mapToQueryParameters(params)
+	path := APIPhysLocations + mapToQueryParameters(params)
 	var data tc.PhysLocationsResponse
 	reqInf, err := to.get(path, header, &data)
 	return data.Response, reqInf, err
@@ -72,7 +75,7 @@ func (to *Session) GetPhysLocations(params map[string]string) ([]tc.PhysLocation
 }
 
 func (to *Session) GetPhysLocationByIDWithHdr(id int, header http.Header) ([]tc.PhysLocation, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_PHYS_LOCATIONS, id)
+	route := fmt.Sprintf("%s?id=%d", APIPhysLocations, id)
 	var data tc.PhysLocationsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -85,7 +88,7 @@ func (to *Session) GetPhysLocationByID(id int) ([]tc.PhysLocation, ReqInf, error
 }
 
 func (to *Session) GetPhysLocationByNameWithHdr(name string, header http.Header) ([]tc.PhysLocation, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_PHYS_LOCATIONS, url.QueryEscape(name))
+	route := fmt.Sprintf("%s?name=%s", APIPhysLocations, url.QueryEscape(name))
 	var data tc.PhysLocationsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -99,7 +102,7 @@ func (to *Session) GetPhysLocationByName(name string) ([]tc.PhysLocation, ReqInf
 
 // DELETE a PhysLocation by ID
 func (to *Session) DeletePhysLocationByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_PHYS_LOCATIONS, id)
+	route := fmt.Sprintf("%s/%d", APIPhysLocations, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/ping.go b/traffic_ops/v3-client/ping.go
index e7f67d9..bd70263 100644
--- a/traffic_ops/v3-client/ping.go
+++ b/traffic_ops/v3-client/ping.go
@@ -16,12 +16,15 @@
 package client
 
 const (
+	// API_PING is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_PING = apiBase + "/ping"
+
+	APIPing = "/ping"
 )
 
 // Ping returns a static json object to show that traffic_ops is responsive
 func (to *Session) Ping() (map[string]string, ReqInf, error) {
 	var data map[string]string
-	reqInf, err := to.get(API_PING, nil, &data)
+	reqInf, err := to.get(APIPing, nil, &data)
 	return data, reqInf, err
 }
diff --git a/traffic_ops/v3-client/profile.go b/traffic_ops/v3-client/profile.go
index 3ba6bc8..961fe1d 100644
--- a/traffic_ops/v3-client/profile.go
+++ b/traffic_ops/v3-client/profile.go
@@ -24,8 +24,14 @@ import (
 )
 
 const (
-	API_PROFILES                 = apiBase + "/profiles"
+	// API_PROFILES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
+	API_PROFILES = apiBase + "/profiles"
+
+	// API_PROFILES_NAME_PARAMETERS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_PROFILES_NAME_PARAMETERS = API_PROFILES + "/name/%s/parameters"
+
+	APIProfiles               = "/profiles"
+	APIProfilesNameParameters = APIProfiles + "/name/%s/parameters"
 )
 
 // CreateProfile creates a Profile.
@@ -51,12 +57,12 @@ func (to *Session) CreateProfile(pl tc.Profile) (tc.Alerts, ReqInf, error) {
 	}
 
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_PROFILES, pl, nil, &alerts)
+	reqInf, err := to.post(APIProfiles, pl, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateProfileByIDWithHdr(id int, pl tc.Profile, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_PROFILES, id)
+	route := fmt.Sprintf("%s/%d", APIProfiles, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, pl, header, &alerts)
 	return alerts, reqInf, err
@@ -69,7 +75,7 @@ func (to *Session) UpdateProfileByID(id int, pl tc.Profile) (tc.Alerts, ReqInf,
 }
 
 func (to *Session) GetParametersByProfileNameWithHdr(profileName string, header http.Header) ([]tc.Parameter, ReqInf, error) {
-	route := fmt.Sprintf(API_PROFILES_NAME_PARAMETERS, profileName)
+	route := fmt.Sprintf(APIProfilesNameParameters, profileName)
 	var data tc.ParametersResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -83,7 +89,7 @@ func (to *Session) GetParametersByProfileName(profileName string) ([]tc.Paramete
 
 func (to *Session) GetProfilesWithHdr(header http.Header) ([]tc.Profile, ReqInf, error) {
 	var data tc.ProfilesResponse
-	reqInf, err := to.get(API_PROFILES, header, &data)
+	reqInf, err := to.get(APIProfiles, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -94,7 +100,7 @@ func (to *Session) GetProfiles() ([]tc.Profile, ReqInf, error) {
 }
 
 func (to *Session) GetProfileByIDWithHdr(id int, header http.Header) ([]tc.Profile, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_PROFILES, id)
+	route := fmt.Sprintf("%s?id=%d", APIProfiles, id)
 	var data tc.ProfilesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -107,7 +113,7 @@ func (to *Session) GetProfileByID(id int) ([]tc.Profile, ReqInf, error) {
 }
 
 func (to *Session) GetProfileByNameWithHdr(name string, header http.Header) ([]tc.Profile, ReqInf, error) {
-	URI := fmt.Sprintf("%s?name=%s", API_PROFILES, url.QueryEscape(name))
+	URI := fmt.Sprintf("%s?name=%s", APIProfiles, url.QueryEscape(name))
 	var data tc.ProfilesResponse
 	reqInf, err := to.get(URI, header, &data)
 	return data.Response, reqInf, err
@@ -120,7 +126,7 @@ func (to *Session) GetProfileByName(name string) ([]tc.Profile, ReqInf, error) {
 }
 
 func (to *Session) GetProfileByParameterWithHdr(param string, header http.Header) ([]tc.Profile, ReqInf, error) {
-	URI := fmt.Sprintf("%s?param=%s", API_PROFILES, url.QueryEscape(param))
+	URI := fmt.Sprintf("%s?param=%s", APIProfiles, url.QueryEscape(param))
 	var data tc.ProfilesResponse
 	reqInf, err := to.get(URI, header, &data)
 	return data.Response, reqInf, err
@@ -133,9 +139,9 @@ func (to *Session) GetProfileByParameter(param string) ([]tc.Profile, ReqInf, er
 }
 
 func (to *Session) GetProfileByCDNIDWithHdr(cdnID int, header http.Header) ([]tc.Profile, ReqInf, error) {
-	URI := fmt.Sprintf("%s?cdn=%d", API_PROFILES, cdnID)
+	uri := fmt.Sprintf("%s?cdn=%d", APIProfiles, cdnID)
 	var data tc.ProfilesResponse
-	reqInf, err := to.get(URI, header, &data)
+	reqInf, err := to.get(uri, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -147,15 +153,15 @@ func (to *Session) GetProfileByCDNID(cdnID int) ([]tc.Profile, ReqInf, error) {
 
 // DeleteProfileByID DELETEs a Profile by ID.
 func (to *Session) DeleteProfileByID(id int) (tc.Alerts, ReqInf, error) {
-	URI := fmt.Sprintf("%s/%d", API_PROFILES, id)
+	uri := fmt.Sprintf("%s/%d", APIProfiles, id)
 	var alerts tc.Alerts
-	reqInf, err := to.del(URI, nil, &alerts)
+	reqInf, err := to.del(uri, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // ExportProfile Returns an exported Profile.
 func (to *Session) ExportProfile(id int) (*tc.ProfileExportResponse, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d/export", API_PROFILES, id)
+	route := fmt.Sprintf("%s/%d/export", APIProfiles, id)
 	var data tc.ProfileExportResponse
 	reqInf, err := to.get(route, nil, &data)
 	return &data, reqInf, err
@@ -163,7 +169,7 @@ func (to *Session) ExportProfile(id int) (*tc.ProfileExportResponse, ReqInf, err
 
 // ImportProfile imports an exported Profile.
 func (to *Session) ImportProfile(importRequest *tc.ProfileImportRequest) (*tc.ProfileImportResponse, ReqInf, error) {
-	route := fmt.Sprintf("%s/import", API_PROFILES)
+	route := fmt.Sprintf("%s/import", APIProfiles)
 	var data tc.ProfileImportResponse
 	reqInf, err := to.post(route, importRequest, nil, &data)
 	return &data, reqInf, err
@@ -171,7 +177,7 @@ func (to *Session) ImportProfile(importRequest *tc.ProfileImportRequest) (*tc.Pr
 
 // CopyProfile creates a new profile from an existing profile.
 func (to *Session) CopyProfile(p tc.ProfileCopy) (tc.ProfileCopyResponse, ReqInf, error) {
-	path := fmt.Sprintf("%s/name/%s/copy/%s", API_PROFILES, p.Name, p.ExistingName)
+	path := fmt.Sprintf("%s/name/%s/copy/%s", APIProfiles, p.Name, p.ExistingName)
 	resp := tc.ProfileCopyResponse{}
 	reqInf, err := to.post(path, p, nil, &resp)
 	return resp, reqInf, err
diff --git a/traffic_ops/v3-client/profile_parameter.go b/traffic_ops/v3-client/profile_parameter.go
index 579294a..9d08aa3 100644
--- a/traffic_ops/v3-client/profile_parameter.go
+++ b/traffic_ops/v3-client/profile_parameter.go
@@ -23,22 +23,25 @@ import (
 )
 
 const (
+	// DEPRECATED: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_PROFILE_PARAMETERS = apiBase + "/profileparameters"
 	ProfileIdQueryParam    = "profileId"
 	ParameterIdQueryParam  = "parameterId"
+
+	APIProfileParameters = "/profileparameters"
 )
 
 // Create a ProfileParameter
 func (to *Session) CreateProfileParameter(pp tc.ProfileParameter) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_PROFILE_PARAMETERS, pp, nil, &alerts)
+	reqInf, err := to.post(APIProfileParameters, pp, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // CreateMultipleProfileParameters creates multiple ProfileParameters at once.
 func (to *Session) CreateMultipleProfileParameters(pps []tc.ProfileParameter) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_PROFILE_PARAMETERS, pps, nil, &alerts)
+	reqInf, err := to.post(APIProfileParameters, pps, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -53,9 +56,9 @@ func (to *Session) GetProfileParameters() ([]tc.ProfileParameter, ReqInf, error)
 }
 
 func (to *Session) GetProfileParameterByQueryParamsWithHdr(queryParams string, header http.Header) ([]tc.ProfileParameter, ReqInf, error) {
-	URI := API_PROFILE_PARAMETERS + queryParams
+	uri := APIProfileParameters + queryParams
 	var data tc.ProfileParametersNullableResponse
-	reqInf, err := to.get(URI, header, &data)
+	reqInf, err := to.get(uri, header, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -80,8 +83,8 @@ func (to *Session) GetProfileParameterByQueryParams(queryParams string) ([]tc.Pr
 
 // DELETE a Parameter by Parameter
 func (to *Session) DeleteParameterByProfileParameter(profile int, parameter int) (tc.Alerts, ReqInf, error) {
-	URI := fmt.Sprintf("%s/%d/%d", API_PROFILE_PARAMETERS, profile, parameter)
+	uri := fmt.Sprintf("%s/%d/%d", APIProfileParameters, profile, parameter)
 	var alerts tc.Alerts
-	reqInf, err := to.del(URI, nil, &alerts)
+	reqInf, err := to.del(uri, nil, &alerts)
 	return alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/region.go b/traffic_ops/v3-client/region.go
index 6e69acc..316464b 100644
--- a/traffic_ops/v3-client/region.go
+++ b/traffic_ops/v3-client/region.go
@@ -26,7 +26,10 @@ import (
 )
 
 const (
+	// API_REGIONS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_REGIONS = apiBase + "/regions"
+
+	APIRegions = "/regions"
 )
 
 // CreateRegion creates a Region.
@@ -42,12 +45,12 @@ func (to *Session) CreateRegion(region tc.Region) (tc.Alerts, ReqInf, error) {
 		region.Division = divisions[0].ID
 	}
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_REGIONS, region, nil, &alerts)
+	reqInf, err := to.post(APIRegions, region, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateRegionByIDWithHdr(id int, region tc.Region, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_REGIONS, id)
+	route := fmt.Sprintf("%s/%d", APIRegions, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, region, header, &alerts)
 	return alerts, reqInf, err
@@ -61,7 +64,7 @@ func (to *Session) UpdateRegionByID(id int, region tc.Region) (tc.Alerts, ReqInf
 
 func (to *Session) GetRegionsWithHdr(header http.Header) ([]tc.Region, ReqInf, error) {
 	var data tc.RegionsResponse
-	reqInf, err := to.get(API_REGIONS, header, &data)
+	reqInf, err := to.get(APIRegions, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -72,7 +75,7 @@ func (to *Session) GetRegions() ([]tc.Region, ReqInf, error) {
 }
 
 func (to *Session) GetRegionByIDWithHdr(id int, header http.Header) ([]tc.Region, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_REGIONS, id)
+	route := fmt.Sprintf("%s?id=%d", APIRegions, id)
 	var data tc.RegionsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -85,7 +88,7 @@ func (to *Session) GetRegionByID(id int) ([]tc.Region, ReqInf, error) {
 }
 
 func (to *Session) GetRegionByNameWithHdr(name string, header http.Header) ([]tc.Region, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_REGIONS, url.QueryEscape(name))
+	route := fmt.Sprintf("%s?name=%s", APIRegions, url.QueryEscape(name))
 	var data tc.RegionsResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -99,7 +102,7 @@ func (to *Session) GetRegionByName(name string) ([]tc.Region, ReqInf, error) {
 
 // DeleteRegionByID DELETEs a Region by ID.
 func (to *Session) DeleteRegionByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_REGIONS, id)
+	route := fmt.Sprintf("%s?id=%d", APIRegions, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
@@ -114,12 +117,12 @@ func (to *Session) DeleteRegion(id *int, name *string) (tc.Alerts, ReqInf, error
 	if name != nil {
 		v.Add("name", *name)
 	}
-	URI := apiBase + "/regions"
+	uri := "/regions"
 	if qStr := v.Encode(); len(qStr) > 0 {
-		URI = fmt.Sprintf("%s?%s", URI, qStr)
+		uri = fmt.Sprintf("%s?%s", uri, qStr)
 	}
 
 	var alerts tc.Alerts
-	reqInf, err := to.del(URI, nil, &alerts)
+	reqInf, err := to.del(uri, nil, &alerts)
 	return alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/role.go b/traffic_ops/v3-client/role.go
index fb7e95c..b4c4eca 100644
--- a/traffic_ops/v3-client/role.go
+++ b/traffic_ops/v3-client/role.go
@@ -24,18 +24,21 @@ import (
 )
 
 const (
+	// API_ROLES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_ROLES = apiBase + "/roles"
+
+	APIRoles = "/roles"
 )
 
 // CreateRole creates a Role.
 func (to *Session) CreateRole(role tc.Role) (tc.Alerts, ReqInf, int, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_ROLES, role, nil, &alerts)
+	reqInf, err := to.post(APIRoles, role, nil, &alerts)
 	return alerts, reqInf, reqInf.StatusCode, err
 }
 
 func (to *Session) UpdateRoleByIDWithHdr(id int, role tc.Role, header http.Header) (tc.Alerts, ReqInf, int, error) {
-	route := fmt.Sprintf("%s/?id=%d", API_ROLES, id)
+	route := fmt.Sprintf("%s/?id=%d", APIRoles, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, role, header, &alerts)
 	return alerts, reqInf, reqInf.StatusCode, err
@@ -50,7 +53,7 @@ func (to *Session) UpdateRoleByID(id int, role tc.Role) (tc.Alerts, ReqInf, int,
 
 func (to *Session) GetRolesWithHdr(header http.Header) ([]tc.Role, ReqInf, int, error) {
 	var data tc.RolesResponse
-	reqInf, err := to.get(API_ROLES, header, &data)
+	reqInf, err := to.get(APIRoles, header, &data)
 	return data.Response, reqInf, reqInf.StatusCode, err
 }
 
@@ -61,7 +64,7 @@ func (to *Session) GetRoles() ([]tc.Role, ReqInf, int, error) {
 }
 
 func (to *Session) GetRoleByIDWithHdr(id int, header http.Header) ([]tc.Role, ReqInf, int, error) {
-	route := fmt.Sprintf("%s/?id=%d", API_ROLES, id)
+	route := fmt.Sprintf("%s/?id=%d", APIRoles, id)
 	var data tc.RolesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, reqInf.StatusCode, err
@@ -74,7 +77,7 @@ func (to *Session) GetRoleByID(id int) ([]tc.Role, ReqInf, int, error) {
 }
 
 func (to *Session) GetRoleByNameWithHdr(name string, header http.Header) ([]tc.Role, ReqInf, int, error) {
-	route := fmt.Sprintf("%s?name=%s", API_ROLES, url.QueryEscape(name))
+	route := fmt.Sprintf("%s?name=%s", APIRoles, url.QueryEscape(name))
 	var data tc.RolesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, reqInf.StatusCode, err
@@ -87,7 +90,7 @@ func (to *Session) GetRoleByName(name string) ([]tc.Role, ReqInf, int, error) {
 }
 
 func (to *Session) GetRoleByQueryParamsWithHdr(queryParams map[string]string, header http.Header) ([]tc.Role, ReqInf, int, error) {
-	route := fmt.Sprintf("%s%s", API_ROLES, mapToQueryParameters(queryParams))
+	route := fmt.Sprintf("%s%s", APIRoles, mapToQueryParameters(queryParams))
 	var data tc.RolesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, reqInf.StatusCode, err
@@ -101,7 +104,7 @@ func (to *Session) GetRoleByQueryParams(queryParams map[string]string) ([]tc.Rol
 
 // DeleteRoleByID DELETEs a Role by ID.
 func (to *Session) DeleteRoleByID(id int) (tc.Alerts, ReqInf, int, error) {
-	route := fmt.Sprintf("%s/?id=%d", API_ROLES, id)
+	route := fmt.Sprintf("%s/?id=%d", APIRoles, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, reqInf.StatusCode, err
diff --git a/traffic_ops/v3-client/server.go b/traffic_ops/v3-client/server.go
index 28fbd12..9622a50 100644
--- a/traffic_ops/v3-client/server.go
+++ b/traffic_ops/v3-client/server.go
@@ -27,9 +27,16 @@ import (
 )
 
 const (
-	API_SERVERS                         = apiBase + "/servers"
-	API_SERVERS_DETAILS                 = apiBase + "/servers/details"
+	// API_SERVERS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
+	API_SERVERS = apiBase + "/servers"
+	// API_SERVERS_DETAILS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
+	API_SERVERS_DETAILS = apiBase + "/servers/details"
+	// API_SERVER_ASSIGN_DELIVERY_SERVICES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_SERVER_ASSIGN_DELIVERY_SERVICES = API_SERVER_DELIVERY_SERVICES + "?replace=%t"
+
+	APIServers                      = "/servers"
+	APIServersDetails               = "/servers/details"
+	APIServerAssignDeliveryServices = APIServerDeliveryServices + "?replace=%t"
 )
 
 func needAndCanFetch(id *int, name *string) bool {
@@ -118,13 +125,13 @@ func (to *Session) CreateServerWithHdr(server tc.ServerV30, hdr http.Header) (tc
 		server.TypeID = &ty[0].ID
 	}
 
-	reqInf, err := to.post(API_SERVERS, server, hdr, &alerts)
+	reqInf, err := to.post(APIServers, server, hdr, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateServerByIDWithHdr(id int, server tc.ServerV30, header http.Header) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	route := fmt.Sprintf("%s/%d", API_SERVERS, id)
+	route := fmt.Sprintf("%s/%d", APIServers, id)
 	reqInf, err := to.put(route, server, header, &alerts)
 	return alerts, reqInf, err
 }
@@ -142,7 +149,7 @@ func (to *Session) UpdateServerByID(id int, server tc.Server) (tc.Alerts, ReqInf
 // GetServersWithHdr retrieves a list of servers using the given optional query
 // string parameters and HTTP headers.
 func (to *Session) GetServersWithHdr(params *url.Values, header http.Header) (tc.ServersV3Response, ReqInf, error) {
-	route := API_SERVERS
+	route := APIServers
 	if params != nil {
 		route += "?" + params.Encode()
 	}
@@ -199,7 +206,7 @@ func (to *Session) GetFirstServer(params *url.Values, header http.Header) (tc.Se
 func (to *Session) GetServerDetailsByHostNameWithHdr(hostName string, header http.Header) ([]tc.ServerDetailV30, ReqInf, error) {
 	v := url.Values{}
 	v.Add("hostName", hostName)
-	route := API_SERVERS_DETAILS + "?" + v.Encode()
+	route := APIServersDetails + "?" + v.Encode()
 	var data tc.ServersV3DetailResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -213,7 +220,7 @@ func (to *Session) GetServerDetailsByHostName(hostName string) ([]tc.ServerDetai
 
 // DeleteServerByID DELETEs a Server by ID.
 func (to *Session) DeleteServerByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_SERVERS, id)
+	route := fmt.Sprintf("%s/%d", APIServers, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
@@ -284,14 +291,14 @@ func (to *Session) GetServersShortNameSearch(shortname string) ([]string, tc.Ale
 // assignments to the server will be replaced.
 func (to *Session) AssignDeliveryServiceIDsToServerID(server int, dsIDs []int, replace bool) (tc.Alerts, ReqInf, error) {
 	// datatypes here match the library tc.Server's and tc.DeliveryService's ID fields
-	endpoint := fmt.Sprintf(API_SERVER_ASSIGN_DELIVERY_SERVICES, server, replace)
+	endpoint := fmt.Sprintf(APIServerAssignDeliveryServices, server, replace)
 	var alerts tc.Alerts
 	reqInf, err := to.post(endpoint, dsIDs, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) GetServerIDDeliveryServicesWithHdr(server int, header http.Header) ([]tc.DeliveryServiceNullable, ReqInf, error) {
-	endpoint := fmt.Sprintf(API_SERVER_DELIVERY_SERVICES, server)
+	endpoint := fmt.Sprintf(APIServerDeliveryServices, server)
 	var data tc.DeliveryServicesNullableResponse
 	reqInf, err := to.get(endpoint, header, &data)
 	return data.Response, reqInf, err
@@ -305,7 +312,7 @@ func (to *Session) GetServerIDDeliveryServices(server int) ([]tc.DeliveryService
 }
 
 func (to *Session) GetServerUpdateStatusWithHdr(hostName string, header http.Header) (tc.ServerUpdateStatus, ReqInf, error) {
-	path := API_SERVERS + `/` + hostName + `/update_status`
+	path := APIServers + `/` + hostName + `/update_status`
 	data := []tc.ServerUpdateStatus{}
 	reqInf, err := to.get(path, header, &data)
 	if err != nil {
diff --git a/traffic_ops/v3-client/server_server_capabilities.go b/traffic_ops/v3-client/server_server_capabilities.go
index 2f3eea6..af8c9c0 100644
--- a/traffic_ops/v3-client/server_server_capabilities.go
+++ b/traffic_ops/v3-client/server_server_capabilities.go
@@ -25,13 +25,16 @@ import (
 )
 
 const (
+	// API_SERVER_SERVER_CAPABILITIES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_SERVER_SERVER_CAPABILITIES = apiBase + "/server_server_capabilities"
+
+	APIServerServerCapabilities = "/server_server_capabilities"
 )
 
 // CreateServerServerCapability assigns a Server Capability to a Server
 func (to *Session) CreateServerServerCapability(ssc tc.ServerServerCapability) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_SERVER_SERVER_CAPABILITIES, ssc, nil, &alerts)
+	reqInf, err := to.post(APIServerServerCapabilities, ssc, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -42,7 +45,7 @@ func (to *Session) DeleteServerServerCapability(serverID int, serverCapability s
 	v.Add("serverId", strconv.Itoa(serverID))
 	v.Add("serverCapability", serverCapability)
 	qStr := v.Encode()
-	queryURL := fmt.Sprintf("%s?%s", API_SERVER_SERVER_CAPABILITIES, qStr)
+	queryURL := fmt.Sprintf("%s?%s", APIServerServerCapabilities, qStr)
 	reqInf, err := to.del(queryURL, nil, &alerts)
 	return alerts, reqInf, err
 }
@@ -58,7 +61,7 @@ func (to *Session) GetServerServerCapabilitiesWithHdr(serverID *int, serverHostN
 	if serverCapability != nil {
 		v.Add("serverCapability", *serverCapability)
 	}
-	queryURL := API_SERVER_SERVER_CAPABILITIES
+	queryURL := APIServerServerCapabilities
 	if qStr := v.Encode(); len(qStr) > 0 {
 		queryURL = fmt.Sprintf("%s?%s", queryURL, qStr)
 	}
diff --git a/traffic_ops/v3-client/server_update_status.go b/traffic_ops/v3-client/server_update_status.go
index a47f7ae..10fb0cf 100644
--- a/traffic_ops/v3-client/server_update_status.go
+++ b/traffic_ops/v3-client/server_update_status.go
@@ -26,7 +26,7 @@ import (
 
 // UpdateServerStatus updates a server's status and returns the response.
 func (to *Session) UpdateServerStatus(serverID int, req tc.ServerPutStatus) (*tc.Alerts, ReqInf, error) {
-	path := fmt.Sprintf("%s/servers/%d/status", apiBase, serverID)
+	path := fmt.Sprintf("/servers/%d/status", serverID)
 	alerts := tc.Alerts{}
 	reqInf, err := to.put(path, req, nil, &alerts)
 	if err != nil {
@@ -44,7 +44,7 @@ var queueUpdateActions = map[bool]string{
 func (to *Session) SetServerQueueUpdate(serverID int, queueUpdate bool) (tc.ServerQueueUpdateResponse, ReqInf, error) {
 	req := tc.ServerQueueUpdateRequest{Action: queueUpdateActions[queueUpdate]}
 	resp := tc.ServerQueueUpdateResponse{}
-	path := fmt.Sprintf("%s/servers/%d/queue_update", apiBase, serverID)
+	path := fmt.Sprintf("/servers/%d/queue_update", serverID)
 	reqInf, err := to.post(path, req, nil, &resp)
 	return resp, reqInf, err
 }
@@ -57,7 +57,7 @@ func (to *Session) SetUpdateServerStatuses(serverName string, updateStatus *bool
 		return reqInf, errors.New("either updateStatus or revalStatus must be non-nil; nothing to do")
 	}
 
-	path := apiBase + `/servers/` + serverName + `/update?`
+	path := `/servers/` + serverName + `/update?`
 	queryParams := []string{}
 	if updateStatus != nil {
 		queryParams = append(queryParams, `updated=`+strconv.FormatBool(*updateStatus))
diff --git a/traffic_ops/v3-client/servercapability.go b/traffic_ops/v3-client/servercapability.go
index 4bce48d..4dc6f44 100644
--- a/traffic_ops/v3-client/servercapability.go
+++ b/traffic_ops/v3-client/servercapability.go
@@ -24,13 +24,16 @@ import (
 )
 
 const (
+	// API_SERVER_CAPABILITIES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_SERVER_CAPABILITIES = apiBase + "/server_capabilities"
+
+	APIServerCapabilities = "/server_capabilities"
 )
 
 // CreateServerCapability creates a server capability and returns the response.
 func (to *Session) CreateServerCapability(sc tc.ServerCapability) (*tc.ServerCapabilityDetailResponse, ReqInf, error) {
 	var scResp tc.ServerCapabilityDetailResponse
-	reqInf, err := to.post(API_SERVER_CAPABILITIES, sc, nil, &scResp)
+	reqInf, err := to.post(APIServerCapabilities, sc, nil, &scResp)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -39,7 +42,7 @@ func (to *Session) CreateServerCapability(sc tc.ServerCapability) (*tc.ServerCap
 
 func (to *Session) GetServerCapabilitiesWithHdr(header http.Header) ([]tc.ServerCapability, ReqInf, error) {
 	var data tc.ServerCapabilitiesResponse
-	reqInf, err := to.get(API_SERVER_CAPABILITIES, header, &data)
+	reqInf, err := to.get(APIServerCapabilities, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -50,7 +53,7 @@ func (to *Session) GetServerCapabilities() ([]tc.ServerCapability, ReqInf, error
 }
 
 func (to *Session) GetServerCapabilityWithHdr(name string, header http.Header) (*tc.ServerCapability, ReqInf, error) {
-	reqUrl := fmt.Sprintf("%s?name=%s", API_SERVER_CAPABILITIES, url.QueryEscape(name))
+	reqUrl := fmt.Sprintf("%s?name=%s", APIServerCapabilities, url.QueryEscape(name))
 	var data tc.ServerCapabilitiesResponse
 	reqInf, err := to.get(reqUrl, header, &data)
 	if err != nil {
@@ -70,7 +73,7 @@ func (to *Session) GetServerCapability(name string) (*tc.ServerCapability, ReqIn
 
 // DeleteServerCapability deletes the given server capability by name.
 func (to *Session) DeleteServerCapability(name string) (tc.Alerts, ReqInf, error) {
-	reqUrl := fmt.Sprintf("%s?name=%s", API_SERVER_CAPABILITIES, url.QueryEscape(name))
+	reqUrl := fmt.Sprintf("%s?name=%s", APIServerCapabilities, url.QueryEscape(name))
 	var alerts tc.Alerts
 	reqInf, err := to.del(reqUrl, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/servercheck.go b/traffic_ops/v3-client/servercheck.go
index b08f3a7..674cb07 100644
--- a/traffic_ops/v3-client/servercheck.go
+++ b/traffic_ops/v3-client/servercheck.go
@@ -19,13 +19,15 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 )
 
+// API_SERVERCHECK is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const API_SERVERCHECK = apiBase + "/servercheck"
 
+const APIServercheck = "/servercheck"
+
 // InsertServerCheckStatus Will insert/update the servercheck value based on if it already exists or not.
 func (to *Session) InsertServerCheckStatus(status tc.ServercheckRequestNullable) (*tc.ServercheckPostResponse, ReqInf, error) {
-	uri := API_SERVERCHECK
 	resp := tc.ServercheckPostResponse{}
-	reqInf, err := to.post(uri, status, nil, &resp)
+	reqInf, err := to.post(APIServercheck, status, nil, &resp)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -38,6 +40,6 @@ func (to *Session) GetServersChecks() ([]tc.GenericServerCheck, tc.Alerts, ReqIn
 		tc.Alerts
 		Response []tc.GenericServerCheck `json:"response"`
 	}
-	reqInf, err := to.get(API_SERVERCHECK, nil, &response)
+	reqInf, err := to.get(APIServercheck, nil, &response)
 	return response.Response, response.Alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/servercheckextensions.go b/traffic_ops/v3-client/servercheckextensions.go
index 5d21011..4c6da56 100644
--- a/traffic_ops/v3-client/servercheckextensions.go
+++ b/traffic_ops/v3-client/servercheckextensions.go
@@ -18,18 +18,21 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 )
 
+// API_TO_EXTENSION is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const API_TO_EXTENSION = apiBase + "/servercheck/extensions"
 
+const APITOExtension = "/servercheck/extensions"
+
 // CreateServerCheckExtension creates a servercheck extension.
 func (to *Session) CreateServerCheckExtension(ServerCheckExtension tc.ServerCheckExtensionNullable) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_TO_EXTENSION, ServerCheckExtension, nil, &alerts)
+	reqInf, err := to.post(APITOExtension, ServerCheckExtension, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // DeleteServerCheckExtension deletes a servercheck extension.
 func (to *Session) DeleteServerCheckExtension(id int) (tc.Alerts, ReqInf, error) {
-	URI := fmt.Sprintf("%s/%d", API_TO_EXTENSION, id)
+	URI := fmt.Sprintf("%s/%d", APITOExtension, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(URI, nil, &alerts)
 	return alerts, reqInf, err
@@ -38,6 +41,6 @@ func (to *Session) DeleteServerCheckExtension(id int) (tc.Alerts, ReqInf, error)
 // GetServerCheckExtensions gets all servercheck extensions.
 func (to *Session) GetServerCheckExtensions() (tc.ServerCheckExtensionResponse, ReqInf, error) {
 	var toExtResp tc.ServerCheckExtensionResponse
-	reqInf, err := to.get(API_TO_EXTENSION, nil, &toExtResp)
+	reqInf, err := to.get(APITOExtension, nil, &toExtResp)
 	return toExtResp, reqInf, err
 }
diff --git a/traffic_ops/v3-client/serviceCategory.go b/traffic_ops/v3-client/serviceCategory.go
index 6f0374d..6acfbc3 100644
--- a/traffic_ops/v3-client/serviceCategory.go
+++ b/traffic_ops/v3-client/serviceCategory.go
@@ -24,19 +24,22 @@ import (
 )
 
 const (
+	// API_SERVICE_CATEGORIES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_SERVICE_CATEGORIES = apiBase + "/service_categories"
+
+	APIServiceCategories = "/service_categories"
 )
 
 // CreateServiceCategory performs a post to create a service category.
 func (to *Session) CreateServiceCategory(serviceCategory tc.ServiceCategory) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_SERVICE_CATEGORIES, serviceCategory, nil, &alerts)
+	reqInf, err := to.post(APIServiceCategories, serviceCategory, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 // UpdateServiceCategoryByName updates a service category by its unique name.
 func (to *Session) UpdateServiceCategoryByName(name string, serviceCategory tc.ServiceCategory, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%s", API_SERVICE_CATEGORIES, name)
+	route := fmt.Sprintf("%s/%s", APIServiceCategories, name)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, serviceCategory, header, &alerts)
 	return alerts, reqInf, err
@@ -44,7 +47,7 @@ func (to *Session) UpdateServiceCategoryByName(name string, serviceCategory tc.S
 
 // GetServiceCategoriesWithHdr gets a list of service categories by the passed in url values and http headers.
 func (to *Session) GetServiceCategoriesWithHdr(values *url.Values, header http.Header) ([]tc.ServiceCategory, ReqInf, error) {
-	path := fmt.Sprintf("%s?%s", API_SERVICE_CATEGORIES, values.Encode())
+	path := fmt.Sprintf("%s?%s", APIServiceCategories, values.Encode())
 	var data tc.ServiceCategoriesResponse
 	reqInf, err := to.get(path, header, &data)
 	return data.Response, reqInf, err
@@ -58,7 +61,7 @@ func (to *Session) GetServiceCategories(values *url.Values) ([]tc.ServiceCategor
 // DeleteServiceCategoryByName deletes a service category by the service
 // category's unique name.
 func (to *Session) DeleteServiceCategoryByName(name string) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%s", API_SERVICE_CATEGORIES, name)
+	route := fmt.Sprintf("%s/%s", APIServiceCategories, name)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/session.go b/traffic_ops/v3-client/session.go
index 8193e43..2e0f4c9 100644
--- a/traffic_ops/v3-client/session.go
+++ b/traffic_ops/v3-client/session.go
@@ -23,31 +23,129 @@ import (
 	"errors"
 	"fmt"
 	"io/ioutil"
+	"math"
 	"net"
 	"net/http"
 	"net/http/cookiejar"
 	"net/http/httptrace"
 	"strconv"
 	"strings"
-	"sync"
 	"time"
 
-	log "github.com/apache/trafficcontrol/lib/go-log"
-	tc "github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-log"
+	"github.com/apache/trafficcontrol/lib/go-tc"
 
 	"golang.org/x/net/publicsuffix"
 )
 
+// Login authenticates with Traffic Ops and returns the client object.
+//
+// Returns the logged in client, the remote address of Traffic Ops which was translated and used to log in, and any error. If the error is not nil, the remote address may or may not be nil, depending whether the error occurred before the login request.
+//
+// See ClientOpts for details about options, which options are required, and how they behave.
+//
+func Login(url, user, pass string, opts ClientOpts) (*Session, ReqInf, error) {
+	if strings.TrimSpace(opts.UserAgent) == "" {
+		return nil, ReqInf{}, errors.New("opts.UserAgent is required")
+	}
+	if opts.RequestTimeout == 0 {
+		opts.RequestTimeout = DefaultTimeout
+	}
+	if opts.APIVersionCheckInterval == 0 {
+		opts.APIVersionCheckInterval = DefaultAPIVersionCheckInterval
+	}
+
+	jar, err := cookiejar.New(&cookiejar.Options{
+		PublicSuffixList: publicsuffix.List,
+	})
+	if err != nil {
+		return nil, ReqInf{}, errors.New("creating cookie jar: " + err.Error())
+	}
+
+	to := NewSession(user, pass, url, opts.UserAgent, &http.Client{
+		Timeout: opts.RequestTimeout,
+		Transport: &http.Transport{
+			TLSClientConfig: &tls.Config{InsecureSkipVerify: opts.Insecure},
+		},
+		Jar: jar,
+	}, false)
+
+	if !opts.ForceLatestAPI {
+		to.latestSupportedAPI = apiVersions()[0]
+	}
+
+	to.forceLatestAPI = opts.ForceLatestAPI
+	to.apiVerCheckInterval = opts.APIVersionCheckInterval
+
+	remoteAddr, err := to.login()
+	if err != nil {
+		return nil, ReqInf{RemoteAddr: remoteAddr}, errors.New("logging in: " + err.Error())
+	}
+	return to, ReqInf{RemoteAddr: remoteAddr}, nil
+}
+
+// ClientOpts is the options to configure the creation of the Client.
+//
+// This exists to allow adding new features without a breaking change to the Login function.
+// Users should understand this, and understand that upgrading their library may result in new options that their application doesn't know to use.
+// New fields should always behave as-before if their value is the default.
+type ClientOpts struct {
+	// ForceLatestAPI will cause Login to return an error if the latest minor API in the client
+	// is not supported by the Traffic Ops Server.
+	//
+	// Note this was the behavior of all Traffic Ops client functions prior to the Login function.
+	//
+	// If this is false or unset, login will determine the latest minor version supported, and use that for all requests.
+	//
+	// Be aware, this means client fields unknown to the server will always be default-initialized.
+	// For example, suppose the field Foo was added in API 3.1, the client code is 3.1, and the server is 3.0.
+	// Then, the field Foo will always be nil or the default value.
+	// Client applications must understand this, and code processing the new feature Foo must be able to
+	// process default or nil values, understanding they may indicate a server version before the feature was added.
+	//
+	ForceLatestAPI bool
+
+	// Insecure is whether to ignore HTTPS certificate errors with Traffic Ops.
+	// Setting this on production systems is strongly discouraged.
+	Insecure bool
+
+	// RequestTimeout is the HTTP timeout for Traffic Ops requests.
+	// If 0 or not explicitly set, DefaultTimeout will be used.
+	RequestTimeout time.Duration
+
+	// UserAgent is the HTTP User Agent to use set when communicating with Traffic Ops.
+	// This field is required, and Login will fail if it is unset or the empty string.
+	UserAgent string
+
+	// APIVersionCheckInterval is how often to try a newer Traffic Ops API Version.
+	// This allows clients to get new Traffic Ops features after Traffic Ops is upgraded
+	// without requiring a restart or new client.
+	//
+	// If 0 or not explicitly set, DefaultAPIVersionCheckInterval will be used.
+	// To disable, set to a very high value (like 100 years).
+	//
+	// This has no effect if ForceLatestAPI is true.
+	APIVersionCheckInterval time.Duration
+}
+
 // Session ...
 type Session struct {
 	UserName     string
 	Password     string
 	URL          string
 	Client       *http.Client
-	cache        map[string]CacheEntry
-	cacheMutex   *sync.RWMutex
-	useCache     bool
 	UserAgentStr string
+
+	latestSupportedAPI string
+	// forceLatestAPI is whether to forcibly always use the latest API version known to this client.
+	// This should only ever be set by ClientOpts.ForceLatestAPI.
+	forceLatestAPI bool
+	// lastAPIVerCheck is the last time the Session tried to get a newer API version from TO.
+	// Used internally to decide whether to try again.
+	lastAPIVerCheck time.Time
+	// apiVerCheckInterval is how often to try a newer Traffic Ops API, in case Traffic Ops was upgraded.
+	// This should only ever be set by ClientOpts.APIVersionCheckInterval.
+	apiVerCheckInterval time.Duration
 }
 
 func NewSession(user, password, url, userAgent string, client *http.Client, useCache bool) *Session {
@@ -56,14 +154,12 @@ func NewSession(user, password, url, userAgent string, client *http.Client, useC
 		Password:     password,
 		URL:          url,
 		Client:       client,
-		cache:        map[string]CacheEntry{},
-		cacheMutex:   &sync.RWMutex{},
-		useCache:     useCache,
 		UserAgentStr: userAgent,
 	}
 }
 
-const DefaultTimeout = time.Second * time.Duration(30)
+const DefaultTimeout = time.Second * 30
+const DefaultAPIVersionCheckInterval = time.Second * 60
 
 // HTTPError is returned on Update Session failure.
 type HTTPError struct {
@@ -78,16 +174,6 @@ func (e *HTTPError) Error() string {
 	return fmt.Sprintf("%s[%d] - Error requesting Traffic Ops %s %s", e.HTTPStatus, e.HTTPStatusCode, e.URL, e.Body)
 }
 
-// CacheEntry ...
-type CacheEntry struct {
-	Entered    int64
-	Bytes      []byte
-	RemoteAddr net.Addr
-}
-
-// TODO JvD
-const tmPollingInterval = 60
-
 // loginCreds gathers login credentials for Traffic Ops.
 func loginCreds(toUser string, toPasswd string) ([]byte, error) {
 	credentials := tc.UserCredentials{
@@ -119,22 +205,16 @@ func loginToken(token string) ([]byte, error) {
 
 // login tries to log in to Traffic Ops, and set the auth cookie in the Session. Returns the IP address of the remote Traffic Ops.
 func (to *Session) login() (net.Addr, error) {
-	credentials, err := loginCreds(to.UserName, to.Password)
-	if err != nil {
-		return nil, errors.New("creating login credentials: " + err.Error())
-	}
+	path := "/user/login"
+	body := tc.UserCredentials{Username: to.UserName, Password: to.Password}
+	alerts := tc.Alerts{}
 
-	path := apiBase + "/user/login"
-	resp, remoteAddr, err := to.RawRequestWithHdr("POST", path, credentials, nil)
-	resp, remoteAddr, err = to.errUnlessOKOrNotModified(resp, remoteAddr, err, path)
-	if err != nil {
-		return remoteAddr, errors.New("requesting: " + err.Error())
-	}
-	defer resp.Body.Close()
+	// Can't use req() because it retries login failures, which would be an infinite loop.
+	reqF := composeReqFuncs(makeRequestWithHeader, []MidReqF{reqTryLatest, reqFallback, reqAPI})
 
-	var alerts tc.Alerts
-	if err := json.NewDecoder(resp.Body).Decode(&alerts); err != nil {
-		return remoteAddr, errors.New("decoding response JSON: " + err.Error())
+	reqInf, err := reqF(to, http.MethodPost, path, body, nil, &alerts)
+	if err != nil {
+		return reqInf.RemoteAddr, fmt.Errorf("Login error %v, alerts string: %+v", err, alerts)
 	}
 
 	success := false
@@ -146,14 +226,14 @@ func (to *Session) login() (net.Addr, error) {
 	}
 
 	if !success {
-		return remoteAddr, fmt.Errorf("Login failed, alerts string: %+v", alerts)
+		return reqInf.RemoteAddr, fmt.Errorf("Login failed, alerts string: %+v", alerts)
 	}
 
-	return remoteAddr, nil
+	return reqInf.RemoteAddr, nil
 }
 
 func (to *Session) loginWithToken(token []byte) (net.Addr, error) {
-	path := apiBase + "/user/login/token"
+	path := to.APIBase() + "/user/login/token"
 	resp, remoteAddr, err := to.RawRequestWithHdr(http.MethodPost, path, token, nil)
 	resp, remoteAddr, err = to.errUnlessOKOrNotModified(resp, remoteAddr, err, path)
 	if err != nil {
@@ -182,7 +262,7 @@ func (to *Session) logout() (net.Addr, error) {
 		return nil, errors.New("creating login credentials: " + err.Error())
 	}
 
-	path := apiBase + "/user/logout"
+	path := to.APIBase() + "/user/logout"
 	resp, remoteAddr, err := to.RawRequestWithHdr("POST", path, credentials, nil)
 	resp, remoteAddr, err = to.errUnlessOKOrNotModified(resp, remoteAddr, err, path)
 	if err != nil {
@@ -215,6 +295,7 @@ func (to *Session) logout() (net.Addr, error) {
 //     to := traffic_ops.Login("user", "passwd", true)
 // subsequent calls like to.GetData("datadeliveryservice") will be authenticated.
 // Returns the logged in client, the remote address of Traffic Ops which was translated and used to log in, and any error. If the error is not nil, the remote address may or may not be nil, depending whether the error occurred before the login request.
+// The useCache argument is ignored. It exists to avoid breaking compatibility, and does not exist in newer functions.
 func LoginWithAgent(toURL string, toUser string, toPasswd string, insecure bool, userAgent string, useCache bool, requestTimeout time.Duration) (*Session, net.Addr, error) {
 	options := cookiejar.Options{
 		PublicSuffixList: publicsuffix.List,
@@ -271,7 +352,8 @@ func LoginWithToken(toURL string, token string, insecure bool, userAgent string,
 	return to, remoteAddr, nil
 }
 
-// Logout of traffic_ops
+// Logout of Traffic Ops.
+// The useCache argument is ignored. It exists to avoid breaking compatibility, and does not exist in newer functions.
 func LogoutWithAgent(toURL string, toUser string, toPasswd string, insecure bool, userAgent string, useCache bool, requestTimeout time.Duration) (*Session, net.Addr, error) {
 	options := cookiejar.Options{
 		PublicSuffixList: publicsuffix.List,
@@ -299,6 +381,7 @@ func LogoutWithAgent(toURL string, toUser string, toPasswd string, insecure bool
 
 // NewNoAuthSession returns a new Session without logging in
 // this can be used for querying unauthenticated endpoints without requiring a login
+// The useCache argument is ignored. It exists to avoid breaking compatibility, and does not exist in newer functions.
 func NewNoAuthSession(toURL string, insecure bool, userAgent string, useCache bool, requestTimeout time.Duration) *Session {
 	return NewSession("", "", toURL, userAgent, &http.Client{
 		Timeout: requestTimeout,
@@ -308,6 +391,14 @@ func NewNoAuthSession(toURL string, insecure bool, userAgent string, useCache bo
 	}, useCache)
 }
 
+func ErrIsNotImplemented(err error) bool {
+	return err != nil && strings.Contains(err.Error(), ErrNotImplemented.Error()) // use string.Contains in case context was added to the error
+}
+
+// ErrNotImplemented is returned when Traffic Ops returns a 501 Not Implemented
+// Users should check ErrIsNotImplemented rather than comparing directly, in case context was added.
+var ErrNotImplemented = errors.New("Traffic Ops Server returned 'Not Implemented', this client is probably newer than Traffic Ops, and you probably need to either upgrade Traffic Ops, or use a client whose version matches your Traffic Ops version.")
+
 // errUnlessOKOrNotModified returns the response, the remote address, and an error if the given Response's status code is anything
 // but 200 OK/ 304 Not Modified. This includes reading the Response.Body and Closing it. Otherwise, the given response, the remote
 // address, and a nil error are returned.
@@ -322,7 +413,7 @@ func (to *Session) errUnlessOKOrNotModified(resp *http.Response, remoteAddr net.
 	defer resp.Body.Close()
 
 	if resp.StatusCode == http.StatusNotImplemented {
-		return resp, remoteAddr, errors.New("Traffic Ops Server returned 'Not Implemented', this client is probably newer than Traffic Ops, and you probably need to either upgrade Traffic Ops, or use a client whose version matches your Traffic Ops version.")
+		return resp, remoteAddr, ErrNotImplemented
 	}
 
 	body, readErr := ioutil.ReadAll(resp.Body)
@@ -334,9 +425,125 @@ func (to *Session) errUnlessOKOrNotModified(resp *http.Response, remoteAddr net.
 
 func (to *Session) getURL(path string) string { return to.URL + path }
 
+type ReqF func(to *Session, method string, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error)
+
+type MidReqF func(ReqF) ReqF
+
+// composeReqFuncs takes an initial request func and middleware, and
+// returns a single ReqFunc to be called,
+func composeReqFuncs(reqF ReqF, middleware []MidReqF) ReqF {
+	// compose in reverse-order, which causes them to be applied in forward-order.
+	for i := len(middleware) - 1; i >= 0; i-- {
+		reqF = middleware[i](reqF)
+	}
+	return reqF
+}
+
+// reqTryLatest will re-set to.latestSupportedAPI to the latest, if it's less than the latest and to.apiVerCheckInterval has passed.
+// This does not fallback, so it should generally be composed with reqFallback.
+func reqTryLatest(reqF ReqF) ReqF {
+	return func(to *Session, method string, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
+		if to.apiVerCheckInterval == 0 {
+			// Session could have been default-initialized rather than created with a func, so we need to check here, not just in login funcs.
+			to.apiVerCheckInterval = DefaultAPIVersionCheckInterval
+		}
+
+		if !to.forceLatestAPI && time.Since(to.lastAPIVerCheck) >= to.apiVerCheckInterval {
+			// if it's been apiVerCheckInterval since the last version check,
+			// set the version to the latest (and fall back again, if necessary)
+			to.latestSupportedAPI = apiVersions()[0]
+
+			// Set the last version check to far in the future, and then
+			// defer setting the last check until this function returns,
+			// so that if fallback takes longer than the interval,
+			// the recursive calls to this function don't end up forever retrying the latest.
+			to.lastAPIVerCheck = time.Now().Add(time.Hour * 24 * 365)
+			defer func() { to.lastAPIVerCheck = time.Now() }()
+		}
+		return reqF(to, method, path, body, header, response)
+	}
+}
+
+// reqLogin makes the request, and if it fails, tries to log in again then makes the request again.
+// If the login fails, the original response is returned.
+// If the second request fails, it's returned. Login is only tried once.
+// This is designed to handle expired sessions, when the time between requests is longer than the session expiration;
+// it does not do perpetual retry.
+func reqLogin(reqF ReqF) ReqF {
+	return func(to *Session, method string, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
+		inf, err := reqF(to, method, path, body, header, response)
+		if inf.StatusCode != http.StatusUnauthorized && inf.StatusCode != http.StatusForbidden {
+			return inf, err
+		}
+		if _, lerr := to.login(); lerr != nil {
+			return inf, err
+		}
+		return reqF(to, method, path, body, header, response)
+	}
+}
+
+// reqFallback calls reqF, and if Traffic Ops doesn't support the latest version,
+// falls back to the previous and retries, recursively.
+// If all supported versions fail, the last response error is returned.
+func reqFallback(reqF ReqF) ReqF {
+	var fallbackFunc func(to *Session, method string, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error)
+	fallbackFunc = func(to *Session, method string, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
+		inf, err := reqF(to, method, path, body, header, response)
+		if err == nil {
+			return inf, err
+		}
+		if !ErrIsNotImplemented(err) ||
+			to.forceLatestAPI {
+			return inf, err
+		}
+
+		apiVersions := apiVersions()
+
+		nextAPIVerI := int(math.MaxInt32) - 1
+		for verI, ver := range apiVersions {
+			if to.latestSupportedAPI == ver {
+				nextAPIVerI = verI
+				break
+			}
+		}
+		nextAPIVerI = nextAPIVerI + 1
+		if nextAPIVerI >= len(apiVersions) {
+			return inf, err // we're already on the oldest minor supported, and the server doesn't support it.
+		}
+		to.latestSupportedAPI = apiVersions[nextAPIVerI]
+
+		return fallbackFunc(to, method, path, body, header, response)
+	}
+	return fallbackFunc
+}
+
+// reqAPI calls reqF with a path not including the /api/x prefix,
+// and adds the API version from the Session.
+//
+// For example, path should be like '/deliveryservices'
+// and this will request '/api/3.1/deliveryservices'.
+//
+func reqAPI(reqF ReqF) ReqF {
+	return func(to *Session, method string, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
+		path = to.APIBase() + path
+		return reqF(to, method, path, body, header, response)
+	}
+}
+
 // makeRequestWithHeader marshals the response body (if non-nil), performs the HTTP request,
 // and decodes the response into the given response pointer.
-func (to *Session) makeRequestWithHeader(method, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
+//
+// Note processing on the following codes:
+// 304 http.StatusNotModified  - Will return the 304 in ReqInf, a nil error, and a nil response.
+//
+// 401 http.StatusUnauthorized - Via to.request(), Same as 403 Forbidden.
+// 403 http.StatusForbidden    - Via to.request()
+//                               Will try to log in again, and try the request again.
+//                               The second request is returned, even if it fails.
+//
+// To request the bytes without deserializing, pass a *[]byte response.
+//
+func makeRequestWithHeader(to *Session, method, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
 	var remoteAddr net.Addr
 	reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: remoteAddr}
 	var reqBody []byte
@@ -359,6 +566,16 @@ func (to *Session) makeRequestWithHeader(method, path string, body interface{},
 	if err != nil {
 		return reqInf, errors.New("requesting from Traffic Ops: " + err.Error())
 	}
+
+	if btsPtr, isBytes := response.(*[]byte); isBytes {
+		bts, err := ioutil.ReadAll(resp.Body)
+		if err != nil {
+			return reqInf, errors.New("reading response body: " + err.Error())
+		}
+		*btsPtr = bts
+		return reqInf, nil
+	}
+
 	if err := json.NewDecoder(resp.Body).Decode(response); err != nil {
 		return reqInf, errors.New("decoding response body: " + err.Error())
 	}
@@ -366,19 +583,24 @@ func (to *Session) makeRequestWithHeader(method, path string, body interface{},
 }
 
 func (to *Session) get(path string, header http.Header, response interface{}) (ReqInf, error) {
-	return to.makeRequestWithHeader(http.MethodGet, path, nil, header, response)
+	return to.req(http.MethodGet, path, nil, header, response)
 }
 
 func (to *Session) post(path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
-	return to.makeRequestWithHeader(http.MethodPost, path, body, header, response)
+	return to.req(http.MethodPost, path, body, header, response)
 }
 
 func (to *Session) put(path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
-	return to.makeRequestWithHeader(http.MethodPut, path, body, header, response)
+	return to.req(http.MethodPut, path, body, header, response)
 }
 
 func (to *Session) del(path string, header http.Header, response interface{}) (ReqInf, error) {
-	return to.makeRequestWithHeader(http.MethodDelete, path, nil, header, response)
+	return to.req(http.MethodDelete, path, nil, header, response)
+}
+
+func (to *Session) req(method string, path string, body interface{}, header http.Header, response interface{}) (ReqInf, error) {
+	reqF := composeReqFuncs(makeRequestWithHeader, []MidReqF{reqTryLatest, reqFallback, reqAPI, reqLogin})
+	return reqF(to, method, path, body, header, response)
 }
 
 // request performs the HTTP request to Traffic Ops, trying to refresh the cookie if an Unauthorized or Forbidden code is received. It only tries once. If the login fails, the original Unauthorized/Forbidden response is returned. If the login succeeds and the subsequent re-request fails, the re-request's response is returned even if it's another Unauthorized/Forbidden.
@@ -447,22 +669,33 @@ func (to *Session) RawRequest(method, path string, body []byte) (*http.Response,
 }
 
 type ReqInf struct {
+	// CacheHitStatus is deprecated and will be removed in the next major version.
 	CacheHitStatus CacheHitStatus
 	RemoteAddr     net.Addr
 	StatusCode     int
 }
 
+// CacheHitStatus is deprecated and will be removed in the next major version.
 type CacheHitStatus string
 
+// CacheHitStatusHit is deprecated and will be removed in the next major version.
 const CacheHitStatusHit = CacheHitStatus("hit")
+
+// CacheHitStatusExpired is deprecated and will be removed in the next major version.
 const CacheHitStatusExpired = CacheHitStatus("expired")
+
+// CacheHitStatusMiss is deprecated and will be removed in the next major version.
 const CacheHitStatusMiss = CacheHitStatus("miss")
+
+// CacheHitStatusInvalid is deprecated and will be removed in the next major version.
 const CacheHitStatusInvalid = CacheHitStatus("")
 
+// String is deprecated and will be removed in the next major version.
 func (s CacheHitStatus) String() string {
 	return string(s)
 }
 
+// StringToCacheHitStatus is deprecated and will be removed in the next major version.
 func StringToCacheHitStatus(s string) CacheHitStatus {
 	s = strings.ToLower(s)
 	switch s {
@@ -476,79 +709,3 @@ func StringToCacheHitStatus(s string) CacheHitStatus {
 		return CacheHitStatusInvalid
 	}
 }
-
-// setCache Sets the given cache key and value. This is threadsafe for multiple goroutines.
-func (to *Session) setCache(path string, entry CacheEntry) {
-	if !to.useCache {
-		return
-	}
-	to.cacheMutex.Lock()
-	defer to.cacheMutex.Unlock()
-	to.cache[path] = entry
-}
-
-// getCache gets the cache value at the given key, or false if it doesn't exist. This is threadsafe for multiple goroutines.
-func (to *Session) getCache(path string) (CacheEntry, bool) {
-	to.cacheMutex.RLock()
-	defer to.cacheMutex.RUnlock()
-	cacheEntry, ok := to.cache[path]
-	return cacheEntry, ok
-}
-
-//if cacheEntry, ok := to.Cache[path]; ok {
-
-// getBytesWithTTL gets the path, and caches in the session. Returns bytes from the cache, if found and the TTL isn't expired. Otherwise, gets it and store it in cache
-func (to *Session) getBytesWithTTL(path string, ttl int64) ([]byte, ReqInf, error) {
-	var body []byte
-	var err error
-	var cacheHitStatus CacheHitStatus
-	var remoteAddr net.Addr
-
-	getFresh := false
-	if cacheEntry, ok := to.getCache(path); ok {
-		if cacheEntry.Entered > time.Now().Unix()-ttl {
-			cacheHitStatus = CacheHitStatusHit
-			body = cacheEntry.Bytes
-			remoteAddr = cacheEntry.RemoteAddr
-		} else {
-			cacheHitStatus = CacheHitStatusExpired
-			getFresh = true
-		}
-	} else {
-		cacheHitStatus = CacheHitStatusMiss
-		getFresh = true
-	}
-
-	if getFresh {
-		body, remoteAddr, err = to.getBytes(path)
-		if err != nil {
-			return nil, ReqInf{CacheHitStatus: CacheHitStatusInvalid, RemoteAddr: remoteAddr}, err
-		}
-
-		newEntry := CacheEntry{
-			Entered:    time.Now().Unix(),
-			Bytes:      body,
-			RemoteAddr: remoteAddr,
-		}
-		to.setCache(path, newEntry)
-	}
-
-	return body, ReqInf{CacheHitStatus: cacheHitStatus, RemoteAddr: remoteAddr}, nil
-}
-
-// GetBytes - get []bytes array for a certain path on the to session.
-// returns the raw body, the remote address the Traffic Ops URL resolved to, or any error. If the error is not nil, the RemoteAddr may or may not be nil, depending whether the error occurred before the request was executed.
-func (to *Session) getBytes(path string) ([]byte, net.Addr, error) {
-	resp, remoteAddr, err := to.request("GET", path, nil, nil)
-	if err != nil {
-		return nil, remoteAddr, err
-	}
-	defer resp.Body.Close()
-
-	body, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, remoteAddr, err
-	}
-
-	return body, remoteAddr, nil
-}
diff --git a/traffic_ops/v3-client/staticdnsentry.go b/traffic_ops/v3-client/staticdnsentry.go
index 8a4ff61..138021f 100644
--- a/traffic_ops/v3-client/staticdnsentry.go
+++ b/traffic_ops/v3-client/staticdnsentry.go
@@ -25,7 +25,10 @@ import (
 )
 
 const (
+	// API_STATIC_DNS_ENTRIES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_STATIC_DNS_ENTRIES = apiBase + "/staticdnsentries"
+
+	APIStaticDNSEntries = "/staticdnsentries"
 )
 
 func staticDNSEntryIDs(to *Session, sdns *tc.StaticDNSEntry) error {
@@ -79,7 +82,7 @@ func (to *Session) CreateStaticDNSEntry(sdns tc.StaticDNSEntry) (tc.Alerts, ReqI
 	if err != nil {
 		return alerts, ReqInf{CacheHitStatus: CacheHitStatusMiss}, err
 	}
-	reqInf, err := to.post(API_STATIC_DNS_ENTRIES, sdns, nil, &alerts)
+	reqInf, err := to.post(APIStaticDNSEntries, sdns, nil, &alerts)
 	return alerts, reqInf, err
 }
 
@@ -90,7 +93,7 @@ func (to *Session) UpdateStaticDNSEntryByIDWithHdr(id int, sdns tc.StaticDNSEntr
 	if err != nil {
 		return alerts, ReqInf{CacheHitStatus: CacheHitStatusMiss}, 0, err
 	}
-	route := fmt.Sprintf("%s?id=%d", API_STATIC_DNS_ENTRIES, id)
+	route := fmt.Sprintf("%s?id=%d", APIStaticDNSEntries, id)
 	reqInf, err := to.put(route, sdns, header, &alerts)
 	return tc.Alerts{}, reqInf, reqInf.StatusCode, err
 }
@@ -103,7 +106,7 @@ func (to *Session) UpdateStaticDNSEntryByID(id int, sdns tc.StaticDNSEntry) (tc.
 
 func (to *Session) GetStaticDNSEntriesWithHdr(header http.Header) ([]tc.StaticDNSEntry, ReqInf, error) {
 	var data tc.StaticDNSEntriesResponse
-	reqInf, err := to.get(API_STATIC_DNS_ENTRIES, header, &data)
+	reqInf, err := to.get(APIStaticDNSEntries, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -114,7 +117,7 @@ func (to *Session) GetStaticDNSEntries() ([]tc.StaticDNSEntry, ReqInf, error) {
 }
 
 func (to *Session) GetStaticDNSEntryByIDWithHdr(id int, header http.Header) ([]tc.StaticDNSEntry, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_STATIC_DNS_ENTRIES, id)
+	route := fmt.Sprintf("%s?id=%d", APIStaticDNSEntries, id)
 	var data tc.StaticDNSEntriesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -127,7 +130,7 @@ func (to *Session) GetStaticDNSEntryByID(id int) ([]tc.StaticDNSEntry, ReqInf, e
 }
 
 func (to *Session) GetStaticDNSEntriesByHostWithHdr(host string, header http.Header) ([]tc.StaticDNSEntry, ReqInf, error) {
-	route := fmt.Sprintf("%s?host=%s", API_STATIC_DNS_ENTRIES, url.QueryEscape(host))
+	route := fmt.Sprintf("%s?host=%s", APIStaticDNSEntries, url.QueryEscape(host))
 	var data tc.StaticDNSEntriesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -141,7 +144,7 @@ func (to *Session) GetStaticDNSEntriesByHost(host string) ([]tc.StaticDNSEntry,
 
 // DeleteStaticDNSEntryByID DELETEs a Static DNS Entry by ID.
 func (to *Session) DeleteStaticDNSEntryByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_STATIC_DNS_ENTRIES, id)
+	route := fmt.Sprintf("%s?id=%d", APIStaticDNSEntries, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/stats_summary.go b/traffic_ops/v3-client/stats_summary.go
index 41a8ae7..66d1bfb 100644
--- a/traffic_ops/v3-client/stats_summary.go
+++ b/traffic_ops/v3-client/stats_summary.go
@@ -20,7 +20,10 @@ import (
 )
 
 const (
+	// API_STATS_SUMMARY is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_STATS_SUMMARY = apiBase + "/stats_summary"
+
+	APIStatsSummary = "/stats_summary"
 )
 
 // GetSummaryStats gets a list of summary stats with the ability to filter on cdn,deliveryService and/or stat
@@ -38,9 +41,9 @@ func (to *Session) GetSummaryStats(cdn, deliveryService, statName *string) (tc.S
 		param.Add("statName", *statName)
 	}
 
-	route := API_STATS_SUMMARY
+	route := APIStatsSummary
 	if len(param) > 0 {
-		route = fmt.Sprintf("%s?%s", API_STATS_SUMMARY, param.Encode())
+		route = fmt.Sprintf("%s?%s", APIStatsSummary, param.Encode())
 	}
 	reqInf, err := to.get(route, nil, &resp)
 	return resp, reqInf, err
@@ -55,8 +58,7 @@ func (to *Session) GetSummaryStatsLastUpdated(statName *string) (tc.StatsSummary
 	if statName != nil {
 		param.Add("statName", *statName)
 	}
-	route := fmt.Sprintf("%s?%s", API_STATS_SUMMARY, param.Encode())
-
+	route := fmt.Sprintf("%s?%s", APIStatsSummary, param.Encode())
 	reqInf, err := to.get(route, nil, &resp)
 	return resp, reqInf, err
 }
@@ -64,6 +66,6 @@ func (to *Session) GetSummaryStatsLastUpdated(statName *string) (tc.StatsSummary
 // CreateSummaryStats creates a stats summary
 func (to *Session) CreateSummaryStats(statsSummary tc.StatsSummary) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_STATS_SUMMARY, statsSummary, nil, &alerts)
+	reqInf, err := to.post(APIStatsSummary, statsSummary, nil, &alerts)
 	return alerts, reqInf, err
 }
diff --git a/traffic_ops/v3-client/status.go b/traffic_ops/v3-client/status.go
index a7ec127..cbdda0c 100644
--- a/traffic_ops/v3-client/status.go
+++ b/traffic_ops/v3-client/status.go
@@ -24,18 +24,21 @@ import (
 )
 
 const (
+	// API_STATUSES is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_STATUSES = apiBase + "/statuses"
+
+	APIStatuses = "/statuses"
 )
 
 // CreateStatusNullable creates a new status, using the tc.StatusNullable structure.
 func (to *Session) CreateStatusNullable(status tc.StatusNullable) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_STATUSES, status, nil, &alerts)
+	reqInf, err := to.post(APIStatuses, status, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateStatusByIDWithHdr(id int, status tc.Status, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_STATUSES, id)
+	route := fmt.Sprintf("%s/%d", APIStatuses, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, status, header, &alerts)
 	return alerts, reqInf, err
@@ -49,7 +52,7 @@ func (to *Session) UpdateStatusByID(id int, status tc.Status) (tc.Alerts, ReqInf
 
 func (to *Session) GetStatusesWithHdr(header http.Header) ([]tc.Status, ReqInf, error) {
 	var data tc.StatusesResponse
-	reqInf, err := to.get(API_STATUSES, header, &data)
+	reqInf, err := to.get(APIStatuses, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -60,7 +63,7 @@ func (to *Session) GetStatuses() ([]tc.Status, ReqInf, error) {
 }
 
 func (to *Session) GetStatusByIDWithHdr(id int, header http.Header) ([]tc.Status, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_STATUSES, id)
+	route := fmt.Sprintf("%s?id=%d", APIStatuses, id)
 	var data tc.StatusesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -73,7 +76,7 @@ func (to *Session) GetStatusByID(id int) ([]tc.Status, ReqInf, error) {
 }
 
 func (to *Session) GetStatusByNameWithHdr(name string, header http.Header) ([]tc.Status, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_STATUSES, url.QueryEscape(name))
+	route := fmt.Sprintf("%s?name=%s", APIStatuses, url.QueryEscape(name))
 	var data tc.StatusesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -87,7 +90,7 @@ func (to *Session) GetStatusByName(name string) ([]tc.Status, ReqInf, error) {
 
 // DeleteStatusByID DELETEs a Status by ID.
 func (to *Session) DeleteStatusByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_STATUSES, id)
+	route := fmt.Sprintf("%s/%d", APIStatuses, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/steering.go b/traffic_ops/v3-client/steering.go
index 0602252..3258758 100644
--- a/traffic_ops/v3-client/steering.go
+++ b/traffic_ops/v3-client/steering.go
@@ -25,7 +25,7 @@ func (to *Session) SteeringWithHdr(header http.Header) ([]tc.Steering, ReqInf, e
 	data := struct {
 		Response []tc.Steering `json:"response"`
 	}{}
-	reqInf, err := to.get(apiBase+`/steering`, header, &data)
+	reqInf, err := to.get(`/steering`, header, &data)
 	return data.Response, reqInf, err
 }
 
diff --git a/traffic_ops/v3-client/steeringtarget.go b/traffic_ops/v3-client/steeringtarget.go
index 807e5e2..555992b 100644
--- a/traffic_ops/v3-client/steeringtarget.go
+++ b/traffic_ops/v3-client/steeringtarget.go
@@ -28,7 +28,7 @@ func (to *Session) CreateSteeringTarget(st tc.SteeringTargetNullable) (tc.Alerts
 		return tc.Alerts{}, ReqInf{CacheHitStatus: CacheHitStatusMiss}, errors.New("missing delivery service id")
 	}
 	alerts := tc.Alerts{}
-	route := fmt.Sprintf("%s/steering/%d/targets", apiBase, *st.DeliveryServiceID)
+	route := fmt.Sprintf("/steering/%d/targets", *st.DeliveryServiceID)
 	reqInf, err := to.post(route, st, nil, &alerts)
 	return alerts, reqInf, err
 }
@@ -41,7 +41,7 @@ func (to *Session) UpdateSteeringTargetWithHdr(st tc.SteeringTargetNullable, hea
 	if st.TargetID == nil {
 		return tc.Alerts{}, reqInf, errors.New("missing target id")
 	}
-	route := fmt.Sprintf("%s/steering/%d/targets/%d", apiBase, *st.DeliveryServiceID, *st.TargetID)
+	route := fmt.Sprintf("/steering/%d/targets/%d", *st.DeliveryServiceID, *st.TargetID)
 	alerts := tc.Alerts{}
 	reqInf, err := to.put(route, st, header, &alerts)
 	return alerts, reqInf, err
@@ -53,7 +53,7 @@ func (to *Session) UpdateSteeringTarget(st tc.SteeringTargetNullable) (tc.Alerts
 }
 
 func (to *Session) GetSteeringTargets(dsID int) ([]tc.SteeringTargetNullable, ReqInf, error) {
-	route := fmt.Sprintf("%s/steering/%d/targets", apiBase, dsID)
+	route := fmt.Sprintf("/steering/%d/targets", dsID)
 	data := struct {
 		Response []tc.SteeringTargetNullable `json:"response"`
 	}{}
@@ -62,7 +62,7 @@ func (to *Session) GetSteeringTargets(dsID int) ([]tc.SteeringTargetNullable, Re
 }
 
 func (to *Session) DeleteSteeringTarget(dsID int, targetID int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/steering/%d/targets/%d", apiBase, dsID, targetID)
+	route := fmt.Sprintf("/steering/%d/targets/%d", dsID, targetID)
 	alerts := tc.Alerts{}
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/tenant.go b/traffic_ops/v3-client/tenant.go
index 932a6a6..b50432d 100644
--- a/traffic_ops/v3-client/tenant.go
+++ b/traffic_ops/v3-client/tenant.go
@@ -24,12 +24,19 @@ import (
 	tc "github.com/apache/trafficcontrol/lib/go-tc"
 )
 
+// API_TENANTS is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const API_TENANTS = apiBase + "/tenants"
+
+// API_TENANT_ID is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const API_TENANT_ID = API_TENANTS + "/%s"
 
+const APITenants = "/tenants"
+
+const APITenantID = APITenants + "/%v"
+
 func (to *Session) TenantsWithHdr(header http.Header) ([]tc.Tenant, ReqInf, error) {
 	var data tc.GetTenantsResponse
-	reqInf, err := to.get(API_TENANTS, header, &data)
+	reqInf, err := to.get(APITenants, header, &data)
 	return data.Response, reqInf, err
 }
 
@@ -41,7 +48,7 @@ func (to *Session) Tenants() ([]tc.Tenant, ReqInf, error) {
 
 func (to *Session) TenantWithHdr(id string, header http.Header) (*tc.Tenant, ReqInf, error) {
 	var data tc.GetTenantsResponse
-	reqInf, err := to.get(fmt.Sprintf("%s?id=%v", API_TENANTS, id), header, &data)
+	reqInf, err := to.get(fmt.Sprintf("%s?id=%v", APITenants, id), header, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -60,7 +67,7 @@ func (to *Session) Tenant(id string) (*tc.Tenant, ReqInf, error) {
 
 func (to *Session) TenantByNameWithHdr(name string, header http.Header) (*tc.Tenant, ReqInf, error) {
 	var data tc.GetTenantsResponse
-	query := API_TENANTS + "?name=" + url.QueryEscape(name)
+	query := APITenants + "?name=" + url.QueryEscape(name)
 	reqInf, err := to.get(query, header, &data)
 	if err != nil {
 		return nil, reqInf, err
@@ -95,7 +102,7 @@ func (to *Session) CreateTenant(t *tc.Tenant) (*tc.TenantResponse, error) {
 	}
 
 	var data tc.TenantResponse
-	_, err := to.post(API_TENANTS, t, nil, &data)
+	_, err := to.post(APITenants, t, nil, &data)
 	if err != nil {
 		return nil, err
 	}
@@ -104,7 +111,7 @@ func (to *Session) CreateTenant(t *tc.Tenant) (*tc.TenantResponse, error) {
 
 func (to *Session) UpdateTenantWithHdr(id string, t *tc.Tenant, header http.Header) (*tc.TenantResponse, ReqInf, error) {
 	var data tc.TenantResponse
-	reqInf, err := to.put(fmt.Sprintf(API_TENANT_ID, id), t, header, &data)
+	reqInf, err := to.put(fmt.Sprintf(APITenantID, id), t, header, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -122,7 +129,7 @@ func (to *Session) UpdateTenant(id string, t *tc.Tenant) (*tc.TenantResponse, er
 // DeleteTenant deletes the Tenant matching the ID it's passed.
 func (to *Session) DeleteTenant(id string) (*tc.DeleteTenantResponse, error) {
 	var data tc.DeleteTenantResponse
-	_, err := to.del(fmt.Sprintf(API_TENANT_ID, id), nil, &data)
+	_, err := to.del(fmt.Sprintf(APITenantID, id), nil, &data)
 	if err != nil {
 		return nil, err
 	}
diff --git a/traffic_ops/v3-client/topology.go b/traffic_ops/v3-client/topology.go
index 37c54ae..0842459 100644
--- a/traffic_ops/v3-client/topology.go
+++ b/traffic_ops/v3-client/topology.go
@@ -23,12 +23,15 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 )
 
+// ApiTopologies is Deprecated: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const ApiTopologies = apiBase + "/topologies"
 
+const APITopologies = "/topologies"
+
 // CreateTopology creates a topology and returns the response.
 func (to *Session) CreateTopology(top tc.Topology) (*tc.TopologyResponse, ReqInf, error) {
 	resp := new(tc.TopologyResponse)
-	reqInf, err := to.post(ApiTopologies, top, nil, resp)
+	reqInf, err := to.post(APITopologies, top, nil, resp)
 	return resp, reqInf, err
 }
 
@@ -45,7 +48,7 @@ func (to *Session) GetTopologies() ([]tc.Topology, ReqInf, error) {
 }
 
 func (to *Session) GetTopologyWithHdr(name string, header http.Header) (*tc.Topology, ReqInf, error) {
-	reqUrl := fmt.Sprintf("%s?name=%s", ApiTopologies, url.QueryEscape(name))
+	reqUrl := fmt.Sprintf("%s?name=%s", APITopologies, url.QueryEscape(name))
 	var data tc.TopologiesResponse
 	reqInf, err := to.get(reqUrl, header, &data)
 	if err != nil {
@@ -65,7 +68,7 @@ func (to *Session) GetTopology(name string) (*tc.Topology, ReqInf, error) {
 
 // UpdateTopology updates a Topology by name.
 func (to *Session) UpdateTopology(name string, t tc.Topology) (*tc.TopologyResponse, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", ApiTopologies, name)
+	route := fmt.Sprintf("%s?name=%s", APITopologies, name)
 	var response = new(tc.TopologyResponse)
 	reqInf, err := to.put(route, t, nil, &response)
 	return response, reqInf, err
@@ -73,7 +76,7 @@ func (to *Session) UpdateTopology(name string, t tc.Topology) (*tc.TopologyRespo
 
 // DeleteTopology deletes the given topology by name.
 func (to *Session) DeleteTopology(name string) (tc.Alerts, ReqInf, error) {
-	reqUrl := fmt.Sprintf("%s?name=%s", ApiTopologies, url.QueryEscape(name))
+	reqUrl := fmt.Sprintf("%s?name=%s", APITopologies, url.QueryEscape(name))
 	var alerts tc.Alerts
 	reqInf, err := to.del(reqUrl, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/topology_queue_updates.go b/traffic_ops/v3-client/topology_queue_updates.go
index 255d0e4..db09284 100644
--- a/traffic_ops/v3-client/topology_queue_updates.go
+++ b/traffic_ops/v3-client/topology_queue_updates.go
@@ -26,7 +26,7 @@ import (
 )
 
 func (to *Session) TopologiesQueueUpdate(topologyName tc.TopologyName, req tc.TopologiesQueueUpdateRequest) (tc.TopologiesQueueUpdateResponse, ReqInf, error) {
-	path := fmt.Sprintf(ApiTopologies+"/%s/queue_update", topologyName)
+	path := fmt.Sprintf("%s/%s/queue_update", APITopologies, topologyName)
 	var resp tc.TopologiesQueueUpdateResponse
 	reqInf, err := to.post(path, req, nil, &resp)
 	return resp, reqInf, err
diff --git a/traffic_ops/v3-client/traffic_monitor.go b/traffic_ops/v3-client/traffic_monitor.go
index ae3e4bd..c239356 100644
--- a/traffic_ops/v3-client/traffic_monitor.go
+++ b/traffic_ops/v3-client/traffic_monitor.go
@@ -29,8 +29,12 @@ import (
 // configuration information. It is meant to be used with fmt.Sprintf to insert the necessary
 // path parameters (namely the Name of the CDN of interest).
 // See Also: https://traffic-control-cdn.readthedocs.io/en/latest/api/v3/cdns_name_configs_monitoring.html
+//
+// DEPRECATED: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 const API_CDN_MONITORING_CONFIG = apiBase + "/cdns/%s/configs/monitoring"
 
+const APICDNMonitoringConfig = "/cdns/%s/configs/monitoring"
+
 // GetTrafficMonitorConfigMap is functionally identical to GetTrafficMonitorConfig, except that it
 // coerces the value returned by the API to the tc.TrafficMonitorConfigMap structure.
 func (to *Session) GetTrafficMonitorConfigMap(cdn string) (*tc.TrafficMonitorConfigMap, ReqInf, error) {
@@ -47,7 +51,7 @@ func (to *Session) GetTrafficMonitorConfigMap(cdn string) (*tc.TrafficMonitorCon
 
 // GetTrafficMonitorConfig returns the monitoring configuration for the CDN named by 'cdn'.
 func (to *Session) GetTrafficMonitorConfig(cdn string) (*tc.TrafficMonitorConfig, ReqInf, error) {
-	route := fmt.Sprintf(API_CDN_MONITORING_CONFIG, cdn)
+	route := fmt.Sprintf(APICDNMonitoringConfig, cdn)
 	var data tc.TMConfigResponse
 	reqInf, err := to.get(route, nil, &data)
 	return &data.Response, reqInf, err
diff --git a/traffic_ops/v3-client/traffic_stats.go b/traffic_ops/v3-client/traffic_stats.go
index 50e8626..267ad34 100644
--- a/traffic_ops/v3-client/traffic_stats.go
+++ b/traffic_ops/v3-client/traffic_stats.go
@@ -21,6 +21,6 @@ import (
 // GetCurrentStats gets current stats for each CDNs and a total across them
 func (to *Session) GetCurrentStats() (tc.TrafficStatsCDNStatsResponse, ReqInf, error) {
 	resp := tc.TrafficStatsCDNStatsResponse{}
-	reqInf, err := to.get(apiBase+"/current_stats", nil, &resp)
+	reqInf, err := to.get("/current_stats", nil, &resp)
 	return resp, reqInf, err
 }
diff --git a/traffic_ops/v3-client/type.go b/traffic_ops/v3-client/type.go
index 615e33b..e9468c2 100644
--- a/traffic_ops/v3-client/type.go
+++ b/traffic_ops/v3-client/type.go
@@ -24,18 +24,21 @@ import (
 )
 
 const (
+	// DEPRECATED: will be removed in the next major version. Be aware this may not be the URI being requested, for clients created with Login and ClientOps.ForceLatestAPI false.
 	API_TYPES = apiBase + "/types"
+
+	APITypes = "/types"
 )
 
 // CreateType creates a Type. There should be a very good reason for doing this.
 func (to *Session) CreateType(typ tc.Type) (tc.Alerts, ReqInf, error) {
 	var alerts tc.Alerts
-	reqInf, err := to.post(API_TYPES, typ, nil, &alerts)
+	reqInf, err := to.post(APITypes, typ, nil, &alerts)
 	return alerts, reqInf, err
 }
 
 func (to *Session) UpdateTypeByIDWithHdr(id int, typ tc.Type, header http.Header) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_TYPES, id)
+	route := fmt.Sprintf("%s/%d", APITypes, id)
 	var alerts tc.Alerts
 	reqInf, err := to.put(route, typ, header, &alerts)
 	return alerts, reqInf, err
@@ -56,7 +59,7 @@ func (to *Session) GetTypesWithHdr(header http.Header, useInTable ...string) ([]
 		return nil, ReqInf{}, errors.New("please pass in a single value for the 'useInTable' parameter")
 	}
 	var data tc.TypesResponse
-	reqInf, err := to.get(API_TYPES, header, &data)
+	reqInf, err := to.get(APITypes, header, &data)
 	if err != nil {
 		return nil, reqInf, err
 	}
@@ -85,7 +88,7 @@ func (to *Session) GetTypes(useInTable ...string) ([]tc.Type, ReqInf, error) {
 
 // GetTypeByID GETs a Type by the Type ID, and filters by http header params in the request.
 func (to *Session) GetTypeByIDWithHdr(id int, header http.Header) ([]tc.Type, ReqInf, error) {
-	route := fmt.Sprintf("%s?id=%d", API_TYPES, id)
+	route := fmt.Sprintf("%s?id=%d", APITypes, id)
 	var data tc.TypesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -98,7 +101,7 @@ func (to *Session) GetTypeByID(id int) ([]tc.Type, ReqInf, error) {
 }
 
 func (to *Session) GetTypeByNameWithHdr(name string, header http.Header) ([]tc.Type, ReqInf, error) {
-	route := fmt.Sprintf("%s?name=%s", API_TYPES, name)
+	route := fmt.Sprintf("%s?name=%s", APITypes, name)
 	var data tc.TypesResponse
 	reqInf, err := to.get(route, header, &data)
 	return data.Response, reqInf, err
@@ -112,7 +115,7 @@ func (to *Session) GetTypeByName(name string) ([]tc.Type, ReqInf, error) {
 
 // DeleteTypeByID DELETEs a Type by ID.
 func (to *Session) DeleteTypeByID(id int) (tc.Alerts, ReqInf, error) {
-	route := fmt.Sprintf("%s/%d", API_TYPES, id)
+	route := fmt.Sprintf("%s/%d", APITypes, id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
diff --git a/traffic_ops/v3-client/user.go b/traffic_ops/v3-client/user.go
index bece5ec..6bd6a26 100644
--- a/traffic_ops/v3-client/user.go
+++ b/traffic_ops/v3-client/user.go
@@ -28,7 +28,7 @@ import (
 
 func (to *Session) GetUsersWithHdr(header http.Header) ([]tc.User, ReqInf, error) {
 	data := tc.UsersResponse{}
-	route := fmt.Sprintf("%s/users", apiBase)
+	route := "/users"
 	inf, err := to.get(route, header, &data)
 	return data.Response, inf, err
 }
@@ -41,7 +41,7 @@ func (to *Session) GetUsers() ([]tc.User, ReqInf, error) {
 
 func (to *Session) GetUsersByRoleWithHdr(roleName string, header http.Header) ([]tc.User, ReqInf, error) {
 	data := tc.UsersResponse{}
-	route := fmt.Sprintf("%s/users?role=%s", apiBase, url.QueryEscape(roleName))
+	route := fmt.Sprintf("/users?role=%s", url.QueryEscape(roleName))
 	inf, err := to.get(route, header, &data)
 	return data.Response, inf, err
 }
@@ -54,7 +54,7 @@ func (to *Session) GetUsersByRole(roleName string) ([]tc.User, ReqInf, error) {
 
 func (to *Session) GetUserByIDWithHdr(id int, header http.Header) ([]tc.User, ReqInf, error) {
 	data := tc.UsersResponse{}
-	route := fmt.Sprintf("%s/users/%d", apiBase, id)
+	route := fmt.Sprintf("/users/%d", id)
 	inf, err := to.get(route, header, &data)
 	return data.Response, inf, err
 }
@@ -66,7 +66,7 @@ func (to *Session) GetUserByID(id int) ([]tc.User, ReqInf, error) {
 
 func (to *Session) GetUserByUsernameWithHdr(username string, header http.Header) ([]tc.User, ReqInf, error) {
 	data := tc.UsersResponse{}
-	route := fmt.Sprintf("%s/users?username=%s", apiBase, url.QueryEscape(username))
+	route := fmt.Sprintf("/users?username=%s", url.QueryEscape(username))
 	inf, err := to.get(route, header, &data)
 	return data.Response, inf, err
 }
@@ -77,7 +77,7 @@ func (to *Session) GetUserByUsername(username string) ([]tc.User, ReqInf, error)
 }
 
 func (to *Session) GetUserCurrentWithHdr(header http.Header) (*tc.UserCurrent, ReqInf, error) {
-	route := apiBase + `/user/current`
+	route := `/user/current`
 	resp := tc.UserCurrentResponse{}
 	reqInf, err := to.get(route, header, &resp)
 	if err != nil {
@@ -97,8 +97,9 @@ func (to *Session) UpdateCurrentUser(u tc.User) (*tc.UpdateUserResponse, ReqInf,
 	user := struct {
 		User tc.User `json:"user"`
 	}{u}
+
 	var clientResp tc.UpdateUserResponse
-	reqInf, err := to.put(apiBase+"/user/current", user, nil, &clientResp)
+	reqInf, err := to.put("/user/current", user, nil, &clientResp)
 	return &clientResp, reqInf, err
 }
 
@@ -126,7 +127,7 @@ func (to *Session) CreateUser(user *tc.User) (*tc.CreateUserResponse, ReqInf, er
 		user.Role = roles[0].ID
 	}
 
-	route := apiBase + "/users"
+	route := "/users"
 	var clientResp tc.CreateUserResponse
 	reqInf, err := to.post(route, user, nil, &clientResp)
 	return &clientResp, reqInf, err
@@ -134,7 +135,7 @@ func (to *Session) CreateUser(user *tc.User) (*tc.CreateUserResponse, ReqInf, er
 
 // UpdateUserByID updates user with the given id
 func (to *Session) UpdateUserByID(id int, u *tc.User) (*tc.UpdateUserResponse, ReqInf, error) {
-	route := apiBase + "/users/" + strconv.Itoa(id)
+	route := "/users/" + strconv.Itoa(id)
 	var clientResp tc.UpdateUserResponse
 	reqInf, err := to.put(route, u, nil, &clientResp)
 	return &clientResp, reqInf, err
@@ -142,7 +143,7 @@ func (to *Session) UpdateUserByID(id int, u *tc.User) (*tc.UpdateUserResponse, R
 
 // DeleteUserByID updates user with the given id
 func (to *Session) DeleteUserByID(id int) (tc.Alerts, ReqInf, error) {
-	route := apiBase + "/users/" + strconv.Itoa(id)
+	route := "/users/" + strconv.Itoa(id)
 	var alerts tc.Alerts
 	reqInf, err := to.del(route, nil, &alerts)
 	return alerts, reqInf, err
@@ -157,6 +158,6 @@ func (to *Session) RegisterNewUser(tenantID uint, roleID uint, email rfc.EmailAd
 		TenantID: tenantID,
 		Role:     roleID,
 	}
-	reqInf, err := to.post(apiBase+"/users/register", reqBody, nil, &alerts)
+	reqInf, err := to.post("/users/register", reqBody, nil, &alerts)
 	return alerts, reqInf, err
 }