Documentation / Guides

Manage documents

Look up a document, edit its title and fields, list documents by field, replace a document with a new version, or delete it.

Look up a document

Use the document_uuid from a search result to get a document’s title and path:

curl --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  https://api.knovas.ch:8443/secured/document/550e8400-e29b-41d4-a716-446655440000

With Document fields enabled, the title shown here is the document’s current title, including one you edited.

Update a document

Upload it again with the same identifier. The new version replaces the old one. See Add documents.

Read and edit a document’s fields

Document fields

This needs Document fields, which is on for every account. Where it is off (an account Knovas took out, or an older release), the /secured/graph/doc-values requests answer 404.

Read a document’s title, description and typed fields by its identifier. Send the identifier in the JSON body: identifiers often carry client or person names, and a query string ends up in proxy and gateway logs. ?pointer= in the query string still works.

curl -X GET https://api.knovas.ch:8443/secured/graph/doc-values \
  --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  -H "Content-Type: application/json" \
  -d '{"pointer": "Kreditoren/2024/RE-2024-0815.pdf"}'
Answer (shortened)
{
  "status": "success",
  "message": "Document values",
  "pointer": "Kreditoren/2024/RE-2024-0815.pdf",
  "document_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "acl_mode": "follows_document",
  "version": 2,
  "title": "Rechnung Beispiel GmbH",
  "title_source": "upload",
  "description": null,
  "path": "Kreditoren/2024/RE-2024-0815.pdf",
  "ingested_at": "2026-10-02T08:15:00Z",
  "warnings": [],
  "fields": {
    "doc_type": "invoice",
    "document_date": {"lo": "2024-03-15", "hi": "2024-03-15", "precision": "day"},
    "amount": {"amount": "1234.50", "currency": "CHF"},
    "party": [{"name": "Beispiel GmbH"}]
  },
  "layers": {
    "doc_type": [
      {"layer": "upload", "value": "invoice", "effective": true, "source_ref": "transmission:<id>"},
      {"layer": "rule", "value": "invoice", "effective": false, "source_ref": "rule:<id>"}
    ]
  }
}
FieldMeaning
versionChanges with every edit. Send it back when you edit (see below).
title_sourceupload, manual (edited by you) or path (no title was sent, so the file name is shown).
fieldsThe value of each field that applies now. Fields with several values show a list.
layersEvery stored value of each field, highest layer first, and which one applies (effective).
acl_modequarantined when the values are held back for access reasons (see privacy). The answer then contains nothing else.
ingested_atWhen an upload last stored these values. null when the values never came with an upload.

A document uploaded before Document fields was enabled answers with version: 0, its file name as title and no fields. A document you may not see, and an identifier that does not exist, both answer 404.

Edit fields and the title

Send your changes with the version you last read:

curl -X PATCH https://api.knovas.ch:8443/secured/graph/doc-values \
  --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  -H "Content-Type: application/json" \
  -d '{
    "pointer": "Kreditoren/2024/RE-2024-0815.pdf",
    "if_version": 2,
    "set": {"title": "Rechnung Beispiel GmbH, Telefon", "Dokumentdatum": "16.03.2024"},
    "add": {"keywords": ["Telefon"]}
  }'
KeyWhat it does
if_versionRequired. The version you last read (0 for a document without values). If someone changed the document since, you get 409 version_conflict: read again and retry.
setSets a field, or title (1 to 500 characters) or description. {"key": null} removes your value, so the uploaded value or the folder default shows again. Keys can be field keys, other names or labels.
unsetA list of fields that should read as empty, whatever the lower layers hold.
add, removeAdd or remove single values of a field that holds several values.
fields_stricttrue turns every warning into an error (422), and nothing is written.
  • Who may edit: the same rule as for changing a document’s access groups. Otherwise the answer is 403 change_not_authorized. If you use access control, send access_groups with every request, as on the knowledge graph (on GET, as ?access_groups=Legal,HR).
  • A value that does not fit is 400 invalid_value with its JSON path, and an AHV number is 400 restricted_identifier. Doubts such as ambiguous_date are warnings.
  • Values held back for access reasons cannot be edited (409 anchor_quarantined).
  • path and ingested_at cannot be edited.
The search index stays the same

Edits change what is shown and what filters find. They do not change the search index: search by meaning keeps using the title and text sent with the upload.

Where values come from

A field’s value can come from four places, called layers. For each field, the highest layer that has a value wins. The lower layers stay stored and show again when you remove the higher value.

LayerWritten byReplaced when
manual (highest)Your edits (the request above)You edit that field again
uploadThe fields of an upload, including those the RemoteController sendsThe next upload of the same identifier that carries fields
extractedReserved for a later release. Nothing writes it today.—
rule (lowest)Folder defaultsA folder default that matches the document’s identifier changes

Titles and descriptions come from the upload or from your edits. An upload never overwrites a title you set.

Folder defaults

