nessie

API

HTTP-forritaskil (API) á bak við alla Nessie-viðskiptavini og hvernig þú auðkennir þig gagnvart því.

Hvað API-ið er

Nessie er með eitt HTTP-API. Stjórnunarvefforritið, macOS- og iOS-forritin og fjarkeyrsluþjónninn (executor) eru allt venjulegir biðlarar þess, og ekkert af því sem þeir geta gert er aðgengilegt á annan hátt. Þetta er JSON-API ofan á Fastify-þjóni, það er ekki GraphQL, og það er enginn sérstakur „opinber“ hluti: það sem þín eigin forrit kalla á er nákvæmlega það sem varan kallar á.

Engin útgáfuslóð er í leiðunum. Allar leiðir eru undir /api, nema innkomni MCP-endapunkturinn POST /mcp og nokkur /.well-known/-uppgötvunarskjöl. Samhæfni er tryggð með því að bæta eingöngu við reitum, þannig að biðlari sem hunsar það sem hann kannast ekki við heldur áfram að virka.

Grunnvefslóð

Nessie er hýst sjálfstætt, þannig að grunnvefslóðin er hvaða uppruni sem uppsetningin þjónar API-inu á. Rekstraraðilinn stillir hana sem NESSIE_API_PUBLIC_URL, og sama gildi er það sem API-ið notar þegar það þarf að útbúa sína eigin algildu vefslóð. Á þeim þjóni sem við rekum er það https://api.nessie.works; þróunaruppsetning sem er ræst með pnpm dev svarar á http://localhost:5454.

Stjórnunarvefforritið er á öðrum uppruna en API-ið, þannig að vafrabiðlarar falla undir CORS-lista yfir leyfða uppruna (NESSIE_CORS_ORIGINS). Beiðnir frá skrift eða þjóni hafa engan uppruna til að athuga og verða ekki fyrir áhrifum.

Auðkenning

Sérhver beiðni utan lítils hóps opinberra leiða ber aðgangstákn í venjulegum haus:

Authorization: Bearer <token>

Tákn er undirritað JWT-tákn sem API-ið gefur út. Það er skammlíft — þrjátíu mínútur sjálfgefið (NESSIE_AUTH_TOKEN_TTL) — og það er eina skilríkið sem venjulegur biðlari framvísar nokkurn tíma. Nessie er ekki með langlíva persónulega API-lykla. Ef þú vilt að forrit kalli á API-ið skráir það sig inn á sama hátt og vafri manneskju gerir og endurnýjar tákn sitt eftir þörfum.

Að sækja tákn

POST /api/auth/session gefur út lotu. Það svarar með aðgangstákninu og auðkenni þess sem kallar, og setur endurnýjunartáknið í sérstaka vafrakökku sem er aðeins aðgengileg um HTTP (HTTP-only).

Hvernig þú sannar hver þú ert ræðst af því hvernig uppsetningin er keyrð. Uppsetning í local-ham tekur við netfangi og lykilorði. Á hosted- eða selfHosted-uppsetningu er innskráning með lykilorði hafnað með öllu með 403 PASSWORD_AUTH_DISABLED, og eina leiðin inn er um stillta auðkenningaraðilann, þannig að reikningurinn getur aldrei eignast aðra, veikari auðkenningarleið við hlið hans.

Innskráning með auðkenningaraðila

Einskráning (SSO) er OAuth-skipti á heimildarkóða með PKCE í þremur skrefum. Auðkenningaraðili Nessie er UnlikeOtherAI, sem á líka skipulag fyrirtækja og teyma sem uppsetningin speglar; skiptin hér að neðan hafa sama form fyrir hvaða stillta auðkenningaraðila sem er.

  1. GET /api/auth/providers sýnir hverja auðkenningaraðila þessi uppsetning tekur við, hvern með providerId, nafni og því hvort innskráningarsíðan á að beina þangað sjálfkrafa.
  2. GET /api/auth/providers/:providerId/authorize, með codeChallenge, redirectUri og state sem fyrirspurnarbreytum, svarar með { data: { authorizeUrl } }. Sendu manneskjuna þangað.
  3. Auðkenningaraðilinn skilar henni á redirectUri þinn með kóða. Sendu hann til baka sem POST /api/auth/session með { providerId, code, codeVerifier, redirectUri }. Allir fjórir eru nauðsynlegir saman, og ófullkomið sett er 400 EXTERNAL_AUTH_INCOMPLETE.

