On request, the client attaches the key. The common patterns are an HTTP header (Authorization: Bearer sk_live_... or x-api-key: ...), a query string parameter (?api_key=...), or a request body field. Headers are preferred because URLs get logged in server access logs, proxies, and browser history, leaking the key.
The server receives the key, hashes or looks it up against its store, and resolves it to an account, a set of permissions (scopes), and a quota. If the key is missing, unknown, revoked, or over its rate limit, the server returns 401 Unauthorized or 429 Too Many Requests. If valid, the request proceeds and the server increments that key's usage counter for billing and analytics.
Good platforms store only a hash of the key, not the raw value, the same way they store passwords. They show you the full key once at creation and never again. They also let you create multiple keys per project so you can rotate or revoke one without breaking everything, and restrict keys by IP address, referrer domain, or allowed API method.
The fundamental weakness is that a key is a bearer token. Anyone who has the string can use it. There is no challenge, no signature over the request body, no proof of identity beyond possession. If the key leaks, the holder is you as far as the API is concerned, until you revoke it.