Skip to content
P
API for partners
Connecting your application — access, authentication and endpoints
API for partners / Authentication

Authentication#

Every API request carries an application key. A user token is added on top when the application acts on behalf of a signed-in person. The two apply together — they are not alternatives.

What Header Who it is Required
Application key X-API-Key: <key> your application (partner integration, mobile app) yes, on every request
User token Authorization: Bearer <token> a signed-in person no

Without a token the call is evaluated as an anonymous visitor (role guest): the application sees what an anonymous visitor of the website sees — public lists, articles and adverts with masked personal data. With a token the call is evaluated with that user's roles, within the roles allowed to the application.

# as an anonymous visitor
curl "https://your-site.com/api/blog/article/get-all?limit=5" \
  -H "X-API-Key: $API_KEY"

# as a signed-in user
curl "https://your-site.com/api/blog/article/get-all?limit=5" \
  -H "X-API-Key: $API_KEY" \
  -H "Authorization: Bearer $TOKEN"

Application key#

The key is the X-API-Key header and is used over HTTPS only. It identifies the application, not a user. It has the form coolcms_ followed by 64 hexadecimal characters.

How to get a key#

  1. Ask the website administrator for a key for your application.
  2. The administrator creates the application in Settings → Applications with Api access and sets its allowed roles and limits. The steps for them are in Applications with Api access.
  3. They hand the key over to you. Store it where your application will read it from.

The full key is shown only once

The administrator sees it in full only when the application is created or a new key is issued. The system stores only a hash, so a lost key cannot be displayed again — only replaced with a new one. The administration shows just the first 16 characters to tell keys apart.

Disabling, another key, expiry and revoking#

An application can have several keys (at most 5 valid) and each key can have an expiry — a date and time when it stops working. The administrator can disable the application and enable it again, issue it another key, set or clear a key's expiry, revoke a key or revoke the whole application permanently. The change applies immediately:

What the administrator does What your application gets
disables the application 401 with code 501 on every request (with any of its keys) until it is enabled again
issues another key the existing keys keep working; you deploy the new key when it suits you
sets an expiry on a key the key works until that moment, then returns 401 with code 501
revokes a key that key returns 401 with code 501 at once; the other keys of the application keep working
revokes the application 401 with code 501 for good with all its keys; a revoked application cannot be enabled or given a key

An expired key gets the same response as an unknown key. If an application that used to work suddenly gets 401 with code 501, contact the website administrator. Request limits belong to the whole application, not to a single key — all keys of the application share them.

Replacing the key#

A key can be replaced without an outage: the administrator sets an expiry on the old key, issues you a new key and you deploy it; both work until the expiry. Plan for this when you build the application:

  • Read the key from configuration, not hard-coded — on a server from an environment variable or a configuration file, so that replacing the key does not need a new code deployment.
  • A mobile app usually has the key in the build, so replacing it means a new version. Agree with the administrator on an expiry for the old key with enough margin for the app store review of the new version and for users to stop using the old one.

Handling the key#

  • Server to server: keep the key secret on your server, out of the repository and out of logs. Do not send it to a browser or into a phone app.
  • Mobile apps and browser scripts: a key shipped inside an app is not secret — anyone can extract it. On its own it therefore gives only anonymous-visitor access. The real boundary remains the signed-in user's rights.
  • A leaked key gives a stranger only what an anonymous visitor of the website sees, and it uses up your application's limits. Ask the administrator for a new key and to revoke the leaked one — a revoked key stops working at once.

The key never widens a user's rights, it can only narrow them

Only the roles the administrator allowed to the application apply through it. A website administrator who signs in through a partner application without the admin role has only a regular user's rights there. See Roles allowed per application.

When the key is missing or invalid#

A missing, wrong, disabled, revoked or expired key always returns the same response — HTTP 401:

{"success":false,"message":"A valid application key (X-API-Key) is required.","data":null,"code":501}

The response intentionally does not say which case it was. Code 501 is API_UNAUTHORIZED. Do not confuse it with 103 (the user token is invalid or expired) or with 400 (permission denied, HTTP 403).

Endpoints that need no key#

Four addresses are called by third parties that cannot send a key. They do not require one:

Address Called by
/api/system/payment/execute the payment gateway (notification and customer return)
/api/system/payment/delivery the gateway or SMS aggregator — delivery notifications
/api/system/payment/express-execute the aggregator of express SMS payments
/api/system/auth/oauth-deauthorize-callback the sign-in provider — authorisation revoked

