# Einführung

Willkommen zur offiziellen API Dokumentation der Propstack App! Mit dieser Doku können Sie eine Menge machen. Diese Dokumenation behandelt unsere API V1.

## API V2 Documentation <a href="#anwendungsf-lle" id="anwendungsf-lle"></a>

Die Dokumenation für API V2 finden Sie [hier](https://api.propstack.de/docs/index.html).

## Anwendungsfälle <a href="#anwendungsf-lle" id="anwendungsf-lle"></a>

Sie können diese API verwenden, um zum Beispiel:

* Homepage mit aktuellen Einheiten/Projekten darzustellen.
* Auswertungen ihrer Kontakte zu machen.
* Backups ihrer wichtigen Daten zu erstellen.

## Fragen / Probleme

Wenn es Fragen oder Probleme zur API von Propstack gibt, senden Sie gerne eine E-Mail an <developers@propstack.de>. Präferierte Sprache im Entwickler-Team ist Englisch. :)

## Basis URL <a href="#basis-url" id="basis-url"></a>

Alle Endpunkte haben folgende Basis-URL.

```
https://api.propstack.de/v1
```

## Authentication <a href="#authentication" id="authentication"></a>

Um Anfragen auf die API machen zu können, braucht es einen API-Schlüssel. Jeder Account in Propstack kann nur einen Schlüssel haben. Dieser Schlüssel muss in jeder Abfrage mitgesendet werden. Dies kann durch 2 Wege passieren:

#### URL mit api\_key als Parameter

```
https://api.propstack.de/v1/brokers?api_key=mein_api_key
```

Die erste Möglichkeit funktioniert über einen Parameter `api_key` in der URL.

#### URL mit X-API-KEY im Header

```
$ curl https://api.propstack.de/v1/brokers -H "X-API-KEY: mein_api_key"
```

Die zweite Möglichkeit nutzt einen Header `X-API-KEY`.

## FAQ: Oft gestellte Fragen

Hier finden Sie einen Überblick über oft gestellte Fragen und Antworten.

<details>

<summary>Wie erstelle ich einen API Key oder finde einen bestehenden API Key? </summary>

In Propstack findet sich die Verwaltung der API Keys in **Verwaltung -> API-Schlüssel** <https://crm.propstack.de/app/admin/api_keys> \
\
Hier können Sie API-Schlüssel für unsere API V1 oder V2 erstellen und ihre Berechtigungen editieren. Hier können Sie auch Logs der API-Keys aufrufen und sehen, in welchen Requests diese verwendet wurden.

</details>

<details>

<summary>Ich entwickle im Auftrag der Firma XY eine Integration. Können Sie mir einen API Key bereitstellen?</summary>

Aus Sicherheitsgründen können wir Ihnen leider keinen API-Key bereitstellen. Bitte setzen Sie sich mit einem Admin Ihrer/Ihres Auftragsgberin/Auftraggebers in Verbindung, um einen API-Key mit den benötigten Berechtigungen zu erhalten.

</details>

<details>

<summary>Welche Unterschiede gibt es zwischen API V1 und API V2?</summary>

API V2 ist aktuell noch in Arbeit. Es sind nicht alle V1-Endpunkte in V2 abgebildet. Allgemein, aber ist V2 bei Abfrage großer Datenmengen mit den Scroll-Endpunkten effizienter. Abhängig von Ihrem Anwendungszweck ist es sinnvoll, beide API Versionen zu verwenden.

</details>

<details>

<summary>Wie verbinde ich meine Website mit Propstack?</summary>

Es gibt mehrere Möglichkeiten, Anfragen von Ihrer Website an Propstack zu übermitteln, nachdem ein Kunde ein Formular ausgefüllt hat:

* **E-Mail mit XML-Anhang**: Sie können die Kundendaten aus ihrem Formular in einer XML-Datei als Anhang via E-Mail an ein in Propstack angebundenes Postfach versenden. Sofern die E-Mail-Adresse des Absenders als Kontaktquelle (<https://crm.propstack.de/app/admin/settings/contacts>) hinterlegt ist, wird diese E-Mail automatisch als Portalanfrage erkannt und kann für eine Automatisierung verwendet werden.
* **Formatierte E-Mail**: Alternativ können Sie die Kundendaten in einer formatierten E-Mail senden. Auch hier muss die Kontaktquelle definiert sein, damit eine Automatisierung ausgelöst werden kann.
* **API-Request**: Hierbei müssen Sie zunächst einen Kontakt anlege und anschließend eine Notiz mit der ID der Kontaktquelle in `client_source_id` setzen. Beim Erstellen dieser Notiz wird dann ein Portalanfrage Trigger für die Automatisierungen ausgelöst.

Eine technische Beschreibungen zu diesen Formaten findet sich hier: <https://docs.propstack.de/webseite/anfragen>

</details>

<details>

<summary>Wie erstelle ich Suchprofile über die API?</summary>

Es gibt in Propstack die Möglichkeit, Suchprofile über die API anzulegen. Dafür müssen Kontakt und Objekt bereits bestehen. Eine techinische Beschreibung der notwendigen Felder finden Sie hier:  <https://docs.propstack.de/reference/suchprofile>

</details>

<details>

<summary>Wie setze ich Custom Felder bei Kontakten oder Objekten?</summary>

Wenn Sie Objekte oder Kontakte via API erstellen oder aktualisieren, können Sie auch Custom Felder setzen. Verwenden Sie dafür am besten das Feld `partial_custom_fields`  im Payload wie hier beschrieben: <https://docs.propstack.de/reference/kontakte#kontakt-erstellen-mit-custom-feldern>\
\
Eine technische Beschreibung zum Erstellen/Lesen von Custom Feldern finden sie hier: <https://docs.propstack.de/reference/custom-felder><br>

</details>

<details>

<summary>Feld XY fehlt auf einem API Endpunkt</summary>

Wir versuchen alle relevanten Felder auf einem Endpunkt bereitzustellen. Falls Sie ein Feld vermissen, können Sie bei Objekten den URL-Parameter `new=1` verwenden. Hierüber haben Sie Zugriff auf weitere Felder. \
\
Ansonsten schreiben Sie uns gerne eine E-Mail an <developers@propstack.de>, wenn sie ein Feld vermissen.

</details>


# Paginierung

Paginierung einer Ressource verläuft immer über die gleichen 2 Parameter, `page` und `per`.

`page` gibt den offset an, wie viele Ressourcen in einer Liste übersprungen werden. Standardmäßig beträgt der Wert `1`. Wie viele übersprungen werden, hängt vom 2. Parameter `per` ab.

`per` gibt an, wie viele Ressourcen pro Seite aufgerufen werden. Dieser Parameter sollte möglichst klein bleiben, um die Ladezeit der Abfrage so gering wie möglich zu halten. Standardmäßig beträgt der Wert dafür `20` oder `25`. Der Wert sollte aber in der Regel nicht mehr als `500` betragen, um mögliche **Timeouts** zu vermeiden.

Das heißt, beim Aufrufen der Objekte werden standardmäßig die ersten 20 Objekte zurückgegeben. Wenn man mehr braucht, setzt man entweder das `per` höher oder man macht mehrere Requests mit `page` `1`, `2`, usw.

Bei Objekten, Kontakten, Suchprofilen, Deals, Terminen, Aufgaben wird Paginierung verwendet.


# Abteilungen

Nutzer eines Unternehmens können einer Abteilung zugewiesen werden. Ein Nutzer kann immer nur zu einer Abteilung maximal angehören.

## Abteilungen lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/teams`

{% tabs %}
{% tab title="200 " %}

```json
[
    {
        "id": 1,
        "name": "Externer Vertrieb",
        "position": 2,
        "logo_url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/qnFkpCA2VRZQefM6zUmu9Udm/logo/wqgrNwWtl132LTA2j1mDYQFQ/logo.jpg",
        "broker_ids": [1, 2],
        "cancellation_policy_note": "<p>Custom Wiederruf</p>",
        "imprint_note": "",
        "terms_note": "<p>custom agb</p>",
        "privacy_note": ""
    }
]
```

{% endtab %}
{% endtabs %}

###

## Abteilung anlegen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/teams`

#### Anfrageformat

```json
{
    "team": {
        "name": "Neue Abteilung",
        "position": 1,
        "logo_url": "https://url-zum-logo.jpg",
        "broker_ids": [1, 2],
        "cancellation_policy_note": "<p>Widerrufsbelehrung</p>",
        "imprint_note": "<p>Impressum</p>",
        "terms_note": "<p>AGB</p>",
        "privacy_note": "<p>Datenschutzerklärung</p>"
    }
}
```

###

## Abteilung bearbeiten

<mark style="color:blue;">`PUT`</mark> `https://api.propstack.de/v1/teams/:id`

#### Anfrageformat

```json
{
    "team": {
        "name": "Neuer Abteilungsname",
        "position": 3,
        "logo_url": "https://neue-url-zum-logo.jpg",
        "broker_ids": [1, 3],
        "cancellation_policy_note": "<p>Aktualisierte Widerrufsbelehrung</p>",
        "imprint_note": "<p>Aktualisiertes Impressum</p>",
        "terms_note": "<p>Aktualisierte AGB</p>",
        "privacy_note": "<p>Aktualisierte Datenschutzerklärung</p>"
    }
}
```

###

## Abteilung löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/teams/:id`

{% tabs %}
{% tab title="200" %}

```json
{
    "id": 1
}
```

{% endtab %}
{% endtabs %}


# Aktivitäten

Eine Aktivität ist ein Container für eine Message, einen Task oder eine Policy.

Aktivitäten können nicht direkt angelegt werden, sondern werden intern durch PS angelegt. Um eine Aktivität anzulegen, muss man entweder eine Message oder einen Task direkt anlegen.

### Arten von Aktivitäten (`activatable_type`)

| Typ     | Beschreibung                                                                                                             |
| ------- | ------------------------------------------------------------------------------------------------------------------------ |
| Message | Ein- und ausgehende E-Mails                                                                                              |
| Task    | Mit Task sind diverse Aktivitätstypen gemeint, wie Notizen, Aufgaben, Termine, Briefe, Absagen                           |
| Policy  | Policies sind Nachweise über die Widerrufsbelehrung oder Kontakterlaubnis. Mehr Infos gibt es [hier](/reference/policy). |

## Aktivitäten lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/activities`

#### Query Parameters

| Name                        | Type       | Description                                                                                                               |
| --------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------- |
| expand                      | Boolean    | um das ausführliche JSON (einschließlich custom Felder) zu erhalten                                                       |
| order                       | String     | Aufsteigend oder absteigend sortieren. Entweder `asc` oder `desc`                                                         |
| category\_id                | Integer    | ID des Aktivitätstypen                                                                                                    |
| category\_ids               | Integer\[] | IDs der Aktivitätstypen                                                                                                   |
| client\_id                  | integer    | ID des Kontaktes                                                                                                          |
| client\_ids                 | Integer\[] | IDs der Kontakte                                                                                                          |
| property\_id                | Integer    | ID des Objektes                                                                                                           |
| property\_ids               | Integer\[] | IDs der Objekte                                                                                                           |
| project\_id                 | Integer    | ID des Projektes                                                                                                          |
| project\_ids                | Integer\[] | IDs der Projekte                                                                                                          |
| item\_type                  | String     | Typ der Aktivität. Eines von `message`, `note`, `reminder`, `event`, `policy`, `cancelation`, `decision`, `sms`, `letter` |
| broker\_id                  | Integer    | ID des Besitzers der Aktivität (Bei Notizen, Terminen, Aufgaben der, dem die Aktivität "zugewiesen" wurde)                |
| creator\_id                 | Integer    | ID des Erstellers der Aktivität                                                                                           |
| starts\_at\_from            | String     | Format: 2022-12-07T10:00:00+01:00                                                                                         |
| starts\_at\_to              | String     | Format: 2022-12-07T23:59:59+01:00                                                                                         |
| original\_created\_at\_from | String     | Format: 2022-12-07T10:00:00+01:00                                                                                         |
| original\_created\_at\_to   | String     | Format: 2022-12-07T23:59:59+01:00                                                                                         |
| only\_inquiries             | Boolean    | auf `true` oder `1` setzen, um nur Aktivitäten vom Typ "Anfrage" zu erhalten                                              |
| not\_completed              | Boolean    | um nur unvollständige Aktivitäten zu erhalten                                                                             |
| reason\_id                  | Integer    | ID des Absagegrundes der Aktivität                                                                                        |
| reason\_ids                 | Integer\[] | IDs der Absagegründe der Aktivität                                                                                        |
| group\_ids                  | Integer\[] | IDs der Merkmale                                                                                                          |
| team\_ids                   | Integer\[] | IDs der Abteilungen                                                                                                       |
| source\_id                  | Integer    | ID der Anfrage-Quelle                                                                                                     |
| blocked                     | Boolean    | Ob der angehängte Kunde gesperrt ist oder nicht                                                                           |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 123,
            "broker_id": 12,
            "client_ids": [
                123401
            ],
            "property_ids": [
                4321
            ],
            "project_ids": [],
            "client_names": [
                "Stefanie Mante"
            ],
            "property_names": [
                "CLA-1050"
            ],
            "project_names": [],
            "conversation_type": "note",
            "sender_type": null,
            "source_id": null,
            "creator_id": 123,
            "category_id": null,
            "reason_id": null,
            "created_at": "2019-01-15T01:22:37.619+01:00",
            "starts_at": null,
            "price": null,
            "group_ids": [],
            "state": "neutral",
            "title": "Eingehender Anruf um 18:00",
            "access_broker_ids": null,
            "access_department_ids": null,
            "blocked": false,
            "comments_count": 0,
            "attachments_count": 0,
            "done": false,
            "outgoing": false,
            "tracking_size": 0,
            "unread_tracking_size": 0,
            "attachments": 0,
            "comment_size": 0
        },
    ],
    "meta": {
        "total_count": 10205
    }
}
```

{% endtab %}
{% endtabs %}

Aktivitäten lassen sich paginieren über die Parameter `page` und `per`. Standardmäßig werden die ersten 20 Aktivitäten angezeigt.

## Einzelne Aktivität lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/activities/:id`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "id": 41711,
    "activatable_type": "Task",
    "activatable": {
        // je nachdem was activatable_type ist, 
        // .. kommt hier das Objekt zur E-Mail oder zum Task
    }
}
```

{% endtab %}
{% endtabs %}

## Aktivität anlegen

In der Regel möchte man eine einfache Notiz anlegen, welches in Propstacks API ein "Task" wäre. Die Beschreibung für einen Task sieht wie folgt aus:

### Task

| Attribut          | Typ        | Beschreibung                                                                                                                  |
| ----------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| title             | string     | Titel                                                                                                                         |
| note\_type\_id    | integer    | Aktivitätstyp (alle bis auf E-Mail-Typen)                                                                                     |
| body              | string     | Notizfeld für weitere Bemerkungen als HTML                                                                                    |
| client\_ids       | integer\[] | Ein Array von Kontakt-IDs mit welcher die Aktivität verknüpft werden soll. In der Regel will man nur eine Kontakt-ID mitgeben |
| property\_ids     | integer\[] | Ein Array von Objekt-IDs, womit die Aktivität verknüpft werden soll.                                                          |
| project\_ids      | integer\[] | Ein Array von Projekt-IDs, womit die Aktivität verknüpft werden soll.                                                         |
| broker\_id        | integer    | Nutzer, dem der Task zugewiesen werden soll                                                                                   |
| task\_creator\_id | integer    | Ersteller des Tasks                                                                                                           |
| task\_updater\_id | integer    | der Nutzer, der den Task zuletzt bearbeitet hat                                                                               |

#### Falls Task eine Aufgabe ist:

| Attribut   | Typ     | Beschreibung                                                                                |
| ---------- | ------- | ------------------------------------------------------------------------------------------- |
| due\_date  | date    | Datum + Uhrzeit der Fälligkeit der Aufgabe                                                  |
| remind\_at | date    | Datum (vor dem due\_date), wann der Zugewiesene erinnert werden soll (in Form einer E-Mail) |
| done       | boolean | Ist die Aufgabe erledigt?                                                                   |

#### Falls Task ein Termin ist:

| Attribut   | Typ     | Beschreibung                                                                                                                                                                |
| ---------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| starts\_at | date    | Beginn des Termins                                                                                                                                                          |
| ends\_at   | date    | Ende des Termins                                                                                                                                                            |
| private    | boolean | Soll der Termin nur für die Teilnehmer sichtbar sein?                                                                                                                       |
| all\_day   | boolean | Ganztägiger Termin?                                                                                                                                                         |
| location   | string  | Ort des Termins                                                                                                                                                             |
| recurring  | boolean | Wiederkehrender Termin?                                                                                                                                                     |
| rrule      | string  | bei wiederkehrenden Terminen der String, welcher die Regeln festlegt, in welchem Interval der Termin stattfindet. Mehr Infos [hier](https://jakubroztocil.github.io/rrule/) |

#### Falls Task eine Anfrage ist:

| Attribut           | Typ     | Beschreibung          |
| ------------------ | ------- | --------------------- |
| client\_source\_id | integer | ID der Anfrage-Quelle |

#### Falls Task eine Absage ist:

| Attribut                | Typ     | Beschreibung         |
| ----------------------- | ------- | -------------------- |
| reservation\_reason\_id | integer | ID des Absagegrundes |

## Aktivitätstypen lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/activity_types`

Aktivitätstypen sind wie Kategorien zu verstehen. Eine Aktivität kann zu einer oder gar keiner Kategorie gehören.

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 35,
            "name": "Anfrage",
            "category": "message"
        },
        {
            "id": 38,
            "name": "Angebot",
            "category": "message"
        },
        {
            "id": 102,
            "name": "Notartermin",
            "category": "event"
        },
        {
            "id": 386,
            "name": "Marketing: Mailing",
            "category": "note"
        },
        {
            "id": 73,
            "name": "Anruf",
            "category": "reminder"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Absagegründe lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/reservation_reasons`

{% tabs %}
{% tab title="200: OK " %}

```json
[
  {
    "id": 1,
    "name": "Finanzierung"
  },
  {
    "id": 2,
    "name": "Ausstattung"
  },
  {
    "id": 3,
    "name": "Preis"
  },
  {
    "id": 4,
    "name": "Lage"
  },
  {
    "id": 5,
    "name": "Größe"
  }
]
```

{% endtab %}
{% endtabs %}


# Aufgaben

## Aufgabe lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/tasks/:id`

#### Request Parameter

| Name    | Type   | Description                                                              |
| ------- | ------ | ------------------------------------------------------------------------ |
| include | string | <p>Standardwert ist:<br><code>clients,units,projects,viewings</code></p> |

{% tabs %}
{% tab title="200" %}

```
{
    "id": 123,
    "title": "Titel"
    ...
}
```

{% endtab %}
{% endtabs %}

## Aufgabe anlegen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/tasks`

Beim Anlegen einer Aufgabe muss der Parameter `is_reminder` auf `true` gesetzt werden. Außerdem muss mindestens `note_type_id` oder `title` ausgefüllt worden sein, sonst kann die Aufgabe nicht angelegt werden. Alle Parameter zur Aufgabe müssen sich in dem Objekt `task` befinden.

#### Request Body

| Name                   | Type    | Description                                                                                                                                                                               |
| ---------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| task\_\_note\_type\_id | integer | ID des Aufgabentypes der Aufgabe                                                                                                                                                          |
| task\_\_broker\_id     | integer | ID des Nutzers, dem die Aufgabe zugewiesen werden soll                                                                                                                                    |
| task\_\_is\_reminder   | boolean | muss auf `true` gesetzt werden, damit die Aktivität als Aufgabe erkannt wird und nicht als einfache Notiz. Wenn `due_date` gesetzt ist, muss dieses Feld nicht zusätzlich gesetzt werden. |
| task\_\_project\_ids   | array   | Eine Liste von Projekt-IDs, die mit der Aufgabe verknüpft werden sollen                                                                                                                   |
| task\_\_property\_ids  | array   | Eine Liste von Objekt-IDs, die mit der Aufgabe verknüpft werden sollen                                                                                                                    |
| task\_\_client\_ids    | array   | Eine Liste von Kontakt-IDs, die mit der Aufgabe verknüpft werden sollen. In der Regel will man nur einen Kontakt mit der Aufgabe verknüpfen.                                              |
| task\_\_due\_date      | string  | Datum+Uhrzeit, wann die Fälligkeit für die Aufgabe ist                                                                                                                                    |
| task\_\_body           | string  | Weitere Beschreibung zur Aufgabe                                                                                                                                                          |
| task\_\_title          | string  | Titel der Aufgabe                                                                                                                                                                         |
| task                   | object  | Alle Felder zur Aufgabe müssen in einem Task-Objekt umschlossen werden                                                                                                                    |

{% tabs %}
{% tab title="201 Aufgabe wurde erfolgreich angelegt" %}

```javascript
{
    "id": 123,
    "activity_id": 456
}
```

{% endtab %}
{% endtabs %}

#### Beispiel Anfrage:

```javascript
{
    "task": {
        "title": "Kontakt zurückanrufen",
        "note_type_id": 123,
        "broker_id": 2,
        "client_ids": [321]
    }
}
```

## Aufgabe bearbeiten

<mark style="color:green;">`PUT`</mark> `https://api.propstack.de/v1/tasks/:id`

#### Beispiel Anfrage:

```javascript
{
    "task": {
        "title": "Titel",
        "broker_id": 3,
        "client_ids": [322]
    }
}
```

### Aufgabe Löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/tasks/:id`

{% tabs %}
{% tab title="200" %}

```json
{
    "ok": true
}
```

{% endtab %}
{% endtabs %}


# Custom Felder

## Custom Felder lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/custom_field_groups`

Custom Felder gehören immer einer Gruppe und zu einer Entität an.

#### Query Parameters

| Name   | Type   | Description                    |
| ------ | ------ | ------------------------------ |
| entity | string | Siehe unten für mögliche Werte |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 1,
            "name": "Marketing",
            "entity": "for_clients",
            "custom_fields": [
                {
                    "id": 2,
                    "name": "marketing_project",
                    "pretty_name": "Marketing-Projekt",
                    "field_type": "String",
                    "position": 1,
                    "custom_options": []
                },
                {
                    "id": 1,
                    "name": "marketing_channel",
                    "pretty_name": "Marketing-Kanal",
                    "field_type": "Dropdown",
                    "position": 2,
                    "custom_options": [
                        {
                            "id": 1,
                            "name": "Lead"
                        },
                        {
                            "id": 2,
                            "name": "Subscriber"
                        }
                    ]
                },
            ]
        }
    ]
}
```

{% endtab %}
{% endtabs %}

Mögliche Entitäten (`entity`):

1. `for_clients`
2. `for_properties`
3. `for_projects`
4. `for_brokers`
5. `for_tasks`
6. `for_deals`

### Filtern von Objekten und Kontakten nach Custom Feld

Um nach Custom Feldern in Ihren Requests zu filtern, verwenden Sie den Schlüssel des jeweiligen Custom Felds, indem Sie ihn mit "cf\_" voranstellen. Zum Beispiel: Wenn Sie ein Custom Feld mit dem Schlüssel "marketing\_channel" haben, nutzen Sie "cf\_marketing\_channel=Lead", um Ergebnisse basierend auf dem Wert "Lead" für dieses Feld zu filtern.


# Deal-Pipelines

Ein Unternehmen kann mehrere Pipelines machen um verschiedene Prozesse abzubilden, z.B. für den Verkauf, für die Akquise oder für die Vermietung einer Immobilie.

## Alle Pipelines lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/deal_pipelines`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 1,
            "name": "Sales-Pipeline",
            "broker_ids": [
                101,
                102,
                103
            ],
            "deal_stages": [
                {
                    "id": 1,
                    "name": "Besichtigt",
                    "position": 0,
                    "color": "#38b9d9",
                    "chance": 0.2
                },
                {
                    "id": 2,
                    "name": "Reserviert",
                    "position": 4,
                    "color": "#f55753",
                    "chance": 0.7
                },
                {
                    "id": 3,
                    "name": "Notartermin",
                    "position": 3,
                    "color": "#f8d053",
                    "chance": 0.9
                },
                {
                    "id": 4,
                    "name": "Gekauft",
                    "position": 5,
                    "color": "#10cfbd",
                    "chance": 1
                }
            ]
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Pipeline lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/deal_pipelines/:id`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "id": 1,
    "name": "Sales-Pipeline",
    "broker_ids": [
        51,
        45,
        48
    ],
    "deal_stages": [
        {
            "id": 71,
            "name": "Besichtigt",
            "position": 0,
            "color": "#38b9d9",
            "chance": 0.2
        },
        {
            "id": 34,
            "name": "Reserviert",
            "position": 4,
            "color": "#f55753",
            "chance": 0.7
        },
        {
            "id": 33,
            "name": "Notartermin",
            "position": 3,
            "color": "#f8d053",
            "chance": 0.9
        },
        {
            "id": 35,
            "name": "Gekauft",
            "position": 5,
            "color": "#10cfbd",
            "chance": 1
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# Deals

Ein Deal ist eine Beziehung zwischen einem Interessenten und einem Objekt und beschreibt in welcher Phase sich der Interessent im Verkaufsprozess befindet.

| Attribut           | Typ     | Beschreibung                                                                                          |
| ------------------ | ------- | ----------------------------------------------------------------------------------------------------- |
| broker\_id         | integer | Besitzer des Deals                                                                                    |
| client\_id         | integer | ID zum Interessenten (Kontakt)                                                                        |
| property\_id       | integer | ID zum Objekt                                                                                         |
| project\_id        | integer | ID zum Projekt (muss nicht selber gesetzt werden, wird über das Objekt automatisch gesetzt)           |
| deal\_stage\_id    | integer | ID zur Deal-Phase                                                                                     |
| deal\_pipeline\_id | integer | ID zur Deal-Pipeline (muss nicht selber gesetzt werden, wird über die Deal-Phase automatisch gesetzt) |
| date               | date    | Datum des Deals                                                                                       |
| price              | float   | (voraussichtlicher) realisierter Preis des Deals                                                      |
| note               | string  | Interne Notiz zum Deal                                                                                |

## Deals lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/client_properties`

#### Query Parameters

| Name                       | Type    | Description                                                                                                                                  |
| -------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| include                    | string  | Liste von möglichen Assoziationen, die in der Antwort mit übergeben werden (kommagetrennt). Kann den Wert `client` und/oder `property` haben |
| sort\_by                   | string  | <p>Sortierkriterium<br>Standard: created\_at</p>                                                                                             |
| order                      | string  | Aufsteigend oder absteigend sortieren. Entweder `asc` oder `desc`                                                                            |
| reservation\_reason\_ids   | array   | Array aus Absagegründen (dessen IDs), um nur verlorene Deals mit bestimmten Absagegründen aufzurufen                                         |
| category                   | string  | Art des Deals. Kann eines von `qualified`, `unqualified`, `lost` sein                                                                        |
| deal\_stage\_ids           | array   | Array aus IDs, um nur Deals in bestimmten Phasen aufzurufen.                                                                                 |
| deal\_pipeline\_id         | integer | Nur Deals aus einer bestimmten Pipeline aufrufen                                                                                             |
| project\_id                | integer | ID eines Projektes, um nur Deals mit Objekten, die zu dem Projekt gehören, aufzurufen                                                        |
| broker\_id                 | integer | ID eines Nutzers, um nur Deals, wo er der Besitzer ist aufzurufen                                                                            |
| client\_id                 | integer | ID des Interessenten (Kontakt), um nur die Deals eines bestimmten Kontaktes aufzurufen                                                       |
| property\_id               | integer | ID des Objektes, um nur dessen Interessenten aufzurufen                                                                                      |
| client\_source\_id         | integer | ID der Anfrage-Quelle                                                                                                                        |
| team\_id                   | integer | ID der Abteilung                                                                                                                             |
| property\_broker\_ids      | array   | IDs der Objektbetreuer                                                                                                                       |
| client\_broker\_ids        | array   | IDs der Kontakt Betreuer                                                                                                                     |
| feeling\_from              | integer | Mindestwert des Bauchgefühls                                                                                                                 |
| feeling\_to                | integer | Höchstwert des Bauchgefühls                                                                                                                  |
| created\_at\_from          | string  | Format: 2022-12-07T10:00:00+01:00                                                                                                            |
| created\_at\_to            | string  | Format: 2022-12-07T23:59:59+01:00                                                                                                            |
| start\_date\_from          | string  | Format: 2022-12-07T10:00:00+01:00                                                                                                            |
| start\_date\_to            | string  | Format: 2022-12-07T10:00:00+01:00                                                                                                            |
| show\_archived\_clients    | boolean | Archivierte Kontakte anzeigen                                                                                                                |
| hide\_archived\_properties | boolean | Archivierte Eigenschaften ausblenden                                                                                                         |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 8145,
            "sold_price": null,
            "note": "",
            "created_at": "2019-02-04T10:37:46.060+01:00",
            "start_date": "2019-02-04T10:37:36.360+01:00",
            "broker_id": 1,
            "client_id": 29934,
            "property_id": 9884,
            "project_id": null,
            "deal_pipeline_id": 2,
            "deal_stage_id": 3,
            "reservation_reason_id": null
        }
    ],
    "meta": {
        "total_count": 120
    }
}
```

{% endtab %}
{% endtabs %}

## Deal anlegen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/client_properties`

#### Path Parameters

| Name             | Type   | Description                                                                           |
| ---------------- | ------ | ------------------------------------------------------------------------------------- |
| client\_property | object | das Deal-Objekt mit 3 Pflicht-Feldern: `client_id`, `property_id` und `deal_stage_id` |

#### Anfrageformat

```json
{
   "client_property": {
       "property_id": 123,
       "client_id": 456,
       "note" : "some note"
   }
}
```

## Deal aktualisieren

<mark style="color:blue;">`PUT`</mark> `https://api.propstack.de/v1/client_properties/:id`

#### Anfrageformat

```json
{
   "client_property": {
       "property_id": 123,
       "client_id": 456,
       "note" : "updated note"
   }
}
```

## Absage erfassen

<mark style="color:blue;">`POST`</mark> `https://api.propstack.de/v1/tasks`

#### Anfrageformat

<pre class="language-json"><code class="lang-json">{
  "task": {
    "title": "Absage",
    "<a data-footnote-ref href="#user-content-fn-1">reservation_reason_id</a>": 1,
    "client_ids": [123],
    "property_ids": [456],
    "body": "Das ist ein Test"
  }
}
</code></pre>

[^1]: Absagegrund


# Dokumente

Dokumente sind Dateien, die entweder zu einem Projekt, einem Objekt oder einem Kontakt gehören

## Dokumente lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/documents`

Die Dokumente werden paginiert.

#### Query Parameters

| Name             | Type    | Description                                                                                                                |
| ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| order\_by        | string  | Sortierung der Ergebnismenge. Standard `position,asc`. Um nach Erstellungsdatum absteigend zu sortieren: `created_at,desc` |
| tag              | string  | ein Schlagwort, welches das Dokument haben muss                                                                            |
| is\_private      | boolean | mögliche Werte:  `true` oder `false`                                                                                       |
| client           | integer | ID des verknüpften Kontaktes                                                                                               |
| property         | integer | ID des verknüpften Objektes                                                                                                |
| project          | integer | ID des verknüpften Projektes                                                                                               |
| client\_property | integer | ID des verknüpften Deal                                                                                                    |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "documents": [
        {
            "id": 11,
            "token": "1hw4mBZRnFrnitGUbj5jL4Rt",
            "title": "grundriss.pdf",
            "name": "grundriss.pdf",
            "url": "...",
            "position": 1,
            "broker_id": 1,
            "is_private": true,
            "on_landing_page": true,
            "is_exposee": false,
            "second_document": null,
            "is_floorplan": true,
            "tags": [],
            "created_at": "2019-11-12T14:56:25.140+01:00",
            "updated_at": "2019-11-12T15:16:28.348+01:00"
        }
    ],
    "meta": {
        "total_count": 1
    }
}
```

{% endtab %}
{% endtabs %}

## Dokument erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/documents`

Alle Parameter in einem `document` Objekt umschlossen werden.\
Ein Dokument sollte mit entweder einem Objekt, einem Projekt, oder einem Kontakt verknüpft werden, und keine Kombination der 3.

#### Request Body

| Name              | Type    | Description                                                                                                            |
| ----------------- | ------- | ---------------------------------------------------------------------------------------------------------------------- |
| tags              | array   | Nicht bereits vorhandene Tags werden automatisch neu angelegt                                                          |
| on\_landing\_page | boolean | Soll das Dokument als Landing Pages angezeigt werden? Nur bei Projekten/Objekten sinnvoll                              |
| is\_floorplan     | boolean | Handelt es sich bei dem Dokument um ein Grundriss?                                                                     |
| is\_exposee       | boolean | Soll das Dokument als das PDF-Exposé benutzt werden? Nur sinnvoll, wenn Dokument mit Projekt oder Objekt verknüpft ist |
| client\_id        | integer | ID des Kontaktes, womit es verknüpft werden soll                                                                       |
| project\_id       | integer | ID des Projektes, womit es verknüpft werden soll                                                                       |
| property\_id      | integer | ID des Objektes, womit es verknüpft werden soll                                                                        |
| doc               | string  | die eigentliche Datei, Base64 kodiert                                                                                  |
| title             | string  | eigener Name für das Dokument, falls nicht der Dateiname benutzt werden soll                                           |
| is\_private       | boolean |                                                                                                                        |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

### Body einer Beispiel-Anfrage

Es wird ein Dokument für das Objekt mit der ID 123 angelegt, was nur ein oranger Pixel ist:

```javascript
{
	"document": {
		"property_id": 123,
		"title": "orange-pixel.png",
		"doc": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8v5vhPwAHNgK7sbW2nQAAAABJRU5ErkJggg=="
	}
}
```

## Dokument lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/documents/:id`

{% tabs %}
{% tab title="200 " %}

```javascript
{
  "id": 11,
  "token": "1hw4mBZRnFrnitGUbj5jL4Rt",
  "title": "grundriss.pdf",
  "name": "grundriss.pdf",
  "url": "...",
  "position": 1,
  "broker_id": 1,
  "is_private": true,
  "on_landing_page": true,
  "is_exposee": false,
  "second_document": null,
  "is_floorplan": true,
  "tags": [],
  "created_at": "2019-11-12T14:56:25.140+01:00",
  "updated_at": "2019-11-12T15:16:28.348+01:00"
}
```

{% endtab %}
{% endtabs %}

## Dokument aktualisieren

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/documents/:id`

Die gleichen Parameter im POST können auch im PUT verändert werden

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "id": 12,
    "token": "zxydpZE62eZ3GcEQSCN84bwT",
    "title": "Exposé.pdf",
    "name": "Exposé.pdf",
    "url": "...",
    "position": 1,
    "broker_id": 1,
    "is_private": true,
    "on_landing_page": true,
    "is_exposee": false,
    "second_document": null,
    "is_floorplan": false,
    "tags": []
}
```

{% endtab %}
{% endtabs %}

## Dokument löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/documents/:id`

{% tabs %}
{% tab title="200: OK " %}

```javascript
```

{% endtab %}
{% endtabs %}

## Tags auslesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/documents/tags`

Alle möglichen Tags auslesen, die ein Dokument haben kann.

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        "Energieausweis"
    ],
    "meta": {
        "total_count": 1
    }
}
```

{% endtab %}
{% endtabs %}


# E-Mails

## Das E-Mail Objekt

| Attribut                 | Typ        | Beschreibung                                                 |
| ------------------------ | ---------- | ------------------------------------------------------------ |
| id                       | integer    | Unique ID der E-Mail                                         |
| subject                  | string     | Betreff der E-Mails                                          |
| body                     | string     | Inhalt der E-Mail als HTML                                   |
| broker\_id               | integer    | Nutzer-ID, der die E-Mail erhalten oder verschickt hat       |
| from                     | string\[]  | Absender der E-Mail                                          |
| to                       | string\[]  | Empfänger der E-Mail                                         |
| cc                       | string\[]  | Empfänger im Kopie                                           |
| bcc                      | string\[]  | Empfänger in Blindkopie                                      |
| client\_ids              | integer\[] | Ein Array von Kontakt-IDs, die mit der E-Mail verknüpft sind |
| property\_ids            | integer\[] | Ein Array von Objekt-IDs, die mit der E-Mail verknüpft sind  |
| project\_ids             | integer\[] | Ein Array von Projekt-IDs, die mit der E-Mail verknüpft sind |
| message\_attachment\_ids | integer\[] | IDs der Anhänge der E-Mail als Array                         |
| client\_source\_id       | integer    | Falls E-Mail eine Anfrage ist, die ID der Quelle der E-Mail  |
| message\_category\_id    | integer    | die ID des E-Mail-Types der E-Mail                           |

### Assoziationen

Eine E-Mail hat mehrere Assoziationen, die beim Lesen der E-Mail mitgezogen werden können. Unter anderem die Infos zum Nutzer, zu den verknüpften Kontakten, Objekten, Projekten und zu den Anhängen der E-Mail.

1. broker
2. attachments
3. clients
4. units (Property)
5. projects
6. client\_source
7. message\_category

### Anhänge

| Attribut | Typ     | Beschreibung                                   |
| -------- | ------- | ---------------------------------------------- |
| id       | integer | Unique ID des Anhanges                         |
| name     | string  | Name des Anhanges                              |
| url      | string  | URL zum Anhang (nur für wenige Minuten gültig) |

## E-Mail senden

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/messages`

#### Request Body

| Name        | Type    | Description                                                                     |
| ----------- | ------- | ------------------------------------------------------------------------------- |
| broker\_id  | integer | Absender der E-Mail. ID des Nutzers, über den die E-Mail versendet werden soll. |
| snippet\_id | integer | ID des Textbausteines, welcher versendet werden soll                            |
| cc          | array   | Empfänder der E-Mail in CC. Eine Liste an E-Mail-Adressen                       |
| to          | array   | Empfänger der E-Mail. Eine Liste an E-Mail-Adresen                              |

#### Beispiel Anfrage:

```json
{
    "message": {
        "broker_id": 12,
        "to": [
            "kontakt@mail.com"
        ],
        "snippet_id": 1,
        "property_ids": [ 
            15 
        ]
    }
}
```

{% tabs %}
{% tab title="200 " %}

```json
{
  "ok": true,
  "id": 48192929
}
```

{% endtab %}
{% endtabs %}

