Skip to main content

Getting Started: Authentication

Every Loca.fi API call (other than login itself) requires a signed JWT presented with a custom auth scheme. This guide walks through logging in, reading the response, and using the token on subsequent requests.

Overview

Authentication is a two-step flow:

  1. POST /api/authentication/login with a username/password to obtain a token pair (Token + Refresh) and the caller's permissions.
  2. Send Authorization: Token <jwt> (not Bearer) on every subsequent request.

Prerequisites

  • A valid Loca.fi username and password for the environment you're targeting.
  • A tool for making HTTP requests (this guide uses curl).

Step-by-step

1. Log in

curl -sk -X POST 'http://localhost:PORT/api/authentication/login' \
-H 'Content-Type: application/json' \
-d '{"Username":"hh","Password":"ramp123"}'

The request body is a simple JSON object:

{
"Username": "hh",
"Password": "ramp123"
}

2. Read the response

A successful login returns HTTP 200 with a body shaped like:

{
"success": true,
"TokenGroup": {
"Token": "<jwt>",
"Refresh": "<jwt>"
},
"Permissions": {
"ReferenceData": 15,
"...": "..."
},
"OrganisationId": "<guid>"
}

Field notes:

  • TokenGroup.Token — the access token to use on subsequent requests.
  • TokenGroup.Refresh — a refresh token (not covered in this guide).
  • Permissions — a per-module bitmask: 1 = Delete, 2 = Update, 4 = Create, 8 = Read, so 15 means all four (full access) on that module and e.g. 12 means Read + Create. A module with value 0 means no access.
  • OrganisationId — the tenant (organisation) the authenticated user belongs to. All data in the API is scoped to this organisation.

3. Use the token on subsequent requests

Every other endpoint expects the token in the Authorization header using the Token scheme — this is easy to get wrong if you're used to OAuth2 Bearer tokens:

curl -sk "http://localhost:PORT/api/Brands/GetFilteredBrands" \
-H "Authorization: Token <jwt>"

Sending Authorization: Bearer <jwt> instead will fail with 401 Unauthorized, even with an otherwise valid token.

4. Filtering list endpoints with OData

Many list/"GetFiltered" endpoints accept standard OData query options: $filter, $top, $skip, $orderby, $select. Because $ is a special character in shells and needs URL-escaping, use %24 in raw curl calls:

curl -sk "http://localhost:PORT/api/Brands/GetFilteredBrands?%24filter=Name%20eq%20%27Nike%27" \
-H "Authorization: Token <jwt>"

Error handling

  • Validation failures — HTTP 400 with a JSON array of error objects:

    [
    { "ErrorCode": "InvalidOperation", "Message": "Username is required.", "Field": "Username" }
    ]

    In practice ErrorCode frequently collapses to "InvalidOperation" regardless of the specific underlying validation rule — treat the Message field as the source of truth for what actually went wrong.

  • Not-found on update/delete — HTTP 400 with:

    [{ "ErrorCode": "NotFound", "Message": "the resource does not exist" }]

    (Not-found on a plain GetById instead returns HTTP 400 with an empty array [] — the API does not distinguish "not found" from a generic bad request in that case.)

  • Auth failures — HTTP 401 with an empty body. This applies both to a missing/invalid token and to using the wrong scheme (Bearer instead of Token).

  • API Reference: Authentication tag, Login operation.
  • Concepts for how OrganisationId scoping and permissions apply across the rest of the API.