
# AI Agent-API

En **AI Agent** er hjernen bag din bot: dens instruktioner, personlighed, sprog, viden og værktøjer. Du bygger en Agent én gang og dirigerer derefter trafikken hen til den. Denne guide dækker alt, hvad du kan gøre med en Agent via API'et — oprette den, konfigurere den, give den viden og værktøjer, gennemse dens kladder og dirigere samtaler til den.

- **Base URL** — `https://api.youraiconnector.com/v1`
- **Autentificering** — din API-nøgle (se [Autentificering](authentication.md))
- **Fejl & paginering** — se [Fejl & Paginering](errors-and-pagination.md)

Alle eksempler herunder viser `?apiKey=` forespørgselsformen i cURL og `X-API-Key` headeren i JavaScript og Python — begge virker på alle slutpunkter.

Hvis du er ny i forhold til konceptet Agents, så læs [AI Agents](../ai-agents/ai-agents.md) først.


---

## Hvordan en Agent er sammensat

Fire ting administreres separat, og det er nyttigt at vide, hvad der er hvad, før du starter:

| Del | Hvad det er | Hvor du indstiller det |
|---|---|---|
| **Konfiguration** | Instruktioner, regler, mål, personlighed, sprog, AI-niveau, booking- og opfølgningsadfærd | `PUT /agents/{agentId}` eller den mere specifikke `PUT /agents/{agentId}/bot-config` |
| **Viden** | Ofte stillede spørgsmål (FAQ) og videnskilder (sider og dokumenter, som platformen har læst for dig) | [FAQs API](faqs.md) og `POST /agents/{agentId}/kb-sources` |
| **Værktøjer** | Brugerdefinerede funktioner og MCP-servere, som Agenten kan kalde midt i en samtale | `POST /agents/{agentId}/custom-functions` og `POST /agents/{agentId}/mcp-servers` |
| **Routing** | Hvilke kanaler og samtaler der rent faktisk når denne Agent | Indgangspunkter — `PUT /entry-points/channel-defaults` og `POST /agents/{agentId}/entry-points` |

