Every API that I have ever signed up with gives you a secret key that you can then paste into your application. They know the key, and so do you. (The one exception may be VAPID for Web Push).
Why is this the case? Some apps and protocols already give users a public/private key pair, and store only the public keys in the database row for the user. The user then signs requests with their corresponding private keys, which are never supposed to leave the device. (Nevermind that in Web3 wallets, you can typically export a private key, I think this is a bad design decision that enables all kinds of phishing and scams.)
Now, I understand that for encryption, we do need to send a symmetric key alongside a payload, to decrypt it. But for simply signing a payload, wouldn't we be able to just hash it and sign the hash with the private key?
The only rationales for using symmetric keys I can think of, have terrible flaws:
Agency. Since the platform is doing the work anyway, then what's the harm in it also knowing the symmetric key? Well, there are two problems with this. One is that if the platform's database is compromised, all the secrets are leaked. Second is that the platform may impersonate the app, pretending that the app signed something when it didn't. It's one thing to make a change in the database's state, it's another to claim that an app or user asked you to do it.
Quantum Resistance. When quantum computers are capable of breaking elliptic curve cryptography, etc. then anyone with sufficient resources can impersonate an app's requests. Well, this is true, but when the time comes we can switch to using SPHINCS+ which is also based on hashes, or perhaps lattice-based cryptography. It's true that we'll need time for apps to switch, but unless you're building a distributed protocol, you can force their hand by simply changing the platform.
Old versions of PHP don't support public key cryptography out of the box, and we don't want our users to have to install custom PHP extensions. I could understand this rationale specifically for Wordpress, Discourse, and other open source platforms that are meant to be self-hosted. But now all the languages do support it out of the box. So what's the problem? Plus, most APIs are run by centralized companies, so this was neevr an issue.
In short, I do not understand why APIs use shared secrets instead of public keys for their API clients.