httpx cookies: client cookies, set cookies, CookieConflict (tested)
Use one httpx.Client (or AsyncClient): its client.cookies jar stores cookies from Set-Cookie and sends them on later requests. Set your own with client.cookies.set("name", "value"); per-request cookies= is deprecated.
httpx keeps cookies only inside a Client / AsyncClient: its client.cookies jar stores Set-Cookie values and sends them back. Measured with httpx 0.28.1 on Python 3.13.5 against a local http.server (srv.py) where /login sets session and theme cookies and every path echoes the Cookie header it received.
1. Response cookies, and why they are not sent back
import httpx
from srv import start
base = start()
r = httpx.get(base + "/login")
print("response cookies:", dict(r.cookies))
# module-level httpx.get() has no memory between calls
print("next call sends: ", httpx.get(base + "/me").json())
Output:
response cookies: {'session': 'abc', 'theme': 'dark'}
next call sends: {'cookie_header': None}
r.cookies holds the cookies one response set. The module-level httpx.get() uses a throwaway client each time, so nothing is remembered between calls.
2. httpx client cookies: a session that remembers
import httpx
from srv import start
base = start()
with httpx.Client(base_url=base) as client:
client.get("/login")
print("jar:", dict(client.cookies))
print("sent:", client.get("/me").json())
Output:
jar: {'session': 'abc', 'theme': 'dark'}
sent: {'cookie_header': 'session=abc; theme=dark'}
3. httpx set cookies on the client
import httpx
from srv import start
base = start()
with httpx.Client(base_url=base, cookies={"consent": "yes"}) as client:
print(client.get("/me").json())
client.cookies.set("lang", "en")
print(client.get("/me").json())
client.cookies.delete("lang")
print(client.get("/me").json())
Output:
{'cookie_header': 'consent=yes'}
{'cookie_header': 'consent=yes; lang=en'}
{'cookie_header': 'consent=yes'}
Pass cookies= to the constructor for starting values, then use client.cookies.set() / .delete() to change the jar.
4. Per-request cookies= is deprecated and not stored
import warnings, httpx
from srv import start
base = start()
warnings.simplefilter("always")
with httpx.Client(base_url=base) as client:
r = client.get("/me", cookies={"one": "off"})
print(r.json())
print("jar after:", dict(client.cookies))
Output:
/tmp/fx384/ve/lib/python3.13/site-packages/httpx/_client.py:1053: DeprecationWarning: Setting per-request cookies=<...> is being deprecated, because the expected behaviour on cookie persistence is ambiguous. Set cookies directly on the client instance instead.
return self.request(
{'cookie_header': 'one=off'}
jar after: {}
client.get(url, cookies=...) still sends the cookie in httpx 0.28.1, but emits a DeprecationWarning (shown here because the block enables warnings) and does not add it to the jar. Set it on client.cookies instead.
5. CookieConflict: same name on two domains
import httpx
from srv import start
base = start()
with httpx.Client(base_url=base) as client:
client.get("/login")
client.cookies.set("session", "other", domain="example.com")
try:
print(client.cookies["session"])
except httpx.CookieConflict as e:
print("CookieConflict:", e)
print(client.cookies.get("session", domain="127.0.0.1"))
Output:
CookieConflict: Multiple cookies exist with name=session
abc
client.cookies["name"] raises httpx.CookieConflict when several cookies share the name (different domain or path). Use client.cookies.get(name, domain=...).
Related: httpx headers, httpx auth, httpx vs requests differences, httpx follow redirects.
Frequently asked questions
How do I keep cookies between requests in httpx?
Use a single httpx.Client or AsyncClient. Module-level httpx.get() does not remember cookies between calls.
How do I set a cookie in httpx?
httpx.Client(cookies={'name': 'value'}) or client.cookies.set('name', 'value'). Per-request cookies= is deprecated in httpx 0.28.1 and is not stored in the jar.
What is httpx.CookieConflict?
It is raised by client.cookies['name'] when several cookies share that name on different domains or paths; use client.cookies.get(name, domain=...).
Written with AI assistance. Measured on 2026-10-23 with httpx 0.28.1 on Python 3.13.5 against a local http.server that sets cookies and echoes the Cookie header. Each block was run verbatim and the output pasted unedited. PlainHeaders is our extension; httpx is free.