Authenticating with a Personal Access Token
A Personal Access Token is sent as an HTTP bearer token. There is nothing to sign, no timestamp, no nonce and no request-body hash — the whole of the authentication is one header.
The Authorization header​
GET /public/account/rest/v1/accounts/EVP1234567890/full-balance HTTP/1.1
Host: api.paysera.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
The Bearer scheme is required, and the token must follow it after whitespace. Send it as Bearer
or bearer — the gateway accepts those two spellings only, so a client that upper-cases the whole
scheme (BEARER) is rejected even though HTTP itself treats the scheme as case-insensitive. A
request with no Authorization header, or with a different scheme such as MAC, is rejected with
401 missing_token.
Base URL​
Production: https://api.paysera.com
The token described in this guide is accepted only on api.paysera.com. The same paths on other
Paysera API hosts are served by integrations that expect MAC or SSL client certificate
authentication, and they will not accept this bearer token. If a request that works against
api.paysera.com fails elsewhere, check the host first.
The POS API calls its credential a Personal Access Token too, but it is
a different credential from a different system: issued in the POS application at
pos.paysera.com/user/settings, sent to pos.paysera.com, and carrying its own permissions. The two
are not interchangeable. If you are integrating POS, follow the POS guide.
There is no sandbox for Personal Access Tokens. Test against production with a token that is scoped narrowly and carries a small spending limit — see Token controls.
What is checked on every request​
Your token passes through the API gateway before it reaches the service. On each request, in order:
The first four checks happen at the gateway. The scope check happens in the service that owns the endpoint, which is why a scope failure looks slightly different from a token failure — see Errors and limits.
Scopes​
A token carries one or more scopes, chosen when you create it. Each endpoint requires exactly one:
| Scope | Grants |
|---|---|
accounts:read | Read account balances |
statements:read | Read account statements |
transfers:read | Read individual transfers and filter the transfer list |
transfers:create | Create and register transfers, set and read the token's spending limits |
transfers:cancel | Cancel transfers |
Scopes are additive and independent, and a token can hold read scopes only. A token that carries
accounts:read and transfers:read observes without being able to move anything — the right shape
for a reporting script or an assistant that answers questions about your account.
See Available endpoints for the exact scope each endpoint requires.
Account restriction​
Scopes can additionally be tied to accounts when the token is created, so a token that reads balances reads only the accounts you named and is refused on every other account, even one you own. The restriction covers all of the token's scopes, not one of them — see Account restriction for how the pairing works and what an empty account list means.
What is inside the token​
The token is a JWT, so its payload is readable — it is signed, not encrypted. You never need to decode it to make a request, but three claims are worth knowing because other parts of this guide refer to them:
| Claim | Meaning |
|---|---|
jti | The token ID. It is what the interface shows in your token list, and what the GET spending-limit endpoint takes as a path parameter. |
psr:u | Your Paysera user ID, as a string. The POST spending-limit endpoint takes the same value in its user_id field, as a number. |
typ | Always PAT for a Personal Access Token. |
# Decode the payload (the middle segment) of your own token.
# A JWT segment is base64url and carries no padding, so `base64 -d` alone does not read it.
echo "$PAYSERA_PAT" | cut -d. -f2 | python3 -c \
"import base64,json,sys; s=sys.stdin.read().strip(); \
print(json.dumps(json.loads(base64.urlsafe_b64decode(s + '=' * (-len(s) % 4))), indent=2))"
{
"jti": "84923f0a-1c7e-4d55-9a1f-77b0a1f0d9c2",
"psr:u": "123456",
"typ": "PAT"
}
The payload carries further claims that the gateway uses. Of the three above, this guide asks you
for jti and psr:u; typ is listed so you can tell a Personal Access Token from another kind of
bearer token.
Keeping the token secret​
- Send it only over HTTPS to
api.paysera.com. The token is a bearer credential: whoever holds it can use it, within its scopes. - Keep it out of URLs. Query strings end up in browser history, proxy logs and referrer headers — the
token belongs in the
Authorizationheader and nowhere else. - Keep it out of source control, container images, CI logs and error reports.
- Prefer a short expiry and re-issue rather than a token that never expires.
- If a token may have leaked, suspend it immediately from bank.paysera.com/en/personal-access-tokens, then revoke it once you have replaced it.