Endurnýjun lotu

Endurnýjunartáknið birtist aldrei í svarinu. Það er sett sem vafraka, aðeins aðgengileg um HTTP, sem heitir nessie_refresh, bundin við slóðina /api/auth, með þrjátíu daga gildistíma sjálfgefið (NESSIE_AUTH_REFRESH_TOKEN_TTL). Kall á POST /api/auth/refresh með þeirri vafraköku notar hana upp, gefur út nýtt aðgangstákn og setur nýja vafrakökku í hennar stað. Táknin snúast, þannig að stolið tákn gildir aðeins þar til raunverulegur biðlari endurnýjar næst.

Vafri sem er innskráður á nokkra reikninga geymir eina slíka vafrakökku fyrir hverja innskráningu, sem heitir nessie_refresh_<slot>, og tilgreinir þá sem beiðni varðar með hausnum x-nessie-account-slot. Biðlari sem sendir engan slíkan haus á við nessie_refresh, sem er allt sem skipanalínubiðlari þarf.

Skipanalínubiðlari þarf því vafrakökusafn (cookie jar). Með curl er það --cookie-jar við innskráninguna og --cookie við endurnýjunina, eins og í dæminu hér að neðan.

Hvað er athugað í hverri beiðni

Auðkenning er ekki bara undirskriftarathugun. Áður en meðhöndlari keyrir sannreynir API-ið undirskrift og gildistíma táknsins, staðfestir að lotan hafi ekki verið afturkölluð (bæði með útgáfunúmeri táknsins fyrir allan notandann og með einstöku lotuauðkenni) og hleður aðild þess sem kallar að fyrirtækinu sem táknið nefnir. Óvirk aðild er 403. Þegar fyrirtækið er tengt ytri auðkenningaraðila er staða þess sem kallar athuguð aftur hjá þeim aðila í beiðninni, í stað þess að lesa hana úr tákninu, þannig að aðgangur sem er fjarlægður þar hættir strax að virka, í stað þess að bíða eftir næsta gildistíma.

Skilríki sem eru ekki lotutákn

Tvenn önnur bearer-skilríki eru til, og hvorugt er almennur lykill. Raddtækjaskilríki er aðeins tekið gilt á raddsímtalaleiðunum, og aðgangsskilríki fulltrúa aðeins á MCP-endapunktinum. Ef þeim er framvísað annars staðar er hafnað með 403 sem nefnir skilríkið, og það er ekki reynt aftur sem veikari lota. Sjá MCP og tengd verkfæri um hvernig skilríki fulltrúa er gefið út.

Svarumslagið

Sérhvert árangursríkt svar er hlutur með data-lykli. Það er enginn hreinn listi og ekkert efst í rótinni, þannig að biðlari þarf aldrei að greina á milli forma:

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

Listaendapunktar bæta meta-hlut við hliðina. Ekkert annað er nokkurn tíma bætt við á efsta stigi.

Villur nota líka eitt form, hvað sem olli þeim:

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

code er vélalæsilegi hlutinn og er það sem þú átt að greina á; message er ætlað manneskju. field og details eru til staðar þegar villan er nógu sérstök til að hægt sé að staðsetja hana. Ómeðhöndluð villa á þjóni er alltaf 500 INTERNAL_ERROR með föstum skilaboðum. Villutextinn sjálfur er skráður en aldrei skilað, því hann gæti hafa tekið upp gögn úr beiðninni á leiðinni út.

Villukóðar sem þú hittir fyrst

StaðaKóðiMerking
400VALIDATION_ERROREfnið eða fyrirspurnin passaði ekki við skemað.
401AUTH_REQUIREDEkkert bearer-tákn, eða hausinn var gallaður.
401TOKEN_EXPIREDAðgangstáknið er runnið út. Endurnýjaðu og reyndu aftur.
401TOKEN_REVOKEDLotunni var lokað, eða allar lotur þvingaðar út.
403ACCOUNT_DEACTIVATEDAðild að þessu fyrirtæki hefur verið gerð óvirk.
404NOT_FOUNDEngin slík leið, eða engin slík færsla sem þessi biðlari sér.
429RATE_LIMITEDHólfið er fullt. Lestu Retry-After.
500INTERNAL_ERRORÓmeðhöndluð villa á þjóni, vísvitandi óljós.

Blaðsíðun

