Authentication
One header. The key names your business, your mode and what you may reach.
#Send your secret key
Authorization: Bearer sk_live_7999df69…Basic with the key as the username also works, because that is what curl -u sends and a developer copying a habit from another gateway should not be stuck:
curl -u sk_live_7999df69...: https://api.paymonetra.com/v1/balance#Two kinds of key
| pk_test_… / pk_live_… | public. Safe in a web page. Names the merchant when a checkout is opened from a browser and can do nothing else. |
| sk_test_… / sk_live_… | secret. Server to server. Creates accounts and starts payments. |
The mode is in the string, so a test key left in production is obvious on sight rather than at the first payment that fails to arrive. Show them differently in the UI as well; the design already does.
#The key decides the mode
The key decides the mode, not the dashboard toggle. A merchant flipping their dashboard to test does not change what their live key does to their production traffic. Verified.
More on what is and is not separated: test mode.
#Three refusals worth knowing
Three refusals worth knowing, because they are the ones a developer hits:
| what they did | what they get |
|---|---|
| no key | 401 "No API key. Send it as: Authorization: Bearer sk_live_..." |
sent a pk_ key | 401 "That is not a secret key. Secret keys start with sk_ and are used server to server; pk_ keys belong in a browser." |
| unknown, revoked or rotated key | 401 "That API key is not valid." |
The third is deliberately one message for all three cases, so the endpoint cannot be used to tell a real key from a guess.
Every other error is on the error reference.
#Which host
| host | who it serves | status |
|---|---|---|
paymonetra.com/api/v1 | the dashboard, and the app | live |
api.paymonetra.com | merchants' own servers | live since 29 Aug 2026 |
pay.paymonetra.com | payers: checkout and payment links | live since 29 Aug 2026 |
Your key only works against https://api.paymonetra.com/v1. Any path outside /v1 on that host answers a JSON 404 rather than reaching anything else, so it cannot be walked into the rest of the application.