Certificates
Certificates are per company, never per tenant. The Tax Administration rejects any message
whose payload OIB differs from the signing certificate’s OIB (s005), and every company has its
own OIB.
Upload a certificate
POST /v1/certificatesmultipart/form-data:
| Part | Required | Notes |
|---|---|---|
company_id | yes | The company this certificate signs for. |
file | yes | The PKCS#12 container (.p12 / .pfx). Maximum 256 KB. |
passphrase | yes | Used once, in memory, to open the container. Never stored, never logged. |
label | no | Human-readable name for the dashboard. |
curl -sS -X POST https://api.fiskhub.com/v1/certificates \ -H "Authorization: Bearer $FISKHUB_API_KEY" \ -F "company_id=3a5f2b18-7c4d-4e91-9a2b-6d8e0f1c3a57" \ -F "passphrase=$P12_PASSPHRASE" \ -F "label=FISKAL 1"The container is streamed over TLS, opened in memory, re-encrypted under a wrapped data key and stored. It is never written to disk in the clear.
What is checked before it is accepted
- The passphrase opens the container, and it holds exactly one private key.
- The chain validates against the trusted roots for this mode.
- The validity window covers now.
- The OIB in the certificate subject equals the company’s OIB. This is checked here so that a
mismatch is a clear
400at upload time rather than ans005from the Tax Administration at the point of sale.
Uploading a certificate for a company that already has one supersedes it: the previous
certificate moves to superseded and stops being used for signing.
Response — 201
{ "id": "c1d9e7f2-4a63-4b0e-8d15-7f2c9a3b6e04", "company_id": "3a5f2b18-7c4d-4e91-9a2b-6d8e0f1c3a57", "label": "FISKAL 1", "subject_oib": "25089460814", "subject_cn": "FISKAL 1", "issuer": "Fina Demo CA 2020", "serial": "2f1a4c8b93d0", "not_before": "2025-09-22T12:00:00+02:00", "not_after": "2028-09-22T12:00:00+02:00", "days_until_expiry": 751, "status": "valid", "uploaded_at": "2026-08-27T09:15:33+02:00"}Metadata only. Nothing in this object, or any other, carries key material.
Errors
| Status | Code |
|---|---|
400 | hr.certificate_oib_mismatch — the subject OIB is not the company’s |
400 | certificate_expired — outside the validity window |
400 | invalid_request — the passphrase is wrong, the container is malformed, or a part is missing |
404 | invalid_request — no such company |
413 | The file exceeds 256 KB |
List certificate metadata
GET /v1/certificates| Parameter | Notes |
|---|---|
company_id | UUID |
status | valid, expiring, expired, superseded, revoked |
curl -sS -G https://api.fiskhub.com/v1/certificates \ -H "Authorization: Bearer $FISKHUB_API_KEY" \ --data-urlencode "company_id=3a5f2b18-7c4d-4e91-9a2b-6d8e0f1c3a57"{ "object": "list", "data": [ { "id": "c1d9e7f2-4a63-4b0e-8d15-7f2c9a3b6e04", "company_id": "3a5f2b18-7c4d-4e91-9a2b-6d8e0f1c3a57", "label": "FISKAL 1 (demo)", "subject_oib": "25089460814", "subject_cn": "FISKAL 1", "issuer": "Fina Demo CA 2020", "serial": "2f1a4c8b93d0", "not_before": "2025-09-22T12:00:00+02:00", "not_after": "2028-09-22T12:00:00+02:00", "days_until_expiry": 751, "status": "valid", "uploaded_at": "2026-06-14T08:44:19+02:00" } ], "has_more": false, "next_cursor": null}status | Meaning |
|---|---|
valid | In use. |
expiring | Under 60 days remaining. |
expired | Past not_after. Every device of this company is blocked. |
superseded | Replaced by a later upload. |
revoked | Revoked by its issuer. |
Expiry is a fleet-wide event
When a certificate expires, the company’s entire fleet stops being able to fiscalize —
certificate_expired on every sale, from every device, at once.
It is the single change most likely to take a whole site offline.
FiskHub sends notices at 60, 30, 14, 7 and 1 days. Reading days_until_expiry into your own
monitoring is worth the ten minutes it takes.
Replacing a certificate is a plain upload: POST /v1/certificates with the new container.
Nothing else changes, and there is no downtime — the old one is superseded the moment the new one
is accepted.
Compliance dates worth knowing
| Date | Change |
|---|---|
| 01.05.2026 | eIDAS trusted-list certificates accepted |
| 01.07.2026 | TEST rejects RSA-SHA1 and TLS 1.1 |
| 31.12.2026 | PROD stops accepting RSA-SHA1 |
| 01.01.2027 | PROD rejects TLS 1.1 |
FiskHub signs with RSA-SHA256 already, so the December 2026 change needs nothing from you. It matters when you are choosing a replacement certificate: make sure it is one an RSA-SHA256 signature can be built from.