API-brug
Lær at bruge API-nøgler til at køre apps programmatisk.
Adgang
- Udvikler, Administrator: Kan oprette og bruge API-nøgler. Anmelder-rollen har ikke adgang — API-nøgler er byggeværktøj.
Forudsætninger
- En aktiv API-nøgle (se API-nøgler)
- En udgivet app du har adgang til
Kør app via API
Endpoint
POST /api/v1/apps/{app_id}/run
Headers
Authorization: Bearer sk_din_api_nøgle
Content-Type: application/json
Request body
{
"inputs": {
"input_felt_1": "værdi",
"input_felt_2": 123
}
}
Fil-inputs
Inputs af typen file sendes som et JSON-objekt med tre felter:
{
"inputs": {
"document": {
"filename": "rapport.pdf",
"mime_type": "application/pdf",
"data": "<base64-kodet indhold>"
}
}
}
| Felt | Beskrivelse |
|---|---|
filename | Det originale filnavn (f.eks. "rapport.pdf") |
mime_type | Filens MIME-type (f.eks. "application/pdf") |
data | Filens indhold, base64-kodet (uden data: prefix) |
Response
Svaret indeholder to felter: execution_id og results.
{
"execution_id": "3f9c1b8a-2c47-4f0e-9c1f-8d2a5b7e4c10",
"results": {
"output_felt": "resultat"
}
}
execution_id er kørslens id — brug det til at slå kørslen op under Kørsler (se Kørselshistorik).
Fil-outputs ligger inde i results i samme format som fil-inputs:
{
"execution_id": "3f9c1b8a-2c47-4f0e-9c1f-8d2a5b7e4c10",
"results": {
"dokument": {
"filename": "resultat.pdf",
"mime_type": "application/pdf",
"data": "<base64-kodet indhold>"
}
}
}
Asynkron kørsel
Lange kørsler - OCR af store PDF'er, løkker, AI-kæder - kan nå at løbe ind i timeout hos din klient eller proxy, mens et almindeligt kald venter på svaret. Start i stedet kørslen asynkront: du får et kørsels-id med det samme og spørger til resultatet bagefter.
Start kørslen
POST /api/v1/apps/{app_id}/run-async
Headers og request body er præcis de samme som ved /run - også fil-inputs.
Svaret kommer med det samme, med statuskoden 202 Accepted:
{
"execution_id": "3f1c...",
"status": "PENDING"
}
Alle afvisninger er de samme som ved /run (401, 404, 410, 422), så en 202 betyder,
at kørslen faktisk er sat i gang. Selve inputtet valideres dog først under kørslen: et
forkert udfyldt felt bliver derfor til en kørsel med status FAILED og den samme
forklaring, som /run ville have svaret 422 med.
Spørg til kørslen
GET /api/v1/apps/{app_id}/runs/{execution_id}
{
"execution_id": "3f1c...",
"status": "COMPLETED",
"results": {
"output_felt": "resultat"
},
"error": null,
"started_at": "2026-09-07T09:00:01Z",
"completed_at": "2026-09-07T09:02:44Z",
"total_nodes": 7,
"completed_nodes": 7
}
| Status | Betydning |
|---|---|
PENDING | Kørslen er accepteret, men er ikke begyndt endnu |
RUNNING | Kørslen er i gang |
COMPLETED | Kørslen er færdig - results indeholder svaret |
FAILED | Kørslen fejlede - error forklarer hvorfor |
results er nøjagtig det samme, som /run ville have svaret med - også filer, der
returneres i samme { filename, mime_type, data }-format.
Kørslen kan kun hentes af den, der startede den: en API-nøgle kan læse sine egne
asynkrone kørsler, men får 403, hvis den spørger til en kørsel, en anden har startet.
Kender appen ikke kørslen, er svaret 404.
Eksempel med cURL
# 1. Start kørslen
EXECUTION_ID=$(curl -s -X POST "https://din-server.dk/api/v1/apps/{app_id}/run-async" \
-H "Authorization: Bearer sk_din_api_nøgle" \
-H "Content-Type: application/json" \
-d '{"inputs": {"tekst": "Hej verden"}}' | jq -r .execution_id)
# 2. Spørg til kørslen
curl "https://din-server.dk/api/v1/apps/{app_id}/runs/$EXECUTION_ID" \
-H "Authorization: Bearer sk_din_api_nøgle"
Eksempel med Python
import time
import requests
BASE = "https://din-server.dk/api/v1"
HEADERS = {"Authorization": "Bearer sk_din_api_nøgle"}
accepted = requests.post(
f"{BASE}/apps/{app_id}/run-async",
headers=HEADERS,
json={"inputs": {"tekst": "Hej verden"}},
)
execution_id = accepted.json()["execution_id"]
while True:
run = requests.get(f"{BASE}/apps/{app_id}/runs/{execution_id}", headers=HEADERS).json()
if run["status"] in ("COMPLETED", "FAILED"):
break
time.sleep(2)
if run["status"] == "COMPLETED":
print(run["results"])
else:
print("Kørslen fejlede:", run["error"])
Kørslen lever i den server, der tog imod kaldet. Bliver serveren genstartet eller
opdateret midt i en kørsel, bliver kørslen ikke genoptaget - den bliver stående som
PENDING eller RUNNING. Start den forfra, hvis en kørsel ikke er blevet færdig
inden for det, du forventer.
Streaming-kørsel
For at modtage real-time opdateringer under kørsel:
Endpoint
POST /api/v1/apps/{app_id}/run-stream
Headers
Authorization: Bearer sk_din_api_nøgle
Accept: text/event-stream
Content-Type: application/json
SSE Events
Du modtager følgende event-typer:
| Event | Beskrivelse |
|---|---|
node_start | En byggeklods starter |
node_complete | En byggeklods er færdig |
node_error | En byggeklods fejlede |
node_skipped | En byggeklods blev sprunget over (f.eks. en gren der ikke blev valgt) |
flow_complete | Hele flowet er færdigt. Felter: results, execution_id |
flow_error | Flowet fejlede. Felter: error, error_type, traceback, execution_id |
Kører flowet en løkke, får du desuden disse events undervejs:
| Event | Beskrivelse |
|---|---|
loop_start | Løkken går i gang |
loop_iteration_start | En gentagelse starter |
loop_iteration_complete | En gentagelse er færdig |
loop_iteration_error | En gentagelse fejlede |
loop_break | Løkken blev afbrudt før tid |
loop_continue | En gentagelse blev sprunget over |
loop_complete | Løkken er færdig med alle gentagelser |
Linjer der starter med : er keepalive-kommentarer, som serveren sender under lange pauser, så forbindelsen ikke lukkes. Din klient skal ignorere dem.
Find appens endpoint og feltnavne
Du behøver ikke gætte hverken adressen eller feltnavnene — appen viser dem selv.
- Åbn appen fra Apps.
- Vælg fanen API (adressen bliver
/apps/{app_id}?tab=api).
Fanen indeholder:
- Endpoint & autentifikation — POST-endpointet med en Kopiér-knap, en note om at bruge din personlige API-nøgle med link til Udviklerværktøjer → API-nøgler, og en tæller der viser antal kald i alt.
- Input-felter og Output-felter — feltnavn, type og mærkatet påkrævet på de felter, der skal med.
- Eksempel på request og Eksempel på response — færdige eksempler på headers, JSON-body, cURL og svaret.

