Contacts API
Contacts (Kontakte) ermöglichen es Ihnen, Ansprechpersonen für Ihre Kunden zu verwalten. Jeder Contact gehört zu einem Customer und kann als primärer Kontakt markiert werden. Contacts werden automatisch bei der Erstellung von Customers angelegt oder können separat verwaltet werden.
Hinweis: Contact-Erstellung
Neue Contacts werden primär über die Customers API erstellt, indem Sie beim Erstellen eines Customers das contact_name Feld verwenden. Dieser Endpoint dient der Verwaltung bestehender Contacts.
Contact-Objekt
{
"data": {
"id": 175,
"company_id": 123,
"customer_id": 410,
"user_id": 456,
"name": "Max Muster",
"email": "max.muster@example.com",
"phone": "+41 44 123 45 67",
"greeting": "Herr",
"is_primary": true,
"archived": false,
"created_at": "2024-12-04T17:11:06.000000Z",
"updated_at": "2024-12-04T17:11:06.000000Z"
}
}Attribute
| Feld | Typ | Beschreibung |
|---|---|---|
id | integer | Eindeutige Contact-ID |
company_id | integer | ID der zugehörigen Firma |
customer_id | integer | ID des zugehörigen Customers |
user_id | integer | ID des Benutzers, der den Contact erstellt hat |
name | string | Name des Kontakts (erforderlich) |
email | string|null | E-Mail-Adresse |
phone | string|null | Telefonnummer |
greeting | string|null | Anrede (z.B. "Herr", "Frau", "Herr Dr.") |
is_primary | boolean | Ob dies der Hauptkontakt für den Customer ist |
archived | boolean | Ob der Contact archiviert ist |
created_at | datetime | Erstellungsdatum |
updated_at | datetime | Datum der letzten Aktualisierung |
Endpoints
Alle Contacts auflisten
GET /companies/{company}/contactsRuft eine paginierte Liste aller Contacts der Firma ab.
Parameter
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
page | integer | 1 | Seitennummer |
per_page | integer | 15 | Anzahl Contacts pro Seite (max. 100) |
filter[customer_id] | integer | - | Filtern nach spezifischem Customer (exakte Übereinstimmung) |
filter[archived] | boolean | - | Filtern nach Archivierungsstatus (exakte Übereinstimmung) |
include | string | - | Zugehörige Daten laden: customer (kommagetrennt) |
Response
{
"data": [
{
"id": 175,
"company_id": 123,
"customer_id": 410,
"user_id": 456,
"name": "Max Muster",
"email": "max.muster@example.com",
"phone": "+41 44 123 45 67",
"greeting": "Herr",
"is_primary": true,
"archived": false,
"created_at": "2024-12-04T17:11:06.000000Z",
"updated_at": "2024-12-04T17:11:06.000000Z"
},
{
"id": 176,
"company_id": 123,
"customer_id": 410,
"user_id": 456,
"name": "Anna Beispiel",
"email": "anna.beispiel@example.com",
"phone": "+41 44 987 65 43",
"greeting": "Frau",
"is_primary": false,
"archived": false,
"created_at": "2024-12-05T09:30:00.000000Z",
"updated_at": "2024-12-05T09:30:00.000000Z"
}
],
"links": {
"first": "https://app.milkee.ch/api/v2/companies/123/contacts?page=1",
"last": "https://app.milkee.ch/api/v2/companies/123/contacts?page=5",
"prev": null,
"next": "https://app.milkee.ch/api/v2/companies/123/contacts?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5,
"path": "https://app.milkee.ch/api/v2/companies/123/contacts",
"per_page": 15,
"to": 15,
"total": 67
}
}Beispiele
# Alle Contacts abrufen
curl -H "Authorization: Bearer 1|abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/contacts"
# Contacts eines bestimmten Customers
curl -H "Authorization: Bearer 1|abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/contacts?filter[customer_id]=410"
# Nur aktive Contacts
curl -H "Authorization: Bearer 1|abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/contacts?filter[archived]=false"
# Mit Customer-Daten
curl -H "Authorization: Bearer 1|abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/contacts?include=customer"Einzelnen Contact abrufen
GET /companies/{company}/contacts/{contact}Ruft die Details eines spezifischen Contacts ab.
Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
company | integer | Firmen-ID |
contact | integer | Contact-ID |
include | string | Zugehörige Daten laden: customer (kommagetrennt) |
Response
{
"data": {
"id": 175,
"company_id": 123,
"customer_id": 410,
"user_id": 456,
"name": "Max Muster",
"email": "max.muster@example.com",
"phone": "+41 44 123 45 67",
"greeting": "Herr",
"is_primary": true,
"archived": false,
"created_at": "2024-12-04T17:11:06.000000Z",
"updated_at": "2024-12-04T17:11:06.000000Z",
"customer": {
"id": 410,
"name": "Muster AG",
"number": 1001,
"email": "info@muster.ch"
}
}
}Beispiele
# Contact abrufen
curl -H "Authorization: Bearer 1|abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/contacts/175"
# Mit Customer-Daten
curl -H "Authorization: Bearer 1|abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/contacts/175?include=customer"Contact aktualisieren
PUT /companies/{company}/contacts/{contact}Aktualisiert einen bestehenden Contact.
Request Body
{
"name": "Max Muster",
"email": "max.muster@muster-ag.ch",
"phone": "+41 44 123 45 67",
"greeting": "Herr Dr.",
"is_primary": true,
"archived": false
}Validierung
| Feld | Regeln |
|---|---|
name | sometimes, required, string, max:255 |
email | nullable, email, max:255 |
phone | nullable, string, max:255 |
greeting | nullable, string, max:255 |
is_primary | sometimes, boolean |
archived | sometimes, boolean |
Besonderheiten
- Primärkontakt: Wenn
is_primary=truegesetzt wird, werden automatisch alle anderen Contacts des gleichen Customers als nicht-primär markiert - Teilweises Update: Alle Felder sind optional, nur die übermittelten Felder werden aktualisiert
Response
{
"data": {
"id": 175,
"company_id": 123,
"customer_id": 410,
"user_id": 456,
"name": "Max Muster",
"email": "max.muster@muster-ag.ch",
"phone": "+41 44 123 45 67",
"greeting": "Herr Dr.",
"is_primary": true,
"archived": false,
"created_at": "2024-12-04T17:11:06.000000Z",
"updated_at": "2025-01-14T15:45:00.000000Z"
}
}Beispiele
# Contact aktualisieren
curl -X PUT \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{
"name": "Max Muster",
"email": "max.muster@muster-ag.ch",
"greeting": "Herr Dr."
}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/175"
# Als primären Contact markieren
curl -X PUT \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{"is_primary": true}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/175"
# Contact archivieren
curl -X PUT \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{"archived": true}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/175"Contact löschen
DELETE /companies/{company}/contacts/{contact}Löscht einen bestehenden Contact unwiderruflich.
Löschbedingungen
Ein Contact kann nur gelöscht werden, wenn:
- Keine Rechnungen mit dem Contact verknüpft sind
- Keine Offerten mit dem Contact verknüpft sind
Andernfalls wird ein 409-Fehler zurückgegeben.
Response
HTTP/1.1 204 No ContentBeispiel
curl -X DELETE \
-H "Authorization: Bearer 1|abcdef123456789..." \
"https://app.milkee.ch/api/v2/companies/123/contacts/176"Mehrere Contacts archivieren/dearchivieren
POST /companies/{company}/contacts/multipleArchiviert oder dearchiviert mehrere Contacts gleichzeitig.
Request Body
{
"ids": [175, 176, 177],
"archive": true
}| Feld | Typ | Beschreibung |
|---|---|---|
ids | array|integer | Array von Contact-IDs oder einzelne ID |
archive | boolean | true zum Archivieren, false zum Dearchivieren (Standard: true) |
Response
HTTP/1.1 204 No ContentBeispiele
# Mehrere Contacts archivieren
curl -X POST \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{
"ids": [175, 176, 177],
"archive": true
}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/multiple"
# Mehrere Contacts dearchivieren
curl -X POST \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{
"ids": [175, 176, 177],
"archive": false
}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/multiple"
# Einzelnen Contact archivieren
curl -X POST \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{
"ids": 175,
"archive": true
}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/multiple"Mehrere Contacts löschen
DELETE /companies/{company}/contacts/multipleLöscht mehrere Contacts gleichzeitig.
Sicheres Löschen
Contacts mit verknüpften Rechnungen oder Offerten werden automatisch übersprungen und nicht gelöscht. Der Vorgang schlägt nicht fehl, sondern löscht nur die Contacts ohne Verknüpfungen.
Request Body
{
"ids": [175, 176, 177]
}| Feld | Typ | Beschreibung |
|---|---|---|
ids | array|integer | Array von Contact-IDs oder einzelne ID |
Response
HTTP/1.1 204 No ContentBeispiel
curl -X DELETE \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{"ids": [176, 177, 178]}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/multiple"Fehlerbehandlung
Häufige Fehler
409 Conflict - Contact hat Rechnungen/Offerten
{
"message": "Dieser Kontakt hat Rechnungen oder Offerten und kann daher nicht gelöscht werden."
}Ursache: Contact ist mit Rechnungen oder Offerten verknüpft und kann nicht gelöscht werden.
Lösung: Archivieren Sie den Contact stattdessen:
curl -X PUT \
-H "Authorization: Bearer 1|abcdef123456789..." \
-H "Content-Type: application/json" \
-d '{"archived": true}' \
"https://app.milkee.ch/api/v2/companies/123/contacts/175"422 Validation Error
{
"message": "The given data was invalid.",
"errors": {
"name": [
"Name für Kontakt fehlt."
],
"email": [
"E-Mail-Adresse ist nicht gültig."
]
}
}Häufige Validierungsfehler:
name.required: Name ist erforderlichname.max: Name zu lang (maximal 255 Zeichen)email.email: Ungültige E-Mail-Adresseemail.max: E-Mail zu lang (maximal 255 Zeichen)phone.max: Telefonnummer zu lang (maximal 255 Zeichen)greeting.max: Anrede zu lang (maximal 255 Zeichen)is_primary.boolean: is_primary muss true oder false seinarchived.boolean: archived muss true oder false sein
Best Practices
Primärkontakt-Verwaltung
Stellen Sie sicher, dass jeder Customer immer einen primären Contact hat. Wenn kein primärer Contact existiert, sollte der erste verfügbare Contact als primär markiert werden.
Archivierung statt Löschung
Verwenden Sie Archivierung statt Löschung für bessere Datenintegrität. Wenn ein Contact Rechnungen oder Offerten hat und nicht gelöscht werden kann (409-Fehler), archivieren Sie ihn stattdessen.
Bulk-Operationen effizient nutzen
Nutzen Sie die /multiple Endpoints für Massen-Operationen, um mehrere Contacts gleichzeitig zu archivieren, dearchivieren oder zu löschen, anstatt einzelne Requests zu senden.
E-Mail-Validierung
Validieren Sie E-Mail-Adressen vor dem Absenden, um Validierungsfehler zu vermeiden. Beachten Sie, dass das E-Mail-Feld optional ist.
Nächste Schritte
- Customers API - Customers verwalten (Contacts werden beim Erstellen von Customers angelegt)
- Invoices API - Rechnungen mit Contacts verknüpfen
- Proposals API - Offerten mit Contacts verknüpfen
- Code-Beispiele ansehen
- Webhooks einrichten
