
# Bygg en integration från början till slut

Den här guiden går igenom allt du behöver för att köra <span data-t="appName">Your AI Connector</span> från din egen kod, utan att någonsin behöva öppna instrumentpanelen. När du är klar kommer du att ha byggt en minimal integration som:

1. Autentiserar med en API-nyckel
2. Skapar en AI-agent och konfigurerar dess assistentbeteende
3. Ansluter en meddelandekanal (vi använder WhatsApp Web som exempel) och kopplar den till agenten
4. Importerar kontakter
5. Skickar och läser meddelanden
6. Läser analysdata
7. Prenumererar på webhooks för händelser i realtid

Varje steg länkar till den fullständiga resursguiden så att du kan fördjupa dig i detaljerna när du behöver. Den här sidan är kartan; resursguiderna är terrängen.

> **Innan du börjar.** API-åtkomst är en betalfunktion. Om din plan inte inkluderar den kommer varje anrop att returnera `403`. Se [API-åtkomst](../integrations/api-access.md) för att bekräfta att den är aktiverad, och [Autentisering](authentication.md) för alla sätt att skicka med din nyckel.

Alla sökvägar nedan är relativa till bas-URL:en:

```
https://api.youraiconnector.com/v1
```

---

## Steg 1 — Hämta en API-nyckel och gör din första förfrågan

Din API-nyckel finns i appen under **Inställningar → Integrationer → API-nyckel** — en egen sektion under Integrationer, separat från Webhooks, som endast visas när API-åtkomst ingår i planen. Generera en nyckel, kopiera den och lagra den på en säker plats (en serverbaserad hemlig lagring eller miljövariabel — aldrig i webbläsarkod). Fullständiga instruktioner finns i [API-åtkomst](../integrations/api-access.md).

När du har en nyckel, bekräfta att den fungerar genom att anropa hälsokontroll-slutpunkten. Det finns flera sätt att skicka nyckeln; det enklaste är frågeparametern `?apiKey=`, men för riktig kod bör du föredra headern `X-API-Key` så att nyckeln aldrig hamnar i serverloggar eller webbläsarhistorik.

**cURL**

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

**JavaScript**

```javascript
const BASE = "https://api.youraiconnector.com/v1";
const headers = { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" };

const res = await fetch(`${BASE}/health`, { headers });
const data = await res.json();
console.log(data); // { "success": true, ... }
```

**Python**

```python
import requests

BASE = "https://api.youraiconnector.com/v1"
HEADERS = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

res = requests.get(f"{BASE}/health", headers=HEADERS)
print(res.json())  # { "success": true, ... }
```

Varje lyckat svar är inpackat i samma kuvert — ett `success: true`-fält plus resultatdatan. Fel returnerar `success: false` med ett `error`-meddelande och en `error_code`. Se [Fel & Sidnumrering](errors-and-pagination.md) för hela listan och för hur list-slutpunkter sidnumreras med `?limit` och `?cursor`.

> **Hastighetsbegränsning.** Autentiserade anrop är begränsade till **300 per minut** (med ett högre tak på 1 200 per minut per konto). Om gränsen överskrids returneras `429`; vänta en stund och försök igen.

---

## Steg 2 — Skapa en AI-agent

En **AI-agent** är den enhet som innehåller din assistents beteende: dess instruktioner, dess mål, dess aktiva tider och hur den kommunicerar med kontakter. Det är den som svarar på en konversation, så detta är det naturliga första steget att skapa.

Skapa en med `POST /agents`. `name` är det enda fältet som behöver skickas initialt; allt annat kan ställas in med bot-konfigurationsanropet nedan.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Inbound WhatsApp Leads",
    "language": "en"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/agents`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    name: "Inbound WhatsApp Leads",
    language: "en",
  }),
});
const { agent_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/agents",
    headers=HEADERS,
    json={"name": "Inbound WhatsApp Leads", "language": "en"},
)
agent_id = res.json()["agent_id"]
```

