Agent Best Practices
This guide covers the recommended approach for AI agents integrating fiskaly APIs — from discovery through production deployment. It highlights common mistakes and per-country nuances that trip up automated integrations.
Recommended integration flow
Section titled “Recommended integration flow”Discover
Fetch
/products.jsonto identify the right product for your target country. CheckapiArchitectureto determine whether you’re working with a specialized or unified API.Authenticate
POST /authwith the API key and secret provided by the user. Cache the access token (24h TTL) — do not re-authenticate per request.Provision
Create the signing infrastructure for the target country: TSS + Client (DE), Taxpayer + Location + System (FR/IT), or equivalent. Check
/human-interventions.jsonfor steps that require human input.Transact
Sign transactions through the appropriate endpoint. SIGN DE uses a two-call PUT pattern (ACTIVE → FINISHED). SIGN FR and SIGN IT use a two-call POST pattern (Intention → Transaction).
Automatable vs human-required actions
Section titled “Automatable vs human-required actions”Not every step in a fiskaly integration can be automated. Before building an agent workflow, check which actions need a human:
| Category | Count | Examples |
|---|---|---|
| Fully automatable | 11 | Authentication, TSS creation, transaction signing |
| Partially automatable | 2 | Entering taxpayer data (human provides tax ID, agent makes API call) |
| Requires human | 7 | Account creation, API key generation, go-live |
Design your agent to pause and prompt the user at human-required steps, then resume automation. See the full Human Intervention Registry for details.
The machine-readable version at /human-interventions.json can be queried at runtime to dynamically adjust your agent’s workflow.
Common anti-patterns
Section titled “Common anti-patterns”Hardcoding base URLs
Section titled “Hardcoding base URLs”Base URLs differ between TEST and LIVE environments, and between specialized and unified APIs. Always fetch them from /products.json instead of hardcoding.
// Don't do thisconst BASE_URL = "https://kassensichv-middleware.fiskaly.com/api/v2";
// Do this — read from products.jsonconst product = products.find(p => p.id === "sign-de");const baseUrl = product.baseUrls.test;Re-authenticating per request
Section titled “Re-authenticating per request”The access token is valid for 24 hours. Cache it and only re-authenticate on 401 responses. Re-authenticating per request wastes time and may trigger rate limits.
Skipping the TEST environment
Section titled “Skipping the TEST environment”Always develop and test against the TEST (sandbox) environment first. TEST is free, uses the same API surface as LIVE, and lets you iterate without affecting real fiscal data.
Reusing UUIDs
Section titled “Reusing UUIDs”For specialized APIs (SIGN DE, SIGN AT, SIGN ES), resource IDs are client-generated UUIDs. Always generate fresh UUIDs — reusing a UUID causes a 409 Conflict.
Ignoring idempotency keys
Section titled “Ignoring idempotency keys”For unified APIs (SIGN FR, SIGN IT), POST and PATCH requests require an X-Idempotency-Key header. Generate a fresh UUID for each unique operation. Retries of the same operation should reuse the same key.
Polling exports synchronously
Section titled “Polling exports synchronously”DSFinV-K and other export operations are asynchronous. Trigger the export, then poll for completion — don’t block on the initial request.
Per-country gotchas
Section titled “Per-country gotchas”Germany (SIGN DE)
Section titled “Germany (SIGN DE)”TSS initialization requires setting an Admin PIN via PATCH /tss/{id} before changing state to INITIALIZED. The PIN must be stored securely — losing it requires TSS replacement.
- TSS state machine:
UNINITIALIZED→INITIALIZED→DISABLED - Client-generated UUIDs for all resource IDs
- Transactions use a revision model: revision 1 (ACTIVE) → revision 2 (FINISHED)
- DSFinV-K export is legally required for audits
France (SIGN FR)
Section titled “France (SIGN FR)”- Requires an organization hierarchy: Organization GROUP → Organization UNIT → Subject → Taxpayer → Location → System → Record
- Taxpayer creation needs a real SIREN number (human-provided)
- Two-call record pattern: Intention (
type: INTENTION) → Transaction (type: TRANSACTION) - Required headers on every request:
X-Api-Version,X-Idempotency-Key,X-Scope-Identifier
Italy (SIGN IT)
Section titled “Italy (SIGN IT)”- Same unified API architecture as France
- Taxpayer needs Agenzia delle Entrate (AdE) credentials — these are human-provided
- Supports Lotteria degli Scontrini (receipt lottery) — include
lottery_codein records when the customer provides one - Real-time reporting to AdE means transaction signing is not retry-safe without idempotency keys
Austria (SIGN AT)
Section titled “Austria (SIGN AT)”- RKSV regulation with FinanzOnline integration
- Separate base URL:
rksv-middleware.fiskaly.com/api/v1 - DEP (Datenerfassungsprotokoll) export for audit trail
Spain (SIGN ES)
Section titled “Spain (SIGN ES)”- TicketBAI and Verifactu regulations
- XML-based invoice signing and submission (not JSON like other products)
- Regional variations between autonomous communities
Quickstart scripts
Section titled “Quickstart scripts”End-to-end quickstart scripts are available for automated testing:
scripts/sign-de-quickstart.mjs— Full SIGN DE flow: auth → TSS → client → transactionscripts/sign-fr-quickstart.mjs— Full SIGN FR flow: auth → org → taxpayer → location → system → record
These scripts demonstrate the complete happy path and can serve as reference implementations for agent-built integrations.
Was this page helpful?