Last reviewed: 2026-10-16
Direct answer
Disable automatic redirect following on authenticated CometAPI generation requests. Treat an unexpected 3xx response as a route-contract exception: stop the current attempt, retain a sanitized status and route revision, and review the destination before sending another request. A redirect can change a POST into a GET or replay its body to another destination. Neither outcome should be hidden inside a successful-looking fallback call.
The CometAPI quick start
documents an HTTPS API base at api.cometapi.com with the /v1 path and sends a bearer-authenticated POST to /v1/chat/completions. Configure that complete endpoint deliberately. The policy here is zero automatic redirect hops for this generation route; an endpoint migration goes through configuration review and readiness checks.
RFC 9110 , section 15.4, explains why the distinction matters. A client may change POST to GET after 301 or 302, while 307 and 308 identify method-preserving redirects. A 303 points to a different resource for retrieval. These are HTTP semantics, not permission to disclose a prompt or credential to a new recipient.
Who this is for
This guide is for gateway maintainers, SREs, and SDK owners operating authenticated LLM POST requests through CometAPI. It is useful when a proxy, ingress rule, SDK upgrade, or endpoint configuration can introduce an unexpected redirect. The examples cover non-streaming Chat Completions. An asynchronous API with a documented 303 result-retrieval workflow needs its own contract.
This is a recommended client policy, not a report of an observed CometAPI redirect incident. No authenticated provider requests were made for this guide. The local test below uses synthetic requests and an in-memory transport.
Key takeaways
- Set redirect behavior explicitly at the request boundary, including when a shared client has a different default.
- Preserve the distinction between method-changing redirects and redirects that can resend the generation body.
- Review the complete destination: scheme, hostname, effective port, endpoint path, and permitted query fields.
- Keep the credential and prompt disclosure decisions separate. Removing authorization does not remove the body.
- Count any authorized replacement request against the original operation’s attempt and time budgets.
- Test the number of outbound requests, not just the exception eventually returned.
Contract details to verify
Start with one record for the route: complete endpoint, POST method, JSON body family, credential source, redirect policy, timeout owner, and configuration revision. Inventory every component that can follow a redirect. An application setting cannot control a sidecar that independently follows upstream responses before returning them to the application.
| Response | Relevant HTTP behavior | Recommended action for this generation route |
|---|---|---|
| 301 or 302 | POST may become GET when followed | Hold the route and review the endpoint configuration |
| 303 | Identifies another resource for a retrieval request | Reject as an unexpected generation envelope; use a separately documented retrieval flow where applicable |
| 307 or 308 | Preserves the request method when followed | Block automatic body replay and review the destination |
| 304 | Concerns a stored representation, not an endpoint move | Reject for this fresh generation POST contract |
| Other 3xx | Does not satisfy the expected success envelope | Stop and classify before any further send |
The RFC supports the protocol distinctions; the hold decisions are this guide’s recommendation. A 307 or 308 does not establish idempotency, recipient authorization, or model compatibility. A permanent redirect also does not authorize a gateway to rewrite its production configuration from a response header.
Check the full origin as a scheme, hostname, and effective port tuple, as defined in RFC 9110 section 4.3.1. Then check the endpoint path separately. A same-origin redirect can still lead to a login page or another API family. Resolve relative locations with a URL parser during controlled investigation; a reference beginning with // can select a different host. Keep that parsing separate from any production send.
Block redirects at the HTTP boundary
HTTPX’s QuickStart
documents that redirects are disabled by default for all methods, and that follow_redirects can change the behavior. Make the request-level choice visible so a shared client’s defaults cannot silently enable following:
import httpx
ENDPOINT = str(
httpx.URL(
scheme="https",
host="api.cometapi.com",
path="/v1/chat/completions",
)
)
class UnexpectedRedirect(RuntimeError):
pass
def post_chat(client: httpx.Client, payload: dict, api_key: str) -> dict:
response = client.post(
ENDPOINT,
headers={"Authorization": f"Bearer {api_key}"},
json=payload,
follow_redirects=False,
timeout=httpx.Timeout(20.0, connect=5.0),
)
if 300 <= response.status_code < 400:
raise UnexpectedRedirect(
f"route_redirect_blocked status={response.status_code}"
)
response.raise_for_status()
return response.json()
Pass a server-side credential and a validated payload whose model is approved for this route. The helper deliberately rejects every 3xx envelope, including 304. Its exception contains a bounded status, without copying Location, headers, response content, or credentials into the message.
This helper establishes the redirect boundary only. The caller still needs response-size limits, a Chat Completions response validator, and a policy for other HTTP and network errors. A JSON response is not by itself usable model output. The HTTPX timeouts shown are network-operation limits; the surrounding gateway must enforce the original end-to-end deadline. A generic retry handler must recognize UnexpectedRedirect as a routing hold rather than a transient error.
For curl-based checks, the curl manual
documents --location for following, --no-location for disabling it, and --location-trusted for permitting secrets to cross origins. Its header section explicitly describes the special treatment of Authorization and Cookie. Keep automatic following disabled on this route. Adding --location-trusted to fix a redirected authentication failure expands credential disclosure instead of repairing the endpoint contract. curl also documents POST-to-GET behavior for 301, 302, and 303; options and explicit method overrides can alter it, so inspect the actual invocation.
Prove that a redirect causes no second send
Run this check with the helper above and HTTPX installed. The transport returns a redirect to an unapproved synthetic destination. The client default intentionally enables following, so the test exercises the request-level override:
def check_redirects():
unapproved = httpx.URL(
scheme="https", host="unapproved.invalid", path="/collect"
)
for status in (301, 302, 303, 307, 308):
sent = []
def upstream(request):
sent.append(request)
return httpx.Response(
status,
headers={"Location": str(unapproved)},
)
with httpx.Client(
transport=httpx.MockTransport(upstream), follow_redirects=True
) as client:
try:
post_chat(client, {"model": "fixture", "messages": []}, "fake-key")
except UnexpectedRedirect as exc:
assert str(exc) == f"route_redirect_blocked status={status}"
else:
raise AssertionError("redirect was accepted")
assert len(sent) == 1
assert str(sent[0].url) == ENDPOINT
check_redirects()
Checked locally on 2026-10-16 with HTTPX 0.28.1: all five status cases raised the expected exception, and each made exactly one mock send to the configured endpoint. No network connection or live API key was involved. The fixture’s empty messages and fixture model test transport control only; they are not a valid provider readiness request.
Extend the same assertion through the deployed gateway and sidecar in a controlled environment. Include same-origin path changes, relative locations, scheme downgrades, a different port, missing Location, and redirect loops. For a zero-hop policy, every case should end without a second upstream send. Inspect the upstream recorder as well as the application result, because a final error can otherwise conceal an earlier disclosure.
Happy-path operator workflow
Load the reviewed endpoint and its credential binding from server-side configuration. Send one validated POST with redirect following disabled. Require the endpoint-specific success envelope and usable content before accepting the result. Record the route revision, status class, elapsed time, and terminal outcome.
Verify the route with the same network path and client settings that will carry user traffic. Use the site’s authorization and endpoint readiness checks as a workflow reference, then rerun the checks for the current configuration. Historical successful calls cannot establish today’s account or endpoint readiness.
Error-path operator workflow
On a 3xx response, close the current attempt without following it. Emit a sanitized route_redirect_blocked event with the status, approved route ID, configuration revision, and attempt number. Keep Location out of routine logs: it can contain sensitive query parameters. The fallback telemetry redaction guide
explains how to build those events from allowed fields.
Have the route owner compare the configured endpoint with current official instructions and the relevant ingress rules. Investigate the destination in a controlled environment using synthetic data and appropriately scoped test credentials. Validate scheme, full origin, exact API path, TLS identity, credential audience, and request/response compatibility before approving a replacement configuration. Retain the TLS verification contract when the destination changes.
A replacement send is a new attempt within the existing user operation. Check the remaining deadline, attempt allowance, and whether the first request could already have caused work. A 3xx alone is not evidence that generation was free, absent, or safely repeatable. Apply the request replay and unknown-outcome checks before another provider call. A separately approved fallback may remain eligible, but the arbitrary redirect destination must not become that fallback automatically.
Failure modes
A shared client enables following. Keep the request-level setting and the one-send test. Recheck wrapper clients and SDK upgrades that construct their own HTTP transport.
Authorization is stripped but the prompt is resent. Credential filtering and request-body filtering are different controls. A method-preserving redirect can disclose the body even when the new request lacks the bearer token.
A trailing-slash correction is waved through. A small path difference can still change the resource. Fix the configured endpoint after review instead of admitting a general redirect exception.
A redirect becomes a generic retry. Map the routing exception before broad retry handling. Repeatedly sending to the original URL can create a loop without following a single redirect.
Only the final status is monitored. A final 200 can hide an intermediate method or destination change. Require zero upstream redirect hops for this route, and verify that requirement where upstream connections are made.
FAQ
Are 307 and 308 safe because they preserve POST?
They preserve method semantics when followed. They do not authorize the recipient or establish that replay is safe. The generation body still needs a disclosure decision.
Can a same-origin redirect be accepted automatically?
This policy holds it for review. Origin equality does not prove that the destination path implements the intended API or preserves the response contract. Updating the reviewed endpoint is easier to audit than accumulating redirect exceptions.
Should every 303 be treated as a provider outage?
No. It is an unexpected envelope for this configured generation POST. A documented job API may intentionally use 303 to retrieve a result from another resource; implement that separate flow according to its authentication and retrieval contract.
Does the mock test prove production behavior?
It proves the shown HTTPX helper’s request-level redirect control in the tested version. It does not exercise DNS, TLS, an ingress, a sidecar, or provider processing. Run the controlled integration cases through those components before relying on the policy.
Reader next step
Pick one authenticated generation route, make its zero-hop redirect setting explicit, and add the five-status one-send check. Then force a redirect through the complete staging path and confirm that neither the gateway nor its proxy contacts the supplied destination. Assign an owner for endpoint migrations and record the readiness evidence required before a replacement send.
When that contract is ready, Start with CometAPI and apply the same destination, credential, and replay checks to the integration.
Sources checked
- CometAPI quick start — accessed 2026-10-16; page marked last modified July 13, 2026. Supports the configured base URL, Chat Completions example, bearer authorization, and server-side key handling.
- RFC 9110: HTTP Semantics — accessed 2026-10-16; June 2022 standard, especially sections 4.3.1, 10.2.2, and 15.4. Supports origin comparison, redirect semantics, method changes, relative locations, sensitive-header considerations, and loop detection.
- HTTPX QuickStart
— accessed 2026-10-16. Supports default redirect behavior,
follow_redirects, response history, HTTP status handling, and the distinction between network timeouts and successful responses. - curl manual — accessed 2026-10-16. Supports redirect options, POST method handling, and credential/header behavior across origins.
These are stable protocol and official client references checked live for this task. Their publication dates do not establish a new provider event; the guide applies their current documented behavior to a specific routing control.