> ## 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.

# Bygg en verktøyintegrasjon (API)

> La agenten din kalle API-ene dine midt i samtalen — søk i en database, opprett en sak, slå opp en bestilling.

En **verktøyintegrasjon** er et gjenbrukbart HTTP-endepunkt som en agent kan
kalle under en samtale. Du gir ThunderPhone en JSON-schemabeskrivelse
av verktøyet samt en endepunkt-URL; agenten avgjør når det skal kalles
basert på samtalen, og ThunderPhone utfører den utgående HTTP-
forespørselen fra serverne sine og returnerer svaret til agenten.

<Note>
  Dashbordet dekker de fleste verktøybehov uten dette API-et: **Tilkoblinger
  → Apper** kobler til Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets og Cal.com med noen få OAuth-klikk; **Tilkoblinger →
  API-er** gjør et hvilket som helst HTTP-API om til en agenthandling (lim inn en cURL-kommando,
  så lager en AI-veiviser et utkast til verktøyet, med innebygd Test forespørsel); og
  **Tilkoblinger → MCP** legger til MCP-servere. Se
  [Tilkoblinger](/nb/guides/concepts). Denne veiledningen dekker det underliggende
  rå-API-et for API-flaten.
</Note>

Denne veiledningen går gjennom hvordan du bygger et verktøy for værdata fra start til slutt.

## Oppbygningen av et verktøy

To deler:

1. **Schemaet** — en funksjonsdefinisjon i OpenAI-stil
   (`{type: "function", function: {name, description, parameters}}`)
   som forteller LLM-en hva verktøyet gjør og hvilke argumenter det tar.
2. **Endepunktet** — URL-en som ThunderPhone-serverne kaller når
   LLM-en bestemmer seg for å bruke verktøyet. Forespørselen er en JSON POST med
   argumentene LLM-en har valgt som brødtekst.

## 1. Velg en lagringsstrategi

<CardGroup cols={2}>
  <Card title="Direkte på agenten" icon="paperclip">
    Knytt et engangsverktøy til agentens `tools`-array. Enkelt, men
    ikke gjenbrukbart.
  </Card>

  <Card title="Lagret integrasjon" icon="plug">
    Lagre verktøyet som en gjenbrukbar [integrasjon](/api-reference/integrations)
    og koble det til mange agenter. Anbefales for alt som brukes mer
    enn én gang.
  </Card>
</CardGroup>

Denne veiledningen bruker fremgangsmåten med lagret integrasjon.

## 2. Opprett integrasjonen

```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" }
    ]
  }'
```

Lagre den returnerte `id`-en (en UUID).

<Tip>
  Legg reell innsats i `description` for verktøyet og hver
  parameter. LLM-en bruker disse strengene under kjøring for å avgjøre om
  og hvordan verktøyet skal kalles. Vage beskrivelser → vage verktøykall.
</Tip>

## 3. Test endepunktet i sandbox

Før du kobler integrasjonen til en agent, send en signert forespørsel
fra ThunderPhone-serverne for å bekrefte tilkoblingen:

```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, ...}"
}
```

Denne testen forsterker også ThunderPhones SSRF-beskyttelse — forespørsler til
localhost eller private IP-områder returnerer `400 code=url_not_allowed`.

## 4. Knytt integrasjonen til en agent

Knytt den til via `integration_ids` når du oppretter eller oppdaterer en agent:

```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-..."]
  }'
```

Du kan knytte mange integrasjoner til én agent. Agentens ledetekst kan
referere til dem ved navn — «bruk `get_weather` når innringeren spør
om værforhold» — eller den kan oppdage dem implisitt fra
skjemabeskrivelsene.

## 5. Implementer endepunktet

Når agenten kaller verktøyet, sender ThunderPhone en signert POST til
din `endpoint_url`:

```
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"}
```

Serveren din svarer med JSON som sendes tilbake til LLM-en:

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

LLM-en tar inn svaret og gir innringeren en naturlig oppsummering.

<Warning>
  Signaturen beregnes over den rå forespørselsbrødteksten med samme
  `secret` som webhook-endepunktet ditt. **Verifiser den** — verktøyendepunkter
  er eksponert mot internett og har de samme risikoene for forfalskning som
  webhooks. Se
  [Verifiser webhook-signaturer](/nb/guides/verify-webhook-signatures).
</Warning>

## 6. Test flyten

Kjør en [mikrofonøkt](/api-reference/mic-sessions) mot agenten og
still spørsmålet verktøyet ditt håndterer («Hvordan er været i
94110?»). Samtaleutskriften viser hele runden:

```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." }
  ]
}
```

Du kan hente dette via
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript);
den rå hendelsesstrømmen (med tidsangivelser og lydforskyvninger per oppføring) finner du på
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history).

## Vanlige fallgruver

<AccordionGroup>
  <Accordion title="Agenten kaller aldri verktøyet">
    LLM-en avgjør basert på verktøyets beskrivelse. Hvis innringerens
    spørsmål ikke samsvarer med beskrivelsen, kaller ikke modellen
    verktøyet. Gjør beskrivelsen mer presis (legg til vanlige synonymer og
    formuleringer), eller nevn det eksplisitt i agentens ledetekst («Når
    innringeren spør om været, bruk `get_weather`.»).
  </Accordion>

  <Accordion title="Verktøyet returnerer for mye data">
    Svar over 6 kB blir avkortet i forhåndsvisningen av utskriften. Returner
    bare feltene LLM-en trenger — ikke hele raden.
  </Accordion>

  <Accordion title="Tidsavbrudd">
    Verktøyendepunkter har en standard tidsavbruddsgrense på 10 sekunder. Hvis du trenger mer tid,
    håndter det asynkront: returner `{"status": "pending", "request_id": "..."}`
    og vis resultatet via et separat verktøykall.
  </Accordion>

  <Accordion title="Versjonering">
    Hver `PATCH` av en integrasjon oppretter en ny revisjon. Undersøk
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    for å se hvem som endret hva. Hvis du ødelegger skjemaet til et verktøy, kan du
    rulle tilbake manuelt ved å PATCH-e et eldre øyeblikksbilde inn igjen.
  </Accordion>
</AccordionGroup>

***

## Neste trinn

<CardGroup cols={2}>
  <Card title="Referanse for integrasjoner" icon="plug" href="/api-reference/integrations">
    CRUD, overføring, versjonshistorikk.
  </Card>

  <Card title="Spesifikasjon for funksjonsverktøy" icon="screwdriver-wrench" href="/nb/tools/overview">
    Fullstendig JSON-schemagrammatikk og kontrakten for signerte endepunkter.
  </Card>

  <Card title="Verifiser signaturer" icon="shield-check" href="/nb/guides/verify-webhook-signatures">
    Bruk mønsteret for webhook-signaturer på verktøyendepunkter.
  </Card>

  <Card title="API for transkripsjon + historikk" icon="phone" href="/api-reference/calls">
    Undersøk hele tur-retur-flyten for et verktøykall.
  </Card>
</CardGroup>
