---
title: "Bir araç entegrasyonu oluşturun (API)"
description: "Ajanınızın görüşme sırasında API'lerinizi çağırmasını sağlayın — veritabanında arama yapın, kayıt oluşturun, sipariş sorgulayın."
---

Bir **araç entegrasyonu**, bir ajanın çağrı sırasında
çağırabileceği yeniden kullanılabilir bir HTTP uç noktasıdır. ThunderPhone'a
aracın JSON şeması açıklamasını ve bir uç nokta URL'si verirsiniz; ajan,
görüşmeye göre ne zaman çağıracağına karar verir ve ThunderPhone sunucularından
giden HTTP isteğini yaparak yanıtı ajana döndürür.

<Note>
  Kontrol paneli, bu API olmadan da çoğu araç ihtiyacını karşılar: **Bağlantılar
  → Uygulamalar**, Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets ve Cal.com'u birkaç OAuth tıklamasıyla bağlar; **Bağlantılar →
  API'ler**, herhangi bir HTTP API'sini ajan eylemine dönüştürür (bir cURL komutu
  yapıştırın; yapay zeka sihirbazı yerleşik bir İsteği Test Et özelliğiyle araç
  taslağını oluşturur); **Bağlantılar → MCP** ise MCP sunucuları ekler. Bkz.
  [Bağlantılar](/tr/guides/concepts). Bu kılavuz, API'ler arayüzünün
  temelindeki ham API'yi açıklar.
</Note>

Bu kılavuz, uçtan uca bir hava durumu sorgulama aracı oluşturmayı anlatır.

## Bir aracın yapısı

İki bölüm:

1. **Şema** — aracın ne yaptığını ve hangi argümanları aldığını LLM'ye
   bildiren OpenAI tarzı işlev tanımı
   (`{type: "function", function: {name, description, parameters}}`).
2. **Uç nokta** — LLM aracı kullanmaya karar verdiğinde ThunderPhone
   sunucularının çağırdığı URL. İstek, gövde olarak LLM'nin seçtiği
   argümanları içeren JSON POST isteğidir.

## 1. Bir düzenleyici seçin

<CardGroup cols={2}>
  <Card title="Kontrol paneli" icon="window-maximize">
    **Bağlantılar → API'ler** bölümünü açın, API bağlantısını oluşturun veya
    düzenleyin, parametre düzenleyicisini **JSON** olarak değiştirin ve biçimi
    buraya ekleyin.
  </Card>
  <Card title="Entegrasyonlar API'si" icon="plug">
    Tanımı `POST /v1/integrations` ile oluşturun veya
    `PATCH /v1/integrations/{id}` ile güncelleyin.
  </Card>
</CardGroup>

Her iki yol da kaydedilmiş bir entegrasyon oluşturur. Kaydettikten sonra bu
entegrasyonu ajana ekleyin. Ajanlar API'sinde yazılabilir satır içi `tools`
alanı yoktur. Bu kılavuz, entegrasyonlar API'si yolunu kullanır.

## 2. Entegrasyonu oluşturun

```bash
curl -X POST https://api.thunderphone.com/v1/integrations \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Weather API",
    "spec": {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Return the current weather for a zip code.",
        "parameters": {
          "type": "object",
          "properties": {
            "zip": { "type": "string", "description": "5-digit US ZIP code" }
          },
          "required": ["zip"]
        }
      }
    },
    "endpoint_url":    "https://api.example.com/weather",
    "endpoint_method": "GET",
    "headers": [
      { "key": "X-Api-Key", "value": "your-provider-key" }
    ]
  }'
```

Döndürülen `id` değerini (bir UUID) kaydedin. Üstbilgi değerleri yalnızca yazılabilir: yanıtlar yalnızca üstbilgi adlarını listeler ve daha sonraki bir `PATCH`, saklanan değeri korumak için `value` olmadan bir üstbilgi gönderebilir.

<Tip>
  Aracın ve her parametrenin `description` alanına gerçekten özen gösterin.
  LLM, aracı çağırıp çağırmayacağına ve nasıl çağıracağına karar vermek için
  çalışma zamanında bu dizeleri kullanır. Belirsiz açıklamalar → belirsiz araç çağrıları.
</Tip>

### Adres parametrelerinde `format: "email"` bildirin

E-posta adresi alan bir parametre bunu şemasında belirtmelidir:

```json
"email": { "type": "string", "format": "email", "description": "The caller's email address" }
```

