nessie

API

HTTP API, mis on iga Nessie kliendi aluseks, ning kuidas sellele autentida.

Mis on API

Nessie’l on üks HTTP-API. Administraatori veebirakendus, macOS- ja iOS-kliendid ning kaug-executori deemon on kõik selle tavalised kliendid ja ükski toiming ei ole kättesaadav muul teel. See on Fastify serveril põhinev JSON-API. See ei ole GraphQL ega ole sellel eraldi „avalikku“ alamhulka: pind, mida teie enda skriptid kutsuvad, on see, mida toode ise kasutab.

Teeosas ei ole versiooninumbrit. Kõik marsruudid asuvad /api all, välja arvatud sissetulev MCP-lõpp-punkt POST /mcp ja mõned /.well-known/ avastamisdokumendid. Ühilduvust hoitakse sellega, et välju ainult lisatakse, nii et klient, mis ei tunne ära kõike, mida saab, töötab edasi.

Baas-URL

Nessie on isemajutatud, seega on baas-URL see päritolu, kust teie juurutus API-d pakub. Operaator seab selle väärtuseks NESSIE_API_PUBLIC_URL ja sama väärtust kasutab API, kui tal on vaja ise luua absoluutne URL. Meie käitatavas instantsis on see https://api.nessie.works; pnpm dev-ga käivitatud arendusinstants vastab aadressil http://localhost:5454.

Administraatori veebirakendus on API-st eraldi päritolu, seega kehtib brauserikklientidele CORS-i lubatud loend (NESSIE_CORS_ORIGINS). Skriptide ja serverite päringutel ei ole kontrollitavat päritolu ning need ei ole sellest mõjutatud.

Autentimine

Iga päring, välja arvatud väike hulk tahtlikult avalikke marsruute, kannab standardses päises juurdepääsutokenit:

Authorization: Bearer <token>

Token on API poolt välja antud allkirjastatud JWT. See kehtib lühikest aega, vaikimisi kolmkümmend minutit (NESSIE_AUTH_TOKEN_TTL), ja see on ainus volitus, mida tavaline kutsuja kunagi esitab. Nessiel ei ole pikaajalisi isiklikke API-võtmeid. Kui soovite, et skript API-d kutsuks, logib see sisse samamoodi nagu inimese brauser ja uuendab tokenit vajadusel.

Tokeni saamine

POST /api/auth/session loob seansi. See vastab juurdepääsutokeni ja kutsuja isikuandmetega ning seab uuendustokeni eraldi HTTP-only küpsisena.

Kuidas end tuvastate, sõltub sellest, kuidas instants on juurutatud. local režiimis töötav instants võtab vastu e-posti ja parooli. hosted või selfHosted instantsil on parooliga sisselogimine otse keelatud, vastusega 403 PASSWORD_AUTH_DISABLED, ja ainus sissepääs on seadistatud identiteedipakkuja. Nii ei saa konto kunagi tekitada selle kõrvale teist, nõrgemat identiteeditee.

Sisselogimine identiteedipakkuja kaudu

Ühekordne sisselogimine (SSO) on OAuthi autoriseerimiskoodi vahetus PKCE-ga kolmes sammus. Nessie identiteedipakkuja on UnlikeOtherAI, mis omab ka organisatsiooni ja meeskondade struktuuri, mida instants peegeldab. Allolev vahetus on sama kuju mis iga seadistatud pakkuja puhul.

  1. GET /api/auth/providers loetleb, mida see instants aktsepteerib. Igaühel on providerId, silt ja see, kas sisselogimisleht suunab automaatselt sinna.
  2. GET /api/auth/providers/:providerId/authorize vastab päringuparameetrite codeChallenge, redirectUri ja state abil väärtusega { data: { authorizeUrl } }. Suunake inimene sinna.
  3. Pakkuja suunab inimese tagasi teie redirectUri-i koodiga. Saatke see tagasi POST /api/auth/session-ile kehaga { providerId, code, codeVerifier, redirectUri }. Kõik neli on koos nõutud ja mittetäielik komplekt annab vastuseks 400 EXTERNAL_AUTH_INCOMPLETE.

Seansi uuendamine

