Code-Beispiele¶
Hier finden Sie praktische Beispiele fuer die Verwendung der calServer REST API mit curl und PHP.
Interaktive Dokumentation
Die interaktive API-Dokumentation generiert automatisch Code-Beispiele in ueber 20 Programmiersprachen fuer jeden Endpunkt. Dort koennen Sie auch Anfragen direkt testen:
- API v1 Dokumentation (Produktion)
- API v2 Dokumentation (Beta — calServer 6.0)
API v2 — Beispiele (Bearer Token)¶
Token erzeugen¶
<?php
$domain = 'ihre-instanz.example.com';
$ch = curl_init("https://{$domain}/api/v2/auth/token");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'email' => 'user@example.com',
'password' => 'IhrPasswort',
'device_name' => 'api-client',
]));
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
$token = $data['token'];
echo "Token: {$token}\n";
Antwort:
Inventar abrufen (API v2)¶
<?php
$domain = 'ihre-instanz.example.com';
$token = '1|a1b2c3d4e5f6...';
$ch = curl_init("https://{$domain}/api/v2/inventories?page[size]=10");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer {$token}",
'Accept: application/json',
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Gesamt: " . $data['meta']['total'] . "\n";
foreach ($data['data'] as $item) {
echo $item['attributes']['asset_number'] . ' — '
. $item['attributes']['manufacturer'] . ' '
. $item['attributes']['model'] . "\n";
}
Antwort:
{
"data": [
{
"id": "ea79b775-8b4b-8e17-98c9-b33e7065ff6f",
"type": "inventory",
"attributes": {
"asset_number": "DMM-001",
"serial_number": "SN-1234567890",
"description": "Digital Multimeter",
"manufacturer": "FLUKE",
"model": "179",
"location": "Labor A",
"status": 1,
"calibration_interval": 12
},
"relationships": {
"customer": { "data": { "id": "45f09720-...", "type": "customer" } },
"categories": [
{
"id": "3fa85f64-...",
"type": "category",
"attributes": {
"name": "Messgeraet",
"type": "inventory",
"color": "#4CAF50"
}
}
]
}
}
],
"meta": { "total": 150, "page": 1, "per_page": 10, "last_page": 15 },
"links": { "self": "...", "next": "...", "prev": null }
}
Kategorien auflisten¶
<?php
$domain = 'ihre-instanz.example.com';
$token = '1|a1b2c3d4e5f6...';
$ch = curl_init("https://{$domain}/api/v2/categories?filter[type]=inventory");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer {$token}",
'Accept: application/json',
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
foreach ($data['data'] as $cat) {
$indent = $cat['attributes']['parent_id'] ? ' └─ ' : '';
echo $indent . $cat['attributes']['name']
. ' (' . $cat['attributes']['type'] . ")\n";
}
Antwort:
{
"data": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "category",
"attributes": {
"name": "Messgeraet",
"short_name": "MG",
"type": "inventory",
"parent_id": null,
"sort_num": 1,
"color": "#4CAF50",
"text_color": "#FFFFFF",
"rentable": 1
}
},
{
"id": "7fb91c22-3a44-4e89-b0fc-8d5e6f7a8b9c",
"type": "category",
"attributes": {
"name": "Multimeter",
"short_name": "MM",
"type": "inventory",
"parent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"sort_num": 1,
"color": "#2196F3",
"text_color": "#FFFFFF",
"rentable": 1
}
}
],
"meta": { "total": 2 }
}
Kategorie erstellen¶
# Hauptkategorie erstellen
curl -X POST "https://ihre-instanz.example.com/api/v2/categories" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Oszilloskope",
"short_name": "OSZ",
"type": "inventory",
"color": "#FF9800",
"text_color": "#000000",
"rentable": 1
}'
# Unterkategorie erstellen (mit parent_id)
curl -X POST "https://ihre-instanz.example.com/api/v2/categories" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Digital-Oszilloskope",
"short_name": "DOSZ",
"type": "inventory",
"parent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"sort_num": 1,
"color": "#E65100"
}'
<?php
$domain = 'ihre-instanz.example.com';
$token = '1|a1b2c3d4e5f6...';
$categoryData = [
'name' => 'Oszilloskope',
'short_name' => 'OSZ',
'type' => 'inventory',
'color' => '#FF9800',
'text_color' => '#000000',
'rentable' => 1,
];
$ch = curl_init("https://{$domain}/api/v2/categories");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer {$token}",
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($categoryData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 201) {
$result = json_decode($response, true);
echo "Kategorie erstellt: " . $result['data']['id'] . "\n";
}
Antwort (201 Created):
{
"data": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"type": "category",
"attributes": {
"name": "Oszilloskope",
"short_name": "OSZ",
"type": "inventory",
"parent_id": null,
"sort_num": 0,
"color": "#FF9800",
"text_color": "#000000",
"rentable": 1
}
}
}
Feldkonfigurationen abrufen¶
# Tabellenuebersicht
curl -X GET "https://ihre-instanz.example.com/api/v2/fields" \
-H "Authorization: Bearer $TOKEN"
# Felder fuer Inventar-Tabelle
curl -X GET "https://ihre-instanz.example.com/api/v2/fields/inventory" \
-H "Authorization: Bearer $TOKEN"
# Felder mit Kategorie-Overrides
curl -X GET "https://ihre-instanz.example.com/api/v2/fields/inventory?category_uID=3fa85f64-5717-4562-b3fc-2c963f66afa6" \
-H "Authorization: Bearer $TOKEN"
<?php
$domain = 'ihre-instanz.example.com';
$token = '1|a1b2c3d4e5f6...';
$categoryUid = '3fa85f64-5717-4562-b3fc-2c963f66afa6';
// Felder fuer Inventar mit Kategorie-Overrides
$url = "https://{$domain}/api/v2/fields/inventory?category_uID={$categoryUid}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer {$token}",
'Accept: application/json',
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
foreach ($result['data'] as $field) {
$attr = $field['attributes'];
$pflicht = $attr['mandatory'] ? '(Pflicht)' : '';
echo "{$attr['api_name']} — {$attr['label']} {$pflicht}\n";
}
Antwort (Tabellenuebersicht):
{
"data": [
{ "table": "inventory", "field_count": 65, "active_field_count": 32 },
{ "table": "calibration", "field_count": 98, "active_field_count": 45 },
{ "table": "customer", "field_count": 38, "active_field_count": 20 },
{ "table": "location", "field_count": 15, "active_field_count": 8 },
{ "table": "repair", "field_count": 20, "active_field_count": 12 }
]
}
Antwort (Felder fuer inventory):
{
"data": [
{
"id": "I4201:inventory",
"type": "field-configuration",
"attributes": {
"api_name": "asset_number",
"column_name": "I4201",
"table_name": "inventory",
"label": "Inventarnummer",
"field_type": "text",
"field_type_raw": "varchar",
"filterable": true,
"sortable": true,
"editable": true,
"visible": true,
"mandatory": true,
"display_order": 1,
"options": null,
"is_user_defined": false
}
},
{
"id": "I4209:inventory",
"type": "field-configuration",
"attributes": {
"api_name": "status_code",
"column_name": "I4209",
"table_name": "inventory",
"label": "Status",
"field_type": "select",
"field_type_raw": "varchar",
"filterable": true,
"sortable": true,
"editable": true,
"visible": true,
"mandatory": false,
"display_order": 9,
"options": [
{ "value": "uuid-active", "label": "Aktiv" },
{ "value": "uuid-inactive", "label": "Inaktiv" },
{ "value": "uuid-repair", "label": "In Reparatur" }
],
"field_category": "StatusDatabase",
"is_user_defined": false
}
}
]
}
Inventar mit Filter und Sortierung¶
<?php
$domain = 'ihre-instanz.example.com';
$token = '1|a1b2c3d4e5f6...';
$params = http_build_query([
'filter' => ['manufacturer' => 'like:FLUKE'],
'sort' => 'asset_number',
'page' => ['size' => 5],
]);
$ch = curl_init("https://{$domain}/api/v2/inventories?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer {$token}",
'Accept: application/json',
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Treffer: {$data['meta']['total']}\n";
API v1 — Beispiele (Header-Auth)¶
Authentifizierung¶
Alle API-v1-Anfragen erfordern drei Authentifizierungsparameter als Query-Parameter:
HTTP_X_REST_USERNAME– Ihr Benutzername (E-Mail)HTTP_X_REST_PASSWORD– Ihr PasswortHTTP_X_REST_API_KEY– Ihr API-Schluessel (im Benutzerkonto generierbar)
Inventar abrufen¶
<?php
$domain = 'demo.net-cal.com';
$params = http_build_query([
'HTTP_X_REST_USERNAME' => 'user@example.com',
'HTTP_X_REST_PASSWORD' => 'yourpassword',
'HTTP_X_REST_API_KEY' => 'your-api-key',
]);
$ch = curl_init("https://{$domain}/api/inventory?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Gesamtanzahl: " . $data['data']['totalCount'] . "\n";
foreach ($data['data']['inventory'] as $item) {
echo $item['I4201'] . ' - ' . $item['I4202'] . ' ' . $item['I4203'] . "\n";
}
Antwort-Struktur:
{
"success": true,
"message": "Record(s) Found",
"data": {
"totalCount": 42,
"inventory": [
{
"MTAG": "ea79b775-8b4b-8e17-98c9-b33e7065ff6f",
"I4201": "Test-API-Asset",
"I4202": "FLUKE",
"I4203": "179",
"I4206": "1234567890",
"I4211": "CALSERVICE",
"I4228": "M",
"I4229": "12"
}
]
}
}
Inventar mit Filter (API v1)¶
curl -X GET "https://demo.net-cal.com/api/inventory?\
HTTP_X_REST_USERNAME=user@example.com&\
HTTP_X_REST_PASSWORD=yourpassword&\
HTTP_X_REST_API_KEY=your-api-key&\
filter=%5B%7B%22property%22%3A%22I4201%22%2C%22value%22%3A%22Test-API-Asset%22%2C%22operator%22%3A%22%3D%22%7D%5D"
Der filter-Parameter URL-encodiert entspricht:
<?php
$domain = 'demo.net-cal.com';
$filter = json_encode([
['property' => 'I4201', 'value' => 'Test-API-Asset', 'operator' => '=']
]);
$params = http_build_query([
'HTTP_X_REST_USERNAME' => 'user@example.com',
'HTTP_X_REST_PASSWORD' => 'yourpassword',
'HTTP_X_REST_API_KEY' => 'your-api-key',
'filter' => $filter,
]);
$ch = curl_init("https://{$domain}/api/inventory?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);
Inventar nach Kategoriename filtern (API v1)¶
Die API unterstuetzt Dot-Notation fuer verknuepfte Felder (relation.field).
Fuer Inventar-Kategorien gibt es zusaetzlich das Shorthand-Feld categoryname,
das intern automatisch ueber die Kategorie-Tabelle aufgeloest wird.
# Variante 1: categoryname-Shorthand (empfohlen fuer Inventar)
curl -X GET "https://demo.net-cal.com/api/inventory?\
HTTP_X_REST_USERNAME=user@example.com&\
HTTP_X_REST_PASSWORD=yourpassword&\
HTTP_X_REST_API_KEY=your-api-key&\
filter=%5B%7B%22property%22%3A%22categoryname%22%2C%22value%22%3A%22Messgeraet%22%2C%22operator%22%3A%22like%22%7D%5D"
Der filter-Parameter URL-encodiert entspricht:
<?php
$domain = 'demo.net-cal.com';
// Variante 1: categoryname-Shorthand
$filter = json_encode([
['property' => 'categoryname', 'value' => 'Messgeraet', 'operator' => 'like']
]);
// Variante 2: Dot-Notation (generisch fuer alle Relations)
// $filter = json_encode([
// ['property' => 'categories.name', 'value' => 'Messgeraet', 'operator' => 'like']
// ]);
$params = http_build_query([
'HTTP_X_REST_USERNAME' => 'user@example.com',
'HTTP_X_REST_PASSWORD' => 'yourpassword',
'HTTP_X_REST_API_KEY' => 'your-api-key',
'filter' => $filter,
]);
$ch = curl_init("https://{$domain}/api/inventory?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Treffer: " . $data['data']['totalCount'] . "\n";
foreach ($data['data']['inventory'] as $item) {
echo $item['I4201'] . ' - ' . $item['I4202'] . ' ' . $item['I4203'] . "\n";
}
Dot-Notation fuer andere Relations
Die Dot-Notation (relation.field) funktioniert generisch fuer alle im Yii-Model
definierten Relations — nicht nur fuer Kategorien. Die API fuegt automatisch den
entsprechenden JOIN hinzu. Beispiel: categories.name, customer.name, etc.
Inventar erstellen (API v1)¶
curl -X POST "https://demo.net-cal.com/api/inventory/insert?\
HTTP_X_REST_USERNAME=user@example.com&\
HTTP_X_REST_PASSWORD=yourpassword&\
HTTP_X_REST_API_KEY=your-api-key" \
-F "ktag=45f09720-082f-5c74-9cfa-a605e2863904" \
-F "I4201=Test-API-Asset" \
-F "I4202=FLUKE" \
-F "I4203=179" \
-F "I4206=1234567890" \
-F "I4211=CALSERVICE" \
-F "I4228=M" \
-F "I4229=12"
<?php
$domain = 'demo.net-cal.com';
$params = http_build_query([
'HTTP_X_REST_USERNAME' => 'user@example.com',
'HTTP_X_REST_PASSWORD' => 'yourpassword',
'HTTP_X_REST_API_KEY' => 'your-api-key',
]);
$postData = [
'ktag' => '45f09720-082f-5c74-9cfa-a605e2863904',
'I4201' => 'Test-API-Asset',
'I4202' => 'FLUKE',
'I4203' => '179',
'I4206' => '1234567890',
'I4211' => 'CALSERVICE',
'I4228' => 'M',
'I4229' => '12',
];
$ch = curl_init("https://{$domain}/api/inventory/insert?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if ($data['success']) {
echo "Inventar erfolgreich erstellt!\n";
} else {
echo "Fehler: " . print_r($data['errors'], true) . "\n";
}
Pagination (Limit & Offset) (API v1)¶
<?php
$domain = 'demo.net-cal.com';
$params = http_build_query([
'HTTP_X_REST_USERNAME' => 'user@example.com',
'HTTP_X_REST_PASSWORD' => 'yourpassword',
'HTTP_X_REST_API_KEY' => 'your-api-key',
'limit' => 10,
'offset' => 30,
]);
$ch = curl_init("https://{$domain}/api/calibration?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Seite mit " . count($data['data']['calibration']) . " Eintraegen\n";
echo "Gesamtanzahl: " . $data['data']['totalCount'] . "\n";
Validierungsregeln abrufen (API v1)¶
Verfuegbare Rules-Endpunkte:
| Ressource | Endpunkt |
|---|---|
| Inventar | GET /api/inventory/rules |
| Kalibrierung | GET /api/calibration/rules |
| Kunden | GET /api/customer/rules |
| Standards | GET /api/standard/rules |
| Benutzer | GET /api/user/rules |
| Reparaturen | GET /api/repair/rules |
| Standorte | GET /api/location/rules |