BYOKchat Blog

AI API Error 401 vs 403 vs 429: What Do They Mean?

A practical guide to diagnosing AI API 401, 403, and 429 errors, including authentication, permissions, quotas, billing, retries, and rate limits.

· 8 min read

On this page
  1. Quick reference
  2. 401 Unauthorized: authentication failed
  3. A good 401 debugging sequence
  4. 401 can also be a custom-endpoint problem
  5. 403 Forbidden: authenticated, but not allowed
  6. Model access is a common source of 403 errors
  7. 429 Too Many Requests: not always “too fast”
  8. Rate limit vs quota vs capacity
  9. Rate limit
  10. Quota
  11. Capacity throttling
  12. How to retry 429 correctly
  13. 400 Bad Request: the request itself is wrong
  14. 404 Not Found: endpoint or model mismatch
  15. 500, 502, and 503: likely server-side
  16. A practical decision tree
  17. The exact error body is often more useful than the status code
  18. What to record when debugging
  19. A better debugging order for BYOK clients
  20. Example: why changing the key can waste time
  21. Example: why retrying can be dangerous with tools
  22. Preventing errors before they happen
  23. The practical takeaway

When an AI API request fails, the HTTP status code is often the fastest clue to the real problem.

Three codes cause a large share of BYOK connection failures: 401, 403, and 429. They may all appear to the user as “the request failed,” but they usually point to different layers of the system.

The useful mental model is:

401 → authentication
403 → authorization
429 → rate, quota, or capacity

That is only the starting point. The response body, endpoint, provider account, and request details still matter.

Quick reference

CodeUsually meansFirst thing to checkRetrying immediately?
401Credentials were not acceptedAPI key and auth headerUsually no
403Identity is known but operation is blockedpermissions and account/model accessUsually no
429A usage or capacity limit was hitrate limit, quota, credits, spending limitSometimes
400Request itself is invalidpayload and unsupported parametersNo
404Endpoint/model/resource not foundbase URL and model identifierNo
5xxServer or gateway failedprovider health and transient failureOften reasonable

If you only remember one debugging rule, remember this: do not rotate keys, change models, and retry repeatedly before identifying which layer failed.

401 Unauthorized: authentication failed

A 401 generally means the server did not accept the credentials attached to the request.

Typical causes include:

  • no API key was sent;
  • the key was copied incompletely;
  • the key was revoked or rotated;
  • the key belongs to a different provider;
  • the authentication header is malformed;
  • the endpoint expects a different authentication scheme;
  • leading or trailing whitespace was stored with the key;
  • the request is going to the wrong host.

A common BYOK mistake is pairing a valid key with the wrong base URL.

For example:

Key:      valid key for Provider A
Base URL: Provider B endpoint
Result:   authentication failure

Creating another Provider A key will not fix that configuration.

A good 401 debugging sequence

  1. Confirm the final hostname and base URL.
  2. Confirm the selected provider/connection in the client.
  3. Re-copy the credential from the provider dashboard.
  4. Check for whitespace or accidental quotes.
  5. Verify the endpoint’s expected auth header.
  6. Confirm the key has not been revoked.
  7. Try the smallest possible request.

Do not paste the real key into screenshots, issue reports, analytics, or public logs while debugging.

401 can also be a custom-endpoint problem

With an OpenAI-compatible API, authentication may not behave exactly like a first-party provider.

A local server may:

  • require no key;
  • accept a placeholder key;
  • require a real server-defined token;
  • sit behind a reverse proxy that handles authentication;
  • require an additional custom header.

That is why “my API key works elsewhere” is not enough evidence. The credential must be valid for the exact endpoint receiving the request.

403 Forbidden: authenticated, but not allowed

A 403 usually means the service recognized the request’s identity but refuses the requested operation.

Possible reasons include:

  • the account cannot access the selected model;
  • the API is disabled for that project;
  • the key has restrictions that exclude the requested service;
  • an organization policy blocks the operation;
  • the feature requires a different account tier;
  • regional or compliance policy blocks access;
  • the project or organization association is wrong;
  • the provider suspended or restricted the account.

