telenoaHjælp
API

Endpoints med eksempler

Alle endpoints i API v1 — henvendelser, kontakter, opkald, viden og Noa Voice — med eksempler i curl og JavaScript.

Alle adresser starter med https://app.telenoa.com/api/v1. Den fulde, maskinlæsbare beskrivelse med alle felter står i openapi.json — den kan læses ind i fx Postman, Insomnia eller en kodegenerator.

Eksemplerne i JavaScript bruger denne lille hjælper (Node 18 eller nyere):

const TELENOA = "https://app.telenoa.com/api/v1";
const NOEGLE = process.env.TELENOA_API_KEY; // tln_live_…

async function telenoa(sti, { metode = "GET", krop, idempotens } = {}) {
  const res = await fetch(TELENOA + sti, {
    method: metode,
    headers: {
      Authorization: `Bearer ${NOEGLE}`,
      ...(krop ? { "Content-Type": "application/json" } : {}),
      ...(idempotens ? { "Idempotency-Key": idempotens } : {}),
    },
    body: krop ? JSON.stringify(krop) : undefined,
  });
  const data = await res.json();
  if (!res.ok) throw new Error(`${data.fejl.kode}: ${data.fejl.besked}`);
  return data;
}

Henvendelser

En henvendelse er en mail, en formular (også fra chat-widgetten) eller et opkald — det samme, som står i Henvendelser i appen.

Felt
statusmodtaget, i_gang, afventer eller loest
mappeindbakke, arkiv eller spam
kanalmail, formular eller opkald
prioritetlav, mellem eller hoej
kategoriKategorien (jeres mærke på henvendelsen), fx { "id": "…", "navn": "Tilbud" }
tildelt_tilMedarbejderen, den er tildelt, eller null
resumeNoas resumé
ekstern_idJeres eget id, hvis I oprettede den med et

List henvendelser

GET /henvendelser — kræver henvendelser:read.

Filtre: status, mappe (standard indbakke), kanal, tildelt_til (et bruger-id eller ingen), kategori_id, kontakt_id, oprettet_efter, oprettet_foer, opdateret_efter, q (fritekst), limit og cursor.

curl "https://app.telenoa.com/api/v1/henvendelser?status=modtaget&kanal=mail&limit=20" \
  -H "Authorization: Bearer $TELENOA_API_KEY"
// Alle henvendelser ændret siden sidste synkronisering
let cursor = null;
do {
  const side = await telenoa(`/henvendelser?opdateret_efter=${sidst}&limit=100${cursor ? `&cursor=${cursor}` : ""}`);
  for (const h of side.data) await gem(h);
  cursor = side.naeste_cursor;
} while (cursor);

Hent én henvendelse

GET /henvendelser/{id} — kræver henvendelser:read. Svaret har også beskeder: mailtråden, ældste først.

curl https://app.telenoa.com/api/v1/henvendelser/6f1c… \
  -H "Authorization: Bearer $TELENOA_API_KEY"

Opret en henvendelse

POST /henvendelser — kræver henvendelser:write.

Henvendelsen behandles præcis som en formular fra jeres hjemmeside: regler og fordeling, spamtjek, Noas resumé og udkast, kvittering til kunden og notifikationer. Den hører under kilden API under Opsætning → Kilder. Sætter I kilden på pause, kan API'et ikke oprette henvendelser.

Send mindst besked eller kontakt.email.

curl -X POST https://app.telenoa.com/api/v1/henvendelser \
  -H "Authorization: Bearer $TELENOA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ordre-1001" \
  -d '{
    "emne": "Spørgsmål til ordre 1001",
    "besked": "Hvornår bliver min ordre leveret?",
    "kontakt": { "navn": "Anna Jensen", "email": "anna@firma.dk" },
    "ekstern_id": "ORD-1001",
    "felter": { "Ordrenummer": "1001" }
  }'
const ny = await telenoa("/henvendelser", {
  metode: "POST",
  idempotens: `ordre-${ordre.id}`,
  krop: {
    emne: `Spørgsmål til ordre ${ordre.id}`,
    besked: ordre.kommentar,
    kontakt: { navn: ordre.navn, email: ordre.email },
    ekstern_id: String(ordre.id),
  },
});

felter er ekstra oplysninger som i en formular (højst 20). Noa ser dem, når hun skriver sit resumé og udkast.

Ret en henvendelse

PATCH /henvendelser/{id} — kræver henvendelser:write. Send kun de felter, der skal ændres: status, mappe, prioritet, tildelt_til, kategori_id, stjernemarkeret, vigtig og svarfrist (ÅÅÅÅ-MM-DD). null fjerner tildeling, kategori og svarfrist.