Uuendustokenit ei ole kunagi vastuse kehas. See seatakse HTTP-only küpsisena nimega nessie_refresh, mille ulatus on /api/auth tee all, ja vaikimisi kolmkümmend päeva (NESSIE_AUTH_REFRESH_TOKEN_TTL). POST /api/auth/refresh väljakutsumine selle küpsisega kasutab selle ära, väljastab uue juurdepääsutokeni ja seab uue küpsise selle asemele. Tokenid vahetuvad iga kord, nii et varastatud token kehtib ainult seni, kuni päris klient järgmisena uuendab.

Mitmesse kontosse sisse logitud brauser hoiab iga sisselogimise kohta sellist küpsist nimega nessie_refresh_<slot> ja märgib päringu puhul, millest see käib, päise x-nessie-account-slot abil. Klient, kes sellist päist ei saada, viitab küpsisele nessie_refresh, mis on kõik, mida käsurea klient vajab.

Käsurea klient vajab seega küpsisefaili. curl-iga on selleks --cookie-jar sisselogimisel ja --cookie uuendamisel, nagu allpool töönäites.

Mida kontrollitakse igal päringul

Autentimine ei ole ainult allkirja kontroll. Enne käsitleja käivitamist kontrollib API tokeni allkirja ja aegumist, kinnitab, et seanss ei ole tühistatud (nii kasutajapõhise tokenversiooni kui ka üksiku seansi ID järgi), ning laadib kutsuja liikmelisuse organisatsioonis, mida token nimetab. Deaktiveeritud liikmelisus annab 403. Kui organisatsioon põhineb välisel identiteedipakkujal, kontrollitakse kutsuja praegust staatust selle pakkuja vastu päringu ajal, mitte tokenist lugedes, nii et väliselt eemaldatud juurdepääs lakkab kohe, mitte järgmisel aegumisel.

Muud volitused, mis ei ole seansi tokenid

Olemas on veel kaks kandja-tüüpi volitust ja kumbki neist ei ole üldotstarbeline võti. Hääleseadme volitust võetakse vastu ainult häälkõnede marsruutidel; agendi juurdepääsuvolitust ainult MCP-lõpp-punktil. Kumbagi esitamine mujal lükatakse tagasi 403-ga, mis nimetab volituse, ega proovita uuesti nõrgema seansina. Vaadake MCP ja ühendatud tööriistad, kuidas agendi volitus väljastatakse.

Vastuse ümbris

Iga edukas vastus on objekt võtmega data. Juurtasemel ei ole paljast massiivi ega sisu, nii et klient ei pea kunagi kujust lähtuvalt eristama:

{
  "data": { "id": "3f1c…", "label": "engineering" }
}

Loendi lõpp-punktid lisavad selle kõrvale objekti meta. Ülemisele tasemele ei lisata kunagi midagi muud.

Vead kasutavad samuti ühte kuju, olenemata sellest, mis neid tekitas:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A message needs content or at least one attachment",
    "field": "body",
    "details": { "formErrors": [], "fieldErrors": {} }
  }
}

code on masinloetav osa ja selle alusel tuleks otsustada; message on inimesele. field ja details on olemas, kui viga on piisavalt täpne, et seda asukohastada. Käsitlemata serveriviga on alati 500 INTERNAL_ERROR kindla sõnumiga. Alusveateksti logitakse, kuid seda ei tagastata, sest see võis oma teel välja tulles endasse võtta päringuandmeid.

Vead, mida kohtate esimesena

StaatusKoodTähendus
400VALIDATION_ERRORKeha või päring ei vastanud skeemile.
401AUTH_REQUIREDKandja-token puudub või päis oli vigane.
401TOKEN_EXPIREDJuurdepääsutokeni aeg on läbi. Uuendage ja proovige uuesti.
401TOKEN_REVOKEDSeansist on välja logitud või kõik seansid on sunnitud välja logitud.
403ACCOUNT_DEACTIVATEDSelle organisatsiooni liikmelisus on deaktiveeritud.
404NOT_FOUNDSellist marsruuti ei ole või sellele kutsujale nähtavat kirjet ei ole.
429RATE_LIMITEDPiirang on täis. Lugege Retry-After.
500INTERNAL_ERRORKäsitlemata serveriviga, tahtlikult varjatud.

Lehitsemine

Loendi lõpp-punktid lehitsevad läbipaistva võtmepõhise kursoriga, mitte nihkega. Ridu lisatakse, kui keegi loeb, ja nihkega korduks teine leht vaikselt kirje, mille esimene leht juba näitas.