The conceptual difference is useful:

401: I cannot authenticate you.
403: I know who you are, but you cannot do this.

That immediately changes what you should investigate.

With a 403, creating a new key under the same restricted account may reproduce the exact same failure.

Model access is a common source of 403 errors

An account can be valid while one model is unavailable to it.

If Model A succeeds and Model B returns 403 with the same connection, the credential itself is probably not the first thing to blame. Check model access, project policy, and account eligibility.

Similarly, a request may work for plain chat while failing for a protected feature such as file processing, tools, or another API surface.

429 Too Many Requests: not always “too fast”

A 429 is commonly called a rate-limit error, but in AI APIs it can represent several different resource limits.

Examples include:

  • requests per minute;
  • input tokens per minute;
  • output or total tokens per minute;
  • concurrent requests;
  • daily quota;
  • monthly quota;
  • account credits;
  • spending caps;
  • temporary service capacity.

This is why the response body matters.

These two failures can both use 429 but need completely different responses:

Case A:
Too many requests in a short period
→ slow down and retry later

Case B:
Monthly credit or account quota exhausted
→ waiting 30 seconds changes nothing

Blind retries are appropriate for Case A and wasteful for Case B.

Rate limit vs quota vs capacity

These terms are often mixed together.

Rate limit

A rate limit controls how quickly you can consume the API.

Examples:

  • 60 requests per minute;
  • 100,000 tokens per minute;
  • 4 concurrent generations.

Once enough time passes, capacity becomes available again.

Quota

A quota controls how much you may consume over a larger period or allocation.

Examples:

  • daily request allowance;
  • project quota;
  • prepaid credits;
  • monthly usage allocation.

A short retry delay may not help.

Capacity throttling

Sometimes the account is healthy but the provider is temporarily unable to serve the requested traffic at the expected rate.

This behaves more like a transient operational condition. Retrying with backoff may succeed.

How to retry 429 correctly

For transient rate limits, clients should prefer provider-supplied retry information when available.

A reasonable strategy is usually:

  1. respect explicit retry timing if returned;
  2. otherwise wait before trying again;
  3. increase the delay after repeated failures;
  4. add small random jitter so many clients do not retry simultaneously;
  5. stop after a sensible number of attempts;
  6. show the user what is happening.

What a client should not do is instantly replay the same request in a tight loop.

That can:

  • keep the account rate-limited;
  • waste quota;
  • create duplicate generations;
  • produce duplicate tool actions;
  • make a provider outage noisier.

For tool-enabled conversations, retry behavior deserves extra caution because a model round may have already caused an external action before the visible request failed.

400 Bad Request: the request itself is wrong

A 400 usually means the server understood where the request was sent but rejected the payload.

Common causes include:

  • unsupported parameter;
  • malformed message structure;
  • invalid JSON;
  • context or input too large;
  • invalid tool schema;
  • unsupported image/file format;
  • structured-output schema rejected;
  • feature not supported by that model.

When 400 appears after switching models, compare model capabilities before changing authentication.

A model that supports plain text may not support tools, images, or the same generation parameters as another model.

404 Not Found: endpoint or model mismatch

A 404 is especially common with custom endpoints.

It can mean:

  • the URL path is wrong;
  • /v1 is missing or duplicated;
  • the server implements a different API route;
  • the requested model identifier does not exist;
  • the client is calling an endpoint the server does not implement.

For example:

Configured base: https://host.example/v1
Client appends:  /v1/chat/completions
Final request:   https://host.example/v1/v1/chat/completions

The key can be perfectly valid and the result will still fail.

500, 502, and 503: likely server-side

A 5xx response usually indicates the provider, reverse proxy, gateway, or upstream service could not complete a request it otherwise accepted.

Common situations include:

  • provider outage;
  • overloaded server;
  • gateway timeout;
  • upstream model process crashed;
  • local inference server ran out of memory;
  • reverse proxy lost connection to the model backend.