`format` yalnızca bir ipucu değildir. Çözümlenmiş bir e-posta şeması için,
uç noktanız çağrılmadan önce ThunderPhone değeri kırpar, alan adını küçük
harfe çevirir, tek başına geçen İngilizce `at`, `dot`, `underscore`,
`dash` ve `hyphen` sözcüklerini karakter karşılıklarına dönüştürür ve
`@`, `.`, `_` ve `-` karakterlerinin hemen çevresindeki boşlukları kaldırır.
Sözcükler, transkriptte zaten değişmez bir `@` karakteri bulunup bulunmamasından
bağımsız olarak aynı anlama gelir: `"john dot smith at gmail dot com"`
şuna dönüşür: `john.smith@gmail.com`.

Diğer tüm iç boşluklar sessizce birleştirilmek yerine reddedilir.
Konuşulan ayırıcı sözcükler yalnızca İngilizce için geçerlidir; İngilizce
olmayan veya tanınmayan boşluklu biçimler kapalı olarak başarısız olur.
Geçerli uluslararasılaştırılmış alan adları ve SMTPUTF8 yerel bölümleri kabul edilir.
Punycode girdisi punycode olarak kalır ve Unicode alan adı girdisi ayrıştırıcı
normalleştirmesinden sonra Unicode olarak kalır; böylece API'niz arayanın
sağladığı geleneksel gösterimi alır. Son değer geçersizse araç **çağrılmaz**.
Ajan, arayanla yazımı doğrulamasını ve değişmez adresi yeniden göndermesini
söyleyen `invalid_email_argument` değerini alır.

Atlanmış isteğe bağlı bir e-posta değiştirilmez. Özellik isteğe bağlı veya
null atanabilir olduğunda `null`, boş dize ya da yalnızca boşluk içeren dize
de değiştirilmez; aynı değerler zorunlu, null atanamayan bir e-posta için reddedilir.

`#/$defs/email` ve `#/definitions/email` gibi yerel şema başvuruları ile
`anyOf`, `oneOf` ve `allOf`, döngü ve derinlik sınırlarıyla incelenir.
Yerel olmayan veya çözümlenemeyen bir `$ref`, bilinen bir zorlamaya ilişkin
sınırdır ve kullanılabilir şeması olmayan araç anlık görüntüsüne sahip bir çağrı
gibi değiştirilmeden iletilir. Bu denetimin uygulanması gerekiyorsa e-posta
şemalarını yerel tutun.

Zorunlu kılınan e-posta biçimi olmayan parametreler, modelin ürettiği şekliyle
aynen iletilir.

Desteklenen biçimler `date-time`, `time`, `date`, `duration`, `email`,
`hostname`, `ipv4`, `ipv6` ve `uuid` biçimleridir; bugün yalnızca `email`
normalleştirilir ve zorunlu kılınır.

## 3. Uç noktayı sandbox ortamında test edin

Entegrasyonu bir ajana bağlamadan önce bağlantıyı doğrulamak için
ThunderPhone sunucularından imzalı bir istek gönderin:

```bash
curl -X POST https://api.thunderphone.com/v1/integrations/test-request \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url":    "https://api.example.com/weather?zip=94110",
    "method": "GET",
    "headers": { "X-Api-Key": "your-provider-key" }
  }'
```

```json Response
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}
```

Bu test, ThunderPhone'un SSRF korumalarını da güçlendirir — localhost'a veya
özel IP aralıklarına yönelik istekler `400 code=url_not_allowed` döndürür.

## 4. Entegrasyonu bir ajana bağlayın

Bir ajan oluştururken veya güncellerken `integration_ids` aracılığıyla ekleyin:

```bash
curl -X PATCH https://api.thunderphone.com/v1/agents/12 \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_ids": ["f9b5a1a4-..."]
  }'
```

Bir ajana birden fazla entegrasyon bağlayabilirsiniz. Ajanın istemi
bunlara adlarıyla başvurabilir — "arayan kişi hava koşulları hakkında
sorduğunda `get_weather` kullanın" — veya şema açıklamalarından
bunları örtük olarak keşfedebilir.

## 5. Uç noktayı uygulayın

Ajan aracı çağırdığında ThunderPhone,
`endpoint_url` adresinize imzalı bir POST gönderir:

```
POST /weather HTTP/1.1
Host: api.example.com
X-Api-Key: your-provider-key
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<HMAC-SHA256 hex>
X-ThunderPhone-Signature: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json

{"zip": "94110"}
```

Sunucunuz, LLM'ye geri iletilen JSON ile yanıt verir:

```json
{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}
```

LLM bu yanıtı alır ve arayan kişiye anlaşılır bir özet sunar.

<Warning>
  İmza, webhook uç noktanızla aynı `secret` kullanılarak ham istek
  gövdesi üzerinden hesaplanır. **Doğrulayın** — araç uç noktaları
  internete açıktır ve webhook'larla aynı sahtecilik risklerine
  tabidir. Bkz.
  [Webhook imzalarını doğrulama](/tr/guides/verify-webhook-signatures).
</Warning>

## 6. Döngüyü test edin

Ajana karşı bir [mikrofon oturumu](/api-reference/mic-sessions)
başlatın ve aracınızın işlediği soruyu sorun ("94110'da hava nasıl?").
Aramanın transkripti tam gidiş dönüşü gösterir:

```json
{
  "call_id": 987654321,
  "transcripts": [
    { "role": "user",
      "content": "What's the weather in 94110?" },
    { "role": "tool_call",
      "content": "{\"tool_call\": \"get_weather\", \"arguments\": {\"zip\": \"94110\"}}" },
    { "role": "tool_response",
      "content": "{\"tool_name\": \"get_weather\", \"response\": {\"temperature_f\": 64, \"condition\": \"Partly cloudy\"}}" },
    { "role": "agent",
      "content": "It's 64 degrees and partly cloudy." }
  ]
}
```

Bunu
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript)
aracılığıyla alabilirsiniz; ham olay akışı (giriş başına zamanlama ve
ses ofsetleriyle birlikte)
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history)
adresindedir.

Çağrı listesi ve analiz yüzeylerinde ThunderPhone artık test çağrılarını gerçek trafikten ayrı olarak raporlar. Browser Talk testleri ve simülasyonları gerçek bir telefon numarasını yeniden kullanabilir ve gelen çağrı gibi görünebilir; ancak üretim çağrısı toplamlarına, puanlara veya sorun metriklerine dahil edilmez.

## Sık karşılaşılan sorunlar

<AccordionGroup>
  <Accordion title="Ajan aracı hiç çağırmıyor">
    LLM, aracın açıklamasına göre karar verir. Arayan kişinin sorusu
    açıklamayla eşleşmiyorsa model aracı çağırmaz. Açıklamayı
    netleştirin (yaygın eş anlamlıları ve ifade biçimlerini ekleyin)
    veya ajanın isteminde açıkça belirtin ("Arayan kişi hava durumu
    hakkında soru sorduğunda `get_weather` kullanın.").
  </Accordion>

  <Accordion title="Araç çok fazla veri döndürüyor">
    6 kB üzerindeki yanıtlar transkript önizlemesinde kesilir. Tüm
    satırınızı değil, yalnızca LLM'nin ihtiyaç duyduğu alanları döndürün.
  </Accordion>

  <Accordion title="Zaman aşımları">
    Araç uç noktalarının varsayılan zaman aşımı 10 saniyedir. Daha uzun
    süreye ihtiyacınız varsa bunu eşzamansız olarak işleyin:
    `{"status": "pending", "request_id": "..."}`
    döndürün ve sonucu ayrı bir araç çağrısı aracılığıyla sunun.
  </Accordion>

  <Accordion title="Sürümleme">
    Her entegrasyon `PATCH` işlemi yeni bir revizyon oluşturur.
    Kimin neyi değiştirdiğini görmek için
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    inceleyin. Bir aracın şemasını bozarsanız eski bir anlık görüntüyü
    tekrar PATCH ederek manuel olarak geri alabilirsiniz.
  </Accordion>
</AccordionGroup>

---

## Sonraki adımlar

<CardGroup cols={2}>
  <Card title="Entegrasyonlar referansı" icon="plug" href="/api-reference/integrations">
    CRUD, aktarım, sürüm geçmişi.
  </Card>
  <Card title="Fonksiyon Araçları teknik özellikleri" icon="screwdriver-wrench" href="/tr/tools/overview">
    Tam JSON şeması dil bilgisi ve imzalı uç nokta sözleşmesi.
  </Card>
  <Card title="İmzaları doğrulama" icon="shield-check" href="/tr/guides/verify-webhook-signatures">
    Webhook imza modelini araç uç noktalarına uygulayın.
  </Card>
  <Card title="Transkript + geçmiş API'si" icon="phone" href="/api-reference/calls">
    Bir araç çağrısının tam gidiş dönüşünü inceleyin.
  </Card>
</CardGroup>
