diff --git a/.docker/Dockerfile b/.docker/Dockerfile
index 235f2f828b0a09c10e717b3ebdcfe9a6295247c4..7202387fd6face8d02c97f51e1c79c6e5a3a0d61 100644
--- a/.docker/Dockerfile
+++ b/.docker/Dockerfile
@@ -12,10 +12,8 @@ RUN apt-get install -y liboctave-dev/buster-backports
 RUN apt-get install -y unzip
 RUN apt-get install -y wget
 
-# install generate-doc package for octave
-RUN wget --output-document generate_doc_unreleased.zip \
-    https://github.com/gnu-octave/generate_doc/archive/refs/heads/main.zip
-RUN octave --eval "pkg install generate_doc_unreleased.zip"
+# install generate-html package for octave
+RUN octave --eval "pkg install 'https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/generate_html-0.3.2.tar.gz'"
 
 # Unit test framework (MOxUnit)
 WORKDIR /
diff --git a/.gitignore b/.gitignore
index 237b657c557f028e96e28384f44ccf8f4bfaec81..3b80efdd05ae5d1c03de33c40b8ee31d7f428e0d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ inst/
 *.tar.gz
 *.zip
 doc/_build_octave/
+NEWS
 
 # Caches
 .*cache
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1282a72ae253e440025384fdf035cecfb5c77c61..15fbbfd5f3935213eae428d4272e368f47f47516 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -27,6 +27,7 @@ variables:
   CPPLIB_BRANCH: f-cpp-to-string
 
   OCTAVEINTTEST_PIPELINE: https://gitlab.indiscale.com/api/v4/projects/121/trigger/pipeline
+  OCTAVEINTTEST_BRANCHES: https://gitlab.indiscale.com/api/v4/projects/121/repository/branches
 
 
 image: $OCTAVE_REGISTRY_IMAGE
@@ -104,7 +105,11 @@ trigger_inttest:
     ## Determine the octaveinttest branch...
     # ... sync'ed f-branch (f-bar on octavelib requires f-bar on octaveinttest)...
     - if echo "$CI_COMMIT_REF_NAME" | grep -c "^f-" ; then
-        OCTAVEINT_REF=$CI_COMMIT_REF_NAME ;
+        if curl -o /dev/null -s -w "%{http_code}" $OCTAVEINTTEST_BRANCHES/$CI_COMMIT_REF_NAME | grep "404"; then
+          OCTAVEINT_REF=dev ;
+        else
+          OCTAVEINT_REF=$CI_COMMIT_REF_NAME ;
+        fi
       fi;
     # ... or use main if possible...
     - if [[ "$CI_COMMIT_REF_NAME" == "main" ]] ; then
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f8400a33edf45615116dbb7ed6c2230c1e0afea5..a298f8a8d33b4219428e5e8f8819e978debdd62c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Added ###
 
 - Full functionality of libcaosdb mapped to Octave / Matlab.
+- Basic documentation (check out the integration tests for more examples).
 
 ## [0.0.1] - 2021-08-12 ##
 
diff --git a/DESCRIPTION b/DESCRIPTION
index 5d2d70059af7c7994ba2e3ce7176fd3c47f006c7..0b13ca6d2a364971dec95324d34d9dca4c721915 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -6,6 +6,8 @@ Author: Daniel Hornung <d.hornung@indiscale.com>
 Maintainer: Daniel Hornung <d.hornung@indiscale.com>
 Title: Octave and Matlab library for CaosDB
 Description: This package contains utility functions to interact with CaosDB.
+ <p>It makes use of <a href=https://gitlab.com/caosdb/caosdb-cpplib>libcaosdb</a>
+ which must be installed on the system.</p>
 License: AGPLv3
 Categories: data management
 Url: https://gitlab.com/caosdb/caosdb-octavelib
diff --git a/Makefile b/Makefile
index 8866139b76072ab087db79db293118998fb47366..ab1d497c421bcf77a3bd1dfa408f017f526d0067 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ help:
 
 .PHONY: doc
 doc:
-	cd doc && $(MAKE) html
+	$(MAKE) -C doc html
 
 ###############################################################################
 #                                   Styling                                   #
@@ -122,3 +122,14 @@ dist/caosdb.tar.gz: dist/
 .PHONY: dist/
 dist/:
 	mkdir -p dist
+
+###############################################################################
+#                                   Cleaning                                  #
+###############################################################################
+
+clean: doc_clean
+.PHONY: clean
+
+doc_clean:
+	rm -r doc/_build_octave/ build/doc/ NEWS || true
+.PHONY: doc_clean
diff --git a/README_SETUP.md b/README_SETUP.md
index 1dd89cf800b321597353d741794169020941e157..8aa03de37630806fe315a826b2fcac5fa2bde577 100644
--- a/README_SETUP.md
+++ b/README_SETUP.md
@@ -10,6 +10,7 @@ This package requires the following software:
 - For running this library, a valid libcaosdb configuration is needed, for example a
   `.caosdb_client.json` file in your home directory or current working directory.  Please look at
   [`README_SETUP.md` in caosdb-cpplib](https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib/-/blob/main/README_SETUP.md) for more information.
