# Document Properties

## A Document as JSON

<pre class="language-json"><code class="lang-json">{
  "id": "1065ff43-2181-4880-905d-bc1d6caefe4e",
  
  // document-key
  "key": "MSPro<a data-footnote-ref href="#user-content-fn-1">.</a>SAP.Invoice",
  "context": null,
  "userId": "24-001",
  
  // document-indentifier = document-key [rank]
  "rank": 0,
  
  // Content
  "contentType": "application/json",
  "content": "{ \"Prop1\" : \"abc\" }",
  
  // User-State
  "userState" : 99,
  "userInfo" : "ERR: Duplicate Invoice",
  
  // State
  "lastUpdateUtc": "2024-05-22T17:57:13.585Z",
  "createdDateUtc": "2024-05-22T17:57:13.585Z",
  
  "clientId": "MyLaptop",
  "clientVersion": 1716400633585,
    
  // Lifetime
  "expirationDateUtc": "2024-05-22T18:57:13.585Z"
}
</code></pre>

{% tabs %}
{% tab title="Index" %}
The Document's *Index* is a unique reference to a document.

The `id` is always unique. The `Id` can be client-provided when creating a new Document or it is created by the service and responded to the client.

**Document identifier**: Either `id` or the ***document-key*** `(key,context,userId)` is used to identify an existing record. When the *document-key* is provided the `key` field is mandatory, while *context* and *userId* are optional. Multiple documents with the same *document-key* can co-exist with a different `rank`. The *rank* used as an *indexer*: *document-key \[rank] -> document*.

<table><thead><tr><th width="174">Property</th><th>Description</th></tr></thead><tbody><tr><td><strong>key</strong><br>(mandatory)</td><td>The <code>key</code> is the type-name of the document. It describes what the document contains. I recommend to using namespaces for keys.<br>Example: <code>MSPro.Templates.WelcomeEMail</code></td></tr><tr><td><a href="document-properties/context"><strong>context</strong></a><br>(default = null)</td><td>The <code>context</code> describes the context in which the current document exists. You can use, for example a <em>ServiceReferenceID</em> an <em>execution-id etc.</em> You may compare the Context with a directory in your filesystem.<br>Example: <code>Key=MSPro.Inbound.ServiceRequest</code>; <code>Context=&#x3C;CustomerName></code></td></tr><tr><td><strong>userId</strong><br>(default = null)</td><td>The <code>UserId</code> was introduced to support an index that came with the document itself. For example, an external key/id like an <em>invoice-id</em>.</td></tr><tr><td><a href="document-properties/rank"><strong>rank</strong></a><br>(default = 0)</td><td>Rank is used to store multiple documents (<strong>Array</strong>) with the same <em>document-key</em> information.</td></tr></tbody></table>
{% endtab %}

{% tab title="Content" %}
The document content can be any information, like a JSON or an XML document, a string or a binary stream. Provide an appropriate `contentType` when creating the document.

<table data-full-width="true"><thead><tr><th width="201">Property</th><th>Description</th></tr></thead><tbody><tr><td><strong>content</strong><br>(mandatory)</td><td></td></tr><tr><td><strong>contentType</strong><br>(mandatory)</td><td>The following content-types are supported: <br><em>text/plain, text/html, text/xml,</em> <br><em>application/json, application/xml</em><br><em>m</em>ore to come...</td></tr></tbody></table>

{% endtab %}

{% tab title="User-State" %}
The two user fields are not used or interpreted by the service. It is solely up to the user to give them a meaning and to use them.

<table><thead><tr><th width="232">Property</th><th>Description</th></tr></thead><tbody><tr><td><strong>userState</strong><br>(mandatory, default=0)</td><td><p>The intention of the <code>userState</code> was to offer some processing state for the Document, like:</p><p>0=pending -> 1=in process -> 2=processed -> 99=error .<br>You may completely ignore this is go with the default=0.<br><br>The <code>userState</code> is part of the APIs and can be used to GET or Query (filter) Documents. For example, all Documents: <code>key="MSPro.SAP.Invoice" and userState=99</code> to fetch all documents with error (see below).</p></td></tr><tr><td>userInfo</td><td>Any text information you might find useful storing with the Document.</td></tr></tbody></table>
{% endtab %}

{% tab title="State" %}

<table><thead><tr><th width="200">Property</th><th>Description</th></tr></thead><tbody><tr><td>lastUpdateUtc</td><td>The UTC date/time with milliseconds when the document was updated last.</td></tr><tr><td>createdDateUtc</td><td>The UTC date/time with milliseconds when the document was created.</td></tr><tr><td>recordVersion</td><td><code>uNow.ToUnixTimeMilliseconds()</code> when the document was updated. You can use this <code>long (64-bit)</code> integer to check if a document has changed. Basically a different format for <code>lastUpdateUtc</code>.</td></tr></tbody></table>
{% endtab %}

{% tab title="Lifetime" %}
{% hint style="info" %}
All documents do have a **life-time** which is, **by default, one hour**!
{% endhint %}

This means, by default, documents are deleted after one hour.&#x20;

Each document has a `expirationDateUtc` which tells you exactly when the life-time expires. You can set or update that property at any time to adjust a dcoument's life-time according to your needs.

> Note, that your [Plan ](https://services.markusschmidt.pro/mspro.services/plans)may limited the maximum lifetime you can define.
> {% endtab %}
> {% endtabs %}

[^1]:
