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

Permissions and roles#

The system checks on every request whether that identity may perform that action on that resource.

Roles#

Role Who
guest not signed in
registrated a signed-in user
owner the owner of a particular record — a conditional role
receiver the receiver of a particular record — a conditional role
admin an administrator

Roles allowed per application#

The roles that take effect on a call are not up to the user alone. The website administrator chooses which roles the application may use (in Settings → Applications with Api access) — a ceiling above the user's rights. The key itself adds no rights. An application without a token acts as guest (see Authentication); with a token the user's roles are used, but only from the allowed set.

The guest role is always allowed — the administrator cannot remove it. A new application gets this default: guest, registrated and the conditional roles owner (own records) and receiver (records addressed to the user). Administrator (privileged) roles only if the administrator explicitly ticks them. Partner integrations usually get the default roles; the website owner's own mobile app may get all of them.

Ask the website administrator which roles your application has. They cannot be found out from outside.

An administrator through an application without the admin role is a regular user

If an administrator signs in through an application that does not allow the admin role, the API treats them as a regular registered user: admin-only actions are refused (403), and admin-only fields and unmasked personal data of other users are not returned.

Without owner, users cannot edit even their own records

An application that does not allow owner cannot edit even the records of its signed-in user.

The guest role is always allowed

Calls without a token and public actions (sign-in, token refresh, forgotten password) are evaluated with the guest role. Without it a user could not even sign in through the application, so every application always has it allowed and it cannot be removed.

The model is flat#

A missing rule means denial

There is no inheritance and no fallback. If there is no record for a given resource-and-action pair, the action is denied — administrators included, until the rule is added.

A rule key looks like:

:Api:<Module>:<Resource>:<action>

For example :Api:Eshop:Order:updateColumns.

What is public#

Mainly reading is open to visitors who are not signed in (calls with an application key but without a token): articles, pages, code lists, categories and products.

Writing always requires signing in.

The exact list is in the data, not in the code

Which rules are open is a setting of the particular installation. The quickest way to find out is to call the action with the application key alone, without a token — it either passes or you get Permission denied.

Ownership#

The owner role permits nothing by itself. Ownership is verified against the database.

Ownership is never taken from the request

If you send your own user identifier in the data, the system ignores it and on insert fills the owner in from the server.

The receiver#

Next to owner ("the record is mine") there is a second conditional role, receiver ("the record was addressed to me"). It is a separate role: where a record has an author and an addressee, the addressee need not hide under the owner.

owner receiver
It asks is the caller the creator or sender of the record? is the caller the one the record was addressed to?
Example the author of a rating, the sender of a reply to an advert the advert's owner for a reply to it; the owner of a rated profile for a reply to a rating

Like owner it allows nothing by itself. A rule with the role receiver passes only when the check of the given area confirms it against the database. Who the receiver is is never taken from the request.

An unconditional rule wins

If there is an unconditional rule for the same key (say, for registrated), every signed-in user passes and the owner or receiver condition is never evaluated. To limit a right to the owner or receiver there must be no unconditional rule for another role.

Where receiver is used today#

Resource and action The receiver is
response (classifieds and company directory) — get the advert's owner, the holder of the advert password, an administrator; not the author of the reply
rating — save-reply the owner of the rated profile; the author of the rating may not reply

For a reply to an advert (response) also: save (edit) and delete stay with the role owner, which both the sender of the reply and the advert's owner satisfy. Writing the read column (marking as read) is allowed by the receiver check; other update-columns columns are for an administrator only.

Marking from the email does not pass from outside

The Označit jako přečtené (mark as read) button in the email uses a key stored with the reply. It is verified only on the internal path (the site calls the API directly) and is not passed in an HTTP request. If you send the key in the address of an external call it does not help — only signing in (or the advert password) makes you the receiver.

Private messages use owner and receiver on conversations, but without HTTP

Actions on one conversation (read messages, reply, mark read, hide, list participants) use both roles: owner is the one who wrote at least one message in the conversation, receiver the one to whom a message came. These actions are internal — they have no HTTP wrapper and are unavailable from outside. Over HTTP the whole resource is for an administrator only.

🔴 Ownership does not work on collections#

get-all, get-by and bulk deletion are always denied to an owner

You cannot say "give me my records" through a general listing. Dedicated actions exist for your own data — but many of them have no HTTP wrapper and are therefore unreachable from outside. See the CRUD pattern.

What you see of other people's records#

The permission for an action decides whether you reach the record. Which values the response gives you is decided by the field itself as well — even when the entity arrives as a nested relation through includes.

Other users' personal data#

The record owner and an administrator see everything. Everyone else gets other people's personal data according to the installation setting (security.personalDataExposure, default sanitized):

Data Default for another caller
e-mail masked (pet***@p***.cz)
a user's phone, street, postcode, company ID, VAT ID, company name, "about me" empty string
IP addresses (on adverts, responses, posts, votes, payments, orders…) empty string
a user's credits, points, discount and discount level the key is missing from the response

The full mode returns everything, the empty mode empties the e-mail too. Which field is personal data is defined in the code; the operator chooses the mode.

Read a seller's contact from the public profile

What a visitor is meant to see is returned by user/public-profile, and the phone on click by user/show-phone (rate limited). Do not rely on includes=user.

A missing key is not an error

A hidden numeric field is dropped from the row, because an empty string would not be a number. Your parser has to expect it.

Fields that never leave the server#

Some values are needed only by the website inside the server, and nobody gets them over HTTP, not even an administrator with a token: the advert and post password, the activation key of an advert and of a newsletter subscription, the readKey of an advert response, the cart key, the outgoing mail password and the hashes of tokens and API keys. A user's password and salt and one-time tokens (password reset, account deletion) are not read even by the website.

In a response such fields are missing or carry a default value.

Filters and ordering only over fields you may read#

A filter is as good a channel as a response: whoever may filter by a password or an e-mail recovers it character by character. That is why filters (nested groups included), orderBys and columns may target only fields you would also get in the response.

Path Result for a regular user
user.id, orderBys[user.username] passes
user.password, user.salt, activationKey HTTP 400
user.email, insertIp, user.phone (personal data) HTTP 400
a non-existent field (a typo) HTTP 400
{"success":false,"message":"Field path \"user.email\" is not allowed in filters, orderBys or columns.","data":null,"code":2}

An administrator filters without restriction.

Fields you may write#

Writing follows the same logic as reading: besides the right to the action, the field decides. A field your account may not write is silently dropped from data and the original value stays in the database (on insert, the default). An owner thus cannot change the credits, discount or e-mail of their account, nor move their comment or response to someone else's record. The list for your own account is in the CRUD pattern.

Modes#

Mode Behaviour
off no checking
log evaluates and records, denies nothing
enforce denies — the current state

The switch applies to the whole API at once

There is no per-module switch. Expect that permission behaviour may change across the board.

A denial#

{
  "success": false,
  "message": "Permission denied",
  "data": null,
  "code": 400
}

with HTTP status 403.

Code 400 means permission denied, not “bad request”

The numeric codes look strikingly like HTTP statuses but do not correspond to them. See Error codes.

Calls from inside the system#

The website and administration call the same resources through an internal route — without HTTP, by building the request directly, so they need no application key. That does not bypass the permission check: both routes go through the same guard and merely have a switch of their own.

For you as an external client, one conclusion follows

Behaviour you see on the website may not be reachable through the API — not because the website skips the check, but because many actions have no HTTP wrapper. See The CRUD pattern.

The difference between the website and the API is not permissions, but which actions exist

If something the website does will not work through the API, look for a missing endpoint or a missing rule — not for a "website exception".

Cookie settings