> **En ny Agent svarer ikke nogen, før du dirigerer trafik til den.** Oprettelse af en Agent placerer den ikke på en kanal. Det er det trin, de fleste integrationer overser — se [Routing af samtaler til en Agent](#routing-conversations-to-an-agent) nederst på denne side.

---

## Agent-objektet

Et fuldt Agent-dokument er stort — flere hundrede kilobyte, primært dens FAQ-liste, dens videnskilder og alt sideindhold læst fra dit websted. Derfor returnerer en liste en kort **oversigtsrække** pr. Agent, når du beder om det:

```json
{
  "id": "ag7HkQ2ZpLxR3mNb",
  "name": "Listing assistant",
  "active": true,
  "language": "en",
  "goal": "Book a viewing",
  "tags": [],
  "anthropic_model": "standard",
  "ai_speed": "balanced",
  "enable_bookings": false,
  "enable_follow_ups": true,
  "faq_refs_count": 42,
  "kb_source_refs_count": 3,
  "created_at": 1700000000000,
  "last_modified_at": 1700000000000
}
```

| Felt | Type | Beskrivelse |
|---|---|---|
| `id` | string | Agentens unikke identifikator. |
| `name` | string \| null | Agentnavn, som vist i dashboardet. |
| `active` | boolean \| null | Om Agenten i øjeblikket har tilladelse til at svare. |
| `language` | string \| null | Sprog, som Agenten svarer på. |
| `goal` | string \| null | Hvad Agenten arbejder hen imod, forkortet til de første 200 tegn (en afsluttende ellipse betyder, at den er blevet forkortet). |
| `tags` | array \| null | Agentens tag-regler. |
| `anthropic_model` | string \| null | AI-kvalitetsniveau: `standard`, `economy`, `max` eller `mini`. |
| `ai_speed` | string \| null | Hvor meget ræsonnement Agenten anvender, før den svarer: `fast`, `fast_thinker`, `balanced` eller `thorough`. |
| `enable_bookings` | boolean \| null | Om Agenten må booke aftaler. |
| `enable_follow_ups` | boolean \| null | Om Agenten sender opfølgningsbeskeder. |
| `faq_refs_count` | integer | Hvor mange FAQs der er i denne Agents vidensbase. |
| `kb_source_refs_count` | integer | Hvor mange videnskilder der er linket til den. |
| `created_at` | integer \| null | Oprettelsestidspunkt, epoke-millisekunder. |
| `last_modified_at` | integer \| null | Sidste ændring, epoke-millisekunder. |

Det fulde dokument tilføjer alt andet: `instructions`, `rules`, `personality`, `availability`, `follow_up_config`, de linkede FAQ- og videnskildelister, de genererede tekstblokke og enhver kørselsstatus (`tag_generation`, `optimize_run`).

> Nogle svar indeholder også `substrate_campaign_id`. Det er en intern post, der føres på ældre konti; du behøver aldrig at foretage dig noget i forhold til den, og på nyere konti er den `null` eller fraværende.

---

## Liste over agenter

`GET /agents` — hver Agent på kontoen, nyeste først.

Dette slutpunkt er **ikke pagineret**. Som standard returneres hver Agent med sin fulde konfiguration, hvilket er tungt: en enkelt Agent kan fylde 580 KB, og en konto med 64 agenter over 3 MB. Send `view=summary` for en kort række pr. Agent i stedet, og læs derefter den, du ønsker, med [Hent en Agent](#get-an-agent).

**Forespørgselsparametre**

| Parameter | Beskrivelse |
|---|---|
| `view` | Sæt til `summary` for korte rækker. Enhver anden værdi returnerer `400`. Udelad for fulde dokumenter. |
| `fields` | Gælder kun sammen med `view=summary`. Kommaseparerede opsummeringsnøgler, der skal beholdes, for eksempel `id,name,active`. `id` er altid inkluderet; ukendte navne ignoreres. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/agents?apiKey=YOUR_API_KEY&view=summary&fields=id,name,active"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents?view=summary", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { agents } = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/agents",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"view": "summary"},
)
agents = res.json()["agents"]
```

**Svar** (`200`)

```json
{
  "success": true,
  "agents": [
    { "id": "ag7HkQ2ZpLxR3mNb", "name": "Listing assistant", "active": true }
  ]
}
```

---

## Opret en Agent

`POST /agents` — kun `name` er reelt nødvendig; send hvilken som helst konfiguration, du allerede kender, sammen med den. En ny Agent er aktiv som standard.

**Anmodningsfelter** (alle valgfrie undtagen `name`)

| Felt | Type | Beskrivelse |
|---|---|---|
| `name` | string | Agentnavn. |
| `active` | boolean | Om den må svare med det samme. Standard er `true`. |
| `language` | string | Sprog, som Agenten svarer på. |
| `instructions` | string | Primære instruktioner, der styrer, hvordan den taler med kontakter. |
| `rules` | string | Hårde regler, den altid skal følge. |
| `goal` | string | Resultatet, den skal arbejde hen imod. |
| `personality` | string | Tonefald og personlighed. |
| `availability` | object | Aktive timer pr. ugedag — se [Indstil aktive timer](#set-active-hours). |
| `ai_speed` | string | `fast`, `fast_thinker`, `balanced` eller `thorough`. |
| `anthropic_model` | string | `standard`, `economy`, `max` eller `mini`. |
| `scrape_urls` | string[] | Sider, der skal læses for at opbygge Agentens instruktioner. |

**Opbygning af en Agent fra din hjemmeside.** Inkluder `scrape_urls`, så læser platformen disse sider og skriver instruktionerne for dig. Svaret fortæller dig, om genereringen er startet, så du ved, om du skal forespørge Agenten om fremskridt.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Listing assistant",
    "language": "en",
    "instructions": "Answer questions about our listings and book viewings.",
    "goal": "Book a viewing"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Listing assistant",
    scrape_urls: ["https://example.com", "https://example.com/faq"],
  }),
});
const data = await res.json();
console.log(data.agent_id);
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/agents",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"name": "Listing assistant", "scrape_urls": ["https://example.com"]},
)
print(res.json()["agent_id"])
```

**Svar** (`201`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "substrate_campaign_id": null,
  "agent_generation_queued": true
}
```

`agent_generation_queued` er `true`, når platformen er begyndt at skrive instruktionerne fra de sider, du har angivet.

En `400` betyder, at brødteksten ikke var et JSON-objekt, et felt blev afvist, eller Agenten overstiger den konfigurationsstørrelse, din plan tillader. En `403` betyder, at kontoen ikke har tilladelse til at bruge en af de indstillinger, du har sendt — for eksempel et AI-niveau, som kontoudbyderen ikke har givet adgang til.

---

## Hent en Agent

`GET /agents/{agentId}`

Send `fields` med en kommasepareret liste for kun at få det tilbage, du har brug for, for eksempel `fields=name,active,goal`. `id` er altid inkluderet, og navne, der ikke findes på Agenten, ignoreres i stedet for at blive afvist. Udelad den for at få hele dokumentet.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY&fields=name,active,goal"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?fields=name,active", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { agent } = await res.json();
```

**Python**

```python
res = requests.get(
    "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"fields": "name,active"},
)
agent = res.json()["agent"]
```

En Agent, der ikke findes på din konto, returnerer `404`.

---

## Opdater en Agent

`PUT /agents/{agentId}` — send kun de felter, du ønsker at ændre; alt andet forbliver uberørt.

Indlejrede indstillinger kan adresseres blad for blad med en prikket nøgle, så `"availability.monday"` kun ændrer mandag og lader resten af ugen være i fred.

**Noter**

- For at ændre hvilken bookbar begivenhedstype Agenten booker ind i, send `event_id` (begivenhedens id, eller `null` for at rydde den). Send `event_ids` med et array for at linke flere på én gang — den første bliver den primære, og `[]` fjerner alle links. `event_id` og `event_ids` udelukker hinanden, og selve `event`-feltet kan ikke skrives direkte.
- `enable_bookings` skal være en reel boolsk værdi, og `booking_provider` skal være en af `default`, `zenchef`, `formitable`.
- Ejer- og identitetsfelter ignoreres, ligesom intern kørselsstatus (genererings- og optimeringsfremskridt).
- **Routing er ikke indstillet her.** Brug `PUT /entry-points/channel-defaults` til at gøre Agenten til svarer for en kanal, `POST /agents/{agentId}/entry-points` for søgeords- og kommentarregler, og `PATCH /agents/{agentId}/active` for at sætte den på pause eller genoptage den.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Answer questions about our listings and always offer a viewing.",
    "anthropic_model": "standard"
  }'
