GFR API Reference
Complete API documentation for GFR's invoice automation platform. Manage users, clients, accounting records, and debtor/creditor relationships. Build integrations that connect directly to DATEV, and other accounting systems.
https://api.gfr.ai/v1API Key (X-API-Key)application/jsonAuthentication
The GFR API uses API Keys for authentication. Generate your API key from the GFR App User Profile, then include it in the X-API-Key header of every request.
Auth Flow
# 1. Generate API Key from GFR App
# Go to: User Profile → API Keys → Generate New Key
# 2. Use the API key in your requests
curl -X GET "https://api.gfr.ai/v1/users/me" \
-H "X-API-Key: gfr_a1b2c3d4e5f6..."
# 3. All protected endpoints require this header:
# X-API-Key: <your_api_key>
# Example with query parameters:
curl -X GET "https://api.gfr.ai/v1/clients?page=1&limit=10" \
-H "X-API-Key: gfr_a1b2c3d4e5f6..." \
-H "Content-Type: application/json"Errors
The API uses standard HTTP status codes. Errors return a JSON body witherrorCode andmessage fields.
| Code | Status | Description |
|---|---|---|
400 | Bad Request | The request body is invalid or missing required fields. |
401 | Unauthorized | Missing or invalid API key. |
403 | Forbidden | Valid token but insufficient role/permissions. |
404 | Not Found | The requested resource does not exist. |
409 | Conflict | Resource already exists (e.g. duplicate email). |
422 | Unprocessable Entity | Validation failed on one or more fields. |
429 | Too Many Requests | Rate limit exceeded. Retry after the indicated period. |
500 | Internal Server Error | An unexpected error occurred on our side. |
502 | Bad Gateway | Upstream service unavailable (e.g. Kladaten API). |
{
"statusCode": 401,
"errorCode": "INVALID_CREDENTIALS",
"message": "The email or password you entered is incorrect.",
"timestamp": "2025-06-20T14:30:00.000Z"
}{
"statusCode": 422,
"errorCode": "VALIDATION_FAILED",
"message": "Validation failed",
"errors": [
{
"field": "email",
"message": "Invalid email format"
},
{
"field": "password",
"message": "Must be at least 8 characters"
}
]
}Pagination
All list endpoints support cursor-based pagination via query parameters. Responses include a meta object with pagination details.
| Parameter | Default | Description |
|---|---|---|
page | 1 | Page number (1-based) |
limit | 25 | Items per page (max 100) |
sortBy | createdAt | Field to sort by |
sortOrder | desc | asc or desc |
{
"data": [
{
"id": "507f1f77...",
"...": "..."
}
],
"meta": {
"page": 1,
"limit": 25,
"total": 134,
"totalPages": 6
}
}Rate Limits
Rate limiting is applied to the authentication endpoints to prevent abuse (credential stuffing, email/SMS spam). Other endpoints are not currently rate-limited, and X-RateLimit-* headers are returned only on the auth endpoints below.
| Endpoint Category | Limit |
|---|---|
| Login | 10 req / min |
| Forgot Password | 3 req / min |
| Reset Password | 5 req / min |
| Change Password | 5 req / min |
| OTP Send | 3 req / min |
| Other auth endpoints | 20 req / min |
# Returned on authentication endpoints (e.g. POST /auth/login):
HTTP/1.1 200 OK
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 8
X-RateLimit-Reset: 1719849600
# When exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 42
Content-Type: application/json
{
"statusCode": 429,
"message": "Rate limit exceeded. Retry after 42 seconds."
}Roles & Permissions
Access control is enforced via role-based authorization. Each user is assigned one system role, and may have additional per-client roles and permissions.
MASTER
- All ADMIN permissions
- Create / delete users
- Full non-paginated lists (/all routes)
ADMIN
- All USER permissions
- Create / update / delete clients
- Assign users to clients
- Create / export accounting records
- Delete accounting records
- Sync debtors / creditors
USER
- View own profile
- View assigned clients
- Read accounting records
- Read debtors / creditors
- Update own profile
VIEWER
- Read-only access
- View assigned clients
- Read accounting records
- Read debtors / creditors
Changelog
- Added Kladaten sync SSE streaming for debtors/creditors
- Added semantic vector search for entity name matching
- New export status tracking for accounting records
- Added Client Admin controller for delegated client management
- Batch user assignment to clients
- User role/permission updates per client relationship
- Added accounting records CRUD with line items
- Added debtors & creditors management
- Export to Azure Service Bus queue
- Advanced filtering (30+ query parameters)
- Initial release
- Authentication (API Keys, login, password reset)
- User management (CRUD, roles, profiles, avatars)
- Client management (CRUD, user assignment)
Users
4 endpointsGet current user profile
Retrieve the profile of the currently authenticated user including role, status, permissions, and profile metadata. Requires API key authentication.
curl -X GET "https://api.gfr.ai/v1/users/me" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "507f1f77bcf86cd799439011",
"email": "user@example.com",
"name": "John Doe",
"companyName": "GFR Software GmbH",
"phoneNumber": "+49123456789",
"role": "USER",
"status": "ACCEPTED",
"profile": {
"avatar": "https://storage.example.com/avatars/507f1f77.jpg",
"timezone": "Europe/Berlin"
},
"permissions": [
"users.read",
"documents.write"
],
"hasCompletedTour": true,
"notificationsEnabled": true,
"createdAt": "2024-09-01T00:00:00.000Z",
"updatedAt": "2025-06-20T10:30:00.000Z",
"lastLoginAt": "2025-06-20T08:15:00.000Z"
}Get the client assigned to user
Retrieve all client relationships for the authenticated user, including role, permissions, and client details. Requires API key authentication.
curl -X GET "https://api.gfr.ai/v1/users/me/relationships" \
-H "X-API-Key: YOUR_API_KEY"Response200
[
{
"clientId": "6904b56a068659ad2ec34548",
"role": "viewer",
"permissions": [
"documents.read"
],
"isActive": true,
"client": {
"id": "6904b56a068659ad2ec34548",
"clientName": "Contora GmbH",
"customer": {
"customerName": "Contora Group"
}
}
}
]Update current user profile
Update the profile of the currently authenticated user. All fields are optional — only provided fields will be updated. Requires API key authentication.
curl -X PATCH "https://api.gfr.ai/v1/users/me" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "John Updated",
"companyName": "GFR Software GmbH",
"phoneNumber": "+491778346763",
"profile": {
"timezone": "Europe/Berlin"
},
"notificationsEnabled": true,
"hasCompletedTour": true
}'Request Body
{
"name": "John Updated",
"companyName": "GFR Software GmbH",
"phoneNumber": "+491778346763",
"profile": {
"timezone": "Europe/Berlin"
},
"notificationsEnabled": true,
"hasCompletedTour": true
}Response200
{
"id": "507f1f77bcf86cd799439011",
"email": "user@example.com",
"name": "John Updated",
"companyName": "GFR Software GmbH",
"role": "USER",
"status": "ACCEPTED",
"notificationsEnabled": true,
"hasCompletedTour": true,
"updatedAt": "2025-06-20T15:00:00.000Z"
}Remove user from client
Remove a user from a client relationship. Requires API key authentication.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client ID to remove from |
curl -X DELETE "https://api.gfr.ai/v1/users/me/remove-client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"message": "Successfully removed from client"
}Clients
7 endpointsList all clients (paginated)
Retrieve a paginated list of all clients. Supports sorting by any field. Available to USER and ADMIN roles.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
page | integer | query | Page number, 1-based (default 1) |
limit | integer | query | Items per page, max 100 (default 25) |
sortBy | string | query | Field to sort by (e.g. clientName, createdAt) |
sortOrder | string | query | Sort order: asc | desc |
curl -X GET "https://api.gfr.ai/v1/clients" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"data": [
{
"id": "60d5ec49f1b2c72d88a1f3e7",
"customerId": "507f1f77bcf86cd799439011",
"clientName": "ABC Corp",
"status": "active",
"createdAt": "2025-06-20T15:00:00.000Z"
},
{
"id": "60d5ec49f1b2c72d88a1f3e8",
"customerId": "507f1f77bcf86cd799439011",
"clientName": "XYZ Services",
"status": "active",
"createdAt": "2025-05-10T09:00:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 25,
"total": 12,
"totalPages": 1
}
}Find client by ID
Retrieve full details for a single client including contact, settings, and accounting configuration.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The client's unique identifier |
curl -X GET "https://api.gfr.ai/v1/clients/{id}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "60d5ec49f1b2c72d88a1f3e7",
"customerId": "507f1f77bcf86cd799439011",
"clientName": "ABC Corp",
"contact": {
"address": "456 Business Ave",
"city": "Los Angeles",
"phone": "+1987654321",
"email": "contact@client.com"
},
"settings": {
"targetSystem": "SAP",
"accountingFramework": "IFRS",
"vatConfig": {
"vatId": "DE123456789",
"countryCode": "DE",
"hasFullVatDeduction": true,
"isVatIdVerified": true,
"vatIdVerifiedAt": "2025-06-15T10:30:00.000Z"
}
},
"accounting": {
"customerNumber": "CUST-001",
"clientNumber": "CLI-001",
"legalForm": "LLC",
"accNumLength": 6
},
"status": "active",
"createdAt": "2025-06-20T15:00:00.000Z",
"updatedAt": "2025-06-20T15:00:00.000Z"
}Get users for a client (paginated)
Retrieve a paginated list of all users assigned to a specific client.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The client's unique identifier |
page | integer | query | Page number, 1-based (default 1) |
limit | integer | query | Items per page, max 100 (default 25) |
curl -X GET "https://api.gfr.ai/v1/clients/{id}/users" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"data": [
{
"id": "507f1f77bcf86cd799439011",
"email": "john@example.com",
"name": "John Doe",
"role": "USER",
"status": "ACCEPTED"
}
],
"meta": {
"page": 1,
"limit": 25,
"total": 3,
"totalPages": 1
}
}Create a new client
Create a new client under a customer. Includes contact information, settings (target system, accounting framework, VAT config), and accounting configuration. Requires ADMIN role.
curl -X POST "https://api.gfr.ai/v1/clients" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "507f1f77bcf86cd799439011",
"clientName": "ABC Corp",
"contact": {
"address": "456 Business Ave",
"city": "Los Angeles",
"phone": "+1987654321",
"email": "contact@client.com"
},
"settings": {
"targetSystem": "SAP",
"accountingFramework": "IFRS",
"vatConfig": {
"vatId": "DE123456789",
"countryCode": "DE",
"hasFullVatDeduction": true
}
},
"accounting": {
"customerNumber": "CUST-001",
"clientNumber": "CLI-001",
"legalForm": "LLC",
"accNumLength": 6
},
"status": "active"
}'Request Body
{
"customerId": "507f1f77bcf86cd799439011",
"clientName": "ABC Corp",
"contact": {
"address": "456 Business Ave",
"city": "Los Angeles",
"phone": "+1987654321",
"email": "contact@client.com"
},
"settings": {
"targetSystem": "SAP",
"accountingFramework": "IFRS",
"vatConfig": {
"vatId": "DE123456789",
"countryCode": "DE",
"hasFullVatDeduction": true
}
},
"accounting": {
"customerNumber": "CUST-001",
"clientNumber": "CLI-001",
"legalForm": "LLC",
"accNumLength": 6
},
"status": "active"
}Response201
{
"id": "60d5ec49f1b2c72d88a1f3e7",
"customerId": "507f1f77bcf86cd799439011",
"clientName": "ABC Corp",
"contact": {
"address": "456 Business Ave",
"city": "Los Angeles",
"phone": "+1987654321",
"email": "contact@client.com"
},
"settings": {
"targetSystem": "SAP",
"accountingFramework": "IFRS"
},
"accounting": {
"customerNumber": "CUST-001",
"clientNumber": "CLI-001",
"legalForm": "LLC",
"accNumLength": 6
},
"status": "active",
"createdAt": "2025-06-20T15:00:00.000Z",
"updatedAt": "2025-06-20T15:00:00.000Z"
}Assign users to a client
Assign one or more users to a client with optional roles and permissions. Requires ADMIN role. Returns counts of assigned and skipped users.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The client's unique identifier |
curl -X POST "https://api.gfr.ai/v1/clients/{id}/assign-user" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"users": [
{
"userId": "507f1f77bcf86cd799439011",
"role": "manager",
"permissions": [
"documents.read",
"exports.create"
]
},
{
"userId": "507f1f77bcf86cd799439012",
"role": "viewer",
"permissions": [
"documents.read"
]
}
]
}'Request Body
{
"users": [
{
"userId": "507f1f77bcf86cd799439011",
"role": "manager",
"permissions": [
"documents.read",
"exports.create"
]
},
{
"userId": "507f1f77bcf86cd799439012",
"role": "viewer",
"permissions": [
"documents.read"
]
}
]
}Response200
{
"message": "Users assigned to client successfully",
"assigned": 2,
"skipped": 0,
"errors": []
}Update client
Update a client's details. All fields are optional — only provided fields will be updated. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The client's unique identifier |
curl -X PATCH "https://api.gfr.ai/v1/clients/{id}" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientName": "ABC Corp Updated",
"contact": {
"email": "new-contact@client.com"
},
"settings": {
"targetSystem": "DATEV",
"accountingFramework": "HGB"
}
}'Request Body
{
"clientName": "ABC Corp Updated",
"contact": {
"email": "new-contact@client.com"
},
"settings": {
"targetSystem": "DATEV",
"accountingFramework": "HGB"
}
}Response200
{
"id": "60d5ec49f1b2c72d88a1f3e7",
"clientName": "ABC Corp Updated",
"status": "active",
"updatedAt": "2025-06-20T16:00:00.000Z"
}Delete client
Permanently delete a client. This action cannot be undone. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The client's unique identifier |
curl -X DELETE "https://api.gfr.ai/v1/clients/{id}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "60d5ec49f1b2c72d88a1f3e7",
"clientName": "ABC Corp",
"status": "active",
"deletedAt": "2025-06-20T17:00:00.000Z"
}Files
7 endpointsList all files for a client
Retrieve all individual files belonging to a specific client with comprehensive filters and pagination. Supports filtering by origin system, file type, file name, MIME type, and status.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | query | Client ID (required) |
originSystem | string | query | Filter by origin: drop | providerApi |
fileType | string | query | Filter by file extension (e.g. pdf, xlsx, csv) |
fileName | string | query | Search by file name (partial match) |
mimeType | string | query | Filter by MIME type (e.g. application/pdf) |
status | string | query | Filter by status: UPLOADED | PROCESSING | PROCESSED | FAILED | DUPLICATE |
sortBy | string | query | Sort field: createdAt | fileName | size |
sortOrder | string | query | Sort order: asc | desc |
page | integer | query | Page number (default 1) |
limit | integer | query | Items per page (default 20) |
curl -X GET "https://api.gfr.ai/v1/files/files" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"data": [
{
"id": "683a1b2c3d4e5f6a7b8c9d0e",
"fileId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"fileBatchId": "683a1b2c3d4e5f6a7b8c9d0f",
"fileName": "1719849600000_a1b2c3d4.pdf",
"originalName": "rechnung_2025_06.pdf",
"mimeType": "application/pdf",
"fileType": "pdf",
"size": 245760,
"url": "https://storage.example.com/files/...",
"status": "PROCESSED",
"batchId": "f1e2d3c4-b5a6-7890-fedc-ba0987654321",
"originSystem": "DROP",
"createdAt": "2025-06-20T14:30:00.000Z",
"updatedAt": "2025-06-20T14:30:12.000Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 150,
"totalPages": 8
}
}List all file batches
Retrieve all file batches for the authenticated user and specified client with pagination. Each batch contains metadata about uploaded files grouped together.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | query | Client ID (required) |
originSystem | string | query | Filter by origin: drop | providerApi |
page | integer | query | Page number (default 1) |
limit | integer | query | Items per page (default 10) |
curl -X GET "https://api.gfr.ai/v1/files/batches" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"data": [
{
"batchId": "f1e2d3c4-b5a6-7890-fedc-ba0987654321",
"clientId": "507f1f77bcf86cd799439011",
"userId": "507f1f77bcf86cd799439022",
"originSystem": "DROP",
"fileCount": 5,
"status": "completed",
"createdAt": "2025-06-20T14:30:00.000Z",
"updatedAt": "2025-06-20T14:31:00.000Z"
},
{
"batchId": "a9b8c7d6-e5f4-3210-9876-fedcba098765",
"clientId": "507f1f77bcf86cd799439011",
"userId": "507f1f77bcf86cd799439022",
"originSystem": "PROVIDER_API",
"fileCount": 12,
"status": "completed",
"createdAt": "2025-06-19T10:15:00.000Z",
"updatedAt": "2025-06-19T10:17:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 10,
"total": 45,
"totalPages": 5
}
}Get a specific batch by ID
Retrieve details of a specific file batch including all files in the batch. Returns comprehensive information about the batch and all associated files.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
batchIdreq | string | path | Batch UUID |
clientIdreq | string | query | Client ID (required) |
curl -X GET "https://api.gfr.ai/v1/files/batches/{batchId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"batchId": "f1e2d3c4-b5a6-7890-fedc-ba0987654321",
"clientId": "507f1f77bcf86cd799439011",
"userId": "507f1f77bcf86cd799439022",
"originSystem": "DROP",
"fileCount": 3,
"status": "completed",
"files": [
{
"fileName": "1719849600000_a1b2c3d4.pdf",
"originalName": "rechnung_2025_06.pdf",
"mimeType": "application/pdf",
"fileType": "pdf",
"size": 245760,
"url": "https://storage.example.com/files/...",
"status": "UPLOADED"
},
{
"fileName": "1719849601000_b2c3d4e5.xlsx",
"originalName": "expenses_june.xlsx",
"mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"fileType": "xlsx",
"size": 52480,
"url": "https://storage.example.com/files/...",
"status": "UPLOADED"
},
{
"fileName": "1719849602000_c3d4e5f6.csv",
"originalName": "transactions.csv",
"mimeType": "text/csv",
"fileType": "csv",
"size": 12800,
"url": "https://storage.example.com/files/...",
"status": "UPLOADED"
}
],
"createdAt": "2025-06-20T14:30:00.000Z",
"updatedAt": "2025-06-20T14:30:02.000Z"
}Upload a single file
Upload a single file to Azure Storage using streaming (memory-efficient). Accepts multipart/form-data. If batchId is provided, adds the file to an existing batch; otherwise creates a new batch.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
Content-Typereq | multipart/form-data | header | Must be multipart/form-data |
clientIdreq | string | path | Client identifier |
batchId | string | query | Batch ID to add file to an existing batch. Omit to create a new batch. |
originSystem | string | query | Origin system: drop | providerApi (default drop, ignored if batchId provided) |
curl -X POST "https://api.gfr.ai/v1/files/upload/single/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response201
{
"batchId": "f1e2d3c4-b5a6-7890-fedc-ba0987654321",
"clientId": "507f1f77bcf86cd799439011",
"userId": "507f1f77bcf86cd799439022",
"originSystem": "DROP",
"fileCount": 1,
"status": "completed",
"files": [
{
"fileName": "1719849600000_a1b2c3d4.pdf",
"originalName": "rechnung_2025_06.pdf",
"mimeType": "application/pdf",
"fileType": "pdf",
"size": 245760,
"url": "https://storage.example.com/files/...",
"status": "UPLOADED"
}
],
"createdAt": "2025-06-20T14:30:00.000Z",
"updatedAt": "2025-06-20T14:30:00.000Z"
}Upload multiple files in bulk
Upload up to 10 files per request. First chunk creates a new batch and returns batchId. Use batchId in subsequent chunks to add files to the same batch. Accepts multipart/form-data with multiple files.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
Content-Typereq | multipart/form-data | header | Must be multipart/form-data |
clientIdreq | string | path | Client identifier |
batchId | string | query | Batch ID from first chunk. Omit to create a new batch. |
originSystem | string | query | Origin system: drop | providerApi (default drop, only used when creating new batch) |
curl -X POST "https://api.gfr.ai/v1/files/upload/bulk/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response201
{
"batchId": "f1e2d3c4-b5a6-7890-fedc-ba0987654321",
"clientId": "507f1f77bcf86cd799439011",
"userId": "507f1f77bcf86cd799439022",
"originSystem": "DROP",
"fileCount": 3,
"status": "completed",
"files": [
{
"fileName": "1719849600000_a1b2c3d4.pdf",
"originalName": "rechnung_2025_06.pdf",
"mimeType": "application/pdf",
"fileType": "pdf",
"size": 245760,
"url": "https://storage.example.com/files/...",
"status": "UPLOADED"
},
{
"fileName": "1719849601000_b2c3d4e5.xlsx",
"originalName": "expenses_june.xlsx",
"mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"fileType": "xlsx",
"size": 52480,
"url": "https://storage.example.com/files/...",
"status": "UPLOADED"
},
{
"fileName": "1719849602000_c3d4e5f6.csv",
"originalName": "transactions.csv",
"mimeType": "text/csv",
"fileType": "csv",
"size": 12800,
"url": "https://storage.example.com/files/...",
"status": "UPLOADED"
}
],
"createdAt": "2025-06-20T14:30:00.000Z",
"updatedAt": "2025-06-20T14:30:02.000Z"
}Delete a single file
Delete a specific file from a batch using its unique fileId. The file is removed from Azure Blob Storage and the database. If no files remain in the batch, the batch is automatically deleted.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
batchIdreq | string | path | Batch UUID |
fileIdreq | string | path | File UUID to delete |
clientIdreq | string | query | Client ID (required) |
curl -X DELETE "https://api.gfr.ai/v1/files/batches/{batchId}/files/by-id/{fileId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"message": "File deleted successfully"
}Delete a batch and all its files
Delete a batch record and all associated files from Azure Storage. This permanently removes all files in the batch and cannot be undone.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
batchIdreq | string | path | Batch UUID to delete |
clientIdreq | string | query | Client ID (required) |
curl -X DELETE "https://api.gfr.ai/v1/files/batches/{batchId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"message": "Batch deleted successfully"
}Accounting Records
7 endpointsList records for a client (paginated)
Retrieve a paginated, filterable list of accounting records for a specific client. Supports extensive filtering by date range, document type, amounts, counterparty, account numbers, VAT, export status, and more.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client's unique identifier |
page | integer | query | Page number, 1-based (default 1) |
limit | integer | query | Items per page, max 100 (default 25) |
startDate | string (ISO 8601) | query | Start date filter |
endDate | string (ISO 8601) | query | End date filter |
docType | string | query | Document type: RECHNUNG | GUTSCHRIFT | etc. |
minAmount | number | query | Minimum gross amount |
maxAmount | number | query | Maximum gross amount |
currency | string | query | Currency filter: EUR | USD | GBP | CHF | JPY |
exportStatus | string | query | Filter: PENDING | RDY_TO_EXPORT | EXPORTED | FAILED |
toCheck | boolean | query | Filter by toCheck flag |
counterpartyName | string | query | Counterparty name (partial match) |
curl -X GET "https://api.gfr.ai/v1/accounting-records/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"data": [
{
"id": "60d5ec49f1b2c72d88a1f3e9",
"clientId": "507f1f77bcf86cd799439011",
"docType": "RECHNUNG",
"docDate": "2024-01-15T00:00:00.000Z",
"docNum": "INV-2024-001",
"counterpartyName": "Business Partner Ltd",
"grossAmount": 1190,
"currency": "EUR",
"exportStatus": "PENDING",
"toCheck": false,
"lineItems": []
}
],
"meta": {
"page": 1,
"limit": 25,
"total": 134,
"totalPages": 6
}
}Find record by ID
Retrieve full details for a single accounting record including all line items. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The accounting record's unique identifier |
clientIdreq | string | path | The client's unique identifier |
curl -X GET "https://api.gfr.ai/v1/accounting-records/{id}/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "60d5ec49f1b2c72d88a1f3e9",
"clientId": "507f1f77bcf86cd799439011",
"docType": "RECHNUNG",
"docDate": "2024-01-15T00:00:00.000Z",
"docNum": "INV-2024-001",
"vatId": "DE123456789",
"iban": "DE89370400440532013000",
"senderName": "ABC Company Ltd",
"receiverName": "XYZ Services Ltd",
"counterpartyName": "Business Partner Ltd",
"counterpartyAddress": "123 Business St, Berlin, DE",
"grossAmount": 1190,
"currency": "EUR",
"exportStatus": "PENDING",
"toCheck": false,
"lineItems": [
{
"id": "li_001",
"vatRate": 19,
"vatAmount": 190,
"netAmount": 1000,
"quantity": 1,
"unitPrice": 1000,
"itemDirection": "debit",
"lineItemDescription": "Consulting services for Q1 2024",
"accountingCategory": "SERVICE",
"account": "4000",
"counterAccount": "1000",
"creditorNumber": "7000000"
}
],
"createdAt": "2025-06-20T15:00:00.000Z",
"updatedAt": "2025-06-20T15:00:00.000Z"
}Get records ready for export by period
Returns accounting records with PENDING export status grouped by month/year period. Useful for the export workflow UI. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client's unique identifier |
curl -X GET "https://api.gfr.ai/v1/accounting-records/client/{clientId}/ready-for-export" \
-H "X-API-Key: YOUR_API_KEY"Response200
[
{
"period": "3/2025",
"count": 3
},
{
"period": "4/2025",
"count": 2
},
{
"period": "5/2025",
"count": 7
}
]Get records by date range
Retrieve paginated accounting records within a specific date range. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client's unique identifier |
startDatereq | string (ISO 8601) | query | Start date (e.g. 2024-01-01T00:00:00.000Z) |
endDatereq | string (ISO 8601) | query | End date (e.g. 2024-12-31T23:59:59.999Z) |
page | integer | query | Page number (default 1) |
limit | integer | query | Items per page, max 100 (default 25) |
curl -X GET "https://api.gfr.ai/v1/accounting-records/client/{clientId}/date-range" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"data": [
{
"id": "60d5ec49f1b2c72d88a1f3e9",
"docType": "RECHNUNG",
"docDate": "2024-06-15T00:00:00.000Z",
"docNum": "INV-2024-042",
"grossAmount": 2380,
"currency": "EUR",
"exportStatus": "EXPORTED"
}
],
"meta": {
"page": 1,
"limit": 25,
"total": 42,
"totalPages": 2
}
}Export records to target system
Export all accounting records for the specified client that have docDate within the provided months and exportStatus = PENDING. Records are sent to Azure Service Bus for processing by the target system (DATEV, SAP, etc.).
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client's unique identifier |
curl -X POST "https://api.gfr.ai/v1/accounting-records/client/{clientId}/export" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"monthsArray": [
"3/2025",
"4/2025"
]
}'Request Body
{
"monthsArray": [
"3/2025",
"4/2025"
]
}Response200
{
"message": "Accounting records exported successfully",
"exported": 5,
"platform": "DATEV"
}Update accounting record
Update an accounting record and its line items. All fields are optional. Available to USER and ADMIN roles.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The accounting record's unique identifier |
clientIdreq | string | path | The client's unique identifier |
curl -X PATCH "https://api.gfr.ai/v1/accounting-records/{id}/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"counterpartyName": "Updated Partner GmbH",
"grossAmount": 1428,
"toCheck": true,
"lineItems": [
{
"vatRate": 19,
"vatAmount": 228,
"netAmount": 1200,
"quantity": 1,
"unitPrice": 1200,
"itemDirection": "debit",
"lineItemDescription": "Updated consulting services",
"account": "4000",
"counterAccount": "1000"
}
]
}'Request Body
{
"counterpartyName": "Updated Partner GmbH",
"grossAmount": 1428,
"toCheck": true,
"lineItems": [
{
"vatRate": 19,
"vatAmount": 228,
"netAmount": 1200,
"quantity": 1,
"unitPrice": 1200,
"itemDirection": "debit",
"lineItemDescription": "Updated consulting services",
"account": "4000",
"counterAccount": "1000"
}
]
}Response200
{
"id": "60d5ec49f1b2c72d88a1f3e9",
"clientId": "507f1f77bcf86cd799439011",
"counterpartyName": "Updated Partner GmbH",
"grossAmount": 1428,
"toCheck": true,
"exportStatus": "PENDING",
"updatedAt": "2025-06-20T16:00:00.000Z"
}Delete accounting record
Permanently delete an accounting record and all its line items. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The accounting record's unique identifier |
clientIdreq | string | path | The client's unique identifier |
curl -X DELETE "https://api.gfr.ai/v1/accounting-records/{id}/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "60d5ec49f1b2c72d88a1f3e9",
"docType": "RECHNUNG",
"docNum": "INV-2024-001",
"deletedAt": "2025-06-20T17:00:00.000Z"
}Debtors & Creditors
7 endpointsList debtors/creditors for a client (paginated)
Retrieve a paginated list of debtors and creditors for a specific client. Supports search by entity name.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client's unique identifier |
page | integer | query | Page number, 1-based (default 1) |
limit | integer | query | Items per page, max 100 (default 25) |
sortBy | string | query | Field to sort by |
sortOrder | string | query | Sort order: asc | desc |
entityName | string | query | Search by entity name (partial match) |
curl -X GET "https://api.gfr.ai/v1/debtors-creditors/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"data": [
{
"id": "60d5ec49f1b2c72d88a1f400",
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Business Partner Ltd",
"accounting": {
"senderNumber": "1000000",
"receiverNumber": "7000000"
},
"origin": "MANUAL",
"status": "active"
},
{
"id": "60d5ec49f1b2c72d88a1f401",
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Supplier GmbH",
"accounting": {
"senderNumber": "1000001",
"receiverNumber": "7000001"
},
"origin": "API",
"status": "active"
}
],
"meta": {
"page": 1,
"limit": 25,
"total": 89,
"totalPages": 4
}
}Search by entity name
Search for a debtor/creditor by entity name within a specific client. Returns the best match. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client's unique identifier |
entityNamereq | string | query | Entity name to search for |
curl -X GET "https://api.gfr.ai/v1/debtors-creditors/client/{clientId}/search" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "60d5ec49f1b2c72d88a1f400",
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Business Partner Ltd",
"accounting": {
"senderNumber": "1000000",
"receiverNumber": "7000000"
},
"taxInfo": {
"vatId": "DE123456789",
"isVatIdVerified": true
},
"banking": {
"iban": "DE89370400440532013000",
"isIbanVerified": true
},
"origin": "MANUAL",
"status": "active"
}Find debtor/creditor by ID
Retrieve full details for a single debtor/creditor record. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The debtor/creditor's unique identifier |
clientIdreq | string | path | The client's unique identifier |
curl -X GET "https://api.gfr.ai/v1/debtors-creditors/{id}/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "60d5ec49f1b2c72d88a1f400",
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Business Partner Ltd",
"accounting": {
"senderNumber": "1000000",
"receiverNumber": "7000000"
},
"taxInfo": {
"vatId": "DE123456789",
"isVatIdVerified": true
},
"banking": {
"iban": "DE89370400440532013000",
"isIbanVerified": true
},
"origin": "MANUAL",
"status": "active",
"createdAt": "2025-06-20T15:00:00.000Z",
"updatedAt": "2025-06-20T15:00:00.000Z"
}Create a debtor/creditor
Create a new debtor or creditor record with accounting numbers, tax info, and banking details. Available to USER and ADMIN roles.
curl -X POST "https://api.gfr.ai/v1/debtors-creditors" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Business Partner Ltd",
"accounting": {
"senderNumber": "1000000",
"receiverNumber": "7000000"
},
"taxInfo": {
"vatId": "DE123456789",
"isVatIdVerified": false
},
"banking": {
"iban": "DE89370400440532013000",
"isIbanVerified": false
},
"origin": "MANUAL",
"status": "active"
}'Request Body
{
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Business Partner Ltd",
"accounting": {
"senderNumber": "1000000",
"receiverNumber": "7000000"
},
"taxInfo": {
"vatId": "DE123456789",
"isVatIdVerified": false
},
"banking": {
"iban": "DE89370400440532013000",
"isIbanVerified": false
},
"origin": "MANUAL",
"status": "active"
}Response201
{
"id": "60d5ec49f1b2c72d88a1f400",
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Business Partner Ltd",
"accounting": {
"senderNumber": "1000000",
"receiverNumber": "7000000"
},
"taxInfo": {
"vatId": "DE123456789",
"isVatIdVerified": false
},
"banking": {
"iban": "DE89370400440532013000",
"isIbanVerified": false
},
"origin": "MANUAL",
"status": "active",
"createdAt": "2025-06-20T15:00:00.000Z",
"updatedAt": "2025-06-20T15:00:00.000Z"
}Sync from Kladaten (SSE)
Sync debtors/creditors from the Kladaten API with real-time progress streaming via Server-Sent Events (SSE). Uses paginated fetching and synchronous embedding generation. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
clientIdreq | string | path | The client's unique identifier |
fiscalYear | string | query | Fiscal year in YYYYMMDD format (default: 20250101) |
curl -X POST "https://api.gfr.ai/v1/debtors-creditors/client/{clientId}/sync-kladaten" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"_note": "SSE stream — events are delivered progressively",
"events": [
{
"type": "progress",
"phase": "fetching",
"message": "Fetching creditors page 1...",
"current": 1,
"total": 5,
"percentage": 20
},
{
"type": "progress",
"phase": "processing",
"message": "Processing 250 records...",
"current": 250,
"total": 500,
"percentage": 50
},
{
"type": "progress",
"phase": "embeddings",
"message": "Generating embeddings...",
"current": 500,
"total": 500,
"percentage": 100
},
{
"type": "complete",
"creditorsUpdated": 320,
"debtorsUpdated": 180,
"recordsCreated": 45,
"embeddingsGenerated": 500,
"duration": 12450
}
]
}Update debtor/creditor
Update a debtor/creditor record. All fields are optional. Available to USER and ADMIN roles.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The debtor/creditor's unique identifier |
clientIdreq | string | path | The client's unique identifier |
curl -X PATCH "https://api.gfr.ai/v1/debtors-creditors/{id}/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entityName": "Updated Partner GmbH",
"taxInfo": {
"vatId": "DE987654321",
"isVatIdVerified": true
},
"banking": {
"iban": "DE27100777770209299700",
"isIbanVerified": true
}
}'Request Body
{
"entityName": "Updated Partner GmbH",
"taxInfo": {
"vatId": "DE987654321",
"isVatIdVerified": true
},
"banking": {
"iban": "DE27100777770209299700",
"isIbanVerified": true
}
}Response200
{
"id": "60d5ec49f1b2c72d88a1f400",
"clientId": "507f1f77bcf86cd799439011",
"entityName": "Updated Partner GmbH",
"taxInfo": {
"vatId": "DE987654321",
"isVatIdVerified": true
},
"banking": {
"iban": "DE27100777770209299700",
"isIbanVerified": true
},
"updatedAt": "2025-06-20T16:00:00.000Z"
}Delete debtor/creditor
Permanently delete a debtor/creditor record. Requires ADMIN role.
Parameters
| Parameter | Type | In | Description |
|---|---|---|---|
idreq | string | path | The debtor/creditor's unique identifier |
clientIdreq | string | path | The client's unique identifier |
curl -X DELETE "https://api.gfr.ai/v1/debtors-creditors/{id}/client/{clientId}" \
-H "X-API-Key: YOUR_API_KEY"Response200
{
"id": "60d5ec49f1b2c72d88a1f400",
"entityName": "Business Partner Ltd",
"status": "active",
"deletedAt": "2025-06-20T17:00:00.000Z"
}