Download OpenAPI specification:
The openHandwerk REST API provides programmatic access to the openHandwerk platform, enabling integration with craft-business management features such as customers, projects, appointments, documents, products, suppliers, and employee management.
All endpoints (except /auth/login and /auth/register)
require a valid JWT Bearer token in the Authorization header.
POST /auth/login.Authorization: Bearer <token>.The token is validated both as a JWT signature and against a server-side token store.
Every JSON response follows a standard envelope:
{
"success": true,
"response": { ... },
"status": 200
}
On error:
{
"success": false,
"response": "Error message",
"status": 400
}
Validates the provided credentials against the openHandwerk account store.
On success, returns a JWT bearer token that must be included in the
Authorization header of all subsequent requests.
| idKn required | string Account / tenant identifier. |
| employee required | string Employee username or identifier within the tenant. |
| password required | string <password> User password. |
{- "idKn": "ACME-001",
- "employee": "jdoe",
- "password": "s3cret!"
}{- "success": true,
- "response": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJBQ01FLTAwMS06Oi1qZG9lIiwiaWF0IjoxNzExMDAwMDAwLCJleHAiOjE3MTEwODY0MDB9.XXXX",
- "status": 200
}Creates a new API user account within the specified tenant.
The user will be able to log in via POST /auth/login after registration.
| idKn required | string Account / tenant identifier. |
| email required | string <email> User e-mail address. |
| employee required | string Employee username. |
| password required | string <password> Desired password. |
{- "idKn": "ACME-001",
- "email": "jdoe@example.com",
- "employee": "jdoe",
- "password": "s3cret!"
}{- "success": true,
- "response": "new user created successfully",
- "status": 200
}Looks up the given token string in the token store and returns the associated account identifier.
| token required | string Example: token=eyJhbGciOiJIUzI1NiIs... The JWT token string to look up. |
{- "success": true,
- "response": {
- "token": "eyJhbGciOiJIUzI1NiIs...",
- "account_id": "ACME-001"
}, - "status": 200
}Returns all employees for the authenticated tenant. Supports optional filtering by email, name, company, and role.
| eamil | string Example: eamil=jdoe@example.com Filter by employee email address (LIKE match). Note — parameter name reflects the API implementation. |
| name | string Example: name=Doe Filter by employee name (LIKE match). |
| company | string Example: company=ACME Filter by company name (LIKE match). |
| role | string Enum: "Administrator" "App" "Employee" Example: role=Administrator Filter by role. Accepted values: |
{- "success": true,
- "response": [
- {
- "id": 7,
- "name": "John Doe",
- "email": "jdoe@example.com",
- "company": "ACME GmbH",
- "role": "Employee"
}
], - "status": 200
}Returns detailed information about a single employee by ID.
| id required | integer Example: 7 Employee ID. |
{- "success": true,
- "response": {
- "id": 7,
- "name": "John Doe",
- "email": "jdoe@example.com",
- "company": "ACME GmbH",
- "role": "Employee"
}, - "status": 200
}Returns a combined listing of both orders and offers for the authenticated tenant.
Use the type parameter to filter to only orders or only offers.
| reference_number | string Example: reference_number=ORD-2025 Filter by reference number (LIKE match). |
| project_name | string Example: project_name=Kitchen Filter by project name (LIKE match). |
| id | integer Example: id=101 Filter by exact project ID. |
| type | string Enum: "order" "orders" "offer" "offers" Restrict results to only orders or only offers. |
{- "success": true,
- "response": {
- "offers": [
- {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}
], - "orders": [
- {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}
]
}, - "status": 200
}Searches across both orders and offers for a matching project. Returns the first matching result.
| projectTerm required | string Search term to match against project name, reference number, etc. |
{- "projectTerm": "Kitchen Renovation"
}{- "success": true,
- "response": {
- "data": {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}
}, - "status": 200
}Provides granular search across orders and offers using multiple filter fields. Results include standard rows for orders and extended rows (with nested tenant, address, client, and dates) for offers.
| tenant_name | string |
| tenant_email | string |
| tenant_phone | string |
| order_number | string |
| project_name | string |
| street | string |
| zip | string |
| city | string |
| country | string |
| reference_number | string |
| customer_number | string |
| company | string |
| contact_person | string |
| client_name | string |
| branch | string |
| search_type | string Default: "all" Enum: "all" "orders" "offers" Restrict results to orders, offers, or both. |
{- "tenant_name": "Mustermann",
- "city": "Berlin",
- "search_type": "all"
}{- "success": true,
- "response": {
- "total_results": 5,
- "orders_count": 3,
- "offers_count": 2,
- "results": {
- "orders": [
- {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}
], - "offers": [
- {
- "id": 202,
- "type": "offer",
- "reference_number": "OFF-2025-0018",
- "project_name": "Bathroom Remodel",
- "status": "pending",
- "archiv": "0",
- "description": "Complete bathroom remodel for unit 3B",
- "offer_number": "ANG-0018",
- "offer_id": 55,
- "tenant": {
- "name": "Max Mustermann",
- "email": "max@example.com",
- "number": "T-001",
- "phones": [
- {
- "number": "+49 170 1234567",
- "description": "Mobile"
}
]
}, - "address": {
- "street": "Musterstraße 12",
- "zip": "10115",
- "city": "Berlin",
- "country": "Deutschland",
- "location": ""
}, - "client": {
- "name": "Musterbau GmbH",
- "customer_number": "KD-1001",
- "company": "Musterbau GmbH",
- "branch": "Berlin-Mitte",
- "contact_person": "Erika Muster",
- "salutation": "Frau"
}, - "dates": {
- "order_date": "2025-03-01",
- "completion_date": "2025-06-15",
- "offer_date": "2025-02-20"
}
}
]
}
}, - "status": 200
}Creates a new project by proxying the request to the openHandwerk cloud backend.
Requires both a project and customer object in the request body.
| project required | object Project / order details forwarded to the openHandwerk backend. |
| customer required | object Customer details for the new project. |
{- "project": {
- "project_name": "New Kitchen Install",
- "reference_number": "ORD-2025-0099"
}, - "customer": {
- "first_name": "Max",
- "last_name": "Mustermann",
- "email": "max@example.com"
}
}{- "success": true,
- "response": { },
- "status": 200
}Returns all orders (Aufträge) for the authenticated tenant with optional filters.
| reference_number | string Filter by reference number (LIKE match). |
| project_name | string Filter by project name (LIKE match). |
| id | integer Filter by exact order ID. |
{- "success": true,
- "response": [
- {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}
], - "status": 200
}Returns detailed information about a specific order by ID.
| id required | integer Example: 101 Order ID. |
{- "success": true,
- "response": {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}, - "status": 200
}Returns all offers (Angebote) for the authenticated tenant with optional filters.
| reference_number | string Filter by reference number (LIKE match). |
| project_name | string Filter by project name (LIKE match). |
| id | integer Filter by exact offer ID. |
{- "success": true,
- "response": [
- {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}
], - "status": 200
}Returns detailed information about a specific offer by ID.
| id required | integer Example: 202 Offer ID. |
{- "success": true,
- "response": {
- "id": 101,
- "order_reference": "ORD-2025-0042",
- "reference_number": "ORD-2025-0042",
- "type": "order",
- "project_name": "Kitchen Renovation",
- "status": "active",
- "archiv": "0",
- "mieter": "Max Mustermann",
- "email_mieter": "max@example.com",
- "strasse": "Musterstraße 12",
- "plz": "10115",
- "ort": "Berlin",
- "land": "Deutschland",
- "anrede": "Herr",
- "company": "Musterbau GmbH"
}, - "status": 200
}Returns all customers for the authenticated tenant. Supports a wide range of optional LIKE filters and category-based filtering.
| company | string Filter by company name (LIKE). |
| city | string Filter by city (LIKE). |
| country | string Filter by country (LIKE). |
| branch | string Filter by branch (LIKE). |
string Filter by email (LIKE). | |
| customer_reference | string Filter by customer reference (LIKE). |
| website | string Filter by website (LIKE). |
| address | string Filter by street address (LIKE, maps to street column). |
| zip | string Filter by postal code (LIKE). |
| first_name | string Filter by first name (LIKE). |
| last_name | string Filter by last name (LIKE). |
| phone | string Filter by phone number (LIKE). |
| mobile | string Filter by mobile number (LIKE). |
| fax | string Filter by fax number (LIKE). |
| phone_private | string Filter by private phone number (LIKE). |
| contact_person | string Filter by contact person (LIKE). |
| id | integer Filter by exact customer ID. |
| polling | string Enum: "1" "true" If truthy, returns only customers created in the last 24 hours. |
| category | string Enum: "Auftraggeber" "Rechnungsempfänger" "Leistungsempfänger" "Lieferscheinempfänger" "Leistungsscheinempfänger" Filter by customer category (German category name). |
{- "success": true,
- "response": [
- {
- "id": 501,
- "customer_reference": "KD-1001",
- "type": "company",
- "category": "Auftraggeber",
- "salutation": "Herr",
- "first_name": "Max",
- "last_name": "Mustermann",
- "full_name": "Max Mustermann",
- "email": "max@example.com",
- "phone": "+49 30 123456",
- "mobile": "+49 170 1234567",
- "fax": "+49 30 123457",
- "phone_private": "+49 30 654321",
- "street": "Musterstraße 12",
- "co": "",
- "zip": 10115,
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Musterbau GmbH",
- "branch": "Berlin-Mitte",
- "contact_person": "Erika Muster",
- "tax_id": "DE123456789",
- "tax_category": 1,
- "ust_id": "DE987654321"
}
], - "status": 200
}Returns detailed information about a single customer by ID.
| id required | integer Example: 501 Customer ID. |
{- "success": true,
- "response": {
- "id": 501,
- "customer_reference": "KD-1001",
- "type": "company",
- "category": "Auftraggeber",
- "salutation": "Herr",
- "first_name": "Max",
- "last_name": "Mustermann",
- "full_name": "Max Mustermann",
- "email": "max@example.com",
- "phone": "+49 30 123456",
- "mobile": "+49 170 1234567",
- "fax": "+49 30 123457",
- "phone_private": "+49 30 654321",
- "street": "Musterstraße 12",
- "co": "",
- "zip": 10115,
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Musterbau GmbH",
- "branch": "Berlin-Mitte",
- "contact_person": "Erika Muster",
- "tax_id": "DE123456789",
- "tax_category": 1,
- "ust_id": "DE987654321"
}, - "status": 200
}Performs a quick search across customer names, companies, and emails using the provided search term in the URL path.
| searchTerm required | string Example: Muster The search term to match. |
{- "success": true,
- "response": {
- "total_results": 2,
- "search_term": "Muster",
- "results": [
- {
- "id": 501,
- "customer_reference": "KD-1001",
- "type": "company",
- "category": "Auftraggeber",
- "salutation": "Herr",
- "first_name": "Max",
- "last_name": "Mustermann",
- "full_name": "Max Mustermann",
- "email": "max@example.com",
- "phone": "+49 30 123456",
- "mobile": "+49 170 1234567",
- "fax": "+49 30 123457",
- "phone_private": "+49 30 654321",
- "street": "Musterstraße 12",
- "co": "",
- "zip": 10115,
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Musterbau GmbH",
- "branch": "Berlin-Mitte",
- "contact_person": "Erika Muster",
- "tax_id": "DE123456789",
- "tax_category": 1,
- "ust_id": "DE987654321"
}
]
}, - "status": 200
}Searches customers by a given term with optional exact-match mode. The search is performed across name, company, email, and other key fields.
| search required | string Search term (applied to name, company, email, etc.). |
| exact_match | boolean Default: false If true, performs an exact-match search instead of LIKE. |
{- "search": "Mustermann",
- "exact_match": false
}{- "success": true,
- "response": {
- "total_results": 3,
- "search_term": "Mustermann",
- "exact_match": false,
- "results": [
- {
- "id": 501,
- "customer_reference": "KD-1001",
- "type": "company",
- "category": "Auftraggeber",
- "salutation": "Herr",
- "first_name": "Max",
- "last_name": "Mustermann",
- "full_name": "Max Mustermann",
- "email": "max@example.com",
- "phone": "+49 30 123456",
- "mobile": "+49 170 1234567",
- "fax": "+49 30 123457",
- "phone_private": "+49 30 654321",
- "street": "Musterstraße 12",
- "co": "",
- "zip": 10115,
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Musterbau GmbH",
- "branch": "Berlin-Mitte",
- "contact_person": "Erika Muster",
- "tax_id": "DE123456789",
- "tax_category": 1,
- "ust_id": "DE987654321"
}
]
}, - "status": 200
}Creates a new customer record for the authenticated tenant.
The type field is required to distinguish between company and person contacts.
| type required | string Enum: "company" "person" Whether this customer is a company or natural person. |
| first_name | string |
| last_name | string |
| salutation | string |
| company | string |
| branch | string |
string <email> | |
| street | string Street name. |
| street_nr | integer House number. |
| zip | integer |
| city | string |
| country | string |
| co | string |
| customer_reference | string |
| phone_private | string |
| fax | string |
| tax_id | string |
| ust_id | string |
| tax_category | integer [ 1 .. 9 ] |
{- "type": "company",
- "first_name": "Max",
- "last_name": "Mustermann",
- "company": "Musterbau GmbH",
- "email": "max@example.com",
- "street": "Musterstraße",
- "street_nr": 12,
- "zip": 10115,
- "city": "Berlin",
- "country": "Deutschland"
}{- "success": true,
- "response": {
- "id": 501,
- "customer_reference": "KD-1001",
- "type": "company",
- "category": "Auftraggeber",
- "salutation": "Herr",
- "first_name": "Max",
- "last_name": "Mustermann",
- "full_name": "Max Mustermann",
- "email": "max@example.com",
- "phone": "+49 30 123456",
- "mobile": "+49 170 1234567",
- "fax": "+49 30 123457",
- "phone_private": "+49 30 654321",
- "street": "Musterstraße 12",
- "co": "",
- "zip": 10115,
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Musterbau GmbH",
- "branch": "Berlin-Mitte",
- "contact_person": "Erika Muster",
- "tax_id": "DE123456789",
- "tax_category": 1,
- "ust_id": "DE987654321"
}, - "status": 200
}Partially updates an existing customer. Only the provided fields will be modified.
| id required | integer Example: 501 Customer ID. |
| type | string Enum: "company" "person" |
| first_name | string |
| last_name | string |
| salutation | string |
| company | string |
| branch | string |
string <email> | |
| street | string |
| street_nr | integer |
| zip | integer |
| city | string |
| country | string |
| co | string |
| customer_reference | string |
| phone_private | string |
| fax | string |
| tax_id | string |
| ust_id | string |
| tax_category | integer [ 1 .. 9 ] |
{- "email": "updated@example.com",
- "city": "Munich"
}{- "success": true,
- "response": {
- "id": 501,
- "customer_reference": "KD-1001",
- "type": "company",
- "category": "Auftraggeber",
- "salutation": "Herr",
- "first_name": "Max",
- "last_name": "Mustermann",
- "full_name": "Max Mustermann",
- "email": "max@example.com",
- "phone": "+49 30 123456",
- "mobile": "+49 170 1234567",
- "fax": "+49 30 123457",
- "phone_private": "+49 30 654321",
- "street": "Musterstraße 12",
- "co": "",
- "zip": 10115,
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Musterbau GmbH",
- "branch": "Berlin-Mitte",
- "contact_person": "Erika Muster",
- "tax_id": "DE123456789",
- "tax_category": 1,
- "ust_id": "DE987654321"
}, - "status": 200
}Returns all suppliers for the authenticated tenant.
{- "success": true,
- "response": [
- {
- "id": 301,
- "supplier_reference": "LF-2001",
- "type": "company",
- "salutation": "Herr",
- "first_name": "Hans",
- "last_name": "Lieferant",
- "email": "hans@lieferant.de",
- "phone": "+49 30 555555",
- "street": "Lieferstraße 5",
- "zip": "10117",
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Lieferant GmbH",
- "branch": "Hauptniederlassung"
}
], - "status": 200
}Returns detailed information about a single supplier by ID.
| id required | integer Example: 301 Supplier ID. |
{- "success": true,
- "response": {
- "id": 301,
- "supplier_reference": "LF-2001",
- "type": "company",
- "salutation": "Herr",
- "first_name": "Hans",
- "last_name": "Lieferant",
- "email": "hans@lieferant.de",
- "phone": "+49 30 555555",
- "street": "Lieferstraße 5",
- "zip": "10117",
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Lieferant GmbH",
- "branch": "Hauptniederlassung"
}, - "status": 200
}Creates a new supplier record. first_name and last_name are required.
Optionally pass a ligId to create an external LIG reference.
| first_name required | string |
| last_name required | string |
| salutation | string |
string <email> | |
| phone | string |
| website | string |
| street | string |
| street_number | string |
| zip | string |
| city | string |
| country | string |
| company | string |
| branch | string |
| ligId | string Optional external reference ID for LIG integration. |
{- "first_name": "Hans",
- "last_name": "Lieferant",
- "company": "Lieferant GmbH",
- "email": "hans@lieferant.de",
- "street": "Lieferstraße",
- "street_number": "5",
- "zip": "10117",
- "city": "Berlin",
- "country": "Deutschland"
}{- "success": true,
- "response": {
- "id": 301,
- "supplier_reference": "LF-2001",
- "type": "company",
- "salutation": "Herr",
- "first_name": "Hans",
- "last_name": "Lieferant",
- "email": "hans@lieferant.de",
- "phone": "+49 30 555555",
- "street": "Lieferstraße 5",
- "zip": "10117",
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Lieferant GmbH",
- "branch": "Hauptniederlassung"
}, - "status": 200
}Partially updates an existing supplier. Only the provided fields will be modified.
| id required | integer Example: 301 Supplier ID. |
| first_name | string |
| last_name | string |
| salutation | string |
string <email> | |
| phone | string |
| website | string |
| street | string |
| street_number | string |
| zip | string |
| city | string |
| country | string |
| company | string |
| branch | string |
{- "email": "updated@lieferant.de",
- "city": "Hamburg"
}{- "success": true,
- "response": {
- "id": 301,
- "supplier_reference": "LF-2001",
- "type": "company",
- "salutation": "Herr",
- "first_name": "Hans",
- "last_name": "Lieferant",
- "email": "hans@lieferant.de",
- "phone": "+49 30 555555",
- "street": "Lieferstraße 5",
- "zip": "10117",
- "city": "Berlin",
- "country": "Deutschland",
- "company": "Lieferant GmbH",
- "branch": "Hauptniederlassung"
}, - "status": 200
}Returns all products / service items for the authenticated tenant.
{- "success": true,
- "response": [
- {
- "id": 401,
- "name": "Sanitärinstallation Standard",
- "manufacturer_name": "Grohe",
- "product_reference": "PROD-5001",
- "long_text": "Standard Sanitärinstallation inkl. Anschluss",
- "unit": "Stk",
- "unit_price": 125.5,
- "ust": 0.19,
- "buying_price": 85,
- "category": "Sanitär",
- "supplier_name": "Lieferant GmbH"
}
], - "status": 200
}Returns detailed information about a single product by ID.
| id required | integer Example: 401 Product ID. |
{- "success": true,
- "response": {
- "id": 401,
- "name": "Sanitärinstallation Standard",
- "manufacturer_name": "Grohe",
- "product_reference": "PROD-5001",
- "long_text": "Standard Sanitärinstallation inkl. Anschluss",
- "unit": "Stk",
- "unit_price": 125.5,
- "ust": 0.19,
- "buying_price": 85,
- "category": "Sanitär",
- "supplier_name": "Lieferant GmbH"
}, - "status": 200
}Creates a new product / service item. Optionally pass a ligId
to create an external LIG reference.
| name required | string |
| unit required | string |
| unit_price required | number <float> |
| buying_price required | number <float> |
| ust | number <float> VAT rate as decimal (e.g. 0.19). Stored internally as integer hundredths. |
| product_reference | string |
| long_text | string |
| manufacturer_name | string |
| category | string |
| supplier_name | string |
| ligId | string Optional external reference ID for LIG integration. |
{- "name": "Sanitärinstallation Standard",
- "unit": "Stk",
- "unit_price": 125.5,
- "buying_price": 85,
- "ust": 0.19,
- "manufacturer_name": "Grohe",
- "category": "Sanitär"
}{- "success": true,
- "response": {
- "id": 401,
- "name": "Sanitärinstallation Standard",
- "manufacturer_name": "Grohe",
- "product_reference": "PROD-5001",
- "long_text": "Standard Sanitärinstallation inkl. Anschluss",
- "unit": "Stk",
- "unit_price": 125.5,
- "ust": 0.19,
- "buying_price": 85,
- "category": "Sanitär",
- "supplier_name": "Lieferant GmbH"
}, - "status": 200
}Partially updates an existing product. Only the provided fields will be modified.
| id required | integer Example: 401 Product ID. |
| name | string |
| unit | string |
| unit_price | number <float> |
| buying_price | number <float> |
| ust | number <float> |
| product_reference | string |
| long_text | string |
| manufacturer_name | string |
| category | string |
| supplier_name | string |
{- "unit_price": 130,
- "ust": 0.19
}{- "success": true,
- "response": {
- "id": 401,
- "name": "Sanitärinstallation Standard",
- "manufacturer_name": "Grohe",
- "product_reference": "PROD-5001",
- "long_text": "Standard Sanitärinstallation inkl. Anschluss",
- "unit": "Stk",
- "unit_price": 125.5,
- "ust": 0.19,
- "buying_price": 85,
- "category": "Sanitär",
- "supplier_name": "Lieferant GmbH"
}, - "status": 200
}Returns all available appointment/calendar categories. Optionally filter by category name.
| name | string Example: name=Kundentermin Filter by category name (LIKE match). |
{- "success": true,
- "response": [
- {
- "id": 1,
- "name": "Kundentermin",
- "color": "#4caf50"
}
], - "status": 200
}Returns all appointments for the authenticated tenant. Supports filtering by various fields including employee email.
string <email> Example: email=jdoe@example.com Filter by employee email — resolves the employee and filters appointments where they are an attendee. | |
| title | string Filter by title (LIKE match). |
| description | string Filter by description (LIKE match). |
| address | string Filter by address (LIKE match). |
| project_id | integer Filter by associated project ID (exact match). |
| category_id | integer Filter by category ID (exact match). |
| id | integer Filter by exact appointment ID. |
| polling | string Enum: "1" "true" If truthy, returns only recently created/updated appointments. |
{- "success": true,
- "response": [
- {
- "id": 601,
- "title": "On-site inspection",
- "start": "2025-04-15T09:00:00",
- "end": "2025-04-15T10:30:00",
- "address": "Musterstraße 12, 10115 Berlin",
- "description": "Inspect bathroom for renovation project",
- "all_day": false,
- "attendees": [
- {
- "attendee_id": 7,
- "first_name": "John",
- "last_name": "Doe",
- "email": "jdoe@example.com"
}
], - "category": {
- "category_id": "TASK",
- "name": "TASK"
}
}
], - "status": 200
}Returns detailed information about a single appointment by ID, including attendees and category.
| id required | integer Example: 601 Appointment ID. |
{- "success": true,
- "response": {
- "id": 601,
- "title": "On-site inspection",
- "start": "2025-04-15T09:00:00",
- "end": "2025-04-15T10:30:00",
- "address": "Musterstraße 12, 10115 Berlin",
- "description": "Inspect bathroom for renovation project",
- "all_day": false,
- "attendees": [
- {
- "attendee_id": 7,
- "first_name": "John",
- "last_name": "Doe",
- "email": "jdoe@example.com"
}
], - "category": {
- "category_id": "TASK",
- "name": "TASK"
}
}, - "status": 200
}Creates a new appointment/calendar event. Attendees are specified as an array of employee IDs that will be resolved to full employee records.
| start required | string <date-time> |
| end required | string <date-time> |
| title required | string |
| category_id required | integer ID of the appointment category (or use built-in string IDs like TASK, VACATION). |
| project_id | integer Optional associated project/order ID. |
| description | string |
| address | string |
| all_day | boolean Default: false |
| attendees | Array of integers Array of employee IDs to assign as attendees. |
{- "start": "2025-04-15T09:00:00",
- "end": "2025-04-15T10:30:00",
- "title": "On-site inspection",
- "category_id": 1,
- "project_id": 101,
- "description": "Inspect bathroom for renovation",
- "address": "Musterstraße 12, 10115 Berlin",
- "all_day": false,
- "attendees": [
- 7,
- 12
]
}{- "success": true,
- "response": {
- "result": {
- "id": 601,
- "title": "On-site inspection",
- "start": "2025-04-15T09:00:00",
- "end": "2025-04-15T10:30:00",
- "address": "Musterstraße 12, 10115 Berlin",
- "description": "Inspect bathroom for renovation project",
- "all_day": false,
- "attendees": [
- {
- "attendee_id": 7,
- "first_name": "John",
- "last_name": "Doe",
- "email": "jdoe@example.com"
}
], - "category": {
- "category_id": "TASK",
- "name": "TASK"
}
}
}, - "status": 200
}Partially updates an existing appointment. Only the provided fields will be modified.
| id required | integer Example: 601 Appointment ID. |
| start | string <date-time> |
| end | string <date-time> |
| title | string |
| category_id | integer |
| project_id | integer |
| description | string |
| address | string |
| all_day | boolean |
| attendees | Array of integers |
{- "title": "Updated inspection",
- "end": "2025-04-15T11:00:00"
}{- "success": true,
- "response": {
- "result": {
- "id": 601,
- "title": "On-site inspection",
- "start": "2025-04-15T09:00:00",
- "end": "2025-04-15T10:30:00",
- "address": "Musterstraße 12, 10115 Berlin",
- "description": "Inspect bathroom for renovation project",
- "all_day": false,
- "attendees": [
- {
- "attendee_id": 7,
- "first_name": "John",
- "last_name": "Doe",
- "email": "jdoe@example.com"
}
], - "category": {
- "category_id": "TASK",
- "name": "TASK"
}
}
}, - "status": 200
}