Vastu võetakse kolm päringuparameetrit: cursor, limit ja direction (forward või backward). Vaikimisi leht on 25 kirjet ja ülempiir 100; suurem väärtus lõigatakse, mitte ei lükata tagasi. Lõpp-punktid, mis sorteerivad või filtreerivad, lisavad veel sort, order ja vabateksti q.

Lehe meta ütleb teile, kus te olete:

{
  "data": [ … ],
  "meta": {
    "hasMore": true,
    "nextCursor": "2026-09-12T08:31:44.005Z|8b2f…",
    "prevCursor": null,
    "total": 134
  }
}

nextCursor ja prevCursor on mõlemad tegelikud: Eelmine ja Järgmine on kontrollid, mida inimene ootab. Need on läbipaistmatud. Server kodeerib nendesse oma sorteerimisvõtme ja klient, kes ühe neist parsib või koostab, puruneb niipea, kui loend muudab järjestust. total on enamikus loendites olemas ja jäetakse välja seal, kus loendamine ei ole mõttekas, näiteks järjestatud otsingutulemustel.

Päringupiirangud

Piirangud kehtivad fikseeritud akna kohta ja need jõustatakse enne, kui päringu keha isegi loetakse. Tagasilükatud päring on 429 koodiga RATE_LIMITED ja päisega Retry-After, mis näitab sekundites.

Enamik piiranguid on seotud kliendi IP-ga. Tundlikud piirangud, nagu sisselogimine, uuendamine, parooli uuesti tõestamine ja MCP-volituste kirjutamised, peavad lisaks ka konto loendurit ning lükkavad tagasi, kui kumbki lävi ületatakse. Nii puutuvad piiranguga kokku nii üks aadress, mis üritab paljusid kontosid, kui ka üks konto, mida rünnatakse paljudest aadressidest. Sisselogimise vaikeväärtus on 10 katset IP kohta ja 5 e-postiaadressi kohta kümne minuti jooksul. Sõnumi postitamine on vaikimisi 60 minutis; kirjutused teel /api/agents on 60 minutis. Iga lävend on juurutuse kohta seadistatav, seega käsitlege neid tarnitud vaikeväärtustena, mitte lepinguna. Tervisekontrollid ja reaalajavood on piirangutest vabad.

Reaalajas

Loendi küsitlemine ei ole õige viis vestluse jälgimiseks. Selle asemel on olemas kolm voogedastuse lõpp-punkti:

  • GET /api/events/stream — serverist saadetud sündmused kõige kohta, mida sisseloginud isik näha võib.
  • GET /api/threads/:threadId/stream — serverist saadetud sündmused ühe lõime kohta. See järgib Last-Event-ID, nii et uuesti ühendamisel jätkatakse, mitte ei alustata uuesti.
  • GET /api/activity — WebSocket, mis kannab tegevusvoogu.

Brauserid ei saa WebSocketi käepigistusel päiseid seada, seega aktsepteerib WebSocket-marsruut juurdepääsutokenit ka päringuparameetrina ?token=. See on ainus koht, kuhu token URL-i kuulub. Kõik muud marsruudid võtavad selle päisest.

Ressursiperekonnad

Lõpp-punkte on üle tuhande, mida on liiga palju, et neid kõiki loetleda. Need on rühmitatud perekondadeks ja kui teate perekonna eesliidet, on üksikud marsruudid ettearvatavad: kollektsioon eesliitel, kirje selle all ja nimetatud toimingud POST-alamteedena.