If the exact request worked moments ago and no configuration changed, a transient retry may be reasonable.

If a local server returns 500 repeatedly, inspect the server logs rather than rotating the client credential.

A practical decision tree

Use the status code to choose the next question:

Request failed

├─ 401 → Is the credential valid for this exact endpoint?

├─ 403 → Does this account/project have permission for this model or feature?

├─ 404 → Is the base URL/path/model identifier correct?

├─ 429 → Is this temporary rate pressure or exhausted quota/credits?

├─ 400 → Is the request or selected feature unsupported?

└─ 5xx → Is the provider/server unhealthy or overloaded?

This is much faster than changing unrelated settings randomly.

The exact error body is often more useful than the status code

HTTP status codes are broad categories. Providers frequently include a structured error payload with a more specific code or message.

A useful client should preserve information such as:

HTTP status: 429
Provider: ExampleAI
Model: example-model
Provider code: rate_limit_exceeded
Detail: token limit exceeded for current project

That is far more actionable than:

Something went wrong.

Friendly UI and technical detail do not have to be opposites. A client can summarize the likely problem while still exposing the provider’s diagnostic information.

What to record when debugging

You usually do not need to record the user’s prompt or API key to troubleshoot an API failure.

Useful diagnostic fields include:

  • timestamp;
  • provider/connection name;
  • hostname or endpoint label;
  • model identifier;
  • HTTP status;
  • provider error code;
  • request ID returned by the provider;
  • whether streaming was enabled;
  • retry count;
  • duration before failure.

Avoid putting secrets, full authorization headers, or sensitive prompt contents into logs.

This matters especially in BYOK software because the provider credential belongs to the user.

A better debugging order for BYOK clients

When a request fails, check the layers in this order:

  1. Network — can the device reach the endpoint?
  2. Endpoint — is the base URL and path correct?
  3. Credential — is authentication valid for this endpoint?
  4. Permission — may the account use this model or feature?
  5. Model — is the model identifier valid and available?
  6. Quota — are rate limits, credits, budgets, or concurrency exhausted?
  7. Request — are the parameters and input supported?
  8. Provider/server health — is the service currently failing?

For local servers, add firewall, machine sleep, and server binding to the network checks. For cloud providers, account status and billing are more likely to matter.

Example: why changing the key can waste time

Imagine this sequence:

1. Client sends request.
2. Provider returns 429 quota exhausted.
3. User assumes the key is broken.
4. User creates a new key under the same account.
5. New key uses the same exhausted quota.
6. Request still returns 429.

Nothing was wrong with either key.

The status category already told you to investigate usage limits rather than authentication.

Example: why retrying can be dangerous with tools

Suppose a model requests a tool that creates an external issue, sends a message, or modifies a file.

If the tool succeeds but a later network response fails, automatically replaying the entire model/tool round can perform the action twice unless the system has idempotency or duplicate protection.

Retry logic for ordinary text generation and retry logic for side-effecting tools should not be treated as the same problem.

Preventing errors before they happen

A well-designed BYOK client can reduce avoidable failures by:

  • validating base URLs;
  • separating credentials by provider connection;
  • discovering models when the provider supports it;
  • not exposing unsupported settings for a selected model;
  • clearly identifying the active provider and model;
  • showing quota-related errors without pretending they are auth failures;
  • preserving provider request IDs for debugging;
  • making retry behavior visible.

If you regularly switch among providers, Using Multiple AI Providers in One Workflow explains why keeping connections separate is safer than treating every API as interchangeable.

The practical takeaway

Remember the core categories:

  • 401 = authentication
  • 403 = authorization
  • 429 = rate, quota, or capacity

Then read the provider’s actual error payload before changing anything.

The fastest debugging path is to identify the failing layer first. In a BYOK setup, the chat client controls request construction and error presentation, while account permissions, billing, quotas, and provider-side availability remain properties of the provider account you control.

Keep reading