```

**JavaScript**

```javascript
await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb", {
  method: "PUT",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ "availability.monday": { start_time: "09:00", end_time: "17:00" } }),
});
```

**Python**

```python
requests.put(
    "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"goal": "Book a viewing within three messages"},
)
```

**Svar** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

En tom brødtekst returnerer `400` med `"No fields to update"`.

---

## Opdater bot-indstillinger

`PUT /agents/{agentId}/bot-config` — den snævre måde at ændre kun samtaleindstillingerne på.

En Agent har ikke en separat bot-sektion: dens indstillinger ligger direkte på Agenten, så feltnavnene her er de samme, som du ville sende til `PUT /agents/{agentId}`. Dette slutpunkt findes som den sikre, fokuserede måde at ændre en håndfuld af dem på. Mindst ét felt er påkrævet.

| Felt | Beskrivelse |
|---|---|
| `instructions` | Primære instruktioner, der styrer, hvordan Agenten taler med kontakter. |
| `rules` | Hårde regler, den altid skal følge. |
| `goal` | Resultatet, den skal arbejde hen imod i hver samtale. |
| `personality` | Beskrivelse af tonefald og personlighed. |
| `language` | Sprog, som Agenten svarer på. |
| `ai_speed` | `fast`, `fast_thinker`, `balanced` eller `thorough`. |
| `anthropic_model` | `standard`, `economy`, `max` eller `mini`. |
| `max_messages` | Maksimalt antal Agent-beskeder pr. samtale. |
| `alert_human_when` | Hvornår Agenten skal advare et menneskeligt teammedlem. |
| `ai_transparency` | Om Agenten oplyser, at den er en AI. |

> **Feltnavne skal være almindelige navne her** — bogstaver, tal, understregninger og bindestreger. Prikkede stier accepteres ikke på dette slutpunkt (i modsætning til `PUT /agents/{agentId}`), så `bot.goal` afvises med en `400`.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/bot-config?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "goal": "Book a viewing within three messages", "ai_speed": "thorough" }'
```

Lang tekst tæller mod den konfigurationsstørrelse, din plan tillader, så et meget stort instruktionssæt kan blive afvist med en `400`.

---

## Indstil aktive timer

`PUT /agents/{agentId}/active-hours` — de timer, hvor Agenten svarer automatisk. Uden for disse vinduer forbliver den tavs.

Send et `availability`-objekt med ugedage som nøgler (`monday` til `sunday`). Hver dag tager et enkelt tidsvindue eller en liste over vinduer i 24-timers `HH:MM`-format. Dage, du udelader, beholder deres nuværende indstillinger, og enhver nøgle, der ikke er en ugedag, afvises — så en slåfejl kan ikke lydløst resultere i ingenting.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active-hours?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "availability": {
      "monday": { "start_time": "09:00", "end_time": "17:00" },
      "tuesday": [
        { "start_time": "09:00", "end_time": "12:00" },
        { "start_time": "13:00", "end_time": "17:00" }
      ]
    }
  }'
```

**Svar** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

En forkert ugedagsnøgle returnerer `400`: `"Invalid availability keys: funday. Allowed keys: monday through sunday."`

---

## Sæt en Agent på pause eller genoptag den

`PATCH /agents/{agentId}/active` — tænder eller slukker for agenten. En pauset agent beholder hele sin konfiguration, men stopper øjeblikkeligt med at svare; genoptagelse træder i kraft med det samme.

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "active": false }'
```

```javascript
await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active", {
  method: "PATCH",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ active: false }),
});
```

**Svar** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "active": false }
```

`active` skal være en reel boolsk værdi — alt andet returnerer `400` med `"active (boolean) is required"`.

---

## Dupliker en agent

`POST /agents/{agentId}/duplicate` — opretter en kopi, hvor konfigurationen bevares. Kopien sender intet, før du peger en kanal eller et indgangspunkt (Entry Point) mod den.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/duplicate?apiKey=YOUR_API_KEY"
```

**Svar** (`201`)

```json
{ "success": true, "agent_id": "ag9WsX3cRfV6tGyH", "source_agent_id": "ag7HkQ2ZpLxR3mNb" }
```

En duplikat tæller med i din plans agent-kvote på præcis samme måde som oprettelse fra bunden, så den afvises med `403`, når kontoen har nået sin grænse.

---

## Slet en agent

`DELETE /agents/{agentId}`

