API
Vmesnik HTTP API, na katerem stoji vsak odjemalec Nessie, in kako se vanj prijaviti.
Kaj je API
Nessie ima en sam HTTP API. Skrbniška spletna aplikacija, odjemalca za macOS in iOS ter oddaljeni demon izvajalca so vsi običajni odjemalci tega API-ja, do česar koli, kar lahko počnejo, pa ni mogoče priti drugače. Gre za JSON API na strežniku Fastify, ni GraphQL in nima ločenega „javnega“ podnabora: površina, ki jo kličejo vaše lastne skripte, je ista, ki jo kliče izdelek.
V poti ni segmenta z različico. Vse poti so pod /api, razen dohodne končne točke MCP POST /mcp in nekaj dokumentov za odkrivanje v /.well-known/. Združljivost zagotavljamo tako, da polja zgolj dodajamo, zato odjemalec, ki ne prepozna nekaterih polj, še naprej deluje.
Osnovni URL
Nessie gostite sami na svojem strežniku, zato je osnovni URL izvor, na katerem vaša namestitev streže API. Upravljavec ga nastavi kot NESSIE_API_PUBLIC_URL, enaka vrednost pa je tista, ki jo API uporabi, kadar mora sam ustvariti absolutni URL. Na strežniku, ki ga upravljamo mi, je to https://api.nessie.works; razvojna namestitev, zagnana z pnpm dev, pa odgovarja na http://localhost:5454.
Skrbniška spletna aplikacija ima drug izvor kot API, zato so odjemalci v brskalniku podvrženi seznamu dovoljenih izvorov CORS (NESSIE_CORS_ORIGINS). Zahteve iz skripte ali strežnika nimajo izvora, ki bi ga bilo treba preverjati, zato nanje to ne vpliva.
Overjanje
Vsaka zahteva, razen peščice namerno javnih poti, nosi dostopni žeton v standardni glavi:
Authorization: Bearer <token>Žeton je podpisan JWT, ki ga izda API. Velja kratek čas – privzeto trideset minut (NESSIE_AUTH_TOKEN_TTL) – in je edina poverilnica, ki jo običajni klic kdaj predloži. Nessie nima dolgoživih osebnih API-ključev. Če želite, da skripta kliče API, naj se prijavi enako kot brskalnik osebe in sproti obnavlja svoj žeton.
Pridobitev žetona
POST /api/auth/session ustvari sejo. Odgovori z dostopnim žetonom in identiteto klicatelja ter nastavi osveževalni žeton kot ločen piškotek, dostopen samo prek HTTP.
Kako dokažete, kdo ste, je odvisno od tega, kako je namestitev postavljena. Namestitev v načinu local sprejme e-poštni naslov in geslo. Pri namestitvah hosted ali selfHosted je prijava z geslom zavrnjena z 403 PASSWORD_AUTH_DISABLED, edini vhod pa je nastavljeni ponudnik identitete – tako račun nikoli ne more dobiti druge, šibkejše poti do identitete ob njem.
Prijava prek ponudnika identitete
Enotna prijava je izmenjava avtorizacijske kode OAuth s PKCE v treh korakih. Nessiejev lastni ponudnik identitete je UnlikeOtherAI, ki prav tako upravlja strukturo organizacij in ekip, ki jo namestitev zrcali; izmenjava spodaj je enake oblike za vsakega nastavljenega ponudnika.
GET /api/auth/providersnašteje, katere ponudnike namestitev sprejema; vsak imaproviderId, oznako in podatek, ali naj stran za prijavo samodejno preusmeri nanj.GET /api/auth/providers/:providerId/authorizes parametri poizvedbecodeChallenge,redirectUriinstateodgovori z{ data: { authorizeUrl } }. Osebo pošljite tja.- Ponudnik osebo vrne na vaš
redirectUris kodo. To kodo pošljite nazaj kotPOST /api/auth/sessionz{ providerId, code, codeVerifier, redirectUri }– vse štiri vrednosti so obvezne hkrati, nepopoln nabor pa vrne400 EXTERNAL_AUTH_INCOMPLETE.
Obnova seje
Osveževalni žeton nikoli ni v telesu odgovora. Nastavljen je kot piškotek, dostopen samo prek HTTP, z imenom nessie_refresh, omejen na pot /api/auth, z življenjsko dobo privzeto trideset dni (NESSIE_AUTH_REFRESH_TOKEN_TTL). Klic POST /api/auth/refresh s tem piškotkom ga porabi, izda nov dostopni žeton in na njegovo mesto nastavi nov piškotek – žetoni se menjajo, zato je ukraden žeton uporaben le do naslednjega osveževanja pravega odjemalca.
Brskalnik, prijavljen v več računov, hrani en tak piškotek za vsako prijavo, imenovan nessie_refresh_<slot>, zahtevo pa z glavo x-nessie-account-slot označi za tisti, na katerega se nanaša. Odjemalec, ki te glave ne pošilja, se nanaša na nessie_refresh, kar je vse, kar potrebuje odjemalec v ukazni vrstici.
Odjemalec v ukazni vrstici zato potrebuje shrambo piškotkov. Pri curl to pomeni --cookie-jar pri klicu za prijavo in --cookie pri osveževanju, kot v spodnjem primeru.
Kaj se preveri pri vsaki zahtevi
Overjanje ni le preverjanje podpisa. Preden se zažene obdelovalnik, API preveri podpis in rok veljavnosti žetona, potrdi, da seja ni bila preklicana (tako s številko različice žetona za uporabnika kot z id-jem posamezne seje), in naloži članstvo klicatelja v organizaciji, ki jo navaja žeton. Dezaktivirano članstvo pomeni 403. Kadar je organizacija vezana na zunanjega ponudnika identitete, se trenutni status klicatelja pri vsaki zahtevi ponovno preveri pri tem ponudniku in ne bere iz žetona, zato dostop, odvzet zunaj, preneha delovati takoj in ne šele ob naslednjem poteku.
Poverilnice, ki niso žetoni sej
Obstajata še dve drugi nosilni poverilnici, vendar nobena ni splošni ključ. Poverilnica glasovne naprave je sprejeta le na poteh za glasovne klice; poverilnica za dostop agenta le na končni točki MCP. Če jo predložite kjer koli drugje, je zavrnjena s kodo 403, ki navaja poverilnico, in ne poskusi znova kot šibkejša seja – glejte MCP in povezana orodja, kako se izda poverilnica agenta.
Ovojnica odgovora
Vsak uspešen odgovor je objekt s ključem data. Ni golega seznama in ni vsebine na korenski ravni, zato odjemalec nikoli ne bo moral razlikovati med oblikami:
{
"data": { "id": "3f1c…", "label": "engineering" }
}Končne točke seznamov poleg njega dodajo objekt meta. Na vrhnji ravni se nikoli ne dodaja nič drugega.
Tudi napake imajo eno obliko, ne glede na to, kaj jih je sprožilo:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "A message needs content or at least one attachment",
"field": "body",
"details": { "formErrors": [], "fieldErrors": {} }
}
}code je strojno berljiv del, po katerem ravnate; message je namenjen človeku. field in details sta prisotna, kadar je napaka dovolj določna, da jo je mogoče natančno opredeliti. Neobdelana napaka strežnika je vedno 500 INTERNAL_ERROR s fiksnim sporočilom – osnovno besedilo napake se zabeleži, nikoli ne vrne, ker je lahko med potjo ujelo podatke zahteve.
Kode napak, s katerimi se boste najprej srečali
| Status | Koda | Pomen |
|---|---|---|
| 400 | VALIDATION_ERROR | Telo zahteve ali poizvedba ne ustrezata shemi. |
| 401 | AUTH_REQUIRED | Ni nosilnega žetona ali pa je bila glava napačno oblikovana. |
| 401 | TOKEN_EXPIRED | Dostopni žeton je potekel. Osvežite ga in poskusite znova. |
| 401 | TOKEN_REVOKED | Seja je bila odjavljena ali pa so bile prisilno odjavljene vse seje. |
| 403 | ACCOUNT_DEACTIVATED | Članstvo v tej organizaciji je bilo deaktivirano. |
| 404 | NOT_FOUND | Take poti ni ali pa zapis ni viden temu klicatelju. |
| 429 | RATE_LIMITED | Omejitev hitrosti je dosežena. Preberite Retry-After. |
| 500 | INTERNAL_ERROR | Neobdelana napaka strežnika; namenoma brez podrobnosti. |
Razdelitev na strani
Končne točke seznamov so razdeljene na strani z neprozornim kazalcem po ključu, ne z odmikom – vrstice se vstavljajo, medtem ko nekdo bere, in pri odmiku druga stran tiho ponovi zapis, ki ga je prva stran že pokazala.
Sprejeti so trije parametri poizvedbe: cursor, limit in direction (forward ali backward). Privzeta stran ima 25 zapisov, zgornja meja je 100; večja vrednost se omeji, ne zavrne. Končne točke, ki tudi razvrščajo ali filtrirajo, dodajo sort, order in prosto besedilno iskanje q.
Objekt meta strani pove, kje ste:
{
"data": [ … ],
"meta": {
"hasMore": true,
"nextCursor": "2026-09-12T08:31:44.005Z|8b2f…",
"prevCursor": null,
"total": 134
}
}nextCursor in prevCursor sta oba resnična: gumba za prejšnjo in naslednjo stran sta nadzora, ki ju oseba pričakuje. Kazalca sta neprozorna – strežnik vanju zakodira svoj ključ za razvrščanje, odjemalec, ki ga razčleni ali sestavi sam, pa se bo pokvaril takoj, ko seznam spremeni način razvrščanja. total je prisoten pri večini seznamov, izpuščen pa tam, kjer štetje ni smiselno, na primer pri razvrščenih rezultatih iskanja.
Omejitve hitrosti
Omejitve veljajo za fiksna časovna okna in se uveljavijo, še preden se sploh prebere telo zahteve. Zavrnjena zahteva je 429 s kodo RATE_LIMITED in glavo Retry-After v sekundah.
Večina kvot je vezanih na IP naslov odjemalca. Tiste, občutljive na poverilnice – prijava, osveževanje, ponovna potrditev gesla, zapisovanje poverilnic MCP – poleg tega vodijo števec za račun in zavrnejo, kadar se sproži katerikoli od obeh, tako da omejitev zadene tako naslov, ki pošilja v mnoge račune, kot račun, ki je napaden z mnogih naslovov. Privzeta vrednost za prijavo je 10 poskusov na IP naslov in 5 na e-poštni naslov v desetih minutah; za objavo sporočila 60 na minuto; za pisanje pod /api/agents 60 na minuto. Vsak prag je mogoče nastaviti za vsako namestitev, zato te vrednosti obravnavajte kot privzete vrednosti ob dobavi, ne kot zavezo. Preverjanja stanja in pretočni tokovi v realnem času so izvzeti.
Realni čas
Za sledenje pogovoru ni prav, da seznam stalno preverjate. Namesto tega obstajajo tri pretočne končne točke:
GET /api/events/stream— dogodki, ki jih strežnik pošilja za vse, kar lahko prijavljena oseba vidi.GET /api/threads/:threadId/stream— dogodki za eno nit. UpoštevaLast-Event-ID, zato se ob ponovni povezavi nadaljuje, ne začne znova.GET /api/activity— WebSocket, ki prenaša tok dejavnosti.
Brskalniki pri rokovanju WebSocket ne morejo nastavljati glav, zato pot WebSocket prav tako sprejme dostopni žeton kot parameter poizvedbe ?token=. To je edino mesto, kamor žeton sodi v URL; vse druge poti ga sprejmejo v glavi.
Družine virov
Končnih točk je precej več kot tisoč, kar je veliko preveč, da bi jih lahko naštevali. Razvrščene so v družine; ko poznate predpono družine, so posamezne poti predvidljive – zbirka na predponi, zapis pod njo in poimenovana dejanja kot podpoti POST.
| Družina | Predpona | Kaj zajema |
|---|---|---|
| Overjanje | /api/auth | Prijava, obnova, odjava, trenutna identiteta in lastne seje osebe. |
| Kanali in niti | /api/channels, /api/threads | Model pogovora: kanali vsebujejo niti, niti sporočila, odgovori pa so gnezdeni pod korenskim sporočilom. |
| Agenti | /api/agents | Opredelitve agentov, njihove povezave s kanali, pogovori, opravila in stanje. |
| Projekti in table | /api/projects, /api/tasks, /api/iterations | Sledenje delu: table in stolpci pod projektom, naloge nanje in iteracije nad njimi. |
| Znanje | /api/knowledge-base | Prostori z različicami strani in datotek, s komentarji, povratnimi povezavami in iskanjem. |
| Pošta | /api/mail, /api/mailbox-connections | Povezani poštni predali, poštni predali agentov in osnutki, ki jih je agent napisal, da jih oseba odobri. |
| Odobritve | /api/approvals | Vrsta dejanj, ki jih agent ne sme izvesti sam, in en klic, ki jih razreši. |
| Revizija | /api/audit-log | Revizijska sled organizacije z verižnim zgoščevanjem in končno točko za preverjanje. Za lastnike in skrbnike. |
| Stroški in poraba | /api/ledger, /api/billing | Obračun tokenov in stroškov, proračuni ter trajanje izvajanj; ločeno kreditne točke in polnjenja. Za lastnike in skrbnike. |
| Organizacija in ekipe | /api/organizations, /api/teams, /api/users | Upravljanje najemnika, ekip in članstev, vključno z vabili. |
| Sprožilci | /api/triggers | Urniki in webhooki, ki sprožijo delo agentov, z zgodovino sprožitev. |
| Klici in glas | /api/calls, /api/voice | Klicanje znotraj kanala ter seja glasovnega pomočnika, prepis in žetoni naprav. |
| Izvajalci | /api/executors, /api/execution-environment-templates | Stroji, na katerih agenti delajo, njihova okolja in kanal za povezovanje demona. |
| Izvajanja | /api/runs | Izvajanja agentov v živo: preklic, nadaljevanje, ponovni zagon, povezava z izvajalcem. |
| Nalaganja | /api/uploads, /api/attachments | Najprej naložite datoteko, nato vrnjeni id povežite s sporočilom. |
| Iskanje | /api/messages/search | Iskanje sporočil po celi organizaciji ali omejeno na en kanal. |
| Skrivnosti in nastavitve | /api/secrets, /api/settings/scoped | Shramba poverilnic samo za pisanje z izrecnimi dovoljenji ter večplastne konfiguracijske vrednosti. |
| Povezana orodja | /api/mcp | Strežniki MCP, h katerim namestitev kliče. Glejte MCP in povezana orodja. |
| Stanje sistema | /api/health | Živost in pripravljenost, obe javni. /api/health/ready preveri tudi bazo podatkov. |
Pravice se uveljavljajo za vsako pot posebej, ne za družino. Na splošno so revizijski dnevnik, knjiga stroškov, pravila in nadzorna ravnina za sklepanje površine za lastnike in skrbnike organizacije, medtem ko so pogovori, projekti, znanje in odobritve odprti vsakemu članu in zoženi na to, kar ta član dejansko lahko vidi.
Primeri
Prijava in shranjevanje piškotka za obnovo
Na namestitvi v načinu local, z geslom. Dostopni žeton se vrne v telesu odgovora; osveževalni žeton pristane v shrambi piškotkov.
curl -sS https://api.example.com/api/auth/session \
--cookie-jar nessie.cookies \
-H 'Content-Type: application/json' \
-d '{"email":"ada@example.com","password":"…"}'{
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"me": {
"user": {
"id": "1d4e…",
"email": "ada@example.com",
"displayName": "Ada Lovelace",
"roleIds": ["owner"],
"superAdmin": false
},
"session": {
"sessionId": "9c07…",
"issuedAt": "2026-09-16T09:00:00.000Z",
"expiresAt": "2026-09-16T09:30:00.000Z"
},
"context": {
"organizationId": "5a81…",
"projectId": "7b12…",
"teamId": "2e60…",
"channelId": null,
"bootstrapMode": false
},
"auth": {
"providerId": "local",
"providerType": "local-bootstrap",
"autoRedirectToSso": false
}
}
}
}Ko žeton poteče, piškotek zamenjajte za novega:
curl -sS -X POST https://api.example.com/api/auth/refresh \
--cookie nessie.cookies --cookie-jar nessie.cookiesOdgovor ima enako obliko { token, me }, shramba piškotkov pa zdaj hrani zamenjani osveževalni žeton.
Seznam kanalov, ki jih vidite
curl -sS https://api.example.com/api/channels \
-H "Authorization: Bearer $TOKEN"{
"data": [
{
"id": "8b2f…",
"label": "engineering",
"type": "standard",
"visibility": "public",
"projectId": "…",
"projectName": "Platform",
"teamId": "…",
"defaultThreadId": "c41a…",
"unreadCount": 3,
"lastMessageAt": "2026-09-15T18:22:07.441Z",
"viewerCanManage": true
}
]
}Dodajte ?teamId=…, da zožite na eno ekipo, ali ?includeArchived=true, da vključite arhivirane kanale. defaultThreadId je tisto, kamor boste objavili naslednje.
Objava sporočila
Sporočilo potrebuje bodisi nekaj content bodisi vsaj eno naloženo priponko. Pošljite Idempotency-Key, in ponovljena zahteva se razreši v sporočilo, ki ga je ustvaril prvi poskus, namesto da bi objavila drugo kopijo.
curl -sS https://api.example.com/api/threads/c41a…/messages \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 0f9c2d16-8f4a-4c1e-9a77-6b0d4f2e1a53' \
-d '{"content":"Deploying the migration now."}'Novo sporočilo je 201:
{
"data": {
"message": {
"id": "d70e…",
"threadId": "c41a…",
"role": "user",
"content": "Deploying the migration now.",
"createdAt": "2026-09-16T09:04:11.882Z"
},
"pendingAgentInvites": []
}
}Ponovitev z istim ključem idempotentnosti odgovori s 200, z izvirnim sporočilom in praznim pendingAgentInvites, ker je prvi poskus že opravil opozarjanje in pošiljanje, ki ju polje opisuje.
Dve zavrnitvi na tej poti je vredno obravnavati posebej. Vsebina, ki presega omejitev dolžine sporočila, je 413 MESSAGE_TOO_LARGE; pravilen odgovor je, da besedilo naložite kot datoteko. Vsebina, ki je po strukturi videti kot poverilnica, je 422 SECRET_INTERCEPTED – strežnik zavrne sporočilo, preden je shranjeno, poslano ali zabeleženo, poverilnica pa spada v /api/secrets.