> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Buat integrasi alat (API)

> Biarkan agen Anda memanggil API Anda di tengah percakapan — mencari basis data, membuat tiket, memeriksa pesanan.

Sebuah **integrasi alat** adalah endpoint HTTP yang dapat digunakan kembali yang dapat
dipanggil agen selama panggilan. Anda memberikan ThunderPhone deskripsi skema JSON
untuk alat tersebut beserta URL endpoint; agen memutuskan kapan akan memanggilnya
berdasarkan percakapan, lalu ThunderPhone membuat permintaan HTTP keluar dari
servernya dan mengembalikan respons kepada agen.

<Note>
  Dasbor mencakup sebagian besar kebutuhan alat tanpa API ini: **Koneksi
  → Aplikasi** menghubungkan Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets, dan Cal.com dalam beberapa klik OAuth; **Koneksi →
  API** mengubah API HTTP apa pun menjadi tindakan agen (tempel perintah cURL
  dan wizard AI akan menyusun alat, dengan Test Request bawaan); dan
  **Koneksi → MCP** menambahkan server MCP. Lihat
  [Koneksi](/id/guides/concepts). Panduan ini membahas
  API mentah yang mendasari antarmuka API.
</Note>

Panduan ini menjelaskan pembuatan alat pencarian cuaca dari awal hingga akhir.

## Anatomi alat

Dua bagian:

1. **Skema** — definisi fungsi bergaya OpenAI
   (`{type: "function", function: {name, description, parameters}}`)
   yang memberi tahu LLM fungsi alat tersebut dan argumen yang diterimanya.
2. **Endpoint** — URL yang dipanggil server ThunderPhone saat
   LLM memutuskan untuk menggunakan alat tersebut. Permintaannya berupa JSON POST dengan
   argumen yang dipilih LLM sebagai isi permintaan.

## 1. Pilih strategi penyimpanan

<CardGroup cols={2}>
  <Card title="Inline pada agen" icon="paperclip">
    Lampirkan alat sekali pakai ke array `tools` agen. Sederhana, tetapi
    tidak dapat digunakan kembali.
  </Card>

  <Card title="Integrasi tersimpan" icon="plug">
    Simpan alat sebagai [integrasi](/api-reference/integrations) yang dapat digunakan kembali
    dan tautkan dari banyak agen. Direkomendasikan untuk apa pun yang digunakan
    lebih dari sekali.
  </Card>
</CardGroup>

Panduan ini menggunakan jalur integrasi tersimpan.

## 2. Buat integrasi

```bash theme={null}
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" }
    ]
  }'
```

Simpan `id` yang dikembalikan (sebuah UUID).

<Tip>
  Luangkan upaya sungguh-sungguh untuk `description` alat dan setiap
  parameter. LLM menggunakan string ini saat runtime untuk memutuskan apakah
  dan bagaimana memanggil alat tersebut. Deskripsi yang samar → panggilan alat yang samar.
</Tip>

## 3. Uji endpoint di sandbox

Sebelum menautkan integrasi ke agen, kirim permintaan bertanda tangan
dari server ThunderPhone untuk mengonfirmasi konektivitas:

```bash theme={null}
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 theme={null}
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}
```

Pengujian ini juga memperkuat pengaman SSRF ThunderPhone — permintaan ke
localhost atau rentang IP privat mengembalikan `400 code=url_not_allowed`.

## 4. Tautkan integrasi ke agen

Lampirkan melalui `integration_ids` saat Anda membuat atau memperbarui agen:

```bash theme={null}
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-..."]
  }'
```

Anda dapat menautkan banyak integrasi ke satu agen. Prompt agen dapat
merujuknya berdasarkan nama — "gunakan `get_weather` saat penelepon bertanya
tentang kondisi cuaca" — atau agen dapat menemukannya secara implisit dari
deskripsi skema.

## 5. Implementasikan endpoint

Saat agen memanggil alat, ThunderPhone mengirim POST yang ditandatangani ke
`endpoint_url` Anda:

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

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

Server Anda merespons dengan JSON yang diteruskan kembali ke LLM:

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

LLM menerima respons tersebut dan menyampaikan ringkasan yang natural kepada
penelepon.

<Warning>
  Tanda tangan dihitung berdasarkan isi permintaan mentah menggunakan
  `secret` yang sama dengan endpoint webhook Anda. **Verifikasi tanda tangan tersebut** — endpoint alat
  dapat diakses dari internet dan menghadapi risiko pemalsuan yang sama seperti
  webhook. Lihat
  [Verifikasi tanda tangan webhook](/id/guides/verify-webhook-signatures).
</Warning>

## 6. Uji alurnya

Jalankan [sesi mikrofon](/api-reference/mic-sessions) terhadap agen
dan ajukan pertanyaan yang ditangani alat Anda ("Bagaimana cuaca di
94110?"). Transkrip panggilan menampilkan perjalanan bolak-balik lengkap:

```json theme={null}
{
  "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." }
  ]
}
```

Anda dapat mengambilnya melalui
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript);
stream peristiwa mentah (dengan waktu per entri dan offset audio) tersedia di
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history).

## Hal yang sering terlewat

<AccordionGroup>
  <Accordion title="Agen tidak pernah memanggil alat">
    LLM memutuskan berdasarkan deskripsi alat. Jika pertanyaan penelepon
    tidak sesuai dengan deskripsi, model tidak akan memanggil
    alat. Perjelas deskripsinya (tambahkan sinonim dan
    frasa umum) atau sebutkan secara eksplisit dalam Prompt agen ("Saat
    penelepon bertanya tentang cuaca, gunakan `get_weather`.").
  </Accordion>

  <Accordion title="Alat mengembalikan terlalu banyak data">
    Respons di atas 6 kB dipotong dalam pratinjau transkrip. Kembalikan
    hanya kolom yang dibutuhkan LLM — bukan seluruh baris data Anda.
  </Accordion>

  <Accordion title="Timeout">
    Endpoint alat memiliki timeout default 10 detik. Jika Anda memerlukan waktu lebih lama,
    tangani secara asinkron: kembalikan `{"status": "pending", "request_id": "..."}`
    dan tampilkan hasilnya melalui pemanggilan alat terpisah.
  </Accordion>

  <Accordion title="Pembuatan versi">
    Setiap `PATCH` integrasi membuat revisi baru. Periksa
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    untuk melihat siapa yang mengubah apa. Jika Anda merusak skema sebuah alat, Anda dapat
    melakukan rollback secara manual dengan menerapkan kembali snapshot lama melalui PATCH.
  </Accordion>
</AccordionGroup>

***

## Langkah berikutnya

<CardGroup cols={2}>
  <Card title="Referensi integrasi" icon="plug" href="/api-reference/integrations">
    CRUD, transfer, riwayat versi.
  </Card>

  <Card title="Spesifikasi Function Tools" icon="screwdriver-wrench" href="/id/tools/overview">
    Tata bahasa skema JSON lengkap dan kontrak endpoint bertanda tangan.
  </Card>

  <Card title="Verifikasi tanda tangan" icon="shield-check" href="/id/guides/verify-webhook-signatures">
    Terapkan pola tanda tangan webhook ke endpoint tool.
  </Card>

  <Card title="API transkrip + riwayat" icon="phone" href="/api-reference/calls">
    Periksa seluruh alur bolak-balik panggilan tool.
  </Card>
</CardGroup>
