API-Referenz

Endpunkte, Datenmodelle und Fehlercodes der LiSA REST API, erzeugt aus dem offiziellen API-Wiki.
Wiki-Stand 158c1a5 · 28.7.2026

Error Handling Guide

Complete guide to error handling in the LISA REST API.

Overview#

The LISA REST API uses a consistent error response format and HTTP status codes to communicate errors clearly. All error responses follow the same structure for easy handling.

Error Response Format#

All error responses follow this consistent format:

{
  "success": false,
  "error": "Error message",
  "details": [
    {
      "field": "fieldName",
      "message": "Specific validation error message"
    }
  ],
  "timestamp": "2024-12-01T08:47:16.838Z"
}

HTTP Status Codes#

CodeDescriptionWhen Used
200OKSuccessful GET, PUT, PATCH requests
201CreatedSuccessful POST requests
400Bad RequestValidation errors, malformed requests
401UnauthorizedMissing or invalid authentication
403ForbiddenValid authentication but insufficient permissions
404Not FoundResource not found
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-side errors

Common Error Types#

Authentication Errors#

Missing Authentication#

Status: 401 Unauthorized

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

When it occurs:

  • No Authorization header provided
  • Empty Authorization header

How to fix:

  • Include Authorization: Bearer <jwt-token> header
  • Generate a valid JWT token first

Invalid Token Format#

Status: 401 Unauthorized

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

When it occurs:

  • Malformed Authorization header
  • Missing "Bearer " prefix
  • Invalid token format

How to fix:

  • Use format: Authorization: Bearer <jwt-token>
  • Ensure token is properly formatted

Expired Token#

Status: 401 Unauthorized

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

When it occurs:

  • JWT token has passed its expiration time
  • Token was issued too long ago

How to fix:

  • Generate a new token using /tokens endpoint
  • Use refresh token to get new access token
  • Implement automatic token refresh

Invalid Token#

Status: 401 Unauthorized

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

When it occurs:

  • Token is malformed or corrupted
  • Token was not issued by this API
  • Token has been tampered with

How to fix:

  • Generate a new token
  • Check token integrity
  • Verify token source

Authorization Errors#

Access Denied#

Status: 403 Forbidden

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

When it occurs:

  • Invalid integrator UID
  • Integrator not found in database
  • Integrator is inactive

How to fix:

  • Verify integrator UID is correct
  • Contact LISA team to activate integrator
  • Check integrator permissions

Insufficient Permissions#

Status: 403 Forbidden

{
  "success": false,
  "error": "Access denied: You can only access your own data",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

When it occurs:

  • Trying to access another user's data
  • Missing required permissions
  • Invalid user context

How to fix:

  • Use correct user ID in request path
  • Verify ownership of requested data
  • Check integrator permissions

Validation Errors#

Missing Required Fields#

Status: 400 Bad Request

{
  "success": false,
  "error": "Validation failed",
  "details": [
    {
      "field": "integratorUID",
      "message": "\"integratorUID\" is required"
    }
  ],
  "timestamp": "2024-12-01T08:47:16.838Z"
}

When it occurs:

  • Required fields missing from request body
  • Required query parameters not provided

How to fix:

  • Include all required fields
  • Check field names and types
  • Review API documentation

Invalid Field Format#

Status: 400 Bad Request

{
  "success": false,
  "error": "Validation failed",
  "details": [
    {
      "field": "MAC",
      "message": "\"MAC\" must be a valid MAC address"
    }
  ],
  "timestamp": "2024-12-01T08:47:16.838Z"
}

When it occurs:

  • Invalid data format for fields
  • Values outside allowed ranges
  • Invalid enum values

How to fix:

  • Check field format requirements
  • Use correct data types
  • Validate input before sending

Invalid Query Parameters#

Status: 400 Bad Request

{
  "success": false,
  "error": "Invalid limit. Must be a number between 1 and 100",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

When it occurs:

  • Query parameters outside valid ranges
  • Invalid parameter values
  • Malformed query strings

How to fix:

  • Check parameter value ranges
  • Use correct parameter formats
  • Validate query parameters

Resource Errors#

Resource Not Found#

Status: 404 Not Found

{
  "success": false,
  "error": "User not found",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

When it occurs:

  • Requested resource doesn't exist
  • Invalid resource ID
  • Resource was deleted

How to fix:

  • Verify resource ID is correct
  • Check if resource exists
  • Use search endpoints to find resources

Invalid Endpoint#

Status: 404 Not Found

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

When it occurs:

  • Invalid API endpoint
  • Wrong HTTP method
  • Malformed URL

How to fix:

  • Check endpoint URL
  • Verify HTTP method
  • Review API documentation

Rate Limiting Errors#

Rate Limit Exceeded#

Status: 429 Too Many Requests

{
  "success": false,
  "error": "Too many requests from this IP, please try again later.",
  "timestamp": "2024-12-01T08:47:16.838Z"
}

When it occurs:

  • Exceeded the IP-based limit (100 requests / 15 minutes)
  • Too many requests in time window
  • Token endpoint rate limit exceeded
  • Exceeded your daily per-endpoint API quota for your account tier (see Billing / API tiers)

There are two independent 429 limiters:

  1. IP limiter (infrastructure): 100 requests per 15 minutes per source IP. Message: Too many requests from this IP, please try again later.
  2. Account quota (billing tier): a per-endpoint, per-day cap tied to your API tier (Free 10, Starter 1,000, Pro 10,000, Enterprise unlimited). Reads and writes both count. Resets daily at 00:00 UTC. Message starts with Daily quota exceeded for this endpoint ....

Quota response headers (sent on every authenticated request):

HeaderMeaning
X-RateLimit-LimitPer-endpoint daily call cap for your tier (unlimited for Enterprise)
X-RateLimit-RemainingCalls remaining for this endpoint today (0 when over quota)
X-RateLimit-ResetUnix epoch seconds of the next 00:00 UTC reset

How to fix:

  • Wait before making more requests (back off until X-RateLimit-Reset)
  • Implement exponential backoff
  • Monitor the X-RateLimit-* headers
  • If you consistently exceed the cap, upgrade your API tier (Starter is free-included for any active per-sow subscription; Pro/Enterprise unlock higher volume and raw sensor data)

Server Errors#

Internal Server Error#

Status: 500 Internal Server Error

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

When it occurs:

  • Database connection issues
  • Service unavailable
  • Unexpected server errors

How to fix:

  • Retry request after delay
  • Check API status
  • Contact support if persistent

Error Handling Best Practices#

Client-Side Error Handling#

JavaScript/TypeScript#

async function makeAPIRequest(url, options = {}) {
  try {
    const response = await fetch(url, {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json',
        ...options.headers
      },
      ...options
    });

    const data = await response.json();

    if (!data.success) {
      // Handle API errors
      if (response.status === 401) {
        // Token expired, try to refresh
        await refreshToken();
        return makeAPIRequest(url, options); // Retry with new token
      }
      
      if (response.status === 429) {
        // Rate limited, implement backoff
        await new Promise(resolve => setTimeout(resolve, 1000));
        return makeAPIRequest(url, options);
      }

      throw new Error(`API Error: ${data.error}`);
    }

    return data;
  } catch (error) {
    console.error('Request failed:', error);
    throw error;
  }
}

Python#

import requests
import time
from typing import Dict, Any

class LISAPIClient:
    def make_request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]:
        try:
            headers = {
                "Authorization": f"Bearer {self.access_token}",
                "Content-Type": "application/json"
            }
            
            response = requests.request(method, endpoint, headers=headers, **kwargs)
            data = response.json()
            
            if not data.get("success", False):
                if response.status_code == 401:
                    # Token expired, refresh and retry
                    self.refresh_token()
                    return self.make_request(method, endpoint, **kwargs)
                
                if response.status_code == 429:
                    # Rate limited, wait and retry
                    time.sleep(1)
                    return self.make_request(method, endpoint, **kwargs)
                
                raise Exception(f"API Error: {data.get('error', 'Unknown error')}")
            
            return data
            
        except requests.exceptions.RequestException as e:
            print(f"Request failed: {e}")
            raise

Error Recovery Strategies#

Token Refresh#

async function handleTokenExpiry() {
  try {
    const response = await fetch('/api/v1/tokens/refresh', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refreshToken: refreshToken })
    });
    
    const data = await response.json();
    if (data.success) {
      accessToken = data.data.accessToken;
      refreshToken = data.data.refreshToken;
      return true;
    }
  } catch (error) {
    console.error('Token refresh failed:', error);
  }
  
  // If refresh fails, generate new token
  return generateNewToken();
}

Exponential Backoff#

async function makeRequestWithRetry(url, options = {}, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        // Rate limited, wait with exponential backoff
        const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
}

Monitoring and Logging#

Error Logging#

function logError(error, context = {}) {
  console.error('API Error:', {
    message: error.message,
    status: error.status,
    timestamp: new Date().toISOString(),
    context: context
  });
  
  // Send to monitoring service
  if (window.monitoring) {
    window.monitoring.captureException(error, {
      extra: context
    });
  }
}

Rate Limit Monitoring#

function checkRateLimit(response) {
  const remaining = response.headers.get('X-RateLimit-Remaining');
  const reset = response.headers.get('X-RateLimit-Reset');
  
  if (remaining && parseInt(remaining) < 10) {
    console.warn(`Rate limit warning: ${remaining} requests remaining`);
  }
  
  return {
    remaining: parseInt(remaining) || null,
    reset: parseInt(reset) || null
  };
}

Common Error Scenarios#

Scenario 1: Token Expired During Long Operation#

Problem: Token expires while processing a large dataset.

Solution:

async function processLargeDataset(userId) {
  let page = 1;
  let allData = [];
  
  while (true) {
    try {
      const response = await fetch(`/api/v1/users/${userId}/animals?page=${page}&limit=100`, {
        headers: { 'Authorization': `Bearer ${accessToken}` }
      });
      
      const data = await response.json();
      
      if (!data.success) {
        if (response.status === 401) {
          await refreshToken();
          continue; // Retry with new token
        }
        throw new Error(data.error);
      }
      
      allData.push(...data.data);
      
      if (page >= data.pagination.totalPages) break;
      page++;
      
    } catch (error) {
      console.error('Error processing page:', page, error);
      throw error;
    }
  }
  
  return allData;
}

Scenario 2: Handling Validation Errors#

Problem: User submits invalid data.

Solution:

async function createUser(userData) {
  try {
    const response = await fetch('/api/v1/users', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userData)
    });
    
    const data = await response.json();
    
    if (!data.success) {
      if (response.status === 400 && data.details) {
        // Handle validation errors
        data.details.forEach(detail => {
          console.error(`Field ${detail.field}: ${detail.message}`);
        });
        return { success: false, validationErrors: data.details };
      }
      throw new Error(data.error);
    }
    
    return { success: true, data: data.data };
    
  } catch (error) {
    console.error('Failed to create user:', error);
    return { success: false, error: error.message };
  }
}

Scenario 3: Network Issues#

Problem: Network connectivity issues.

Solution:

async function makeRequestWithRetry(url, options = {}, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      return response;
    } catch (error) {
      if (attempt === maxRetries) {
        throw new Error(`Request failed after ${maxRetries} attempts: ${error.message}`);
      }
      
      // Wait before retry (exponential backoff)
      const delay = Math.pow(2, attempt - 1) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

Debugging Tips#

1. Check Response Headers#

const response = await fetch(url, options);
console.log('Status:', response.status);
console.log('Headers:', Object.fromEntries(response.headers.entries()));

2. Validate Request Data#

function validateRequestData(data, schema) {
  const errors = [];
  
  if (schema.required) {
    schema.required.forEach(field => {
      if (!data[field]) {
        errors.push(`${field} is required`);
      }
    });
  }
  
  return errors;
}

3. Test Token Validity#

async function testToken() {
  try {
    const response = await fetch('/api/v1/tokens/validate', {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    });
    
    const data = await response.json();
    console.log('Token valid:', data.success);
    return data.success;
  } catch (error) {
    console.error('Token validation failed:', error);
    return false;
  }
}

Next: Code Examples - Complete implementation examples

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 158c1a5 · 28.7.2026
Wir schätzen Ihre Privatsphäre

Wir verwenden Cookies und ähnliche Technologien, um diese Website zu betreiben und mit Ihrer Einwilligung für Analysen und (falls zutreffend) Werbung. Sie können alle akzeptieren, alle ablehnen oder Ihre Auswahl anpassen. Einzelheiten finden Sie in unserer Datenschutzerklärung und Cookie-Richtlinie.

Kategorien: Notwendig (Immer aktiv), Funktional, Analytik, Marketing

Hallo! Brauchen Sie Hilfe? Chatten Sie mit mir!