## E-Mail aktualisieren

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/messages/:id`

#### Request Body

| Name                                      | Type    | Description                                                  |
| ----------------------------------------- | ------- | ------------------------------------------------------------ |
| message<mark style="color:red;">\*</mark> | object  | ein `message` Objekt,  siehe unten für alle möglichen Felder |
| read                                      | boolean | Status "gelesen"                                             |
| archived                                  | boolean | Status "archiviert"                                          |
| message\_category\_id                     | integer | ID der E-Mail-Kategorie                                      |
| client\_ids                               | array   | verknüpfte Kontakte                                          |
| property\_ids                             | array   | verknüpfte Objekte                                           |
| project\_ids                              | array   | verknüpfte Projekte                                          |

#### Beispiel Anfrage:

```json
{
    "message": {
        "message_category_id": 1
    }
}
```

{% tabs %}
{% tab title="200 E-Mail-Objekt" %}

```javascript
{
  "id": 1,
  "subject": "Propstack",
  "body": "Hallo",
  ...
}
```

{% endtab %}
{% endtabs %}


# Geolagen

Bezirke beschreiben ein Gebiet und sind essentiell für das Matching zwischen Objekten und Suchprofilen sind.

## Geolagen lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/locations`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 214,
            "name": "Mitte",
            "sub_locations": [
                {
                    "id": 229,
                    "name": "Wedding",
                    "sub_locations": [
                        {
                            "id": 408,
                            "name": "Leopoldplatz"
                        }
                    ]
                }
            ]
        },
        {
            "id": 463,
            "name": "Reinickendorf",
            "sub_locations": [
                {
                    "id": 464,
                    "name": "Tegel",
                    "sub_locations": []
                },
                {
                    "id": 465,
                    "name": "Wittenau",
                    "sub_locations": []
                }
            ]
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# Kontakte

## Das Kontakt Objekt

| Attribut                                 | Typ       | Beschreibung                                                                         |
| ---------------------------------------- | --------- | ------------------------------------------------------------------------------------ |
| parent\_id                               | integer   | ID zum Hauptkontakt (anhand dieses Attributes erkennt man einen Unterkontakt)        |
| is\_company                              | boolean   | Ist der Kontakt eine Firma?                                                          |
| item\_id                                 | integer   | autom. hochgezählte Kundennummer                                                     |
| salutation                               | string    | Anrede. Eines von `mr` oder `ms`                                                     |
| academic\_title                          | title     | Titel, z.B. "Dr."                                                                    |
| first\_name                              | string    | Vorname                                                                              |
| last\_name                               | string    | Nachname                                                                             |
| email                                    | string    | Primär-Email                                                                         |
| home\_cell                               | string    | Handynummer                                                                          |
| home\_phone                              | string    | Festnetznummer                                                                       |
| office\_phone                            | string    | Geschäftliche Telefonnummer                                                          |
| office\_cell                             | string    | Geschäftliche Handynummer                                                            |
| dob                                      | date      | Geburtsdatum                                                                         |
| birth\_name                              | string    | Geburtsname                                                                          |
| birth\_place                             | string    | Geburtsort                                                                           |
| birth\_country                           | string    | Geburtsland                                                                          |
| identity\_number                         | string    |                                                                                      |
| issuing\_authority                       | string    |                                                                                      |
| tax\_identification\_number              | string    |                                                                                      |
| rating                                   | integer   | Bewertung von 0-3                                                                    |
| description                              | string    | Notizfeld für Bemerkungen zum Kontakt                                                |
| company                                  | string    | Unternehmen für welches der Kontakt arbeitet                                         |
| position                                 | string    | Position im Unternehmen                                                              |
| emails                                   | string\[] | Alle E-Mail-Adressen des Kontaktes                                                   |
| full\_salutation                         | string    | E-Mail Anrede, z.B. "Sehr geehrter Herr Doe"                                         |
| language                                 | string    | Sprache des Benutzers. Mögliche Werte: `de`, `en`, `es`                              |
| income                                   | string    | Einkommen                                                                            |
| newsletter                               | boolean   | Möchte Newsletter haben?                                                             |
| accept\_contact                          | boolean   | Hat Kontakterlaubnis bestätigt?                                                      |
| warning\_notice                          | string    | Warnhinweis, der im Kontakt auffällig angezeigt wird                                 |
| client\_source\_id                       | integer   | ID der Quelle des Kontaktes                                                          |
| client\_status\_id                       | integer   | ID des Statuses des Kontaktes                                                        |
| archived                                 | boolean   | Kontakt archiviert?                                                                  |
| last\_contact\_at                        | date      | Letzter Kontakt mit ihm                                                              |
| created\_at                              | date      | Erstellungsdatum                                                                     |
| updated\_at                              | date      | Zuletzt bearbeitet                                                                   |
| creator\_id                              | integer   | der Benutzer, der den Kontakt angelegt hat                                           |
| updater\_id                              | integer   | der Benutzer, der den Kontakt zuletzt bearbeitet hat                                 |
| gdpr\_status                             | integer   | DSGVO-Status. Eines von 0, 1, 2, 3 (Keine Angabe, Ignoriert, Zugestimmt, Widerrufen) |
| keep\_data\_till                         | date      | Speichern-bis Datum                                                                  |
| client\_reason\_id                       | id        | ID des Speichern-Grund, siehe Speicherungsgründe unten                               |
| cp\_delete\_request\_date                | date      | Datum der Löschungsbeantragung vom Kontakt                                           |
| custom\_fields / partial\_custom\_fields | object    | Custom Felder. Nutze `partial_custom_fields` zum Bearbeiten eines Kontaktes          |

### Assoziationen

1. broker
2. second\_broker
3. client\_source
4. client\_status
5. documents
6. owned\_properties
7. children

## Kontakte lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/contacts`

#### Query Parameters

| Name                 | Type    | Description                                                                                                                                                                            |
| -------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| expand               | boolean | um das ausführliche JSON (einschließlich custom Felder) zu erhalten                                                                                                                    |
| with\_meta           | boolean | Mit zusätzlichen Metadaten                                                                                                                                                             |
| sort\_by             | string  | **Mögliche Werte:** `last_contact_at`, `created_at`, `updated_at`, `first_name`, `last_name`                                                                                           |
| order                | string  | Aufsteigend oder absteigend sortieren. Entweder `asc` oder `desc`                                                                                                                      |
| project\_ids         | array   | Kontakte, die mit einem bestimmten Projekt oder eines von mehreren verknüpft ist                                                                                                       |
| phone\_number        | string  | Exakte Telefonnummer, die der Kontakt haben muss (Leerzeichen, Bindestriche sind egal)                                                                                                 |
| q                    | string  | Suchparameter, der in Vorname, Nachname, Emails, Anschrift und Telefonnummern sucht                                                                                                    |
| archived             | string  | wenn `-1`, dann werden alle Kontakte gezogen, bei `1`, nur die archivierten. Ansonsten standardmäßig erhält man nur die Nicht-Archivierten                                             |
| email                | string  | E-Mail des Kontakts                                                                                                                                                                    |
| include\_children    | boolean | Unterkontakte einbeziehen                                                                                                                                                              |
| parent\_id           | integer | ID des Oberkontakts                                                                                                                                                                    |
| broker\_id           | integer | Kontakt-Betreuer-ID                                                                                                                                                                    |
| gdpr\_status         | integer | <p>DSGVO-Status<br><strong>Mögliche Werte:</strong> <br><code>0</code> (Keine Angabe)<br><code>1</code> (Ignorieren)<br><code>2</code> (Zugestimmt)<br><code>3</code> (Widerrufen)</p> |
| group                | array   | IDs der Merkmale                                                                                                                                                                       |
| not\_in\_group       | array   | IDs der nicht enthaltenen Merkmale                                                                                                                                                     |
| status               | array   | IDs der Kontaktstatus                                                                                                                                                                  |
| sources              | array   | IDs der Kontakt-Quellen                                                                                                                                                                |
| home\_countries      | array   | Länder                                                                                                                                                                                 |
| newsletter           | boolean | Newsletter gewünscht                                                                                                                                                                   |
| accept\_contact      | boolean | Kontakterlaubnis                                                                                                                                                                       |
| language             | array   | Format: `de`, `en`, `es` ...                                                                                                                                                           |
| owner                | boolean | Eigentümer                                                                                                                                                                             |
| owned\_property\_ids | array   | IDs der Eigentumsobjekte                                                                                                                                                               |
| created\_at\_from    | string  | Format: 2022-12-07T10:00:00+01:00                                                                                                                                                      |
| created\_at\_to      | string  | Format: 2022-12-07T23:59:59+01:00                                                                                                                                                      |
| updated\_at\_from    | string  | Format: 2022-12-07T10:00:00+01:00                                                                                                                                                      |
| updated\_at\_to      | string  | Format: 2022-12-07T23:59:59+01:00                                                                                                                                                      |
|                      |         |                                                                                                                                                                                        |

{% tabs %}
{% tab title="200 " %}

```json
[
    {
        "id": 30267,
        "item_id": 1314,
        "salutation": "mr",
        "academic_title": "",
        "name": "John Doe",
        "is_company": false,
        "company": "John Doe AG",
        "email": "john@doe.de",
        "phone": null,
        "last_contact_at": "2018-12-01T16:37:56.250+01:00",
        "created_at": "2018-11-27T19:58:35.146+01:00",
        "updated_at": "2019-01-02T11:10:36.709+01:00",
        "client_status_id": 45,
        "client_source_id": null,
        "locked": false,
        "broker_ids": [],
        "children_size": 0,
        "groups": []
    }
]
```

{% endtab %}
{% endtabs %}

####

#### Beispiele für Anfragen nach Telefonnummer

Ist bei einem Kontakt die Telefonnummer `0157 123 456 78` hinterlegt, kann man mit folgenden Anfragen finden:

`https://api.propstack.de/v1/contacts?phone_number=015712345678`\
`oder:`\
`https://api.propstack.de/v1/contacts?phone_number=0157-123-456-78`

## Kontakt erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/contacts`

Erstellt ein Kontakt im CRM, bzw. aktualisiert einen vorhandenen Kontakt, wenn dieser anhand der Emailadresse (`email`M-ID" (`old_crm_id`) gefunden wird.

#### Request Body

| Name   | Type   | Description                                            |
| ------ | ------ | ------------------------------------------------------ |
| client | object | siehe Kontakt-Objekt oben, welche Felder es haben kann |

#### Anfrageformat

```json
{
  "client": {
    "salutation": "mr",
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@doe.com"
  }
}
```

### Kontakt erstellen mit Custom Feldern

```json
{
  "client": {
    "first_name": "John",
    "email": "john@doe.com",
    "partial_custom_fields": {
      "my_custom_field": 123,
      "important_notes": "Important info"
    }
  }
}
```

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "ok": true,
    "id": 123
}
```

{% endtab %}
{% endtabs %}

## Kontakt lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/contacts/:id`

#### Query Parameters

| Name    | Type   | Description                                                                                                                                |
| ------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| include | string | Beziehungen, die in der Antwort mit übergeben werden. Kann die Werte `children`, `documents`, `relationships` und `owned_properties` haben |

{% tabs %}
{% tab title="200 " %}

```json
{
    "id": 1,
    "item_id": 1,
    "salutation": "ms",
    "academic_title": null,
    "name": "Atze Tango",
    "is_company": false,
    "company": "Propstack",
    "email": "atze.tango@example.com",
    "phone": null,
    "last_contact_at": "2019-08-14T14:36:57.000+02:00",
    "created_at": "2019-06-04T17:08:59.386+02:00",
    "updated_at": "2019-08-22T11:00:42.458+02:00",
    "home_phone": null,
    "home_cell": null,
    "office_phone": null,
    "office_cell": null,
    "client_status_id": null,
    "client_source_id": null,
    "locked": false,
    "broker_ids": null,
    "status": {},
    "children_size": 0,
    "old_crm_id": null,
    "broker_id": null,
    "first_name": "Atze",
    "last_name": "Tango",
    "home_address": null,
    "office_address": null,
    "dob": null,
    "birth_name": null,
    "birth_place": null,
    "birth_country": null,
    "identity_number": null,
    "issuing_authority": null,
    "nationality": null,
    "rating": 0,
    "description": null,
    "position": "Geschäftsführer",
    "full_salutation": "Sehr geehrte Frau Tango,",
    "emails": [
        "atze.tango@example.com"
    ],
    "home_street": null,
    "home_house_number": null,
    "home_zip_code": null,
    "home_city": null,
    "home_country": null,
    "office_street": null,
    "office_house_number": null,
    "office_zip_code": null,
    "office_city": null,
    "office_country": null,
    "tax_identification_number": null,
    "token": "gioWo5KczySDb1gRfT7bik52",
    "deleted_at": null,
    "parent_id": null,
    "language": null,
    "custom_fields": {},
    "income": null,
    "handover_date": null,
    "rent_date": null,
    "mvsigned": null,
    "hvsigned": null,
    "followup_date": null,
    "newsletter": null,
    "newsletter_unsubscribed": false,
    "message_salutation": null,
    "accept_contact": false,
    "warning_notice": null,
    "pass_type": null,
    "conspicuity": null,
    "legal_form": null,
    "register_number": null,
    "archived": false,
    "creator_id": null,
    "updater_id": null,
    "cp_delete_request_date": null,
    "gdpr_status": 0,
    "keep_data_till": null,
    "client_reason_id": null,
    "last_contact_at_formatted": "14.08.2019 14:36",
    "created_at_formatted": "04.06.2019 17:08",
    "updated_at_formatted": "22.08.2019 11:00",
    "broker": null,
    "second_broker": null,
    "groups": [
        {
            "id": 6,
            "name": "IT-Branche",
            "super_group_id": null
        }
    ],
    "documents": [],
    "owned_properties": [],
    "children": [],
    "client_source": null,
    "client_status": null
}
```

{% endtab %}
{% endtabs %}

#### Anmerkungen:

`owned_properties` listet die Objekte auf, wo der Kontakt als Eigentümer eingetragen ist.

## Kontakt aktualisieren

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/contacts/:id`

Einen vorhandenen Kontakt aktualisieren.&#x20;

#### Request Body

| Name   | Type   | Description                                               |
| ------ | ------ | --------------------------------------------------------- |
| client | string | ein `client` Objekt, siehe oben für alle möglichen Felder |

#### Anfrageformat

```json
{
  "client": {
    "first_name": "Atze Tango",
  }
}
```

{% tabs %}
{% tab title="200 Kontakt-Objekt" %}

```javascript
{
    "id": 1,
    "item_id": 1,
    "salutation": "mr",
    "academic_title": null,
    "name": "Atze Tango",
    "group_ids": [1,2,3], // will rewrite all previous group IDs,
    "add_group_ids": [5], // add this group IDs
    "sub_group_ids": [1]. // remove these group IDs
    ...
}
```

{% endtab %}
{% endtabs %}

Der Parameter `id` ist Propstacks interne ID (z.B. `2049`). Wenn man aber z.B. einen anderen Identifier hat, z.B. den Token des Kontaktes, welcher ein langer String ist, kann man diesen auch als id übergeben, muss aber dann noch einen weiteren Parameter `identifier` hinzufügen, welcher den Wert `token` hat:

```scheme
https://api.propstack.de/v1/contacts/gioWo5KczySDb1gRfT7bik52?identifier=token
```

## Kontakt löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/contacts/:id`

Einen vorhandenen Kontakt anhand seiner ID löschen. Der Kontakt landet dann in einem Papierkorb und wird nach 30 Tagen dann für immer gelöscht, sofern er in der zeit nicht wiederhergestellt wurde.

#### Path Parameters

| Name | Type   | Description                                    |
| ---- | ------ | ---------------------------------------------- |
| id   | string | ID des Kontaktes, welcher gelöscht werden soll |

{% tabs %}
{% tab title="200 Es wird die ID des gelöschten Kontaktes zurückgegeben" %}

```json
{
  "ok": true,
  "id": 1
}
```

{% endtab %}
{% endtabs %}

## Kontakt-Quellen lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/contact_sources`

{% tabs %}
{% tab title="200 " %}

```json
[
    {
        "id": 26,
        "name": "Immobilienscout 24"
    }
]
```

{% endtab %}
{% endtabs %}


# Favoriten

Objekte von Kontakten favorisieren/liken lassen

## Favorit togglen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/contacts/:client_id/favorites`

Mit diesem Endpoint wird ein Favorit neu erstellt oder gelöscht, wenn es einen bereits gab.

#### Path Parameters

| Name       | Type    | Description                               |
| ---------- | ------- | ----------------------------------------- |
| client\_id | integer | Die ID des Kontaktes, welcher favorisiert |

#### Query Parameters

| Name         | Type    | Description                                   |
| ------------ | ------- | --------------------------------------------- |
| property\_id | integer | Die ID des Objektes, welches favorisiert wird |

{% tabs %}
{% tab title="200 Cake successfully retrieved." %}

```
{    "name": "Cake's name",    "recipe": "Cake's recipe name",    "cake": "Binary cake"}
```

{% endtab %}

{% tab title="404 Could not find a cake matching this query." %}

```
{    "message": "Ain't no cake like that."}
```

{% endtab %}
{% endtabs %}


# Beziehungen

Beziehungen zwischen Kontakten und Objekten verwalten

## Eigentümer

## Eigentümer erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/ownerships`

#### Request Body

| Name                                           | Type    | Description                                      |
| ---------------------------------------------- | ------- | ------------------------------------------------ |
| client\_id<mark style="color:red;">\*</mark>   | integer | ID des Kontaktes, womit es verknüpft werden soll |
| property\_id<mark style="color:red;">\*</mark> | integer | ID des Objektes, womit es verknüpft werden soll  |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "okay": true
}
```

{% endtab %}
{% endtabs %}

## Eigentümer löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/ownerships`

#### Request Body

| Name                                           | Type    | Description                                      |
| ---------------------------------------------- | ------- | ------------------------------------------------ |
| client\_id<mark style="color:red;">\*</mark>   | integer | ID des Kontaktes, womit es verknüpft werden soll |
| property\_id<mark style="color:red;">\*</mark> | integer | ID des Objektes, womit es verknüpft werden soll  |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "okay": true
}
```

{% endtab %}
{% endtabs %}

## Partner

## Partner erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/partnerships`

#### Request Body

| Name                                           | Type    | Description                                      |
| ---------------------------------------------- | ------- | ------------------------------------------------ |
| client\_id<mark style="color:red;">\*</mark>   | integer | ID des Kontaktes, womit es verknüpft werden soll |
| property\_id<mark style="color:red;">\*</mark> | integer | ID des Objektes, womit es verknüpft werden soll  |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "okay": true
}
```

{% endtab %}
{% endtabs %}

## Partner löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/partnerships`

#### Request Body

| Name                                           | Type    | Description                                      |
| ---------------------------------------------- | ------- | ------------------------------------------------ |
| client\_id<mark style="color:red;">\*</mark>   | integer | ID des Kontaktes, womit es verknüpft werden soll |
| property\_id<mark style="color:red;">\*</mark> | integer | ID des Objektes, womit es verknüpft werden soll  |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "okay": true
}
```

{% endtab %}
{% endtabs %}


# Merkmale

Merkmale kann man als "Tags" verstehen, welche man Kontakten, Objekten oder Aktivitäten geben kann, um sie später danach filtern zu können.

## Merkmale abrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/groups`

Hier werden alle Merkmale entweder von Kontakten, Objekten oder Aktivitäten zurückgegeben. Wenn kein Wert unter `entity` angegeben wird, dann werden standardmäßig nur die Merkmale der Kontakte zurückgegeben.

#### Query Parameters

| Name         | Type    | Description                                                                              |
| ------------ | ------- | ---------------------------------------------------------------------------------------- |
| super\_group | integer | ID der Oberkategorie                                                                     |
| entity       | string  | Eines von `for_clients`, `for_properties`, oder `for_activities`. Default: `for_clients` |

{% tabs %}
{% tab title="200 " %}

```javascript
[
    {
        "id": 100,
        "name": "Eigentümer",
        "super_group_id": 99
    }
]
```

{% endtab %}
{% endtabs %}

## Merkmal erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/groups`

#### Request Body

| Name             | Type    | Description                                                                   |
| ---------------- | ------- | ----------------------------------------------------------------------------- |
| super\_group\_id | integer | ID der Oberkategorie (auch ein Merkmal)                                       |
| entity           | string  | Eines von `for_clients`, `for_properties` oder `for_activities`.              |
| name             | string  | Name des Merkmals. Es darf kein anderes Merkmal mit dem gleichen Namen geben. |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Obermerkmale lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/super_groups`

#### Query Parameters

| Name    | Type   | Description                                                 |
| ------- | ------ | ----------------------------------------------------------- |
| entity  | string | eines von `for_clients`, `for_properties`, `for_activities` |
| include | string | kann den Wert `groups` haben, um die Merkmale mitzuliefern  |

{% tabs %}
{% tab title="200 Antwort, wenn man include=groups mitgibt. Ansonsten fehlt das Attribut groups" %}

```javascript
{
    "data": [
        {
            "id": 1,
            "name": "Berufe",
            "entity": "for_clients",
            "groups": [
                {
                    "id": 1789,
                    "name": "Architekt",
                    "super_group_id": 1
                },
                {
                    "id": 1802,
                    "name": "Designeer",
                    "super_group_id": 1
                }
            ]
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# Nutzer

Nutzer sind die Mitarbeiter eines Unternehmens.

## &#x20;Nutzer abrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/brokers`

{% tabs %}
{% tab title="200 " %}

```javascript
[
  {
    "id": 123,
    "salutation": "mr",
    "academic_title": "Dr.",
    "first_name": "Max",
    "last_name": "Mustermann",
    "name": "Dr. Max Mustermann",
    "avatar":
      "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/mu9Udm/avatar/cc2cyRBi/thumb_foo.jpg",
    "avatar_url":
      "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/mu9Udm/avatar/cc2cyRBi/foo.jpg",
    "old_crm_id": null,
    "email": "max@makler.de",
    "position": "Geschäftsführer",
    "phone": "+49 123 456 78",
    "phone_system_number": "+49 123 456 78",
    "color": "#c754b4",
    "team_id": 1,
    "department_ids": [2],
    "shop": {
      "name": "Propstack GmbH",
      "color": "#54b4f5"
    },
    "abstract": "Kurzbeschreibung zum Nutzer...",
    "description": "Gesamtbeschreibung zum Nutzer..."
  }
]
```

{% endtab %}
{% endtabs %}

In der Response ist unter `avatar` das Bild in der Größe 280x280px. Unter `avatar_url` erhält man das Originalbild, so wie es in Propstack hochgeladen wurde.

In Propstack kann ein Nutzer mehreren Teams angehören. Die IDs dieser Teams findet man unter `department_ids`. Unter `team_id` ist die Abteilung zu verstehen. Leider sind die englischen Begriffe mit den deutschen Begriffen vertauscht. 😅


# Objekte

## Objekte lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/units?with_meta=1`

#### Query Parameters

| Name                  | Type    | Description                                                                                                                                                                                                 | Usage Example                |
| --------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| expand                | boolean | um das ausführliche JSON (einschließlich custom Felder) zu erhalten                                                                                                                                         | expand=1                     |
| include\_translations | string  | <p>Einschließen von Übersetzungen<br>z.B <code>en,de</code></p>                                                                                                                                             | include\_translations=en     |
| order                 | string  | Aufsteigend oder absteigend sortieren. Entweder `asc` oder `desc`                                                                                                                                           | order=asc                    |
| sort\_by              | string  | Feld wonach sortiert werden soll. Siehe unten für mögliche Optionen (Default ist `unit_id.raw`)                                                                                                             | sort\_by=construction\_year  |
| status                | string  | ID des Statuses, in welchem sich das Objekt befinden muss. Mehrere Stati übergibt man kommagetrennt                                                                                                         | status=274                   |
| group                 | integer | Merkmal-ID, die das Objekt haben muss. Kommagetrennt, wenn es eines von mehreren Merkmalen haben muss                                                                                                       | group=234                    |
| q                     | string  | Volltextsuche: Sucht in `unit_id`, `street`, `zip_code`, `city`, `Bezirk`, `exposee_id`                                                                                                                     | q=Berlin                     |
| country               | string  | 2-stelliger ISO Code des Landes, zB `DE` oder `FR`                                                                                                                                                          | country=DE                   |
| project\_id           | integer | nur zu einem bestimmten Projekt die Einheiten                                                                                                                                                               | project\_id=123              |
| marketing\_type       | string  | ob Kauf (`BUY`) oder Miete (`RENT`)                                                                                                                                                                         | marketing\_type=BUY          |
| rs\_type              | string  | siehe unten für mögliche Werte (z.B. `HOUSE`, um nur Häuser zu erhalten)                                                                                                                                    | rs\_type=HOUSE               |
| archived              | string  | wenn `-1`, dann werden alle Objekte gezogen, bei `1`, nur die archivierten. Ansonsten standardmäßig erhält man nur die **Nicht-Archivierten**                                                               | archived=-1                  |
| property\_ids         | array   | Array aus IDs, um nur die Objekte mit bestimmten Propstack-IDs aufzurufen                                                                                                                                   | property\_ids=1986,1987,1988 |
| include\_variants     | boolean | Varianten einbeziehen                                                                                                                                                                                       | include\_variants=1          |
| exact                 | boolean | Für die Abfrage benutzerdefinierter Eigenschaftsfelder vom Typ `STRING` / `TEXT`. Ermöglicht eine exakte, case-sensitive Übereinstimmung mit dem vollständigen, nicht-analysierten Feldwert, z.B. für URLs. | exact=1                      |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 5,
            "name": "001",
            "title": "Traumhafte Familienwohnung im klassischen Altbau in ruhiger Lage!",
            "unit_id": "001",
            "exposee_id": "",
            "project_id": 2,
            "street": "Gottschalkstraße",
            "house_number": "7",
            "district": null,
            "region": "Berlin",
            "zip_code": "13359",
            "city": "Berlin",
            "country": "DEU",
            "address": "Gottschalkstraße 7, 13359 Berlin, Deutschland",
            "short_address": "Gottschalkstraße 7, 13359 Berlin",
            "lat": null,
            "lng": null,
            "number_of_rooms": 3,
            "price": null,
            "base_rent": 400,
            "living_space": 77,
            "number_of_bed_rooms": 2,
            "number_of_bath_rooms": 2,
            "property_space_value": 77,
            "images": [
                {
                    "original": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/Objekt.jpg",
                    "big": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/big_Objekt.jpg",
                    "medium": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/medium_Objekt.jpg",
                    "thumb": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/thumb_Objekt.jpg",
                    "tags": null,
                    "is_floorplan": false,
                    "is_private": false
                }
            ],
            "status": {
                "id": 2,
                "name": "In Vorbereitung",
                "color": "#ed892b"
            }
        },
    ],
    "meta": {
        "total_count": 150
    }
}
```

{% endtab %}
{% endtabs %}

Eine Excel-Datei mit allen relevanten Felder eines Objektes, gruppiert nach Objekttyp:

{% file src="/files/-Loymnd4Wjxxr1S8TNY6" %}
Objekt-Felder (für Exposés speziell)
{% endfile %}

### Mehrsprachigkeit

In Propstack kann man bestimmte Texte eines Objektes in mehreren Sprachen einstellen. Folgende Felder können übersetzt werden:

1. Überschrift (title)
2. Objektbeschreibung (description\_note)
3. Lagebeschreibung (location\_note)
4. Ausstattung (furnishing\_note)
5. Sonstiges (other\_note)
6. Käuferprovision (courtage)
7. Provisionshinweis (courtage\_note)

Um die Objekte in einer anderen Sprache zu erhalten gibt man einen weiteren Parameter `locale` mit. Standardmäßig erhält man die deutsche Sprache. Über `locale=en` würde man die englischen Texte erhalten. Es ist auch möglich, mehrere Sprachen zu erhalten. Beispiel: `locale=de,en`

### Weitere Filtermöglichkeiten

Folgende Felder kann man zusätzlich über die API filtern anhand von "ab-bis" Angaben:

* Kaufpreis: price
* Kaltmiete: base\_rent
* Warmmiete: total\_rent
* Fläche: property\_space\_value
* Wohnfläche: living\_space
* Grundstücksfläche: plot\_area
* Zimmer: number\_of\_rooms
* Schlafzimmer: number\_of\_bed\_rooms
* Badezimmer: number\_of\_bath\_rooms
* Etage: floor
* Baujahr: construction\_year

Die Parameter dafür haben immer ein `_from` *oder* `_to` angehängt, um zu bestimmen ob es ab diesem Wert gilt oder bis zu diesem Wert. Beispiel:

`?price_from=300000&price_to=350000` wirft alle Objekte aus, deren Preis zwischen 300.000 und 350.000 € liegen. `?plot_area=1500` wirft alle Objekte aus, deren Grundstücksfläche über 1.500qm beträgt.

### Sortierungsmöglichkeiten

* Auftragsnummer: `exposee_id`
* Baujahr: `construction_year`
* Einheitenummer: `unit_id.raw`
* Etage: `floor`
* Erstellungsdatum: `created_at`
* Fläche: `property_space_value`
* Grundstücksfläche: `plot_area`
* Kaltmiete: `base_rent`
* Kaufpreis: `price`
* Preis: `object_price`
* Fläche/qm: `price_per_sqm`
* Status: `property_status_position`
* Straße: `street_number.raw`
* Verkaufsdatum: `sold_date`
* Warmmiete: `total_rent`
* Zimmer: `number_of_rooms`
* Zuletzt bearbeitet: `updated_at`

Mögliche Vermarktungsart (`marketing_type`):&#x20;

1. `BUY`&#x20;
2. `RENT`

Mögliche Oberkategorie für Objekttypen `object_type`:

1. `LIVING`
2. `COMMERCIAL`
3. `INVESTMENT`

Mögliche Objekttypen (`rs_type`):

1. `APARTMENT`
2. `HOUSE`
3. `TRADE_SITE`
4. `GARAGE`
5. `SHORT_TERM_ACCOMODATION`
6. `OFFICE`
7. `GASTRONOMY`
8. `INDUSTRY`
9. `STORE`
10. `SPECIAL_PURPOSE`
11. `INVESTMENT`

(Text-)Felder, die in verschiedenen Sprachen hinterlegt werden können:

* title
* description\_note
* location\_note
* furnishing\_note
* other\_note
* long\_description\_note
* long\_location\_note
* long\_furnishing\_note
* long\_other\_note
* courtage
* courtage\_note

Mögliche Objektarten (`rs_category`):

* `ROOF_STOREY` - Dachgeschoss
* `LOFT` - Loft
* `MAISONETTE` - Maisonette
* `PENTHOUSE` - Penthouse
* `TERRACED_FLAT` - Terrassenwohnung
* `GROUND_FLOOR` - Erdgeschosswohnung
* `APARTMENT` - Etagenwohnung
* `RAISED_GROUND_FLOOR` - Hochparterre
* `HALF_BASEMENT` - Souterrain
* `ATTIKA` -Attikawohnung
* `OTHER` - Sonstige
* `SINGLE_FAMILY_HOUSE` - Einfamilienhaus
* `TWO_FAMILY_HOUSE` - Zweifamilienhaus
* `TERRACE_HOUSE` - Reihenhaus
* `MID_TERRACE_HOUSE` - Reihenmittelhaus
* `TERRACE_END_HOUSE` - Reihenendhaus
* `END_TERRACE_HOUSE` - Reiheneckhaus
* `MULTI_FAMILY_HOUSE` - Mehrfamilienhaus
* `TOWNHOUSE` - Stadthaus
* `FINCA` - Finca
* `BUNGALOW` - Bungalow
* `FARMHOUSE` - Bauernhaus
* `SEMIDETACHED_HOUSE` - Doppelhaushälfte
* `VILLA` - Villa
* `CASTLE_MANOR_HOUSE` - Burg/Schloss
* `SPECIAL_REAL_ESTATE` - Besondere Immobilie
* `TWIN_SINGLE_FAMILY_HOUSE` - Doppeleinfamilienhaus
* `SUMMER_RESIDENCE` - Ferienhaus
* `GARAGE` - Garage
* `STREET_PARKING` - Außenstellplatz
* `CARPORT` - Carport
* `DUPLEX` - Duplex
* `CAR_PARK` - Parkhaus
* `UNDERGROUND_GARAGE` - Tiefgarage
* `DOUBLE_GARAGE` - Doppelgarage
* `NO_INFORMATION` - Keine Angabe
* `OFFICE_LOFT` - Loft
* `STUDIO` - Atelier
* `OFFICE` - Büro
* `OFFICE_FLOOR` - Büroetage
* `OFFICE_BUILDING` - Bürohaus
* `OFFICE_CENTRE` - Bürozentrum
* `OFFICE_STORAGE_BUILDING` - Büro-/ Lagergebäude
* `SURGERY` - Praxis
* `SURGERY_FLOOR` - Praxisetage
* `SURGERY_BUILDING` - Praxishaus
* `COMMERCIAL_CENTRE` - Gewerbezentrum
* `LIVING_AND_COMMERCIAL_BUILDING` - Wohn- und Geschäftsgebäude
* `OFFICE_AND_COMMERCIAL_BUILDING` - Büro- und Geschäftsgebäude
* `BAR_LOUNGE` - Barbetrieb/Lounge
* `CAFE` - Café
* `CLUB_DISCO` - Club/Diskothek
* `GUESTS_HOUSE` - Gästehaus
* `TAVERN` - Gaststätte
* `HOTEL` - Hotel
* `HOTEL_RESIDENCE` - Hotelanwesen
* `HOTEL_GARNI` - Hotel garni
* `PENSION` - Pension
* `RESTAURANT` - Restaurant
* `SHOWROOM_SPACE` - Ausstellungsfläche
* `HALL` - Halle
* `HIGH_LACK_STORAGE` - Hochregallager
* `INDUSTRY_HALL` - Industriehalle
* `INDUSTRY_HALL_WITH_OPEN_AREA` - Industriehalle mit Freifläche
* `COLD_STORAGE` - Kühlhaus
* `MULTIDECK_CABINET_STORAGE` - Kühlregallager
* `STORAGE_WITH_OPEN_AREA` - Lager mit Freifläche
* `STORAGE_AREA` - Lagerfläche
* `STORAGE_HALL` - Lagerhalle
* `SERVICE_AREA` - Servicefläche
* `SHIPPING_STORAGE` - Speditionslager
* `REPAIR_SHOP` - Werkstatt
* `SHOPPING_CENTRE` - Einkaufszentrum
* `FACTORY_OUTLET` - Factory Outlet
* `DEPARTMENT_STORE` - Kaufhaus
* `KIOSK` - Kiosk
* `STORE` - Laden
* `SELF_SERVICE_MARKET` - SB-Markt
* `SALES_AREA` - Verkaufsfläche
* `SALES_HALL` - Verkaufshalle
* `RESIDENCE` - Anwesen
* `FARM` - Bauernhof
* `LEISURE_FACILITY` - Freizeitanlage
* `COMMERCIAL_UNIT` - Gewerbeeinheit
* `INDUSTRIAL_AREA` - Gewerbefläche
* `NURSING_HOME` - Pflegeheim
* `ASSISTED_LIVING` - Betreutes Wohnen
* `HORSE_FARM` - Reiterhof
* `VINEYARD` - Weingut
* `REPAIR_SHOP` - Werkstatt
* `SPECIAL_ESTATE` - Spezialobjekt
* `INVEST_LIVING_BUSINESS_HOUSE` - Wohn-/Geschäftshaus
* `INVEST_HOUSING_ESTATE` - Wohnanlage
* `INVEST_MICRO_APARTMENTS` - Micro-Apartments
* `INVEST_OFFICE_BUILDING` - Bürohaus
* `INVEST_COMMERCIAL_BUILDING` - Geschäftshaus
* `INVEST_OFFICE_AND_COMMERCIAL_BUILDING` - Büro- und Geschäftshaus
* `INVEST_SHOP_SALES_FLOOR` - Laden/Verkaufsfläche
* `INVEST_SUPERMARKET` - Supermarkt
* `INVEST_SHOPPING_CENTRE` - Einkaufszentrum
* `INVEST_RETAIL_PARK` - Fachmarktzentrum
* `INVEST_HOTEL` - Hotel
* `INVEST_BOARDING_HOUSE` - Boarding House
* `INVEST_SURGERY_BUILDING` - Ärztehaus
* `INVEST_CLINIC` - Klinik
* `INVEST_REHAB_CLINIC` - Rehaklinik
* `INVEST_MEDICAL_SERVICE_CENTER` - MVZ
* `INVEST_INTEGRATION_ASSISTANCE` - Eingliederungshilfe
* `INVEST_DAY_NURSERY` - Kita
* `INVEST_DAY_CARE` - Tagespflege
* `INVEST_NURSING_HOME` - Pflegeheim
* `INVEST_ASSISTED_LIVING` - Betreutes Wohnen
* `INVEST_COMMERCIAL_CENTRE` - Gewerbepark
* `INVEST_HALL_STORAGE` - Halle/Logistik
* `INVEST_INDUSTRIAL_PROPERTY` - Produktion/Fertigung
* `INVEST_CAR_PARK` - Parkhaus
* `INVEST_PLOT` - Grundstück
* `INVEST_COMMERCIAL_UNIT` - Gewerbeeinheit
* `INVEST_OTHER` - Sonstiges

## Objekt anlegen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/units`