Kopiér feltnavnene direkte fra Input-felter og Output-felter i stedet for at gætte dem. Navnene kommer fra appens opsætning og kan afvige fra det, felterne hedder i brugerfladen.
Begrænsninger
API-nøgler kan kun bruges til at køre apps. De kan ikke:
- Liste agenter
- Oprette agenter
- Liste apps
- Oprette apps
- Ændre brugerdata
- Læse kørselshistorik. Den ene undtagelse er en asynkron kørsel, nøglen selv har startet: den kan hentes med
GET /apps/{app_id}/runs/{execution_id}(se Asynkron kørsel)
Fejlhåndtering
| HTTP Status | Betydning |
|---|---|
202 | Asynkron kørsel accepteret — svaret indeholder execution_id |
401 | Ugyldig eller tilbagekaldt API-nøgle — eller ingen adgang til appen (samme svar i begge tilfælde) |
404 | Appen findes ikke |
410 | Appen er ikke aktiv længere (f.eks. arkiveret) |
422 | Manglende eller forkert input |
500 | Serverfejl |
Fejler selve kørslen (typisk 422 fra flowets egen validering eller 500), er detail en forklaring på dansk, og svaret bærer headeren X-Execution-Id med kørslens id, når kørslen nåede at blive registreret. Brug id'et til at slå kørslen op, når du er logget ind i AgentBase: under Kørsler (kræver Udvikler-rollen) eller via GET /api/v1/executions/{id} med et almindeligt login-token (JWT, mindst Anmelder-rollen). API-nøglen selv kan ikke læse kørsler — bortset fra en asynkron kørsel, den selv har startet (se Asynkron kørsel). Headeren mangler, når kørslen aldrig startede — fx når et påkrævet felt mangler.
Eksempel med cURL
curl -X POST "https://din-server.dk/api/v1/apps/{app_id}/run" \
-H "Authorization: Bearer sk_din_api_nøgle" \
-H "Content-Type: application/json" \
-d '{"inputs": {"tekst": "Hej verden"}}'
Eksempel med Python
import requests
response = requests.post(
"https://din-server.dk/api/v1/apps/{app_id}/run",
headers={
"Authorization": "Bearer sk_din_api_nøgle",
"Content-Type": "application/json"
},
json={"inputs": {"tekst": "Hej verden"}}
)
result = response.json()
print(result["results"])
Eksempel med fil-upload (Python)
import base64
import requests
# Indlæs fil og konvertér til base64
with open("dokument.pdf", "rb") as f:
file_data = base64.b64encode(f.read()).decode("utf-8")
response = requests.post(
"https://din-server.dk/api/v1/apps/{app_id}/run",
headers={
"Authorization": "Bearer sk_din_api_nøgle",
"Content-Type": "application/json"
},
json={
"inputs": {
"document": {
"filename": "dokument.pdf",
"mime_type": "application/pdf",
"data": file_data
}
}
}
)
result = response.json()
print(result["results"])