Listaendapunktar skipta í síður með ógagnsæjum lykilbendli (keyset cursor), ekki með frávik (offset). Færslur bætast við á meðan einhver les, og með frávik myndi önnur síðan endurtaka í hljóði færslu sem sú fyrsta sýndi.

Þrjár fyrirspurnarbreytur eru samþykktar: cursor, limit og direction (forward eða backward). Sjálfgefin síða telur 25 færslur og hámarkið er 100; hærra gildi er takmarkað í stað þess að vera hafnað. Endapunktar sem raða eða sía bæta einnig við sort, order og frjálsum leitartexta q.

meta síðunnar segir þér hvar þú ert:

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

nextCursor og prevCursor eru bæði raunveruleg: Fyrri og Næsta eru bæði stýringar sem fólk býst við. Þau eru ógagnsæ. Þjónninn kóðar sinn eigin röðunarlykil í þau, og biðlari sem þáttar þau eða smíðar eitt þeirra bilar um leið og listi breytir röðun sinni. total er til staðar á flestum listum og er sleppt þar sem talning skiptir ekki máli, eins og í röðuðum leitarniðurstöðum.

Hraðatakmarkanir

Takmarkanir gilda fyrir fastan glugga og eru framfylgdar áður en efni beiðninnar er jafnvel lesið. Hafnuð beiðni er 429 með kóðanum RATE_LIMITED og Retry-After-hausi í sekúndum.

Flest hólf eru bundin við IP-tölu biðlarans. Þau sem eru viðkvæm fyrir skilríkjum (innskráning, endurnýjun, endurstaðfesting lykilorðs, skrif á MCP-skilríki) halda líka teljara á hvern reikning og hafna þegar annað hvort lætur undan. Þannig rekast bæði á vegg: ein IP-tala sem reynir mörg reikninga og einn reikningur sem er ráðist á frá mörgum IP-tölum. Innskráning er sjálfgefið 10 tilraunir á IP-tölu og 5 á netfang á tíu mínútum; skilaboð senda 60 á mínútu; skrif undir /api/agents eru 60 á mínútu. Sérhver mörk eru stillanleg í hverri uppsetningu, þannig að líttu á þessi gildi sem sjálfgefin gildi í útgáfu, ekki sem samning. Heilsuathuganir og rauntímastraumar eru undanþegnir.

Rauntími

Að kanna lista aftur og aftur er rangt til að fylgjast með samtali. Í staðinn eru þrír straumendapunktar:

  • GET /api/events/stream — server-sent events fyrir allt sem innskráð manneskja getur séð.
  • GET /api/threads/:threadId/stream — server-sent events fyrir einn þráð. Hann virðir Last-Event-ID, þannig að endurtenging heldur áfram í stað þess að byrja upp á nýtt.
  • GET /api/activity — WebSocket sem flytur virknistrauminn.

Vafrar geta ekki sett hausa í WebSocket-handaband, þannig að WebSocket-leiðin tekur líka við aðgangstákninu sem ?token=-fyrirspurnarbreytu. Það er eini staðurinn þar sem tákn á heima í vefslóð; allar aðrar leiðir taka við því í hausnum.

Auðlindafjölskyldurnar

Endapunktarnir eru vel á annað þúsund, sem er allt of mikið til að telja upp. Þeir flokkast í fjölskyldur, og þegar þú þekkir forskeyti fjölskyldu eru einstakar leiðir fyrirsjáanlegar: safn undir forskeytinu, færsla þar undir og nefndar aðgerðir sem POST-undirslóðir.

