> For the complete documentation index, see [llms.txt](https://docs.flowretail.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flowretail.com/docs/developers/authentication.md).

# Authentication

The three token types, how to get one, and what permissions they need.

Every request to the Flow Retail API carries a bearer token:

```
Authorization: Bearer <TOKEN>
```

Always over HTTPS. There are three token types, and which one you want depends entirely on what is making the call.

| Token type            | Use it for                                                      |
| --------------------- | --------------------------------------------------------------- |
| **Integration token** | Server-to-server work — ERP, e-commerce, sync jobs. Start here. |
| **Access token**      | Acting on behalf of a signed-in user.                           |
| **Device token**      | POS hardware and managed devices.                               |

## 1. Integration token — start here

A long-lived token tied to an **Integration user** in your tenant. This is what almost every backend integration should use.

### Create one in Flow Retail Admin

1. In [Flow Retail Admin](https://admin.flowretail.com/), create a user of type **Integration user (API user)** for your tenant.
2. Give it only the permissions it needs — see [Permissions](#permissions).
3. Generate an integration token for that user.

You are shown the token value **once**. Store it in a secret manager or an environment variable, never in source control, and treat it like a password.

### Or create one over the API

Tokens can also be managed programmatically, which is what you want if you are rotating them on a schedule:

```
GET    /tenants/{tenantUid}/users/{tenantUserUid}/tokens
POST   /tenants/{tenantUid}/users/{tenantUserUid}/tokens
DELETE /tenants/{tenantUid}/users/{tenantUserUid}/tokens/{tenantUserTokenUid}
```

These require the `USER_TOKEN` permission. The caller needs a token that already has it — bootstrap the first one in Admin.

### Use it

```bash
export FLOW_TOKEN="your-integration-token"

curl -H "Authorization: Bearer $FLOW_TOKEN" \
     -H "Accept: application/json" \
     "https://api.stage.flowretail.com/v2/tenants/{tenantUid}/reasons"
```

## 2. Access token — acting as a user

When your application acts on behalf of a signed-in user, exchange that user's auth token for a tenant-scoped access token:

```bash
curl -X POST "https://api.flowretail.com/v2/tenants/{tenantUid}/account" \
  -H "Authorization: Bearer YOUR_USER_AUTH_TOKEN" \
  -H "Accept: application/json"
# -> use the returned access token on subsequent calls
```

`POST /tenants/{tenantUid}/account` accepts a user auth token only. The access token it returns is short-lived and scoped to that tenant, and is accepted by most endpoints alongside integration tokens.

## 3. Device token — POS hardware

Devices link once, then exchange a refresh token for a device token:

```bash
# 1. link the device
curl -X POST "https://api.flowretail.com/v2/device/{deviceCode}/link"

# 2. exchange for a device token
curl -X POST "https://api.flowretail.com/v2/device/token" \
  -H "Content-Type: application/json" \
  -d '{ "appId": "your-app-id", "refreshToken": "device-refresh-token" }'
```

`appId` is issued by Flow Retail; `refreshToken` comes from the linking step. Both fields are required. Neither `/device/token` nor `/device/{deviceCode}/link` requires an existing bearer token.

## Permissions

A token authenticates *who* you are. Permissions decide *what* that identity may do, and they are granted to the user the token belongs to.

Endpoints declare the permission they require in the OpenAPI specification, as `x-flow-permissions`. The names are flat identifiers naming an area of the product — there are around seventy. Some of the most common:

| Permission                 | Covers                           |
| -------------------------- | -------------------------------- |
| `PRODUCT`                  | Products and product data        |
| `CUSTOMER`                 | Customers and customer data      |
| `SALES_ORDER,RETURN_ORDER` | Sales and return orders          |
| `PURCHASE_ORDER`           | Purchase orders                  |
| `WAREHOUSE`                | Warehouses and stock             |
| `PAYMENT_METHOD`           | Payment method configuration     |
| `ACCOUNTING_CONFIG`        | Accounting configuration         |
| `REPORTING`                | Reports                          |
| `IMPORT`                   | Bulk import                      |
| `USER_TOKEN`               | Creating and revoking API tokens |

Where an endpoint lists more than one, as with `SALES_ORDER,RETURN_ORDER`, the user needs the permissions named.

The authoritative list is the specification itself — check the endpoint's reference page for the exact requirement rather than guessing, and grant least privilege. An integration that only reads products should not hold `USER_TOKEN`.

## When authentication fails

| Status | Code                   | Meaning                                              |
| ------ | ---------------------- | ---------------------------------------------------- |
| `401`  | `ErrInvalidToken`      | Token missing, malformed, expired or revoked         |
| `403`  | `ErrPermissionDenied`  | Token is valid; the user lacks the permission        |
| `403`  | `ErrAccessDenied`      | Token is valid but not allowed on this resource      |
| `403`  | `ErrStoreAccessDenied` | The user has no access to the store in the path      |
| `404`  | `ErrNotFound`          | Often a tenant mismatch rather than a missing record |

A `404` where you expected data usually means the token and the `{tenantUid}` in the path belong to different tenants.

## Good practice

* Prefer integration tokens for anything server-side, and rotate them on a schedule.
* Grant least privilege — only the permissions the integration actually uses.
* Keep tokens out of source control, logs and error reports.
* Check that the token's tenant matches the `{tenantUid}` you are calling.
* Build against stage before production.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.flowretail.com/docs/developers/authentication.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