Sletningen afvises, så længe agenten stadig er tilknyttet noget, der ville holde op med at fungere uden den — en udsendelse (broadcast), et indgangspunkt eller (på ældre konti) en kampagne. Svaret viser, hvad der holder på den, så du først kan fjerne tilknytningen og prøve igen.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY"
```

**Svar** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

**Blokeret** (`409`)

```json
{
  "success": false,
  "error": "Agent is still attached to one or more broadcast(s). Detach it first.",
  "blocking_campaign_ids": [],
  "blocking_broadcast_ids": ["bc5TgYhUj8IkOlPm"],
  "blocking_entry_point_ids": []
}
```

---

## Kladder: gennemse ændringer, før de går live

Redigeringer foretaget i editoren, og enhver omskrivning produceret med [Optimer med AI](#optimize-an-agent-with-ai), gemmes som en **upubliceret kladde**, indtil du publicerer dem. Den live agent fortsætter med at svare med sin nuværende konfiguration indtil da.

### Publicer kladden

`POST /agents/{agentId}/publish-draft` — flytter kladden over på live-konfigurationen og sletter kladden i samme trin.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/publish-draft?apiKey=YOUR_API_KEY"
```

**Svar** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "published_keys": ["instructions", "goal"] }
```

`published_keys` viser de indstillinger, der blev flyttet fra kladden til live-agenten, så du kan se, hvad der er ændret.

> **Kontroller, at der findes en kladde, før du kalder dette.** Publicering af en agent, der ikke har nogen kladde, er ikke et understøttet kald og returneres i øjeblikket som en `500` med en generisk besked, ikke en specifik. For at kassere en kladde i stedet, skal du bruge discard nedenfor.

### Kassér kladde

`POST /agents/{agentId}/discard-draft` — smider kladden væk og lader den aktive konfiguration forblive præcis, som den er. Det er sikkert at kalde, når der ikke er nogen kladde; der sker ingenting.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/discard-draft?apiKey=YOUR_API_KEY"
```

---

## Optimer en agent med AI

`POST /agents/{agentId}/optimize` — omskriver agentens konfiguration baseret på din feedback ("den bliver ved med at tilbyde rabatter", "svarene er for lange") og gemmer omskrivningen **som en kladde** i stedet for at gøre den aktiv.

Send enten `user_feedback` (en simpel instruktion) eller, når du reagerer på et specifikt dårligt svar, `thumbs_down_feedback` sammen med det problematiske `thumbs_down_message`. Mindst én af de to skal indeholde tekst.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/optimize?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "user_feedback": "Keep replies under three sentences." }'
```

**Respons** (`202`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Arbejdet kører i baggrunden, og kaldet returnerer med det samme. Læs agenten med `GET /agents/{agentId}` og hold øje med `optimize_run.status`; når den er tilbage til `Draft`, venter omskrivningen som agentens kladde. Gennemgå den, og udgiv den derefter eller kassér den.

Kun én kørsel ad gangen pr. agent — et andet kald, mens en kørsel er i gang, returnerer `409`. Dette bruger AI-kreditter.

---

## Tagging-regler

En tagging-regel er et tag plus en beskrivelse af, hvornår det gælder. Under en samtale læser agenten beskrivelsen og tager kontakten, når det passer, hvilket er sådan, tag-drevne automatiseringer udløses.

**Regelobjektet**

| Felt | Påkrævet | Beskrivelse |
|---|---|---|
| `name` | Ja | Tagget der skal anvendes, for eksempel `hot-lead`. |
| `description` | Nej | Hvornår agenten skal anvende det, skrevet som en instruktion den følger. |
| `webhook` | Nej | URL der kaldes, når agenten anvender dette tag. |
| `ai_can_remove` | Nej | Om agenten også må fjerne tagget igen. Standard er `false`. |
| `tag_id` | Nej | Id på et eksisterende tag på din konto, som reglen skal linkes til. Uden dette linkes reglen til tagget med samme navn, og opretter det, hvis det ikke findes — så enhver regel kan adresseres via tag-id efterfølgende. |

### Tilføj en tagging-regel

`POST /agents/{agentId}/tags`

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tag": {
      "name": "hot-lead",
      "description": "Apply when the contact asks about pricing or wants to book a call.",
      "ai_can_remove": false
    }
  }'
```

**Svar** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "tag": { "name": "hot-lead", "...": "..." } }
```

### Erstat en tagging-regel

`PUT /agents/{agentId}/tags/{tagId}` — reglen findes via tag-id'et i stien og **erstattes fuldstændigt**, ikke flettet, så send hele reglen i stedet for kun den del, du ændrer. Tagget, den peger på, bevares, selv hvis du udelader `tag_id`, så en redigering kan ikke løsrive reglen fra dens tag.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/tg8YuIoP2aSdF3gH?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tag": { "name": "hot-lead", "description": "Apply only when the contact asks to book a call." } }'
```

### Fjern en tag-regel

`DELETE /agents/{agentId}/tags/{tagId}` — Agenten stopper med at anvende det tag. Selve tagget, og alle kontakter der allerede har det, forbliver uberørte.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/tg8YuIoP2aSdF3gH?apiKey=YOUR_API_KEY"
```

Begge slutpunkter returnerer `404`, når Agenten ikke eksisterer, **eller** når den ikke har nogen regel for det tag.

### Generer et tag-sæt med AI

`POST /agents/{agentId}/tags/generate` — designer et helt sæt regler (tagnavnene og "anvend når…"-formuleringen bag hver enkelt) ved at læse Agentens egne instruktioner og mål.

| Felt | Beskrivelse |
|---|---|
| `mode` | `merge` (standard) beholder de regler, der allerede er på Agenten, og tilføjer til dem. `replace` designer sættet fra bunden. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/generate?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mode": "merge" }'
```

