Dokumentacja integracji

Jak uwierzytelniać żądania do API Tracera i odbierać zdarzenia webhookiem, w imieniu Twojej organizacji.

Uwierzytelnianie kluczem API

Dołącz swój klucz API w nagłówku X-API-Key do każdego żądania. Utwórz klucz w zakładce Klucze API w ustawieniach organizacji.

curl "https://api.tracera.app/api/v1/external/events?limit=20&eventType=report_completed" \
  -H "X-API-Key: ftk_your_api_key"

Pobieranie zdarzeń (pull)

GET /api/v1/external/events zwraca zdarzenia Twojej organizacji, stronicowane i opcjonalnie filtrowane po eventType. Limit żądań: 30/min na adres IP (burst 10). Parametr limit domyślnie 20, maksymalnie 100.

curl "https://api.tracera.app/api/v1/external/events?limit=20&eventType=report_completed" \
  -H "X-API-Key: ftk_your_api_key"
{
  "content": [
    {
      "id": "3f2a9c34-1e9a-4c3b-9e2b-9a5d9a6b6b12",
      "organizationUUID": "8f6e2a3d-...-...-...",
      "eventType": "report_completed",
      "payload": { "reportId": "..." },
      "occurredAt": "2026-07-23T09:12:04.512Z"
    }
  ],
  "total": 128,
  "page": 1,
  "limit": 20
}

Typy zdarzeń

Te same wartości eventType pojawiają się zarówno w odpowiedzi API, jak i w treści webhooka.

eventTypeOpis
user_registeredNowy użytkownik zarejestrował się w organizacji.
report_completedRaport inspekcji został ukończony.
alert_violationReguła alertu RCP została naruszona.
fault_reportedZgłoszono nową usterkę.
fault_resolvedUsterka została rozwiązana.

Wpisy RCP (pull)

GET /api/v1/external/rcp/entries zwraca odbicia RCP (check-in/check-out) Twojej organizacji w zadanym zakresie dat, stronicowane. Ze względu na wysoką częstotliwość te dane nie są wysyłane webhookiem — pobieraj je okresowo. Zakres domyślny to ostatnie 30 dni, limit domyślnie 20, maksymalnie 100.

curl "https://api.tracera.app/api/v1/external/rcp/entries?from=2026-07-01T00:00:00Z&to=2026-07-31T23:59:59Z&limit=50" \
  -H "X-API-Key: ftk_your_api_key"
{
  "content": [
    {
      "id": "6a1e2b3c-4d5e-...-...-...",
      "userId": 42,
      "entryType": "check_in",
      "scannedAt": "2026-07-23T07:58:11Z",
      "status": "valid",
      "nfcTagId": 7,
      "nfcTagUuid": "9c8b7a6d-...-...-..."
    }
  ],
  "total": 964,
  "page": 1,
  "limit": 50
}

Usterki (pull)

GET /api/v1/external/faults zwraca usterki Twojej organizacji, stronicowane i opcjonalnie filtrowane po status oraz severity. Limit domyślnie 20, maksymalnie 100.

curl "https://api.tracera.app/api/v1/external/faults?status=open&limit=20" \
  -H "X-API-Key: ftk_your_api_key"
{
  "content": [
    {
      "id": "b2f1a3c4-...-...-...",
      "tagId": 7,
      "reporterId": 42,
      "assigneeId": 15,
      "title": "Leaking valve",
      "description": "Valve on line 3 is leaking coolant.",
      "severity": "high",
      "status": "open",
      "createdAt": "2026-07-20T08:15:00Z",
      "updatedAt": "2026-07-20T08:15:00Z"
    }
  ],
  "total": 12,
  "page": 1,
  "limit": 20
}

Inspekcje (pull)

GET /api/v1/external/inspections zwraca inspekcje Twojej organizacji, stronicowane i filtrowane po status, type oraz nfcTagId. Limit domyślnie 20, maksymalnie 100.

curl "https://api.tracera.app/api/v1/external/inspections?status=completed&limit=20" \
  -H "X-API-Key: ftk_your_api_key"
{
  "content": [
    {
      "id": "c3d2e1f0-...-...-...",
      "inspectionType": "checklist",
      "status": "completed",
      "scannedAt": "2026-07-22T11:00:00Z",
      "completedAt": "2026-07-22T11:20:00Z",
      "progress": 100,
      "nfcTag": { "id": "9c8b7a6d-...-...-...", "name": "Pump Station A" },
      "user": { "id": "1a2b3c4d-...-...-...", "firstName": "Anna", "lastName": "Kowalska" },
      "createdAt": "2026-07-22T11:00:00Z"
    }
  ],
  "total": 340,
  "page": 1,
  "limit": 20
}

Tagi NFC / zasoby

GET /api/v1/external/nfc-tags zwraca pełną listę tagów NFC (zasobów) Twojej organizacji. Bez stronicowania — inwentarz tagów w organizacji jest niewielki, więc całość zwracana jest w jednym żądaniu.

curl "https://api.tracera.app/api/v1/external/nfc-tags" \
  -H "X-API-Key: ftk_your_api_key"
{
  "content": [
    {
      "id": "9c8b7a6d-...-...-...",
      "name": "Pump Station A",
      "location": "Building 2, Level 1",
      "hardwareUid": "04a1b2c3d4e5",
      "role": "inspection"
    }
  ],
  "total": 58
}

Webhooki (push)

Każde zdarzenie jest wysyłane jako POST na Twój targetUrl (musi być https://). Zweryfikuj nagłówek X-FieldTag-Signature sekretem pokazanym przy tworzeniu webhooka, zanim zaufasz treści żądania.

{
  "id": "3f2a9c34-1e9a-4c3b-9e2b-9a5d9a6b6b12",
  "organizationUUID": "8f6e2a3d-...-...-...",
  "eventType": "report_completed",
  "payload": { "reportId": "..." },
  "occurredAt": "2026-07-23T09:12:04.512Z"
}

Dostarczenie ponawiane jest do 3 razy przy błędzie lub statusie spoza zakresu 2xx, z limitem czasu 5 s na próbę.

Weryfikacja podpisu

Bezpieczeństwo
const crypto = require("crypto")

function isValidSignature(secret, rawBody, signatureHeader) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex")
  return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected))
}
import hashlib
import hmac

def is_valid_signature(secret: str, raw_body: bytes, signature_header: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature_header, expected)