Ett lyckat skapande returnerar `201` med det nya ID:t:

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

**Spara `agent_id`** — du kommer att referera till den när du dirigerar kanaler.

### Konfigurera assistenten

`PUT /agents/{agentId}/bot-config` ställer in assistentens beteende. Det *slår samman* fälten du skickar med den befintliga konfigurationen, så allt du utelämnar bevaras:

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/abc123agent/bot-config" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Greet warmly, answer questions about our services, and offer to book a call.",
    "goal": "Book a discovery call.",
    "ai_speed": "balanced"
  }'
```

Ställ in aktiva tider med `PUT /agents/{agentId}/active-hours` så att assistenten endast svarar under kontorstid; utanför dessa tidsfönster svarar den inte automatiskt.

> **Kunskapsbas.** För att låta assistenten svara utifrån ditt eget innehåll, bifoga vanliga frågor (FAQ). Se [FAQ-guiden](faqs.md).

> **Äldre: klassiska kampanjer.** Konton som fortfarande har en **Kampanjer**-sida skapar samma assistentbeteende på en kampanj istället (`POST /campaigns` med ett `type`- och ett `bot`-objekt, sedan `PUT /campaigns/{campaignId}/bot-config`). Den fullständiga listan över kampanjfält och livscykelkontroller finns i [Kampanjguiden](campaigns.md). Om du bygger något nytt, skapa en agent.

---

## Steg 3 — Anslut en kanal

En agent behöver ett sätt att skicka och ta emot meddelanden. Sju anslutningsflöden kan styras via API:et: WhatsApp Business, WhatsApp Web, Instagram och Messenger tillsammans (ett delat Meta-flöde), personliga Instagram-konton, Telegram, LINE och Viber. De övriga kanalerna — bland annat SMS, e-post, chattwidgeten och anpassade kanaler — ställs in i kontrollpanelen istället för via REST, och när de väl är anslutna fungerar slutpunkterna för meddelanden, kontakter och dirigering på exakt samma sätt. `GET /channels` är den aktuella källan för vad ett visst konto faktiskt har anslutet:

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

Den fullständiga uppsättningen av anslutnings-/frånkopplingsflöden för varje kanal finns dokumenterad i [Kanalguiden](channels.md). Nedan går vi igenom **WhatsApp Web** från början till slut, eftersom det visar det mest intressanta mönstret: ett QR-kodsparingsflöde som din wrapper måste rendera och polla.

### Genomgånget exempel: para ihop WhatsApp Web via QR-kod

Parkoppling med WhatsApp Web är en dans i tre anrop — **starta**, **hämta QR-koden**, **polla tills ansluten**.

**1. Starta parkopplingssessionen.** Ange numret du vill ansluta i E.164-format.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "+15551230000" }'
```

```javascript
await fetch(`${BASE}/channels/whatsapp-web/connections`, {
  method: "POST",
  headers,
  body: JSON.stringify({ phone_number: "+15551230000" }),
});
```

```python
requests.post(
    f"{BASE}/channels/whatsapp-web/connections",
    headers=HEADERS,
    json={"phone_number": "+15551230000"},
)
```

**2. Hämta QR-koden och visa den för användaren.** Polla detta var 10–15 sekund. Svaret innehåller den råa `qr_code`-nyttolasten (rendera den som en QR-bild själv) och en `qr_data_url` som är redo att visas.

```bash
curl "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/+15551230000/qr?apiKey=YOUR_API_KEY"
```

```json
{
  "success": true,
  "phone_number": "+15551230000",
  "status": "qr_pending",
  "qr_code": "2@abc...",
  "qr_data_url": "data:image/png;base64,iVBORw0KGgo..."
}
```

I din wrappers användargränssnitt, placera `qr_data_url` direkt i en `<img src="...">` och be användaren att skanna den från **WhatsApp → Länkade enheter** på sin telefon. Om QR-koden går ut (ett `410`-svar), starta om från steg 1 för att få en ny.