**Respons** (`202`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "mode": "merge" }
```

Arbejdet kører i baggrunden. Læs Agenten og hold øje med `tag_generation.status`; selve reglerne lander i Agentens `tags`. Kun én kørsel ad gangen pr. Agent (`409` ellers), og det bruger AI-kreditter.

---

## Videnskilder

Videnskilder er de sider og dokumenter, som platformen har læst for dig. Ved at tilknytte en til en Agent kan den svare ud fra det indhold.

**Hvor kilde-id'er kommer fra.** Tilføj indhold med vidensbase-slutpunkterne — `POST /kb-sources/url` for en side, `POST /kb-sources/file` for et dokument, `POST /kb-sources/bulk-import` for et helt websted. De returnerer et `source_id`, som du poller med `GET /kb-sources/{sourceId}`, indtil det er klar. `POST /kb-sources/url` tager også `autoLinkToAgentId`, som tilknytter kilden til en Agent, så snart importen er færdig, så du kan springe tilknytningskaldet nedenfor over.

### Tilknyt videnskilder

`POST /agents/{agentId}/kb-sources` — send `kb_source_ids` med en liste for at tilknytte et helt sæt i ét kald (hvad du ønsker efter crawling af et websted), eller `kb_source_id` for en enkelt. Send den ene eller den anden. At tilknytte noget, der allerede er tilknyttet, ændrer intet.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/kb-sources?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kb_source_ids": ["kb2QwErTyUi9OpAs", "kb6ZxCvBnM4kLjHg"] }'
```

**Svar** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "kb_source_id": "kb2QwErTyUi9OpAs",
  "kb_source_ids": ["kb2QwErTyUi9OpAs", "kb6ZxCvBnM4kLjHg"]
}
```

### Frakobl videnskilder

`DELETE /agents/{agentId}/kb-sources/{kbSourceId}` for én, eller `POST /agents/{agentId}/kb-sources/bulk-remove` med `kb_source_ids` for flere. Massefjernelse er en `POST`, fordi listen over id'er sendes i brødteksten.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/kb-sources/bulk-remove?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kb_source_ids": ["kb2QwErTyUi9OpAs"] }'
```

Selve kilderne slettes ikke og forbliver tilgængelige for dine andre agenter. At fjerne tilknytningen til noget, der ikke er tilknyttet, ændrer intet.

### Ofte stillede spørgsmål (FAQ)

Ofte stillede spørgsmål administreres på deres egne slutpunkter og linkes til en agent derfra: `POST /faqs/{faqId}/link` med `{ "agent_id": "ag7HkQ2ZpLxR3mNb" }`, og `POST /faqs/{faqId}/unlink` for at fjerne det igen. Et FAQ-element kan deles af et vilkårligt antal agenter. Se [FAQs API](faqs.md).

> Et FAQ-element bruges kun af de agenter, det er linket til — at oprette et er ikke nok i sig selv.

---

## Værktøjer

### Brugerdefinerede funktioner

`POST /agents/{agentId}/custom-functions` lader agenten kalde en af dine brugerdefinerede funktioner under samtaler. Kun funktioner, der tilhører den samme konto, kan tilknyttes, og at tilknytte en, der allerede er tilknyttet, ændrer intet.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/custom-functions?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "custom_function_id": "cf7Hk2ZpLxR3mNbV" }'
```

`DELETE /agents/{agentId}/custom-functions/{customFunctionId}` fjerner tilknytningen. Selve funktionen slettes ikke og forbliver tilgængelig for dine andre agenter.

Administrer selve funktionerne på `/custom-functions` — se [Brugerdefinerede funktioner](../ai-automation/custom-functions.md) for at læse om, hvad de er.

### MCP-servere

En MCP-server er en færdig pakke af værktøjer, som din agent selv kan finde og kalde — se [Forbind MCP-servere til din bot](../ai-automation/mcp-servers.md). Serverne registreres én gang på kontoen og tilknyttes derefter de agenter, der skal bruge dem.

> MCP-servere kræver funktionen **brugerdefinerede funktioner** i dit abonnement. Uden den returnerer `/mcp-servers`-slutpunkterne på kontoniveau `403`. Tilknytning af en allerede registreret server til en agent er ikke begrænset.

#### Registrer en server

`POST /mcp-servers`

| Felt | Påkrævet | Beskrivelse |
|---|---|---|
| `name` | Ja | En etiket for serveren. |
| `url` | Ja | Serverens adresse. Skal kunne nås via det offentlige internet. |
| `auth_type` | Nej | `header` (standard) for en statisk godkendelsesoverskrift, eller `oauth2`. |
| `auth_header_name` | Nej | Overskrift til afsendelse af legitimationsoplysninger. Standard er `Authorization`. |
| `auth_header_value` | Nej | Selve legitimationsoplysningerne. Returneres aldrig i noget svar. |
| `enabled` | Nej | Om serveren er tilgængelig for agenter. Standard er `true`. |
| `enabled_tools` | Nej | Tilladelsesliste over værktøjsnavne. `null` betyder, at alle værktøjer, som serveren tilbyder, er aktiveret. |
| `tool_policies` | Nej | Grænser pr. værktøj, angivet efter værktøjsnavn — hvor ofte et værktøj må køre, resultatcaching og en skrivebeskyttet tilsidesættelse. Send `null` for at rydde dem alle. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/mcp-servers?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Inventory",
    "url": "https://tools.example.com/mcp",
    "auth_header_value": "Bearer sk_live_xxx"
  }'
```

