Last reviewed: 2026-07-15
Direct answer
Verify authorization before fallback routing with three separate checks: a real-key success request, an intentionally invalid-key request, and a valid-key request missing one required body field. In a bounded CometAPI validation with eight contract requests plus one model-catalog preflight, the real-key Responses and non-streaming Chat requests returned usable 200 responses; the invalid credential returned 401; and missing messages or input returned 400 with code=invalid_request. These results prove that the tested client can distinguish success, authentication failure, and request-shape failure. They do not prove uptime, latency, quota, or production readiness.
Keep endpoint families separate. Chat Completions uses messages and returns a chat.completion object. Responses uses input and returned a response object with status completed. A fallback client that sends the right bearer token to the wrong endpoint shape can still fail before model work begins.
Who this is for
This guide is for engineers responsible for gateway configuration, fallback promotion, secret injection, and incident reproduction. Run the checks from the same network and client stack used by the intended route, but keep the prompt non-sensitive and the request count bounded.
Key takeaways
- The tested API base was
https://api.cometapi.com/v1with bearer-token authorization. - Responses with
gpt-5-nano-2025-08-07returned HTTP 200, objectresponse, statuscompleted, and usable content. - Non-streaming Chat Completions with
gpt-4.1-nanoreturned HTTP 200, objectchat.completion, finish reasonstop, and usable content. - An intentionally invalid bearer token returned HTTP 401 with error keys
code,message, andtype. - A valid-key request missing
messagesorinputreturned HTTP 400 withcode,message,param, andtype; the observed code wasinvalid_request. - Do not include a real key, request ID, full prompt, full response, or commercial data in shared validation notes.
These point-in-time observations are backed by the sanitized eight-case contract evidence artifact , not inferred from HTTP status alone. The artifact also records the one-request ceiling deviation caused by counting the authenticated model-catalog preflight separately.
Contract details to verify
| Contract area | Value or assertion | Evidence |
|---|---|---|
| API base | https://api.cometapi.com/v1 | CometAPI docs |
| Endpoint paths | /chat/completions and /responses use different body contracts | Chat reference and Responses reference |
| Authorization header | Authorization: Bearer ${COMETAPI_KEY} from a secret source | Official references above |
| Required fields | Chat requires messages; Responses requires input; both require a model | Endpoint references above |
| Success contract | Require the endpoint-specific object, terminal state, and usable content | Sanitized run |
| Controlled errors | Invalid bearer: 401; omitted required field: 400 in this run | Sanitized run; exact message wording is not asserted |
| Streaming | Envelope completion is insufficient without content | Sanitized negative sample; streaming promotion remains held |
| Model IDs | Recheck /v1/models before execution | Model catalog and sanitized run preflight; future availability is not asserted |
| Rate limits and billing | Not asserted; verify in the current account and product documentation | Outside this authorization test |
Run the success check
Set the key without printing it, then run one minimal Chat request:
curl --fail-with-body --silent --show-error \
https://api.cometapi.com/v1/chat/completions \
-H "Authorization: Bearer ${COMETAPI_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-4.1-nano",
"messages": [{"role": "user", "content": "Reply exactly: OK"}],
"max_completion_tokens": 64
}'
The minimum pass is not merely HTTP 200. Assert the top-level object, one choice, assistant content, and a terminal finish reason. The sanitized observed record was:
{
"endpoint_family": "chat_completions",
"http_status": 200,
"object": "chat.completion",
"finish_reason": "stop",
"content_assertion": "passed"
}
For a Responses route, change both the path and body contract:
curl --fail-with-body --silent --show-error \
https://api.cometapi.com/v1/responses \
-H "Authorization: Bearer ${COMETAPI_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-5-nano-2025-08-07",
"input": "Reply exactly: OK",
"max_output_tokens": 64
}'
The observed Responses contract was HTTP 200, object response, status completed, with the content assertion passing.
Run the invalid-authorization check
Use a fixed invalid value, never a modified copy of the real credential:
curl --silent --show-error \
https://api.cometapi.com/v1/chat/completions \
-H 'Authorization: Bearer intentionally-invalid' \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-5-nano-2025-08-07",
"messages": [{"role": "user", "content": "Reply exactly: OK"}],
"max_completion_tokens": 8
}'
The expected and observed classification is HTTP 401 with a parseable error object. Assert the presence of code, message, and type; do not assert the exact human-readable message because wording can change.
{
"http_status": 401,
"error_fields": ["code", "message", "type"],
"fallback_decision": "hold"
}
Separate authentication from request-shape errors
After the 401 check, restore the real secret source and deliberately omit messages:
curl --silent --show-error \
https://api.cometapi.com/v1/chat/completions \
-H "Authorization: Bearer ${COMETAPI_KEY}" \
-H 'Content-Type: application/json' \
-d '{"model": "gpt-5-nano-2025-08-07"}'
The corresponding Responses negative test omits input. Both observed requests returned HTTP 400, included code, message, param, and type, and used code=invalid_request. That is evidence the credential was accepted far enough for request validation and that the client can distinguish malformed input from failed authorization.
Authorization assertion table
| Check | Expected | Observed | Route decision |
|---|---|---|---|
| Chat success | 200 plus usable chat content | Passed | Continue contract checks |
| Responses success | 200, completed response, usable content | Passed | Continue contract checks |
| Invalid bearer token | 401 and structured error | Passed | Hold; fix credential source |
Missing messages | 400, invalid_request, param | Passed | Hold; fix Chat body |
Missing input | 400, invalid_request, param | Passed | Hold; fix Responses body |
Streaming boundary
Do not infer streaming readiness from the non-streaming checks. Two separate Chat SSE probes returned HTTP 200, three chunks, and [DONE], yet produced no content and finished with length at a 64-token cap. That is a negative content sample. Keep streaming promotion disabled until a later bounded run returns usable content and passes parser assertions.
Failure modes and boundaries
- Stop if the runtime reads a key from an unexpected environment, file, or account scope.
- Do not retry a 401 as though it were a provider outage; repair authorization first.
- Do not treat a 400 missing-field result as model unavailability.
- Do not log the bearer token, full prompt, full output, or request identifiers.
- Do not use these calls to claim price, balance, quota, latency, uptime, or universal model behavior.
For response-field assertions, use How to Use Response Contract Evidence to Harden LLM API Failover . Before promotion, complete Build a CometAPI Fallback Evidence Checklist .
Sources checked
- CometAPI documentation — accessed 2026-07-15 for the API base and authentication context.
- Chat Completions reference — accessed 2026-07-15 for the Chat contract.
- Responses reference — accessed 2026-07-15 for the Responses contract.
- CometAPI model catalog — accessed 2026-07-15 before selecting the bounded test models.
- CometAPI help center — accessed 2026-07-15 for escalation context.
- Sanitized eight-case contract evidence artifact — accessed 2026-07-15 for bounded success, authorization-error, request-shape, usage, and streaming evidence.
Reader next step
Compare CometAPI models , then create or review the API key used by the controlled client.
FAQ
Should fallback trigger on a 401?
No. A 401 is an authorization boundary, not evidence that another model route is healthy. Hold the route and fix the credential source.
Can the same request body test both endpoint families?
No. Chat requires messages; Responses requires input. Test and assert them separately.