Go Scribi

The API

Finding things

Search, subjects, folders and templates: the calls a program makes before it knows which note it wants.

Every call here carries Authorization: Bearer <key> and answers JSON. What is true of every call, and what every refusal means.

GET /api/v1/w/:workspace_id/search

Search the workspace, with the operators the search box takes.

needs
read on the thing it touches
answers
query, ran, total, page, pages, and results — each a note, the sentence that matched, matched_in when it was in one of the note's rows — kind (item, node, card or column), id, the row's own text, and in_its_note when the match was in its note rather than its words — and what was found inside an attachment.
refusals
unauthorized, not_found, too_many_requests
Parameters for GET /api/v1/w/:workspace_id/search
Parameter In Type Description
q required query string
page query integer

Twenty-five to a page, and it takes no per_page.

ran: false means the query could not be searched — said rather than answered with an empty list.

The snippet is plain text, never our HTML: a program pasting it into a page of its own is not being handed an injection.

An example
curl -X GET https://goscribi.com/api/v1/w/11059/search?q=lease \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "query": "lease",
  "ran": true,
  "total": 1,
  "page": 1,
  "pages": 1,
  "results": [
    {
      "note": {
        "id": 12964,
        "title": "Leases",
        "type": "markdown",
        "folder": {
          "id": 3334,
          "name": "Survey"
        },
        "diary_date": null,
        "subject": null,
        "created_at": "2026-09-16T01:10:31Z",
        "updated_at": "2026-09-16T01:10:31Z",
        "lock_version": 0,
        "url": "https://goscribi.com/w/11059/notes/12964"
      },
      "snippet": "ferry terminal]] lease runs",
      "found_in": null
    }
  ]
}

GET /api/v1/w/:workspace_id/subjects

Everything [[a thing]] has been written about.

needs
read on the thing it touches
answers
subjects, each with its key, name and count.
refusals
unauthorized, not_found, too_many_requests
Parameters for GET /api/v1/w/:workspace_id/subjects
Parameter In Type Description
in query string One namespace. - means those with none.
only query string once for the ones mentioned a single time.

Sixty a minute, not three hundred.

An example
curl -X GET https://goscribi.com/api/v1/w/11127/subjects \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "subjects": [
    {
      "key": "ferry terminal",
      "name": "ferry terminal",
      "written": "ferry terminal",
      "namespace": null,
      "count": 1
    }
  ]
}

GET /api/v1/w/:workspace_id/subjects/:id

One subject: its own note, if it has one, and everywhere it is mentioned.

needs
read on the thing it touches
answers
subject, page (the note about it, or null), mentions, total, truncated.
refusals
unauthorized, not_found, too_many_requests

The id is the folded key — /subjects/ferry-terminal and /subjects/ferry%20terminal are the same page.

A subject nobody has written about still answers 200, because a [[link]] that 404s is a broken link. Asking never creates the page.

An example
curl -X GET https://goscribi.com/api/v1/w/10844/subjects/ferry%20terminal \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "subject": {
    "key": "ferry terminal",
    "name": "ferry terminal",
    "written": "ferry terminal"
  },
  "page": null,
  "total": 1,
  "truncated": false,
  "mentions": [
    {
      "note": {
        "id": 11877,
        "title": "Leases",
        "type": "markdown",
        "folder": {
          "id": 3287,
          "name": "Survey"
        },
        "diary_date": null,
        "subject": null,
        "created_at": "2026-09-16T01:10:31Z",
        "updated_at": "2026-09-16T01:10:31Z",
        "lock_version": 0,
        "url": "https://goscribi.com/w/10844/notes/11877"
      },
      "kind": null,
      "row_id": null,
      "text": "The [[ferry terminal]] lease runs to 2031.",
      "written": "ferry terminal",
      "at": "2026-09-16T01:10:31Z"
    }
  ]
}

GET /api/v1/w/:workspace_id/folders

The folders you can read.

needs
read on the thing it touches
answers
folders.
refusals
unauthorized, not_found
An example
curl -X GET https://goscribi.com/api/v1/w/259/folders \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "folders": [
    {
      "id": 323,
      "name": "Survey",
      "parent_id": null,
      "daily_note": false,
      "catches_captures": false,
      "created_at": "2026-09-21T04:59:00Z",
      "updated_at": "2026-09-21T04:59:00Z",
      "url": "https://goscribi.com/w/259/folders/323"
    }
  ]
}

GET /api/v1/w/:workspace_id/folders/:id

One folder, and the notes in it.

needs
read on the thing it touches
answers
folder and notes.
refusals
unauthorized, not_found
An example
curl -X GET https://goscribi.com/api/v1/w/266/folders/330 \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "folder": {
    "id": 330,
    "name": "Survey",
    "parent_id": null,
    "daily_note": false,
    "catches_captures": false,
    "created_at": "2026-09-21T04:59:01Z",
    "updated_at": "2026-09-21T04:59:01Z",
    "url": "https://goscribi.com/w/266/folders/330"
  },
  "notes": [
    {
      "id": 535,
      "title": "Leases",
      "type": "markdown",
      "folder": {
        "id": 330,
        "name": "Survey"
      },
      "diary_date": null,
      "subject": null,
      "created_at": "2026-09-21T04:59:01Z",
      "updated_at": "2026-09-21T04:59:01Z",
      "lock_version": 0,
      "url": "https://goscribi.com/w/266/notes/535"
    }
  ]
}