PerekondEesliideMida katab
Autentimine/api/authSisselogimine, uuendamine, väljalogimine, praegune identiteet ja isiku enda seansid.
Kanalid ja lõimed/api/channels, /api/threadsVestlusmudel: kanalid hoiavad lõimi, lõimed sõnumeid ja vastused pesastuvad juurde.
Agendid/api/agentsAgentide määratlused, nende kanaliseotused, vestlused, ülesanded ja staatus.
Projektid ja tahvlid/api/projects, /api/tasks, /api/iterationsTöö jälgimine: projekti all olevad tahvlid ja veerud, nende ülesanded ning nende kohal olevad iteratsioonid.
Teadmised/api/knowledge-baseVersioonitud lehtede ja failide ruumid, koos kommentaaride, tagasilinkide ja otsinguga.
Post/api/mail, /api/mailbox-connectionsÜhendatud postkastid, agentide postkastid ja mustandid, mille agent kirjutas isikule kinnitamiseks.
Kinnitused/api/approvalsToimingute järjekord, mida agent ei või iseseisvalt teha, ja üks kõne, mis need lahendab.
Audit/api/audit-logOrganisatsiooni räsiahelaga auditijälg koos kontrollimise lõpp-punktiga. Omanikele ja administraatoritele.
Kulud ja kasutus/api/ledger, /api/billingTokenite ja kulude arvestus, eelarved ja käivitusajad; eraldi krediidid ja täiendamised. Omanikele ja administraatoritele.
Organisatsioon ja meeskonnad/api/organizations, /api/teams, /api/usersRentniku, meeskonna ja liikmelisuse haldus, kaasa arvatud kutsed.
Päästikud/api/triggersAjastused ja veebikonksud, mis käivitavad agenditöö, koos nende käivituste ajalooga.
Kõned ja hääl/api/calls, /api/voiceKanalisisesed kõned ning häälassistendi seanss, transkriptsioon ja seadmetokenid.
Executorid/api/executors, /api/execution-environment-templatesMasinad, millel agendid töötavad, nende keskkonnad ja deemoni sidumiskanal.
Käivitused/api/runsElavad agendikäivitused: tühistamine, jätkamine, uuesti alustamine ja sidumine executoriga.
Üleslaadimised/api/uploads, /api/attachmentsLaadige fail esmalt üles, seejärel seostage tagastatud ID sõnumiga.
Otsing/api/messages/searchSõnumite otsing, kogu organisatsioonis või ühe kanali piires.
Saladused ja seaded/api/secrets, /api/settings/scopedAinult kirjutatav mandaatide hoidla selgete õigustega ja kihiliste seadistusväärtustega.
Ühendatud tööriistad/api/mcpMCP-serverid, mida see instants välja kutsub. Vaadake MCP ja ühendatud tööriistad.
Tervis/api/healthElujõulisus ja valmisolek, mõlemad avalikud. /api/health/ready kontrollib ka andmebaasi.

Õigused jõustatakse marsruudi kaupa, mitte perekonna kaupa. Üldiselt on auditijälg, kuluraamat, poliitikareeglid ja mudelite juhtimistasand organisatsiooni omanike ja administraatorite pinnad, samas kui vestlused, projektid, teadmised ja kinnitused on avatud igale liikmele ning piiratud sellega, mida see liige tegelikult näha saab.

Töönäited

Sisselogimine ja uuendusküpsise hoidmine

local-režiimis instantsil, parooliga. Juurdepääsutoken tuleb tagasi kehas; uuendustoken jõuab küpsisefaili.

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
      }
    }
  }
}

Kui token aegub, vahetage küpsis uue vastu:

curl -sS -X POST https://api.example.com/api/auth/refresh \
  --cookie nessie.cookies --cookie-jar nessie.cookies

Vastus on sama { token, me } kuju ja küpsisefailis on nüüd vahetatud uuendustoken.

Loetle kanalid, mida näete

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
    }
  ]
}

Lisage ?teamId=…, et piirduda ühe meeskonnaga, või ?includeArchived=true, et lisada arhiveeritud kanalid. defaultThreadId on see, kuhu postitate järgmisena.

Postitage sõnum

Sõnum vajab kas mingit content-i või vähemalt ühte üleslaaditud manust. Saatke Idempotency-Key, ja korduspäring lahendub sõnumiks, mille esimene katse lõi, mitte ei postita teist koopiat.

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."}'

Uus sõnum on 201:

{
  "data": {
    "message": {
      "id": "d70e…",
      "threadId": "c41a…",
      "role": "user",
      "content": "Deploying the migration now.",
      "createdAt": "2026-09-16T09:04:11.882Z"
    },
    "pendingAgentInvites": []
  }
}

Sama idempotentsusvõtme kordus vastab 200-ga algse sõnumi ja tühja massiiviga pendingAgentInvites, sest esimene katse oli juba teinud teavitamise ja edastamise, mida massiiv kirjeldab.

Selle marsruudi kaks keeldumist väärivad eraldi käsitlemist. Sisu, mis ületab vestluse pikkuspiiri, on 413 MESSAGE_TOO_LARGE ja õige vastus on tekst üles laadida failina. Sisu, mis struktuurilt näeb välja nagu mandaat, on 422 SECRET_INTERCEPTED. Server keeldub enne, kui sõnum on salvestatud, edastatud või logitud, ja mandaat kuulub /api/secrets-i.