Introduction
Welcome to the einfachArchiv API! If you're looking to integrate your application with einfachArchiv or create your own application in concert with data inside of einfachArchiv, you're in the right place. We're happy to have you!
Making a request
All URLs start with https://www.einfacharchiv.app/api/. URLs are HTTPS only. We use JSON for all API data and the snake_case notation for all keys. The outer-most resource is wrapped in a data key.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/teams" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
To make a request for all teams in your account, append the teams path to the API endpoint to form something like https://www.einfacharchiv.app/api/teams.
Error responses
The API uses HTTP status codes to distinguish between authentication, authorization, request validation, and resource-state problems.
| Status | Meaning |
|---|---|
401 Unauthorized |
The request is missing a valid access token, or the token is no longer valid. |
403 Forbidden |
The authenticated user does not have access to the requested resource or is not allowed to perform the requested action. |
404 Not Found |
The requested resource does not exist or is not visible to the authenticated user. |
409 Conflict |
The user may perform the action in principle, but the current resource state prevents it. For example, a document is already archived, locked, trashed, or otherwise not in a required status. |
422 Unprocessable Entity |
The request payload is syntactically valid JSON, but one or more submitted fields are invalid or missing. |
Validation and conflict responses include a human-readable message and an errors object. Conflict responses can also include a stable machine-readable code, the current status, and additional fields such as required_statuses, locked_until, or modifiable_until.
Authentication
You must create an Access Token or an OAuth App in order to interact with einfachArchiv. You can do that on your profile page.
If you're making a public integration with einfachArchiv for others to enjoy, you must use OAuth2. OAuth2 allows users to authorize your application to use einfachArchiv on their behalf without having to copy/paste access tokens or touch sensitive login information.
OAuth2
Redirecting for authorization
Once you have created an OAuth app, you may use the client ID and secret to request an authorization code and access token from einfachArchiv. First, your application should make a redirect request to the /oauth/authorize path like so:
https://www.einfacharchiv.app/oauth/authorize?client_id=client-id&redirect_uri=http://example.com/callback&response_type=code
Converting authorization codes to access tokens
Example request:
curl -X POST "https://www.einfacharchiv.app/oauth/token" \
-d "grant_type"="authorization_code" \
-d "client_id"="client-id" \
-d "client_secret"="client-secret" \
-d "redirect_uri"="http://example.com/callback" \
-d "code"="code"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/oauth/token",
"method": "POST",
"data": {
"grant_type": "authorization_code",
"client_id": "client-id",
"client_secret": "client-secret",
"redirect_uri": "http://example.com/callback",
"code": "code"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
If the user approves the authorization request, they will be redirected back to your application. Your application should then issue a POST request to einfachArchiv to request an access token. The request should include the authorization code that was issued by einfachArchiv when the user approved the authorization request.
This /oauth/token path will return the access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.
Refreshing tokens
Example request:
curl -X POST "https://www.einfacharchiv.app/oauth/token" \
-d "grant_type"="refresh_token" \
-d "refresh_token"="the-refresh-token" \
-d "client_id"="client-id" \
-d "client_secret"="client-secret"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/oauth/token",
"method": "POST",
"data": {
"grant_type": "refresh_token",
"refresh_token": "the-refresh-token",
"client_id": "client-id",
"client_secret": "client-secret"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
If the access token expires, you will need to refresh the access token via the refresh token that was provided to you when the access token was issued.
This /oauth/token path will return the access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.
Contacts
Get contacts
Returns a paginated list of all contacts.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/contacts" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "sort"="name" \
-d "per_page"="25" \
-d "query"="invoice january" \
-d "starts_with"="ipsam" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts",
"method": "GET",
"data": {
"team_id": 42,
"sort": "name",
"per_page": 25,
"query": "invoice january",
"starts_with": "ipsam"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET contacts
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| sort | string | optional | name or -name |
| per_page | integer | optional | Between: 1 and 100 |
| query | string | optional | Maximum: 255 |
| starts_with | string | optional | Maximum: 10 |
Suggest contacts
Returns a paginated list of suggested contacts. 5 per page.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/contacts/suggest" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "query"="invoice january" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts/suggest",
"method": "GET",
"data": {
"team_id": 42,
"query": "invoice january"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET contacts/suggest
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| query | string | optional |
Create a contact
Returns the created contact.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/contacts" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "name"="Max Mustermann" \
-d "email"="max.mustermann@example.org" \
-d "website"="https://example.org"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts",
"method": "POST",
"data": {
"team_id": 42,
"name": "Max Mustermann",
"email": "max.mustermann@example.org",
"website": "https:\/\/example.org"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST contacts
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| name | string | required | Maximum: 255 |
| optional | Maximum: 255 |
||
| website | url | optional | Maximum: 255 |
Get a contact
Returns the requested contact.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/contacts/{contact}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts/{contact}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET contacts/{contact}
Update a contact
Returns the updated contact.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/contacts/{contact}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "email"="max.mustermann@example.org" \
-d "website"="https://example.org"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts/{contact}",
"method": "PUT",
"data": {
"name": "Max Mustermann",
"email": "max.mustermann@example.org",
"website": "https:\/\/example.org"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT contacts/{contact}
PATCH contacts/{contact}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | required | Maximum: 255 |
| optional | Maximum: 255 |
||
| website | url | optional | Maximum: 255 |
Merge a contact into another contact
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/contacts/{contact}/merge" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "target_id"="99888"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts/{contact}/merge",
"method": "PUT",
"data": {
"target_id": 99888
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT contacts/{contact}/merge
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| target_id | integer | required | Valid contact id |
Delete multiple contacts
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/contacts" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "contact_ids[]"="1" \
-d "contact_ids[0]"="16"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts",
"method": "DELETE",
"data": {
"contact_ids": [
16
]
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE contacts
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| contact_ids | array | required | Must be an array Minimum: 1 |
| contact_ids[0] | integer | optional | Valid contact id |
Delete a contact
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/contacts/{contact}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/contacts/{contact}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE contacts/{contact}
Document Shares
Get the share link for a document
Returns 409 Conflict if the document is not archived.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/documents/{document}/share" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/share",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET documents/{document}/share
Create or regenerate a share link
Returns 409 Conflict if the document is not archived.
Example request:
curl -X POST "https://www.einfacharchiv.app/api/documents/{document}/share" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "password"="assumenda" \
-d "regenerate"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/share",
"method": "POST",
"data": {
"password": "assumenda",
"regenerate": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST documents/{document}/share
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| password | string | optional | Minimum: 8 Maximum: 255 |
| regenerate | boolean | optional |
Update share link settings (password or regeneration)
Returns 409 Conflict if the document is not archived.
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/share" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "password"="non" \
-d "clear_password"="1" \
-d "regenerate"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/share",
"method": "PUT",
"data": {
"password": "non",
"clear_password": true,
"regenerate": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/share
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| password | string | optional | Minimum: 8 Maximum: 255 |
| clear_password | boolean | optional | |
| regenerate | boolean | optional |
Revoke a share link
Returns 409 Conflict if the document is not archived.
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/documents/{document}/share" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/share",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE documents/{document}/share
Documents
Get documents
Returns a paginated list of all documents.
If you need to filter or search within documents (e.g., by filename, date, or other criteria), use the Search endpoint instead.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/documents" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "folder_id"="99" \
-d "with_subfolders"="1" \
-d "stacked"="1" \
-d "sort"="date" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents",
"method": "GET",
"data": {
"team_id": 42,
"folder_id": 99,
"with_subfolders": true,
"stacked": true,
"sort": "date",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET documents
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| folder_id | integer | optional | Valid folder id |
| with_subfolders | boolean | optional | |
| stacked | boolean | optional | |
| sort | string | optional | filename, -filename, date, -date, amount_to_pay, -amount_to_pay, locked_until or -locked_until |
| per_page | integer | optional | Between: 1 and 100 |
Export documents
Queues an export and returns the export payload.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/documents/export" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "folder_id"="99" \
-d "with_subfolders"="1" \
-d "metadata_only"="1" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/export",
"method": "GET",
"data": {
"team_id": 42,
"folder_id": 99,
"with_subfolders": true,
"metadata_only": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET documents/export
POST documents/export
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| folder_id | integer | optional | Valid folder id |
| with_subfolders | boolean | optional | |
| metadata_only | boolean | optional |
Upload a document
Returns the metadata of the uploaded document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
- uploader
visitor
Information fields
All document types accept the standardized exdata fields: title, payment_due_date, period_start, period_end, document_number, customer_id, contract_id, order_id, reference_id, net_amount, gross_amount, tax_amount, tax_rate, opening_balance, closing_balance, payment_status, payment_reference, cost_center, account_holder, iban, bic, bank, tax_breakdowns, tax_system, taxability, tax_collection_mechanism, cross_border_tax_treatment, supply_type and tax_exemption_reason.
Party and contact fields: sender_street, sender_zip, sender_city, sender_state, sender_country_code, sender_tax_id, sender_vat_number, recipient_street, recipient_zip, recipient_city, recipient_state, recipient_country_code, recipient_tax_id, recipient_vat_number, company_register_id, vat_number, tax_number, phone, email and website.
Email header fields: from, from_email, to, to_email, subject, email_date, message_id and in_reply_to.
Canonical fields and legacy aliases
New integrations should use the canonical fields. The following type-specific aliases remain accepted:
- invoice and reminder:
document_number->invoice_id - credit-note:
document_number->credit_note_id - invoice, credit-note and reminder:
gross_amount->amount_to_pay - salary-statement:
net_amount->net_earningsandgross_amount->gross_earnings
Send only one representation for each value. If both representations are submitted, they are
stored independently while canonical values take precedence in derived data such as search and sorting.
Document metadata responses expose stored information keys and do not add missing aliases automatically,
so readers should use the canonical field first and its legacy alias only as a fallback.
data.information is sparse: it contains the stored, non-blank keys. Null values, blank strings
and empty arrays are omitted, while 0, "0" and false remain visible. Both representations
can appear if both were stored. The top-level data.document_number provides a unified value,
preferring document_number and falling back to the type-specific legacy number.
Single-document uploads may include an Idempotency-Key header (maximum 128 characters).
Repeating a request with the same key for the same team returns the document created by the
first request instead of storing another copy. Upload side effects are recorded atomically
and recovered independently if their initial queue hand-off fails.
Money fields use an amount/currency object. For backwards compatibility, payment_status
accepts Boolean values, 0/1 and the strings "0"/"1". true, 1 and "1" become paid;
false, 0 and "0" become open. Other strings are trimmed and stored unchanged, up to
255 characters, so readers should allow values beyond paid and open.
tax_breakdowns contains at most 100 per-rate tax rows. Each row may only contain
taxable_amount, tax_amount, tax_rate, taxability, tax_collection_mechanism and
tax_exemption_reason; unknown keys return HTTP 422. Rows have no currency field and their
amounts are numeric values, not nested money objects. Use one document currency consistently;
currency consistency is not validated by the API.
Example request:
curl -X POST "https://www.einfacharchiv.app/api/documents" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-F "team_id"="42" \
-F "file"="@path" \
-F "filename"="2026-01-15_Invoice.pdf" \
-F "sender"="Example GmbH" \
-F "recipient"="Max Mustermann" \
-F "type"="invoice" \
-F "date"="2026-01-15" \
-F "title"="Invoice January 2026" \
-F "document_number"="INV-2026-0001" \
-F "order_id"="ORDER-2026-0042" \
-F "reference_id"="REF-2026-0042" \
-F "net_amount[amount]"="1000.00" \
-F "net_amount[currency]"="EUR" \
-F "gross_amount[amount]"="1190.00" \
-F "gross_amount[currency]"="EUR" \
-F "tax_amount[amount]"="190.00" \
-F "tax_amount[currency]"="EUR" \
-F "tax_rate"="19.00" \
-F "tax_system"="VAT" \
-F "taxability"="taxable" \
-F "tax_collection_mechanism"="standard" \
-F "cross_border_tax_treatment"="domestic" \
-F "supply_type"="goods" \
-F "tax_exemption_reason"="Not applicable" \
-F "sender_street"="nostrum" \
-F "sender_zip"="nostrum" \
-F "sender_city"="nostrum" \
-F "sender_state"="nostrum" \
-F "sender_country_code"="DE" \
-F "sender_tax_id"="nostrum" \
-F "sender_vat_number"="nostrum" \
-F "recipient_street"="nostrum" \
-F "recipient_zip"="nostrum" \
-F "recipient_city"="nostrum" \
-F "recipient_state"="nostrum" \
-F "recipient_country_code"="AT" \
-F "recipient_tax_id"="nostrum" \
-F "recipient_vat_number"="nostrum" \
-F "from"="nostrum" \
-F "from_email"="assunta.conn@example.org" \
-F "to"="nostrum" \
-F "to_email"="assunta.conn@example.org" \
-F "subject"="nostrum" \
-F "email_date"="2026-01-15" \
-F "message_id"="nostrum" \
-F "in_reply_to"="nostrum" \
-F "payment_due_date"="2026-01-30" \
-F "customer_id"="CUST-2026-1001" \
-F "payment_status"="partially_paid" \
-F "opening_balance[amount]"="1000.00" \
-F "opening_balance[currency]"="EUR" \
-F "closing_balance[amount]"="1250.00" \
-F "closing_balance[currency]"="EUR" \
-F "cost_center"="CC-001" \
-F "account_holder"="Example GmbH" \
-F "iban"="DE89370400440532013000" \
-F "bic"="DEUTDEDBBER" \
-F "bank"="Deutsche Bank" \
-F "payment_reference"="Invoice #2026-001" \
-F "company_register_id[area]"="HRB" \
-F "company_register_id[number]"="12345" \
-F "company_register_id[office]"="Berlin" \
-F "vat_number"="DE123456789" \
-F "tax_number[number]"="12/345/67890" \
-F "tax_number[state]"="Berlin" \
-F "phone"="+49 30 1234567" \
-F "email"="max.mustermann@example.org" \
-F "website"="https://example.org" \
-F "period_start"="2026-01-01" \
-F "period_end"="2026-01-31" \
-F "contract_id"="CON-2026-001" \
-F "tags[]"="Invoices" \
-F "note"="Payment due within 14 days" \
-F "folder_id"="99" \
-F "unzip"="1" \
-F "archive"="1" \
-F "tax_breakdowns[0][taxable_amount]"="1000.00" \
-F "tax_breakdowns[0][tax_amount]"="190.00" \
-F "tax_breakdowns[0][tax_rate]"="19.00" \
-F "tax_breakdowns[0][taxability]"="taxable" \
-F "tax_breakdowns[0][tax_collection_mechanism]"="standard" \
-F "tax_breakdowns[0][tax_exemption_reason]"="Not applicable"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents",
"method": "POST",
"data": {
"team_id": 42,
"file": "@path",
"filename": "2026-01-15_Invoice.pdf",
"sender": "Example GmbH",
"recipient": "Max Mustermann",
"type": "invoice",
"date": "2026-01-15",
"title": "Invoice January 2026",
"document_number": "INV-2026-0001",
"order_id": "ORDER-2026-0042",
"reference_id": "REF-2026-0042",
"net_amount": {
"amount": "1000.00",
"currency": "EUR"
},
"gross_amount": {
"amount": "1190.00",
"currency": "EUR"
},
"tax_amount": {
"amount": "190.00",
"currency": "EUR"
},
"tax_rate": "19.00",
"tax_system": "VAT",
"taxability": "taxable",
"tax_collection_mechanism": "standard",
"cross_border_tax_treatment": "domestic",
"supply_type": "goods",
"tax_exemption_reason": "Not applicable",
"sender_street": "nostrum",
"sender_zip": "nostrum",
"sender_city": "nostrum",
"sender_state": "nostrum",
"sender_country_code": "DE",
"sender_tax_id": "nostrum",
"sender_vat_number": "nostrum",
"recipient_street": "nostrum",
"recipient_zip": "nostrum",
"recipient_city": "nostrum",
"recipient_state": "nostrum",
"recipient_country_code": "AT",
"recipient_tax_id": "nostrum",
"recipient_vat_number": "nostrum",
"from": "nostrum",
"from_email": "assunta.conn@example.org",
"to": "nostrum",
"to_email": "assunta.conn@example.org",
"subject": "nostrum",
"email_date": "2026-01-15",
"message_id": "nostrum",
"in_reply_to": "nostrum",
"payment_due_date": "2026-01-30",
"customer_id": "CUST-2026-1001",
"payment_status": "partially_paid",
"opening_balance": {
"amount": "1000.00",
"currency": "EUR"
},
"closing_balance": {
"amount": "1250.00",
"currency": "EUR"
},
"cost_center": "CC-001",
"account_holder": "Example GmbH",
"iban": "DE89370400440532013000",
"bic": "DEUTDEDBBER",
"bank": "Deutsche Bank",
"payment_reference": "Invoice #2026-001",
"company_register_id": {
"area": "HRB",
"number": "12345",
"office": "Berlin"
},
"vat_number": "DE123456789",
"tax_number": {
"number": "12\/345\/67890",
"state": "Berlin"
},
"phone": "+49 30 1234567",
"email": "max.mustermann@example.org",
"website": "https:\/\/example.org",
"period_start": "2026-01-01",
"period_end": "2026-01-31",
"contract_id": "CON-2026-001",
"tags": [
"Invoices"
],
"note": "Payment due within 14 days",
"folder_id": 99,
"unzip": true,
"archive": true,
"tax_breakdowns": [
{
"taxable_amount": "1000.00",
"tax_amount": "190.00",
"tax_rate": "19.00",
"taxability": "taxable",
"tax_collection_mechanism": "standard",
"tax_exemption_reason": "Not applicable"
}
]
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST documents
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| file | file | required | Must be a file upload Maximum: 40000 |
| filename | string | optional | Maximum: 255 |
| sender | string | optional | Maximum: 255 |
| recipient | string | optional | Maximum: 255 |
| type | string | optional | invoice, credit-note, reminder, salary-statement, bank-statement, contract, balance-sheet, tax-assessment-note, timesheet, email, letter or other |
| type_id | integer | optional | |
| date | date | optional | |
| title | string | optional | Maximum: 1000 |
| document_number | string | optional | Maximum: 255 |
| order_id | string | optional | Maximum: 255 |
| reference_id | string | optional | Maximum: 255 |
| net_amount | array | optional | Must be an array |
| net_amount[amount] | numeric | optional | |
| net_amount[currency] | string | optional | Must have the size of 3 |
| gross_amount | array | optional | Must be an array |
| gross_amount[amount] | numeric | optional | |
| gross_amount[currency] | string | optional | Must have the size of 3 |
| tax_amount | array | optional | Must be an array |
| tax_amount[amount] | numeric | optional | |
| tax_amount[currency] | string | optional | Must have the size of 3 |
| tax_rate | numeric | optional | |
| tax_breakdowns | array | optional | Must be an array Maximum: 100. Only the documented row keys are accepted; unknown keys return HTTP 422. |
| tax_system | string | optional | Maximum: 100 |
| taxability | string | optional | Maximum: 64 |
| tax_collection_mechanism | string | optional | Maximum: 64 |
| cross_border_tax_treatment | string | optional | Maximum: 100 |
| supply_type | string | optional | Maximum: 100 |
| tax_exemption_reason | string | optional | Maximum: 2000 |
| sender_street | string | optional | Maximum: 255 |
| sender_zip | string | optional | Maximum: 32 |
| sender_city | string | optional | Maximum: 255 |
| sender_state | string | optional | Maximum: 255 |
| sender_country_code | string | optional | Must have the size of 2 |
| sender_tax_id | string | optional | Maximum: 255 |
| sender_vat_number | string | optional | Maximum: 255 |
| recipient_street | string | optional | Maximum: 255 |
| recipient_zip | string | optional | Maximum: 32 |
| recipient_city | string | optional | Maximum: 255 |
| recipient_state | string | optional | Maximum: 255 |
| recipient_country_code | string | optional | Must have the size of 2 |
| recipient_tax_id | string | optional | Maximum: 255 |
| recipient_vat_number | string | optional | Maximum: 255 |
| from | string | optional | Maximum: 998 |
| from_email | optional | Maximum: 255 |
|
| to | string | optional | Maximum: 998 |
| to_email | optional | Maximum: 255 |
|
| subject | string | optional | Maximum: 998 |
| email_date | date | optional | |
| message_id | string | optional | Maximum: 998 |
| in_reply_to | string | optional | Maximum: 998 |
| payment_due_date | date | optional | |
| customer_id | string | optional | Maximum: 255 |
| invoice_id | string | optional | Maximum: 255 |
| credit_note_id | string | optional | Maximum: 255 |
| amount_to_pay | array | optional | Must be an array |
| amount_to_pay[amount] | numeric | optional | |
| amount_to_pay[currency] | string | optional | Must have the size of 3 |
| payment_status | boolean or string | optional | Boolean values and 0/1 are normalized to paid/open; strings may contain up to 255 characters. |
| opening_balance | array | optional | Must be an array |
| opening_balance[amount] | numeric | optional | |
| opening_balance[currency] | string | optional | Must have the size of 3 |
| closing_balance | array | optional | Must be an array |
| closing_balance[amount] | numeric | optional | |
| closing_balance[currency] | string | optional | Must have the size of 3 |
| cost_center | string | optional | Maximum: 255 |
| account_holder | string | optional | Maximum: 255 |
| iban | string | optional | Maximum: 34 |
| bic | string | optional | Maximum: 11 |
| bank | string | optional | Maximum: 255 |
| payment_reference | string | optional | Maximum: 255 |
| company_register_id | array | optional | Must be an array |
| company_register_id[area] | string | optional | HRA or HRB |
| company_register_id[number] | string | optional | Maximum: 255 |
| company_register_id[office] | string | optional | Maximum: 255 |
| vat_number | string | optional | Maximum: 255 |
| tax_number | array | optional | Must be an array |
| tax_number[number] | string | optional | Maximum: 255 |
| tax_number[state] | string | optional | Maximum: 255 |
| phone | string | optional | Maximum: 255 |
| optional | Maximum: 255 |
||
| website | string | optional | Maximum: 255 |
| period_start | date | optional | |
| period_end | date | optional | |
| net_earnings | array | optional | Must be an array |
| net_earnings[amount] | numeric | optional | |
| net_earnings[currency] | string | optional | Must have the size of 3 |
| gross_earnings | array | optional | Must be an array |
| gross_earnings[amount] | numeric | optional | |
| gross_earnings[currency] | string | optional | Must have the size of 3 |
| contract_id | string | optional | Maximum: 255 |
| tags | array | optional | Must be an array |
| note | string | optional | Maximum: 65535 |
| folder_id | integer | optional | |
| unzip | boolean | optional | |
| archive | boolean | optional | |
| tax_breakdowns[0] | array | optional | Must be an array |
| tax_breakdowns[0][taxable_amount] | numeric | optional | Numeric amount in the currency used by the document-level money fields. |
| tax_breakdowns[0][tax_amount] | numeric | optional | Numeric amount in the currency used by the document-level money fields. |
| tax_breakdowns[0][tax_rate] | numeric | optional | |
| tax_breakdowns[0][taxability] | string | optional | Maximum: 64 |
| tax_breakdowns[0][tax_collection_mechanism] | string | optional | Maximum: 64 |
| tax_breakdowns[0][tax_exemption_reason] | string | optional | Maximum: 2000 |
Get a document
Returns the file.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/documents/{document}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET documents/{document}
Get a preview
Returns the file.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/documents/{document}/preview" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/preview",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET documents/{document}/preview
Get a thumbnail
Returns the file.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/documents/{document}/thumbnail" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/thumbnail",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET documents/{document}/thumbnail
Update a document
Only possible if the document status is under_review or archived.
Returns 409 Conflict if the document is not in an updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns 409 Conflict with code document_processing_changed if a
reanalysis or extraction retry started after the replacement request
began. Retry the request against the current document state.
Returns 422 Unprocessable Entity if the storage is full.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
- uploader
visitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/documents/{document}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-F "file"="@path"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}",
"method": "POST",
"data": {
"file": "@path"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST documents/{document}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| file | file | required | Must be a file upload Maximum: 40000 |
Archive a document
Only possible if the document status is under_review.
Returns 409 Conflict if the document is already archived or otherwise not in an archivable status.
Conflict response
{
"message": "The document cannot be archived because its status is \"archived\". Allowed status: under_review.",
"code": "document_not_archivable",
"status": "archived",
"required_statuses": ["under_review"],
"errors": {
"status": [
"The document cannot be archived because its status is \"archived\". Allowed status: under_review."
]
}
}
Returns 422 Unprocessable Entity if the storage is full.
Returns the metadata of the archived document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/archive" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/archive",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/archive
Trash a document
Only possible if the document status is under_review or archived and locked_until is in the past.
Returns 409 Conflict if the document is locked or otherwise not in a trashable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the trashed document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/trash" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/trash",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/trash
Restore a document
Only possible if the document status is trashed.
Returns 409 Conflict if the document is not in a restorable status.
Returns the metadata of the restored document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/restore" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/restore",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/restore
Delete a document
Only possible if the document status is under_review or trashed.
Returns 409 Conflict if the document is not in a deletable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document or of another member of its stack is
running. Retry the request once the analysis finished.
Returns 409 Conflict with code document_stack_not_updatable if
another member of the stack is not in a status that allows unstacking.
Returns 409 Conflict with code document_stack_assignment_changed if
the stack assignment of the document changed while the request acquired
its locks. Retry the request against the current stack state.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/documents/{document}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE documents/{document}
Emails
Get emails
Returns a paginated list of all emails.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/emails" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "sort"="-subject" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/emails",
"method": "GET",
"data": {
"team_id": 42,
"sort": "-subject",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET emails
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| sort | string | optional | subject or -subject |
| per_page | integer | optional | Between: 1 and 100 |
Get an email
Returns the requested email.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/emails/{email}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/emails/{email}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET emails/{email}
Get a preview
Returns a preview of the requested email in HTML format.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/emails/{email}/preview" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/emails/{email}/preview",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET emails/{email}/preview
Get an EML file
Returns the requested email as an EML file.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/emails/{email}/download" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/emails/{email}/download",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET emails/{email}/download
Get an attachment
Returns the requested attachment for the email.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/emails/{email}/attachments/{attachmentId}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/emails/{email}/attachments/{attachmentId}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET emails/{email}/attachments/{attachmentId}
Events
Get events
Returns a paginated list of all events.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/events" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "document_id"="1001" \
-d "sort"="-created_at" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/events",
"method": "GET",
"data": {
"team_id": 42,
"document_id": 1001,
"sort": "-created_at",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET events
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | optional | Required if the parameters document_id are not present. |
| document_id | integer | optional | Required if the parameters team_id are not present. |
| sort | string | optional | created_at or -created_at |
| per_page | integer | optional | Between: 1 and 100 |
Exports
Get exports
Returns an unpaginated list of all exports for the current user.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/exports" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/exports",
"method": "GET",
"data": {
"team_id": 42
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET exports
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required |
Create an export
Returns the queued export.
Example request:
curl -X POST "https://www.einfacharchiv.app/api/exports" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "type"="invoice" \
-d "scope"="all" \
-d "document_ids[]"="100" \
-d "document_ids[]"="200" \
-d "exclude_document_ids[]"="1" \
-d "only_duplicates"="1" \
-d "status"="archived" \
-d "query"="invoice january" \
-d "metadata_only"="1" \
-d "folder_id"="99" \
-d "with_subfolders"="1" \
-d "document_ids[0]"="4759874" \
-d "exclude_document_ids[0]"="4759874"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/exports",
"method": "POST",
"data": {
"team_id": 42,
"type": "invoice",
"scope": "all",
"document_ids": [
4759874,
200
],
"exclude_document_ids": [
4759874
],
"only_duplicates": true,
"status": "archived",
"query": "invoice january",
"metadata_only": true,
"folder_id": 99,
"with_subfolders": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST exports
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| type | string | required | archive, folder, search or documents |
| scope | string | optional | selected or all |
| document_ids | array | optional | Required if scope is selected Must be an array Minimum: 1 |
| exclude_document_ids | array | optional | Must be an array |
| only_duplicates | boolean | optional | |
| status | string | optional | under_review or archived |
| query | string | optional | Required if type is search |
| metadata_only | boolean | optional | |
| folder_id | integer | optional | Required if type is folder Valid folder id |
| with_subfolders | boolean | optional | |
| document_ids[0] | integer | optional | Valid document id |
| exclude_document_ids[0] | integer | optional | Valid document id |
Download an export
Example request:
curl -X GET "https://www.einfacharchiv.app/api/exports/{export}/download" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/exports/{export}/download",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET exports/{export}/download
Folders
Get folders
Returns a paginated list of all folders.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/folders" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "parent_folder_id"="12" \
-d "sort"="name" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/folders",
"method": "GET",
"data": {
"team_id": 42,
"parent_folder_id": 12,
"sort": "name",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET folders
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| parent_folder_id | integer | optional | |
| sort | string | optional | name or -name |
| per_page | integer | optional | Between: 1 and 100 |
Create a folder
Returns the created folder.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/folders" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "parent_folder_id"="12" \
-d "name"="Max Mustermann" \
-d "classification"="unclassified" \
-d "user_ids[]"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/folders",
"method": "POST",
"data": {
"team_id": 42,
"parent_folder_id": 12,
"name": "Max Mustermann",
"classification": "unclassified",
"user_ids": [
1
]
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST folders
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| parent_folder_id | integer | optional | Valid folder id |
| name | string | required | Maximum: 255 |
| classification | string | optional | unclassified or confidential |
| user_ids | array | optional | Must be an array |
Get a folder
Returns the requested folder.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/folders/{folder}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/folders/{folder}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET folders/{folder}
Update a folder
Returns the updated folder.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/folders/{folder}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "classification"="confidential" \
-d "user_ids[]"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/folders/{folder}",
"method": "PUT",
"data": {
"name": "Max Mustermann",
"classification": "confidential",
"user_ids": [
1
]
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT folders/{folder}
PATCH folders/{folder}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | required | Maximum: 255 |
| classification | string | optional | unclassified or confidential |
| user_ids | array | optional | Must be an array |
Duplicate a folder tree
Returns the created folder(s).
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/folders/{folder}/duplicate" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "parent_folder_id"="12" \
-d "year"="1399" \
-d "month"="8" \
-d "month_mode"="all"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/folders/{folder}/duplicate",
"method": "POST",
"data": {
"parent_folder_id": 12,
"year": 1399,
"month": 8,
"month_mode": "all"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST folders/{folder}/duplicate
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| parent_folder_id | integer | optional | Valid folder id |
| year | integer | required | Minimum: 1900 Maximum: 2100 |
| month | integer | optional | Between: 1 and 12 |
| month_mode | string | optional | single or all |
Move a folder
Returns 422 Unprocessable Entity if the parent folder is the same folder.
Returns 422 Unprocessable Entity if the parent folder is a child of the folder.
Returns the moved folder.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/folders/{folder}/parentFolder" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "parent_folder_id"="12"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/folders/{folder}/parentFolder",
"method": "PUT",
"data": {
"parent_folder_id": 12
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT folders/{folder}/parentFolder
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| parent_folder_id | integer | required | Valid folder id Not in: `` |
Delete a folder
If the folder has no subfolders, all documents in the folder will be moved to the parent folder. If the folder has subfolders, deletion is only possible when the whole folder tree contains no documents.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/folders/{folder}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/folders/{folder}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE folders/{folder}
Inbox
Get documents
Returns a paginated list of all documents in the inbox.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/inbox" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "sort"="-created_at" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/inbox",
"method": "GET",
"data": {
"team_id": 42,
"sort": "-created_at",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET inbox
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| sort | string | optional | created_at or -created_at |
| per_page | integer | optional | Between: 1 and 100 |
Update the inbox
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
super-archivistarchivistuploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/inbox" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "classification"="unclassified" \
-d "user_ids[]"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/inbox",
"method": "PUT",
"data": {
"team_id": 42,
"classification": "unclassified",
"user_ids": [
1
]
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT inbox
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| classification | string | optional | unclassified or confidential |
| user_ids | array | optional | Must be an array |
Invoices
Get invoices
Returns an unpaginated list of all invoices.
Authorized roles
- owner
user-managementsuper-archivistarchivistuploadervisitor
Example request:
curl -X GET "https://www.einfacharchiv.app/api/invoices" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/invoices",
"method": "GET",
"data": {
"team_id": 42
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET invoices
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required |
Get an invoice
Returns the file.
Authorized roles
- owner
user-managementsuper-archivistarchivistuploadervisitor
Example request:
curl -X GET "https://www.einfacharchiv.app/api/invoices/{invoice}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "disposition"="inline" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/invoices/{invoice}",
"method": "GET",
"data": {
"team_id": 42,
"disposition": "inline"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET invoices/{invoice}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| disposition | string | optional | inline or attachment |
Lists
Get lists
Returns a paginated list of all lists.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/lists" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "sort"="name" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/lists",
"method": "GET",
"data": {
"team_id": 42,
"sort": "name",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET lists
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| sort | string | optional | name or -name |
| per_page | integer | optional | Between: 1 and 100 |
Create a list
Returns the created list.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/lists" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "name"="Max Mustermann" \
-d "archive_immediately"="1" \
-d "default_type_id"="1" \
-d "default_folder_id"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/lists",
"method": "POST",
"data": {
"team_id": 42,
"name": "Max Mustermann",
"archive_immediately": true,
"default_type_id": 1,
"default_folder_id": 1
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST lists
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| name | string | required | Maximum: 255 |
| archive_immediately | boolean | optional | |
| default_type_id | integer | optional | Valid type id |
| default_folder_id | integer | optional | Valid folder id |
Get a list
Returns the requested list.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/lists/{list}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/lists/{list}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET lists/{list}
Update a list
Returns the updated list.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/lists/{list}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "archive_immediately"="1" \
-d "default_type_id"="489128773" \
-d "default_folder_id"="489128773"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/lists/{list}",
"method": "PUT",
"data": {
"name": "Max Mustermann",
"archive_immediately": true,
"default_type_id": 489128773,
"default_folder_id": 489128773
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT lists/{list}
PATCH lists/{list}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | optional | Maximum: 255 |
| archive_immediately | boolean | optional | |
| default_type_id | integer | optional | Valid type id |
| default_folder_id | integer | optional | Valid folder id |
Delete a list
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/lists/{list}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/lists/{list}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE lists/{list}
Metadata
Get metadata
Returns the metadata of the requested document.
Duplicate metadata is visibility-scoped. Exact duplicates are exposed through has_duplicates
and exact_duplicate_document_ids; potential duplicates are exposed through
has_potential_duplicates, potential_duplicate_document_ids, and duplicate_matches.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/documents/{document}/metadata" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/metadata",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET documents/{document}/metadata
Reanalyze a document
Starts the analysis of the sender, recipient, type, date, and information of the requested document.
By default the reanalysis replaces the analyzable metadata with the
newly extracted values. For archived documents, preserve_metadata
keeps the confirmed metadata (type, date, note, manually assigned
filenames, and existing information) and only appends missing
information. Missing contacts are still derived from the extraction,
which may also update the document flow and regenerate automatically
named titles. The active mode is exposed on the document as
reanalysis_preserve_metadata.
Only possible if the document status is under_review or archived.
Returns 409 Conflict if the document is not in a reanalyzable status.
Returns 409 Conflict if exdata does not support the document file for extraction.
Returns 409 Conflict with code document_reanalysis_in_progress if a
reanalysis of the archived document is already running. Retry the
request once the analysis finished.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/extractions" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "preserve_metadata"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/extractions",
"method": "PUT",
"data": {
"preserve_metadata": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/extractions
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| preserve_metadata | boolean | optional |
Regenerate a thumbnail
Starts the generation of the thumbnail of the requested document.
Only possible if the document status is archived.
Returns 409 Conflict if the document is not in a status that supports thumbnail regeneration.
Returns 409 Conflict if exdata does not support thumbnail generation for the document file.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/thumbnail" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/thumbnail",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/thumbnail
Update a filename
Only possible if the document status is under_review or archived.
If the filename is null, the filename will be reset to the original filename.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/filename" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "filename"="2026-01-15_Invoice.pdf"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/filename",
"method": "PUT",
"data": {
"filename": "2026-01-15_Invoice.pdf"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/filename
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| filename | string | optional | Maximum: 255 |
Update a sender
Only possible if the document status is under_review or archived.
The recipient will be set to the current team.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/sender" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "sender"="Example GmbH"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/sender",
"method": "PUT",
"data": {
"sender": "Example GmbH"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/sender
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| sender | string | optional | Maximum: 255 |
Update a recipient
Only possible if the document status is under_review or archived.
The sender will be set to the current team.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/recipient" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "recipient"="Max Mustermann"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/recipient",
"method": "PUT",
"data": {
"recipient": "Max Mustermann"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/recipient
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| recipient | string | optional | Maximum: 255 |
Swap a sender and a recipient
Only possible if the document status is under_review or archived.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/contacts" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/contacts",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/contacts
Update information
Only possible if the document status is under_review or archived.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Replacement semantics
This endpoint replaces the complete information object; it is not a partial update.
Every existing information field omitted from the request, set to null or submitted as a
blank string or empty array is deleted. Fetch the current document with
GET /api/documents/{document}/metadata, merge the intended changes, and send every
information field that must be retained.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Information fields
All document types accept the standardized exdata fields: title, payment_due_date, period_start, period_end, document_number, customer_id, contract_id, order_id, reference_id, net_amount, gross_amount, tax_amount, tax_rate, opening_balance, closing_balance, payment_status, payment_reference, cost_center, account_holder, iban, bic, bank, tax_breakdowns, tax_system, taxability, tax_collection_mechanism, cross_border_tax_treatment, supply_type and tax_exemption_reason.
Party and contact fields: sender_street, sender_zip, sender_city, sender_state, sender_country_code, sender_tax_id, sender_vat_number, recipient_street, recipient_zip, recipient_city, recipient_state, recipient_country_code, recipient_tax_id, recipient_vat_number, company_register_id, vat_number, tax_number, phone, email and website.
Email header fields: from, from_email, to, to_email, subject, email_date, message_id and in_reply_to.
Canonical fields and legacy aliases
New integrations should use the canonical fields. The following type-specific aliases remain accepted:
- invoice and reminder:
document_number->invoice_id - credit-note:
document_number->credit_note_id - invoice, credit-note and reminder:
gross_amount->amount_to_pay - salary-statement:
net_amount->net_earningsandgross_amount->gross_earnings
Send only one representation for each value. If both representations are submitted, they are
stored independently while canonical values take precedence in derived data such as search and sorting.
Document metadata responses expose stored information keys and do not add missing aliases automatically,
so readers should use the canonical field first and its legacy alias only as a fallback.
data.information is sparse: it contains the stored, non-blank keys. Null values, blank strings
and empty arrays are omitted, while 0, "0" and false remain visible. Both representations
can appear if both were stored. The top-level data.document_number provides a unified value,
preferring document_number and falling back to the type-specific legacy number.
Money fields use an amount/currency object. For backwards compatibility, payment_status
accepts Boolean values, 0/1 and the strings "0"/"1". true, 1 and "1" become paid;
false, 0 and "0" become open. Other strings are trimmed and stored unchanged, up to
255 characters, so readers should allow values beyond paid and open.
tax_breakdowns contains at most 100 per-rate tax rows. Each row may only contain
taxable_amount, tax_amount, tax_rate, taxability, tax_collection_mechanism and
tax_exemption_reason; unknown keys return HTTP 422. Rows have no currency field and their
amounts are numeric values, not nested money objects. Use one document currency consistently;
currency consistency is not validated by the API.
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/information" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "type"="invoice" \
-d "date"="2026-01-15" \
-d "title"="Invoice January 2026" \
-d "document_number"="INV-2026-0001" \
-d "order_id"="ORDER-2026-0042" \
-d "reference_id"="REF-2026-0042" \
-d "net_amount[amount]"="1000.00" \
-d "net_amount[currency]"="EUR" \
-d "gross_amount[amount]"="1190.00" \
-d "gross_amount[currency]"="EUR" \
-d "tax_amount[amount]"="190.00" \
-d "tax_amount[currency]"="EUR" \
-d "tax_rate"="19.00" \
-d "tax_system"="VAT" \
-d "taxability"="taxable" \
-d "tax_collection_mechanism"="standard" \
-d "cross_border_tax_treatment"="domestic" \
-d "supply_type"="goods" \
-d "tax_exemption_reason"="Not applicable" \
-d "sender_street"="sint" \
-d "sender_zip"="sint" \
-d "sender_city"="sint" \
-d "sender_state"="sint" \
-d "sender_country_code"="DE" \
-d "sender_tax_id"="sint" \
-d "sender_vat_number"="sint" \
-d "recipient_street"="sint" \
-d "recipient_zip"="sint" \
-d "recipient_city"="sint" \
-d "recipient_state"="sint" \
-d "recipient_country_code"="AT" \
-d "recipient_tax_id"="sint" \
-d "recipient_vat_number"="sint" \
-d "from"="sint" \
-d "from_email"="hortense78@example.net" \
-d "to"="sint" \
-d "to_email"="hortense78@example.net" \
-d "subject"="sint" \
-d "email_date"="2026-01-15" \
-d "message_id"="sint" \
-d "in_reply_to"="sint" \
-d "payment_due_date"="2026-01-30" \
-d "customer_id"="CUST-2026-1001" \
-d "payment_status"="partially_paid" \
-d "opening_balance[amount]"="1000.00" \
-d "opening_balance[currency]"="EUR" \
-d "closing_balance[amount]"="1250.00" \
-d "closing_balance[currency]"="EUR" \
-d "cost_center"="CC-001" \
-d "account_holder"="Example GmbH" \
-d "iban"="DE89370400440532013000" \
-d "bic"="DEUTDEDBBER" \
-d "bank"="Deutsche Bank" \
-d "payment_reference"="Invoice #2026-001" \
-d "company_register_id[area]"="HRB" \
-d "company_register_id[number]"="12345" \
-d "company_register_id[office]"="Berlin" \
-d "vat_number"="DE123456789" \
-d "tax_number[number]"="12/345/67890" \
-d "tax_number[state]"="Berlin" \
-d "phone"="+49 30 1234567" \
-d "email"="max.mustermann@example.org" \
-d "website"="https://example.org" \
-d "period_start"="2026-01-01" \
-d "period_end"="2026-01-31" \
-d "contract_id"="CON-2026-001" \
-d "tax_breakdowns[0][taxable_amount]"="1000.00" \
-d "tax_breakdowns[0][tax_amount]"="190.00" \
-d "tax_breakdowns[0][tax_rate]"="19.00" \
-d "tax_breakdowns[0][taxability]"="taxable" \
-d "tax_breakdowns[0][tax_collection_mechanism]"="standard" \
-d "tax_breakdowns[0][tax_exemption_reason]"="Not applicable"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/information",
"method": "PUT",
"data": {
"type": "invoice",
"date": "2026-01-15",
"title": "Invoice January 2026",
"document_number": "INV-2026-0001",
"order_id": "ORDER-2026-0042",
"reference_id": "REF-2026-0042",
"net_amount": {
"amount": "1000.00",
"currency": "EUR"
},
"gross_amount": {
"amount": "1190.00",
"currency": "EUR"
},
"tax_amount": {
"amount": "190.00",
"currency": "EUR"
},
"tax_rate": "19.00",
"tax_system": "VAT",
"taxability": "taxable",
"tax_collection_mechanism": "standard",
"cross_border_tax_treatment": "domestic",
"supply_type": "goods",
"tax_exemption_reason": "Not applicable",
"sender_street": "sint",
"sender_zip": "sint",
"sender_city": "sint",
"sender_state": "sint",
"sender_country_code": "DE",
"sender_tax_id": "sint",
"sender_vat_number": "sint",
"recipient_street": "sint",
"recipient_zip": "sint",
"recipient_city": "sint",
"recipient_state": "sint",
"recipient_country_code": "AT",
"recipient_tax_id": "sint",
"recipient_vat_number": "sint",
"from": "sint",
"from_email": "hortense78@example.net",
"to": "sint",
"to_email": "hortense78@example.net",
"subject": "sint",
"email_date": "2026-01-15",
"message_id": "sint",
"in_reply_to": "sint",
"payment_due_date": "2026-01-30",
"customer_id": "CUST-2026-1001",
"payment_status": "partially_paid",
"opening_balance": {
"amount": "1000.00",
"currency": "EUR"
},
"closing_balance": {
"amount": "1250.00",
"currency": "EUR"
},
"cost_center": "CC-001",
"account_holder": "Example GmbH",
"iban": "DE89370400440532013000",
"bic": "DEUTDEDBBER",
"bank": "Deutsche Bank",
"payment_reference": "Invoice #2026-001",
"company_register_id": {
"area": "HRB",
"number": "12345",
"office": "Berlin"
},
"vat_number": "DE123456789",
"tax_number": {
"number": "12\/345\/67890",
"state": "Berlin"
},
"phone": "+49 30 1234567",
"email": "max.mustermann@example.org",
"website": "https:\/\/example.org",
"period_start": "2026-01-01",
"period_end": "2026-01-31",
"contract_id": "CON-2026-001",
"tax_breakdowns": [
{
"taxable_amount": "1000.00",
"tax_amount": "190.00",
"tax_rate": "19.00",
"taxability": "taxable",
"tax_collection_mechanism": "standard",
"tax_exemption_reason": "Not applicable"
}
]
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/information
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| type | string | optional | Required if the parameters type_id are not present. invoice, credit-note, reminder, salary-statement, bank-statement, contract, balance-sheet, tax-assessment-note, timesheet, email, letter or other |
| type_id | integer | optional | Required if the parameters type are not present. Valid type id |
| date | date | required | |
| title | string | optional | Maximum: 1000 |
| document_number | string | optional | Maximum: 255 |
| order_id | string | optional | Maximum: 255 |
| reference_id | string | optional | Maximum: 255 |
| net_amount | array | optional | Must be an array |
| net_amount[amount] | numeric | optional | |
| net_amount[currency] | string | optional | Must have the size of 3 |
| gross_amount | array | optional | Must be an array |
| gross_amount[amount] | numeric | optional | |
| gross_amount[currency] | string | optional | Must have the size of 3 |
| tax_amount | array | optional | Must be an array |
| tax_amount[amount] | numeric | optional | |
| tax_amount[currency] | string | optional | Must have the size of 3 |
| tax_rate | numeric | optional | |
| tax_breakdowns | array | optional | Must be an array Maximum: 100. Only the documented row keys are accepted; unknown keys return HTTP 422. |
| tax_system | string | optional | Maximum: 100 |
| taxability | string | optional | Maximum: 64 |
| tax_collection_mechanism | string | optional | Maximum: 64 |
| cross_border_tax_treatment | string | optional | Maximum: 100 |
| supply_type | string | optional | Maximum: 100 |
| tax_exemption_reason | string | optional | Maximum: 2000 |
| sender_street | string | optional | Maximum: 255 |
| sender_zip | string | optional | Maximum: 32 |
| sender_city | string | optional | Maximum: 255 |
| sender_state | string | optional | Maximum: 255 |
| sender_country_code | string | optional | Must have the size of 2 |
| sender_tax_id | string | optional | Maximum: 255 |
| sender_vat_number | string | optional | Maximum: 255 |
| recipient_street | string | optional | Maximum: 255 |
| recipient_zip | string | optional | Maximum: 32 |
| recipient_city | string | optional | Maximum: 255 |
| recipient_state | string | optional | Maximum: 255 |
| recipient_country_code | string | optional | Must have the size of 2 |
| recipient_tax_id | string | optional | Maximum: 255 |
| recipient_vat_number | string | optional | Maximum: 255 |
| from | string | optional | Maximum: 998 |
| from_email | optional | Maximum: 255 |
|
| to | string | optional | Maximum: 998 |
| to_email | optional | Maximum: 255 |
|
| subject | string | optional | Maximum: 998 |
| email_date | date | optional | |
| message_id | string | optional | Maximum: 998 |
| in_reply_to | string | optional | Maximum: 998 |
| payment_due_date | date | optional | |
| customer_id | string | optional | Maximum: 255 |
| invoice_id | string | optional | Maximum: 255 |
| credit_note_id | string | optional | Maximum: 255 |
| amount_to_pay | array | optional | Must be an array |
| amount_to_pay[amount] | numeric | optional | |
| amount_to_pay[currency] | string | optional | Must have the size of 3 |
| payment_status | boolean or string | optional | Boolean values and 0/1 are normalized to paid/open; strings may contain up to 255 characters. |
| opening_balance | array | optional | Must be an array |
| opening_balance[amount] | numeric | optional | |
| opening_balance[currency] | string | optional | Must have the size of 3 |
| closing_balance | array | optional | Must be an array |
| closing_balance[amount] | numeric | optional | |
| closing_balance[currency] | string | optional | Must have the size of 3 |
| cost_center | string | optional | Maximum: 255 |
| account_holder | string | optional | Maximum: 255 |
| iban | string | optional | Maximum: 34 |
| bic | string | optional | Maximum: 11 |
| bank | string | optional | Maximum: 255 |
| payment_reference | string | optional | Maximum: 255 |
| company_register_id | array | optional | Must be an array |
| company_register_id[area] | string | optional | HRA or HRB |
| company_register_id[number] | string | optional | Maximum: 255 |
| company_register_id[office] | string | optional | Maximum: 255 |
| vat_number | string | optional | Maximum: 255 |
| tax_number | array | optional | Must be an array |
| tax_number[number] | string | optional | Maximum: 255 |
| tax_number[state] | string | optional | Maximum: 255 |
| phone | string | optional | Maximum: 255 |
| optional | Maximum: 255 |
||
| website | string | optional | Maximum: 255 |
| period_start | date | optional | |
| period_end | date | optional | |
| net_earnings | array | optional | Must be an array |
| net_earnings[amount] | numeric | optional | |
| net_earnings[currency] | string | optional | Must have the size of 3 |
| gross_earnings | array | optional | Must be an array |
| gross_earnings[amount] | numeric | optional | |
| gross_earnings[currency] | string | optional | Must have the size of 3 |
| contract_id | string | optional | Maximum: 255 |
| tax_breakdowns[0] | array | optional | Must be an array |
| tax_breakdowns[0][taxable_amount] | numeric | optional | Numeric amount in the currency used by the document-level money fields. |
| tax_breakdowns[0][tax_amount] | numeric | optional | Numeric amount in the currency used by the document-level money fields. |
| tax_breakdowns[0][tax_rate] | numeric | optional | |
| tax_breakdowns[0][taxability] | string | optional | Maximum: 64 |
| tax_breakdowns[0][tax_collection_mechanism] | string | optional | Maximum: 64 |
| tax_breakdowns[0][tax_exemption_reason] | string | optional | Maximum: 2000 |
Update tags
Only possible if the document status is under_review or archived.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/tags" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "tags[]"="Invoices"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/tags",
"method": "PUT",
"data": {
"tags": [
"Invoices"
]
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/tags
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| tags | array | optional | Must be an array |
Update a note
Only possible if the document status is under_review or archived.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/note" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "note"="Payment due within 14 days"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/note",
"method": "PUT",
"data": {
"note": "Payment due within 14 days"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/note
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| note | string | optional | Maximum: 65535 |
Update a folder
Only possible if the document status is under_review or archived.
Returns 409 Conflict if the document is not in a metadata-updatable status.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/folder" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "folder_id"="99"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/folder",
"method": "PUT",
"data": {
"folder_id": 99
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/folder
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| folder_id | integer | required | Valid folder id |
Update a stack
Only possible if the document status is under_review, archived, or trashed.
Submitting the current stack assignment is idempotent and returns the unchanged document metadata.
Returns 409 Conflict if the document is not in a stack-updatable status or a trashed document is assigned to a stack.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document or of another member of an affected stack
is running. Retry the request once the analysis finished.
Returns 409 Conflict with code document_stack_assignment_changed if
the stack assignment of an affected document changed while the request
acquired its locks. Retry the request against the current stack state.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/stack" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "stack_id"="5217164"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/stack",
"method": "PUT",
"data": {
"stack_id": 5217164
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/stack
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| stack_id | integer | optional | Valid stack id |
Update retention periods
This operation is only possible if the document’s status is archived and its archived_at timestamp is within the last 24 hours.
Returns 409 Conflict if the document is not in a retention-modifiable status or the retention window has expired.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of the document is running. Retry the request once the
analysis finished.
Returns the metadata of the updated document.
Authorized roles
- owner
- user-management
- super-archivist
archivistuploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/documents/{document}/retention" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "locked_for"="6m" \
-d "trash_after"="1y"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/documents/{document}/retention",
"method": "PUT",
"data": {
"locked_for": "6m",
"trash_after": "1y"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT documents/{document}/retention
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| locked_for | string | optional | Date Interval: 7d or 6m or 1y |
| trash_after | string | optional | Date Interval: 7d or 6m or 1y |
Missing recurring documents
Get missing recurring documents
Returns a paginated list of detected missing recurring documents for a team.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/missing-recurring-documents" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "status"="resolved" \
-d "sort"="detected_at" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/missing-recurring-documents",
"method": "GET",
"data": {
"team_id": 42,
"status": "resolved",
"sort": "detected_at",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET missing-recurring-documents
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | Valid team id |
| status | string | optional | open, ignored, resolved or all |
| sort | string | optional | missing_period_start, -missing_period_start, detected_at or -detected_at |
| per_page | integer | optional | Between: 1 and 100 |
Mark a missing recurring document as ignored
Returns the updated missing recurring document.
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/missing-recurring-documents/{missingRecurringDocument}/ignore" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/missing-recurring-documents/{missingRecurringDocument}/ignore",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT missing-recurring-documents/{missingRecurringDocument}/ignore
Mark a missing recurring document as resolved
Returns the updated missing recurring document.
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/missing-recurring-documents/{missingRecurringDocument}/resolve" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/missing-recurring-documents/{missingRecurringDocument}/resolve",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT missing-recurring-documents/{missingRecurringDocument}/resolve
Partner Payouts
Get partner payouts
Returns an unpaginated list of all partner payouts.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/partner-payouts" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/partner-payouts",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET partner-payouts
Get a partner payout
Returns the file.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/partner-payouts/{partner_payout}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "disposition"="inline" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/partner-payouts/{partner_payout}",
"method": "GET",
"data": {
"disposition": "inline"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET partner-payouts/{partner_payout}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| disposition | string | optional | inline or attachment |
Reminders
Get reminders
Returns a paginated list of all reminders.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/reminders" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "status"="due" \
-d "assigned_to"="115" \
-d "is_done"="1" \
-d "sort"="due_date" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/reminders",
"method": "GET",
"data": {
"team_id": 42,
"status": "due",
"assigned_to": 115,
"is_done": true,
"sort": "due_date",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET reminders
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| status | string | optional | due or overdue |
| assigned_to | integer | optional | |
| is_done | boolean | optional | |
| sort | string | optional | due_date or -due_date |
| per_page | integer | optional | Between: 1 and 100 |
Create a reminder
Returns the created reminder.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/reminders" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "document_id"="1001" \
-d "description"="Pay invoice" \
-d "assigned_to"="115" \
-d "due_date"="2026-02-15" \
-d "recurrence_interval"="292" \
-d "recurrence_unit"="year"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/reminders",
"method": "POST",
"data": {
"document_id": 1001,
"description": "Pay invoice",
"assigned_to": 115,
"due_date": "2026-02-15",
"recurrence_interval": 292,
"recurrence_unit": "year"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST reminders
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| document_id | integer | optional | Valid document id |
| description | string | required | Maximum: 255 |
| assigned_to | integer | required | |
| due_date | date | required | |
| recurrence_interval | integer | optional | Between: 1 and 365 |
| recurrence_unit | string | optional | day, week, month or year |
Get a reminder
Returns the requested reminder.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/reminders/{reminder}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/reminders/{reminder}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET reminders/{reminder}
Update a reminder
Returns the updated reminder.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/reminders/{reminder}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "description"="Pay invoice" \
-d "assigned_to"="115" \
-d "due_date"="2026-02-15" \
-d "recurrence_interval"="214" \
-d "recurrence_unit"="month"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/reminders/{reminder}",
"method": "PUT",
"data": {
"description": "Pay invoice",
"assigned_to": 115,
"due_date": "2026-02-15",
"recurrence_interval": 214,
"recurrence_unit": "month"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT reminders/{reminder}
PATCH reminders/{reminder}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| description | string | required | Maximum: 255 |
| assigned_to | integer | required | |
| due_date | date | required | |
| recurrence_interval | integer | optional | Between: 1 and 365 |
| recurrence_unit | string | optional | day, week, month or year |
Mark a reminder as done
Assigned users and users with reminder-management permissions can mark reminders as done.
Returns the updated reminder.
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/reminders/{reminder}/done" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/reminders/{reminder}/done",
"method": "PUT",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT reminders/{reminder}/done
Delete a reminder
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/reminders/{reminder}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/reminders/{reminder}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE reminders/{reminder}
Search
Get results
Returns a paginated list of documents that match the given full‑text query.
You can combine free‑text terms with powerful filters (e.g., flow:incoming archived_at:2026-05-05). A complete reference of supported query filters is available in the search help article.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/search" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "query"="invoice january" \
-d "sort"="relevance" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/search",
"method": "GET",
"data": {
"team_id": 42,
"query": "invoice january",
"sort": "relevance",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET search
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| query | string | required | |
| sort | string | optional | relevance, -relevance, filename, -filename, date, -date, amount_to_pay, -amount_to_pay, archived_at, -archived_at, locked_until or -locked_until |
| per_page | integer | optional | Between: 1 and 1000 |
Stacks
Get stacks
Returns a paginated list of all stacks.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/stacks" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "sort"="name" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/stacks",
"method": "GET",
"data": {
"team_id": 42,
"sort": "name",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET stacks
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| sort | string | optional | name or -name |
| per_page | integer | optional | Between: 1 and 100 |
Create a stack
A document that is already being reanalyzed or is not in a stackable status when the request is validated is reported as a validation error. The conflicts below cover changes that are only detectable while the locks of the mutation are held.
Returns 409 Conflict with code document_reanalysis_in_progress if a
reanalysis of one of the documents starts after that validation. Retry
the request once the analysis finished.
Returns 409 Conflict with code document_stack_not_updatable if one of
the documents leaves a stackable status after that validation.
Returns 409 Conflict with code document_stack_assignment_changed if
the stack assignment of one of the documents changed while the request
acquired its locks. Retry the request against the current stack state.
Returns the created stack.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/stacks" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "name"="Max Mustermann" \
-d "display_mode"="main" \
-d "document_ids[]"="100" \
-d "document_ids[]"="200" \
-d "main_document_id"="200"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/stacks",
"method": "POST",
"data": {
"team_id": 42,
"name": "Max Mustermann",
"display_mode": "main",
"document_ids": [
100,
200
],
"main_document_id": 200
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST stacks
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| name | string | optional | Maximum: 255 |
| display_mode | string | required | all or main |
| document_ids | array | required | Must be an array Minimum: 2 |
| main_document_id | integer | optional | Valid document id |
Get a stack
Returns the requested stack.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/stacks/{stack}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/stacks/{stack}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET stacks/{stack}
Update a stack
Documents that this request removes from the stack are not part of its validation, so their conflicts always surface below. A document that stays in the stack or is newly assigned is reported as a validation error when it already violates the rules; the conflicts below then cover changes that are only detectable while the locks are held.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of a removed document is running, or if a reanalysis of
another affected document starts after the validation. Retry the request
once the analysis finished.
Returns 409 Conflict with code document_stack_not_updatable if a
removed document is not in a status that allows unstacking, or if
another affected document leaves its allowed status after the
validation.
Returns 409 Conflict with code document_stack_assignment_changed if
the membership of the stack changed while the request acquired its
locks. Retry the request against the current stack state.
Returns the updated stack.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/stacks/{stack}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "display_mode"="main" \
-d "document_ids[]"="100" \
-d "document_ids[]"="200" \
-d "main_document_id"="200"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/stacks/{stack}",
"method": "PUT",
"data": {
"name": "Max Mustermann",
"display_mode": "main",
"document_ids": [
100,
200
],
"main_document_id": 200
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT stacks/{stack}
PATCH stacks/{stack}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | optional | Maximum: 255 |
| display_mode | string | optional | all or main |
| document_ids | array | optional | Must be an array Minimum: 2 |
| main_document_id | integer | optional | Valid document id |
Delete a stack
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of one of its documents is running. Retry the request once
the analysis finished.
Returns 409 Conflict with code document_stack_not_updatable if one of
its documents is not in a status that allows unstacking.
Returns 409 Conflict with code document_stack_assignment_changed if
the membership of the stack changed while the request acquired its
locks. Retry the request against the current stack state.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/stacks/{stack}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/stacks/{stack}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE stacks/{stack}
Storage
Get storage
Returns the archived, versioned, free, and total attributes.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/storage" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/storage",
"method": "GET",
"data": {
"team_id": 42
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET storage
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required |
Tags
Get tags
Returns a paginated list of all tags.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/tags" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "sort"="-name" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/tags",
"method": "GET",
"data": {
"team_id": 42,
"sort": "-name",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET tags
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| sort | string | optional | name or -name |
| per_page | integer | optional | Between: 1 and 100 |
Suggest tags
Returns a paginated list of suggested tags. 5 per page.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/tags/suggest" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "query"="invoice january" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/tags/suggest",
"method": "GET",
"data": {
"team_id": 42,
"query": "invoice january"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET tags/suggest
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| query | string | optional |
Create a tag
Returns the created tag.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/tags" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "name"="Max Mustermann"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/tags",
"method": "POST",
"data": {
"team_id": 42,
"name": "Max Mustermann"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST tags
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| name | string | required | Maximum: 255 |
Get a tag
Returns the requested tag.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/tags/{tag}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/tags/{tag}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET tags/{tag}
Update a tag
Returns the updated tag.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/tags/{tag}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/tags/{tag}",
"method": "PUT",
"data": {
"name": "Max Mustermann"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT tags/{tag}
PATCH tags/{tag}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | required | Maximum: 255 |
Merge a tag into another tag
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/tags/{tag}/merge" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "target_id"="1085178"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/tags/{tag}/merge",
"method": "PUT",
"data": {
"target_id": 1085178
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT tags/{tag}/merge
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| target_id | integer | required | Valid tag id |
Delete a tag
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/tags/{tag}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/tags/{tag}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE tags/{tag}
Team Subscriptions
Change the plan for a centrally billed team
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/teams/{team}/subscription" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "plan"="enterprise-plus"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams/{team}/subscription",
"method": "PUT",
"data": {
"team_id": 42,
"plan": "enterprise-plus"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT teams/{team}/subscription
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| plan | string | required | team, startup, business, business-plus, enterprise, enterprise-plus, enterprise-plus2, enterprise-250k or enterprise-500k |
Cancel the plan for a centrally billed team
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/teams/{team}/subscription" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams/{team}/subscription",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE teams/{team}/subscription
Teams
Get teams
Returns an unpaginated list of all teams the current user belongs to.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/teams" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET teams
Create a centrally billed team
Enforces centrally_billed=true and requires a main_team_id owned by the caller.
Example request:
curl -X POST "https://www.einfacharchiv.app/api/teams" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "main_team_id"="96351"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams",
"method": "POST",
"data": {
"name": "Max Mustermann",
"main_team_id": 96351
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST teams
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | required | Maximum: 255 |
| main_team_id | integer | required | Valid team id |
Get a team
Returns the requested team. Additional billing information will be returned for owners.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/teams/{team}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams/{team}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET teams/{team}
Update a centrally billed team
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/teams/{team}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "slug"="quis"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams/{team}",
"method": "PUT",
"data": {
"name": "Max Mustermann",
"slug": "quis"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT teams/{team}
PATCH teams/{team}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | required | Maximum: 255 |
| slug | string | required | Allowed: alpha-numeric characters, as well as dashes and underscores. Maximum: 255 |
Delete a centrally billed team
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/teams/{team}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "confirm_migration"="1" \
-d "confirm_legal"="1" \
-d "release_from_retention"="1" \
-d "reason"="quia" \
-d "password"="quia"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/teams/{team}",
"method": "DELETE",
"data": {
"confirm_migration": true,
"confirm_legal": true,
"release_from_retention": true,
"reason": "quia",
"password": "quia"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE teams/{team}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| confirm_migration | boolean | required | |
| confirm_legal | boolean | required | |
| release_from_retention | boolean | required | |
| reason | string | required | Minimum: 25 |
| password | string | required |
Trash
Get documents
Returns a paginated list of all documents in the trash.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/trash" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "sort"="trashed_at" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/trash",
"method": "GET",
"data": {
"team_id": 42,
"sort": "trashed_at",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET trash
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| sort | string | optional | trashed_at or -trashed_at |
| per_page | integer | optional | Between: 1 and 100 |
Empty the trash
Documents are deleted one by one. The first document that cannot be deleted answers the request with a conflict, so the trash may already be partially emptied. Repeat the request once the conflict is resolved.
Returns 409 Conflict with code document_reanalysis_in_progress while
a reanalysis of another member of a stack of a trashed document is
running. Retry the request once the analysis finished.
Returns 409 Conflict with code document_not_deletable if a document
left the trash after it was selected.
Returns 409 Conflict with code document_stack_not_updatable if
another member of the stack of a trashed document is not in a status
that allows unstacking.
Returns 409 Conflict with code document_stack_assignment_changed if
the stack assignment of a document changed while the request acquired
its locks. Retry the request against the current stack state.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
- archivist
uploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/trash/empty" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/trash/empty",
"method": "POST",
"data": {
"team_id": 42
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST trash/empty
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required |
Types
Get types
Returns an unpaginated list of all types.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/types" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/types",
"method": "GET",
"data": {
"team_id": 42
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET types
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required |
Create a type
Returns the created type.
Authorized roles
- owner
- user-management
- super-archivist
archivistuploadervisitor
Example request:
curl -X POST "https://www.einfacharchiv.app/api/types" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "name"="Max Mustermann" \
-d "locked_for"="6m" \
-d "trash_after"="1y"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/types",
"method": "POST",
"data": {
"team_id": 42,
"name": "Max Mustermann",
"locked_for": "6m",
"trash_after": "1y"
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST types
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| name | string | required | Maximum: 255 |
| locked_for | string | optional | Date Interval: 7d or 6m or 1y |
| trash_after | string | optional | Date Interval: 7d or 6m or 1y |
Get a type
Returns the requested type.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/types/{type}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/types/{type}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET types/{type}
Update a type
Returns the updated type.
Authorized roles
- owner
- user-management
- super-archivist
archivistuploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/types/{type}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "locked_for"="6m" \
-d "trash_after"="1y" \
-d "apply_retention_to_existing"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/types/{type}",
"method": "PUT",
"data": {
"name": "Max Mustermann",
"locked_for": "6m",
"trash_after": "1y",
"apply_retention_to_existing": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT types/{type}
PATCH types/{type}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | required | Maximum: 255 |
| locked_for | string | optional | Date Interval: 7d or 6m or 1y |
| trash_after | string | optional | Date Interval: 7d or 6m or 1y |
| apply_retention_to_existing | boolean | optional |
Merge a type into another type
Only possible if type is custom.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
archivistuploadervisitor
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/types/{type}/merge" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "target_id"="7"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/types/{type}/merge",
"method": "PUT",
"data": {
"target_id": 7
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT types/{type}/merge
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| target_id | integer | required | Valid type id |
Delete a type
Only possible if type is custom.
Returns 204 No Content if successful.
Authorized roles
- owner
- user-management
- super-archivist
archivistuploadervisitor
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/types/{type}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/types/{type}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE types/{type}
Upcoming Trash
Get documents
Returns a paginated list of archived documents whose automatic trash date falls within the provided lookahead window.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/upcoming-trash" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "days"="221" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/upcoming-trash",
"method": "GET",
"data": {
"team_id": 42,
"days": 221,
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET upcoming-trash
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| days | integer | optional | Minimum: 1 Maximum: 365 |
| per_page | integer | optional | Between: 1 and 100 |
User
Get current user
Example request:
curl -X GET "https://www.einfacharchiv.app/api/user" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/user",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET user
Users
Get users
Returns an unpaginated list of all users.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/users" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/users",
"method": "GET",
"data": {
"team_id": 42
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET users
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required |
Get a user
Returns the requested user.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/users/{user}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/users/{user}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET users/{user}
Versions
Get versions
Returns a paginated list of all versions.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/versions" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "document_id"="1001" \
-d "sort"="created_at" \
-d "per_page"="25" \
-G
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/versions",
"method": "GET",
"data": {
"document_id": 1001,
"sort": "created_at",
"per_page": 25
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET versions
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| document_id | integer | required | |
| sort | string | optional | created_at or -created_at |
| per_page | integer | optional | Between: 1 and 100 |
Get a document
Returns the file.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/versions/{version}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/versions/{version}",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET versions/{version}
Webhooks
Example payload (for
document.incoming):
{
"event": "document.incoming",
"document": {
"id": 231,
"status": "extracting_data",
"created_at": "2026-11-01T18:00:05.060478Z",
"original_filename": "Invoice-2A5D1E69-0002.pdf",
"file_format": "pdf",
"file_size": 56175,
"permalink": "https://www.einfacharchiv.app/d/231",
"folder": {
"id": 1,
"name": "Main Archive"
},
"created_by": {
"id": 1,
"first_name": "Tom",
"last_name": "Cook"
}
},
"team_id": 1,
"delivery_id": "c2d3419b-20b2-4474-981c-cbc2eed1ced5",
"dispatched_at": "2026-11-01T18:00:05+00:00",
"webhook": {
"id": 1,
"name": "Webhook Incoming",
"event": "document.incoming"
}
}
Manage webhook subscriptions for your teams.
Webhooks let einfachArchiv call a URL you control whenever something
important happens, so you can keep other tools in sync or trigger automations.
You can also manage webhooks manually through the UI at
https://www.einfacharchiv.app/profile/api. Each webhook belongs to a team and
listens for exactly one event. When that event occurs, we send an HTTP request
using the POST method, include the event payload as JSON, and sign the message
with an X-Signature header so you can verify it came from us. Each logical
delivery has a stable UUID in delivery_id, Idempotency-Key and
X-Webhook-Delivery-ID; receivers should use it to ignore repeated delivery.
Delivery is retried up to 3 times, and every attempt has a 3-second
timeout.
Available events:
document.incoming: a new document reaches your inbox.document.analyzed: automatic data extraction finishes.document.archived: a document is moved to the archive.
Signing and secrets:
- If you set a secret while creating the webhook, einfachArchiv signs every call before it reaches your receiver.
- When a secret is present, the request carries an
X-Signatureheader that contains an HMAC-SHA256 hash of the JSON payload and your secret. - Verify the webhook by recomputing
hash_hmac('sha256', json_encode($payload), $secret)in your receiver and comparing it to the header.List webhooks you can manage
Returns every webhook on teams where you have permission to administer
members. The response contains the webhook definitions plus a meta
section that repeats the available events, lists the teams you can target,
and exposes the signature header name your receiver should check.
Example request:
curl -X GET "https://www.einfacharchiv.app/api/webhooks" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/webhooks",
"method": "GET",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
GET webhooks
Create a new webhook
Provide the team, the event you want to listen for, the destination URL, and an optional secret for signing verification. Once saved, einfachArchiv will call the URL every time the chosen event fires.
Example request:
curl -X POST "https://www.einfacharchiv.app/api/webhooks" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "team_id"="42" \
-d "name"="Max Mustermann" \
-d "event"="document.archived" \
-d "url"="http://schultz.com/autem-non-ducimus-molestiae.html" \
-d "secret"="illum" \
-d "is_active"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/webhooks",
"method": "POST",
"data": {
"team_id": 42,
"name": "Max Mustermann",
"event": "document.archived",
"url": "http:\/\/schultz.com\/autem-non-ducimus-molestiae.html",
"secret": "illum",
"is_active": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
POST webhooks
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| team_id | integer | required | |
| name | string | required | Maximum: 255 |
| event | string | required | document.incoming, document.analyzed or document.archived |
| url | url | required | |
| secret | string | optional | Maximum: 255 |
| is_active | boolean | optional |
Update an existing webhook
You can rename the webhook, switch to another event, change the URL or
secret, or pause delivery with is_active. Any changes take effect for
the very next matching event.
Example request:
curl -X PUT "https://www.einfacharchiv.app/api/webhooks/{webhook}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "name"="Max Mustermann" \
-d "event"="document.analyzed" \
-d "url"="https://www.windler.biz/inventore-perferendis-voluptatum-ex-ullam" \
-d "secret"="praesentium" \
-d "is_active"="1"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/webhooks/{webhook}",
"method": "PUT",
"data": {
"name": "Max Mustermann",
"event": "document.analyzed",
"url": "https:\/\/www.windler.biz\/inventore-perferendis-voluptatum-ex-ullam",
"secret": "praesentium",
"is_active": true
},
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
PUT webhooks/{webhook}
PATCH webhooks/{webhook}
Parameters
| Parameter | Type | Status | Description |
|---|---|---|---|
| name | string | required | Maximum: 255 |
| event | string | required | document.incoming, document.analyzed or document.archived |
| url | url | required | |
| secret | string | optional | Maximum: 255 |
| is_active | boolean | optional |
Delete a webhook
Permanently removes the webhook so no further calls are made for its event. Use this when an integration is no longer required.
Example request:
curl -X DELETE "https://www.einfacharchiv.app/api/webhooks/{webhook}" \
-H "Accept: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
var settings = {
"async": true,
"crossDomain": true,
"url": "https://www.einfacharchiv.app/api/webhooks/{webhook}",
"method": "DELETE",
"headers": {
"accept": "application/json",
"authorization": "Bearer " + access_token
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
HTTP Request
DELETE webhooks/{webhook}