# API referansı

Base URL: `https://hubzone.app/api`

## Anahtar

### Anahtar bilgisi

`GET /open/v1/me`

Anahtarın neler yapabildiğini ve çağrı türü başına sınırları gösterir.

İzin: `any key`

**Örnek**

```bash
curl "https://hubzone.app/api/open/v1/me" \
  -H "Authorization: Bearer $HUBZONE_KEY"
```

**Yanıtlar**

- 200: Anahtar.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "keyId": "3f0c8f0e-2b1a-4c55-9a38-0d6c1c9d7e11",
  "scopes": [
    "contacts.read",
    "contacts.write"
  ],
  "limits": {
    "get": {
      "label": "Read one record",
      "perMinute": 600
    }
  },
  "allScopes": 14
}
```

## Özellikler

### Özellikleri listele

`GET /open/v1/properties/{type}`

Bir kayıt türünün özellikleri (alanları): adları, türleri ve seçim listeleri için seçenekleri. Oluşturma, değiştirme ve arama çağrılarında bu adları kullanın.

İzin: `{type}.read`

**Parametreler**

- `type` (path, required, string): Kayıt türü. contacts, companies, deals, tickets, products, orders, calls.

**Örnek**

```bash
curl "https://hubzone.app/api/open/v1/properties/contacts" \
  -H "Authorization: Bearer $HUBZONE_KEY"
```

**Yanıtlar**

- 200: Özellikler.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 403: Anahtarın bu çağrı için izni yok.
- 404: Bulunamadı (ya da başka bir çalışma alanına ait).
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "properties": [
    {
      "key": "email",
      "type": "text",
      "label_i18n": {
        "en": "Email",
        "tr": "E-posta"
      },
      "options": null
    },
    {
      "key": "lifecycle_stage",
      "type": "enum",
      "label_i18n": {
        "en": "Lifecycle stage",
        "tr": "Yaşam döngüsü aşaması"
      },
      "options": [
        {
          "value": "lead",
          "label_i18n": {
            "en": "Lead"
          }
        }
      ]
    }
  ]
}
```

## Kayıtlar

### Kayıtları listele ya da bul

`GET /open/v1/objects/{type}`

Bir türün kayıtları, en yeni etkinlik önce, sayfa sayfa. "q", metin özellikleri bu metni içeren kayıtları bulur. Sonraki sayfa için cevaptaki "after" değerini gönderin.

İzin: `{type}.read`

**Parametreler**

- `type` (path, required, string): Kayıt türü. contacts, companies, deals, tickets, products, orders, calls.
- `limit` (query, integer 1-100): Sayfa başına kayıt (varsayılan 25).
- `after` (query, string): Sonraki sayfanın imleci, önceki cevaptan.
- `q` (query, string): Aranacak metin.

**Örnek**

```bash
curl "https://hubzone.app/api/open/v1/objects/contacts?limit=25&q=ada" \
  -H "Authorization: Bearer $HUBZONE_KEY"
```

**Yanıtlar**

- 200: Bir sayfa kayıt. Son sayfada "paging.next.after" null'dır.
- 400: İstek geçersiz; mesaj nedenini söyler.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 403: Anahtarın bu çağrı için izni yok.
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "results": [
    {
      "id": "8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12",
      "objectType": "contacts",
      "properties": {
        "first_name": "Ada",
        "last_name": "Lovelace",
        "email": "ada@example.com"
      },
      "ownerId": "5d1f0f3e-7e0a-4b8e-9a50-aa14d3c9b2f1",
      "isPrivate": false,
      "createdAt": "2026-11-10T09:30:00.000Z",
      "updatedAt": "2026-11-10T09:30:00.000Z",
      "pipelineId": null,
      "stageId": null,
      "stageChangedAt": null,
      "lastActivityAt": null
    }
  ],
  "paging": {
    "next": {
      "after": "eyJ2IjoxfQ"
    }
  },
  "total": {
    "value": 1,
    "capped": false
  }
}
```

### Kayıt ara

`POST /open/v1/objects/{type}/search`

Süzgeç, sıralama ve metin sorgusuyla ara. Bir kayıt, "filters" içindeki her süzgeci sağlıyorsa eşleşir. İşleçler: eq, neq, gt, gte, lt, lte, contains, starts_with, in, exists, not_exists.

İzin: `{type}.read`

**Parametreler**

- `type` (path, required, string): Kayıt türü. contacts, companies, deals, tickets, products, orders, calls.

**İstek gövdesi** (JSON): Tüm alanlar isteğe bağlıdır.

```json
{
  "query": "renewal",
  "filters": [
    {
      "property": "amount",
      "op": "gte",
      "value": 1000
    }
  ],
  "sort": {
    "property": "amount",
    "direction": "desc"
  },
  "limit": 25
}
```

**Örnek**

```bash
curl -X POST "https://hubzone.app/api/open/v1/objects/contacts/search" \
  -H "Authorization: Bearer $HUBZONE_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"renewal","filters":[{"property":"amount","op":"gte","value":1000}],"sort":{"property":"amount","direction":"desc"},"limit":25}'