#### Request Body

| Name     | Type   | Description                               |
| -------- | ------ | ----------------------------------------- |
| property | object | siehe alle möglichen Werte für ein Objekt |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

### Objekt anlegen mit Eigentümer

Beim Anlegen eines Objektes kann auch gleichzeitig ein Eigentümer mitverknüpft werden. Der Payload dafür sieht wie folgt aus:

```javascript
{
  "property": {
    "title": "Nice apartment",
    // ...
    "relationships_attributes": [{
        "internal_name": "owner",
        "related_client_id": 123
    }]
  }
}
```

Der Eigentümer muss vorher in Propstack existieren. Die ID des Kontaktes wird dann unter `related_client_id` mitgegeben.

### Objekt anlegen mit einem verknüpften Kontakt

Beim Anlegen eines Objektes kann auch gleichzeitig ein Kontakt (Partner) mitverknüpft werden. Der Payload dafür sieht wie folgt aus:

<pre class="language-javascript"><code class="lang-javascript"><strong>{
</strong>  "property": {
    "title": "Nice apartment",
    // ...
    "relationships_attributes": [{
        "internal_name": "partner",
        "name": "Käufer",
        "related_client_id": 123
    }]
  }
}
</code></pre>

Der Kontakt muss vorher in Propstack existieren. Die ID des Kontaktes wird dann unter `related_client_id` mitgegeben.

### Objekt anlegen mit Custom Feldern

Beim Anlegen eines Objekts können benutzerdefinierte Felder verwendet werden, um zusätzliche Informationen hinzuzufügen. Der Payload für die Anfrage könnte folgendermaßen aussehen:

```json
{
  "property": {
    "title": "Nice apartment",
    // ...
    "partial_custom_fields": {
      "my_custom_field": "description"
    }
  }
}
```

Die benutzerdefinierten Felder werden im `partial_custom_fields`-Objekt angegeben und können je nach Bedarf angepasst werden.

## Objekt bearbeiten

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/units/:id`

Ein vorhandendes Objekt bearbeiten

#### Request Body

| Name     | Type   | Description                               |
| -------- | ------ | ----------------------------------------- |
| property | object | siehe alle möglichen Werte für ein Objekt |

#### Hinweis

Die Payloads, die für die Erstellaktion verwendet werden, können auch für die Aktualisierungsaktion verwendet werden.

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Objekt löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/units/:id`

Ein vorhandenes Objekt löschen

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Objekt lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/units/:id?new=1`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "id": 5,
    "name": "001",
    "title": {
        "label": "Überschrift",
        "value": "Traumhafte Familienwohnung im klassischen Altbau in ruhiger Lage!"
    },
    "unit_id": "001",
    "exposee_id": "",
    "project_id": 2,
    "broker_id": 1,
    "archived": false,
    "street": "Gottschalkstraße",
    "house_number": "7",
    "zip_code": "13359",
    "city": "Berlin",
    "address": "Gottschalkstraße 7, 13359 Berlin, Deutschland",
    "short_address": "Gottschalkstraße 7, 13359 Berlin",
    "marketing_type": "RENT",
    "object_type": "LIVING",
    "rs_type": "APARTMENT",
    "rs_category": "PENTHOUSE",
    "custom_fields": {
        "gebaudeversicherung": {
            "value": null,
            "pretty_value": null
        }
    },
    "created_at": "2019-06-04T17:09:21.109+02:00",
    "updated_at": "2019-10-08T14:16:29.488+02:00",
    "description_note": {
        "label": "Beschreibung",
        "value": "Die bezugsfreie Eigentumswohnung befindet sich im Hochparterre und EG in einem gepflegten Jugendstilgebäude. The dwelling is located in the 1. floor in a building of 1908."
    },
    "broker": {
        "id": 1,
        "salutation": "mr",
        "academic_title": null,
        "first_name": "Max",
        "last_name": "Mustermann",
        "name": "Max Mustermann",
        "avatar": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/avatar/ASLYoUSnKDYGZR2ZuA7cB19e/thumb_profilbild.jpg",
        "avatar_url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/avatar/ASLYoUSnKDYGZR2ZuA7cB19e/profilbild.jpg",
        "old_crm_id": null,
        "position": "CEO",
        "email": "makler@propstack.de",
        "phone": "+49 030 399 282 39",
        "color": "#0d68de",
        "connected": true,
        "team_id": null,
        "department_ids": [],
        "abstract": null,
        "description": null,
        "custom_fields": {}
    },
    "project": {
        "title": "Colors of Reinickendorf"
    },
    "property_groups": [
        {
            "id": 23,
            "name": "foo",
            "super_group_id": null
        }
    ],
    "documents": [],
    "floorplans": [
        {
            "id": 5,
            "name": "niceundriss.pdf",
            "title": "niceundriss.pdf",
            "url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/floorplans/EKuaWsFFoCcwrYd92KRfaQ9B/plan/FWpUaaDpwKgkCrHXr4zf3Lxg/grundriss.pdf",
            "position": 1,
            "updated_at": "2019-10-08T14:16:29.481+02:00"
        }
    ],
    "links": [],
    "images": [
        {
            "id": 8,
            "is_floorplan": false,
            "is_private": false,
            "title": "Objekt",
            "tags": null,
            "position": 1,
            "url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/Objekt.jpg",
            "updated_at": "2019-07-16T21:46:13.892+02:00",
            "big_url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/big_Objekt.jpg",
            "medium_url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/medium_Objekt.jpg",
            "thumb_url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/thumb_Objekt.jpg",
            "small_thumb_url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/small_thumb_Objekt.jpg",
            "square_url": "https://dev-propstack.s3.eu-central-1.amazonaws.com/photos/EKuaWsFFoCcwrYd92KRfaQ9B/photo/bayDE6L8RZYbimGFH4mJtgNV/square_Objekt.jpg"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Objekt-Stati lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/property_statuses`

Ein Objekt hat in der Regel immer einen Status, z.B. "Verfügbar" oder "Verkauft". Über diesen Endpoint kann man sich alle möglichen Objekt-Stati ziehen, die ein Objekt haben kann.

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": [
        {
            "id": 274,
            "name": "Verfügbar",
            "position": 1,
            "color": "#009cde",
            "nonpublic": false
        },
        {
            "id": 276,
            "name": "Reserviert",
            "position": 3,
            "color": "#f55753",
            "nonpublic": false
        },
        {
            "id": 278,
            "name": "Verkauft",
            "position": 5,
            "color": "#10cfbd",
            "nonpublic": true
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# Bilder

## Bild hochladen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/images`

Endpoint zum Hochladen eines Bildes. Ein Bild gehört immer entweder zu einem Projekt oder zu einem Objekt. Die Bilder-Parameter müssen um ein `image` Objekt umschlossen werden.

#### Request Body

| Name            | Type    | Description                                                                                            |
| --------------- | ------- | ------------------------------------------------------------------------------------------------------ |
| photo           | string  | base64 encoded String für das Bild                                                                     |
| imageable\_id   | integer | ID des Objektes/Projektes                                                                              |
| imageable\_type | string  | Entweder "Property" oder "Project", je nachdem ob das Bild an ein Objekt oder Projekt angehangen wird. |
| is\_private     | boolean | Wenn `false` => Bild auf Portale anzeigen. Bei `true` => Bild wird nicht zu Portalen übertragen        |
| title           | string  | Bildbeschreibung. Wird auch als Dateiname in der URL verwendet                                         |

{% tabs %}
{% tab title="201 Bild erfolgreich erstellt. ID des Bildes wird zurückgegeben." %}

```javascript
{
  "ok": true,
  "id": 38202
}
```

{% endtab %}
{% endtabs %}

### Beispiel Payload

```javascript
{
  "image": {
    "imageable_id": 12,
    "imageable_type": "Property",
    "photo": "data:image/png;base64,...",
    "title": "Ausblick"
  }
}
```

## Bild bearbeiten

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/images/{id}`

#### Request Body

| Name        | Type   | Description                                                                                     |
| ----------- | ------ | ----------------------------------------------------------------------------------------------- |
| title       | String | Bildbeschreibung                                                                                |
| is\_private | String | Wenn `false` => Bild auf Portale anzeigen. Bei `true` => Bild wird nicht zu Portalen übertragen |

### Bild-Beschreibung mehrsprachig bearbeiten

Die Bildbeschreibung ist ein mehrsprachiges Feld, d.h. man kann es in verschiedenen Sprachen befüllen. Über die API geht das, indem man das Feld `title_[locale]` bedient. \[locale] muss mit der jeweiligen Sprache ersetzt werden. Ein Beispiel-Payload um die deutsche und englische Version gleichzeitig zu setzen:

```
{
  "image": {
    "title_de": "Ausblick",
    "title_en": "View"
  }
}
```


# Links

## Link erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/links`

Dieser Endpoint erstellt einen Link für ein bestimmtes Objekt.

#### Query Parameters

| Name                      | Type    | Description                                                           |
| ------------------------- | ------- | --------------------------------------------------------------------- |
| link\_\_is\_embedable     | boolean | Soll der Link als Iframe auf der Objekt-Landing-Page angezeigt werden |
| link\_\_on\_landing\_page | boolean | Soll der Link auf der Objekt-Landing-Page angezeigt werden            |
| link\_\_is\_private       | boolean | Soll der Link auf Portale übertragen werden                           |
| link\_\_url               | string  | URL des Links                                                         |
| property\_id              | integer | Propstack-ID des Objektes, bei dem der Link angelegt werden soll      |
| link\_\_title             | string  | Titel des Links                                                       |

{% tabs %}
{% tab title="200 Link wurde erstellt" %}

```javascript
{
    "id": 1,
    "title": "Foo",
    "url": "https://foo.bar",
    "is_private": false,
    "tags": [],
    "is_embedable": false,
    "on_landing_page": false,
    "position": 1
}
```

{% endtab %}
{% endtabs %}

## Link aktualisieren

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/links/:id`

Einen vorhandenen Link aktualisieren.  Die gleichen Parameter wie beim Erstellen sind hier verfügbar.

{% tabs %}
{% tab title="200 " %}

```
{
    "id": 1,
    "title": "Foobar",
    "url": "https://foo.bar",
    "is_private": false,
    "tags": [],
    "is_embedable": false,
    "on_landing_page": false,
    "position": 1
}
```

{% endtab %}
{% endtabs %}

## Link löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/links/:id`

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}


# Policy

Policies sind Nachweise in Form von Aktivitäten, die automatisch von Propstack beim Abschicken bestimmter Formulare (wie der Widerrufsbelehrung) angelegt werden.

Policies können (aktuell) nicht über die API angelegt werden. Sie sind `read_only` beim Lesen von Aktivitäten zu finden.

## Das Policy Objekt

| Attribut        | Typ     | Beschreibung                                                                                                                            |
| --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| name            | string  | Human readable Beschreibung der Art der Policy. z.B. "Widerrufsbelehrung" oder "Kontakterlaubnis erteilt" oder "Speicherung zugestimmt" |
| message\_id     | integer | Referenz zu einer E-Mail, worüber die Policy angelegt wurde. Muss immer existieren                                                      |
| created\_at     | date    | Erstellungsdatum der Policy                                                                                                             |
| read            | boolean | Wurde die Widerrufsbelehrung gelesen?                                                                                                   |
| accept\_service | boolean | Wurde der frühzeitigen Maklertätigkeit zugestimmt                                                                                       |
| accept\_terms   | boolean | Wurden den AGB zugestimmt? (sofern die AGB in Propstack eingetragen ist)                                                                |
| accept\_privacy | boolean | Wurde der Datenschutzerklärung zugestimmt? (sofern die Datenschutzerklärung in Propstack hinterlegt wurde)                              |
| accept\_contact | boolean | Wurde die Kontakterlaubnis bestätigt?                                                                                                   |
| accept\_storage | boolean | Wurde der Speicherung der Daten zugestimmt?                                                                                             |


# Portal-Export

Übertragung von Objekten zu Portalen

## Objekt zu Portal exportieren

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/portals/publish`

#### Request Body

| Name                                            | Type       | Description                                                                                               |
| ----------------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------- |
| property\_ids<mark style="color:red;">\*</mark> | integer\[] | Array as Objekt-IDs, die übertragen werden sollen                                                         |
| portal\_ids<mark style="color:red;">\*</mark>   | integer\[] | Array aus Portal-IDs, zu denen die Objekte übertragen werden sollen                                       |
| active                                          | boolean    | default `true`. Wenn `false` angegeben wird, werden die Objekte aus den Portalen entfernt                 |
| is24\_delete                                    | boolean    | default `false`. Wenn `true` angegeben wird, werden die Objekte aus dem ImmobilienScout24-Portal entfernt |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    ok: true
}
```

{% endtab %}
{% endtabs %}


# Projekte

Projekte sind als "Über-Objekte" zu verstehen. Ein Projekt umfasst in der Regel mehrere Objekte, auch Einheiten genannt.

## Project Schema

<table><thead><tr><th>Field Name</th><th>Field Type</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>The name of the project.</td></tr><tr><td>status</td><td>enum</td><td><p>one of: </p><pre><code>ACQUISITION
PROGRESS
SALES
SOLD
</code></pre></td></tr><tr><td>note</td><td>string</td><td></td></tr><tr><td>warning_notice</td><td>string</td><td>Shown in the project as a red warning bar</td></tr><tr><td>broker_id</td><td>integer</td><td>Reference who is responsible for the project. See "Nutzer" table</td></tr><tr><td>title</td><td>string</td><td>headline for the exposé</td></tr><tr><td>for_rent</td><td>boolean</td><td>to be marked as a project for rental properties</td></tr><tr><td>street</td><td>string</td><td></td></tr><tr><td>house_number</td><td>string</td><td></td></tr><tr><td>zip_code</td><td>string</td><td></td></tr><tr><td>city</td><td>string</td><td></td></tr><tr><td>lat</td><td>float</td><td>latitude</td></tr><tr><td>lng</td><td>float</td><td>longitude</td></tr><tr><td>location_id</td><td>integer</td><td>see "Geolagen" table</td></tr><tr><td>courtage</td><td>string</td><td></td></tr><tr><td>courtage_note</td><td>string</td><td></td></tr><tr><td>description_note</td><td>string</td><td></td></tr><tr><td>location_note</td><td>string</td><td></td></tr><tr><td>furnishing_note</td><td>string</td><td></td></tr><tr><td>construction_year</td><td>integer</td><td></td></tr></tbody></table>

## Projekte abrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/projects`

Mit diesem Endpoint erhältst du alle Projekte des Unternehmens.

#### Path Parameters

| Name   | Type   | Description                                                                                                                                      |
| ------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| expand | string | Wert ist egal, z.B. `1`. Wenn der Parameter gesetzt ist, werden die erweiterten Daten zurückgegeben, wie wenn man ein einzelnes Projekt aufruft. |

{% tabs %}
{% tab title="200 successfully retrieved." %}