A folder default gives every document whose identifier starts with a certain prefix a value in its lowest layer. For example: everything under Kreditoren/ is an invoice.

# Set a default (replaces an earlier one for the same prefix)
curl -X PUT https://api.knovas.ch:8443/secured/graph/doc-field-rules \
  --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  -H "Content-Type: application/json" \
  -d '{"pointer_prefix": "Kreditoren/", "set": {"doc_type": "Rechnung"}}'

# List your defaults
curl --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem https://api.knovas.ch:8443/secured/graph/doc-field-rules

# Remove a default
curl -X DELETE https://api.knovas.ch:8443/secured/graph/doc-field-rules \
  --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  -H "Content-Type: application/json" \
  -d '{"pointer_prefix": "Kreditoren/"}'
  • For each field, the longest matching prefix wins. {"key": null} switches a shorter prefix’s default off for that field.
  • Documents already stored under the prefix are updated in the background, usually within minutes. Nothing has to be uploaded again. New uploads get the default at once.
  • Uploaded values and your edits always win over a default.
  • The prefix is compared with the document identifier. Documents synced by the RemoteController have identifiers that start with rc-sync/ unless it is configured otherwise, so their prefixes start with it too.
  • Setting, listing and removing defaults is an administrator task.

List documents by field

Document fields

Listing needs Document fields and field filters, both on for every account. Where Knovas switched field filters off the request answers 400 where_unsupported, and without Document fields 404.

List every document with certain values, without asking a question and without ranking. For example: all invoices of 2024, newest first. where and return_fields work exactly as in search.

curl -X POST https://api.knovas.ch:8443/secured/graph/doc-values/find \
  --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  -H "Content-Type: application/json" \
  -d '{
    "where": {"doc_type": "Rechnung", "period": "GJ 2024"},
    "sort": {"field": "document_date", "order": "desc"},
    "limit": 100,
    "return_fields": ["document_date", "amount"]
  }'

# Next page: send the same request with "after": "<next_after of the previous page>"
Answer (shortened)
{
  "status": "success",
  "message": "Documents found",
  "documents": [
    {"pointer": "Kreditoren/2024/RE-2024-0815.pdf",
     "document_uuid": "550e8400-e29b-41d4-a716-446655440000",
     "title": "Rechnung Beispiel GmbH",
     "fields": {"document_date": {"lo": "2024-03-15", "hi": "2024-03-15", "precision": "day"},
                "amount": {"amount": "1234.50", "currency": "CHF"}}}
  ],
  "next_after": null,
  "complete": true,
  "where": {"applied": true, "clauses": 2,
            "resolved": [{"field": "doc_type", "op": "eq", "value": "invoice"},
                         {"field": "period", "op": "eq", "interval": ["2024-01-01", "2024-12-31"]}]},
  "return_fields": {"applied": true}
}
  • Keep paging until next_after is null. Pages can be short or even empty before that, because Knovas only lists documents you may see.
  • At the end, complete: true means you have seen every matching document you may see. complete: false means the list stopped at its limit: narrow where.
  • sort: {"field": "pointer"} (the default) or a date or period field, with "order": "asc" or "desc". Documents without that field come last.
  • limit: 1 to 200 documents per page (default 100).
  • total_count is only returned on the first page, and only to a caller who may see every document of your account.
  • If the list cannot be built, the answer is 503 where_unavailable. Knovas never falls back to an unfiltered list.

Delete one document

Delete a document by its identifier. Its text and search data are removed, and so are its title and field values if you use Document fields.

curl -X DELETE https://api.knovas.ch:8443/secured/delete_information_object \
  --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  -H "Content-Type: application/json" \
  -d '{"pointer": "reports/2025/q3.pdf"}'

If the identifier does not exist, you get 404.

Delete all documents

This cannot be undone

This erases every document you have uploaded. Neither you nor Knovas can bring them back. You would have to upload them again.

As a safety check, you must repeat your own account number (client_id). You got it when you signed up, and it is also written in your certificate. Both examples read it for you:

# Your account number is the id in the OU field of your certificate
CLIENT_ID=$(openssl x509 -in client_cert.pem -noout -subject -nameopt multiline \
  | grep organizationalUnitName | grep -oE '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}')

curl -X DELETE https://api.knovas.ch:8443/secured/delete_all_documents \
  --cert client_cert.pem --key client_key.pem --cacert ca_root_cert.pem \
  -H "Content-Type: application/json" \
  -d "{\"confirm_client_id\": \"$CLIENT_ID\"}"

If the number does not match, nothing is deleted.

DeletedKept
All documents, all versions and their search dataYour account, certificates and access groups. You can upload again right away.
Your ratings and feedbackUsage and billing records (they count requests, never contents)
Uploads that were still in progressYour field list, field settings and folder defaults
Document titles, descriptions and field values

To close your account and erase everything, including usage records, contact Knovas.

Questions? Write to contact@knovas.ch.

This page describes Knovas 1.6.0. Last updated .