**3. Polla statusen tills den ansluter.** Efter att användaren har skannat, fortsätt polla status-slutpunkten tills den rapporterar `connected` (tjänsten kan även rapportera `open`). Betrakta `disconnected` och `not_initialized` som terminala fel.

```python
import time

PHONE = "+15551230000"
while True:
    res = requests.get(
        f"{BASE}/channels/whatsapp-web/connections/{PHONE}/status",
        headers=HEADERS,
    )
    status = res.json()["status"]
    if status in ("connected", "open"):
        print("Connected!")
        break
    if status in ("disconnected", "not_initialized"):
        raise RuntimeError(f"Pairing failed: {status}")
    time.sleep(5)
```

```javascript
async function waitForConnection(phone) {
  while (true) {
    const res = await fetch(
      `${BASE}/channels/whatsapp-web/connections/${encodeURIComponent(phone)}/status`,
      { headers }
    );
    const { status } = await res.json();
    if (status === "connected" || status === "open") return;
    if (status === "disconnected" || status === "not_initialized") {
      throw new Error(`Pairing failed: ${status}`);
    }
    await new Promise((r) => setTimeout(r, 5000));
  }
}
```

> **Observera.** Varje anslutet WhatsApp Web-nummer medför en återkommande månatlig underhållsavgift tills du kopplar från det (`DELETE /channels/whatsapp-web/connections/{phoneNumber}`).

### Dirigera kanalen till din agent

Att ansluta en kanal gör att den fungerar; att dirigera den talar om för plattformen *vilken AI-agent* som ska svara på helt nya inkommande konversationer i den. Ställ in kanalens standard-startpunkt (Entry Point) och ange namnet på den agent du skapade i steg 2:

```bash
curl -X PUT "https://api.youraiconnector.com/v1/entry-points/channel-defaults" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "whatsapp_web", "agent_id": "abc123agent" }'
```

Upprepa anropet en gång per kanal — en kanalstandard per kanal. För att lämna en kanal utan att någon agent svarar, anropa `DELETE /entry-points/channel-defaults?channel=whatsapp_web`; för att kontrollera om startpunktslistan är aktiv för kontot, anropa `GET /entry-points/routing-status`. Den äldre `POST /channels/campaign`-mappningen behålls endast för återställning och används inte längre för inkommande dirigering. Se [Kanalguiden](channels.md) för de andra kanaltyperna och för WhatsApp Business OAuth-flödet.

---

## Steg 4 — Importera dina kontakter

När en kanal är aktiv, ladda in de personer du vill nå. Import-endpointen hanterar upp till **500 poster per anrop**. Varje post behöver ett `phone_number` i internationellt format; allt annat är valfritt. Poster med felaktiga nummer, kanaler som inte stöds eller nummer som redan finns hoppas över — och varje hopp rapporteras med index och orsak, så att du bara kan försöka igen med de som misslyckades.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/import" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      { "phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee" },
      { "phone_number": "+12025551235", "first_name": "Bob" }
    ],
    "defaultChannel": "whatsapp_web"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/contacts/import`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    contacts: [
      { phone_number: "+12025551234", first_name: "Ann", last_name: "Lee" },
      { phone_number: "+12025551235", first_name: "Bob" },
    ],
    defaultChannel: "whatsapp_web",
  }),
});
const result = await res.json();
console.log(`${result.imported} imported, ${result.skipped.length} skipped`);
```

**Python**

```python
res = requests.post(
    f"{BASE}/contacts/import",
    headers=HEADERS,
    json={
        "contacts": [
            {"phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee"},
            {"phone_number": "+12025551235", "first_name": "Bob"},
        ],
        "defaultChannel": "whatsapp_web",
    },
)
result = res.json()
print(f"{result['imported']} imported, {len(result['skipped'])} skipped")
```