Partner applications do not call them. Everything else, including sign-in, token refresh and sign-out, requires the key.

The website and administration need no key

They call the API internally, without HTTP. The key concerns external applications only.

JWT — user identity#

Sign-in, refresh and sign-out are ordinary API calls, so they carry the application key too.

Endpoint What it does
POST /api/system/auth/login signs in, returns a token pair
POST /api/system/auth/refresh refreshes the pair
POST /api/system/auth/logout signs out
GET /api/system/auth/me the signed-in user's profile
GET/POST /api/system/auth/is-auth-valid verifies a token from the Authorization header or from the body (token)

You sign in with a username or an e-mail

The field is called username but accepts both. A value shaped like an e-mail is looked up among e-mails first, only then among usernames.

Sign-in via a third-party service has no HTTP wrapper

Google, Facebook and other providers are verified on the website, which checks the identity directly with the provider. No endpoint accepts a finished result from outside — a bare "provider and identifier" would be enough to take over someone else's account.

The request body#

Form encoding, not JSON

The authentication endpoints (login, refresh, logout) read only a form-encoded body. A JSON body is not read.

The header#

X-API-Key: <application key>
Authorization: Bearer <access token>

An invalid token is not replaced by guest access

If Authorization is absent, the caller is a visitor. If the token is invalid, expired or revoked, however, the API returns 401 with code 103, not a silent guest access. The application must refresh the token or sign in again. The exception is the public actions that do not read the token from the header (sign-in, token refresh, forgotten password) — they are always evaluated as a visitor.

Lifetimes#

Token Lifetime
Access 15 minutes
Refresh 60 days, rotated

Rotation and theft detection#

Every refresh returns a new pair. The old refresh token stops working.

Using an old refresh token invalidates the whole chain

The system treats it as theft and signs you out too. The response carries code 103. Always store the most recently returned pair.

When a token stops working early#

Signing out puts the access token on a deny list. Blocking or deactivating the account, a password change or reset (also by an administrator) and an account deletion request additionally invalidate all tokens issued to the account so far — access and refresh.

Your client must handle a 401 at any time

Not only after fifteen minutes. Signing out on another device, a password change or a blocked account invalidates the token at once.

A refused sign-in#

Situation Response
unknown account or wrong password code 110 — both alike, so it cannot be learned which account exists
inactive account code 109, only after a correct password
blocked account code 104, only after a correct password
account pending deletion code 117; data.scheduledAt carries the deletion date (other data items serve the website)
deleted account code 110 — the original username and e-mail no longer lead to the account
too many failures HTTP 429, see Limits

A token refresh for an inactive, blocked or pending-deletion account returns code 102.

Account deletion is not started from the API

The request, confirmation and cancellation of an account deletion run on the website. An account pending deletion cannot sign in during the grace period; a deleted (anonymized) account cannot be saved — user/save returns 120.

Changing and resetting the password#

Passwords and keys only in the POST body, never in the URL

A URL ends up in server and proxy logs and stays in history. The actions below read passwords, keys and tokens only from the body (form or JSON); the same value in the URL is ignored and the action ends as if it were missing.

Changing the signed-in user's password#

POST /api/system/user/update-password with the Authorization header:

Body field Meaning
currentPassword the current password — required
password the new password, at least 8 characters
Result Code
changed 0; data carries a new pair token, refreshToken and payload
missing or wrong current password 108
new password too short 611
too many wrong attempts 404

Store the new token pair after a password change

The change revokes every existing refresh token of the account, yours included. A client that does not store the new pair is signed out when its access token expires. Other devices must sign in again.

Forgotten password#

  1. /api/system/user/send-new-password?username=… sends the account's e-mail a link to set a new password, valid for an hour. The password itself does not change and the response is always the same, whether the account exists or not.
  2. The link leads to a website page. The password is set by POST /api/system/user/reset-password with the body fields email, key and password. An invalid, used or expired key and an unknown e-mail return one code, 112; a short password 611. On success every token of the account is revoked.

Verifying a token#

is-auth-valid takes the token from the Authorization: Bearer header, otherwise from the body field token. A token in the URL is not read and the response is 103.

Failed attempts#

They are written to the audit log and to a table. The sign-in endpoint has a limit of 5 failed attempts per 5 minutes per account and address pair, and 20 failed attempts per hour per account from all addresses.

Cookie settings