Skip to content

HTTP API

Base URL: https://api.gutternote.com

Authentication

Every /v1 request carries the project’s public key and is authorised by its Origin:

Gutternote-Key: pk_live_...
Origin: https://gutternote-git-fix-nav-acme.vercel.app

The key identifies the project; the origin authorises the call. An origin that doesn’t match one of the project’s patterns returns 403 origin_not_allowed, and no CORS headers are echoed back.

Endpoints

GET /v1/config

Widget bootstrap: project identity and backend capabilities.

{
"projectId": "",
"name": "Acme Website",
"backend": "postgres",
"capabilities": {
"attachments": true,
"edit": true,
"delete": true,
"guestAuthors": true,
"lowLatencyReads": true
}
}

GET /v1/threads?path=/pricing

Anchors for one page. Never touches the body store, so pins render at full speed even when bodies live in GitHub. Bodies are omitted.

Optional: deploymentId, includeResolved=true.

POST /v1/threads

{
"anchor": {
"path": "/pricing",
"strategy": "selector",
"selector": "[data-testid=\"cta\"]",
"textQuote": "Start free trial",
"x": 0.5, "y": 0.5,
"viewportW": 1440, "viewportH": 900
},
"deployment": { "url": "https://…vercel.app", "branch": "fix/nav", "prNumber": 42 },
"author": { "id": "guest_9a1", "kind": "guest", "displayName": "Dana Reed" },
"markdown": "The CTA is 4px off."
}

Returns 201 with the thread.

GET /v1/threads/{id}

The thread with its bodies, resolved from whichever store holds them. This is the only read that touches the body store, which is why the widget calls it on thread open rather than on page load.

POST /v1/threads/{id}/replies

PATCH /v1/threads/{id}/status

{ "status": "resolved", "by": "Dana Reed" }

Status is anchor-layer state, so this never touches the body store.

Errors

{ "error": { "code": "unsupported_by_backend", "message": "the github backend cannot store attachments" } }
StatusMeaning
400Malformed request or invalid anchor
401Missing or unknown project key
403Origin not registered for the project
404Thread not found
409The project’s backend can’t do this — e.g. attachments on github
502The configured body store failed. Retryable.

502 is worth calling out: for the github and external backends the body store is a system Gutternote doesn’t control, so a failure there is distinct from a Gutternote bug and is usually worth retrying.