**Svar** (`201`)

```json
{
  "success": true,
  "server_id": "ms4TgBnH7yUj2kLp",
  "tools": [{ "name": "check_stock", "description": "Look up stock for a SKU." }],
  "last_error": null,
  "server": { "server_id": "ms4TgBnH7yUj2kLp", "name": "Inventory", "...": "..." }
}
```

Ved lagring opretter platformen forbindelse til serveren og cacher listen over værktøjer, den tilbyder. **En server, der ikke kan nås, gemmes stadig**, med årsagen i `last_error` og en tom værktøjsliste — så du kan registrere først og løse forbindelsesproblemer bagefter.

En `auth_type` af `oauth2` gemmer registreringen med `oauth_connected: false` og ingen værktøjer: der er endnu intet token. Godkendelse af en OAuth-server kræver et browser-login og gøres fra dashboardet, ikke via API'et.

#### List, opdater og slet servere

- `GET /mcp-servers` — hver registreret server, nyeste først, under `servers`.
- `PUT /mcp-servers/{serverId}` — send kun det, du vil ændre. Ændring af URL'en eller godkendelsesfelterne tester forbindelsen igen og opdaterer den cachede værktøjsliste.
- `DELETE /mcp-servers/{serverId}` — fjerner registreringen og fjerner linket fra enhver agent og kampagne, der havde den aktiveret.

```bash
curl "https://api.youraiconnector.com/v1/mcp-servers?apiKey=YOUR_API_KEY"
```

**Hemmeligheder kommer aldrig tilbage.** Svar indeholder `auth_header_value_set` (et `true`/`false` flag, der angiver, at en værdi er gemt) i stedet for legitimationsoplysningerne, og OAuth-tokens og klienthemmeligheder forbliver på serversiden. Alt andet returneres: `name`, `url`, `enabled`, `auth_type`, `auth_header_name`, `tools`, `enabled_tools`, `tool_policies`, `oauth_connected`, `tools_cached_at`, `last_connected_at`, `last_error`, `created_at`, `updated_at`.

#### Test en forbindelse

`POST /mcp-servers/test-connection` — opretter forbindelse til en server og viser dens værktøjer. To måder at kalde den på:

- med `server_id` — tester den **gemte** konfiguration og opdaterer dens cachede værktøjsliste;
- med en inline `url` (plus `auth_header_name` / `auth_header_value`) — en test før lagring, der ikke gemmer noget.

```bash
curl -X POST "https://api.youraiconnector.com/v1/mcp-servers/test-connection?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://tools.example.com/mcp", "auth_header_value": "Bearer sk_live_xxx" }'
```

**Svar** (`200`)

```json
{
  "success": true,
  "server_name": "Inventory tools",
  "tools": [{ "name": "check_stock", "description": "Look up stock for a SKU." }]
}
```

En forbindelsesfejl er **ikke** en HTTP-fejl — du får en `200` med `success: false` og en `error`, der beskriver, hvad der gik galt, så du kan vise det ved siden af det felt, operatøren redigerer.

#### Tilknyt en server til en agent

Registrering af en server giver ikke nogen agent adgang til den. Tilknyt den:

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/mcp-servers?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mcp_server_id": "ms4TgBnH7yUj2kLp" }'
```

**Svar** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "mcp_server_id": "ms4TgBnH7yUj2kLp" }
```

`DELETE /agents/{agentId}/mcp-servers/{mcpServerId}` fjerner tilknytningen igen. Selve serveren slettes ikke og forbliver tilgængelig for dine andre agenter. Tilknytning eller fjernelse af tilknytning for noget, der allerede er i den tilstand, ændrer intet.

---

## Mediebibliotek

Mediebiblioteket indeholder de filer, en agent kan sende under en samtale — en menu, en prisliste, et produktbillede. En agent kan højst have **50 elementer**.

### List medier

`GET /agents/{agentId}/media-library`

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library?apiKey=YOUR_API_KEY"
```

**Svar** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "media_items": [
    {
      "id": "mi4RtY7uIoP1aSdF",
      "item_id": "mi4RtY7uIoP1aSdF",
      "media_home": "agent",
      "title": "Spring menu",
      "description": "Send when someone asks what is on the menu.",
      "ai_description": "A one-page menu listing seasonal dishes and prices.",
      "type": "document",
      "media_content_type": "application/pdf",
      "media_url": "https://storage.googleapis.com/...",
      "max_sends_per_conversation": 1,
      "created_at": 1700000000000
    }
  ]
}
```

Elementer gemt på agenten kommer først, efterfulgt af ældre elementer, der stadig er gemt på den kampagne, som agenten blev oprettet fra; `media_home` (`agent` eller `campaign`) angiver, hvad der er hvad. Inden for hver gruppe vises det nyeste først.

