Skip to main content

Production Guide

Before you point this integration at the production environment (https://eservices.yeka.gr/WebservicesAPI/Api/), make sure your code does the five things below. Each is based on documented Ergani behavior — no invented guarantees.

1. Token refresh strategy

Access tokens last 3 hours (accessTokenExpired: 10800). Refresh tokens last 7 days.

Do this:

  • Store accessToken, refreshToken, and refreshTokenExpired alongside each set of credentials you manage.
  • On every API call, check if the access token is close to expiry (e.g. refresh proactively if more than 2h45m have passed since it was issued) — or simply call Authentication/Refresh reactively when a request returns 401 / api-token-expired: true, then retry once.
  • If Authentication/Refresh itself returns 401, the refresh token has expired (7 days) — call Authentication with credentials again.

Don't do this:

2. Rate limiting

The only documented rate limit is on authentication calls (429 Too Many Requests). There's no documented per-minute limit on Documents/WRKCardSE itself, but the fix for 429 is the same either way: reuse your access token across requests instead of re-authenticating.

3. Idempotency and deduplication

Ergani has no idempotency-key mechanism

There is no request ID or idempotency header that lets you safely "retry the exact same submission" and get the exact same result back. Each accepted POST returns a new protocol, even if the payload is identical to a previous request.

What Ergani does guarantee (see Repeated events for the same employee and day): for a given f_afm + f_reference_date + f_type, the most recently submitted event is the one that counts in the Actual Work Calendar. Earlier submissions for the same combination aren't deleted, but they stop being authoritative.

Practical deduplication strategy:

  1. Before submitting, check whether you already have a stored protocol for this exact event (same employee, reference date, and event type) from this run.
  2. If yes, don't resubmit — you already have a confirmed result.
  3. If you're unsure whether a previous request succeeded (e.g. after a network error), it is safe to resubmit the same event: Ergani will record it again with a new protocol, and because it has the same f_type + f_reference_date + f_afm, it simply becomes the authoritative value (which, if your data didn't change, is the correct outcome anyway). See Network failure mid-request.

Don't build your own idempotency layer that prevents resubmission on uncertainty — Ergani's "most recent wins" rule already makes resubmission safe for this specific event shape.

4. Logging requirements

For every submission, log:

FieldWhy
Request payload (Cards.Card[].Details.CardDetails[])Reproduce what was sent if a dispute arises.
protocol (on success)Required to retrieve the PDF later via GET Documents/WRKCardSE?protocol=...&submittedDate=.... This is your audit trail.
submitDate (on success)When Ergani recorded it — compare against f_date to confirm it was on time.
message (on failure)The exact rejection reason — needed for support/debugging.

Without a logged protocol, you cannot prove a specific event was accepted.

5. The 15-minute window drives your retry budget

Every check-in/check-out must reach Ergani within 15 minutes (± 1 minute) of f_date to be on-time. This has two operational consequences:

  • Submit immediately, don't batch. If your system queues events and sends them in batches every 30 minutes, every event will be late, and late events require a justification code that (per Late and justified submissions) only covers force-majeure — not "we batch."
  • Build retries into that 15-minute budget. If a submission fails due to 401/expired token, refresh and retry immediately — you have minutes, not hours, before the event becomes late.

If your devices are sometimes offline for longer than 15 minutes, read Network failure mid-request for how to handle the resulting late submissions honestly.

What's next

Real-World Scenarios walks through the failure cases this guide prepares you for.