```javascript
[
  {
    "id": 23,
    "title": "Living Home",
    "status": {
      "label": "Vertrieb",
      "color": "#123123"
    },
    "broker_id": 66,
    "title_image": {
      "url": "https://...jpg",
      "square_url": "https://...jpg"
    },
    "project_id": "LH",
    "sub_headline": null,
    "tagline": null,
    "logo_url": "https://...jpg",
    "street": "Hauptstraße",
    "house_number": "12",
    "sublocality_level_1": "Kreuzberg",
    "zip_code": "12345",
    "city": "Berlin",
    "address": "Hauptstraße 12, 12345 Berlin, Deutschland",
    "lat": 13.4483934,
    "lng": 49.3483043,
    "hide_address": false,
    "custom_fields": {}
  }
]
```

{% endtab %}
{% endtabs %}

## Create a Project

<mark style="color:blue;">`POST`</mark> `https://api.propstack.de/v1/projects`

**Request Body**

| Name    | Type   | Description        |
| ------- | ------ | ------------------ |
| project | object | See project schema |

**Response**

**201 Created**

```javascript
{
  "ok": true,
  "id": 24
}
```

## Projekt abrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/projects/:id`

#### Path Parameters

| Name | Type   | Description      |
| ---- | ------ | ---------------- |
| id   | number | ID des Projektes |

{% tabs %}
{% tab title="200 " %}

```javascript
{
  "id": 23,
  "title": "Living Home",
  "status": {
    "label": "Vertrieb",
    "color": "#123123"
  },
  "broker_id": 66,
  "title_image": {
    "url": "https://...jpg",
    "square_url": "https://...jpg"
  },
  "project_id": "LH",
  "sub_headline": null,
  "tagline": null,
  "logo_url": "https://...jpg",
  "street": "Hauptstraße",
  "house_number": "12",
  "sublocality_level_1": "Kreuzberg",
  "zip_code": "12345",
  "city": "Berlin",
  "address": "Hauptstraße 12, 12345 Berlin, Deutschland",
  "lat": 13.4483934,
  "lng": 49.3483043,
  "hide_address": false,
  "custom_fields": {},
  "description_note": "...",
  "location_note": "...",
  "images": [
    {
      "id": 123,
      "is_floorplan": false,
      "is_private": true,
      "title": "Schlafzimmer",
      "url": "https://...",
      "square_url": "https://..."
    }
  ],
  "floorplans": [
    {
      "id": 123,
      "title": "Grundriss",
      "url": "https://..."
    }
  ],
  "documents": [
    {
      "id": 123,
      "title": "Dokument A",
      "is_private": true,
      "url": "https://..."
    }
  ],
  "links": [
    {
      "id": 123,
      "title": "Homepage",
      "url": "https://..."
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## Update a Project

<mark style="color:blue;">`PUT`</mark> `https://api.propstack.de/v1/projects/:id`

**Path Parameters**

| Name | Type   | Description                  |
| ---- | ------ | ---------------------------- |
| id   | number | ID of the project to update. |

**Request Body**

| Name    | Type   | Description        |
| ------- | ------ | ------------------ |
| project | object | See project schema |

**Response**

**200 OK**

```javascript
{
  "id": 24,
  "title": "Updated Project",
  ...
}
```


# Snom Integration

Auf dieser Seite wird gezeigt wie man auf seinem Snom-Gerät den Namen des Kontaktes anzeigen kann.

## Anrufinfo erhalten

<mark style="color:blue;">`GET`</mark> `https://crm.propstack.de/api/snom-phonebook`

#### Query Parameters

| Name     | Type   | Description                                                  |
| -------- | ------ | ------------------------------------------------------------ |
| api\_key | string | Der API-Key, um auf die Kundendaten in Propstack zuzugreifen |
| number   | string | Die Telefonnummer des Anrufenden                             |

{% tabs %}
{% tab title="200 Kontakt gefunden (wenn kein Kontakt gefunden, ist die Antwort leer!)" %}

```markup
<?xml version="1.0" encoding="UTF-8"?>
<SnomIPPhoneText state="relevant">
    <Title>CRM Anrufinfo</Title>
    <Prompt></Prompt>
    <Text>
      Anruf
      <br/>-<br/>
      Apple Inc.
      <br/>
      John Doe
    </Text>
</SnomIPPhoneText>
```

{% endtab %}
{% endtabs %}

Beispiel-URL:

`https://crm.propstack.de/api/snom-phonebook?api_key=mein-api-key&number=$remote`

`mein-api-key` müsste natürlich mit einem eigentlichen API-Key von Propstack ersetzt werden. Dem API-Key muss auch das Recht für die Snom-Integration explizit gesetzt werden!

`$remote` ist ein Platzhalter, den das Snom-Telefon bei einem eingehenden Anruf mit der eigentlichen Telefonnummer ersetzen würde.


# Suchprofile

Suchprofile gehören immer zu einem Kontakt und beschreiben die Art der Immobilie, die der Kontakt erwerben möchte.

## Suchprofile lesen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/saved_queries`

Suchprofile lassen sich paginieren über die Parameter `page` und `per`. Standardmäßig werden die ersten 25 Suchprofile angezeigt.

#### Query Parameters

| Name   | Type   | Description                 |
| ------ | ------ | --------------------------- |
| client | number | <p>ID des Kontaktes<br></p> |

{% tabs %}
{% tab title="200 Cake successfully retrieved." %}

```javascript
{
    "data": [
        {
            "id": 1,
            "created_at": "2018-01-19T18:51:43.133+01:00",
            "updated_at": "2018-12-07T18:34:28.075+01:00",
            "broker_id": 2,
            "client_id": 3,
            "price": null,
            "price_to": null,
            "base_rent": 1520.496,
            "base_rent_to": 1858.384,
            "total_rent": 1815.093,
            "total_rent_to": 2218.447,
            "living_space": 0,
            "living_space_to": null,
            "number_of_rooms": 2.5,
            "number_of_rooms_to": 5,
            "property_status_ids": [],
            "location_ids": [],
            "cities": [
                "Berlin",
                "Frankfurt"
            ],
            "regions": [],
            "marketing_type": "RENT",
            "rs_types": [],
            "rs_categories": [],
            "note": "Sucht sehr dringend",
            "number_of_bedrooms": "",
            "number_of_bedrooms_to": "",
            "floor": "",
            "floor_to": "",
            "plot_area": "",
            "plot_area_to": "",
            "total_floor_space": null,
            "total_floor_space_to": null,
            "construction_year": null,
            "construction_year_to": null,
            "lift": "",
            "balcony": "",
            "garden": "",
            "built_in_kitchen": "",
            "cellar": "",
            "rented": "",
            "price_per_sqm": null,
            "price_per_sqm_to": null,
            "net_floor_space": null,
            "net_floor_space_to": null,
            "price_multiplier": null,
            "price_multiplier_to": null,
            "yield_actual": null,
            "yield_actual_to": null,
            "investment_category": null,
            "purchase_form": null,
            "industrial_area": null,
            "industrial_area_to": null,
            "tenant_structure": null,
            "walt": null,
            "single_rooms_quota": null,
            "single_rooms_quota_to": null,
            "occupancy_rate": null,
            "occupancy_rate_to": null,
            "monument": null,
            "conservation_areas": null,
            "condition": null,
            "number_of_parking_spaces": null,
            "number_of_parking_spaces_to": null,
            "short_term_constructible": null,
            "recommended_use_types": null,
            "site_development_type": null,
            "building_permission": null,
            "preliminary_enquiry": null
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Suchprofil erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/saved_queries`

#### Request Body

| Name         | Type   | Description                                     |
| ------------ | ------ | ----------------------------------------------- |
| saved\_query | object | siehe alle möglichen Felder zu einem Suchprofil |

{% tabs %}
{% tab title="201 Es wird die ID des angelegten Suchprofils zurückgegeben" %}

```
{
    "ok": true,
    "id": 123
}
```

{% endtab %}
{% endtabs %}

## Suchprofil aktualisieren

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/saved_queries/:id`

#### Request Body

| Name         | Type   | Description                                     |
| ------------ | ------ | ----------------------------------------------- |
| saved\_query | object | siehe alle möglichen Felder zu einem Suchprofil |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Suchprofil löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/saved_queries/:id`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "ok": true,
    "id": 123,
}
```

{% endtab %}
{% endtabs %}

## Das Suchprofil Objekt

| Attribut        | Typ        | Beschreibung                                                                                                          |
| --------------- | ---------- | --------------------------------------------------------------------------------------------------------------------- |
| client\_id      | integer    | ID des Kontaktes, zu welches das Suchprofil gehört                                                                    |
| active          | boolean    | Soll das Suchprofil für das Matching von Objekten genutzt werden?                                                     |
| cities          | string\[]  | Eine Liste von Städten (einfache Strings, wie Berlin oder München)                                                    |
| regions         | string\[]  | Eine Liste von Regionen/Bundesländern                                                                                 |
| lat             | float      | Breitengrad (für Radiussuche)                                                                                         |
| lng             | float      | Längengrad (für Radiussuche)                                                                                          |
| radius          | integer    | Radius in Meter (für Radiussuche)                                                                                     |
| marketing\_type | string     | eines von `BUY`, oder `RENT` oder leer lassen                                                                         |
| rs\_types       | string\[]  | eine Liste von Objektypen, siehe [hier](https://propstack.gitbook.io/docs/reference/objekte) für alle möglichen Werte |
| rs\_categories  | string\[]  | eine Liste von Objektarten, siehe unten für mögliche Werte                                                            |
| group\_ids      | integer\[] | eine Liste von Objektmerkmalen                                                                                        |
| note            | string     | Notizfeld für weitere Anmerkungen                                                                                     |

### Weitere Felder vom Suchprofil, die für Wohnobjekte interessant sind:

| Attribut                 | Typ     | Beschreibung                                                                           |
| ------------------------ | ------- | -------------------------------------------------------------------------------------- |
| living\_space            | float   | Mindest(wohn)fläche, die das Objekt haben muss                                         |
| living\_space\_to        | float   | Maximale Fläche, die das Objekt haben kann                                             |
| price                    | float   | Mindestpreis des Objektes                                                              |
| price\_to                | float   | Maximaler Kaufpreis, welche das Objekt haben kann                                      |
| number\_of\_rooms        | float   | Mindest- Zimmeranzahl                                                                  |
| number\_of\_rooms\_to    | float   | Maximale Anzahl an Zimmer                                                              |
| number\_of\_bedrooms     | float   | Mindest-Schlafzimmeranzahl                                                             |
| number\_of\_bedrooms\_to | float   | Maximale Anzahl an Schlafzimmer                                                        |
| base\_rent               | float   | Mindestkaltmiete des Objektes                                                          |
| base\_rent\_to           | float   | Maximale Kaltmiete des Objektes                                                        |
| floor                    | integer | Mindest Etage des Objekte (`2` => ab 2. Etage)                                         |
| floor\_to                | integer | Maximale Etage                                                                         |
| plot\_area               | float   | Mindest Grundstücksfläche                                                              |
| plot\_area\_to           | float   | Maximale Grundstücksfläche                                                             |
| construction\_year       | integer | Mindest Baujahr (z.B. `2018`)                                                          |
| construction\_year\_to   | integer | Maximales Baujahr                                                                      |
| lift                     | string  | Muss einen Fahrstuhl haben? `true`, `false` oder einfach leer lassen, wenn es egal ist |
| balcony                  | string  | Muss ein Balkon haben? s. lift für mögliche Optionen                                   |
| garden                   | string  | Muss einen Garten haben? s. lift für mögliche Optionen                                 |
| built\_in\_kitchen       | string  | Einbauküche? s. lift für mögliche Optionen                                             |
| cellar                   | string  | Keller? s. lift für mögliche Optionen                                                  |
| rented                   | string  | Soll das Objekt vermietet sein? s. lift für mögliche Optionen                          |

## Anmerkungen

**Verfügbare Objektarten (`rs_categories`):**

```javascript
{
  "ROOF_STOREY": "Dachgeschoss",
  "LOFT": "Loft",
  "MAISONETTE": "Maisonette",
  "PENTHOUSE": "Penthouse",
  "TERRACED_FLAT": "Terrassenwohnung",
  "GROUND_FLOOR": "Erdgeschosswohnung",
  "APARTMENT": "Etagenwohnung",
  "RAISED_GROUND_FLOOR": "Hochparterre",
  "HALF_BASEMENT": "Souterrain",
  "ATTIKA": "Attikawohnung",
  "OTHER": "Sonstige",
  "SINGLE_FAMILY_HOUSE": "Einfamilienhaus",
  "TWO_FAMILY_HOUSE": "Zweifamilienhaus",
  "TERRACE_HOUSE": "Reihenhaus",
  "MID_TERRACE_HOUSE": "Reihenmittelhaus",
  "TERRACE_END_HOUSE": "Reihenendhaus",
  "END_TERRACE_HOUSE": "Reiheneckhaus",
  "MULTI_FAMILY_HOUSE": "Mehrfamilienhaus",
  "TOWNHOUSE": "Stadthaus",
  "FINCA": "Finca",
  "BUNGALOW": "Bungalow",
  "FARMHOUSE": "Bauernhaus",
  "SEMIDETACHED_HOUSE": "Doppelhaushälfte",
  "VILLA": "Villa",
  "CASTLE_MANOR_HOUSE": "Burg/Schloss",
  "SPECIAL_REAL_ESTATE": "Besondere Immobilie",
  "TWIN_SINGLE_FAMILY_HOUSE": "Doppeleinfamilienhaus",
  "SUMMER_RESIDENCE": "Ferienhaus",
  "GARAGE": "Garage",
  "STREET_PARKING": "Außenstellplatz",
  "CARPORT": "Carport",
  "DUPLEX": "Duplex",
  "CAR_PARK": "Parkhaus",
  "UNDERGROUND_GARAGE": "Tiefgarage",
  "DOUBLE_GARAGE": "Doppelgarage",
  "OFFICE_LOFT": "Loft",
  "STUDIO": "Atelier",
  "OFFICE": "Büro",
  "OFFICE_FLOOR": "Büroetage",
  "OFFICE_BUILDING": "Bürohaus",
  "OFFICE_CENTRE": "Bürozentrum",
  "OFFICE_STORAGE_BUILDING": "Büro-/ Lagergebäude",
  "SURGERY": "Praxis",
  "SURGERY_FLOOR": "Praxisetage",
  "SURGERY_BUILDING": "Praxishaus",
  "COMMERCIAL_CENTRE": "Gewerbepark",
  "LIVING_AND_COMMERCIAL_BUILDING": "Wohn- und Geschäftsgebäude",
  "OFFICE_AND_COMMERCIAL_BUILDING": "Büro- und Geschäftshaus",
  "BAR_LOUNGE": "Barbetrieb/Lounge",
  "CAFE": "Café",
  "CLUB_DISCO": "Club/Diskothek",
  "GUESTS_HOUSE": "Gästehaus",
  "TAVERN": "Gaststätte",
  "HOTEL": "Hotel",
  "HOTEL_RESIDENCE": "Hotelanwesen",
  "HOTEL_GARNI": "Hotel garni",
  "PENSION": "Pension",
  "RESTAURANT": "Restaurant",
  "SHOWROOM_SPACE": "Ausstellungsfläche",
  "HALL": "Halle",
  "HIGH_LACK_STORAGE": "Hochregallager",
  "INDUSTRY_HALL": "Industriehalle",
  "INDUSTRY_HALL_WITH_OPEN_AREA": "Industriehalle mit Freifläche",
  "COLD_STORAGE": "Kühlhaus",
  "MULTIDECK_CABINET_STORAGE": "Kühlregallager",
  "STORAGE_WITH_OPEN_AREA": "Lager mit Freifläche",
  "STORAGE_AREA": "Lagerfläche",
  "STORAGE_HALL": "Lagerhalle",
  "SERVICE_AREA": "Servicefläche",
  "SHIPPING_STORAGE": "Speditionslager",
  "REPAIR_SHOP": "Werkstatt",
  "SHOPPING_CENTRE": "Einkaufszentrum",
  "FACTORY_OUTLET": "Factory Outlet",
  "DEPARTMENT_STORE": "Kaufhaus",
  "KIOSK": "Kiosk",
  "STORE": "Laden",
  "SELF_SERVICE_MARKET": "SB-Markt",
  "SALES_AREA": "Verkaufsfläche",
  "SALES_HALL": "Verkaufshalle",
  "RESIDENCE": "Anwesen",
  "FARM": "Bauernhof",
  "LEISURE_FACILITY": "Freizeitanlage",
  "COMMERCIAL_UNIT": "Gewerbeeinheit",
  "INDUSTRIAL_AREA": "Gewerbefläche",
  "NURSING_HOME": "Pflegeheim",
  "ASSISTED_LIVING": "Betreutes Wohnen",
  "HORSE_FARM": "Reiterhof",
  "SPECIAL_ESTATE": "Spezialobjekt",
  "VINEYARD": "Weingut",
  "INVEST_FREEHOLD_FLAT": "Eigentumswohnung",
  "INVEST_SINGLE_FAMILY_HOUSE": "Einfamilienhaus",
  "INVEST_MULTI_FAMILY_HOUSE": "Mehrfamilienhaus",
  "INVEST_LIVING_BUSINESS_HOUSE": "Wohn-/Geschäftshaus",
  "INVEST_HOUSING_ESTATE": "Wohnanlage",
  "INVEST_MICRO_APARTMENTS": "Micro-Apartments",
  "INVEST_OFFICE_BUILDING": "Bürohaus",
  "INVEST_COMMERCIAL_BUILDING": "Geschäftshaus",
  "INVEST_OFFICE_AND_COMMERCIAL_BUILDING": "Büro- und Geschäftshaus",
  "INVEST_SHOP_SALES_FLOOR": "Laden/Verkaufsfläche",
  "INVEST_SUPERMARKET": "Supermarkt",
  "INVEST_SHOPPING_CENTRE": "Einkaufszentrum",
  "INVEST_RETAIL_PARK": "Fachmarktzentrum",
  "INVEST_HOTEL": "Hotel",
  "INVEST_BOARDING_HOUSE": "Boarding House",
  "INVEST_SURGERY_BUILDING": "Ärztehaus",
  "INVEST_CLINIC": "Klinik",
  "INVEST_REHAB_CLINIC": "Rehaklinik",
  "INVEST_MEDICAL_SERVICE_CENTER": "MVZ",
  "INVEST_INTEGRATION_ASSISTANCE": "Eingliederungshilfe",
  "INVEST_DAY_NURSERY": "Kita",
  "INVEST_DAY_CARE": "Tagespflege",
  "INVEST_NURSING_HOME": "Pflegeheim",
  "INVEST_ASSISTED_LIVING": "Betreutes Wohnen",
  "INVEST_COMMERCIAL_CENTRE": "Gewerbepark",
  "INVEST_HALL_STORAGE": "Halle/Logistik",
  "INVEST_INDUSTRIAL_PROPERTY": "Produktion/Fertigung",
  "INVEST_CAR_PARK": "Parkhaus",
  "INVEST_PLOT": "Grundstück",
  "INVEST_COMMERCIAL_UNIT": "Gewerbeeinheit",
  "INVEST_OTHER": "Sonstiges",
  "SHORT_TERM_APARTMENT": "Apartment",
  "SHORT_TERM_ROOM": "Zimmer",
  "SHORT_TERM_HOUSE": "Haus",
  "SHORT_TERM_FLAT": "Wohnung",
  "TRADE_SITE": "Grundstück"
}
```


# Task

Task ist ein Sammelbegriff, welches mehrere Arten von Aktivitäten bezeichnet.

Ein Task kann mehreres sein: Eine Notiz, eine Aufgabe, ein Termin, ein Brief, eine SMS, eine Absage, eine Anfrage.

## Das Task (Stamm-)Objekt

| Attribut          | Typ        | Beschreibung                                                                                                                  |
| ----------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| title             | string     | Titel                                                                                                                         |
| note\_type\_id    | integer    | Aktivitätstyp (alle bis auf E-Mail-Typen)                                                                                     |
| body              | string     | Notizfeld für weitere Bemerkungen als HTML                                                                                    |
| client\_ids       | integer\[] | Ein Array von Kontakt-IDs mit welcher die Aktivität verknüpft werden soll. In der Regel will man nur eine Kontakt-ID mitgeben |
| property\_ids     | integer\[] | Ein Array von Objekt-IDs, womit die Aktivität verknüpft werden soll.                                                          |
| project\_ids      | integer\[] | Ein Array von Projekt-IDs, womit die Aktivität verknüpft werden soll.                                                         |
| broker\_id        | integer    | Nutzer, dem der Task zugewiesen werden soll                                                                                   |
| task\_creator\_id | integer    | Ersteller des Tasks                                                                                                           |
| task\_updater\_id | integer    | der Nutzer, der den Task zuletzt bearbeitet hat                                                                               |

#### Falls Task eine Aufgabe ist:

| Attribut     | Typ     | Beschreibung                                                                                |
| ------------ | ------- | ------------------------------------------------------------------------------------------- |
| is\_reminder | boolean | muss `true` sein                                                                            |
| due\_date    | date    | Datum + Uhrzeit der Fälligkeit der Aufgabe                                                  |
| remind\_at   | date    | Datum (vor dem due\_date), wann der Zugewiesene erinnert werden soll (in Form einer E-Mail) |
| done         | boolean | Ist die Aufgabe erledigt?                                                                   |

#### Falls Task ein Termin ist:

| Attribut   | Typ     | Beschreibung                                                                                                                                                                |
| ---------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| is\_event  | boolean | muss `true` sein                                                                                                                                                            |
| starts\_at | date    | Beginn des Termins                                                                                                                                                          |
| ends\_at   | date    | Ende des Termins                                                                                                                                                            |
| private    | boolean | Soll der Termin nur für die Teilnehmer sichtbar sein?                                                                                                                       |
| all\_day   | boolean | Ganztägiger Termin?                                                                                                                                                         |
| location   | string  | Ort des Termins                                                                                                                                                             |
| recurring  | boolean | Wiederkehrender Termin?                                                                                                                                                     |
| rrule      | string  | bei wiederkehrenden Terminen der String, welcher die Regeln festlegt, in welchem Interval der Termin stattfindet. Mehr Infos [hier](https://jakubroztocil.github.io/rrule/) |

### Assoziationen

1. clients
2. units (Property)
3. projects
4. broker
5. task\_creator
6. note\_type
7. attachments

### Anhänge

| Attribut | Typ     | Beschreibung                                   |
| -------- | ------- | ---------------------------------------------- |
| id       | integer | Unique ID des Anhanges                         |
| name     | string  | Name des Anhanges                              |
| url      | string  | URL zum Anhang (nur für wenige Minuten gültig) |

## Task erstellen

<mark style="color:green;">`POST`</mark> `http://api.propstack.de/v1/tasks`