+* MOxUnit for unit tests, see below.
 
 ## Install and Load
 
@@ -22,6 +23,10 @@ This package requires the following software:
 
 ## Run Unit Tests
 
+* run `make test`
+
+### Requirements
+
 We use the standard test framework of Octave.
 
 See [this article](https://wiki.octave.org/Tests) for a primer and use
@@ -59,3 +64,7 @@ static website. If you rather would like to use the native,
 - `sphinx`
 - `sphinx-autoapi`
 - `recommonmark`
+- The Octave package `generate-html`, install it with
+  ```sh
+octave --eval "pkg install 'https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/generate_html-0.3.2.tar.gz'"
+  ```
diff --git a/doc/Development.rst b/doc/Development.rst
index 177393b86e356969ea988c6cc7935327fbe7d989..f177ecd01657ef899a11d9be48588487f9daacd2 100644
--- a/doc/Development.rst
+++ b/doc/Development.rst
@@ -32,6 +32,19 @@ Writing Documentation
 
        generate_package_html('caosdb', 'htdocs', 'octave-forge')
 
+Requirements
+------------
+
+
+- We use a dedicated Octave package for documentation generation: ` ``generate_html`` <https://keepachangelog.org>`_.  This package
+  can be installed as follows:
+
+    .. code-block:: octave
+
+        pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/generate_html-0.3.2.tar.gz"
+
+.. _generate_html: https://gnu-octave.github.io/packages/generate_html
+
 TexInfo details
 ---------------
 
diff --git a/doc/Generate_Octave_Doc.m b/doc/Generate_Octave_Doc.m
index f8093dc03f0fb2af550b8445cbb7c3d27fb76959..da28d6fdafa75294466f5b4d154d6de506f68a16 100644
--- a/doc/Generate_Octave_Doc.m
+++ b/doc/Generate_Octave_Doc.m
@@ -42,10 +42,12 @@ header = @(a_1, a_2, a_3) ...
            '<div id="doccontent">' ...
           ]);
 
-pkg load generate_doc;
+pkg load generate_html;
 of_options = get_html_options("octave-forge");
 setfield(of_options, '__header__', header);
-% (Re)loading caosdb package
+of_options.package_doc = "caosdb.texi";
+
+% (re)loading caosdb package
 pkg install ..;
 pkg load caosdb;
 generate_package_html('caosdb', '_build_octave/', of_options);
diff --git a/doc/Makefile b/doc/Makefile
index 5f1840a185541ad9699c4ad79cb721d1295a3a34..4ba3c85e109a54bb25f3503bfda48a212f7c5c51 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -42,10 +42,12 @@ doc-help:
 
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
+%: Makefile octavedoc
 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 octavedoc:
 	mkdir -p $(OCTAVEBUILDDIR)
+	# pandoc ../CHANGELOG.md -o ../NEWS
+	cp ../CHANGELOG.md ../NEWS
 	@$(OCTAVE) Generate_Octave_Doc.m
-
+	cp "_build_octave/caosdb/package_doc/Overview.html" "_build_octave/caosdb/overview.html"
diff --git a/doc/api/_caosdb.rst b/doc/api.rst
similarity index 79%
rename from doc/api/_caosdb.rst
rename to doc/api.rst
index 27865077f464686ac15a2fed5d3889d2afcc25ec..7b86c75cc5462358f59f117bdb99745d64682aa3 100644
--- a/doc/api/_caosdb.rst
+++ b/doc/api.rst
@@ -2,7 +2,7 @@
     #
     # This file is a part of the CaosDB Project.
     #
-    # Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
+    # Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
     # Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
     #
     # This program is free software: you can redistribute it and/or modify
@@ -19,16 +19,9 @@
     # along with this program. If not, see <https://www.gnu.org/licenses/>.
     #
 
-.. _coasdb:
 
-caosdb
-======
+Package documentation
+=====================
 