```

**Yanıtlar**

- 200: Liste çağrısındaki gibi bir sayfa kayıt.
- 400: İstek geçersiz; mesaj nedenini söyler.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 403: Anahtarın bu çağrı için izni yok.
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "results": [
    {
      "id": "8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12",
      "objectType": "contacts",
      "properties": {
        "first_name": "Ada",
        "last_name": "Lovelace",
        "email": "ada@example.com"
      },
      "ownerId": "5d1f0f3e-7e0a-4b8e-9a50-aa14d3c9b2f1",
      "isPrivate": false,
      "createdAt": "2026-11-10T09:30:00.000Z",
      "updatedAt": "2026-11-10T09:30:00.000Z",
      "pipelineId": null,
      "stageId": null,
      "stageChangedAt": null,
      "lastActivityAt": null
    }
  ],
  "paging": null,
  "total": {
    "value": 1,
    "capped": false
  }
}
```

### Tek kaydı oku

`GET /open/v1/objects/{type}/{id}`

Tüm özellikleriyle bir kayıt.

İzin: `{type}.read`

**Parametreler**

- `type` (path, required, string): Kayıt türü. contacts, companies, deals, tickets, products, orders, calls.
- `id` (path, required, string (uuid)): Kaydın kimliği.

**Örnek**

```bash
curl "https://hubzone.app/api/open/v1/objects/contacts/8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12" \
  -H "Authorization: Bearer $HUBZONE_KEY"
```

**Yanıtlar**

- 200: Kayıt.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 403: Anahtarın bu çağrı için izni yok.
- 404: Bulunamadı (ya da başka bir çalışma alanına ait).
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "id": "8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12",
  "objectType": "contacts",
  "properties": {
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com"
  },
  "ownerId": "5d1f0f3e-7e0a-4b8e-9a50-aa14d3c9b2f1",
  "isPrivate": false,
  "createdAt": "2026-11-10T09:30:00.000Z",
  "updatedAt": "2026-11-10T09:30:00.000Z",
  "pipelineId": null,
  "stageId": null,
  "stageChangedAt": null,
  "lastActivityAt": null
}
```

### Kayıt oluştur

`POST /open/v1/objects/{type}`

Bir kayıt oluşturur. Özellikleri "Özellikleri listele" çıktısındaki adlarla gönderin. Yalnızca properties, ownerId, stageId ve pipelineId kabul edilir. ownerId aksini söylemedikçe kaydın sahibi anahtarın kişisidir. Telefon görüşmesi kaydetmek için bunun yerine calls uç noktasını kullanın.

İzin: `{type}.write`

**Parametreler**

- `type` (path, required, string): Kayıt türü. contacts, companies, deals, tickets, products, orders, calls.

**İstek gövdesi** (JSON): "properties" zorunludur.

```json
{
  "properties": {
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com"
  }
}
```

**Örnek**

```bash
curl -X POST "https://hubzone.app/api/open/v1/objects/contacts" \
  -H "Authorization: Bearer $HUBZONE_KEY" \
  -H "content-type: application/json" \
  -d '{"properties":{"first_name":"Ada","last_name":"Lovelace","email":"ada@example.com"}}'
```

**Yanıtlar**

- 201: Yeni kayıt.
- 400: İstek geçersiz; mesaj nedenini söyler.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 403: Anahtarın bu çağrı için izni yok.
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "id": "8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12",
  "objectType": "contacts",
  "properties": {
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com"
  },
  "ownerId": "5d1f0f3e-7e0a-4b8e-9a50-aa14d3c9b2f1",
  "isPrivate": false,
  "createdAt": "2026-11-10T09:30:00.000Z",
  "updatedAt": "2026-11-10T09:30:00.000Z",
  "pipelineId": null,
  "stageId": null,
  "stageChangedAt": null,
  "lastActivityAt": null
}
```

### Kaydı değiştir

`PATCH /open/v1/objects/{type}/{id}`

Gönderdiğiniz özellikleri değiştirir; diğerleri olduğu gibi kalır. Bir özelliği temizlemek için null gönderin. Bir fırsat ya da talep stageId ile başka bir aşamaya taşınır.

İzin: `{type}.write`

**Parametreler**

- `type` (path, required, string): Kayıt türü. contacts, companies, deals, tickets, products, orders, calls.
- `id` (path, required, string (uuid)): Kaydın kimliği.

