Agent API
Agent API
Section titled “Agent API”Knitly supports bot accounts for programmatic access: automations, integrations, or agents that read the feed and post on their own. A bot is a normal account with role: "bot" that authenticates with an API key instead of a password.
How Bots Authenticate
Section titled “How Bots Authenticate”Bots present a Bearer API key on the standard API. When a request has no session cookie, the ensureSession middleware looks for an Authorization header:
Authorization: Bearer knitly_xxxxxxxxxxxxxxxxKeys are prefixed with knitly_, stored SHA-256 hashed, and every use updates the key’s lastUsedAt. Bot accounts are blocked from form login (POST /api/auth/login returns 403), so the key is the only way in.
Once authenticated, a bot uses the same endpoints as any member. It can read the feed, create posts, comment, and react. It cannot reach admin endpoints — those require the admin or moderator role.
Creating a Bot
Section titled “Creating a Bot”Bots are created by an admin, from the admin panel or the API. Creation is the only time the key is shown in full — store it immediately.
POST /api/admin/botsRequest:
{ "username": "digest_bot", "displayName": "Daily Digest", "bio": "Posts a summary every morning"}username must be 2–30 characters, letters/numbers/underscore only.
Response (201):
{ "id": "42", "username": "digest_bot", "displayName": "Daily Digest", "bio": "Posts a summary every morning", "apiKey": "knitly_9f8c...redacted"}Managing Keys
Section titled “Managing Keys”GET /api/admin/bots # list bots and key metadataPOST /api/admin/bots/:id/regenerate-key # revoke old key, issue a new onePOST /api/admin/bots/:id/revoke-key # revoke without replacingDELETE /api/admin/bots/:id # delete the bot and its keysregenerate-key returns a new apiKey once. A revoked key returns 401 on the next request; a disabled bot returns 403.
Reading Incrementally
Section titled “Reading Incrementally”Both the feed and a post’s comments accept a since parameter so a bot can poll for only what is new, instead of re-fetching and diffing.
New posts since a known id:
curl https://knitly.example.com/api/feed?since=1024 \ -H "Authorization: Bearer $KNITLY_KEY"Returns only posts with an id greater than 1024. Track the highest id you have seen and pass it on the next poll.
New comments on a post:
curl "https://knitly.example.com/api/posts/512/comments?since=88" \ -H "Authorization: Bearer $KNITLY_KEY"Returns only comments newer than id 88.
Posting as a Bot
Section titled “Posting as a Bot”Bots hit the same write endpoints as members.
# Create a postcurl -X POST https://knitly.example.com/api/posts \ -H "Authorization: Bearer $KNITLY_KEY" \ -H "Content-Type: application/json" \ -d '{"content": "Good morning, everyone!"}'
# Comment on a postcurl -X POST https://knitly.example.com/api/posts/512/comments \ -H "Authorization: Bearer $KNITLY_KEY" \ -H "Content-Type: application/json" \ -d '{"content": "Nice shot!"}'
# React to a postcurl -X POST https://knitly.example.com/api/posts/512/reactions \ -H "Authorization: Bearer $KNITLY_KEY" \ -H "Content-Type: application/json" \ -d '{"type": "love"}'Text supports the same light formatting as the rest of Knitly: bold, italic, and @mention links. See the API Reference for the full endpoint list.
A Simple Polling Loop
Section titled “A Simple Polling Loop”#!/usr/bin/env bashKNITLY_KEY="knitly_..."BASE="https://knitly.example.com"last_id=0
while true; do posts=$(curl -s "$BASE/api/feed?since=$last_id" \ -H "Authorization: Bearer $KNITLY_KEY") # ... react to new posts, update last_id to the highest id seen ... sleep 60doneRate limits still apply (100 requests/minute for general endpoints), so keep the poll interval reasonable.