> **`media_url` udløber efter 7 dage.** Det er download-linket, der blev oprettet, da filen blev uploadet – betragt et gammelt link som forældet frem for ødelagt, og hent listen igen for at få et nyt link.

### Upload medier

`POST /agents/{agentId}/media-library` – filen uploades inline som base64, op til **10 MB**. Kaldet returnerer, når filen er gemt, så forvent lidt længere svartid end ved en normal anmodning. Bemærk, at denne body bruger camelCase-feltnavne.

| Felt | Påkrævet | Beskrivelse |
|---|---|---|
| `base64Data` | Ja | Filindhold, base64-kodet, uden et data-URL-præfiks. |
| `mimeType` | Ja | MIME-type for filen. |
| `fileName` | Ja | Oprindeligt filnavn, der bruges til at navngive den gemte fil. |
| `title` | Nej | Kort etiket, der vises i biblioteket. |
| `description` | Nej | Instruktionen "hvornår skal agenten sende dette". |
| `sendMessage` | Nej | Foretrukken ordlyd, som agenten bruger, når den sender elementet. Beskæres til 500 tegn. |
| `maxSendsPerConversation` | Nej | Hvor mange gange det må sendes til den samme kontakt i én samtale. Standard er `1`. |
| `sendAsVoiceNote` | Nej | Kun lyd-uploads – gem filen som en WhatsApp-talebesked. Ignoreres for andre filtyper. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "base64Data": "JVBERi0xLjQKJcfs...",
    "mimeType": "application/pdf",
    "fileName": "spring-menu.pdf",
    "title": "Spring menu",
    "description": "Send when someone asks what is on the menu.",
    "maxSendsPerConversation": 1
  }'
```

To ting sker automatisk: en animeret GIF konverteres til video, så den kan afspilles på alle kanaler, og platformen skriver et kort resumé af, hvad filen faktisk indeholder, så agenten ved, hvornår den passer ind.

En `400` dækker over manglende felter, en ikke-understøttet filtype, en tom eller for stor fil samt overskridelse af grænsen på 50 elementer. En `403` betyder, at mediebiblioteket er deaktiveret for kontoen.

### Opdater et medieelement

`PATCH /agents/{agentId}/media-library/{itemId}` – kun metadata. Selve filen kan ikke erstattes; upload et nyt element og slet det gamle. Denne body bruger snake_case: `title`, `description`, `send_message`, `max_sends_per_conversation` (et ikke-negativt heltal, eller `null` for at fjerne grænsen).

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library/mi4RtY7uIoP1aSdF?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Summer menu", "max_sends_per_conversation": 2 }'
```

**Svar** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "item_id": "mi4RtY7uIoP1aSdF",
  "campaign_id": "",
  "media_home": "agent"
}
```

### Slet et medieelement

`DELETE /agents/{agentId}/media-library/{itemId}` – fjerner elementet og dets gemte fil. Sletning af et element, der allerede er væk, lykkes og rapporterer `deleted: false`, så kaldet er sikkert at forsøge igen.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library/mi4RtY7uIoP1aSdF?apiKey=YOUR_API_KEY"
```

---

## Generer opfølgningsbeskeder

`POST /agents/{agentId}/template-generation` – skriver agentens opfølgningsbeskeder for dig (de påmindelser, den sender, når en samtale går i stå), baseret på hvad agentens formål er.

| Felt | Beskrivelse |
|---|---|
| `type` | `all` (standard) skriver hele sættet. `cold_only` skriver kun beskederne til kontakter, der aldrig har svaret. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/template-generation?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "all" }'
```

Der er to måder, dette returneres på, og feltet `target` fortæller dig hvilken:

- **`target: "agent"` med en `200`** — beskederne blev skrevet under opkaldet, og resultatet findes i `data`. Læs dem fra agentens `follow_up_config`. Dette er det normale tilfælde.
- **`target: "campaign"` med en `202`** — arbejdet blev sat i kø til kampagnen navngivet i `campaign_id`. Hold øje med kampagnens `template_generation_status`, indtil den er færdig.

`cold_only` kræver en udgående kampagne og afvises med `409` (`reason: "cold_only_requires_campaign"`) på en agent, der ikke har nogen. En `403` betyder, at automatiske opfølgninger ikke er slået til for kontoen. Dette bruger AI-kreditter, og en `400` med `"Insufficient credits."` betyder, at kontoen er løbet tør.

---

## Routing af samtaler til en agent

En agent besvarer kun de samtaler, som et **indgangspunkt** sender til den. Indtil en kanal har et, gemmes den første besked fra en person, du aldrig har talt med, men intet samler den op, og ingen assistent svarer.

| Hvad du vil gøre | Kald |
|---|---|
| Gør en agent til besvarer for en hel kanal | `PUT /entry-points/channel-defaults` med `{ "channel": "instagram", "agent_id": "AGENT_ID" }` |
| Tilføj en mere specifik regel (nøgleord, kommentarer, nye følgere) | `POST /agents/{agentId}/entry-points` |
| Se reglerne, der peger på én agent | `GET /agents/{agentId}/entry-points` |
| Efterlad en kanal uden nogen til at svare | `DELETE /entry-points/channel-defaults?channel=instagram` |

### Vis en agents indgangspunkter

`GET /agents/{agentId}/entry-points` — de routing-regler, der sender samtaler til denne agent, nyeste først. Både nuværende og pensionerede regler returneres; en pensioneret regel har `enabled: false`.

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/entry-points?apiKey=YOUR_API_KEY"
```