POST /api/v1/w/:workspace_id/folders

Make a folder, somewhere to file notes.

needs
create on the thing it touches
answers
**201**, and folder.
refusals
unauthorized, not_found, forbidden, read_only_key, workspace_locked, missing_parameter, invalid
Parameters for POST /api/v1/w/:workspace_id/folders
Parameter In Type Description
folder[name] required body string Up to 200 characters.
folder[parent_id] body integer Inside this folder. Left out, it goes at the top level.

Needs create where it goes — in that folder, or across the workspace for the top level. The same permission making a note there needs.

A folder is somewhere to put things and nothing more here: its daily notes, colour and emoji are set by a person, in the interface.

An example
curl -X POST https://goscribi.com/api/v1/w/319/folders \
  -H "Authorization: Bearer $GO_SCRIBI_KEY" \
  -H "Content-Type: application/json" \
  -d '"{\"folder\":{\"name\":\"Harbour\"}}"'

Answers 201:

{
  "folder": {
    "id": 383,
    "name": "Harbour",
    "parent_id": null,
    "daily_note": false,
    "catches_captures": false,
    "created_at": "2026-09-21T04:59:06Z",
    "updated_at": "2026-09-21T04:59:06Z",
    "url": "https://goscribi.com/w/319/folders/383"
  }
}

PATCH PUT /api/v1/w/:workspace_id/folders/:id

Rename a folder, or move it inside another.

needs
write on the thing it touches
answers
folder.
refusals
unauthorized, not_found, forbidden, read_only_key, workspace_locked, missing_parameter, invalid
Parameters for PATCH /api/v1/w/:workspace_id/folders/:id
Parameter In Type Description
folder[name] body string
folder[parent_id] body integer Moves it, which is a separate permission from renaming it: a move is a delete here and a create there, so it needs create on the folder AND create at the destination. null means the top level; left out, it stays where it is.

A folder cannot go inside itself, or inside a folder that is inside it.

An example
curl -X PATCH https://goscribi.com/api/v1/w/309/folders/370 \
  -H "Authorization: Bearer $GO_SCRIBI_KEY" \
  -H "Content-Type: application/json" \
  -d '"{\"folder\":{\"name\":\"Survey, 2026\"}}"'

Answers 200:

{
  "folder": {
    "id": 370,
    "name": "Survey, 2026",
    "parent_id": null,
    "daily_note": false,
    "catches_captures": false,
    "created_at": "2026-09-21T04:59:05Z",
    "updated_at": "2026-09-21T04:59:05Z",
    "url": "https://goscribi.com/w/309/folders/370"
  }
}

DELETE /api/v1/w/:workspace_id/folders/:id

Remove a folder. The notes in it go to the bin.

needs
create on the thing it touches
answers
folder, deleted: true, notes_binned — how many notes went to Deleted notes — and a message that says so.
refusals
unauthorized, not_found, forbidden, read_only_key

WHAT THE BUTTON DOES. The folder and every folder inside it are gone; every note in any of them goes to Deleted notes for 30 days, and one put back lands at the top level, since the folder it came from no longer exists.

The one delete here that is not wholly undone: the notes come back, the folder, its subfolders and their settings do not.

Works while the workspace is locked, like deleting a note: removing things is the way out of being over the limit.

An example
curl -X DELETE https://goscribi.com/api/v1/w/323/folders/389 \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "folder": {
    "id": 389,
    "name": "Survey"
  },
  "deleted": true,
  "notes_binned": 3,
  "message": "Removed. The 3 notes inside went to Deleted notes, and can be put back for 30 days — at the top level, since the folder has gone."
}

GET /api/v1/w/:workspace_id/templates

The templates a new note can be stamped from.

needs
read on the thing it touches
answers
templates.
refusals
unauthorized, not_found
An example
curl -X GET https://goscribi.com/api/v1/w/10616/templates \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "templates": [
    {
      "id": 576,
      "name": "Survey day",
      "type": "checklist",
      "body": "- [ ] Tide times",
      "created_at": "2026-09-16T01:10:31Z",
      "updated_at": "2026-09-16T01:10:31Z"
    }
  ]
}

GET /api/v1/w/:workspace_id/templates/:id

One template, with its body.

needs
read on the thing it touches
answers
template.
refusals
unauthorized, not_found
An example
curl -X GET https://goscribi.com/api/v1/w/9885/templates/500 \
  -H "Authorization: Bearer $GO_SCRIBI_KEY"

Answers 200:

{
  "template": {
    "id": 500,
    "name": "Survey day",
    "type": "checklist",
    "body": "[ ] Meter readings",
    "created_at": "2026-09-16T01:10:31Z",
    "updated_at": "2026-09-16T01:10:31Z"
  }
}