curl -X PATCH https://app.telenoa.com/api/v1/henvendelser/6f1c… \
  -H "Authorization: Bearer $TELENOA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "loest" }'

Ændringen står på henvendelsens tidslinje i appen med nøglens navn. Bliver en henvendelse løst, sendes tilfredshedsmålingen, hvis I har slået den til.

Svar kunden

POST /henvendelser/{id}/svar — kræver henvendelser:write.

Svaret sendes med det samme fra jeres mailkonto — den, kunden skrev til, ellers den første aktive. Det er samme afsendelse som Send på Noas udkast i appen, og svaret ligger bagefter i tråden. Tomme linjer i tekst bliver til afsnit.

curl -X POST https://app.telenoa.com/api/v1/henvendelser/6f1c…/svar \
  -H "Authorization: Bearer $TELENOA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: svar-6f1c-1" \
  -d '{ "tekst": "Hej Anna\n\nDin ordre bliver leveret på torsdag.\n\nVenlig hilsen\nButikken" }'

Svaret er 409 med koden konflikt, hvis henvendelsen ikke har en mailadresse, eller hvis I ikke har en aktiv mailkonto under Forbindelser → Mail.

Brug altid en Idempotency-Key, når I sender svar. Så får kunden ikke den samme mail to gange, hvis jeres system prøver igen.

Kontakter

En kontakt er en kunde i jeres kundekartotek, med status: ny, i_gang, tilbud_sendt, vundet eller tabt.

List og find kontakter

GET /kontakter — kræver kontakter:read. Filtre: status, q, email, telefon, opdateret_efter, limit og cursor.

curl "https://app.telenoa.com/api/v1/kontakter?email=anna@firma.dk" \
  -H "Authorization: Bearer $TELENOA_API_KEY"

GET /kontakter/{id} henter én kontakt.

Opret en kontakt

POST /kontakter — kræver kontakter:write. En kontakt skal have email eller telefon. Findes der allerede en kontakt med samme mail eller telefon, får I den i stedet (200 og "oprettet": false) — så opstår der ikke dubletter.

const { kontakt, oprettet } = await telenoa("/kontakter", {
  metode: "POST",
  krop: { navn: "Anna Jensen", email: "anna@firma.dk", firma: "Firma ApS", status: "tilbud_sendt" },
});

Ret en kontakt

PATCH /kontakter/{id} — kræver kontakter:write. Felter: navn, firma, cvr, email, telefon, adresse og status.

curl -X PATCH https://app.telenoa.com/api/v1/kontakter/91ab… \
  -H "Authorization: Bearer $TELENOA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "vundet" }'

Opkald

Opkald, Noa har taget på Noa Voice eller i «Tal med Noa».

GET /opkald — kræver opkald:read. Filtre: udfald (besked, booket, omstillet, ubesvaret), startet_efter, startet_foer, limit og cursor.

GET /opkald/{id} giver også udskrift: hvad kunden og Noa sagde, og hvad Noa gjorde undervejs.

curl "https://app.telenoa.com/api/v1/opkald?udfald=besked" \
  -H "Authorization: Bearer $TELENOA_API_KEY"
const opkald = await telenoa(`/opkald/${id}`);
console.log(opkald.resultat.titel, opkald.resume);
for (const tur of opkald.udskrift) console.log(tur.hvem, tur.tekst);

Et opkald har samme id som den henvendelse, det er gemt som. Optagelser følger ikke med i API'et.

Viden til Noa

POST /viden/noter — kræver viden:write. Noten lægges i Videnbase, og Noa bruger den i mails, chat og telefon. titel højst 120 tegn, indhold højst 20.000.

curl -X POST https://app.telenoa.com/api/v1/viden/noter \
  -H "Authorization: Bearer $TELENOA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "titel": "Levering i december", "indhold": "Bestillinger efter 20. december leveres først 2. januar." }'

Er videnbasen fuld, svarer Telenoa 409.

Noa Voice

GET /noa/linje — kræver noa:read. Status, nummer og månedens tal.

{
  "har_linje": true,
  "status": "aktiv",
  "nummer": "+45 35 15 37 20",
  "nummer_e164": "+4535153720",
  "viderestillet_fra": "+45 70 20 30 40",
  "aktiveret": "2026-09-01T08:00:00.000Z",
  "denne_maaned": { "opkald": 112, "minutter": 240, "klaret_af_noa": 71, "beskeder": 30, "omstillet": 11 }
}

Se også

På denne side