GFR.AIAPI
v1.3.0
Operational

Getting Started

API Reference

Users4

Clients7

Files7

Accounting Records7

Debtors & Creditors7

Base URL
https://api.gfr.ai/v1
RESTful API · JSON · HTTPS

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.

🌐 Base URL
https://api.gfr.ai/v1
🔑 Authentication
API Key (X-API-Key)
📦 Content-Type
application/json

Authentication

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
Get API Key
Log into GFR App → User Profile → Generate API Key
2
Save Securely
Copy and save your API key - it's only shown once
3
Use API Key
Include X-API-Key: {your_api_key} in request headers
4
Manage Keys
Regenerate or revoke keys from your profile anytime
Authentication Example
# 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.

CodeStatusDescription
400Bad RequestThe request body is invalid or missing required fields.
401UnauthorizedMissing or invalid API key.
403ForbiddenValid token but insufficient role/permissions.
404Not FoundThe requested resource does not exist.
409ConflictResource already exists (e.g. duplicate email).
422Unprocessable EntityValidation failed on one or more fields.
429Too Many RequestsRate limit exceeded. Retry after the indicated period.
500Internal Server ErrorAn unexpected error occurred on our side.
502Bad GatewayUpstream service unavailable (e.g. Kladaten API).
Error Response Format
{
  "statusCode": 401,
  "errorCode": "INVALID_CREDENTIALS",
  "message": "The email or password you entered is incorrect.",
  "timestamp": "2025-06-20T14:30:00.000Z"
}
Validation Error (422)
{
  "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.

ParameterDefaultDescription
page1Page number (1-based)
limit25Items per page (max 100)
sortBycreatedAtField to sort by
sortOrderdescasc or desc
Paginated Response
{
  "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 CategoryLimit
Login10 req / min
Forgot Password3 req / min
Reset Password5 req / min
Change Password5 req / min
OTP Send3 req / min
Other auth endpoints20 req / min
Rate Limit Headers (auth endpoints)
# 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

v1.3.02025-06-18
  • Added Kladaten sync SSE streaming for debtors/creditors
  • Added semantic vector search for entity name matching
  • New export status tracking for accounting records
v1.2.02025-05-02
  • Added Client Admin controller for delegated client management
  • Batch user assignment to clients
  • User role/permission updates per client relationship
v1.1.02025-03-15
  • Added accounting records CRUD with line items
  • Added debtors & creditors management
  • Export to Azure Service Bus queue
  • Advanced filtering (30+ query parameters)
v1.0.02025-01-10
  • Initial release
  • Authentication (API Keys, login, password reset)
  • User management (CRUD, roles, profiles, avatars)
  • Client management (CRUD, user assignment)
API Reference

Users

4 endpoints

Get current user profile

Retrieve the profile of the currently authenticated user including role, status, permissions, and profile metadata. Requires API key authentication.

API Key Required
200
cURL
curl -X GET "https://api.gfr.ai/v1/users/me" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
200
cURL
curl -X GET "https://api.gfr.ai/v1/users/me/relationships" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
[
  {
    "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.

API Key Required
200
cURL
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
JSON
{
  "name": "John Updated",
  "companyName": "GFR Software GmbH",
  "phoneNumber": "+491778346763",
  "profile": {
    "timezone": "Europe/Berlin"
  },
  "notificationsEnabled": true,
  "hasCompletedTour": true
}
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client ID to remove from
200
cURL
curl -X DELETE "https://api.gfr.ai/v1/users/me/remove-client/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "message": "Successfully removed from client"
}

Clients

7 endpoints

List all clients (paginated)

Retrieve a paginated list of all clients. Supports sorting by any field. Available to USER and ADMIN roles.

API Key Required
Parameters
ParameterTypeInDescription
page
integerqueryPage number, 1-based (default 1)
limit
integerqueryItems per page, max 100 (default 25)
sortBy
stringqueryField to sort by (e.g. clientName, createdAt)
sortOrder
stringquerySort order: asc | desc
200
cURL
curl -X GET "https://api.gfr.ai/v1/clients" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe client's unique identifier
200
cURL
curl -X GET "https://api.gfr.ai/v1/clients/{id}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe client's unique identifier
page
integerqueryPage number, 1-based (default 1)
limit
integerqueryItems per page, max 100 (default 25)
200
cURL
curl -X GET "https://api.gfr.ai/v1/clients/{id}/users" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
201
cURL
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
JSON
{
  "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
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe client's unique identifier
200
cURL
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
JSON
{
  "users": [
    {
      "userId": "507f1f77bcf86cd799439011",
      "role": "manager",
      "permissions": [
        "documents.read",
        "exports.create"
      ]
    },
    {
      "userId": "507f1f77bcf86cd799439012",
      "role": "viewer",
      "permissions": [
        "documents.read"
      ]
    }
  ]
}
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe client's unique identifier
200
cURL
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
JSON
{
  "clientName": "ABC Corp Updated",
  "contact": {
    "email": "new-contact@client.com"
  },
  "settings": {
    "targetSystem": "DATEV",
    "accountingFramework": "HGB"
  }
}
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe client's unique identifier
200
cURL
curl -X DELETE "https://api.gfr.ai/v1/clients/{id}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "id": "60d5ec49f1b2c72d88a1f3e7",
  "clientName": "ABC Corp",
  "status": "active",
  "deletedAt": "2025-06-20T17:00:00.000Z"
}

Files

7 endpoints

List 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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringqueryClient ID (required)
originSystem
stringqueryFilter by origin: drop | providerApi
fileType
stringqueryFilter by file extension (e.g. pdf, xlsx, csv)
fileName
stringquerySearch by file name (partial match)
mimeType
stringqueryFilter by MIME type (e.g. application/pdf)
status
stringqueryFilter by status: UPLOADED | PROCESSING | PROCESSED | FAILED | DUPLICATE
sortBy
stringquerySort field: createdAt | fileName | size
sortOrder
stringquerySort order: asc | desc
page
integerqueryPage number (default 1)
limit
integerqueryItems per page (default 20)
200
cURL
curl -X GET "https://api.gfr.ai/v1/files/files" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringqueryClient ID (required)
originSystem
stringqueryFilter by origin: drop | providerApi
page
integerqueryPage number (default 1)
limit
integerqueryItems per page (default 10)
200
cURL
curl -X GET "https://api.gfr.ai/v1/files/batches" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
batchIdreq
stringpathBatch UUID
clientIdreq
stringqueryClient ID (required)
200
cURL
curl -X GET "https://api.gfr.ai/v1/files/batches/{batchId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
Content-Typereq
multipart/form-dataheaderMust be multipart/form-data
clientIdreq
stringpathClient identifier
batchId
stringqueryBatch ID to add file to an existing batch. Omit to create a new batch.
originSystem
stringqueryOrigin system: drop | providerApi (default drop, ignored if batchId provided)
201
cURL
curl -X POST "https://api.gfr.ai/v1/files/upload/single/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response201
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
Content-Typereq
multipart/form-dataheaderMust be multipart/form-data
clientIdreq
stringpathClient identifier
batchId
stringqueryBatch ID from first chunk. Omit to create a new batch.
originSystem
stringqueryOrigin system: drop | providerApi (default drop, only used when creating new batch)
201
cURL
curl -X POST "https://api.gfr.ai/v1/files/upload/bulk/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response201
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
batchIdreq
stringpathBatch UUID
fileIdreq
stringpathFile UUID to delete
clientIdreq
stringqueryClient ID (required)
200
cURL
curl -X DELETE "https://api.gfr.ai/v1/files/batches/{batchId}/files/by-id/{fileId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
batchIdreq
stringpathBatch UUID to delete
clientIdreq
stringqueryClient ID (required)
200
cURL
curl -X DELETE "https://api.gfr.ai/v1/files/batches/{batchId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "message": "Batch deleted successfully"
}

Accounting Records

7 endpoints

List 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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client's unique identifier
page
integerqueryPage number, 1-based (default 1)
limit
integerqueryItems per page, max 100 (default 25)
startDate
string (ISO 8601)queryStart date filter
endDate
string (ISO 8601)queryEnd date filter
docType
stringqueryDocument type: RECHNUNG | GUTSCHRIFT | etc.
minAmount
numberqueryMinimum gross amount
maxAmount
numberqueryMaximum gross amount
currency
stringqueryCurrency filter: EUR | USD | GBP | CHF | JPY
exportStatus
stringqueryFilter: PENDING | RDY_TO_EXPORT | EXPORTED | FAILED
toCheck
booleanqueryFilter by toCheck flag
counterpartyName
stringqueryCounterparty name (partial match)
200
cURL
curl -X GET "https://api.gfr.ai/v1/accounting-records/client/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe accounting record's unique identifier
clientIdreq
stringpathThe client's unique identifier
200
cURL
curl -X GET "https://api.gfr.ai/v1/accounting-records/{id}/client/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client's unique identifier
200
cURL
curl -X GET "https://api.gfr.ai/v1/accounting-records/client/{clientId}/ready-for-export" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
[
  {
    "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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client's unique identifier
startDatereq
string (ISO 8601)queryStart date (e.g. 2024-01-01T00:00:00.000Z)
endDatereq
string (ISO 8601)queryEnd date (e.g. 2024-12-31T23:59:59.999Z)
page
integerqueryPage number (default 1)
limit
integerqueryItems per page, max 100 (default 25)
200
cURL
curl -X GET "https://api.gfr.ai/v1/accounting-records/client/{clientId}/date-range" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.).

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client's unique identifier
200
cURL
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
JSON
{
  "monthsArray": [
    "3/2025",
    "4/2025"
  ]
}
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe accounting record's unique identifier
clientIdreq
stringpathThe client's unique identifier
200
cURL
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
JSON
{
  "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
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe accounting record's unique identifier
clientIdreq
stringpathThe client's unique identifier
200
cURL
curl -X DELETE "https://api.gfr.ai/v1/accounting-records/{id}/client/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "id": "60d5ec49f1b2c72d88a1f3e9",
  "docType": "RECHNUNG",
  "docNum": "INV-2024-001",
  "deletedAt": "2025-06-20T17:00:00.000Z"
}

Debtors & Creditors

7 endpoints

List debtors/creditors for a client (paginated)

Retrieve a paginated list of debtors and creditors for a specific client. Supports search by entity name.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client's unique identifier
page
integerqueryPage number, 1-based (default 1)
limit
integerqueryItems per page, max 100 (default 25)
sortBy
stringqueryField to sort by
sortOrder
stringquerySort order: asc | desc
entityName
stringquerySearch by entity name (partial match)
200
cURL
curl -X GET "https://api.gfr.ai/v1/debtors-creditors/client/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client's unique identifier
entityNamereq
stringqueryEntity name to search for
200
cURL
curl -X GET "https://api.gfr.ai/v1/debtors-creditors/client/{clientId}/search" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe debtor/creditor's unique identifier
clientIdreq
stringpathThe client's unique identifier
200
cURL
curl -X GET "https://api.gfr.ai/v1/debtors-creditors/{id}/client/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "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.

API Key Required
201
cURL
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
JSON
{
  "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
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
clientIdreq
stringpathThe client's unique identifier
fiscalYear
stringqueryFiscal year in YYYYMMDD format (default: 20250101)
200
cURL
curl -X POST "https://api.gfr.ai/v1/debtors-creditors/client/{clientId}/sync-kladaten" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "_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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe debtor/creditor's unique identifier
clientIdreq
stringpathThe client's unique identifier
200
cURL
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
JSON
{
  "entityName": "Updated Partner GmbH",
  "taxInfo": {
    "vatId": "DE987654321",
    "isVatIdVerified": true
  },
  "banking": {
    "iban": "DE27100777770209299700",
    "isIbanVerified": true
  }
}
Response200
Response
{
  "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.

API Key Required
Parameters
ParameterTypeInDescription
idreq
stringpathThe debtor/creditor's unique identifier
clientIdreq
stringpathThe client's unique identifier
200
cURL
curl -X DELETE "https://api.gfr.ai/v1/debtors-creditors/{id}/client/{clientId}" \
  -H "X-API-Key: YOUR_API_KEY"
Response200
Response
{
  "id": "60d5ec49f1b2c72d88a1f400",
  "entityName": "Business Partner Ltd",
  "status": "active",
  "deletedAt": "2025-06-20T17:00:00.000Z"
}

Support

Questions or issues? api@gfr.ai

Status

gfr.ai/status

 

© 2026 GFR Software GmbH