Pierwsze kroki
API integracji eLearning.edu.pl pozwala systemowi kadrowemu, dostawcy tożsamości albo narzędziu raportowemu wymieniać z platformą dane o osobach, przydziałach szkoleń i stanie zgodności.
1. Uzyskaj dane dostępowe
Poproś administratora IT swojej organizacji o utworzenie klienta integracji w panelu administracji IT. Administrator wybiera:
- zakresy (scopes) — co klient może robić (
users:read,users:write,enrollments:write,compliance:read,webhooks:manage,scim); - metody uwierzytelniania — klucz API, OAuth 2.0 client credentials albo obie;
- opcjonalnie listę dozwolonych adresów IP i datę ważności.
Otrzymujesz identyfikator klienta i sekret w postaci lms_live_<12 znaków>_<32 znaki>. Sekret jest pokazywany tylko raz —
zapisz go w menedżerze sekretów.
Potrzebujesz też kodu organizacji (tenant code) — identyfikatora Twojej organizacji widocznego w panelu IT.
2. Wykonaj pierwsze wywołanie
BASE_URL="${BASE_URL:-https://api.elearning.edu.pl}"
curl --fail-with-body -sS "$BASE_URL/api/v1/users?limit=5" \
-H "X-Tenant-Code: $TENANT_CODE" \
-H "X-API-Key: $API_KEY"import os
import requests
BASE_URL = os.environ.get("BASE_URL", "https://api.elearning.edu.pl")
response = requests.get(
f"{BASE_URL}/api/v1/users",
headers={
"X-Tenant-Code": os.environ["TENANT_CODE"],
"X-API-Key": os.environ["API_KEY"],
},
params={"limit": 5},
timeout=30,
)
response.raise_for_status()
for user in response.json()["users"]:
print(user["employee_no"], user["first_name"], user["last_name"])<?php
require __DIR__ . '/vendor/autoload.php';
$client = new GuzzleHttp\Client([
'base_uri' => getenv('BASE_URL') ?: 'https://api.elearning.edu.pl',
'timeout' => 30,
]);
$response = $client->request('GET', '/api/v1/users', [
'headers' => [
'X-Tenant-Code' => getenv('TENANT_CODE'),
'X-API-Key' => getenv('API_KEY'),
],
'query' => ['limit' => 5],
]);
$page = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
foreach ($page['users'] as $user) {
echo $user['employee_no'], ' ', $user['first_name'], ' ', $user['last_name'], PHP_EOL;
}package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
type user struct {
EmployeeNo string `json:"employee_no"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func main() {
baseURL := os.Getenv("BASE_URL")
if baseURL == "" {
baseURL = "https://api.elearning.edu.pl"
}
req, err := http.NewRequest("GET", baseURL+"/api/v1/users?limit=5", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-Tenant-Code", os.Getenv("TENANT_CODE"))
req.Header.Set("X-API-Key", os.Getenv("API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
fmt.Fprintln(os.Stderr, "request failed:", res.Status)
os.Exit(1)
}
var page struct {
Users []user `json:"users"`
}
if err := json.NewDecoder(res.Body).Decode(&page); err != nil {
panic(err)
}
for _, u := range page.Users {
fmt.Println(u.EmployeeNo, u.FirstName, u.LastName)
}
}const BASE_URL = process.env.BASE_URL ?? "https://api.elearning.edu.pl";
const response = await fetch(`${BASE_URL}/api/v1/users?limit=5`, {
headers: {
"X-Tenant-Code": process.env.TENANT_CODE ?? "",
"X-API-Key": process.env.API_KEY ?? "",
},
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const page = await response.json();
for (const user of page.users) {
console.log(user.employee_no, user.first_name, user.last_name);
}using System.Net.Http.Json;
using System.Text.Json;
var baseUrl = Environment.GetEnvironmentVariable("BASE_URL") ?? "https://api.elearning.edu.pl";
using var http = new HttpClient { BaseAddress = new Uri(baseUrl) };
http.DefaultRequestHeaders.Add("X-Tenant-Code", Environment.GetEnvironmentVariable("TENANT_CODE"));
http.DefaultRequestHeaders.Add("X-API-Key", Environment.GetEnvironmentVariable("API_KEY"));
using var response = await http.GetAsync("/api/v1/users?limit=5");
response.EnsureSuccessStatusCode();
var page = await response.Content.ReadFromJsonAsync<JsonElement>();
foreach (var user in page.GetProperty("users").EnumerateArray())
{
Console.WriteLine($"{user.GetProperty("employee_no")} {user.GetProperty("first_name")} {user.GetProperty("last_name")}");
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
String baseUrl = System.getenv().getOrDefault("BASE_URL", "https://api.elearning.edu.pl");
HttpRequest request = HttpRequest.newBuilder(URI.create(baseUrl + "/api/v1/users?limit=5"))
.header("X-Tenant-Code", System.getenv("TENANT_CODE"))
.header("X-API-Key", System.getenv("API_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IllegalStateException(response.statusCode() + " " + response.body());
}
// Parse the JSON with your library of choice (Jackson, Gson, …).
System.out.println(response.body());
}
}Każde żądanie wymaga nagłówka X-Tenant-Code (SCIM: kod organizacji jest częścią ścieżki). Adres API nie zmienia się,
nawet gdy Twoja organizacja zostanie przeniesiona do innego węzła centrum danych, więc możesz go wpisać na stałe.
3. Co dalej
- Uwierzytelnianie — klucz API a tokeny OAuth 2.0.
- Typowy przepływ — synchronizacja osób, przydział szkoleń, odczyt zgodności.
- Webhooki — powiadomienia o ukończeniach i wygaśnięciach zamiast odpytywania.
- Limity i błędy — klient, który poprawnie ponawia żądania.
Testowanie API
Używaj organizacji testowej, oddzielonej od danych produkcyjnych — poproś o nią opiekuna wdrożenia. Utwórz klienta integracji w jej panelu IT i wywołuj API z jej kodem organizacji.