Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

urljoin removes /v1 when the endpoint reference begins with a slash: that slash makes it an absolute-path reference, replacing the base URL’s path. For example, joining https://api.example.test/v1 and /items produces https://api.example.test/items. To preserve the prefix with a relative endpoint, make the base path directory-like by ending it with a slash and use an endpoint without a leading slash.

Why does urljoin remove my /v1 API prefix?

urllib.parse.urljoin(base, url) resolves the second argument as a URL reference against the first. A reference beginning with / is an absolute path: it replaces the base URL’s entire path rather than appending to it. Python’s official urllib.parse documentation describes this behavior, which follows the URI resolution rules in RFC 3986.

from urllib.parse import urljoin

base = "https://api.example.test/v1"
urljoin(base, "/items")
# 'https://api.example.test/items'

The resulting path is /items, not /v1/items, because the leading slash tells the resolver to start at the root of the host.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I preserve a base path when joining URLs in Python?

Use a trailing slash on the base path and a relative endpoint without a leading slash. The trailing slash makes /v1/ the directory-like base for the next path segment.

base = "https://api.example.test/v1/"
urljoin(base, "items")
# 'https://api.example.test/v1/items'

Both details matter. If the base is https://api.example.test/v1 without a final slash, a relative reference such as items is resolved as though v1 were the last file-like segment, so it is replaced. If the endpoint starts with /, it replaces the base path regardless of whether the base ends with a slash.

Which URL forms preserve the version prefix?

Base URL Endpoint Resolved path Why
https://api.example.test/v1 /items /items Leading slash replaces the base path.
https://api.example.test/v1/ items /v1/items Relative endpoint is merged beneath the slash-terminated base path.
https://api.example.test/v1 items /items Without the trailing slash, the final base segment is replaced.

These results follow the URL-resolution rules documented by Python and RFC 3986. For an API client, settle on one convention—typically a slash-terminated base URL and endpoint paths without leading slashes—and apply it consistently.

How should I verify the URL before sending a request?

  1. Inspect the configured base URL. Record its scheme, host, and path, including whether the path ends in /.
  2. Inspect the exact endpoint string. Check whether it begins with / and whether it contains a scheme or hostname.
  3. Resolve and inspect the complete URL. Confirm that the result has the expected host and /v1 path before the request is sent.

If a request loses the prefix, a leading slash in the endpoint is a likely explanation, but the exact cause depends on the actual base and endpoint strings. Check the final prepared request URL as well as the values passed to urljoin; another layer of the client may transform the URL afterward.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can the second argument change the host or scheme?

Yes. A fully qualified URL in the second argument can replace the base URL’s scheme or hostname, not just its path. Python’s documentation warns: “Because an absolute URL may be passed as the url parameter, it is generally not secure to use urljoin with an attacker-controlled url.” If the endpoint can come from a user or another untrusted source, validate the resolved scheme, authority, and path before making the request. See the Python documentation’s security warning.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Does the Python version matter?

Python’s documentation says urljoin behavior was updated in Python 3.5 to match RFC 3986 semantics. The rule behind the lost-prefix example is therefore the documented behavior for current Python versions; code running on an older version may have different resolution details. Consult the Python 3.14.7 reference for the current documented behavior.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.