For hele kontoens kanalstandarder, inklusive en kanal, der bevidst er sat til ingen, skal du læse `GET /entry-points/channel-defaults` i stedet.

### Opret et indgangspunkt

`POST /agents/{agentId}/entry-points` — agenten i stien vinder altid, så en regel kan aldrig oprettes for en anden agent end den, der er i URL'en.

| `type` | Hvad den gør |
|---|---|
| `channel_default` | Agenten besvarer enhver ny kontakt på de angivne kanaler. Foretræk `PUT /entry-points/channel-defaults` til dette — den pensionerer den tidligere besvarer for dig, hvilket oprettelse af en anden standard her ikke gør. |
| `keyword` | Agenten tager over, når den første besked indeholder et af `match_config.keywords`. Mindst ét nøgleord er påkrævet. |
| `instagram_comment` / `facebook_comment` | Agenten svarer på kommentarer til dine opslag. Den matchende kanal skal være angivet i `channels`. |
| `instagram_follower` | Agenten hilser på nye følgere. |

`channels` er påkrævet og angiver, hvilke kanaler reglen dækker — for eksempel `whatsapp`, `whatsapp_web`, `instagram`, `messenger`, `telegram`, `sms`, `email`, `chat_widget` eller `custom_channel`. Nye regler er aktiveret, medmindre du angiver andet.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/entry-points?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "keyword",
    "channels": ["whatsapp", "instagram"],
    "match_config": { "keywords": ["pricing", "quote"] }
  }'
```

**Svar** (`201`)

```json
{ "success": true, "entry_point_id": "ep3KmQ8vTzXr5nWd" }
```

**Hvilken regel vinder, når flere kan:** en igangværende samtale eller en manuel tildeling beholder den agent, den allerede har; ellers slår nøgleordsregler kommentarregler, som slår følgerregler, og en kanalstandard er sidste udvej. Hvorvidt disse regler overhovedet bestemmer noget på en konto, rapporteres af `GET /entry-points/routing-status`.

Dette er den korte version. Guiden [Entry Points API](entry-points.md) dækker hele stigen, regler for kommentarer og følgere, én agent pr. WhatsApp-nummer samt ændring eller sletning af en regel. Se [Entry Points](../ai-agents/entry-points.md) for konceptet og [Channels API](channels.md) for at forbinde selve kanalen.

---

## Fejl i AI Agents API

Agent-endepunkter returnerer standardfejl-konvolutten:

```json
{
  "success": false,
  "error": "Agent not found"
}
```

| Status | Hvornår det sker på et Agent-endepunkt |
|---|---|
| `400` | Et påkrævet felt mangler eller er ugyldigt — en tom opdateringskrop, en værdi uden for en tilladt liste (`ai_speed`, `anthropic_model`, `booking_provider`, `mode`, `type`), en nøgle der ikke er en ugedag i `availability`, et feltnavn med punktum i `bot-config`, eller et forkert formateret id i stien. |
| `403` | Kontoen har ikke tilladelse til at bruge en indstilling, du har sendt, du har nået din plans grænse for agenter, eller en funktion, som dette endepunkt kræver (mediebibliotek, opfølgninger, brugerdefinerede funktioner til MCP-servere), er deaktiveret. En ændring, der overstiger den konfigurationsstørrelse, din plan tillader, afvises med `400`. |
| `404` | Agenten, tag-reglen, medieelementet eller MCP-serveren blev ikke fundet — enten eksisterer den ikke, eller også tilhører den en anden konto. |
| `409` | Noget er allerede i gang eller i vejen: en optimering eller tag-generering kører, agenten er stadig tilknyttet en udsendelse, et indgangspunkt eller en kampagne, eller `cold_only` blev anmodet om uden en udgående kampagne. |

De delte koder, som ethvert endpoint kan returnere — `401`, `403` (din plan inkluderer ikke API-adgang), `429` (rate limit) og `500` — er angivet med vejledning om genforsøg i [Errors & Pagination](errors-and-pagination.md).

> **En note om udforskeren.** `/agents`-endepunkterne findes i den publicerede OpenAPI-specifikation, så du kan gennemse deres præcise felter og køre live-anmodninger i [API-referencen](reference.md). `/mcp-servers`-endepunkterne på kontoniveau findes også i specifikationen, så du kan udforske dem der også.


---

## Relateret

- [AI-agenter](../ai-agents/ai-agents.md) — hvad en agent er, forklaret i almindeligt sprog.
- [Indgangspunkter](../ai-agents/entry-points.md) — hvordan samtaler dirigeres til en agent.
- [FAQ-API](faqs.md) — opbyg og link den viden, din agent svarer ud fra.
- [Kanal-API](channels.md) — forbind de kanaler, en agent svarer på.
- [Forbind MCP-servere til din bot](../ai-automation/mcp-servers.md) · [Brugerdefinerede funktioner](../ai-automation/custom-functions.md)
- [API-reference](reference.md) — den fulde interaktive endepunktsudforsker.
