FleekSiteFLEEKSITE
On this section
Platform API

Authentication and roles.

Public reads aside, the API asks who you are and what you may do. A request carries a credential, that credential resolves to a user, and the user has a role on the site being addressed. This page covers how to sign a request, how to obtain a token, and what each role is allowed.

Authentication is not enforced at the door. Every request runs the same way: if it carries a credential, the runtime resolves the user and their membership; if it does not, it continues as anonymous. Each endpoint then decides for itself. That is why a public read serves an anonymous caller, while a protected endpoint answers 401 when no credential is present, or 403 when the credential resolves to a role that is too low.

How a request is authenticated

There are two interchangeable ways to present a credential. Both carry the same token, and every endpoint accepts either.

  • Bearer token. Send Authorization: Bearer . This is how a server-side or command-line client authenticates.
  • Session cookie. The current_user cookie, set by the login endpoint, carries the same token. A browser sends it automatically, so a page's own fetch calls are signed in without any extra header. An older fs_session cookie is accepted as a fallback.

The token itself is a JSON Web Token: signed by the platform, with your user identifier as its subject. Treat it as opaque. You obtain it by logging in and then present it unchanged; you never construct or decode it to call the API.

Logging in

Exchange an email and password for a token at POST /api/v1/auth/login (also reachable at /auth/login). The endpoint is public and rate limited. The login is scoped to the site host you send it to, so a user signs in on their own site.

curl -X POST https://your-site.fleeksite.com/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email": "you@example.com", "password": "your-password"}'

A successful login returns the token at data.token and, in a browser, also sets the current_user cookie:

{ "data": { "text": "Welcome!", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }, "state": "ok" }

From there, send the token as a bearer credential on any authenticated call:

curl https://your-site.fleeksite.com/api/v1/leads \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'

Bad credentials return 401 with a message at data.text; a disabled account returns 403. From a browser you can skip the header entirely and rely on the cookie the login set.

Other ways to sign in

Login is the common path, but the platform offers a few alternatives, all under the same auth prefix and all returning or setting the same token:

  • Sign-up. POST /api/v1/auth/signup registers a new user (at the base role) and returns a token exactly as login does.
  • Email code. A passwordless flow: POST /api/v1/auth/login/code emails a one-time code, and POST /api/v1/auth/login/verify exchanges the code for a token.
  • Social login. OAuth sign-in with Facebook, Google and Twitter is available under the /auth/ prefix. Each finds or creates the user and returns the same kind of token; the provider-specific flow is out of scope here.

Password reset and email verification live under the same prefix. All of these are public entry points, since a person cannot yet be authenticated when they use them.

The role model

A user has a numeric role. Higher is more permission. These are the role numbers and names the platform uses:

RoleNameTypically
1customerA registered visitor, buyer or commenter.
2writerContributes content.
3marketerManages content, leads, orders and site tooling.
4designerWorks on templates and presentation.
5adminManages site settings.
7super adminPlatform staff, who act across sites.

Reads of published content need no role at all. The line falls between reading content, which is public, and everything else, which needs a credential and usually a role. The main threshold is role 3: it is where managing the site, and reading the data that identifies people, begins.

To do thisYou need
Read posts, templates, bits, files, comments, redirects and the product cataloguenothing (public)
Submit a lead, quote a discount, hold an anonymous cartnothing (public)
Create content, read your own orders, post a commentsession
Manage content, redirects and bits; read leads and orders; manage plugins and webhooks; presign an upload; read logsrole 3+
List site usersrole 2+
Update site settings; send a notificationrole 5+
Delete a siteowner or role 7+

Many write endpoints also let the record's own author act on it regardless of a low role. That is what owner or role 3+ means in the API tables: the person who created the post, template or file can edit it, and so can anyone at role 3 or above.

A role is scoped to one site. A membership belongs to a single site, so the role a request is granted is the caller's role on the site being addressed, not on whichever site their account was created. A token minted elsewhere grants no role here unless that same person also holds a membership on this site. Platform staff (role 7 and above) are the deliberate exception: they carry their role across sites.

current_user in a template

The same principal is exposed to your Liquid as current_user. On an anonymous request it is empty, so it doubles as the signed-in test:

{% if current_user %}
  >Signed in as {{ current_user.name }}.>
{% else %}
   href="/login">Sign in>
{% endif %}

current_user.role is the site-scoped role: the caller's membership role on the site being rendered, following the same rule as the API. A visitor with no membership on this site carries no elevated role, so a role gate in a template reliably fences off staff-only content:

{% if current_user.role > 2 %}
   href="/admin/content">Manage content>
{% endif %}

Because the role is resolved per site, the same account can be an admin on one site and an ordinary visitor on another, and the template sees whichever applies to the site it is rendering. Continue to Validate and deploy to edit a template, check it and ship the change.