Svaret talar om exakt vad som hände:

```json
{
  "success": true,
  "imported": 2,
  "contact_ids": ["contactId1", "contactId2"],
  "skipped": []
}
```

För skapande en i taget, listning/sökning, listor, taggar och anpassade fält, se [Kontaktguiden](contacts.md).

---

## Steg 5 — Skicka och läs meddelanden

### Skicka ett meddelande

Det enklaste sättet att skicka är **kanaloberoende**: ange kontaktens identitet och meddelandetexten, så levererar plattformen det via den kanal kontakten använder. Du kan rikta dig via `contact_id`, eller via `channel` plus det matchande identitetsfältet (`phone_number` för WhatsApp/WhatsApp Web/SMS, `instagram_id` för Instagram, och så vidare).

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/send" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp_web",
    "phone_number": "+12025551234",
    "body": "Hi Ann! Thanks for reaching out."
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/contacts/send`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    channel: "whatsapp_web",
    phone_number: "+12025551234",
    body: "Hi Ann! Thanks for reaching out.",
  }),
});
const { message_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/contacts/send",
    headers=HEADERS,
    json={
        "channel": "whatsapp_web",
        "phone_number": "+12025551234",
        "body": "Hi Ann! Thanks for reaching out.",
    },
)
message_id = res.json()["message_id"]
```

Leveransen är **asynkron** — ett `201` betyder att meddelandet har *accepterats och köats*, inte att det har levererats än. (Kontakter med stör ej-läge eller privat läge aktiverat avvisas med ett `422`.)

```json
{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp_web"
}
```

### Läs en konversation

För att läsa meddelanden, lista dem per kontakt, nyast först, med markörbaserad paginering. Skicka med `next_cursor` från ett svar som `cursor` i nästa för att gå bakåt genom historiken.

```bash
curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&apiKey=YOUR_API_KEY"
```

```python
res = requests.get(
    f"{BASE}/contacts/contact123/messages",
    headers=HEADERS,
    params={"limit": 50},
)
page = res.json()
for msg in page["messages"]:
    print(msg)
next_cursor = page["next_cursor"]  # pass back as ?cursor= for the next page
```

Du kan också filtrera efter innehållstyp (`?filter=text|media|tool_use`) eller riktning (`?direction=inbound|outbound`). [Meddelandeguiden](messages.md) täcker mediebilagor, markering av meddelanden som lästa och sessionsbaserade meddelandevyer.

> **Avfråga inte efter svar.** Att lista meddelanden med en timer fungerar, men det slösar på anrop och skapar fördröjning. För inkommande meddelanden, använd webhooks istället — det är steg 7.

---

## Steg 6 — Läs analysdata

När meddelanden väl flödar ger analyssammanfattningen dig aggregerade antal över ett datumintervall: skickade, levererade, lästa, besvarade, bokade, skapade kontakter och förbrukade/påfyllda krediter. Du får både totaler för intervallet och en nollfylld serie per dag – perfekt för ett instrumentpanelsdiagram. Du kan valfritt begränsa det till en enskild kampanj med `campaign_id` (exemplen nedan använder ett platshållar-kampanj-ID, `abc123campaign`); utelämna parametern för totaler för hela kontot.

```bash
curl "https://api.youraiconnector.com/v1/analytics/summary?from=2026-05-01&to=2026-05-31&campaign_id=abc123campaign&apiKey=YOUR_API_KEY"
```

```javascript
const params = new URLSearchParams({
  from: "2026-05-01",
  to: "2026-05-31",
  campaign_id: "abc123campaign",
});
const res = await fetch(`${BASE}/analytics/summary?${params}`, { headers });
const { totals, by_date } = await res.json();
```

```python
res = requests.get(
    f"{BASE}/analytics/summary",
    headers=HEADERS,
    params={"from": "2026-05-01", "to": "2026-05-31", "campaign_id": "abc123campaign"},
)
data = res.json()
totals = data["totals"]
by_date = data["by_date"]
```

