API-Referenz

Endpunkte, Datenmodelle und Fehlercodes der LiSA REST API, erzeugt aus dem offiziellen API-Wiki.

Wiki-Stand e01e79e · 19.8.2026

Authentication Guide

The LISA REST API uses a JWT token-based authentication system designed for third-party integrations and applications.

Overview#

The authentication system consists of:

  1. JWT Token Generation - Generate access and refresh tokens
  2. Token Validation - Validate tokens on each request
  3. Token Refresh - Refresh expired access tokens
  4. Token Revocation - Revoke tokens when no longer needed

Two token types#

The API issues two kinds of access token. They authenticate differently, are scoped differently, and do not grant the same endpoints — picking the wrong one is the most common cause of an unexpected 403.

Integrator tokenUser token
Obtained withPOST /tokens with your integratorUIDPOST /tokens/login with email + password
Identifiesa third-party integration (your organisation)one BioCV user account
Can readevery account that has linked your integratoronly its own account
API tierfrom the integrator's account (free / starter / pro / enterprise)none — a fixed allowance of 1,000 calls per endpoint per day
Raw sensor data (/sensordata*)yes, on the Pro or Enterprise tierno — at any tier

If you need raw sensor data, you need an integrator token. A user token cannot reach /sensordata* no matter how its account is configured, so a 403 there is not fixed by an API tier change — it is fixed by authenticating as an integrator. If your organisation does not have an integrator account, contact BioCV.

To read a customer's data with an integrator token, that account must have linked your integrator first. The account owner authorises the link themselves via POST /partners/link using their own user token, or BioCV provisions it. An integrator cannot link itself to an account.

Authentication Flow#

sequenceDiagram
    participant Client
    participant API
    participant Database

    Client->>API: POST /tokens (integratorUID)
    API->>Database: Validate integratorUID
    Database-->>API: Integrator data
    API-->>Client: JWT tokens (access + refresh)
    
    Client->>API: API Request (Authorization: Bearer token)
    API->>API: Validate JWT token
    API-->>Client: Response data

Getting Started#

Step 1: Generate JWT Tokens#

Generate JWT tokens using the token endpoint:

curl -X POST "https://api.biocv.info/api/v1/tokens" \
  -H "Content-Type: application/json" \
  -d '{
    "integratorUID": "your-integrator-uid",
    "expiresIn": 3600,
    "refreshToken": true
  }'

Request Body:

{
  "integratorUID": "your-integrator-uid",
  "expiresIn": 3600,
  "refreshToken": true
}

Response:

{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiresAt": 1640995200000,
    "tokenType": "Bearer"
  },
  "message": "Token generated successfully",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Step 2: Use Tokens in API Requests#

Include the access token in the Authorization header:

curl -H "Authorization: Bearer your-access-token" \
     "https://api.biocv.info/api/v1/users/user123/animals"

Token Management Endpoints#

Generate Tokens#

POST /tokens

Generate new JWT access and refresh tokens.

Parameters:

  • integratorUID (required) - Your integrator UID
  • expiresIn (optional) - Token expiration in seconds (300-86400, default: 3600)
  • refreshToken (optional) - Whether to include refresh token (default: false)

Refresh Access Token#

POST /tokens/refresh

Refresh an expired access token using a refresh token.

curl -X POST "https://api.biocv.info/api/v1/tokens/refresh" \
  -H "Content-Type: application/json" \
  -d '{"refreshToken": "your-refresh-token"}'

Request Body:

{
  "refreshToken": "your-refresh-token"
}

Response:

{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiresAt": 1640995200000,
    "tokenType": "Bearer"
  },
  "message": "Token refreshed successfully",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Validate Token#

GET /tokens/validate

Validate a JWT token and get token information.

curl -H "Authorization: Bearer your-access-token" \
     "https://api.biocv.info/api/v1/tokens/validate"

Response:

{
  "success": true,
  "data": {
    "valid": true,
    "integratorUID": "your-integrator-uid",
    "integrator": {
      "email": "integrator@example.com",
      "name": "Integrator Name",
      "isActive": true
    },
    "tokenType": "access",
    "expiresAt": "2024-12-01T09:47:16.838Z"
  },
  "message": "Token is valid",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Revoke Token#

POST /tokens/revoke

Revoke a JWT token (logout).

curl -X POST "https://api.biocv.info/api/v1/tokens/revoke" \
  -H "Authorization: Bearer your-access-token"

Response:

{
  "success": true,
  "message": "Token revoked successfully",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Get Token Information#

GET /tokens/info

Get detailed token information (requires valid token).

curl -H "Authorization: Bearer your-access-token" \
     "https://api.biocv.info/api/v1/tokens/info"

Response:

{
  "success": true,
  "data": {
    "integratorUID": "your-integrator-uid",
    "integrator": {
      "email": "integrator@example.com",
      "name": "Integrator Name",
      "isActive": true,
      "createdAt": "2024-01-01T00:00:00.000Z"
    },
    "token": {
      "type": "access",
      "issuedAt": "2024-12-01T08:47:16.838Z",
      "expiresAt": "2024-12-01T09:47:16.838Z",
      "jti": "token-unique-id"
    },
    "config": {
      "accessTokenExpiry": 3600,
      "refreshTokenExpiry": 604800
    }
  },
  "message": "Token information retrieved successfully",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Token Lifecycle Management#

Token Expiration#

  • Access Tokens: Default 1 hour (3600 seconds)
  • Refresh Tokens: Default 7 days
  • Configurable: Access token expiry can be set between 5 minutes and 24 hours

Automatic Token Refresh#

Implement automatic token refresh in your application:

class LISAPIClient {
  constructor(integratorUID) {
    this.integratorUID = integratorUID;
    this.accessToken = null;
    this.refreshToken = null;
  }

  async ensureValidToken() {
    if (!this.accessToken || this.isTokenExpired()) {
      if (this.refreshToken && !this.isRefreshTokenExpired()) {
        await this.refreshAccessToken();
      } else {
        await this.generateNewTokens();
      }
    }
  }

  isTokenExpired() {
    if (!this.accessToken) return true;
    const payload = JSON.parse(atob(this.accessToken.split('.')[1]));
    return Date.now() >= payload.exp * 1000;
  }

  async refreshAccessToken() {
    const response = await fetch('https://api.biocv.info/api/v1/tokens/refresh', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refreshToken: this.refreshToken })
    });
    
    const data = await response.json();
    if (data.success) {
      this.accessToken = data.data.accessToken;
      this.refreshToken = data.data.refreshToken;
    }
  }
}

Error Handling#

Common Authentication Errors#

Missing Token:

{
  "success": false,
  "error": "Authorization header is required",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Invalid Token:

{
  "success": false,
  "error": "Invalid token",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Expired Token:

{
  "success": false,
  "error": "Token has expired",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Invalid Integrator:

{
  "success": false,
  "error": "Access denied: Invalid integratorUID",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

Security Best Practices#

Token Storage#

  • Server-side: Store tokens in secure environment variables
  • Client-side: Use secure storage mechanisms (Keychain, Keystore)
  • Never: Store tokens in localStorage or sessionStorage for production

Token Rotation#

  • Implement automatic token refresh
  • Use refresh tokens to get new access tokens
  • Revoke tokens when no longer needed
  • Monitor token usage patterns

Rate Limiting#

Token endpoints have stricter rate limits:

  • Token Generation: 20 requests per 15 minutes per IP
  • Token Refresh: 20 requests per 15 minutes per IP
  • General API (IP limit): 100 requests per 15 minutes per IP

In addition to the IP limit, authenticated requests are subject to a per-endpoint, per-day account quota. For integrator tokens this follows the integrator's API tier (Free 10, Starter 1,000, Pro 10,000, Enterprise unlimited). User tokens have a fixed allowance of 1,000 calls per endpoint per day, which no tier setting changes. Both reads and writes count, and the quota resets at 00:00 UTC. Monitor the X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers. See Endpoints and Error Handling for details.

Integration Examples#

JavaScript/Node.js#

class LISAPIClient {
  constructor(integratorUID, baseURL = 'https://api.biocv.info/api/v1') {
    this.integratorUID = integratorUID;
    this.baseURL = baseURL;
    this.accessToken = null;
    this.refreshToken = null;
  }

  async generateTokens(expiresIn = 3600) {
    const response = await fetch(`${this.baseURL}/tokens`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        integratorUID: this.integratorUID,
        expiresIn,
        refreshToken: true
      })
    });

    const data = await response.json();
    if (data.success) {
      this.accessToken = data.data.accessToken;
      this.refreshToken = data.data.refreshToken;
      return data.data;
    }
    throw new Error(data.error);
  }

  async makeRequest(endpoint, options = {}) {
    await this.ensureValidToken();

    const url = `${this.baseURL}${endpoint}`;
    const headers = {
      'Authorization': `Bearer ${this.accessToken}`,
      'Content-Type': 'application/json',
      ...options.headers
    };

    const response = await fetch(url, { ...options, headers });
    const data = await response.json();
    
    if (!data.success) {
      throw new Error(`API Error: ${data.error}`);
    }

    return data;
  }
}

Python#

import requests
import time

class LISAPIClient:
    def __init__(self, integrator_uid, base_url="https://api.biocv.info/api/v1"):
        self.integrator_uid = integrator_uid
        self.base_url = base_url
        self.access_token = None
        self.refresh_token = None
        self.token_expires_at = None

    def generate_tokens(self, expires_in=3600):
        response = requests.post(f"{self.base_url}/tokens", 
            json={
                "integratorUID": self.integrator_uid,
                "expiresIn": expires_in,
                "refreshToken": True
            }
        )
        
        data = response.json()
        if data["success"]:
            self.access_token = data["data"]["accessToken"]
            self.refresh_token = data["data"]["refreshToken"]
            self.token_expires_at = data["data"]["expiresAt"]
            return data["data"]
        raise Exception(f"Failed to generate tokens: {data.get('error', 'Unknown error')}")

    def is_token_expired(self):
        if not self.token_expires_at:
            return True
        return time.time() * 1000 >= self.token_expires_at

    def ensure_valid_token(self):
        if not self.access_token or self.is_token_expired():
            if self.refresh_token and not self.is_token_expired():
                self.refresh_access_token()
            else:
                self.generate_tokens()

    def make_request(self, method, endpoint, **kwargs):
        self.ensure_valid_token()
        
        headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json"
        }
        
        url = f"{self.base_url}{endpoint}"
        response = requests.request(method, url, headers=headers, **kwargs)
        data = response.json()
        
        if not data.get("success", False):
            raise Exception(f"API Error: {data.get('error', 'Unknown error')}")
        
        return data

Troubleshooting#

Common Issues#

  1. 401 Unauthorized: Check token format and expiration
  2. 403 Forbidden: Verify integrator UID is valid and active
  3. 403 on /sensordata* with a user token: expected — raw sensor data is not available to user tokens at any tier. Use an integrator token (POST /tokens) on the Pro or Enterprise tier. An API tier change will not help.
  4. 403 "Integrator does not have access to this user's data": the account has not linked your integrator. The account owner authorises it via POST /partners/link, or BioCV provisions it.
  5. Token Expired: Implement automatic refresh logic
  6. Rate Limited: Implement exponential backoff

Debug Steps#

  1. Test token generation
  2. Validate token with /tokens/validate
  3. Check token expiration times
  4. Verify integrator UID is correct
  5. Monitor rate limit headers

Next: API Endpoints - Complete endpoint documentation

Diese Seite wird aus dem offiziellen LiSA-API-Wiki erzeugt. Sollte etwas falsch sein oder fehlen, kontaktieren Sie uns — wir korrigieren es an der Quelle.

Wiki-Stand e01e79e · 19.8.2026