#### Path Parameters

| Name | Type   | Description                            |
| ---- | ------ | -------------------------------------- |
| task | object | siehe oben welche Felder es haben kann |

{% tabs %}
{% tab title="201 ID des erstellten Tasks wird zurückgegeben" %}

```javascript
{
  "id": 50095
}
```

{% endtab %}
{% endtabs %}

Beispiel-Request zum Anlegen eines **Termins**:

```javascript
{
  "task": {
    "is_event": true,
    "title": "Besichtigungstermin",
    "note_type_id": 123,
    "client_ids": [10002],
    "property_ids": [1004],
    "location": "Musterstraße 123, 12345 Berlin",
    "starts_at": "2020-02-20T14:00:00+01:00",
    "ends_at": "2020-02-20T14:30:00+01:00"
  }
}
```

Beispiel-Request zum Anlegen einer **Aufgabe**:

```javascript
{
  "task": {
    "is_reminder": true,
    "title": "Propstacks Dokumenation verstehen",
    "note_type_id": 503,
    "client_ids": [50002],
    "property_ids": [5004],
    "due_date": "2020-02-20T09:00:00+01:00"
  }
}
```

Beispiel-Request zum Anlegen einer **Notiz**:

```javascript
{
  "task": {
    "title": "Anfrage über die Webseite",
    "note_type_id": 720,
    "client_ids": [2006],
    "property_ids": [7006],
    "body": "Folgender Interessent hat angefragt:<br>Name: Hans Peter<br>Email..."
  }
}
```

## Task bearbeiten

<mark style="color:orange;">`PUT`</mark> `https://api.propstack.de/v1/tasks/:id`

Einen vorhandenen Task bearbeiten

**Request body**

| Name | Type   | Description                               |
| ---- | ------ | ----------------------------------------- |
| task | object | siehe alle möglichen Werte für einen Task |

**Hinweis**

Die Payloads, die für die Erstellaktion verwendet werden, können auch für die Aktualisierungsaktion verwendet werden.

{% tabs %}
{% tab title="200" %}

```javascript
```

{% endtab %}
{% endtabs %}

Beispiel-Request zum Bearbeiten eines Tasks:

```javascript
{
    "task": {
        "body": "Neue Anfrage von: Anna Müller"
    }
}
```


# Teams

Nutzer eines Unternehmens können mehreren Teams zugewiesen werden. Teams werden in Propstack hauptsächlich für Nutzerrechte verwendet.

## Teams abrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/departments`

{% tabs %}
{% tab title="200 " %}

```javascript
[
    {
        "id": 1,
        "name": "Geschäftsführung",
        "broker_ids": [1, 2]
    }
]
```

{% endtab %}
{% endtabs %}


# Termine

## Termine abrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/events`

#### Query Parameters