Intervallet är som standard de senaste 30 dagarna och är begränsat till 366 dagar. För användningsloggar per kredit och kostnadsfördelning för AI, se [Analysguiden](analytics.md).

---

## Steg 7 — Prenumerera på webhooks för händelser i realtid

Polling fungerar bra för ett snabbt skript, men en riktig integration bör vara **push-baserad**. Webhooks låter plattformen anropa *din* server i samma ögonblick som något händer — en ny kontakt, ett svar, ett bokat möte, en avslutad chatt.

Upptäck först de exakta händelsenamn du kan prenumerera på:

```bash
curl "https://api.youraiconnector.com/v1/webhooks/events?apiKey=YOUR_API_KEY"
```

```json
{
  "success": true,
  "events": [
    "Contact Created",
    "Human Alerted",
    "Appointment Booked",
    "Replies",
    "New Message",
    "Chat Concluded",
    "Task Created",
    "Daily Summary Created"
  ]
}
```

Skapa sedan en prenumeration som pekar på en HTTPS-URL på din server. Använd de exakta händelsesträngarna från anropet ovan.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "name": "Lead updates hook"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/webhooks`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    url: "https://hooks.example.com/incoming",
    subscribed_to: ["Contact Created", "Replies"],
    name: "Lead updates hook",
  }),
});
const { webhook_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/webhooks",
    headers=HEADERS,
    json={
        "url": "https://hooks.example.com/incoming",
        "subscribed_to": ["Contact Created", "Replies"],
        "name": "Lead updates hook",
    },
)
webhook_id = res.json()["webhook_id"]
```

```json
{
  "success": true,
  "webhook_id": "1",
  "webhook": {
    "id": "1",
    "name": "Lead updates hook",
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}
```

URL:en måste använda HTTPS och vara publikt nåbar. Från och med nu tar din server emot ett POST-anrop för varje prenumererad händelse. Du kan skicka en testleverans, kontrollera en prenumerations status och återaktivera en prenumeration som inaktiverats automatiskt efter upprepade fel — se [Webhook-guiden](webhooks.md) och sidan för [Webhooks](../integrations/webhooks.md) på integrationsnivå för nyttolastformat och verifiering.

---

## Sammanfattning

Här är hela flödet i korthet:

| Steg | Mål | Nyckelanrop |
|---|---|---|
| 1 | Autentisera | `GET /health` |
| 2 | Skapa + finjustera assistenten | `POST /agents`, `PUT /agents/{id}/bot-config`, `PUT /agents/{id}/active-hours` |
| 3 | Anslut en kanal och dirigera den | `POST /channels/whatsapp-web/connections` → hämta QR + status → `PUT /entry-points/channel-defaults` |
| 4 | Ladda kontakter | `POST /contacts/import` |
| 5 | Skicka & läs | `POST /contacts/send`, `GET /contacts/{id}/messages` |
| 6 | Mät | `GET /analytics/summary` |
| 7 | Reagera i realtid | `POST /webhooks` |

En minimal wrapper består bara av dessa sju anrop kopplade till ditt eget gränssnitt. Därifrån kan du lägga till resursguider allt eftersom du behöver mer:

- [Kampanjer](campaigns.md) · [Kontakter](contacts.md) · [FAQ](faqs.md) · [Meddelanden](messages.md) · [Möten](appointments.md)
- [Kanaler](channels.md) · [Mallar](templates.md) · [Analys](analytics.md) · [Webhooks](webhooks.md) · [API-nycklar](api-keys.md)
- Ny här? [Kom igång](getting-started.md) · [Autentisering](authentication.md) · [Fel & Paginering](errors-and-pagination.md)

Stuck on something this guide does not cover? Email [<span data-t="supportEmail">hi@youraiconnector.com</span>](mailto:hi@youraiconnector.com).