FjölskyldaForskeytiÞað sem þetta nær yfir
Auðkenning/api/authInnskráning, endurnýjun, útskráning, núverandi auðkenni og eigin lotur manneskju.
Rásir og þræðir/api/channels, /api/threadsSamskiptalíkanið: rásir geyma þræði, þræðir geyma skilaboð, svör hreiðrast undir rót.
Fulltrúar/api/agentsSkilgreiningar fulltrúa, rásatengingar þeirra, samtöl, verkefnalistar og staða.
Verkefni og töflur/api/projects, /api/tasks, /api/iterationsVerkefnaskráning: töflur og dálkar undir verkefni, verkefni á þeim og lotur yfir þeim.
Þekking/api/knowledge-baseSvæði með útgefnum síðum og skrám, með athugasemdum, bakvísunum og leit.
Póstur/api/mail, /api/mailbox-connectionsTengd pósthólf, pósthólf fulltrúa og drög sem fulltrúi skrifaði fyrir manneskju til að samþykkja.
Samþykktir/api/approvalsBiðröðin yfir aðgerðir sem fulltrúi má ekki framkvæma einhliða, og eina kallið sem leysir þær.
Endurskoðun/api/audit-logHash-tengd endurskoðunarslóð fyrirtækisins, með sannprófunarendapunkti. Eigendur og stjórnendur.
Kostnaður og notkun/api/ledger, /api/billingNotkunar- og kostnaðarbókhald fyrir tákn, fjárhagsáætlanir og tímasetningar keyrslna; sér, inneign og áfyllingar. Eigendur og stjórnendur.
Fyrirtæki og teymi/api/organizations, /api/teams, /api/usersStjórnun fyrirtækis, teyma og aðildar, þar á meðal boð.
Kveikjur/api/triggersÁætlanir og vefkrókar sem ræsa vinnu fulltrúa, ásamt sögu ræsinga þeirra.
Símtöl og raddir/api/calls, /api/voiceSímtöl innan rásar, og lota raddaðstoðarans, afrit hennar og tækjatákn.
Executors/api/executors, /api/execution-environment-templatesVélarnar sem fulltrúar vinna á, umhverfi þeirra og pörunarrásin fyrir executor-þjóninn.
Keyrslur/api/runsLifandi keyrslur fulltrúa: hætta við, halda áfram, endurræsa, tengja við executor.
Innhleðslur/api/uploads, /api/attachmentsHladdu skrá upp fyrst, tengdu síðan skilaða auðkennið við skilaboð.
Leit/api/messages/searchLeit í skilaboðum, fyrir allt fyrirtækið eða bundin við eina rás.
Leyndarmál og stillingar/api/secrets, /api/settings/scopedGeymsla skilríkja sem aðeins er hægt að skrifa í, með skýrum heimildum, og lagskipt stillingargildi.
Tengd verkfæri/api/mcpMCP-þjónar sem þessi uppsetning kallar út á. Sjá MCP og tengd verkfæri.
Heilsa/api/healthLifun og tilbúningur, báðir opinberir. /api/health/ready athugar líka gagnagrunninn.

Réttindi eru framfylgd á hverri leið, ekki á hverjum flokki. Almennt séð eru endurskoðunarslóðin, kostnaðarbókin, stefnureglurnar og stjórnflötur inferensins yfirborð fyrir eigendur og stjórnendur fyrirtækisins, en samtöl, verkefni, þekking og samþykktir eru opin hverjum meðlim og takmörkuð við það sem sá meðlimur sér í raun.

Dæmi

Skráðu þig inn og geymdu endurnýjunarvafrakökuna

Á local-uppsetningu, með lykilorði. Aðgangstáknið kemur til baka í meginmáli svarsins; endurnýjunartáknið lendir í vafrakökusafninu.

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

Þegar táknið rennur út, skiptu vafrakökunni fyrir nýja:

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

Svarið er sama { token, me }-formið, og vafrakökusafnið geymir nú snúna endurnýjunartáknið.

Listaðu rásirnar sem þú sérð

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

Bættu við ?teamId=… til að þrengja að einu teymi, eða ?includeArchived=true til að taka með rásir í skjalasafni. defaultThreadId er það sem þú sendir á næst.

Sendu skilaboð

Skilaboð þurfa annað hvort eitthvert content-efni eða að minnsta kosti eitt innhlaðið viðhengi. Sendu Idempotency-Key og endurreynd beiðni skilar skilaboðunum sem fyrsta tilraunin bjó til, í stað þess að senda annað afrit.

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

Ný skilaboð eru 201:

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

Endursending með sama lykli svarar 200 með upprunalegu skilaboðunum og tómu pendingAgentInvites, því fyrsta tilraunin hafði þegar séð um viðvaranir og sendingu sem fylkið lýsir.

Tvær hafnanir á þessari leið er vert að meðhöndla sérstaklega. Efni umfram lengdarmörk spjallsins er 413 MESSAGE_TOO_LARGE, og rétta svarið er að hlaða textanum upp sem skrá. Efni sem lítur út eins og skilríki er 422 SECRET_INTERCEPTED. Þjónninn hafnar því áður en skilaboðin eru geymd, send eða skráð, og skilríkið á heima í /api/secrets.