My App

Tokens, Certificates & Credentials

KSeF token management, certificate enrollment, credentials lifecycle, and MF public keys.

Before submitting invoices to KSeF, a company needs authentication credentials. The Gateway manages three layers:

  • Gateway Credentials — KSeF tokens or certificates stored encrypted in the Gateway database
  • KSeF Tokens — managed via KSeF API directly on the Ministry of Finance side
  • MF Public Keys — encryption keys from the Ministry of Finance (cached, auto-refreshed)

Typical flow: Add KSeF token → Open session (Sessions) → Submit invoices (Invoice Submission)


Credentials (Gateway DB)

Credentials are stored encrypted (Fernet/AES-128) in the Gateway database. They are used when opening KSeF sessions.

Add KSeF Token

The simplest way to authenticate. Get a token from the KSeF portal and store it.

POST /api/companies/{company_id}/credentials/token
Authorization: Bearer {token}
Content-Type: application/json
{
  "ksef_token": "20260311-EC-4D56D35000-D0583EABAF-4E|nip-8133793363|a7fd8fb...",
  "valid_from": "2026-03-11T00:00:00Z",
  "valid_to": "2027-03-11T00:00:00Z"
}
FieldTypeRequiredDescription
ksef_tokenstring✅Token from KSeF portal (min 10 chars). Encrypted at rest.
valid_fromdatetime❌Token validity start
valid_todatetime❌Token validity end

Response (201):

{
  "credential_id": "1eade95b-923c-4b7e-8fa1-3906d37c8599",
  "company_id": "22919080-f3fe-4aff-8d71-f6493afc956a",
  "credential_type": "ksef_token",
  "status": "active",
  "valid_from": "2026-03-11T22:31:51.828012Z",
  "valid_to": null,
  "created_at": "2026-03-11T22:31:51.810844Z"
}

The token value is never returned after creation. Only a token_preview (first 4 + last 4 chars) is available via the detail endpoint.

Add Certificate (PEM)

For XAdES-based authentication. Upload a PEM-encoded certificate and private key.

POST /api/companies/{company_id}/credentials
Authorization: Bearer {token}
Content-Type: application/json
{
  "certificate": "-----BEGIN CERTIFICATE-----\nMIIE...\n-----END CERTIFICATE-----",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----",
  "password": "optional-private-key-password"
}

List Credentials

GET /api/companies/{company_id}/credentials

Returns all credentials (active and revoked) with their type, status, and validity dates.

Get Active Credential by Type

GET /api/companies/{company_id}/credentials/active/{credential_type}

Where {credential_type} is ksef_token or certificate. Returns 404 if no active credential of that type exists.

Get Credential Detail

GET /api/companies/{company_id}/credentials/{credential_id}

Includes token_preview (first 4 + last 4 chars) and is_valid boolean.

Revoke Credential

PATCH /api/companies/{company_id}/credentials/{credential_id}
Content-Type: application/json
{
  "status": "revoked",
  "revoked_reason": "Replaced with new token"
}

Prefer revocation over deletion — it preserves the audit trail.

Delete Credential

DELETE /api/companies/{company_id}/credentials/{credential_id}

Response: 204 No Content. Use only for test/cleanup.


KSeF Tokens (via KSeF API)

These endpoints interact directly with the Ministry of Finance KSeF API.

Generate KSeF Token

POST /api/companies/{company_id}/ksef-tokens
Content-Type: application/json
{
  "permissions": ["InvoiceWrite", "InvoiceRead", "CredentialsRead", "CredentialsManage"],
  "description": "API production token"
}

Available permissions:

PermissionDescription
InvoiceReadRead invoices
InvoiceWriteSubmit invoices
CredentialsReadRead credentials/permissions
CredentialsManageManage credentials/permissions
SubunitManageManage subunits

Response (202):

{
  "referenceNumber": "20260311-EC-4D56D35000-D0583EABAF-4E",
  "token": "20260311-EC-4D56D35000-...|nip-8133793363|a7fd8fb..."
}

The token value is shown only once. Store it immediately and add it as a credential via POST /credentials/token.

List KSeF Tokens

GET /api/companies/{company_id}/ksef-tokens

Get Token Status

GET /api/companies/{company_id}/ksef-tokens/{reference_number}

Revoke KSeF Token

DELETE /api/companies/{company_id}/ksef-tokens/{reference_number}

This is permanent — a revoked KSeF token cannot be reactivated.


Certificate Management (via KSeF API)

Start Automated Enrollment

POST /api/companies/{company_id}/certificates/enroll
Content-Type: application/json
{
  "certificate_name": "ProductionCert2026",
  "certificate_type": "Authentication",
  "valid_from": "2026-03-14T00:00:00Z"
}

Check Enrollment Status

GET /api/companies/{company_id}/certificates/enroll/{reference_number}/status

Other Certificate Operations

MethodEndpointDescription
POST.../certificates/enrollmentsLow-level enrollment (pass CSR)
GET.../certificates/enrollments/dataGet enrollment data
GET.../certificates/limitsCheck enrollment limits
POST.../certificates/querySearch certificates
POST.../certificates/retrieveRetrieve by serial
POST.../certificates/{serial}/revokeRevoke certificate

MF Public Keys

Used internally for encrypting AES-256 symmetric keys and KSeF tokens. The Gateway caches these automatically.

List Public Keys

GET /api/public-keys
{
  "certificates": [
    {
      "certificate": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...",
      "validFrom": "2025-09-29T06:03:19Z",
      "validTo": "2027-09-29T06:03:18Z",
      "usage": ["KsefTokenEncryption"]
    },
    {
      "certificate": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...",
      "validFrom": "2025-09-29T06:17:45Z",
      "validTo": "2027-09-29T06:17:44Z",
      "usage": ["SymmetricKeyEncryption"]
    }
  ]
}
Key UsagePurpose
KsefTokenEncryptionEncrypt KSeF tokens during authentication
SymmetricKeyEncryptionEncrypt AES-256-CBC symmetric keys for invoice encryption

Get Active Key

GET /api/public-keys/active

Clear Cache

POST /api/public-keys/clear-cache

Forces re-fetch from KSeF. Use when keys have been rotated by the Ministry of Finance.


Authentication Flows

KSeF Token flow (simpler):
  1. Gateway reads stored token from DB (decrypts)
  2. GET /auth/challenge from KSeF → gets challenge + timestamp
  3. GET /security/public-key-certificates → gets MF public key
  4. Encrypts token with RSA (MF public key)
  5. POST /auth/ksef-token to KSeF → gets session reference

Certificate/XAdES flow (advanced):
  1. Gateway reads certificate + private key from DB
  2. GET /auth/challenge from KSeF → gets challenge XML
  3. Signs challenge XML with XAdES (private key)
  4. POST /auth/xades to KSeF → gets session reference

Important Notes

Token vs Certificate: For most integrations, a KSeF token is sufficient and simpler. Certificates are needed for XAdES authentication or offline invoice signing.

Credential lifecycle: When rotating credentials, add the new credential first (it becomes active), then revoke the old one. This ensures no downtime during rotation.

KSeF token vs Gateway credential: A KSeF token is generated on the KSeF portal. A Gateway credential stores that token encrypted in the Gateway database. You need both.

On this page