**İstek gövdesi** (JSON): Yalnızca değişeni gönderin.

```json
{
  "properties": {
    "job_title": "Mathematician"
  }
}
```

**Örnek**

```bash
curl -X PATCH "https://hubzone.app/api/open/v1/objects/contacts/8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12" \
  -H "Authorization: Bearer $HUBZONE_KEY" \
  -H "content-type: application/json" \
  -d '{"properties":{"job_title":"Mathematician"}}'
```

**Yanıtlar**

- 200: Değişen kayıt.
- 400: İstek geçersiz; mesaj nedenini söyler.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 403: Anahtarın bu çağrı için izni yok.
- 404: Bulunamadı (ya da başka bir çalışma alanına ait).
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "id": "8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12",
  "objectType": "contacts",
  "properties": {
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com",
    "job_title": "Mathematician"
  },
  "ownerId": "5d1f0f3e-7e0a-4b8e-9a50-aa14d3c9b2f1",
  "isPrivate": false,
  "createdAt": "2026-11-10T09:30:00.000Z",
  "updatedAt": "2026-11-10T09:30:00.000Z",
  "pipelineId": null,
  "stageId": null,
  "stageChangedAt": null,
  "lastActivityAt": null
}
```

## Aramalar

### Telefon görüşmesi kaydet

`POST /open/v1/calls`

Telefonlar ve santraller için: görüşme o telefon numarasındaki kişiye bağlanır ve zaman çizelgesinde görünür. Ses asla gönderilmez. externalId ile iki kez gönderdiğiniz görüşme bir kez saklanır.

İzin: `calls.write`

**İstek gövdesi** (JSON): phoneNumber zorunludur. direction: inbound ya da outbound. outcome: busy, connected, left_live_message, left_voicemail, meeting_booked, no_answer ya da wrong_number.

```json
{
  "phoneNumber": "+90 532 000 00 00",
  "direction": "outbound",
  "startedAt": "2026-11-10T09:30:00Z",
  "durationSeconds": 184,
  "outcome": "connected",
  "note": "Asked for a quote",
  "externalId": "pbx-7781"
}
```

**Örnek**

```bash
curl -X POST "https://hubzone.app/api/open/v1/calls" \
  -H "Authorization: Bearer $HUBZONE_KEY" \
  -H "content-type: application/json" \
  -d '{"phoneNumber":"+90 532 000 00 00","direction":"outbound","startedAt":"2026-11-10T09:30:00Z","durationSeconds":184,"outcome":"connected","note":"Asked for a quote","externalId":"pbx-7781"}'
```

**Yanıtlar**

- 201: Görüşme ve bağlandığı kişi (o numarada kişi yoksa linked false olur).
- 400: İstek geçersiz; mesaj nedenini söyler.
- 401: Anahtar yok, yanlış, iptal edilmiş ya da süresi dolmuş.
- 403: Anahtarın bu çağrı için izni yok.
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "id": "c1d2e3f4-0000-4000-8000-000000000001",
  "activityId": "a1b2c3d4-0000-4000-8000-000000000002",
  "contactId": "8a3b2f64-1c9d-4e05-b7a1-3f2c9d0e4a12",
  "linked": true,
  "duplicate": false
}
```

## Etkinlikler

### Özel etkinlik gönder

`POST /public/events/{eventKey}`

Tanımladığınız bir özel etkinliğin bir oluşumunu kaydeder. Authorization başlığı yok: adresteki etkinlik anahtarı kimlik bilgisidir. Özel etkinlikler rehberine bakın.

İzin: `event key` (Authorization başlığı yok)

**Parametreler**

- `eventKey` (path, required, string): Etkinliğin anahtarı (hze_ ile başlar), etkinliği oluştururken bir kez gösterilir.

**İstek gövdesi** (JSON): email zorunludur.

```json
{
  "email": "person@example.com",
  "properties": {
    "plan": "pro",
    "seats": 5
  },
  "occurredAt": "2026-11-10T09:30:00Z"
}
```

**Örnek**

```bash
curl -X POST "https://hubzone.app/api/public/events/hze_your_event_key" \
  -H "content-type: application/json" \
  -d '{"email":"person@example.com","properties":{"plan":"pro","seats":5},"occurredAt":"2026-11-10T09:30:00Z"}'
```

**Yanıtlar**

- 201: Saklandı. linkedToContact, o e-posta adresinde bir kişi olup olmadığını söyler.
- 400: İstek geçersiz; mesaj nedenini söyler.
- 404: Bilinmeyen etkinlik anahtarı.
- 429: Çok fazla çağrı: Retry-After'ı bekleyin.

```json
{
  "id": "1b7e0c52-6f0e-4c7a-9a43-2d5e9d1f0a77",
  "linkedToContact": true
}
```