-
-.. toctree::
-    :glob:
-
-    function/*
-
-.. raw:: html
-   :file: ../_build_octave/caosdb/overview.html
+The Octave package documentation, including some code examples, can be found `here
+<_static/caosdb/index.html>`_.
diff --git a/doc/api/function/caosdb.rst b/doc/api/function/caosdb.rst
deleted file mode 100644
index d3bbbe134126b86438b43192bc94c8695894fd81..0000000000000000000000000000000000000000
--- a/doc/api/function/caosdb.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-..
-    #
-    # This file is a part of the CaosDB Project.
-    #
-    # Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
-    # Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
-    #
-    # This program is free software: you can redistribute it and/or modify
-    # it under the terms of the GNU Affero General Public License as
-    # published by the Free Software Foundation, either version 3 of the
-    # License, or (at your option) any later version.
-    #
-    # This program is distributed in the hope that it will be useful,
-    # but WITHOUT ANY WARRANTY; without even the implied warranty of
-    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    # GNU Affero General Public License for more details.
-    #
-    # You should have received a copy of the GNU Affero General Public License
-    # along with this program. If not, see <https://www.gnu.org/licenses/>.
-    #
-
-.. _caosdb_main:
-
-caosdb
-======
-
-.. toctree::
-    :hidden:
-
-.. raw:: html
-   :file: ../../_build_octave/caosdb/function/caosdb.html
diff --git a/doc/api/index.rst b/doc/api/index.rst
deleted file mode 100644
index 41b70c8d03ad88bf0d78a05a5e75b1d0def99a6f..0000000000000000000000000000000000000000
--- a/doc/api/index.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-..
-    #
-    # This file is a part of the CaosDB Project.
-    #
-    # Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
-    # Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
-    #
-    # This program is free software: you can redistribute it and/or modify
-    # it under the terms of the GNU Affero General Public License as
-    # published by the Free Software Foundation, either version 3 of the
-    # License, or (at your option) any later version.
-    #
-    # This program is distributed in the hope that it will be useful,
-    # but WITHOUT ANY WARRANTY; without even the implied warranty of
-    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    # GNU Affero General Public License for more details.
-    #
-    # You should have received a copy of the GNU Affero General Public License
-    # along with this program. If not, see <https://www.gnu.org/licenses/>.
-    #
-
-.. _api_root:
-
-Packages
-========
-
-.. toctree::
-    :glob:
-
-    _*
diff --git a/doc/caosdb.texi b/doc/caosdb.texi
new file mode 100644
index 0000000000000000000000000000000000000000..c7c73dcb9233f4346c0d60a9959fb8b68e948909
--- /dev/null
+++ b/doc/caosdb.texi
@@ -0,0 +1,170 @@
+@c This file is a part of the CaosDB Project.
+@c
+@c Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+@c Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
+@c
+@c This program is free software: you can redistribute it and/or modify
+@c it under the terms of the GNU Affero General Public License as
+@c published by the Free Software Foundation, either version 3 of the
+@c License, or (at your option) any later version.
+@c
+@c This program is distributed in the hope that it will be useful,
+@c but WITHOUT ANY WARRANTY; without even the implied warranty of
+@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+@c GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License
+@c along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@macro param{name, type, body}
+@var{\name\} : \type\
+@display
+\body\
+@end display
+@end macro
+
+
+@node Top
+@top CaosDB library for Octave/Matlab
+
+This package contains utility functions to interact with CaosDB, the flexible semantic data
+management platform.
+
+It makes use of @url{https://gitlab.com/caosdb/caosdb-cpplib, libcaosdb} which must be installed on
+the system.
+
+Full documentation how to install this package and a short tutorial for first steps with the Octave
+CaosDB library can be found on @url{https://docs.indiscale.com/caosdb-octavelib}, the source code
+for this library is freely available at @url{https://gitlab.com/caosdb/caosdb-octavelib}.
+
+If you are interested in the documentation of the functions and classes provided by this library,
+follow this link to the @url{../overview.html, API overview}.
+
+@menu
+* Overview::  How CaosDB works in Octave, and first steps.
+* Caosdb::    The @code{Caosdb} class.  This class handles connections to CaosDB servers and
+              transactions.
+* Entity::    The @code{Entity} class.  This class represents Entities (Records, RecordTypes,
+              Properties) in the CaosDB server.
+* Parents and Properties::  The subordinate classes @code{Property} and @code{Parent}, used for
+                            adding information to Entities.
+* Message::   The @code{Message} class, used for passing errors, warnings, infos.
+* Index::     Complete index for concepts, classes, functions.
+@end menu
+
+@node Overview
+
+@chapter Overview
+@cindex Installation
+@section Installation
+
+@cindex Requirements for installation
+Before installing the @code{caosdb} library in Octave, you first need to install @i{libcaosdb} with
+Conan.  Typically, it should be sufficient to download the sources from
+@url{https://gitlab.com/caosdb/caosdb-cpplib} and execute @code{make conan}.
+
+@cindex Installation, with @code{pkg install}
+@unnumberedsubsec With @code{pkg install}
+Then get the Octave package for the @code{caosdb} library or its source code and install it from
+within Octave with @code{pkg install caosdb.tar.gz;} (if you downloaded the package) or @code{pkg
+install /path/to/source/dir;}.  To make the library contents available to your code, activate it
+with @code{pkg load caosdb;}
+
+@cindex Installation, manual
+@unnumberedsubsec Manual installation
+For other environments which lack a package management system, such as Matlab, you can go into the
+@code{src/} directory and call @command{./configure} there, followed by @command{make install}.  You
+will then have to copy the resulting files to a place which is in your search path so that the
+@file{.m} and @file{.mex} files can be found.  Once the files are in your search path, they are
+immediately available to your code.
+
+@cindex Configuration (libcaosdb)
+@unnumberedsubsec Configuration
+Since the Octave CaosDB library uses @i{libcaosdb}, the configuration is handled by libcaosdb as
+well.  In practice this means that there should be a configuration file, either in the current
+directory, your home directory or at a location specified by the @env{CAOSDB_CLIENT_CONFIGURATION}
+environment variable.  More information about the configuration is available at the
+@url{https://docs.indiscale.com/caosdb-cpplib, libcaosdb documentation}.
+
+@cindex First steps
+@section First steps
+
+Starting off with CaosDB in Octave is easy:
+
+@example
+%% Set up the library
+pkg load caosdb;   % Not necessary if you manually put the CaosDB files into your search path.
+c = Caosdb();      % Uses the default connection as defined in the configuration.
+c.info()           % Output some diagnostic message.
+
+%% Execute a simple query
+my_query = 'FIND Record MusicalInstrument WITH price > 2000';
+results = c.query(my_query);
+disp(['Found ' num2str(numel(results)) ' results']);
+if numel(results) > 0
+  disp(results@{1@});
+end
+@end example
+
+You can create and modify CaosDB entities much in the same way as with libcaosdb, so please refer to
+the documentation available there for details.  These operations, and also inserting, updating and
+deleting entities are straight-forward in Octave:
+
+@example
+%% Continuing from the code above...
+my_instrument = Entity();       % Create new entity, set role and name
+my_instrument.role = 'RECORD';
+my_instrument.name = 'My new theremin';
+
+% set parent
+instrument_id = c.query('FIND RecordType MusicalInstrument')@{1@}.id;
+instrument = Parent();
+instrument.id = instrument_id;
+
+my_instrument.set_parents(@{instrument@});
+
+% set property
+price_id = c.query('FIND Property price')@{1@}.id;
+price = Property();
+price.id = price_id;
+price.set_datatype('DOUBLE');   % Datatype must be set in order to set a value.
+price.value = 2300;             % Integer values would need to be cast to int64.
+
+my_instrument.set_properties(@{price@});
+
+%% Insert the instrument Record.
+insert_result = c.insert(@{my_instrument@});
+
+disp(insert_result@{1@}.id);
+
+@end example
+
+
+@section Further reading
+
+For more information, you may want to read up on
+@itemize
+@item @ref{Caosdb, , The @code{Caosdb} class}, which holds connection information and handles the
+      transactions.
+@item @ref{Entity, , The @code{Entity} class}, a representation of CaosDB entities (Records,
+      RecordTypes, Properties).
+@item The subordinate classes @code{Property} and @code{Parent}, used for adding information to
+      Entities.
+@end itemize
+
+@c Chapters with API reference, roughly by class
+@include incl_Caosdb.texi
+@include incl_Entity.texi
+@include incl_Parents_Properties.texi
+@include incl_Message.texi
+
+@node Index
+@unnumbered Index
+
+@c Merge indices:
+@syncodeindex tp cp
+@syncodeindex fn cp
+@syncodeindex vr cp
+
+@c Print (merged) concept index:
+@printindex cp
diff --git a/doc/incl_Caosdb.texi b/doc/incl_Caosdb.texi
new file mode 100644
index 0000000000000000000000000000000000000000..b140b2852be59d72689adb6210163738e69df908
--- /dev/null
+++ b/doc/incl_Caosdb.texi
@@ -0,0 +1,185 @@
+@c This file is a part of the CaosDB Project.
+@c
+@c Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+@c Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
+@c
+@c This program is free software: you can redistribute it and/or modify
+@c it under the terms of the GNU Affero General Public License as
+@c published by the Free Software Foundation, either version 3 of the
+@c License, or (at your option) any later version.
+@c
+@c This program is distributed in the hope that it will be useful,
+@c but WITHOUT ANY WARRANTY; without even the implied warranty of
+@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+@c GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License
+@c along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@node Caosdb
+@comment  node-name,  next,  previous,  up
+@chapter The CaosDB class
+
+@c %%%%%%%%%%%%%%% Caosdb %%%%%%%%%%%%%%%
+
+@deftp {Class} Caosdb
+
+This is the main class of the CaosDB client for Octave.
+
+The @code{Caosdb} class holds information about the connection to a CaosDB server.  It provides a
+convenient interface to the possible transactions (insert, query, retrieve, update, delete) with the
+server.
+
+@end deftp
+
+@c %%%%%%%%%%%%%%% connection %%%%%%%%%%%%%%%
+@deftypeivar {Caosdb} string connection
+
+The name of the connection which shall be used for transactions via this @code{Caosdb} object.  The
+available connections are taken from the active libcaosdb configuration.  If @code{connection} is
+the empty string, the default connection will be used.
+
+@end deftypeivar
+
+@c %%%%%%%%%%%%%%% Caosdb() %%%%%%%%%%%%%%%
+@defmethod Caosdb Caosdb ([string @var{connection}])
+
+The constructor takes an optional @var{connection} argument which, if given, is used as connection
+name for transactions via this object.
+
+@end defmethod
+
+@c %%%%%%%%%%%%%%% info() %%%%%%%%%%%%%%%
+@defmethod Caosdb info ()
+
+Return a string with information about the libraries and the server.
+
+@end defmethod
+
+@c %%%%%%%%%%%%%%% retrieve_by_id() %%%%%%%%%%%%%%%
+@defmethod Caosdb retrieve_by_id( @var{ids}, @dots{} )
+
+Retrieve entities by IDs.
+
+@example
+entities = Caosdb.retrieve_by_id("my_id", @{"more", "ids"@});
+@end example
+
+@strong{Parameters}
+
+@param{ids, string or cell array of strings, The ID(s) of the entity (entities) to be retrieved.}
+
+@strong{Returns}
+
+@param{entities, cell array, The retrieved entities.}
+
+@end defmethod
+
+@c %%%%%%%%%%%%%%% query() %%%%%%%%%%%%%%%
+@defmethod Caosdb query( @var{query_str} )
+
+Execute a query.
+
+@example
+entities = Caosdb.query("FIND Record Foo WITH bar=baz");
+entities = Caosdb.query("COUNT Record Foo WITH bar=baz");
+@end example
+
+@strong{Parameters}
+
+@param{query_str, string, The query to be executed.}
+
+@strong{Returns}
+
+@param{entities, cell array, The retrieved entities.  If the query was a COUNT query@comma{} the
+result is an int64 instead.}
+
+@end defmethod
+
+@c %%%%%%%%%%%%%%% insert() %%%%%%%%%%%%%%%
+@defmethod Caosdb insert( @var{entities} )
+
+Insert an entity.
+
+@example
+inserted = Caosdb.insert(entities);
+@end example
+
+@strong{Parameters}
+
+@param{entities, cell array, A cell array with the entities to be inserted.}
+
+@strong{Returns}
+
+@param{inserted, cell array, The resulting inserted entities (sparse@comma{} only for ID and
+version).}
+
+@end defmethod
+
+@c %%%%%%%%%%%%%%% update() %%%%%%%%%%%%%%%
+@defmethod Caosdb update( @var{entities} )
+
+Update an entity.
+
+@example
+updated = Caosdb.update(entities);
+@end example
+
+@strong{Parameters}
+
+@param{entities, cell array, A cell array with the entities to be updated.  All entities must have a
+valid ID.}
+
+@strong{Returns}
+
+@param{updated, cell array, The resulting updated entities.}
+
+@end defmethod
+
+@c %%%%%%%%%%%%%%% delete_by_id() %%%%%%%%%%%%%%%
+@defmethod Caosdb retrieve_by_id( @var{ids}, @dots{} )
+
+Delete entities by IDs.
+
+@example
+entities = Caosdb.delete_by_id("my_id", @{"more", "ids"@});
+@end example
+
+The usage is equivalent to @code{retrieve_by_id(...)}.
+
+@cartouche
+@b{Note:} @code{Caosdb.delete()} will call the destructor of the Caosdb object.
+@end cartouche
+
+@strong{Parameters}
+
+@param{ids, string or cell array of strings, The ID(s) of the entity (entities) to be deleted.}
+
+@strong{Returns}
+
+@param{entities, cell array, The deleted entities.}
+
+@end defmethod
+
+@c %%%%%%%%%%%%%%% download_file_by_single_id() %%%%%%%%%%%%%%%
+@defmethod Caosdb download_file_by_single_id( @var{id}, @var{local_path} )
+
+Download a file by ID.
+
+@example
+entity = Caosdb.download_file_by_single_id("my_id", "/save/file/here.dat");
+@end example
+
+Inserting files is done by creating a "@code{FILE}" @ref{Entity} and inserting it.
+
+@strong{Parameters}
+
+@param{ids, string, The ID of the file to be downloaded.}
+@param{local_path, string, The location where the file shall be saved.}
+
+@strong{Returns}
+
+@param{entity, cell array, 1x1 cell array with the retrieved file entity.}
+
+@end defmethod
+
diff --git a/doc/incl_Entity.texi b/doc/incl_Entity.texi
new file mode 100644
index 0000000000000000000000000000000000000000..ec0441faec6c5fd4394b6543fd20721641a9e7dc
--- /dev/null
+++ b/doc/incl_Entity.texi
@@ -0,0 +1,131 @@
+@c This file is a part of the CaosDB Project.
+@c
+@c Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+@c Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
+@c
+@c This program is free software: you can redistribute it and/or modify
+@c it under the terms of the GNU Affero General Public License as
+@c published by the Free Software Foundation, either version 3 of the
+@c License, or (at your option) any later version.
+@c
+@c This program is distributed in the hope that it will be useful,
+@c but WITHOUT ANY WARRANTY; without even the implied warranty of
+@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+@c GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License
+@c along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@node Entity
+@comment  node-name,  next,  previous,  up
+@chapter The Entity class
+
+@c %%%%%%%%%%%%%%% Entity %%%%%%%%%%%%%%%
+
+@deftp Class Entity
+
+This class represents Entities (Records, RecordTypes, Properties) in the CaosDB server, much like in
+libcaosdb.  Detailed information can be found @url{https://docs.indiscale.com/caosdb-cpplib, there}.
+
+@end deftp
+
+@c %%%%%%%%%%%%%%% properties %%%%%%%%%%%%%%%
+@deftypeivar Entity string role
+One of ``@code{RECORD}'', ``@code{RECORD_TYPE}'',  ``@code{PROPERTY}'',  ``@code{FILE}''.
+@end deftypeivar
+
+@deftypeivar Entity string id
+See libcaosdb.
+@end deftypeivar
+@deftypeivar Entity string versionId
+@end deftypeivar
+@deftypeivar Entity string name
+@end deftypeivar
+@deftypeivar Entity string description
+@end deftypeivar
+@deftypeivar Entity string unit
+@end deftypeivar
+@deftypeivar Entity array value
+The exact type of the @var{value} property should match the datatype of the Entity object.
+@end deftypeivar
+@deftypeivar Entity array filepath
+Only for ``@code{FILE}'' entities: the file path on the server.
+@end deftypeivar
+@deftypeivar Entity array localpath
+Only for ``@code{FILE}'' entities: the local path to the file (for upload).
+@end deftypeivar
+
+
+@c %%%%%%%%%%%%%%% methods %%%%%%%%%%%%%%%
+
+@defmethod Entity Entity ([struct @var{data}])
+
+The constructor takes an optional @var{data} argument which may provide initial content.  The
+typical user will just use the empty constructor @code{Entity()} and add content later.  (Details
+about requirements for a valid @var{data} struct array can be found in the
+@url{https://gitlab.indiscale.com/caosdb/src/caosdb-octavelib/-/blob/main/src/lib/maoxdb.hpp, source
+code}.)
+@end defmethod
+
+@defmethod Entity get_datatype ()
+@end defmethod
+@defmethod Entity get_parents ()
+@end defmethod
+@defmethod Entity get_properties ()
+@end defmethod
+@defmethod Entity get_errors ()
+@strong{Returns}
+@param{, cell, A cell array of @ref{Message} objects@comma{} this Entity's errors.}
+@end defmethod
+@defmethod Entity get_warnings ()
+@strong{Returns}
+@param{, cell, A cell array of @ref{Message} objects@comma{} this Entity's warnings.}
+@end defmethod
+@defmethod Entity get_infos ()
+@strong{Returns}
+@param{, cell, A cell array of @ref{Message} objects@comma{} this Entity's info messages.}
+@end defmethod
+
+@defmethod Entity set_datatype (string @var{dtype_name}, [logical @var{is_reference} = false, logical @var{is_list} = false])
+Set the datatype of this Entity in a consistent manner.
+
+@strong{Parameters}
+
+@param{dtype_name, string, Either the atomic datatype (for scalar simple values) or the ID of the referenced entity (in the case of reference values).}
+@param{is_reference, logical, True if the value is a reference@comma{} else false (the default).}
+@param{is_list, logical, True if the value is list types@comma{} false if it is a scalar (the default).}
+@end defmethod
+
+@defmethod Entity set_parents (cell @var{parents})
+@strong{Parameters}
+@param{parents, cell, A cell array with the parents (objects of class @var{Parent}).}
+@end defmethod
+@defmethod Entity set_properties (cell @var{properties})
+@strong{Parameters}
+@param{properties, cell, A cell array with the properties (objects of class @var{Property}).}
+@end defmethod
+
+@defmethod Entity has_errors ()
+@strong{Returns}
+@param{, logical, True iff this Entity has stored any error messages).}
+@end defmethod
+@defmethod Entity has_warnings ()
+@strong{Returns}
+@param{, logical, True iff this Entity has stored any warning messages).}
+@end defmethod
+@defmethod Entity has_infos ()
+@strong{Returns}
+@param{, logical, True iff this Entity has stored any info messages).}
+@end defmethod
+
+@defmethod Entity to_struct ([bool @var{warn}=true])
+@strong{Note:} This method is mostly interesting for internal use of the library, end users probably
+will never need it.
+
+Convert to a struct which has all the fields that may be needed for interaction with the backend C++
+functions.
+
+If the @var{datatype} indicates a list value, the @var{value} is interpreted as such. It is an error
+if the @var{value} is list-like (cell string or more than one numeric element) while the
+@var{datatype} indicates a scalar value.
+@end defmethod
diff --git a/doc/incl_Message.texi b/doc/incl_Message.texi
new file mode 100644
index 0000000000000000000000000000000000000000..b2e97721f6ae1d10ba7d23475739bf7576ffae14
--- /dev/null
+++ b/doc/incl_Message.texi
@@ -0,0 +1,47 @@
+@c This file is a part of the CaosDB Project.
+@c
+@c Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+@c Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
+@c
+@c This program is free software: you can redistribute it and/or modify
+@c it under the terms of the GNU Affero General Public License as
+@c published by the Free Software Foundation, either version 3 of the
+@c License, or (at your option) any later version.
+@c
+@c This program is distributed in the hope that it will be useful,
+@c but WITHOUT ANY WARRANTY; without even the implied warranty of
+@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+@c GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License
+@c along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@node Message
+@chapter The Message class
+
+Messages represent errors, warnings and informative notes from the server.  If an @ref{Entity}
+object has such messages attached, it may mean that a transaction did not work out as expected, or
+that the submitted entities may not completely follow the datamodel.
+
+@c %%%%%%%%%%%%%%% Message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@deftp Class Message
+The class for server messages.
+@end deftp
+
+@c %%%%%%%%%%%%%%% properties %%%%%%%%%%%%%%%
+@deftypeivar Message int64 code
+The message code as specified
+@url{https://gitlab.com/caosdb/caosdb-proto/-/blob/main/proto/caosdb/entity/v1alpha1/main.proto, in
+the Protobuf specification}.
+@end deftypeivar
+@deftypeivar Message string description
+A human-readable description of the message.
+@end deftypeivar
+
+@c %%%%%%%%%%%%%%% methods %%%%%%%%%%%%%%%
+
+@defmethod Message Message (struct @var{data})
+
+Typically @code{Message} objects are not created by the user, but by the caosdb library. This
+constructor takes a @var{data} argument which provides initial content.
+@end defmethod
diff --git a/doc/incl_Parents_Properties.texi b/doc/incl_Parents_Properties.texi
new file mode 100644
index 0000000000000000000000000000000000000000..e6ffcd0a4a4d639665b835ca28bd3e696993737a
--- /dev/null
+++ b/doc/incl_Parents_Properties.texi
@@ -0,0 +1,114 @@
+@c This file is a part of the CaosDB Project.
+@c
+@c Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
+@c Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
+@c
+@c This program is free software: you can redistribute it and/or modify
+@c it under the terms of the GNU Affero General Public License as
+@c published by the Free Software Foundation, either version 3 of the
+@c License, or (at your option) any later version.
+@c
+@c This program is distributed in the hope that it will be useful,
+@c but WITHOUT ANY WARRANTY; without even the implied warranty of
+@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+@c GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License
+@c along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@node Parents and Properties
+@chapter Parents and Properties
+
+@code{Parent} and @code{Property} objects represent the parents and properties of actual
+@code{Entity} objects in Octave / Matlab.  Again, please look at the
+@url{https://docs.indiscale.com/caosdb-cpplib, libcaosdb documentation} for details on the
+relationships between these classes.
+
+@c %%%%%%%%%%%%%%% Parent %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+@deftp Class Parent
+The parent for an Entity.
+@end deftp
+
+@c %%%%%%%%%%%%%%% properties %%%%%%%%%%%%%%%
+@deftypeivar Parent string id
+@end deftypeivar
+@deftypeivar Parent string name
+@end deftypeivar
+@deftypeivar Parent string description
+@end deftypeivar
+
+@c %%%%%%%%%%%%%%% methods %%%%%%%%%%%%%%%
+
+@defmethod Parent Parent ([struct @var{data}])
+
+The constructor takes an optional @var{data} argument which may provide initial content.  The
+typical user will just use the empty constructor @code{Parent()} and add content later.
+@end defmethod
+
+@defmethod Parent to_struct ()
+@strong{Note:} This method is mostly interesting for internal use of the library, end users probably
+will never need it.
+
+Convert to a struct which has all the fields that may be needed for interaction with the backend C++
+functions.
+@end defmethod
+
+@c %%%%%%%%%%%%%%% Property %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+@deftp Class Property
+A property of an Entity. Note that this class is for concrete property instances which are attached
+to an Entity.  To create new Property entities in CaosDB, use the @ref{Entity} class with @var{role}
+``@code{PROPERTY}''.
+@end deftp
+
+@c %%%%%%%%%%%%%%% properties %%%%%%%%%%%%%%%
+@deftypeivar Property string id
+@end deftypeivar
+@deftypeivar Property string name
+@end deftypeivar
+@deftypeivar Property string description
+@end deftypeivar
+@deftypeivar Property string importance
+Must be one of the supported importances ``@code{OBLIGATORY}'', ``@code{RECOMMENDED}'',
+``@code{SUGGESTED}'' or ``@code{FIX}'' (see also the
+@url{https://docs.indiscale.com/caosdb-server/_apidoc/org/caosdb/server/entity/StatementStatus.html,
+server documentation}).
+@end deftypeivar
+@deftypeivar Property string unit
+@end deftypeivar
+@deftypeivar Property string value
+The exact type of the @var{value} property should match the datatype of the Property object.
+@end deftypeivar
+
+@c %%%%%%%%%%%%%%% methods %%%%%%%%%%%%%%%
+
+@defmethod Property Property ([struct @var{data}])
+The constructor takes an optional @var{data} argument which may provide initial content.  The
+typical user will just use the empty constructor @code{Provide()} and add content later.
+@end defmethod
+
+@defmethod Property get_datatype ()
+@end defmethod
+
+@defmethod Property set_datatype (string @var{dtype_name}, [logical @var{is_reference} = false, logical @var{is_list} = false])
+Set the datatype of this Property in a consistent manner.
+
+@strong{Parameters}
+
+@param{dtype_name, string, Either the atomic datatype (for scalar simple values) or the ID of the referenced entity (in the case of reference values).}
+@param{is_reference, logical, True if the value is a reference@comma{} else false (the default).}
+@param{is_list, logical, True if the value is list types@comma{} false if it is a scalar (the default).}
+@end defmethod
+
+@defmethod Property to_struct ()
+@strong{Note:} This method is mostly interesting for internal use of the library, end users probably
+will never need it.
+
+Convert to a struct which has all the fields that may be needed for interaction with the backend C++
+functions.
+
+If the @var{datatype} indicates a list value, the @var{value} is interpreted as such. It is an error
+if the @var{value} is list-like (cell string or more than one numeric element) while the
+@var{datatype} indicates a scalar value.
+@end defmethod
diff --git a/doc/index.rst b/doc/index.rst
index 6ccd2939ebe461fa4cb92af557b63c8e430dfbdb..8ce2d942c48dd62a9bd14c98c7f142cef19e620d 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -25,20 +25,17 @@
 Welcome to caosdb-octavelib's documentation!
 ============================================
 
-This is the documentation for the GNU-Octave client library for CaosDB, ``caosdb-octavelib``.
+This is the documentation for the GNU Octave client library for CaosDB, ``caosdb-octavelib``.
 
-This is work in progress.
+Note that most of the documentation is in Octave's native format.
 
 
-.. raw:: html
-   :file: ./_build_octave/caosdb/index.html
-
 .. toctree::
     :maxdepth: 4
     :caption: Contents:
 
     Welcome <self>
     Development
-    api/index
+    Package documentation <api>
 
 * :ref:`genindex`
diff --git a/src/Caosdb.m b/src/Caosdb.m
index 3337f669ecd42fb717d47f41537890d265453d4e..2c7bba712196d7a6db61089862c78d3bf8d4a1fb 100644
--- a/src/Caosdb.m
+++ b/src/Caosdb.m
@@ -1,5 +1,3 @@
-% This file is a part of the CaosDB Project.
-%
 % Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
 % Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com>
 %
@@ -16,6 +14,9 @@
 % You should have received a copy of the GNU Affero General Public License
 % along with this program. If not, see <https://www.gnu.org/licenses/>.
 
+%% Developer's note: Documentation may start to work with Octave 6, earlier versions cannot handle
+% the help strings in classdef files.
+
 % -*- texinfo -*-
 % @deftypefn {Class} {} Caosdb ()
 % This is the main class of the CaosDB client for Octave.
@@ -37,9 +38,6 @@
 %
 % @end deftypefn
 
-%!demo
-%! ## Print Help:
-%! caosdb --help;
 classdef Caosdb < handle
   properties
     connection = ""             % Will use the default connection
@@ -69,7 +67,7 @@ classdef Caosdb < handle
     %%
     % Retrieve entities by IDs
     %
-    % entities = Caosdb.retrieve_by_id("my_id", {"more", "ids"})
+    % entities = Caosdb.retrieve_by_id("my_id", {"more", "ids"});
     %
     % Parameters
     % ----------
@@ -114,8 +112,8 @@ classdef Caosdb < handle
     %%
     % Execute a query
     %
-    % entities = Caosdb.query("FIND Record Foo WITH bar=baz")
-    % entities = Caosdb.query("COUNT Record Foo WITH bar=baz")
+    % entities = Caosdb.query("FIND Record Foo WITH bar=baz");
+    % entities = Caosdb.query("COUNT Record Foo WITH bar=baz");
     %
     % Parameters
     % ----------
@@ -145,9 +143,9 @@ classdef Caosdb < handle
     end
 
     %%
-    % Insert an entity
+    % Insert an entity.
     %
-    % inserted = Caosdb.insert(entities)
+    % inserted = Caosdb.insert(entities);
     %
     % Parameters
     % ----------
@@ -185,13 +183,13 @@ classdef Caosdb < handle
     %%
     % Update an entity
     %
-    % updated = Caosdb.update(entities)
+    % updated = Caosdb.update(entities);
     %
     % Parameters
     % ----------
     %
     % entities: cell array
-    %  A cell array with the entities to be updated.
+    %  A cell array with the entities to be updated.  All entities must have a valid ID.
     %
     % Returns
     % -------
@@ -226,11 +224,11 @@ classdef Caosdb < handle
     %%
     % Delete entities by IDs.
     %
-    % entities = Caosdb.delete_by_id("my_id", {"more", "ids"})
+    % entities = Caosdb.delete_by_id("my_id", {"more", "ids"});
     %
     % The usage is equivalent to retrieve_by_id(...).
     %
-    % Note: Caosdb.delete will call the object's destructor
+    % Note: Caosdb.delete will call the destructor of the Caosdb object.
     %
     % Parameters
     % ----------
@@ -285,7 +283,7 @@ classdef Caosdb < handle
     %%
     % Download a file by ID
     %
-    % entity = Caosdb.download_file_by_single_id("my_id", "/save/file/here.dat")
+    % entity = Caosdb.download_file_by_single_id("my_id", "/save/file/here.dat");
     %
     % Inserting files is done by creating a "FILE" Entity and inserting it.
     %
diff --git a/src/Entity.m b/src/Entity.m
index 70fba8d8366bbc9437960c142ba7e0e344896699..29d55b6e72fe286ef10c20b11a87b9df41cc5e18 100644
--- a/src/Entity.m
+++ b/src/Entity.m
@@ -26,8 +26,8 @@ classdef Entity < handle
     description
     unit
     value
-    filepath    % Only for file entities: the file path on the server
-    localpath   % Only for file entities: the local path to the file (for upload)
+    filepath    % Only for file entities: the file path on the server.
+    localpath   % Only for file entities: the local path to the file (for upload).
   end
   properties (Access = private)
     datatype_    % 1x1 struct with the following fields: