> ## Documentation Index
> Fetch the complete documentation index at: https://developers.jobhandy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentifizierung und Zugriffsscope

> Authentifizieren Sie Anfragen mit X-API-Key, wählen Sie den Tenant-Kontext und behandeln Sie Credential-Fehler.

<Badge color="green" shape="pill" icon="shield-check">Server-zu-Server</Badge> <Badge color="blue" shape="pill" icon="key-round">API-Key</Badge>

Alle geschützten JobHandy-Operationen erfordern einen API-Key im Header `X-API-Key`. `GET /health` ist die einzige öffentliche Operation.

<Info>
  Sie benötigen noch einen Key? Folgen Sie zunächst der Anleitung zur [API-Key-Verwaltung](/de/get-started/api-key-management).
</Info>

## API-Key senden

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl --request GET \
    --url 'https://api.jobhandy.io/v1/employees' \
    --header 'X-API-Key: YOUR_API_KEY'
  ```

  ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch('https://api.jobhandy.io/v1/employees', {
    headers: {
      'X-API-Key': process.env.JOBHANDY_API_KEY,
    },
  });

  if (!response.ok) {
    throw new Error(`JobHandy request failed: ${response.status}`);
  }
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import os
  import requests

  response = requests.get(
      'https://api.jobhandy.io/v1/employees',
      headers={'X-API-Key': os.environ['JOBHANDY_API_KEY']},
      timeout=30,
  )
  response.raise_for_status()
  ```

  ```csharp C# theme={"theme":{"light":"github-light","dark":"github-dark"}}
  using var client = new HttpClient
  {
      BaseAddress = new Uri("https://api.jobhandy.io/v1/")
  };
  client.DefaultRequestHeaders.Add(
      "X-API-Key",
      Environment.GetEnvironmentVariable("JOBHANDY_API_KEY")
  );
  using var response = await client.GetAsync("employees");
  response.EnsureSuccessStatusCode();
  ```

  ```powershell PowerShell theme={"theme":{"light":"github-light","dark":"github-dark"}}
  $headers = @{
      'X-API-Key' = $env:JOBHANDY_API_KEY
  }
  Invoke-RestMethod `
      -Method Get `
      -Uri 'https://api.jobhandy.io/v1/employees' `
      -Headers $headers
  ```
</CodeGroup>

## Tenant auswählen

Ein API-Key kann einen oder mehrere Tenants umfassen. Wo dies dokumentiert ist, wählt `X-Tenant-ID` genau einen Tenant aus, der bereits im Scope des Keys enthalten ist.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
X-Tenant-ID: {{tenantId}}
```

| Situation                                          | Verhalten des Headers                                                                |
| -------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Collection-Read über alle autorisierten Tenants    | `X-Tenant-ID` weglassen                                                              |
| Collection-Read für einen autorisierten Tenant     | `X-Tenant-ID` senden                                                                 |
| Schreibvorgang mit einem eindeutigen Ziel-Tenant   | Die API kann den Tenant entsprechend der jeweiligen Operationsbeschreibung ermitteln |
| Schreibvorgang mit mehreren möglichen Ziel-Tenants | `X-Tenant-ID` oder einen anderen dokumentierten Placement-Selektor senden            |
| Tenant außerhalb des API-Key-Scopes                | Die Anfrage schlägt mit `TENANT_NOT_IN_SCOPE` fehl                                   |

<Note>
  `X-Tenant-ID` gewährt niemals zusätzlichen Zugriff. Der Header schränkt ausschließlich den bereits zugewiesenen Scope des API-Keys ein.
</Note>

## Authentifizierungsablauf

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
sequenceDiagram
    participant Client
    participant API as JobHandy API
    Client->>API: Anfrage + X-API-Key
    API->>API: Key und aktiven Status prüfen
    API->>API: Zugewiesenen Tenant- und Divisionsscope laden
    opt X-Tenant-ID wurde gesendet
        API->>API: Prüfen, ob der ausgewählte Tenant im Scope liegt
    end
    alt Autorisiert
        API-->>Client: Antwort + X-Request-ID
    else Key fehlt, ist ungültig oder inaktiv
        API-->>Client: 401 INVALID_API_KEY
    else Tenant liegt außerhalb des Scopes
        API-->>Client: 403 TENANT_NOT_IN_SCOPE
    end
```

## Fehler bei Zugangsdaten

|  HTTP | Fehlercode            | Bedeutung                                          | Korrektur                            | Retry |
| ----: | --------------------- | -------------------------------------------------- | ------------------------------------ | ----: |
| `401` | `INVALID_API_KEY`     | Key fehlt, ist ungültig, gelöscht oder inaktiv     | Secret und Key-Status prüfen         |  Nein |
| `403` | `TENANT_NOT_IN_SCOPE` | Ausgewählter Tenant liegt außerhalb des Key-Scopes | Tenant oder Key-Scope korrigieren    |  Nein |
| `400` | `UNSUPPORTED_HEADER`  | Ein Request-Header wird nicht akzeptiert           | Nicht unterstützten Header entfernen |  Nein |
| `400` | `INVALID_REQUEST_ID`  | `X-Request-ID` ist keine UUID v4 oder v7           | Gültige UUID erzeugen                |  Nein |

## Regeln für den Umgang mit Zugangsdaten

<AccordionGroup>
  <Accordion title="Secret-Speicherung" defaultOpen icon="lock-keyhole">
    Speichern Sie den Key in einem verwalteten Secret Store oder einer geschützten Umgebungsvariable. Beschränken Sie den Lesezugriff auf die Runtime der Integration.
  </Accordion>

  <Accordion title="Logging">
    Protokollieren Sie niemals den vollständigen Key. Protokollieren Sie die zurückgegebene `X-Request-ID`, Operation, Status, Fehlercode und eine nicht geheime interne Bezeichnung der Zugangsdaten.
  </Accordion>

  <Accordion title="Rotation">
    Erstellen und prüfen Sie einen Ersatz-Key, bevor die alte Zugangsdaten deaktiviert wird. Siehe [API-Keys rotieren](/de/guides/rotate-api-keys).
  </Accordion>

  <Accordion title="Client-Grenze">
    Stellen Sie den Key niemals Browsercode, mobilen Anwendungen, gemeinsam genutzten Arbeitsstationen oder kundenseitig kontrollierten Skripten zur Verfügung.
  </Accordion>
</AccordionGroup>