| Name               | Type    | Description                                                                                       |
| ------------------ | ------- | ------------------------------------------------------------------------------------------------- |
| recurring          | boolean | Nur wiederkehrende Termine zurückgeben. Wert für diesen Parameter ist egal, kann einfach `1` sein |
| ends\_at\_after    | string  | Enddatum des Termins soll nach diesem Zeitpunkt sein                                              |
| ends\_at\_before   | string  | Enddatum des Termins soll vor diesem Zeitpunkt sein                                               |
| starts\_at\_after  | string  | Startdatum des Termins soll nach diesem Zeitpunkt sein                                            |
| starts\_at\_before | string  | Startdatum des Termins soll vor diesem Zeitpunkt sein                                             |
| tag                | integer | ID eines Merkmals. Besserer Name wäre `group` gewesen                                             |
| broker             | integer | ID des Nutzers, dem der Termin zugewiesen wurde                                                   |
| note\_type         | integer | ID der Kategorie des Termins                                                                      |
| state              | string  | Phase in welcher sich der Termin befindet. Eines von `neutral`, `took_place`, `cancelled`         |
| client             | integer | ID des Kontaktes                                                                                  |
| property           | integer | ID des Objektes                                                                                   |
| project            | integer | ID des Projektes                                                                                  |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "events": [
        {
            "id": 3273,
            "note_type_id": 56,
            "get_title": "Schöner Termin",
            "broker_id": 1,
            "body": "",
            "location": "",
            "starts_at": "2016-09-29T15:00:46.605+02:00",
            "ends_at": "2016-09-29T15:30:46.605+02:00",
            "state": "neutral",
            "recurring": null,
            "rrule": null,
            "all_day": false,
            "private": false,
            "client": null,
            "property": {
                "id": 1564,
                "name": "WE 127"
            },
            "comment_size": 0,
            "group_ids": [12],
            "title": "Schöner Termin"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

Wie man Termine anlegt, siehe die Dokumentation zu Tasks:

{% content-ref url="/pages/-LZd1U89DNd-U2siHnuU" %}
[Task](/reference/task)
{% endcontent-ref %}


# Webhooks

Mit Webhooks kann man über bestimmte Ereignisse in Propstack benachrichtigt werden, wie z.B. wenn ein Objekt aktualisiert wird.

Wenn ein Event ausgelöst wird, wird die URL unter `target_url` mit einem `POST` aufgerufen und die Daten des Kontaktes bzw. des Objektes mit übergeben.

Bei `client_updated` und `property_updated` wird zusätzlich der Parameter `changed_attributes` übergeben, damit man auf Aktualisierungen von bestimmten Feldern reagieren kann. Beispielsweise will man in seiner eigenen App eine Aktion ausführen, sobald sich der Preis eines Objektes ändert, und nicht bei jedem Update eines Objektes.

**Mögliche Events:**

1. `client_created`
2. `client_updated` (wird auch beim Löschen gefeuert)
3. `property_created`
4. `property_updated` (wird auch beim Löschen gefeuert)
5. `task_created`
6. `task_updated`&#x20;
7. `task_deleted`
8. `client_property_created`
9. `client_property_updated`
10. `client_property_deleted`
11. `project_created`
12. `project_updated`
13. `document_created`
14. `document_updated`
15. `document_deleted`
16. `saved_query_created`
17. `saved_query_updated`
18. `saved_query_deleted`

## Hook erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/hooks`

#### Query Parameters

| Name        | Type   | Description                                                          |
| ----------- | ------ | -------------------------------------------------------------------- |
| target\_url | string | Die URL, die aufgerufen soll, wenn der Hook ausgelöst wird           |
| event       | string | Das Ereignis, worauf man hören möchte. Siehe oben für mögliche Werte |

{% tabs %}
{% tab title="200 ID des erstellten Hooks" %}

```javascript
{
    "id": 123
}
```

{% endtab %}
{% endtabs %}

## Hooks aufrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/hooks`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "hooks": [
        {
            "id": 10,
            "event": "CLIENT_CREATED",
            "target_url": "https://propstack-immobilien.de/ps-hook"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Hook löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/hooks/:id`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "ok": true
}
```

{% endtab %}
{% endtabs %}

## Verifying Webhooks

Verifying webhooks is crucial to ensure the authenticity of the incoming requests and confirm that the data originates from Propstack. To enhance security, we have implemented HMAC (Hash-based Message Authentication Code) verification. This allows developers to confirm that requests come from a genuine source.

When creating a new webhook in the Web UI, there is a field called "Secret Key". Adding a secret key is optional. If it's not set, then no signature will be sent with the webhook. If you do add a secret key, we use this to generate a signature and pass it as a header called `X-Propstack-Signature`.

Here's a simple JavaScript example showcasing how to verify the HMAC signature from your end:

```javascript
const crypto = require('crypto');

function verifySignature(requestBody, signature, secret) {
  const hash = crypto
    .createHmac('sha256', secret)
    .update(requestBody, 'utf8')
    .digest('hex');

  return hash === signature;
}
```

This function generates a hash using the request body and a shared secret, then compares it to the signature provided to validate the request.

#### Verifying HMAC Signature in PHP (WordPress)

For WordPress developers, verifying the HMAC signature can also be done using PHP as shown below:

```php
function verify_signature($requestBody, $signature, $secret) {
  $hash = hash_hmac('sha256', $requestBody, $secret);
  return hash_equals($hash, $signature);
}

// Usage example within a WordPress context
$requestBody = file_get_contents('php://input');
$providedSignature = $_SERVER['HTTP_X_PROPSTACK_SIGNATURE'];
$secret = 'your_secret_key';

if (verify_signature($requestBody, $providedSignature, $secret)) {
  // The request is verified
} else {
  // The request could not be verified
}
```

This PHP function computes an HMAC hash of the request body using the shared secret and compares it to the incoming signature to ensure authenticity.


# Datendump

Einen ganzen Dump ziehen aller relevanten Daten aus Propstack

Propstack bietet die Möglichkeit komplette Datensätze im JSON-Format zu exportieren (Datendump). Mögliche Verwendungszwecke umfassen die Erstellung von detaillierten Auswertungen in Drittanbietersoftware, z.B. PowerBi oder Google Data Studio, oder auch die  Onsite-Datensicherung. Der Datendump wird täglich durchgeführt.

*Es handelt sich hierbei um ein Premium-Feature. Sollten Interesse bestehen, wenden Sie sich bitte an den Vertrieb.*

Der Datendump besteht aus mehreren JSON-Dateien, zu der man über eine Abfrage auf die API weitergeleitet wird. Es stehen folgende Dateien (oder "Tabellen") bereit:

* Termine (appointments)
* Nutzer (brokers)
* Absagen (cancelations)
* Provisionssplits (commission\_splits)
* Kontakte (contacts)
* Deal-Pipelines inkl. Deal-Phasen (deal\_pipelines)
* Deals (deals)
* Teams (departments)
* Dokumente (documents)
* Bilder (images)
* Emails (messages)
* Notizen (notes)
* Nachweise (policies)
* Projekte (projects)
* Objekte (properties)
* Objekt-Texte inkl. Übersetungen (property\_details)
* Beziehungen (relationships)
* Suchprofile (saved\_queries)
* Mandaten (teams)
* Aufgaben (todos)

Weiterhin gibt es einige Key-Value-Objekte mit den Feldern id und name:

* Merkmale (groups)
* Kontakt-Quellen (contact\_sources)
* Speichergründe (contact\_reasons)
* Kontakt-Status (contact\_statuses)
* Absagegründe (reservation\_reasons)
* Objekt-Status (property\_statuses)

Die Daten variieren bzgl. der angelegten Custom Felder.

```aspnet
https://api.propstack.de/v1/datadump/*
```

## Kontakte

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/datadump/contacts`

{% tabs %}
{% tab title="200 " %}

```javascript
[
  {
    "academic_title": null,
    "active_reservations": [],
    "archived": false,
    "birth_name": null,
    "broker_id": 2,
    "broker_ids": [],
    "cancelation_reason_ids": [],
    "canceled_reservations": [],
    "children_count": 0,
    "client_reason_id": null,
    "client_source_id": 5,
    "client_status_id": 3,
    "commercial": false,
    "company": "Musterfirma",
    "confirmed_at": null,
    "contact_sync_broker_ids": null,
    "cp_delete_request_date": null,
    "cp_profile_updated_at": null,
    "created_at": "2021-07-04T22:00:00",
    "create_notification": false,
    "creator_id": null,
    "customer_protection_partner": false,
    "deleted_at": null,
    "department_ids": [],
    "description": null,
    "dob": "2002-11-10",
    "email": null,
    "emails": [
      "test@example.com"
    ],
    "equity": null,
    "first_name": "Max",
    "gdpr_status": 0,
    "has_protection": false,
    "home_address": null,
    "home_cell": "+49-1231-12312321",
    "home_city": "Berlin",
    "home_country": "Deutschland",
    "home_fax": null,
    "home_house_number": "76",
    "home_phone": null,
    "home_street": "Musterstrasse",
    "home_url": "example.com",
    "home_zip_code": "42573",
    "id": 109,
    "identity_number": null,
    "issuing_authority": null,
    "item_id": 109,
    "keep_data_till": null,
    "last_contact_at": "2021-06-25T22:00:00",
    "last_logged_in_at": null,
    "last_name": "Mustermann",
    "locale": null,
    "nationality": null,
    "newsletter": null,
    "office_address": null,
    "office_cell": null,
    "office_city": null,
    "office_country": null,
    "office_fax": null,
    "office_house_number": null,
    "office_phone": null,
    "office_street": null,
    "office_url": null,
    "office_zip_code": null,
    "old_crm_id": null,
    "online": false,
    "parent_id": null,
    "photo": null,
    "policy_accepted_at": null,
    "position": "Manager",
    "preferred_contact_channel": "account_email",
    "preferred_contact_time": null,
    "property_mailing_wanted": false,
    "rating": 0,
    "relationship": null,
    "salutation": "mr",
    "score": 0,
    "second_broker_id": null,
    "tags": [],
    "third_broker_id": null,
    "time_zone": null,
    "updated_at": "2021-07-12T10:43:32.805814",
    "updater_id": null,
    "mvsigned": false,
    "hvsigned": false,
    "newsletter_unsubscribed": false,
    "from_website": false,
    "locked": false,
    "home_address_validated": false,
    "status": "Kunde",
    "source": "Facebook Ads",
    ...
  }
]
```

{% endtab %}
{% endtabs %}

## Objekte

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/datadump/properties`

{% tabs %}
{% tab title="200 " %}

```javascript
[
  {
    "address": null,
    "administrative_area_level_1": null,
    "archived": false,
    "base_rent": null,
    "broker_id": 3,
    "brokers": [
      1
    ],
    "city": "Berlin",
    "copying": false,
    "country": "DEU",
    "courtage": null,
    "created_at": "2021-07-12T10:43:40.238882",
    "creator_id": null,
    "deleted_at": null,
    "department_ids": [],
    "exposee_id": null,
    "featured": false,
    "for_bidding": false,
    "gastronomy_type": null,
    "has_courtage": false,
    "hide_address": true,
    "house_number": "90",
    "id": 1,
    "industry_type": null,
    "investment_type": null,
    "is24_id": null,
    "lat": 52.59733,
    "living_space": 127,
    "lng": 13.36681,
    "locale": null,
    "location_id": 3,
    "marketing_type": "BUY",
    "net_floor_space": null,
    "number_of_rooms": 5,
    "object_type": "LIVING",
    "office_type": null,
    "old_crm_id": null,
    "plot_area": null,
    "price": 425000,
    "price_interval_type": null,
    "project_id": 1,
    "property_status_id": 6,
    "rs_type": "APARTMENT",
    "short_term_accomodation_type": null,
    "special_purpose_type": null,
    "start_rental_date": null,
    "statistics": "{}",
    "street": "Musterstrasse",
    "sublocality_level_1": null,
    "total_floor_space": null,
    "unit_id": "1000",
    "updated_at": "2021-07-12T10:43:40.238882",
    "zip_code": "80896",
    "lift": false,
    "ramp": false,
    "floor": 3,
    "sauna": false,
    "cellar": false,
    "garden": false,
    "loggia": false,
    "rented": true,
    "balcony": false,
    "chimney": false,
    "terrace": false,
    "monument": false,
    "auto_lift": false,
    "condition": "DERELICT",
    "storeroom": false,
    "demolition": false,
    "goods_lift": false,
    "non_smoker": false,
    "total_rent": 1784.3500000000001,
    "has_canteen": false,
    "lodger_flat": false,
    "other_costs": 317.5,
    "alarm_system": false,
    "barrier_free": false,
    "crane_runway": false,
    "firing_types": "GAS",
    "guest_toilet": false,
    "heating_type": "NIGHT_STORAGE_HEATER",
    "high_voltage": false,
    "rent_subsidy": 1016,
    "flooring_type": [
      "TERRACOTTA"
    ],
    "has_furniture": false,
    "heating_costs": 190.5,
    "rental_income": 13030.2,
    "swimming_pool": false,
    "wellness_area": false,
    "winter_garden": false,
    "apartment_type": "ATTIKA",
    "rotation_fixed": false,
    "service_charge": 508,
    "air_conditioning": false,
    "built_in_kitchen": false,
    "interior_quality": "SIMPLE",
    "kitchen_complete": false,
    "number_of_floors": 5,
    "price_on_inquiry": false,
    "construction_year": 1926,
    "conservation_areas": false,
    "building_permission": false,
    "flat_share_suitable": false,
    "maintenance_reserve": 381,
    "preliminary_enquiry": false,
    "landing_page_blocked": false,
    "short_term_constructible": false,
    "construction_year_unknown": false,
    "summer_residence_practical": false,
    "energy_certificate_availability": "NOT_REQUIRED",
    "heating_costs_in_service_charge": false,
    "certificate_of_eligibility_needed": false,
    "energy_consumption_contains_warm_water": false,
    "status": "Inaktiv",
    ...
  }
]
```

{% endtab %}
{% endtabs %}

## Termine

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/datadump/appointments`

{% tabs %}
{% tab title="200 " %}

```javascript
[
  {
    "id": 368,
    "created_at": "2021-07-20T11:12:45.178614",
    "note_type_id": 6,
    "starts_at": "2021-07-20T11:40:00",
    "ends_at": "2021-07-20T12:10:00",
    "title": "Test",
    "body": "<p>Test</p>",
    "broker_id": 3,
    "state": 0,
    "clients_ids": [
      1
    ],
    "properties_ids": [
      18
    ],
    "projects_ids": [
      2
    ],
    "rrule": null,
    "is_campaign": false,
    "clients_status": [],
    "send_reminders": false,
    ...
  }
]
```

{% endtab %}
{% endtabs %}

## Absagen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/datadump/cancelations`

{% tabs %}
{% tab title="200 " %}

```javascript
[
  {
    "id": 365,
    "created_at": "2021-07-20T11:08:20.841356",
    "note_type_id": 11,
    "starts_at": "2021-07-19T11:40:00",
    "ends_at": "2021-07-19T16:10:00",
    "broker_id": 4,
    "state": 0,
    "client_ids": [
      28
    ],
    "property_ids": [
      3
    ],
    "project_ids": [
      1
    ],
    "reservation_reason_id": 1m
    ...
  }
]
```

{% endtab %}
{% endtabs %}

## Deals

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/datadump/deals`

{% tabs %}
{% tab title="200 " %}

```javascript
[
  {
    "id": 1,
    "created_at": "2021-07-12T10:43:57.738701",
    "updated_at": "2021-07-12T10:43:57.738701",
    "deal_stage_id": 1,
    "deal_pipeline_id": 1,
    "deal_stage_chance": 1,
    "reservation_reason_id": 1,
    "client_source_id": 1,
    "broker_id": 1,
    "client_id": 63,
    "property_id": 30,
    "project_id": 1,
    "start_date": "2021-07-19",
    "price": 500000.00,
    ...
  }
]
```

{% endtab %}
{% endtabs %}


# Notizen

## Notizen abrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/notes`

This endpoint allows you to get free cakes.

#### Query Parameters

| Name       | Type    | Description                                      |
| ---------- | ------- | ------------------------------------------------ |
| tag        | integer | ID des Merkmals                                  |
| broker     | integer | ID des Benutzers, dem die Notiz zugewiesen wurde |
| note\_type | integer | ID der Notiz-Kategorie                           |
| client     | integer | ID des Kontaktes                                 |
| property   | integer | ID des Objektes                                  |
| project    | integer | ID des Projektes                                 |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "notes": [
        {
            "id": 3273,
            "note_type_id": 56,
            "get_title": "Schöne Notiz",
            "broker_id": 1,
            "body": "",
            "client": null,
            "property": {
                "id": 1564,
                "name": "WE 127"
            },
            "comment_size": 0,
            "group_ids": [12],
            "title": "Schöne Notiz"
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# Zusammenfassung

Die Webseite an Propstack anbinden

In diesem Artikel wird beschrieben, wie man die typischen Funktionen auf der Webseite in Bezug auf Propstack abbilden kann.

### **Objekte übertragen**

In erster Linie möchte man die Objekte aus Propstack auf die eigene Webseite übertragen und dort darstellen.

Wer bisher Objekte auf Basis von OpenImmo übertragen hat (z. B. über eine bestehende Webseite oder ein Plugin), kann dies weiterhin problemlos nutzen. Dazu muss die Webseite lediglich als „Portal“ in Propstack hinterlegt werden, und die Objekte werden genauso übertragen wie bei anderen Portalen wie Immowelt und Co. Wer eine neue Webseite entwickeln möchte, kann dies mit einem erfahrenen Dienstleister umsetzen. Verschiedene Anbieter bieten moderne und leistungsfähige Webseiten zu attraktiven Preisen an, die ebenfalls über OpenImmo anbindbar sind.

Möchte man eine Webseite selber entwickeln und kein Openimmo Plugin nutzen, kann man jederzeit auf Propstacks API direkt zugreifen, was von unserer Seite nichts kostet, aber mit höherem Entwicklungsaufwand auf Ihrer Seite verbunden ist. Dazu würde man sich folgende Seite genauer anschauen (Programmierkenntnisse vorausgesetzt):

{% content-ref url="/pages/-LQi1Lokkgk9TXDzV3zz" %}
[Objekte](/reference/objekte)
{% endcontent-ref %}

### Projekte übertragen

Die einzige Möglichkeit Immobilienprojekte auf die Webseite zu übertragen ist über unsere API. Wie man die Projekte aus Propstack über die API ausliest wird hier beschrieben:

{% content-ref url="/pages/-LNa2VBlW\_3rFOGgy2TW" %}
[Projekte](/reference/projects)
{% endcontent-ref %}

### Anfragen an Propstack übermitteln

Wenn ein Interessent zu einer Immobilie anfragt oder auch nur eine allgemeine Kontaktanfrage stellt, ist der einfachste Weg, die Daten aus der Anfrage **per E-Mail** an Propstack zu übermitteln. Dabei schickt man eine E-Mail an eine E-Mailadresse, die in Propstack verbunden ist, in der Regel lautet die E-Mailadresse <anfrage@muster-immobilien.de> oder ähnliches. Damit Propstack die E-Mail automatisch auslesen kann,  muss diese E-Mail in einem bestimmten Format sein. Auf folgender Seite wird dies genauer beschrieben:

{% content-ref url="/pages/-LdE4uVpGDjzVaKFZpGL" %}
[Interessenten-Anfragen](/webseite/anfragen)
{% endcontent-ref %}

### Online Wertermittlung für Eigentümer

Bei der Akquise von neuen Objekten kann ein Online-Wertermittlung hilfreich sein. Dieses Tool kennt man vor allem von [Sprengnetter](https://shop.sprengnetter.de/Lead-Immobilienrechner-fuer-Ihre-Website/SW10139.1) oder vom [IBB Institut](https://www.iib-institut.de/loesungen/wohnmarktanalyse).

Propstack bietet ebenfalls so ein Tool für die eigene Webseite an, dieser nennt sich Leadfisher. Die eigentliche Bewertung der Immobilie kommt von unserem Partner Sprengnetter. Den Leadfisher kann man als extra Paket buchen. Sie können sich gerne bei weiteren Fragen direkt bei unserem Sales Team über die E-Mailadresse <sales@propstack.de> melden.

### Suchanfragen aufnehmen

Suchanfragen funktionieren vom Prinzip her genau so wie die Anfragen zu einer Immobilie. Man legt ein Formular an auf der Webseite, mit den Suchprofil-Feldern, die für einen relevant sind. Die Werte versendet man dann per E-Mail an Propstack und die E-Mail muss so formatiert sein, dass Propstack die Werte automatisch auslesen kann, wie es hier beschrieben ist:

{% content-ref url="/pages/-LdE4uVpGDjzVaKFZpGL" %}
[Interessenten-Anfragen](/webseite/anfragen)
{% endcontent-ref %}


# Interessenten-Anfragen

In dem Artikel wird beschrieben, wie man Anfragen von der Webseite automatisch in Propstack einlesen kann.

## XML-Datei mitschicken

Wenn jemand auf der Homepage ein Formular ausfüllt, möchte man in der Regel, dass dieser Kontakt in Propstack erfasst wird, genau so wie es auch bei den Immobilienportalen der Fall ist.

Die Immobilienportale schicken eine E-Mail mit den Daten zum Interessenten in einer XML-Datei, die im Anhang dabei ist. Die XML-Datei ist im Openimmo-Format und heißt in der Regel "kontakt-xml" oder "kontaktanfrage.xml".

Propstack kann diese XML-Dateien beim Empfangen der E-Mail auslesen und anhand dessen den Kontakt dann anlegen.

Das gleiche Prinzip kann man auch auf der Webseite anwenden, das nach dem Ausfüllen eines Formulars eine E-Mail an den Makler verschickt wird mit der XML-Datei im Anhang.

{% file src="/files/-LdE6xVFS3GnhYi7pEv5" %}
Openimmo-XML Datei (Muster)
{% endfile %}

Möchte man UTM-Parameter mitschicken würde die XML-Datei so aussehen:

{% file src="/files/-MO0VNfRZALMKxaOMvFv" %}
Openimmo-XML Datei mit UTM Parametern
{% endfile %}

## Mail-Inhalt formatieren

Eine alternative und **deutlich einfachere Lösung** zur XML-Datei ist den Inhalt der E-Mail so zu formatieren, dass Propstack leicht den Mail-Inhalt nach Infos zum Interessenten auslesen kann.

Dafür muss im Mail-Inhalt zunächst ein "Container" existieren, der exakt folgende ID besitzt: "ps-kontaktanfrage". Man kann diese ID z.B. einfach einem `div`-Tag geben.

Dann müssen im Mail-Inhalt die nötigen Infos mit einem HTML-Tag umhüllt werden und eine bestimmte ID jeweils vergeben werden, damit Propstack die Info in das richtige Feld im Kontakt hinterlegt.

Ein Muster, wie der E-Mail Inhalt aussehen kann, sieht man hier:

{% file src="/files/5azxgBCO9cTTTMwNFEmO" %}
anfrage-muster.html
{% endfile %}

Im Prinzip müssen die Stellen nur mit einem `<span>`-Tag umschlossen und dem Tag eine `id` vergeben werden, das wars im Prinzip schon.

Es können auch Custom Felder über den E-Mail Body übergeben werden. Dafür muss der Feldname des Custom Feldes mit einem `client_cf_` Prefix verwendet werden. Der eingegebene Wert wird ist dann in der Propstack Automatisierung **Neue Portalanfrage** verfügbar.

| ID                                  | Beschreibung                                          |
| ----------------------------------- | ----------------------------------------------------- |
| client\_salutation                  | Anrede. eines von `mr` und `ms`                       |
| client\_academic\_title             | Akad. Titel des Kontaktes                             |
| client\_first\_name                 | Vorname                                               |
| client\_last\_name                  | Nachname                                              |
| client\_email                       | E-Mail-Adresse                                        |
| client\_phone                       | Telefonnummer                                         |
| client\_street                      | Straße + Hausnummer                                   |
| client\_zip\_code                   | PLZ                                                   |
| client\_city                        | Stadt                                                 |
| client\_country                     | Land                                                  |
| client\_locale                      | Sprache des Interessenten. Mögliche Werte: de, en, es |
| client\_status                      | Kontakt-Status, z.B. Interessent                      |
| client\_accep&#x74;*\_*&#x63;ontact | Kontakterlaubnis bestätigt (ja/nein)                  |
| client\_newsletter                  | Newsletter gewünscht (ja/nein)                        |
| client\_property\_mailing\_wanted   | Immobilienmailings gewünscht (ja/nein)                |
| client\_cf\_fieldname               | Kontakt-Custom Feld                                   |
| body                                | Bemerkung zum Kontakt                                 |
| property\_id                        | Propstack-ID des angefragten Objektes                 |
| project\_id                         | Propstack-ID des angefragten Projektes                |

### Suchanfragen

In Propstack kann man auch neben den Kontaktdaten die Suchanfrage des Kontaktes automatisch einlesen lassen. Dafür nutzt man die "Mail-Inhalt"-Lösung, wie oben beschrieben und erweitert den E-Mail-Inhalt um die Felder der Suchanfrage.

Folgende Felder können in der E-Mail mitgegeben werden:

| ID                                 | Typ       | Mögliche Werte                                                 |
| ---------------------------------- | --------- | -------------------------------------------------------------- |
| query\_locations                   | string\[] |                                                                |
| query\_cities                      | string\[] |                                                                |
| query\_regions                     | string\[] |                                                                |
| query\_price                       | float     |                                                                |
| query\_price\_to                   | float     |                                                                |
| query\_base\_rent                  | float     |                                                                |
| query\_base\_rent\_to              | float     |                                                                |
| query\_living\_space               | float     |                                                                |
| query\_living\_space\_to           | float     |                                                                |
| query\_total\_floor\_space         | float     |                                                                |
| query\_total\_floor\_space\_to     | float     |                                                                |
| query\_number\_of\_rooms           | float     |                                                                |
| query\_number\_of\_rooms\_to       | float     |                                                                |
| query\_number\_of\_bedrooms        | integer   |                                                                |
| query\_number\_of\_bedrooms\_to    | integer   |                                                                |
| query\_number\_of\_bath\_rooms     | integer   |                                                                |
| query\_number\_of\_bath\_rooms\_to | integer   |                                                                |
| query\_marketing\_type             | string    | BUY,RENT                                                       |
| query\_rs\_types                   | string\[] | APARTMENT,HOUSE,TRADE\_SITE,OFFICE,GASTRONOMY,STORE,INVESTMENT |
| query\_rs\_categories              | string\[] |                                                                |
| query\_lift                        | boolean   |                                                                |
| query\_balcony                     | boolean   |                                                                |
| query\_garden                      | boolean   |                                                                |
| query\_built\_in\_kitchen          | boolean   |                                                                |
| query\_cellar                      | boolean   |                                                                |
| query\_rented                      | boolean   |                                                                |
| query\_note                        | string    |                                                                |

Hier wieder eine Muster-HTML, wie es aussehen würde, wenn man ein Suchprofil mitgeben möchte:

{% file src="/files/LlxH7xWXshYMpsVBhO0a" %}
Suchprofil-Muster-HTML
{% endfile %}


# Eigentümer-Anfragen

Anfragen von Leads (Eigentümern) von Propstack automatisch verarbeiten lassen

In diesem Artikel wird erklärt, wie man Eigentümer-Anfragen formatieren muss, damit Propstack diese automatisch verarbeiten kann, analog zu Anfragen von Immoscout, Immowelt oder Aroundhome.

### Formatierung des E-Mail-Inhaltes

Im E-Mail-Inhalt muss ein "Container" existieren, der exakt folgende ID besitzt: `ps-immo-valuation`. Man kann diese ID z.B. einfach dem `body`-Tag geben.

Dann müssen im Mail-Inhalt die nötigen Infos mit einem HTML-Tag umhüllt werden und eine bestimmte ID jeweils vergeben werden, damit Propstack die Info in das richtige Feld im Kontakt hinterlegt.

Eine Muster-E-Mail mit den Eigentümerdaten, wie der E-Mail Inhalt aussehen kann, sieht man hier:

{% file src="/files/NPICXuu1E2SbtfwY9H5N" %}
Beispiel-Email für Eigentümer-Anfrage
{% endfile %}

Zusätzlich zum Eigentümer können auch die Objektdaten übergeben werden, damit Propstack das Objekt direkt anlegt.

Eine Muster-E-Mail, mit Objektdaten:

{% file src="/files/fGQ1HzitckEV3vN7ohIe" %}


# Newsletter-Anmeldung

Anleitung zum Entwickeln eine Newsletter-Registrierung auf der Webseite

In diesem Artikel wird ein Prozess vorgeschlagen, wie man Besucher der Webseite zu einem Newsletter anmeldet und die dazugehörigen Daten in Propstack hinterlegt.

### Schritt 1: Newsletter-Formular

Auf der Webseite stellt man ein Formular bereit. Propstack hat kein Widget dafür oder ähnliches. Dafür ist man das Gestaltung ganz frei. Meistens besteht ein Newsletter-Formular nur aus einem Feld, der E-Mail-Adresse. Es können aber auch weitere Felder, wie Anrede, Vorname, Nachname hinzugefügt werden.

### Schritt 2: Abschicken des Formulars

Wenn das Newsletter-Formular abgeschickt wird, ruft man im Hintergrund die API von Propstack auf. Mit den Daten des Formulars legt man einen Kontakt in Propstack an. [Hier](/reference/kontakte#kontakt-erstellen) wird genauer erklärt, wie die API dafür aufgerufen werden muss. Ein möglicher Payload könnte so aussehen:

```
POST /v1/contacts
Body:
{
  "client": {
    "email": "max.muster@gmail.com"
  }
}
```

So wird der Newsletter-Abonnent in Propstack als Kontakt hinterlegt. Falls ein Kontakt mit der Emailadresse bereits existiert, wird **kein** neuer Kontakt angelegt.

### Schritt 3: Double Opt In

Im nächsten Schritt muss die E-Mail-Adresse des Abonnenten bestätigt werden. Das macht man, indem man dem Abonnenten eine E-Mail schickt, mit einem Link zum Bestätigen der Newsletter-Anmeldung. So verifiziert der Abonnent, dass die angegebene E-Mail-Adresse auch wirklich seine ist.

Über die API von Propstack kann man E-Mails über das E-Mail-Konto eines Nutzers versenden. [Hier](/reference/e-mails#e-mail-senden) wird genauer beschrieben wie das geht. Den Inhalt der E-Mail hinterlegt man in einem Textbaustein, den man in der Verwaltung in Propstack erstellt.

Der Inhalt könnte beispielsweise so aussehen:

> **Betreff:** Bitte bestätigen Sie Ihre Newsletter Anmeldung
>
> {{ anrede }}
>
> vielen Dank für Ihr Interesse an unserem Newsletter.
>
> Um Ihre Anmeldung abzuschließen, bestätigen Sie bitte durch einen Klick auf den folgenden Aktivierungs-Link, dass Sie sich selbst für den kostenlosen Newsletter angemeldet haben und zukünftig durch {{ konto.name }} per E-Mail über Neuigkeiten in der Immobilienbranche informiert werden wollen.
>
> {{ kontakt\_link }}
>
> Nach dem Klick auf den Link werden Sie in einem Browserfenster über die erfolgreiche Aktivierung informiert.
>
> Sie haben jederzeit die Möglichkeit den Newsletter wieder abzubestellen. Dies können Sie uns persönlich mitteilen oder sich selbst über einen in unserem Newsletter befindenden Link abmelden.

Über die {{ kontakt\_link }} Variable werden im Kontakt die Schalter "Kontaktierung erlaubt", "Immobilienmailings gewünscht" und "Newsletter gewüsncht" aktiviert bzw. auf "ja" gestellt. Zudem wird eine Aktivität im Kontakt hinterlegt, dass er auf den Link in der E-Mail geklickt hat.

Der Request, um eine E-Mail zu senden, könnte wie folgt aussehen:

```
POST /v1/messages
Body:
{
  "message": {
    "broker_id": 123,
    "to": ["max.muster@gmail.com"],
    "snippet_id": 12345
  }
}
```

`123` ist die ID des Nutzers in Propstack, über den die E-Mail versendet werden soll. Meistens nimmt man hier einen Nutzer der ein info@ E-Mail-Konto verbunden hat.

`12345` ist die ID des Textbausteines, welcher versendet werden soll.


# Kunden-Registrierung

Anleitung zum Entwickeln eines Kundenbereichs auf der Webseite

Die API von Propstack kann dabei helfen, einen Kundenbereich für Interessenten oder Eigentümer auf der eigenen Homepage zu entwickeln. Propstack bietet dafür mehrere API-Endpoints an um einen Registrierungsprozess abzubilden.&#x20;

Da Propstack keine E-Mails verschickt oder Landing Pages für die Registrierung anbietet, ist immer noch viel Entwicklungsaufwand seitens der Homepage nötig.

## Registrierungsprozess

### Registrierungsformular

Zum Erstellen eines neuen Kundenkontos würde es ein Formular auf der Homepage geben, in der man mindestens eine E-Mailadresse und Passwort eingibt, meistens aber noch einen Vor- und Nachnamen.

![Beispiel-Registrierungsformular](/files/-MIZR33xiMF5NWEG8T31)

Beim Registrieren wird ein neuer Kontakt in Propstack angelegt, bzw. ein vorhandener Kontakt (anhand der angegebenen E-Mail-Adresse) gefunden und ein Kundenkonto angelegt.

Wenn dieses Formular abgeschickt wird, werden die Daten an Propstack übertragen, an folgenden API-Endpoint:

```javascript
POST /v1/contacts/register

{
  "client": {
    "email": "foo.bar@example.de",
    "password": "12345678",
    "password_confirmation": "12345678",
    "first_name": "Foo",
    "last_name": "Bar",
    "salutation": "mr"
  }
}
```

Als Antwort von propstack wird ein Token geliefert, welcher für den Double Opt-In verwendet wird:

```javascript
{
  "confirmation_token": "abc"
}
```

### Bestätigen des Kundenkontos

Das Kundenkonto wurde angelegt, muss aber noch bestätigt werden (Double Opt-In).  Dafür schickt man dem Kunden eine E-Mail, zum Bestätigen des angelegten Kundenkontos.

In der E-Mail muss sich ein Link/Button befinden, den der Kunde anklicken muss, damit die Bestätigung ausgelöst wird. Die URL hinter dem Link muss den Token aus dem letzten Schritt beinhalten. Die URL könnte in etwa so aussehen:

```bash
https://www.meine-immobilien.de/confirm/abc
```

Wenn der Kunde diese URL aufgerufen hat, würde die Homepage den Token (`abc`) aus der URL auslesen und damit einen API-Request an Propstack machen:

```bash
POST /v1/contacts/confirm

{
  "confirmation_token": "abc"
}
```

Propstack bestätigt dann bei sich das Kundenkonto für den Kontakt, damit er sich zukünftig anmelden kann. Als Antwort erhält man von Propstack die ID und den Namen des Kontaktes:

```javascript
{
  "client": {
    "id": 123,
    "name": "Foo Bar"
  }
}
```

### Einloggen in den Kundenbereich

Das eigentliche Einloggen muss die Webseite mit Hilfe von z.B. Cookies lösen. In einem Cookie würde man mindestens die Propstack-ID des Kontaktes (im oberen Beispiel die `123`) oder ein ganzes JSON abspeichern.

Zur Sicherheit sollte aber auf jeden Fall die Infos in dem Cookie verschlüsselt sein und nicht einfach die Kontakt-ID als Klartext stehen! Um die Daten sicher in Cookies zu speichern, ist die Nutzung von [JWT](https://developer.okta.com/blog/2019/02/04/create-and-verify-jwts-in-php) empfehlenswert.

Nach dem Bestätigen des Kundenkontos kann man die Response von Propstack nehmen und zum Einloggen nutzen.

Wenn ein Kunde bereits ein Kundenkonto hat und sich nun anmelden möchte, gibt es einen Endpoint zum Verifizieren der E-Mail-Adresse und des Passworts:

```javascript
POST /v1/contacts/login

{
  "credentials": {
    "email": "foo.bar@example.de",
    "password": "12345678"
  }
}
```

Wenn die Login-Daten stimmen, erhält man die gleiche Antwort wie nach dem Double Opt-In, welche man wieder zu  Erstellen eines Cookies verwenden würde:

```javascript
{
  "client": {
    "id": 123,
    "name": "Foo Bar"
  }
}
```

### Passwort zurücksetzen

Es kann durchaus passieren, dass ein Kunde sein Passwort für den Kundenbereich vergessen hat. Deshalb gibt es über die API auch die Möglichkeit das Passwort für einen Kunden zurücksetzen zu können.

Dafür muss die Homepage zunächst wieder ein Formular anbieten, in der man nur eine E-Mail-Adresse angeben muss

```javascript
POST /v1/contacts/send_password_reset

{
  "email": "foo.bar@example.de"
}
```

Wenn ein Kontakt mit der angegebenen E-Mail-Adresse gefunden wird, beginnt der Prozess zum Zurücksetzen des Passworts. In der Antwort befindet sich dafür ein Token, um später das Vergeben eines neuen Passworts zu verifizieren:

```javascript
{
  "token": "xyz"
}
```

Dieser Token wird ähnlich wie beim Double Opt-In verwendet, um eine E-Mail an den Kunden zu senden, mit einem Link, der diesen Token in der URL beinhaltet, z.B.:

```bash
https://www.meine-immobilien.de/reset-password/xyz
```

![Beispiel-Formular zum Vergeben eines neuen Passworts](/files/-MIZe3I8cvVJCDPcMkey)

Auf dieser Seite, die von der Homepage bereitgestellt wird, sollte sich ein kleines Formular befinden, in der der Kontakt ein neues Passwort vergeben kann.

Das neue Passwort wird dann zusammen mit dem Token aus der vorherigen URL an Propstack mitgeschickt, damit Propstack das Passwort für den Kontakt aktualisiert:

```javascript
POST /v1/contats/xyz/reset_password

{
  "client": {
    "password": "87654321",
    "password_confirmation": "87654321"
  }
}
```

Wenn die Aktualisierung des Passworts erfolgreich war, erhält man wieder die gleiche Antwort wie bei einem Login, welche man nutzen kann, um den Kontakt direkt anzumelden ohne noch mal die Zugangsdaten eingeben zu müssen.

```javascript
{
  "client": {
    "id": 123,
    "name": "Foo Bar"
  }
}
```

## Zusammenfassung

Mit Hilfe von 2 Endpoints kann man ein neues Kundenkonto erstellen und bestätigen. Es gibt einen Endpoint zum Anmelden in ein Kundenkonto. Für das Zurücksetzen eines Passworts gibt es ebenfalls 2 Endpoints

Propstack bietet keine Formulare zum Registrieren/Anmelden an, und verschickt auch keine E-Mails zum Double Opt-In oder Zurücksetzen des Passworts; das man auf der Homepage selber entwickeln. So hat man komplette Freiheit was das Design der E-Mails und der Formulare angeht.


# Projekt Landing-Pages

Wie man ein eigenes Template für Projekt Landing-Pages erstellt

Ein Template für eine Projekt Landing-Page ist eine einfache HTML-Datei, dessen Inhalt man nimmt und in Propstack eingibt.

Damit die Templates dynamisch sind, d.h. je nach Projekt andere Daten anzeigen, muss eine Template-Engine benutzt werden. Propstack nutzt dafür [Liquid](https://shopify.github.io/liquid/) von Shopify.

Im Template hat man Zugriff auf folgende Daten (in JSON-Format dargestellt):

```javascript
{
  "project": {
    "id": "123",
    "name": "Templiner Park",
    "street": "Musterstraße",
    "houseNumber": "12",
    "zipCode": "12345",
    "city": "Berlin",
    "country": "DEU",
    "lat": 50.7010491,
    "lng": 12.6461906,
    "logoUrl": null,
    "broker": {
      "id": "4010",
      "name": "Lars Heckmann",
      "email": "heckmann@muster-immobilien.de",
      "phone": "030 123 456 89",
      "avatarUrl": "https://images.propstack.de/..."
    },
    "title": "",
    "courtage": "3,57% inkl. Mwst.",
    "courtageNote": "Die Courtage beträgt für beide Parteien (Eigentümer und Käufer) jeweils die gleiche Höhe auf den beurkundeten Kaufpreis inkl. der gesetzlichen Umsatzsteuer",
    "subHeadline": "...",
    "tagline": "...",
    "descriptionNote": "Phosfluorescently incentivize orthogonal ROI with highly efficient e-business.\n\nMonotonectally formulate equity invested mindshare...",
    "furnishingNote": "",
    "locationNote": "Authoritatively generate customer directed interfaces before visionary solutions.\n\nDramatically procrastinate parallel supply chains...",
    "longDescriptionNote": "",
    "longFurnishingNote": "",
    "longLocationNote": "",
    "constructionYear": 2018,
    "showUnitsOnLandingPage": true,
    "enableLinkingToUnitsLp": true,
    "properties": [
      {
        "objectType": "LIVING",
        "rsType": "APARTMENT",
        "unitId": "WE 01",
        "categoryLabel": "Etagenwohnung",
        "floor": "1",
        "floorLabel": "1. OG",
        "numberOfFloors": 5,
        "numberOfRooms": 3.0,
        "numberOfParkingSpaces": 1,
        "numberOfBedRooms": 2,
        "livingSpace": 104.98,
        "propertySpaceValue": 104.98,
        "usableFloorSpace": null,
        "minDivisible": null,
        "plotArea": null,
        "rentSubsidy": 320,
        "rented": false,
        "baseRent": null,
        "price": 549000.0,
        "pricePerSqm": 5229.57,
        "titleImageUrl": "https://...",
        "floorplans": [
          {
            "url": "...",
            "title": "Grundriss.pdf"
          }
        ],
        "propertyStatus": {
          "name": "Verkauft",
          "nonpublic": true
        },
        "lp_url": "https://crm.propstack.de/..."
      }
    ],
    "images": [
      {
        "photoUrl": "https://images.propstack.de/...",
        "title": "Visualisierung Projekt"
      },
      {
        "photoUrl": "https://images.propstack.de/...",
        "title": "Wohnzimmer Beispielwohnung"
      }
    ],
    "documents": [
      {
        "title": "Energieausweis",
        "url": "...",
        "isExposee": false
      },
      {
        "title": "Exposé.pdf",
        "url": "...",
        "isExposee": true
      }
    ],
    "links": [
      {
        "url": "...",
        "title": "360° Rundgang Beispielwohnung",
        "isEmbedable": true
      },
      {
        "url": "...",
        "title": "Mit welchem Budget können Sie rechnen?",
        "isEmbedable": false
      }
    ],
    "shop": {
      "logoUrl": "...",
      "imprintNote": null,
      "termsNote": null,
      "privacyNote": null,
      "homepage": "http://muster-immobilien.de",
      "name": "Muster Immobilien GmbH"
    }
  },
  "broker": {
    "id": "4010",
    "name": "Lars Heckmann",
    "email": "heckmann@muster-immobilien.de",
    "phone": "030 123 456 89",
    "avatarUrl": "https://images.propstack.de/..."
  },
  "locale": "de",
  "t": {
    "navi": {
      "description": "Objektdaten",
      "documents": "Dokumente",
      "units": "Einheiten",
      "images": "Bilder",
      "location": "Lage"
    },
    "units": "Einheiten",
    "size": "Größe",
    "rented": "Vermietet",
    "rooms": "Zimmer",
    "description": "Beschreibung",
    "furnishing": "Ausstattung",
    "images": "Bilder",
    "documents": "Dokumente",
    "links": "Links",
    "constructionYear": "Baujahr",
    "unit": "Einheit",
    "floor": "Etage",
    "price": "Preis",
    "status": "Status",
    "floorplan": "Grundriss",
    "location": "Lage",
    "allUnits": "Alle Einheiten anzeigen",
    "available": "Verfügbar",
    "sold": "Verkauft",
    "contactForm": {
      "title": "Gerne beraten wir Sie persönlich",
      "salutation": "Anrede",
      "salutationMr": "Herr",
      "salutationMs": "Frau",
      "firstName": "Vorname",
      "lastName": "Nachname",
      "email": "E-Mail",
      "company": "Firma",
      "phone": "Telefon",
      "body": "Nachricht",
      "send": "Abschicken",
      "success": {
        "title": "Vielen Dank",
        "desc": "Wir freuen uns über Ihr Interesse.\nIhr Anliegen werden wir so schnell wie möglich bearbeiten.",
        "back": "Zurück"
      }
    }
  }
}
```

Wenn man nun z.B. im Template den Titel des Projektes anzeigen möchte, gibt man folgendes an: `{{ project.title }}`

Ansprechpartner: Für den Absender der E-Mail nutzt man `{{ broker.* }}` und für den Projekt-Betreuer `{{ project.broker.* }}`.

Ein Beispiel HTML-Template findest du hier:

{% file src="/files/-MWQq4zGdU0z8DQB2h1e" %}


# E-Mail-Vorlagen

Schön designte E-Mail-Vorlagen erstellen

Manchmal kommt der Wunsch auf, dass bestimmte E-Mails schöner designed werden sollen. Teilweise ist der Wunsch, dass sie so aussehen wie klassische "Newsletter".

Neben Textbausteinen, die die Nutzer anlegen können, gibt es auch die Möglichkeit ganze E-Mail-Vorlagen zu erstellen. Eine E-Mail-Vorlage ist eine HTML-Datei, ähnlich wie man es aus Projekt-Landing-Pages oder Schaufenster-Screens kennt. Sie nutzt die [Liquid Template Engine](https://shopify.github.io/liquid/).

In einer E-Mail-Vorlage kann man jegliche Variablen nutzen, die man auch in Textbausteinen verwenden kann. Die E-Mail-Vorlage ist im Prinzip ein Wrapper um den Text, den man in der E-Mail schreibt. Der Text aus der E-Mail muss über eine spezielle Variable gezogen werden. Dafür nutzt man folgende Variable: {{ body }}.

### Standard-Vorlage

Für normale E-Mails nutzt Propstack auch eine E-Mail-Vorlage, die man über folgenden Link herunterladen und einsehen kann:

{% file src="/files/zWJin6Yt6qeTIX40eYd6" %}
email-template.html
{% endfile %}

Die vordefinierte E-Mail-Vorlage von Propstack sieht sehr mager aus. Das einzige was sie macht, ist den Inhalt der E-Mail in eine \<table> zu wrappen und der Tabelle eine maximale Breite von 620px zu geben.

Außerdem wird noch der globale Schrift-Stil über die Variablen `system.message_default_font_family`, `system.message_default_font_size` und `system.message_default_font_color` gesetzt, welche aber bei einem eigenen E-Mail-Template höchstwahrscheinlich keine Rolle spielen werden.

### Verwaltung von E-Mail-Vorlagen

Wenn man eine eigene E-Mail-Vorlagen erstellt hat, hinterlegt man sie in Propstack unter *Verwaltung > E-Mail-Einstellungen > HTML-Vorlagen*. Man kann mehrere E-Mail-Vorlagen hinterlegen, für verschiedene Anlässe.

Um eine hinterlegte HTML-Vorlage kann man nur indirekt über einen Textbaustein verwenden. D.h. beim Erstellen oder Bearbeiten eines Textbausteines erscheint ein neues Feld zum Auswählen einer selbst hinterlegten E-Mail-Vorlage. Wenn man dann den Textbaustein in einer E-Mail auswählt, wird auch die E-Mail-Vorlage verwendet und man kann das Ergebnis in der E-Mail-Vorschau betrachten.

### E-Mail-Vorlagen in verschiedenen Sprachen

Die Sprache einer E-Mail hängt von der ausgewählten Sprache des Empfängers ab. In einem Kontakt gibt es ein Feld "Sprache", in der man Deutsch oder Englisch auswählen kann. Man würde dann nicht 2 E-Mail-Vorlagen erstellen, sondern eine Vorlage mit einer if-else Bedingung, um den Text in der richtigen Sprache anzuzeigen. So würde die Bedingung aussehen:

```markup
{% if kontakt.sprache == "en" %}
    <p>contact speaks english</p>
{% else %}
    <p>deutscher Text!</p>
{% endif %}
```


# Schaufenster-Screens

Design-Anpassung vom Schaufenster-Screen

Ein Template für die Schaufenster-Screens ist eine einfache HTML-Datei. Den Code für das Standard-Template kann man hier herunterladen und als Vorlage für sein eigenes Template nutzen:

{% file src="/files/3JvP3JETNr5g6DNyAgkH" %}
standard-template.html
{% endfile %}

Damit die Templates dynamisch sind, d.h. je nach verknüpften Objekten andere Daten anzeigen, muss eine Template-Engine benutzt werden. Propstack nutzt dafür [Liquid](https://shopify.github.io/liquid/) von Shopify.

Den veränderten Code fügt man dann unter [Verwaltung > Schaufenster](https://crm.propstack.de/admin/shopwindows) > Eigenes Schaufenster-Screen-Template ein.

Im Template hat man Zugriff auf folgende Daten (in JSON-Format dargestellt):

```javascript
{
  "shop": {
    "name": "Musterimmobilien GmbH",
    "color": "#0c6bc4"
  },
  "properties": [
    {
      "title": "Reihenendhaus in Berlin Treptow",
      "unit_id": "ETW-2001",
      "exposee_id": "",
      "marketing_type": "BUY",
      "object_type": "LIVING",
      "rs_type": "HOUSE",
      "construction_year": 2015,
      "free_from": "01.02.2020",
      "rented": true,
      "floor_label": null,
      "street": "Lesvou",
      "house_number": "21",
      "zip_code": "12345",
      "city": "Berlin",
      "country": "DEU",
      "price": 280000.0,
      "sold_price": null,
      "base_rent": null,
      "total_rent": null,
      "service_charge": null,
      "parking_space_price": 30000.0,
      "number_of_rooms": 5.0,
      "plot_area": 800.0,
      "living_space": 185.0,
      "usable_floor_space": 185.0,
      "property_space_value": 185.0,
      "price_per_sqm": 1513.51,
      "has_courtage": true,
      "courtage": "3,57% inkl. Mwst.",
      "courtage_note": "",
      "deposit": null,
      "thermal_characteristic": null,
      "gfz": null,
      "grz": null,
      "bmz": null,
      "monument": false,
      "built_in_kitchen": true,
      "lift": false,
      "cellar": false,
      "description_note": "Wohnen auf 3 Ebenen mit einem kleinen Gartenbereich...",
      "location_note": "Berg- und Meer-Blick aus einer Immobilie, das können Sie hier genießen...",
      "furnishing_note": "",
      "other_note": "",
      "long_description_note": "",
      "long_location_note": "",
      "long_furnishing_note": "",
      "long_other_note": "",
      "energy_certificate_availability": "wird nicht benötigt",
      "building_energy_rating_type": null,
      "energy_efficiency_class": null,
      "firing_types": null,
      "heating_type": null,
      "formatted": {
        "id": 56,
        "name": "1055",
        "unit_id": "1055",
        "exposee_id": null,
        "marketing_type": "Miete",
        "rs_type": "Wohnung",
        "rs_category": "Souterrain",
        "construction_year": 1902,
        "equipment_technology_construction_year": null,
        "free_from": null,
        "price": null,
        "base_rent": "342 €",
        "total_rent": "522 €",
        "rental_income": null,
        "rent_subsidy": null,
        "parking_space_price": null,
        "number_of_parking_spaces": null,
        "parking_space_number": null,
        "rented": "nein",
        "yield_actual": null,
        "yield_target": null,
        "rental_income_actual": null,
        "rental_income_target": null,
        "distance_to_pt": null,
        "distance_to_fm": null,
        "distance_to_mrs": null,
        "distance_to_airport": null,
        "construction_phase": null,
        "tenancy": null,
        "price_on_inquiry": "nein",
        "short_term_constructible": "nein",
        "site_development_type": null,
        "site_constructible_type": null,
        "recommended_use_types": null,
        "min_divisible": null,
        "grz": null,
        "gfz": null,
        "net_floor_space": null,
        "number_of_apartments": null,
        "number_of_commercials": null,
        "special_purpose_type": null,
        "price_per_sqm": "8,55",
        "price_multiplier": null,
        "industrial_area": null,
        "additional_area": null,
        "price_type": null,
        "rent_duration": null,
        "heating_costs": "60 €",
        "heating_costs_in_service_charge": "nein",
        "service_charge": "120 €",
        "other_costs": null,
        "property_space_value": "40",
        "living_space": "40",
        "plot_area": null,
        "total_floor_space": null,
        "number_of_rooms": "1",
        "number_of_bed_rooms": null,
        "number_of_bath_rooms": null,
        "balcony_space": null,
        "last_refurbishment": null,
        "condition": "Neuwertig",
        "interior_quality": "Gehoben",
        "floor_label": "5. OG",
        "number_of_floors": 6,
        "parking_space_type": null,
        "number_of_balconies": null,
        "number_of_terraces": null,
        "energy_certificate_availability": "liegt vor",
        "building_energy_rating_type": "Bedarfsausweis",
        "energy_efficiency_class": "E",
        "thermal_characteristic": 160,
        "thermal_characteristic_electricity": null,
        "thermal_characteristic_heating": null,
        "energy_consumption_contains_warm_water": false,
        "energy_certificate_start_date": null,
        "energy_certificate_end_date": null,
        "heating_type": "Gas-Heizung",
        "firing_types": "KWK regenerativ",
        "lan_cables": false,
        "air_conditioning": "nein",
        "flooring_type": "Epoxidharz",
        "bathroom": null,
        "te_id": null,
        "duration_from": null,
        "duration_until": null,
        "sold_date": null,
        "sold_price": null,
        "number_of_units": null,
        "price_multiplier_target": null,
        "investment_category": null,
        "purchase_form": null,
        "tenant_structure": null,
        "walt": null,
        "number_of_single_rooms": null,
        "single_rooms_quota": null,
        "occupancy_rate": null,
        "number_of_vacancies": null,
        "conservation_areas": "nein",
        "bmz": null,
        "co_ownership_share": null,
        "renter": null,
        "local_court": null,
        "register_number": null,
        "land_registry": null,
        "contract_type": null,
        "duration": null,
        "cost_other": null,
        "cubature": null,
        "valuation_price_from": null,
        "valuation_price_to": null,
        "lift": "nein",
        "cellar": "nein",
        "barrier_free": "nein",
        "guest_toilet": "nein",
        "built_in_kitchen": "nein",
        "balcony": "nein",
        "garden": "nein",
        "monument": "nein",
        "construction_year_unknown": "nein",
        "flat_share_suitable": "nein",
        "building_permission": "nein",
        "demolition": "nein",
        "has_canteen": "nein",
        "kitchen_complete": "nein",
        "high_voltage": "nein",
        "lodger_flat": "nein",
        "terrace": "nein",
        "auto_lift": "nein",
        "ramp": "nein",
        "summer_residence_practical": "nein",
        "non_smoker": "nein",
        "preliminary_enquiry": "nein"
      },
      "property_status": {
        "id": null,
        "name": null
      },
      "location_name": null,
      "images": [
        {
          "url": "...",
          "big_url": "...",
          "medium_url": "...",
          "title": "Meerblick Willkommen"
        }
      ],
      "currency": "€",
      "custom": {},
      "broker": {
        "id": 123,
        "salutation": "ms",
        "name": "John Doe",
        "email": "john.doe@mustermann.estate",
        "phone": "123123123",
        "publicEmail": "",
        "publicPhone": "",
        "position": "Sales Agent",
        "avatarUrl": "https://images.propstack.de/...",
      }
    }
  ]
}
```


# Telefonanlage

Wie man seine Telefonanlage mit Propstack verbindet

Als Telefonanlage empfehlen wir die Anbieter [Placetel](https://www.placetel.de/), [3CX](https://www.3cx.com/) oder [Sipgate](https://www.sipgate.de/).

Bei einer Integration zwischen Propstack und einer Telefonanlage geht es prinzipiell um 2 Funktionen, die man haben möchte: "Contact Lookup" und "Call Journaling".

### Contact Lookup

Bei einem **Contact Lookup** fragt die Telefonanlage beim CRM an, wer der Anrufer ist und wenn ein Kontakt mit der angegeben Telefonnummer gefunden wurde, werden die Infos (z.B. Name und Firma) aus Propstack in der Telefonanlage angezeigt.

Für Kunden, die Snom-Telefone im Büro nutzen haben wir eine spezielle Integration dafür, die auf folgender Seite im Detail beschrieben wird:

{% content-ref url="/pages/-LXKG6t4ERtRQlvXoNTl" %}
[Snom Integration](/reference/snom-integration)
{% endcontent-ref %}

### Call Journaling

Beim **Call Journaling** informiert die Telefonanlage Propstack über eingehende oder ausgehende Telefonate, damit diese als Aktivität beim Kontakt automatisch verbucht wird.

Für Sipgate-Kunden gibt es folgenden Hilfe-Artikel, der beschreibt, wie man in der Sipgate-Konsole Call Journaling einstellt: <http://help.propstack.de/de/articles/2607973-sipgate>

### 3CX

{% file src="/files/KIufB5NHbAdoLYRpI8qg" %}
3cx.xml
{% endfile %}

In 3CX kann beide Funktionen in ihrem [CRM Template Wizard](https://www.3cx.com/docs/crm-integration/) einstellen. Dafür installiert man sich deren "3CX CRM Template Generator" und durchläuft dann mehrere Schritte für die Integration. Das [Video-Tutorial](https://www.youtube.com/watch?v=gEZOsfcWPto) von 3CX kann dabei sehr hilfreich sein.

#### **Schritt 1: Authentication**

Als Method `API Key` auswählen und einen API Key aus Propstack eintragen. Der API Key für 3CX muss vorher in Propstack angelegt werden.

#### **Schritt 2: Contact Lookup Einstellungen**

API URL (GET): \
`https://api.propstack.de/v1/contacts?with_meta=1&phone_number=[Number]`

Contact ID: `data.id`\
First Name: `data.first_name`\
Last Name: `data.last_name`\
Company Name: `data.company`\
Email (optional): `data.email`\
Business Phone: `data.office_phone`\
Mobile Phone: `data.home_cell`\
Mobile Phone 2: `data.home_phone`

#### **Schritt 3: Contact Creation**

überspringen

#### **Schritt 4: Call Journaling Einstellungen**

API URL (POST): `https://api.propstack.de/v1/calls/3cx`&#x20;

Request Encoding: `JSON`

Request data for inbound answered calls:\
`{ "duration": "[Duration]", "direction": "in", "from": "[Number]", "to": "[Agent]" }`

Request data for outbound answered calls:\
`{ "duration": "[Duration]", "direction": "out", "from": "[Agent]", "to": "[Number]" }`

Request data for inbound missed calls:\
`{ "duration": "[Duration]", "direction": "in", "from": "[Number]", "to": "[Agent]", "hangup_cause": "notAnswered" }`

Request data for outbound not answered calls:\
`{ "duration": "[Duration]", "direction": "out", "from": "[Agent]", "to": "[Number]", "hangup_cause": "notAnswered" }`

###

### Allgemeine API

## Telefonat-Aktivitäten erstellen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/calls/phone`

Telefonate mit Kunden als Aktivität verbuchen.\
Es wird nur eine Aktivität angelegt, wenn ein Kontakt anhand der Telefonnummer gefunden werden konnte.

#### Query Parameters

| Name                                        | Type   | Description                                                                                                       |
| ------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------- |
| type                                        | string | Grund des Auflegens. Bei normalen Telefonaten leer lassen. Wenn Anruf nicht angenommen wurde `noAnswer` übergeben |
| duration                                    | string | Die Dauer des Anrufs in Sekunden, Format: mm:ss                                                                   |
| to<mark style="color:red;">\*</mark>        | string | Nummer des Angerufenen                                                                                            |
| from<mark style="color:red;">\*</mark>      | string | Nummer des Anrufers                                                                                               |
| direction<mark style="color:red;">\*</mark> | string | `in` für eingehende Anrufe, `out` für ausgehende Anrufe                                                           |
| event<mark style="color:red;">\*</mark>     | string | eines von `incoming-call`, `outgoing-call` oder `hangup`                                                          |
| note                                        | string | Eine Notiz, die als Inhalt der Aktivität gespeichert wird                                                         |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}


# MCP Server

Mit einem MCP-Server (Model Context Protocol) kann ein KI-Assistent wie ChatGPT oder Claude auf Ihre Propstack-Daten zugreifen und bestimmte Aktionen über die Propstack API ausführen. Dadurch lassen sich typische CRM-Abläufe per Chat oder Sprache anstoßen, zum Beispiel Kontaktsuche, Objektabfragen oder Pipeline-Übersichten.

> Hinweis: Bei dem unten verlinkten MCP-Server handelt es sich um ein externes Community-Projekt. Es ist kein offizielles Propstack-Produkt, wird nicht von Propstack betrieben oder supportet und wird ausschließlich auf eigenes Risiko verwendet.

### Community-Projekt, nicht von Propstack betrieben

Der hier beschriebene MCP-Server ist ein Open-Source-Projekt eines externen Entwicklers:

* GitHub: [ashev87/propstack-mcp](https://github.com/ashev87/propstack-mcp)
* npm: [propstack-mcp-server](https://www.npmjs.com/package/propstack-mcp-server)

Wichtig:

* Dies ist **kein offizielles Produkt von Propstack**.
* Der Entwickler des Projekts ist **nicht mit Propstack verbunden**.
* Propstack entwickelt, betreibt, prüft, überwacht oder supportet diesen MCP-Server **nicht**.
* Propstack übernimmt **keine Gewähr, Haftung oder Zusage** für Installation, Verfügbarkeit, Sicherheit, Funktionsumfang, Datenverarbeitung oder Ergebnisse dieses Drittprojekts.
* Die Nutzung erfolgt **ausschließlich auf eigenes Risiko**.

Wenn Sie den MCP-Server einsetzen, prüfen Sie bitte selbst, ob der Quellcode, die Berechtigungen, die eingesetzten Modelle und die verarbeiteten Daten zu Ihren internen Sicherheits-, Datenschutz- und Compliance-Anforderungen passen.

### Mögliche Anwendungsfälle

Laut Open-Source-Projekt unterstützt der MCP-Server unter anderem folgende Szenarien:

* Kontakte suchen, anlegen und aktualisieren
* Objekte suchen und Objektdetails abrufen
* Deals und Pipeline-Stufen verwalten
* Aufgaben und Termine anlegen
* Suchprofile verwalten
* Projekt- und Aktivitätsdaten abrufen
* E-Mails und Dokumente über angebundene API-Funktionen verarbeiten

Der genaue Funktionsumfang hängt vom jeweiligen Stand des Open-Source-Projekts ab. Maßgeblich ist immer die Dokumentation des Projekts selbst.

### Voraussetzungen

Für die Nutzung benötigen Sie in der Regel:

* einen Propstack Account mit API-Zugriff
* einen gültigen API-Schlüssel
* einen MCP-fähigen Client, zum Beispiel ChatGPT, Claude Desktop, Claude Code oder Cursor
* Node.js in einer kompatiblen Version

Den Propstack API-Schlüssel finden Sie in Propstack unter **Verwaltung > API-Schlüssel**.

### Installation

Für die Installation, lesen Sie sich bitte die [README.md](readme.mdhttps://github.com/ashev87/propstack-mcp/blob/master/README.md) Datei aus dem Projekt durch.

### Sicherheit und Verantwortung

Wenn Sie einen MCP-Server mit Propstack verbinden, sollten Sie besonders auf folgende Punkte achten:

* Verwenden Sie nur API-Schlüssel mit den Berechtigungen, die Sie wirklich benötigen.
* Prüfen Sie, ob der KI-Client Anfragen an externe Modelle oder Dienste weiterleitet.
* Testen Sie Schreibzugriffe zunächst in einer kontrollierten Umgebung.
* Prüfen Sie vor dem produktiven Einsatz, welche Kontakt-, Objekt- oder Vorgangsdaten an KI-Systeme übergeben werden können.
* Überwachen Sie Updates des Drittprojekts vor einer erneuten Verwendung.

Propstack stellt mit der API die technische Grundlage bereit. Die Auswahl, Installation, Prüfung und der Betrieb dieses konkreten MCP-Servers liegen jedoch vollständig in der Verantwortung des jeweiligen Nutzers oder Unternehmens.

### Support

Bei Fragen oder Problemen mit diesem MCP-Server wenden Sie sich bitte an den Maintainer des Open-Source-Projekts über GitHub:

* [ashev87/propstack-mcp](https://github.com/ashev87/propstack-mcp)

Propstack Support kann für dieses Drittprojekt keinen technischen Support, keine Fehleranalyse und keine Zusagen zur Kompatibilität übernehmen.

### Hinweis

Diese Seite dient ausschließlich als Hinweis auf ein externes Community-Projekt. Sie ist keine Produktfreigabe, keine Empfehlung, keine Sicherheitsprüfung und keine Zusicherung der Eignung für einen bestimmten Zweck.


