# Create article
Source: https://apidocs.neetokb.com/api-reference-v1/articles/create
bundled-v1/articles.yaml POST /articles
This API allows to create a new article.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get article
Source: https://apidocs.neetokb.com/api-reference-v1/articles/get
bundled-v1/articles.yaml GET /articles/{article_id}
This API allows to fetch article details.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List articles
Source: https://apidocs.neetokb.com/api-reference-v1/articles/list
bundled-v1/articles.yaml GET /articles
This API allows to get a list of articles. Only published articles are returned unless you pass `state`.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update article
Source: https://apidocs.neetokb.com/api-reference-v1/articles/update
bundled-v1/articles.yaml PATCH /articles/{permalink_id}
This API allows to update an existing article.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List authors
Source: https://apidocs.neetokb.com/api-reference-v1/authors/list
bundled-v1/authors.yaml GET /authors
This API allows to get a list of all authors.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List categories
Source: https://apidocs.neetokb.com/api-reference-v1/categories/list
bundled-v1/categories.yaml GET /categories
This API allows to get a list of all categories.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get recommended articles
Source: https://apidocs.neetokb.com/api-reference-v1/recommendations/get
bundled-v1/recommendations.yaml GET /recommendations
This API returns recommended articles based on a specific URL or path.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get organization settings
Source: https://apidocs.neetokb.com/api-reference-v1/settings/get
bundled-v1/settings.yaml GET /settings
This API allows to fetch organization settings.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Add team members
Source: https://apidocs.neetokb.com/api-reference-v1/team-members/add
bundled-v1/team-members.yaml POST /team_members
Add team members to the workspace.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List team members
Source: https://apidocs.neetokb.com/api-reference-v1/team-members/list
bundled-v1/team-members.yaml GET /team_members
List team members in the workspace.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Remove team member
Source: https://apidocs.neetokb.com/api-reference-v1/team-members/remove
bundled-v1/team-members.yaml DELETE /team_members/{team_member_id}
Remove a team member from the workspace.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update team member details
Source: https://apidocs.neetokb.com/api-reference-v1/team-members/update
bundled-v1/team-members.yaml PATCH /team_members/{team_member_id}
Update a team member.
> [!WARNING]
>
> **Deprecated:** This is a **v1** endpoint. It will continue to work, but we recommend migrating to
> the [v2 equivalent](/api) for improved REST compliance (correct HTTP status codes,
> consistent response envelopes, and hyphenated URLs).
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Archive article
Source: https://apidocs.neetokb.com/api/articles/archive
bundled/articles.yaml POST /articles/{article_id}/archive
This API archives an article. Its state becomes `draft` and `is_archived` becomes true. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Trash articles in bulk
Source: https://apidocs.neetokb.com/api/articles/bulk-trash
bundled/articles.yaml DELETE /articles/bulk_destroy
This API moves up to 100 articles to the trash in one call. It is all-or-nothing: if any identifier is unknown, or any article is synced from another product, nothing is trashed. For CLI sessions, this needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update articles in bulk
Source: https://apidocs.neetokb.com/api/articles/bulk-update
bundled/articles.yaml PATCH /articles/bulk_update
This API changes up to 100 articles at once. Send `article_ids` and exactly one of `category_id`, `state` or `status`. It is all-or-nothing. For CLI sessions, this needs the Modify articles permission. Setting `state` also needs the Manage articles permission. The `put` method works too.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Clone article
Source: https://apidocs.neetokb.com/api/articles/clone
bundled/articles.yaml POST /articles/{article_id}/clone
This API copies an article into a new draft titled `
- CLONED - `. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Create article
Source: https://apidocs.neetokb.com/api/articles/create
bundled/articles.yaml POST /articles
This API allows to create a new article. Pass `tags` to attach tags, `related_article_ids` to link related articles or `note` to add an internal note. For CLI sessions, creating a draft needs the Modify articles permission. Creating an article with `state: published` also needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Schedule article
Source: https://apidocs.neetokb.com/api/articles/create-schedule
bundled/articles.yaml POST /articles/{article_id}/schedules
This API schedules the article to be published or unpublished at a future time. An article holds at most one schedule of each kind. When it has both, the unpublish time must not come after the publish time. For CLI sessions, this needs the Modify articles permission. A `publish` schedule also needs the Manage articles permission. A synced article cannot be scheduled.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete article schedule
Source: https://apidocs.neetokb.com/api/articles/delete-schedule
bundled/articles.yaml DELETE /articles/{article_id}/schedules/{id}
This API deletes a scheduled action of an article. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Discard draft
Source: https://apidocs.neetokb.com/api/articles/discard-draft
bundled/articles.yaml DELETE /articles/{article_id}/draft
This API discards the unpublished draft of a published article. The live content is not changed. An article that is not published cannot have its draft discarded, because the draft holds all of its content; move it to the trash instead. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get article
Source: https://apidocs.neetokb.com/api/articles/get
bundled/articles.yaml GET /articles/{article_id}
This API allows to fetch article details. Reads made with a CLI session token are not counted as article views.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get article revision
Source: https://apidocs.neetokb.com/api/articles/get-revision
bundled/articles.yaml GET /articles/{article_id}/revisions/{id}
This API returns one revision of an article, with the title and HTML content it held. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get article SEO settings
Source: https://apidocs.neetokb.com/api/articles/get-seo-setting
bundled/articles.yaml GET /articles/{article_id}/seo_setting
This API returns the SEO settings of an article. An article without saved settings returns the defaults. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get unlisted link
Source: https://apidocs.neetokb.com/api/articles/get-unlisted-link
bundled/articles.yaml GET /articles/{article_id}/unlisted_link
Returns the link the article already has. Never creates or replaces a link. Use the regenerate endpoint to create the first link or to replace an expired one.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List articles
Source: https://apidocs.neetokb.com/api/articles/list
bundled/articles.yaml GET /articles
This API allows to get a list of articles. Only published articles are returned unless you pass `state`.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List article revisions
Source: https://apidocs.neetokb.com/api/articles/list-revisions
bundled/articles.yaml GET /articles/{article_id}/revisions
This API lists the revisions of an article, newest first. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List article schedules
Source: https://apidocs.neetokb.com/api/articles/list-schedules
bundled/articles.yaml GET /articles/{article_id}/schedules
This API lists the scheduled publish and unpublish actions of an article. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Regenerate unlisted link
Source: https://apidocs.neetokb.com/api/articles/regenerate-unlisted-link
bundled/articles.yaml PUT /articles/{article_id}/unlisted_link
This API allows to generate a fresh unlisted link for the article, replacing any existing one. The previous URL stops working immediately.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Restore article revision
Source: https://apidocs.neetokb.com/api/articles/restore-revision
bundled/articles.yaml POST /articles/{article_id}/revisions/{revision_id}/restoration
This API copies the title and HTML content of a revision into the article's draft. The live content does not change until you publish. For CLI sessions, this needs the Modify articles permission. A synced article cannot be restored.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Trash article
Source: https://apidocs.neetokb.com/api/articles/trash
bundled/articles.yaml DELETE /articles/{article_id}
This API moves an article to the trash. The article is deleted for good after the days shown by [List trashed articles](/api/trash/list). For CLI sessions, this needs the Manage articles permission. A synced article cannot be trashed.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Unarchive article
Source: https://apidocs.neetokb.com/api/articles/unarchive
bundled/articles.yaml DELETE /articles/{article_id}/archive
This API unarchives an article. Its state stays `draft`. For CLI sessions, this needs the Modify articles permission. A synced article cannot be unarchived.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update article
Source: https://apidocs.neetokb.com/api/articles/update
bundled/articles.yaml PATCH /articles/{id}
This API allows to update an existing article. Pass `category` to move the article to another category. For CLI sessions, editing a draft needs the Modify articles permission. Setting `state: published`, or changing an already published article, also needs the Manage articles permission. Pass `tags`, `related_article_ids` or `note` to replace the article's tags, related articles or internal note. The `put` method works too.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update article SEO settings
Source: https://apidocs.neetokb.com/api/articles/update-seo-setting
bundled/articles.yaml PATCH /articles/{article_id}/seo_setting
This API changes the SEO settings of an article. Only the fields you send change. The cover image and the Google Analytics ID are not available here. The `put` method works too. For CLI sessions, this needs the Modify articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Upload attachment
Source: https://apidocs.neetokb.com/api/attachments/create
bundled/attachments.yaml POST /attachments
Upload a file (such as an image, PDF, or document) and get back a link you can use inside an article, so you don't have to embed the full file directly in the article's content, which makes articles large and slow to load. Send the file as multipart `file`, or send a JSON body with either a public https `url` or `content_base64` with `filename`. For CLI sessions, this needs the Modify articles permission. For images, the response also includes `attachable_html`: the image already formatted as ready-to-paste code that you can add straight into the article's `html_content`. Any file you upload but never use in an article is removed automatically.
Send the file as multipart `file`, or send a JSON body with a public `url` or `content_base64` and `filename`.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Authentication
Source: https://apidocs.neetokb.com/api/authentication
Learn how to authenticate your requests to the NeetoKB API using API keys.
## Generating an API key
To use the NeetoKB APIs, you must first generate an API key:
1. Go to the **Admin panel** and click **API keys**.
2. Click **Add API key**. The **Add new API key** pane opens.
3. Enter a **Name** for the key.
4. Under **Type**, choose **General**. The **Zapier** type is only for the Zapier integration.
5. Pick an **Expiry date**, or check **Never expires**.
6. Click **Save changes**.
7. Copy the key from the **API keys** list using the copy icon. The key stays in the list, so you can copy it again later.
[Learn more about API keys here.](https://help.neetokb.com/articles/api-keys)
## Making authenticated API requests
To authenticate your API requests, include a valid API key in the `X-Api-Key` header.
```bash theme={"system"}
curl https://{your-subdomain}.neetokb.com/api/external/v2/team-members \
--header 'X-Api-Key: your-api-key' \
--header 'Content-Type: application/json'
```
## Header format
Include your API key in the `X-Api-Key` header of every request:
```http theme={"system"}
X-Api-Key: your-api-key
```
> [!TIP]
>
> Generate separate API keys for different workspaces. An API key generated in
> one workspace will not work in another.
> [!WARNING]
>
> API keys provide access to sensitive data. Treat them like passwords and
> follow security best practices.
## Error responses
### 401 Unauthorized
If your API key is missing, invalid, or expired, you'll receive a 401 error:
```json theme={"system"}
{
"error": "Could not authenticate, invalid API Key"
}
```
### Common authentication issues
> **Invalid API key**
>
> **Problem**: API key is missing or invalid. \\
>
> **Solution**: Verify your API key is correct and hasn't been revoked/expired.
> **Incorrect workspace subdomain**
>
> **Problem**: Subdomain is left as the default value (**spinkart**) or incorrect. \\
>
> **Solution**: Verify your subdomain name is properly added in the request URL.
# List authors
Source: https://apidocs.neetokb.com/api/authors/list
bundled/authors.yaml GET /authors
This API allows to get a list of all authors with their article counts. Deactivated authors are included.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Create category
Source: https://apidocs.neetokb.com/api/categories/create
bundled/categories.yaml POST /categories
This API creates a category. For CLI sessions, this needs the Manage categories permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete category
Source: https://apidocs.neetokb.com/api/categories/delete
bundled/categories.yaml DELETE /categories/{id}
This API deletes a category. Its articles and subcategories move to `move_to_category_id`, or to the parent category when you leave it out. A top-level category that has articles or subcategories needs `move_to_category_id`. The last remaining category cannot be deleted. For CLI sessions, this needs the Manage categories permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get category
Source: https://apidocs.neetokb.com/api/categories/get
bundled/categories.yaml GET /categories/{id}
This API returns one category. `articles_count` counts published articles only.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List categories
Source: https://apidocs.neetokb.com/api/categories/list
bundled/categories.yaml GET /categories
This API allows to get a list of categories. By default it returns the category tree, which omits categories without published articles and hides private categories from API-key callers. Pass `flat=true` to get every category, including empty and private ones, as flat rows.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Reorder category articles
Source: https://apidocs.neetokb.com/api/categories/reorder-articles
bundled/categories.yaml PATCH /categories/{category_id}/article_order
This API sets the order of articles in a category. Listed articles get positions 1 to n. Articles of the category that you leave out follow in their current order. The `put` method works too. For CLI sessions, this needs the Manage categories permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update category
Source: https://apidocs.neetokb.com/api/categories/update
bundled/categories.yaml PATCH /categories/{id}
This API renames a category, changes its privacy, moves it or changes its position. The `put` method works too. For CLI sessions, this needs the Manage categories permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Getting the article ID
Source: https://apidocs.neetokb.com/api/getting-article-id
Understand how to retrieve article identifiers for use in your API calls.
## What is an article identifier?
Article identifiers are unique values used to reference specific articles in your knowledge base when making API requests. Understanding the different types of identifiers and how to find them is essential for working with the NeetoKB API.
NeetoKB supports three types of identifiers for articles, each serving different purposes:
* **ID (UUID)** - Permanent unique identifier.
Example: `285c4bab-3ca4-4a24-9288-73392a04554e`
* **Slug** - Human-readable URL identifier.
Example: `getting-started-guide`
* **Permalink** - Stable short identifier for updates.
Example: `a-d17829fc`
There are two main ways to get article identifiers:
* **Using the API** - Programmatically retrieve all articles and their identifiers.
* **From the URL** - Extract identifier directly from your browser's address bar.
> [!NOTE]
>
> Permalinks cannot be retrieved via the API or extracted from the URL. Refer to
> the [help article](https://help.neetokb.com/articles/permalinks) for more information.
## Method 1: Using the API endpoint
The [List all articles](/api/articles/list) API endpoint allows you to retrieve a list of all articles in your workspace, including their identifiers. This is particularly useful when you need to programmatically access or retrieve the identifiers of all available articles.
### Step-by-step instructions
**1. Make the API request**
Send a `GET` request to the [List all articles](/api/articles/list) API endpoint, including your API key in the request header.
**2. Parse the response**
The response will contain an array of articles, each with `id`, `slug`, and other fields.
Example:
```json theme={"system"}
{
"articles": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"slug": "getting-started",
"title": "Getting Started Guide",
"state": "published",
"unique_views_count": 123,
"category": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Tutorials"
}
},
// ... rest of the articles
],
"pagination": {
"total_records": 123,
"total_pages": 5,
"current_page_number": 1,
"page_size": 30
}
}
```
**3. Extract the article identifier**
Here the article identifiers for the `Getting Started Guide` are:
* **ID**: `3c90c3cc-0d44-4b50-8888-8dd25736052a`
* **Slug**: `getting-started`
You can access the article identifiers in your code from the response using:
```javascript JavaScript theme={"system"}
// Get the first article's ID
const articleId = response.articles[0].id;
// Or iterate through all articles to find a specific one
const startedGuide = response.articles.find(article =>
article.title === "Getting Started Guide"
);
const startedGuideId = startedGuide.id;
const startedGuideSlug = startedGuide.slug;
```
```python Python theme={"system"}
# Get the first article's ID
article_id = response["articles"][0]["id"]
# Or iterate through all articles to find a specific one
for article in response["articles"]:
if article["title"] == "Getting Started Guide":
started_guide_id = article["id"]
started_guide_slug = article["slug"]
break
```
```bash Bash theme={"system"}
# Using jq to extract IDs from the response
curl -X GET "https://{your-subdomain}.neetokb.com/api/external/v2/articles" \
-H 'X-Api-Key: your-api-key' | \
jq '.articles[0].id'
```
> [!NOTE]
>
> The `articles` array contains all articles in your workspace. If you have
> multiple articles, you may want to filter by title or other properties to find
> the specific article you need.
## Method 2: From the URL
Article identifiers appear in the URL when you view an article in your workspace. This method provides only the slug, not the article’s ID or permalink. For example, in the URL:
```
https://spinkart.neetokb.com/admin/categories/product-guides/articles/getting-started-guide/edit
```
The article slug is: **getting-started-guide**
### Step-by-step instructions
**1. Navigate to your article**
Log into your NeetoKB workspace and navigate to the article you want to work with.
**2. Locate the article URL**
Once you're viewing the article, look at your browser's address
bar. The URL will contain the
article identifier.
**3. Extract the article identifier**
The article identifier is typically found in the URL path. Look for a pattern like:
```
https://your-subdomain.neetokb.com/admin/categories/product-guides/articles/{article-identifier}/edit
```
The `{article-identifier}` part is what you need.
### Examples
Here are some examples of how article identifiers appear in URLs & permalinks:
| URL Example | Article Identifier |
| - | - |
| `https://mycompany.neetokb.com/admin/categories/getting-started/articles/user-guide/edit` | `user-guide` |
| `https://support.neetokb.com/admin/categories/faq/articles/troubleshooting-tips/edit` | `troubleshooting-tips` |
| `https://docs.neetokb.com/admin/categories/developer-guides/articles/api-integration-guide/edit` | `api-integration-guide` |
| Permalink Example | Article Identifier |
| - | - |
| `https://mycompany.neetokb.com/p/a-84af178b` | a-84af178b |
| `https://support.neetokb.com/p/b-93cd289f` | b-93cd289f |
| `https://docs.neetokb.com/p/c-47de12ac` | c-47de12ac |
# Getting the category ID
Source: https://apidocs.neetokb.com/api/getting-category-id
Understand how to retrieve category IDs for use in your API calls.
## What is a category ID?
Category IDs are unique identifiers used to reference specific categories in your knowledge base when making API requests. To work effectively with the NeetoKB API, it’s important to know how to retrieve these IDs. You can do this programmatically by using the API to fetch all categories and their associated information.
## Using the API endpoint
The [List all categories](/api/categories/list) API endpoint allows you to retrieve a list of all categories in your workspace, including their IDs. This is particularly useful when you need to programmatically access or retrieve the IDs of all available categories.
### Step-by-step instructions
**1. Make the API request**
Send a `GET` request to the [List all categories](/api/categories/list) API endpoint, including your API key in the request header.
**2. Parse the response**
The response will contain an array of categories with detailed information including `id`, `name`, count statistics, and nested subcategories.
Example:
```json theme={"system"}
{
"categories": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Getting Started",
"description": "Essential guides to get you started",
"sequence": 1,
"parent_id": null,
"depth": 0,
"articles_count": 3,
"categories_count": 2,
"total_articles_count": 8,
"url": "https://example.neetokb.com/categories/getting-started",
"subcategories": [
{
"id": "b8e3d4f2-1a56-4c78-9012-345678901234",
"name": "Quick Setup",
"articles_count": 2,
"categories_count": 0,
"total_articles_count": 2
}
],
"ancestors": [],
"children": ["b8e3d4f2-1a56-4c78-9012-345678901234"],
"articles": [
{
"id": "f1a2b3c4-5d6e-7f8g-9h0i-1j2k3l4m5n6o",
"url": "https://example.neetokb.com/articles/welcome",
"title": "Welcome to NeetoKB",
"created_at": "2024-01-15T10:30:00Z",
"content": "Welcome to your knowledge base..."
}
]
},
// ... rest of the categories
],
"pagination": {
"total_records": 3,
"total_pages": 1,
"current_page_number": 1,
"page_size": 30
}
}
```
**3. Extract the category ID**
Here the category ID for the `Getting Started` category is:
* **ID**: `3c90c3cc-0d44-4b50-8888-8dd25736052a`
You can access the category information in your code from the response using:
```javascript JavaScript theme={"system"}
// Get the first category's ID and metadata
const category = response.categories[0];
const categoryId = category.id;
const articlesCount = category.articles_count;
const totalArticles = category.total_articles_count;
// Find a specific category by name
const gettingStartedCategory = response.categories.find(category =>
category.name === "Getting Started"
);
if (gettingStartedCategory) {
const id = gettingStartedCategory.id;
const subcategories = gettingStartedCategory.subcategories;
const articles = gettingStartedCategory.articles;
}
```
```python Python theme={"system"}
# Get the first category's ID and metadata
category = response["categories"][0]
category_id = category["id"]
articles_count = category["articles_count"]
total_articles = category["total_articles_count"]
# Find a specific category by name
for category in response["categories"]:
if category["name"] == "Getting Started":
getting_started_id = category["id"]
subcategories = category["subcategories"]
articles = category["articles"]
break
```
```bash Bash theme={"system"}
# Using jq to extract different fields from the response
curl -X GET "https://{your-subdomain}.neetokb.com/api/external/v2/categories" \
-H 'X-Api-Key: your-api-key' | \
jq '.categories[0] | {id, name, articles_count, total_articles_count}'
```
> [!NOTE]
>
> The `categories` array contains all categories in your workspace with rich metadata:
>
> * **Hierarchy**: `subcategories`, `ancestors`, `children`, `parent_id`, `depth` show the category structure
> * **Statistics**: `articles_count`, `categories_count`, `total_articles_count` provide count information
> * **Content**: `articles` array includes embedded article objects for each category
> * **Identification**: UUID `id` is provided for referencing categories
>
> If you have multiple categories, you may want to filter by name or other properties to find the specific category you need.
# Update NeetoChat integration
Source: https://apidocs.neetokb.com/api/integrations/neeto-chat
bundled/integrations.yaml PATCH /integrations/neeto_chat
This API turns the NeetoChat integration on or off. The `put` method works too. For CLI sessions, this needs the Manage integrations permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# NeetoKB API
Source: https://apidocs.neetokb.com/api/introduction
Welcome to the NeetoKB API documentation.
The NeetoKB API is organized around REST principles and uses standard HTTP response codes. All API endpoints return JSON responses and require authentication.
Before you start with NeetoKB APIs you will need the following:
1. [Workspace subdomain](/api/workspace-subdomain).
2. [API key](/api/authentication).
## Rate limiting
API requests are subject to rate limiting to ensure fair use. If you exceed the rate limit, you'll receive a 429 response. If you encounter this error try again after some time.
## Need help?
Visit our [help center](https://help.neetokb.com), email us at [support@neetokb.com](mailto:support@neetokb.com), or join the [Neeto Community](https://neeto.com/community).
The community is powered by Slack and is the fastest way to get help directly from the developers, designers, and product folks building NeetoKB.
# Get my preferences
Source: https://apidocs.neetokb.com/api/my-preferences/get
bundled/my-preferences.yaml GET /my_preferences
This API returns the preferences of the signed-in user. It works only for a signed-in user, such as a CLI session. An API key has no user, so the request is refused.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update my preferences
Source: https://apidocs.neetokb.com/api/my-preferences/update
bundled/my-preferences.yaml PATCH /my_preferences
This API updates the preferences of the signed-in user. It needs no extra permission, because the data is the user's own. An API key has no user, so the request is refused. The `put` method works too.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List navigation links
Source: https://apidocs.neetokb.com/api/navigation-links/list
bundled/navigation-links.yaml GET /navigation_links
This API returns the header links and the footer links, each in display order.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update navigation links
Source: https://apidocs.neetokb.com/api/navigation-links/update
bundled/navigation-links.yaml PATCH /navigation_links
This API replaces the header links, the footer links or both. Each set you send becomes exactly the list you send, in that order. The position of a link is its index. A set you do not send is not changed. The change is all-or-nothing. The `put` method works too. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Pagination
Source: https://apidocs.neetokb.com/api/pagination
Learn how to handle paginated responses in the NeetoKB API.
## Pagination parameters
You can control pagination using the following query parameters:
**page\_number** `integer`
The page of results you want to retrieve (starting from 1).
**page\_size** `integer`
The number of items to return per page.
## Example usage
Here's how to retrieve paginated results:
```bash cURL theme={"system"}
curl --request GET \
--url "https://{your-subdomain}.neetokb.com/api/external/v2/team-members?page_number=2&page_size=25" \
--header 'X-Api-Key: your-api-key'
```
```javascript JavaScript theme={"system"}
const response = await fetch(
"https://{your-subdomain}.neetokb.com/api/external/v2/team-members?page_number=2&page_size=25",
{
method: "GET",
headers: {
"X-Api-Key": "your-api-key",
"Content-Type": "application/json",
},
}
);
const data = await response.json();
console.log(data);
```
```python Python theme={"system"}
import requests
url = "https://{your-subdomain}.neetokb.com/api/external/v2/team-members"
params = {
"page_number": 2,
"page_size": 25
}
headers = {
"X-Api-Key": "your-api-key",
"Content-Type": "application/json"
}
response = requests.get(url, params=params, headers=headers)
data = response.json()
print(data)
```
This retrieves the second page of team members, with 25 results per page.
## Response structure
Paginated responses include metadata about the pagination:
```json Response example theme={"system"}
{
"team_members": [
// ... array of team member objects
],
"pagination": {
"total_records": 150,
"current_page_number": 2,
"total_pages": 6,
"page_size": 25
}
}
```
**pagination.total\_records** `integer`
The total number of items across all pages.
**pagination.current\_page\_number** `integer`
The current page number.
**pagination.total\_pages** `integer`
The total number of pages available.
**pagination.page\_size** `integer`
The number of items per page.
## Default behavior
> [!NOTE]
>
> * If you leave out `page_number`, you get the first page.
> * If you leave out `page_size`, each page has 30 items.
## Best practices
1. **Start with reasonable page sizes**: Use page sizes between 10-100 items for optimal performance.
2. **Handle empty results**: Always check if the returned array is empty to detect the end of data.
3. **Use total\_records**: Use the `pagination.total_records` field to calculate the total number of pages needed.
4. **Implement error handling**: Handle cases where the requested page doesn't exist.
# Create recommendation
Source: https://apidocs.neetokb.com/api/recommendations/create
bundled/recommendations.yaml POST /recommendations
This API creates a recommendation that shows articles or categories on pages whose URL matches. For CLI sessions, this needs the Manage recommendations permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete recommendation
Source: https://apidocs.neetokb.com/api/recommendations/delete
bundled/recommendations.yaml DELETE /recommendations/{id}
This API deletes a recommendation. For CLI sessions, this needs the Manage recommendations permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get recommended articles
Source: https://apidocs.neetokb.com/api/recommendations/get
bundled/recommendations.yaml GET /recommendations
This API returns recommended articles based on a specific URL or path.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get recommendation
Source: https://apidocs.neetokb.com/api/recommendations/get-one
bundled/recommendations.yaml GET /recommendations/{id}
This API returns one recommendation with its articles and categories.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update recommendation
Source: https://apidocs.neetokb.com/api/recommendations/update
bundled/recommendations.yaml PATCH /recommendations/{id}
This API updates a recommendation. Only the fields you send change. The `put` method works too. For CLI sessions, this needs the Manage recommendations permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Create redirection
Source: https://apidocs.neetokb.com/api/redirections/create
bundled/redirections.yaml POST /redirections
This API creates a redirection. For CLI sessions, this needs the Manage redirections permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete redirection
Source: https://apidocs.neetokb.com/api/redirections/delete
bundled/redirections.yaml DELETE /redirections/{id}
This API deletes a redirection. For CLI sessions, this needs the Manage redirections permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get redirection
Source: https://apidocs.neetokb.com/api/redirections/get
bundled/redirections.yaml GET /redirections/{id}
This API returns one redirection.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List redirections
Source: https://apidocs.neetokb.com/api/redirections/list
bundled/redirections.yaml GET /redirections
This API lists redirections, newest first. The domain redirection is included.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update redirection
Source: https://apidocs.neetokb.com/api/redirections/update
bundled/redirections.yaml PATCH /redirections/{id}
This API updates a redirection. Only the fields you send change. The `put` method works too. For CLI sessions, this needs the Manage redirections permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Clear failed searches
Source: https://apidocs.neetokb.com/api/reports/clear-failed-searches
bundled/reports.yaml DELETE /reports/failed_searches
This API deletes the rows of this report that fall in the period you pick. With no parameters it deletes every row. It cannot be undone. For CLI sessions, this needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Clear invalid URLs
Source: https://apidocs.neetokb.com/api/reports/clear-invalid-urls
bundled/reports.yaml DELETE /reports/invalid_urls
This API deletes the rows of this report that fall in the period you pick. With no parameters it deletes every row. It cannot be undone. For CLI sessions, this needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Clear popular searches
Source: https://apidocs.neetokb.com/api/reports/clear-popular-searches
bundled/reports.yaml DELETE /reports/popular_searches
This API deletes the rows of this report that fall in the period you pick. With no parameters it deletes every row. It cannot be undone. For CLI sessions, this needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List failed searches
Source: https://apidocs.neetokb.com/api/reports/failed-searches
bundled/reports.yaml GET /reports/failed_searches
This API lists the searches that found no article, with how often each was made, for the period you pick.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List invalid URLs
Source: https://apidocs.neetokb.com/api/reports/invalid-urls
bundled/reports.yaml GET /reports/invalid_urls
This API lists URLs visitors opened that did not exist, with how often each was opened, for the period you pick.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get knowledge base visits
Source: https://apidocs.neetokb.com/api/reports/kb-visits
bundled/reports.yaml GET /reports/kb_visits
This API returns the number of visits to the knowledge base for each day in the period, oldest day first. It is not paginated.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List popular searches
Source: https://apidocs.neetokb.com/api/reports/popular-searches
bundled/reports.yaml GET /reports/popular_searches
This API lists the searches that found at least one article, with how often each was made, for the period you pick.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# HTTP response codes
Source: https://apidocs.neetokb.com/api/response-codes
Learn about the HTTP status codes returned by the NeetoKB API.
## Success codes
**200 OK**
The request was successful and the server returned the requested data.
**201 Created**
The request was successful and a new resource was created. Returned for POST requests that create new resources.
**204 No Content**
The request was successful but there is no content to return. Typically returned for DELETE operations.
## Error codes
**400 Bad Request**
There was an issue with the request. This usually indicates malformed JSON,
missing required parameters, or invalid parameter values.
**401 Unauthorized**
The request needs to be authenticated. This typically means:
* Missing API key.
* Invalid API key.
* Expired API key.
**403 Forbidden**
An operation was not allowed. This could mean:
* Insufficient permissions for the requested action.
* Attempting to access a resource you don't own.
* API key doesn't have the required scope.
**404 Not Found**
The requested URL or resource was not found. This could indicate:
* Incorrect endpoint URL.
* Resource ID doesn't exist.
* Workspace subdomain is incorrect.
**422 Unprocessable Entity**
The given request could not be processed by the server due to malformed
request. Check the request body once again.
**429 Too Many Requests**
Rate limit exceeded. Try again after some time.
## Server error codes
**500 Internal Server Error**
An unexpected error occurred on the server. If this persists, please contact
support.
**501 Not Implemented**
The server does not support the functionality required to fulfill the request.
## Error response format
When an error occurs, the API returns a JSON response with error details:
```json 401 Unauthorized theme={"system"}
{
"error": "Could not authenticate, invalid API Key"
}
```
**error** `string`
A human-readable error message.
> [!TIP]
>
> When debugging API issues, the HTTP status code often provides the first clue
> about what went wrong. Start by checking the status code before diving into
> the response body.
# Search articles
Source: https://apidocs.neetokb.com/api/search/get
bundled/search.yaml GET /search
This API runs a full-text search across the workspace's published articles. Results are ranked by relevance, with the title weighted highest, then content, slug, category name, and keywords. Each match includes highlighted snippets showing where the search term appears.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get SEO settings
Source: https://apidocs.neetokb.com/api/seo-settings/get
bundled/seo-settings.yaml GET /seo_setting
This API returns the SEO settings of the knowledge base. For CLI sessions, this needs the Manage SEO settings permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update SEO settings
Source: https://apidocs.neetokb.com/api/seo-settings/update
bundled/seo-settings.yaml PATCH /seo_setting
This API updates the SEO settings of the knowledge base. Send at least one field. The `put` method works too. For CLI sessions, this needs the Manage SEO settings permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get organization settings
Source: https://apidocs.neetokb.com/api/settings/get
bundled/settings.yaml GET /setting
This API allows to fetch workspace settings.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update organization settings
Source: https://apidocs.neetokb.com/api/settings/update
bundled/settings.yaml PATCH /setting
This API updates workspace settings. Send at least one field. The `put` method works too. For CLI sessions, this needs the Manage basic info permission. `enable_social_media_sharing` and `facebook_app_id` need the Manage social sharing permission instead. Only the fields you send are checked.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Create tag
Source: https://apidocs.neetokb.com/api/tags/create
bundled/tags.yaml POST /tags
This API creates a tag. For CLI sessions, this needs the Manage tags permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete tag
Source: https://apidocs.neetokb.com/api/tags/delete
bundled/tags.yaml DELETE /tags/{id}
This API deletes a tag and removes it from every article. The articles are kept. For CLI sessions, this needs the Manage tags permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List tags
Source: https://apidocs.neetokb.com/api/tags/list
bundled/tags.yaml GET /tags
This API lists the tags in the workspace with the number of articles each one has.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Merge tags
Source: https://apidocs.neetokb.com/api/tags/merge
bundled/tags.yaml POST /tags/merge
This API merges tags into one. Articles that carry a secondary tag get the primary tag. The secondary tags are then deleted. If any tag is unknown, nothing is merged. For CLI sessions, this needs the Manage tags permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update tag
Source: https://apidocs.neetokb.com/api/tags/update
bundled/tags.yaml PATCH /tags/{id}
This API updates a tag. The `put` method works too. For CLI sessions, this needs the Manage tags permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Add team members
Source: https://apidocs.neetokb.com/api/team-members/add
bundled/team-members.yaml POST /team-members
Add team members to the workspace.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get team member details
Source: https://apidocs.neetokb.com/api/team-members/get
bundled/team-members.yaml GET /team-members/{team_member_id}
Retrieves details of a specific team member.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List team members
Source: https://apidocs.neetokb.com/api/team-members/list
bundled/team-members.yaml GET /team-members
List team members in the workspace.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Remove team member
Source: https://apidocs.neetokb.com/api/team-members/remove
bundled/team-members.yaml DELETE /team-members/{team_member_id}
Remove a team member from the workspace.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update team member
Source: https://apidocs.neetokb.com/api/team-members/update
bundled/team-members.yaml PATCH /team-members/{team_member_id}
Update a team member.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Clone theme
Source: https://apidocs.neetokb.com/api/themes/clone
bundled/themes.yaml POST /themes/{theme_id}/clone
This API copies a built-in or custom theme into a new unpublished custom theme named ` - Clone N`. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Create theme font
Source: https://apidocs.neetokb.com/api/themes/create-font
bundled/themes.yaml POST /themes/{theme_id}/fonts
This API adds a Google font to a custom theme. `name` is required. Built-in themes return 422. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete theme
Source: https://apidocs.neetokb.com/api/themes/delete
bundled/themes.yaml DELETE /themes/{id}
This API deletes a custom theme. Built-in themes cannot be deleted and return 404. The published theme cannot be deleted. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete theme font
Source: https://apidocs.neetokb.com/api/themes/delete-font
bundled/themes.yaml DELETE /themes/{theme_id}/fonts/{id}
This API deletes a font of a custom theme. Built-in themes return 422. A title or body font setting that points to it is not cleared. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get theme
Source: https://apidocs.neetokb.com/api/themes/get
bundled/themes.yaml GET /themes/{id}
This API returns one theme.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get theme configuration
Source: https://apidocs.neetokb.com/api/themes/get-configuration
bundled/themes.yaml GET /themes/{theme_id}/configuration
This API returns the fonts, colors, images and custom CSS of a theme.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List themes
Source: https://apidocs.neetokb.com/api/themes/list
bundled/themes.yaml GET /themes
This API lists the themes of the workspace, built-in themes first and then custom themes. It is not paginated.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Publish theme
Source: https://apidocs.neetokb.com/api/themes/publish
bundled/themes.yaml POST /themes/{theme_id}/publish
This API makes the theme the one visitors see. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update theme
Source: https://apidocs.neetokb.com/api/themes/update
bundled/themes.yaml PATCH /themes/{id}
This API renames a custom theme. Built-in themes cannot be renamed and return 404. The `put` method works too. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update theme configuration
Source: https://apidocs.neetokb.com/api/themes/update-configuration
bundled/themes.yaml PATCH /themes/{theme_id}/configuration
This API changes the configuration of a custom theme. Send at least one field. Built-in themes cannot be changed: clone the theme first. Header text and search input text are workspace settings, so change them with [Update organization settings](/api/settings/update). The `put` method works too. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update theme font
Source: https://apidocs.neetokb.com/api/themes/update-font
bundled/themes.yaml PATCH /themes/{theme_id}/fonts/{id}
This API changes a font of a custom theme. Send at least one field. Built-in themes return 422. The `put` method works too. For CLI sessions, this needs the Manage themes permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete trashed article
Source: https://apidocs.neetokb.com/api/trash/delete
bundled/trashed-articles.yaml DELETE /trashed_articles/{id}
This API deletes a trashed article for good. It cannot be undone. For CLI sessions, this needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List trashed articles
Source: https://apidocs.neetokb.com/api/trash/list
bundled/trashed-articles.yaml GET /trashed_articles
This API lists the articles in the trash. For CLI sessions, this needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Restore trashed article
Source: https://apidocs.neetokb.com/api/trash/restore
bundled/trashed-articles.yaml POST /trashed_articles/{trashed_article_id}/restoration
This API moves an article out of the trash. For CLI sessions, this needs the Manage articles permission.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Create webhook
Source: https://apidocs.neetokb.com/api/webhooks/create
bundled/webhooks.yaml POST /webhooks
This API creates a webhook.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Delete webhook
Source: https://apidocs.neetokb.com/api/webhooks/delete
bundled/webhooks.yaml DELETE /webhooks/{id}
This API deletes a webhook. It works for deprecated and expired webhooks too.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List webhook events
Source: https://apidocs.neetokb.com/api/webhooks/events
bundled/webhooks.yaml GET /webhooks/events
This API lists the events a webhook can subscribe to.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Get webhook
Source: https://apidocs.neetokb.com/api/webhooks/get
bundled/webhooks.yaml GET /webhooks/{id}
This API returns one webhook.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# List webhooks
Source: https://apidocs.neetokb.com/api/webhooks/list
bundled/webhooks.yaml GET /webhooks
This API lists the webhooks of the workspace. The secret is never returned.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Update webhook
Source: https://apidocs.neetokb.com/api/webhooks/update
bundled/webhooks.yaml PATCH /webhooks/{id}
This API updates a webhook. Send at least one field. A webhook on a deprecated or expired payload version cannot be updated or activated. Delete it instead. The `put` method works too.
> [!NOTE]
>
> Replace `{your-subdomain}` with your workspace's subdomain. \
> Learn how to find your subdomain in [Workspace subdomain](/api/workspace-subdomain).
# Workspace subdomain
Source: https://apidocs.neetokb.com/api/workspace-subdomain
Learn how to find your workspace subdomain.
## What is a subdomain?
A subdomain is the part of your workspace URL that comes before the main domain. For example, in the URL:
```
https://spinkart.neetokb.com
```
**spinkart** is the subdomain.
This subdomain is crucial for making API requests, as it identifies your specific workspace within NeetoKB.
## Step-by-step instructions
**1. Locate your workspace URL**
You can usually find this in your browser's address bar when logged into your workspace.
Example:
```
https://your-subdomain.neetokb.com/admin/articles
```
**2. Identify the main domain**
Our main domain is: `neetokb.com`
**3. Extract the part before the main domain**
Everything before `neetokb.com` is your subdomain.
**Example:**
* URL: `https://green-earth.neetokb.com`
* Subdomain: `green-earth`
## Using your subdomain in API requests
Once you've identified your subdomain, you'll use it in all API requests. The base URL format is:
```
https://{your-subdomain}.neetokb.com/api/external/v2
```
For example, if your subdomain is `mycompany`, your API base URL would be:
```
https://mycompany.neetokb.com/api/external/v2
```
## Common examples
Here are some common subdomain patterns:
| Type | Example URL | Subdomain |
| - | - | - |
| Company | `https://acmecorp.neetokb.com/admin/articles` | `acmecorp` |
| Department | `https://marketing.neetokb.com/admin/reports/dashboard` | `marketing` |
| Project | `https://product-launch.neetokb.com/admin/my-preferences` | `product-launch` |
# Articles
Source: https://apidocs.neetokb.com/cli-reference/articles
List, search, view, create, update, trash, schedule, and share articles.
An article is a single page of content in your knowledge base. For fields and response details, see the [API reference](/api/articles/list).
Every command that takes an article ID accepts the article's slug, its permalink identifier (`a-XXXXXXXX`), or its UUID. See [Getting an article ID](/api/getting-article-id).
## List articles
This command lists published articles by default; pass `--state all` to include drafts. Use this when you want to review what exists, filter by category or state, or collect IDs for another command.
```bash theme={"system"}
neetokb articles list
neetokb articles list --state draft
neetokb articles list --state all --sort-by updated_at --order-by asc
neetokb articles list --category-id b7e91c2a-8f43-4d0e-9a15-6c2d8e7f1b3a
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--category-id` | `string` | | | Filter by category ID |
| `--order-by` | `string` | | | Sort order: asc or desc |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--search-term` | `string` | | | Search term |
| `--sort-by` | `string` | | | Sort field: title, slug, state, category\_name, views\_count, created\_at, updated\_at |
| `--state` | `string` | | | Filter by state: draft, published, archived or all (default: published) |
```json Sample output (--json) theme={"system"}
{
"data": [
{
"id": "a1b2c3d4-1111-2222-3333-444455556666",
"slug": "getting-started",
"title": "Getting Started Guide",
"state": "published",
"permalink_identifier": "a-84af178b",
"author": {
"id": "aaaabbbb-cccc-dddd-eeee-ffff00001111",
"name": "Oliver Smith",
"email": "oliver@example.com"
},
"tags": ["tutorial"],
"url": "https://spinkart.neetokb.com/articles/getting-started",
"draft_url": null,
"permalink": "https://spinkart.neetokb.com/p/a-84af178b",
"published_at": "2026-08-01T10:00:00.000Z",
"created_at": "2026-07-30T09:00:00.000Z",
"updated_at": "2026-08-01T10:00:00.000Z",
"unique_views_count": 42,
"is_archived": false,
"category": {
"id": "b7e91c2a-8f43-4d0e-9a15-6c2d8e7f1b3a",
"name": "Getting Started",
"is_private": false
}
}
],
"breadcrumbs": [
{ "label": "Show", "command": "neetokb articles show " },
{ "label": "Update", "command": "neetokb articles update " }
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page_number": 1,
"page_size": 30
}
}
```
`--state` takes `draft`, `published`, `archived` or `all`. `--search-term` is a partial, case-insensitive match on title, slug and body; with `--state draft` or `all` it also matches unpublished draft revisions. It is not relevance ranked, so use [search](#search-articles) for that. `--sort-by` takes `title`, `slug`, `state`, `category_name`, `views_count`, `created_at` or `updated_at`, and `--order-by` takes `asc` or `desc`.
## Search articles
This command runs a full-text search across your published articles, ranked by relevance. Use this when you know roughly what an article says but not where it lives; `articles list --search-term` filters the same corpus but returns the full list shape. For fields and response details, see the [API reference](/api/search/get).
```bash theme={"system"}
neetokb search --search-term "billing"
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--search-term` | `string` | Yes | | Search query |
The table shows the article ID, the matched snippet and the article URL. The snippet is flattened to plain text, so the highlight markup and the article's own line breaks never break the column alignment. `--json` and `--toon` carry every field the API returns, including `title`, `category`, `category_url`, `matched_title` and `matched_category`.
```json Sample output (--json) theme={"system"}
{
"data": [
{
"id": "a1b2c3d4-1111-2222-3333-444455556666",
"url": "https://spinkart.neetokb.com/articles/billing-and-invoices",
"title": "Billing and invoices",
"category": "Getting Started",
"category_url": "https://spinkart.neetokb.com/folders/getting-started",
"matched_title": "Billing and invoices",
"matched_content": "Your billing cycle starts on the day you subscribe.",
"matched_category": null
}
],
"breadcrumbs": [
{ "label": "Show article", "command": "neetokb articles show " }
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page_number": 1,
"page_size": 30
}
}
```
## Show an article
This command shows the full record for one article, including its HTML body, author, category, and tags. Use this when you want to read or export an article after finding its ID from `articles list` or `search`.
```bash theme={"system"}
neetokb articles show getting-started
neetokb articles show a-84af178b
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
```json Sample output (--json) theme={"system"}
{
"data": {
"article": {
"id": "a1b2c3d4-1111-2222-3333-444455556666",
"slug": "getting-started",
"title": "Getting Started Guide",
"state": "published",
"full_url": "https://spinkart.neetokb.com/articles/getting-started",
"url": "/articles/getting-started",
"html_content": "
Welcome
This is a getting started guide.
",
"author": {
"name": "Oliver Smith",
"email": "oliver@example.com",
"profile_image_url": null
},
"category": {
"id": "b7e91c2a-8f43-4d0e-9a15-6c2d8e7f1b3a",
"name": "Getting Started"
}
},
"meta": {
"url": "/articles/getting-started",
"page_title": "Getting Started - Knowledge Base",
"meta_description": "A comprehensive guide to help you get started with our platform"
}
}
}
```
## Create an article
This command creates an article in a category. Use this when you want to publish content from a script or a content pipeline instead of the editor.
```bash theme={"system"}
neetokb articles create \
--title "Getting Started" \
--slug getting-started \
--category "Installation,Getting Started" \
--html-content "
Welcome
Example content
" \
--state draft
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--category` | `string` | Yes | | Category path, most specific first (comma-separated, e.g. 'Installation,Getting Started') |
| `--html-content` | `string` | | | Article HTML content |
| `--note` | `string` | | | Internal note |
| `--related-articles` | `string` | | | Related article IDs, slugs or permalink identifiers (comma-separated) |
| `--slug` | `string` | | | Article slug |
| `--state` | `string` | | | Article state (draft/published) |
| `--tags` | `string` | | | Tag names (comma-separated); missing tags are created |
| `--title` | `string` | | | Article title |
`--category` is the category path, most specific first: `"Installation,Getting Started"` places the article in `Installation`, whose parent is `Getting Started`. Names are matched, not IDs or slugs. `--tags` takes comma-separated tag names, and tags that do not exist are created. Omit `--state` and the article is created as a draft. Creating with `--state published` needs the Manage articles permission.
```json Sample output (--json) theme={"system"}
{
"data": {
"article": {
"id": "a1b2c3d4-1111-2222-3333-444455556666",
"slug": "getting-started",
"permalink": "a-84af178b"
}
},
"breadcrumbs": [
{ "label": "Show", "command": "neetokb articles show " }
]
}
```
With `--quiet`, this prints only the new article's ID.
## Update an article
This command updates an existing article's title, body, slug, state, or category. Use this to publish a draft, correct content, rename an article's URL, or move an article to another category.
```bash theme={"system"}
neetokb articles update a-84af178b --title "Getting Started Guide"
neetokb articles update a-84af178b --state published
neetokb articles update a-84af178b --category "Installation,Getting Started"
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--category` | `string` | | | New category path, most specific first, comma-separated; missing categories are created |
| `--html-content` | `string` | | | Article HTML content |
| `--note` | `string` | | | Internal note; an empty value deletes it |
| `--related-articles` | `string` | | | Related article IDs, slugs or permalink identifiers (comma-separated) that replace all related articles; an empty value removes all |
| `--slug` | `string` | | | Article slug |
| `--state` | `string` | | | Article state (draft/published) |
| `--tags` | `string` | | | Tag names (comma-separated) that replace all tags; missing tags are created, an empty value removes all |
| `--title` | `string` | | | Article title |
Only the flags you pass are changed. `--tags` replaces all tags, and an empty value removes them all. `--related-articles` replaces all related articles with the given IDs, slugs or permalink identifiers, and an empty value removes them all; an unknown article changes nothing. `--note` sets the internal note, and an empty value deletes it. `--slug` can be modified only while the article is published. `--category` is the category path, most specific first, and moves the article; categories that do not exist are created.
Drafts need the Modify articles permission. Publishing, and any change to an already published article, also needs the Manage articles permission.
```json Sample output (--json) theme={"system"}
{
"data": {
"article": {
"id": "a1b2c3d4-1111-2222-3333-444455556666",
"slug": "getting-started",
"title": "Getting Started Guide",
"state": "published",
"permalink": "a-84af178b"
}
}
}
```
## Unlisted links
An unlisted link is a secret URL that lets anyone view a published article without signing in. For fields and response details, see the [API reference](/api/articles/get-unlisted-link).
### Get an unlisted link
This command shows the unlisted link an article already has. It never creates a link, so it fails when the article has none or the link has expired. Use this when you want to share a published article outside your knowledge base.
```bash theme={"system"}
neetokb articles unlisted-links get getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
```json Sample output (--json) theme={"system"}
{
"data": {
"unlisted_link": {
"url": "https://spinkart.neetokb.com/public/p-1a2b3c4d5e",
"enabled": true,
"expiration_type": "never",
"expiration_date": null
}
},
"breadcrumbs": [
{
"label": "Regenerate",
"command": "neetokb articles unlisted-links regenerate "
}
]
}
```
To create the first link, or to replace an expired one, use `regenerate`. The article must be published; a draft returns an error.
### Regenerate an unlisted link
This command issues a new unlisted link and invalidates the old URL immediately. Use this when a link has been shared too widely, or when you want the link to expire.
```bash theme={"system"}
neetokb articles unlisted-links regenerate getting-started
neetokb articles unlisted-links regenerate getting-started --expiration-type seven_days
neetokb articles unlisted-links regenerate getting-started \
--expiration-type custom --expiration-date 2026-08-21T10:00:00Z
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--expiration-date` | `string` | | | Exact expiry datetime (ISO8601, future). Required with --expiration-type custom; implies custom when --expiration-type is omitted; rejected alongside presets or never |
| `--expiration-type` | `string` | | | Expiration preset: never (default, no expiration), one\_day, seven\_days, thirty\_days, or custom; preset dates are computed server-side and reject --expiration-date |
The presets `one_day`, `seven_days`, and `thirty_days` compute the expiry on the server and reject `--expiration-date`. Use `custom` together with `--expiration-date` for an exact time; passing `--expiration-date` alone is treated as `custom`.
```json Sample output (--json) theme={"system"}
{
"data": {
"unlisted_link": {
"url": "https://spinkart.neetokb.com/public/p-9f8e7d6c5b",
"enabled": true,
"expiration_type": "seven_days",
"expiration_date": "2026-08-07T10:00:00.000Z"
}
},
"breadcrumbs": [
{
"label": "Get",
"command": "neetokb articles unlisted-links get "
}
]
}
```
## Trash an article
This command moves an article to the trash. It stays there for 30 days before it is deleted for good. Needs the Manage articles permission. Use [`neetokb trash`](/cli-reference/trash) to restore it. A synced article cannot be trashed.
```bash theme={"system"}
neetokb articles trash getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
## Trash articles in bulk
This command moves up to 100 articles to the trash. If one cannot be trashed, none are.
```bash theme={"system"}
neetokb articles bulk-trash --ids getting-started,a-84af178b
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--ids` | `string` | Yes | | Article IDs, slugs or permalink identifiers (comma-separated, up to 100) |
## Archive and unarchive an article
Archiving turns an article into a draft and keeps it out of the public knowledge base. Unarchiving brings it back as a draft. List archived articles with `neetokb articles list --state archived`.
```bash theme={"system"}
neetokb articles archive getting-started
neetokb articles unarchive getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
## Discard a draft
This command throws away the unpublished draft changes of a published article. The live version stays. An article that is not published has no live version to keep, so the command is refused; trash the article instead.
```bash theme={"system"}
neetokb articles discard-draft getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
## Clone an article
This command copies an article into a new draft titled ` - CLONED - `.
```bash theme={"system"}
neetokb articles clone getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
## Update articles in bulk
This command changes up to 100 articles at once. Give exactly one of `--category-id`, `--state` or `--status`. The change is all-or-nothing. `--state` also needs the Manage articles permission.
```bash theme={"system"}
neetokb articles bulk-update --ids getting-started,a-84af178b --category-id b7e91c2a-8f43-4d0e-9a15-6c2d8e7f1b3a
neetokb articles bulk-update --ids getting-started --status archive
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--category-id` | `string` | | | Move the articles to this category ID |
| `--ids` | `string` | Yes | | Article IDs, slugs or permalink identifiers (comma-separated, up to 100) |
| `--state` | `string` | | | Set the state: draft or published |
| `--status` | `string` | | | Set the status: archive or active |
`--state` takes `draft` or `published`. `--status` takes `archive` or `active`.
## Schedules
A schedule publishes or unpublishes an article at a future time. Creating a `publish` schedule also needs the Manage articles permission.
```bash theme={"system"}
neetokb articles schedules list getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
### Create a schedule
This command schedules a publish or unpublish.
```bash theme={"system"}
neetokb articles schedules create getting-started \
--kind publish --datetime 2026-12-01T10:00:00 --time-zone Asia/Kolkata
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--datetime` | `string` | Yes | | Future date and time (ISO 8601); read in --time-zone when it has no offset |
| `--kind` | `string` | Yes | | What happens at the time: publish or unpublish |
| `--publish-note` | `string` | | | Note saved with the publication |
| `--time-zone` | `string` | Yes | | IANA time zone name, for example Asia/Kolkata |
The date must be in the future. When it has no offset, it is read in `--time-zone`. An article can have one schedule of each kind, and when it has both, the unpublish time must not come after the publish time.
### Delete a schedule
This command deletes a schedule.
```bash theme={"system"}
neetokb articles schedules delete getting-started 8e1f3a60-b2c7-4d95-8a04-5c7d9e2b6f13
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
* `` - Schedule ID from `schedules list`
## Article SEO settings
These commands show and change the SEO settings of one article. For the whole knowledge base, see [`neetokb workspace seo`](/cli-reference/workspace#knowledge-base-seo-settings).
```bash theme={"system"}
neetokb articles seo show getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
### Update article SEO settings
Only the flags you pass change.
```bash theme={"system"}
neetokb articles seo update getting-started --title "Get started" --keywords setup,install
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--allow-search-engine-crawl` | `bool` | | `false` | Let search engines crawl the article (--allow-search-engine-crawl=false blocks them) |
| `--description` | `string` | | | Meta description |
| `--keywords` | `string` | | | Keywords (comma-separated); replaces the current list |
| `--title` | `string` | | | Page title |
| `--title-suffix` | `string` | | | Text added after the page title |
`--keywords` replaces the whole list. The cover image and the Google Analytics ID are not available here.
## Revisions
A revision is a saved earlier version of an article.
```bash theme={"system"}
neetokb articles revisions list getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
### Show a revision
This command shows a revision with its title and HTML content.
```bash theme={"system"}
neetokb articles revisions show getting-started 2a6d8c14-9e03-4b57-b8f1-d4c7e0a35962
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
* `` - Revision ID from `revisions list`
### Restore a revision
This command copies a revision into the draft of an article. The live content does not change until you publish the draft. A synced article cannot be restored.
```bash theme={"system"}
neetokb articles revisions restore getting-started 2a6d8c14-9e03-4b57-b8f1-d4c7e0a35962
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
* `` - Revision ID from `revisions list`
# Attachments
Source: https://apidocs.neetokb.com/cli-reference/attachments
Upload images and files to use inside articles.
An attachment is a file, such as an image, that you can use inside an article. For fields and response details, see the [API reference](/api/attachments/create).
## Upload an attachment
This command uploads a file from a public URL or from your computer. Use this when you want an image or document inside an article's HTML content. It needs the Modify articles permission.
```bash theme={"system"}
neetokb attachments create --file ./diagram.png
neetokb attachments create --url https://example.com/diagram.png
```
Give exactly one of `--url` or `--file`. With `--file`, the CLI sends the file as base64 and takes the file name and type from the path unless you pass `--filename` or `--content-type`.
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--content-type` | `string` | | | MIME type (default: guessed from the --file extension) |
| `--file` | `string` | | | Path of a local file to upload |
| `--filename` | `string` | | | File name to store (default: the base name of --file) |
| `--url` | `string` | | | Public URL of the file to attach |
```json Sample output (--json) theme={"system"}
{
"data": {
"id": "c3d4e5f6-1111-2222-3333-444455556666",
"filename": "diagram.png",
"content_type": "image/png",
"byte_size": 20480,
"blob_url": "https://spinkart.neetokb.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMi/diagram.png",
"attachable_html": ""
},
"breadcrumbs": [
{
"label": "Use in article",
"command": "neetokb articles update --html-content '......'"
}
]
}
```
Paste `attachable_html` into the `--html-content` of [`articles create`](/cli-reference/articles#create-an-article) or [`articles update`](/cli-reference/articles#update-an-article). `attachable_html` is `null` for files that are not images. A file that is never used in an article is removed automatically.
# Authors
Source: https://apidocs.neetokb.com/cli-reference/authors
List the people who have written articles in your knowledge base.
An author is a workspace user credited on one or more articles. For fields and response details, see the [API reference](/api/authors/list).
## List authors
This command lists the authors in your workspace. Use this when you want to see who contributes content, or to match an article's author to a workspace account.
```bash theme={"system"}
neetokb authors list
neetokb authors list --sort-by articles_count --order-by desc
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--order-by` | `string` | | | Sort order: asc or desc |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--sort-by` | `string` | | | Sort field: name or articles\_count |
```json Sample output (--json) theme={"system"}
{
"data": [
{
"id": "aaaabbbb-cccc-dddd-eeee-ffff00001111",
"name": "Oliver Smith",
"email": "oliver@example.com",
"profile_image_url": null,
"articles_count": 14,
"published_articles_count": 12,
"draft_articles_count": 2
}
],
"breadcrumbs": [
{ "label": "List articles", "command": "neetokb articles list" }
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page_number": 1,
"page_size": 30
}
}
```
Deactivated authors are included. `--sort-by` takes `name` or `articles_count`, and `--order-by` takes `asc` or `desc`. The list covers authors only. To manage workspace access, see [Team members](/cli-reference/team-members).
# Categories
Source: https://apidocs.neetokb.com/cli-reference/categories
List, create, update, delete, and reorder the categories that organize your knowledge base.
A category groups articles in your knowledge base and can nest inside another category. For fields and response details, see the [API reference](/api/categories/list).
## List categories
This command lists the category tree with article counts. The tree omits categories without published articles, and omits private categories for API keys. Pass `--flat` to list every category, including empty and private ones, as flat rows. Use this when you want a category ID to filter articles by, or to check where a new article should go before creating it.
```bash theme={"system"}
neetokb categories list
neetokb categories list --page-size 100
neetokb categories list --flat
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--flat` | `bool` | | `false` | List every category, including empty and private ones, as flat rows with counts |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
```json Sample output (--json) theme={"system"}
{
"data": [
{
"id": "b7e91c2a-8f43-4d0e-9a15-6c2d8e7f1b3a",
"name": "Getting Started",
"slug": "getting-started",
"description": null,
"parent_id": null,
"depth": 0,
"articles_count": 12,
"categories_count": 2,
"total_articles_count": 18,
"url": "/categories/getting-started",
"subcategories": [],
"ancestors": []
}
],
"breadcrumbs": [
{
"label": "List articles in category",
"command": "neetokb articles list --category-id "
}
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page_number": 1,
"page_size": 30
}
}
```
`subcategories` nests the full child categories, and `ancestors` lists the parents up to the root. `articles_count` covers the category itself; `total_articles_count` includes its subcategories.
With `--flat`, each row also carries `is_private` and has no `subcategories` or `ancestors`. Private categories are hidden from logged-out visitors only; members see every article.
> [!TIP]
>
> Pass an `id` from this list to [`neetokb articles list --category-id`](/cli-reference/articles#list-articles). To place a new article, [`neetokb articles create --category`](/cli-reference/articles#create-an-article) takes category *names*, not these IDs.
## Show a category
This command shows one category. `articles_count` counts published articles only.
```bash theme={"system"}
neetokb categories show billing
```
**Required arguments:**
* `` - Category UUID or slug
## Create a category
This command creates a category. Changing categories needs the Manage categories permission.
```bash theme={"system"}
neetokb categories create --name Billing --description "Invoices" --parent getting-started --position 1
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--description` | `string` | | | Category description |
| `--name` | `string` | Yes | | Category name (up to 120 characters) |
| `--parent` | `string` | | | Parent category ID or slug |
| `--position` | `int` | | `0` | Position among sibling categories, starting at 1 |
| `--private` | `bool` | | `false` | Hide the category from visitors who are not signed in (--private=false makes it public) |
`--position` is 1-based among the siblings. A number larger than the sibling count puts the category last. A public category cannot sit under a private parent.
## Update a category
This command renames a category, changes its privacy, moves it or changes its position. Only the flags you pass change.
```bash theme={"system"}
neetokb categories update billing --name "Billing and invoices"
neetokb categories update billing --parent ""
```
**Required arguments:**
* `` - Category UUID or slug
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--description` | `string` | | | Category description |
| `--name` | `string` | | | Category name (up to 120 characters) |
| `--parent` | `string` | | | Parent category ID or slug |
| `--position` | `int` | | `0` | Position among sibling categories, starting at 1 |
| `--private` | `bool` | | `false` | Hide the category from visitors who are not signed in (--private=false makes it public) |
`--parent ""` moves the category to the top level. `--private` also applies to its subcategories.
## Delete a category
This command deletes a category. Its articles and subcategories move to `--move-to-category-id`, or to the parent category when you leave it out.
```bash theme={"system"}
neetokb categories delete billing --move-to-category-id getting-started
```
**Required arguments:**
* `` - Category UUID or slug
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--move-to-category-id` | `string` | | | Category ID or slug that receives the articles and subcategories |
A top-level category that has articles or subcategories needs `--move-to-category-id`. The last remaining category cannot be deleted.
## Reorder category articles
This command sets the order of the articles in a category. Articles you leave out follow in their current order.
```bash theme={"system"}
neetokb categories reorder-articles billing --article-ids refund-policy,invoices
```
**Required arguments:**
* `` - Category UUID or slug
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--article-ids` | `string` | Yes | | Article IDs, slugs or permalink identifiers in the wanted order (comma-separated) |
Each article must be in the category. An article cannot be listed twice.
# Integrations
Source: https://apidocs.neetokb.com/cli-reference/integrations
Turn workspace integrations on or off.
For fields and response details, see the [API reference](/api/integrations/neeto-chat).
## NeetoChat
This command turns the NeetoChat integration on or off. It needs the Manage integrations permission.
```bash theme={"system"}
neetokb integrations neeto-chat --enabled
neetokb integrations neeto-chat --enabled=false
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--enabled` | `bool` | Yes | `false` | Turn NeetoChat on (--enabled=false turns it off) |
# Navigation links
Source: https://apidocs.neetokb.com/cli-reference/navigation-links
Show and replace the header and footer links of the knowledge base site.
Navigation links are the links shown in the header and footer of your public knowledge base. For fields and response details, see the [API reference](/api/navigation-links/list).
## List navigation links
This command shows the header links and the footer links, each in display order.
```bash theme={"system"}
neetokb navigation-links list
```
## Update navigation links
This command replaces the header links, the footer links or both. It reads them from a JSON file. Updating needs the Manage themes permission.
```bash theme={"system"}
neetokb navigation-links update --json-file links.json
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--json-file` | `string` | Yes | | JSON file such as `{"header_links":[{"label":"Docs","link":"https://example.com","kind":"external_link"}],"footer_links":[]}`; each link has label, link and kind (external\_link or action), and an optional id |
```json links.json theme={"system"}
{
"header_links": [
{ "label": "Docs", "link": "https://example.com/docs", "kind": "external_link" }
],
"footer_links": []
}
```
Each set you send becomes exactly that list, in that order. Links that are not in the list are deleted, and an empty list clears the set. A set you leave out is not changed. A link is matched to an existing one by `id`, or by `label` when it has no `id`. A label is up to 25 characters and unique within its set. `kind` is `external_link` or `action`. The change is all-or-nothing.
# Commands overview
Source: https://apidocs.neetokb.com/cli-reference/overview
Every neetokb command grouped by resource, with links to the full reference.
## Global flags
These flags work on every command and are left out of the per-command flag tables below. See [Output formats](/cli/output-formats) for details.
| Flag | Description |
| - | - |
| `--json` | Output as JSON |
| `--quiet` | Output raw data only (no envelope) |
| `--toon` | Output in TOON format (token-optimized for AI agents) |
| `--subdomain` | Override saved subdomain |
### articles
Manage articles
| Command | Description |
| - | - |
| [`neetokb articles archive`](/cli-reference/articles) | Archive an article: it becomes a draft that is kept out of the public knowledge base |
| [`neetokb articles bulk-trash`](/cli-reference/articles) | Move up to 100 articles to the trash; if one cannot be trashed none are |
| [`neetokb articles bulk-update`](/cli-reference/articles) | Move up to 100 articles to a category, set their state, or archive or unarchive them; give exactly one of --category-id, --state or --status |
| [`neetokb articles clone`](/cli-reference/articles) | Copy an article into a new draft |
| [`neetokb articles create`](/cli-reference/articles) | Create an article |
| [`neetokb articles discard-draft`](/cli-reference/articles) | Throw away the unpublished draft changes of an article and keep its live version |
| [`neetokb articles list`](/cli-reference/articles) | List articles |
| [`neetokb articles revisions list`](/cli-reference/articles) | List the revisions of an article, newest first |
| [`neetokb articles revisions restore`](/cli-reference/articles) | Copy a revision into the draft of an article; the live content does not change until the draft is published |
| [`neetokb articles revisions show`](/cli-reference/articles) | Show a revision with its title and content |
| [`neetokb articles schedules create`](/cli-reference/articles) | Schedule an article to be published or unpublished at a future time; when both kinds exist, the unpublish time must not come after the publish time |
| [`neetokb articles schedules delete`](/cli-reference/articles) | Delete a schedule |
| [`neetokb articles schedules list`](/cli-reference/articles) | List the schedules of an article |
| [`neetokb articles seo show`](/cli-reference/articles) | Show the SEO settings of an article |
| [`neetokb articles seo update`](/cli-reference/articles) | Update the SEO settings of an article; only the given fields change |
| [`neetokb articles show`](/cli-reference/articles) | Show an article |
| [`neetokb articles trash`](/cli-reference/articles) | Move an article to the trash, where it stays for 30 days before it is deleted for good; restore it with trash restore |
| [`neetokb articles unarchive`](/cli-reference/articles) | Bring an archived article back as a draft |
| [`neetokb articles unlisted-links get`](/cli-reference/articles) | Fetch an article's existing unlisted share link; fails if it has none or it expired, so use unlisted-links regenerate to create one (article-id: slug, permalink identifier a-XXXXXXXX, or UUID; article must be published) |
| [`neetokb articles unlisted-links regenerate`](/cli-reference/articles) | Regenerate an article's unlisted share link, invalidating the old URL immediately (article-id: slug, permalink identifier a-XXXXXXXX, or UUID; article must be published) |
| [`neetokb articles update`](/cli-reference/articles) | Update an article |
### attachments
Manage attachments
| Command | Description |
| - | - |
| [`neetokb attachments create`](/cli-reference/attachments) | Upload an attachment from a URL or a local file |
### authors
List article authors
| Command | Description |
| - | - |
| [`neetokb authors list`](/cli-reference/authors) | List authors |
### categories
Manage categories
| Command | Description |
| - | - |
| [`neetokb categories create`](/cli-reference/categories) | Create a category |
| [`neetokb categories delete`](/cli-reference/categories) | Delete a category; its articles and subcategories move to --move-to-category-id, which a top-level category with content needs |
| [`neetokb categories list`](/cli-reference/categories) | List categories |
| [`neetokb categories reorder-articles`](/cli-reference/categories) | Set the order of articles in a category; articles not listed follow in their current order |
| [`neetokb categories show`](/cli-reference/categories) | Show a category (id: UUID or slug) |
| [`neetokb categories update`](/cli-reference/categories) | Rename, move, reorder or change the privacy of a category; --parent "" moves it to the top level |
### doctor
Check CLI health and connectivity
| Command | Description |
| - | - |
| [`neetokb doctor`](/cli-reference/utility) | Check CLI health and connectivity |
### integrations
Manage integrations
| Command | Description |
| - | - |
| [`neetokb integrations neeto-chat`](/cli-reference/integrations) | Turn the NeetoChat integration on or off |
### login
Authenticate to NeetoKB via browser
| Command | Description |
| - | - |
| [`neetokb login`](/cli-reference/utility) | Authenticate to NeetoKB via browser |
### logout
Sign out and clear saved credentials
| Command | Description |
| - | - |
| [`neetokb logout`](/cli-reference/utility) | Sign out and clear saved credentials |
### navigation-links
Manage header and footer navigation links
| Command | Description |
| - | - |
| [`neetokb navigation-links list`](/cli-reference/navigation-links) | List the header and footer navigation links |
| [`neetokb navigation-links update`](/cli-reference/navigation-links) | Replace the header links, footer links or both from a JSON file; a set that is sent becomes exactly that list and links left out are deleted |
### preferences
Manage your own notification preferences; needs a signed-in user, not an API key
| Command | Description |
| - | - |
| [`neetokb preferences show`](/cli-reference/preferences) | Show your preferences |
| [`neetokb preferences update`](/cli-reference/preferences) | Update your preferences |
### recommendations
Manage recommendations
| Command | Description |
| - | - |
| [`neetokb recommendations create`](/cli-reference/recommendations) | Create a recommendation that suggests articles or categories on pages matching a URL |
| [`neetokb recommendations delete`](/cli-reference/recommendations) | Delete a recommendation |
| [`neetokb recommendations list`](/cli-reference/recommendations) | List recommendations |
| [`neetokb recommendations show`](/cli-reference/recommendations) | Show a recommendation with the articles and categories it points to |
| [`neetokb recommendations update`](/cli-reference/recommendations) | Update a recommendation; --entity replaces all its entities and --clear-entities removes them |
### redirections
Manage redirections
| Command | Description |
| - | - |
| [`neetokb redirections create`](/cli-reference/redirections) | Create a redirection from an old path to a new path or URL |
| [`neetokb redirections delete`](/cli-reference/redirections) | Delete a redirection |
| [`neetokb redirections list`](/cli-reference/redirections) | List redirections, newest first |
| [`neetokb redirections show`](/cli-reference/redirections) | Show a redirection |
| [`neetokb redirections update`](/cli-reference/redirections) | Update a redirection; only the given fields change |
### reports
Show search and visit reports
| Command | Description |
| - | - |
| [`neetokb reports clear failed-searches`](/cli-reference/reports) | Delete the failed searches data for the chosen period, or all of it when no period is given |
| [`neetokb reports clear invalid-urls`](/cli-reference/reports) | Delete the invalid URLs data for the chosen period or URL, or all of it when no filter is given |
| [`neetokb reports clear popular-searches`](/cli-reference/reports) | Delete the popular searches data for the chosen period, or all of it when no period is given |
| [`neetokb reports failed-searches`](/cli-reference/reports) | Show searches that found nothing |
| [`neetokb reports invalid-urls`](/cli-reference/reports) | Show visited URLs that do not exist |
| [`neetokb reports popular-searches`](/cli-reference/reports) | Show the most searched keywords |
| [`neetokb reports visits`](/cli-reference/reports) | Show knowledge base visits per day, oldest first |
### search
Search articles
| Command | Description |
| - | - |
| [`neetokb search`](/cli-reference/articles) | Search articles |
### setup
Set up NeetoKB for AI coding assistants
| Command | Description |
| - | - |
| [`neetokb setup claude`](/cli-reference/utility) | Register NeetoKB plugin with Claude Code |
| [`neetokb setup codex`](/cli-reference/utility) | Add NeetoKB instructions for OpenAI Codex |
| [`neetokb setup copilot`](/cli-reference/utility) | Add NeetoKB instructions for GitHub Copilot |
| [`neetokb setup cursor`](/cli-reference/utility) | Write NeetoKB rules for Cursor IDE |
| [`neetokb setup gemini`](/cli-reference/utility) | Add NeetoKB instructions for Gemini CLI |
| [`neetokb setup windsurf`](/cli-reference/utility) | Write NeetoKB rules for Windsurf IDE |
### tags
Manage article tags
| Command | Description |
| - | - |
| [`neetokb tags create`](/cli-reference/tags) | Create a tag |
| [`neetokb tags delete`](/cli-reference/tags) | Delete a tag; it is removed from every article and the articles are kept |
| [`neetokb tags list`](/cli-reference/tags) | List tags with the number of articles that use them |
| [`neetokb tags merge`](/cli-reference/tags) | Merge tags into one; articles of the secondary tags get the primary tag, which survives, and the secondary tags are deleted |
| [`neetokb tags update`](/cli-reference/tags) | Update a tag |
### team-members
Manage team members
| Command | Description |
| - | - |
| [`neetokb team-members create`](/cli-reference/team-members) | Invite team members |
| [`neetokb team-members delete`](/cli-reference/team-members) | Remove a team member |
| [`neetokb team-members list`](/cli-reference/team-members) | List team members |
| [`neetokb team-members show`](/cli-reference/team-members) | Show a team member |
| [`neetokb team-members update`](/cli-reference/team-members) | Update a team member |
### themes
Manage themes
| Command | Description |
| - | - |
| [`neetokb themes clone`](/cli-reference/themes) | Copy a built-in or custom theme into a new unpublished custom theme that can be edited |
| [`neetokb themes config show`](/cli-reference/themes) | Show the configuration of a theme |
| [`neetokb themes config update`](/cli-reference/themes) | Change the configuration of a custom theme; colors are merged into the current ones |
| [`neetokb themes delete`](/cli-reference/themes) | Delete a custom theme; the published theme cannot be deleted |
| [`neetokb themes fonts create`](/cli-reference/themes) | Add a Google font to a custom theme |
| [`neetokb themes fonts delete`](/cli-reference/themes) | Remove a font from a custom theme |
| [`neetokb themes fonts update`](/cli-reference/themes) | Change a font of a custom theme |
| [`neetokb themes list`](/cli-reference/themes) | List built-in and custom themes |
| [`neetokb themes publish`](/cli-reference/themes) | Make a theme the live theme of the public knowledge base |
| [`neetokb themes show`](/cli-reference/themes) | Show a theme |
| [`neetokb themes update`](/cli-reference/themes) | Rename a custom theme; built-in themes cannot be changed, clone them first |
### trash
Manage trashed articles
| Command | Description |
| - | - |
| [`neetokb trash delete`](/cli-reference/trash) | Delete a trashed article for good; this cannot be undone |
| [`neetokb trash list`](/cli-reference/trash) | List trashed articles and the days left before each is deleted for good |
| [`neetokb trash restore`](/cli-reference/trash) | Restore a trashed article |
### update
Update the CLI to the latest version
| Command | Description |
| - | - |
| [`neetokb update`](/cli-reference/utility) | Update the CLI to the latest version |
### version
Print the CLI version
| Command | Description |
| - | - |
| [`neetokb version`](/cli-reference/utility) | Print the CLI version |
### webhooks
Manage webhooks
| Command | Description |
| - | - |
| [`neetokb webhooks create`](/cli-reference/webhooks) | Create a webhook that sends article events to an endpoint |
| [`neetokb webhooks delete`](/cli-reference/webhooks) | Delete a webhook |
| [`neetokb webhooks events`](/cli-reference/webhooks) | List the events a webhook can subscribe to |
| [`neetokb webhooks list`](/cli-reference/webhooks) | List webhooks |
| [`neetokb webhooks show`](/cli-reference/webhooks) | Show a webhook; its secret is never shown |
| [`neetokb webhooks update`](/cli-reference/webhooks) | Update a webhook; --event replaces the whole event list |
### whoami
Show current authenticated user(s)
| Command | Description |
| - | - |
| [`neetokb whoami`](/cli-reference/utility) | Show current authenticated user(s) |
### workspace
Manage workspace
| Command | Description |
| - | - |
| [`neetokb workspace info`](/cli-reference/workspace) | Show workspace information |
| [`neetokb workspace seo show`](/cli-reference/workspace) | Show the knowledge base SEO settings |
| [`neetokb workspace seo update`](/cli-reference/workspace) | Update the knowledge base SEO settings; --keywords replaces the whole list |
| [`neetokb workspace update`](/cli-reference/workspace) | Update the knowledge base name, texts, sign-up, contact section and social sharing settings |
# Preferences
Source: https://apidocs.neetokb.com/cli-reference/preferences
Show and update your own notification preferences.
Preferences belong to the signed-in user. They need a signed-in session, so they do not work with an API key. For fields and response details, see the [API reference](/api/my-preferences/get).
## Show your preferences
This command shows your preferences.
```bash theme={"system"}
neetokb preferences show
```
## Update your preferences
This command changes your preferences. It needs no extra permission.
```bash theme={"system"}
neetokb preferences update --monthly-reports-mail=false
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--monthly-reports-mail` | `bool` | | `false` | Get the monthly report email (--monthly-reports-mail=false turns it off) |
# Recommendations
Source: https://apidocs.neetokb.com/cli-reference/recommendations
List, view, create, update, and delete the article recommendations for your pages.
A recommendation is a group of articles NeetoKB suggests for a given page, used to surface contextual help. For fields and response details, see the [API reference](/api/recommendations/get).
## List recommendations
This command returns the recommended articles for a page. Use this when you want to preview what your in-app help widget would show for a URL, or to build your own contextual help surface.
```bash theme={"system"}
neetokb recommendations list
neetokb recommendations list --match-uri feedback
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--match-uri` | `string` | | | Filter recommendations by URI |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
`--match-uri` is the relative or full URL of the page you want suggestions for. Omit it to get the default recommendations.
```json Sample output (--json) theme={"system"}
{
"data": [
{
"title": "Feedback",
"articles": [
{
"id": "a1b2c3d4-1111-2222-3333-444455556666",
"title": "Collecting customer feedback",
"category": {
"id": "b7e91c2a-8f43-4d0e-9a15-6c2d8e7f1b3a",
"name": "Getting Started"
}
}
]
}
],
"breadcrumbs": [
{ "label": "List articles", "command": "neetokb articles list" }
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page_number": 1,
"page_size": 30
}
}
```
Each entry is a titled group holding the articles recommended for it. Pass an article `id` to [`neetokb articles show`](/cli-reference/articles#show-an-article) to read the full content.
## Show a recommendation
This command shows a recommendation with the articles and categories it points to.
```bash theme={"system"}
neetokb recommendations show 6f0c3e84-d12a-4b79-9e58-a1b7c4d2e093
```
**Required arguments:**
* `` - Recommendation ID from `recommendations list`
## Create a recommendation
This command creates a recommendation that suggests articles or categories on pages whose URL matches. Changing recommendations needs the Manage recommendations permission.
```bash theme={"system"}
neetokb recommendations create --title Refunds --url /refund \
--entity Article:a1b2c3d4-1111-2222-3333-444455556666 \
--entity Category:b7e91c2a-8f43-4d0e-9a15-6c2d8e7f1b3a
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--entity` | `stringArray` | | `[]` | Article or category to recommend as Article:\ or Category:\; repeat for several |
| `--matching-criteria` | `string` | | | How the URL is matched: contains, exact\_match or regex |
| `--title` | `string` | Yes | | Recommendation title, unique ignoring case |
| `--url` | `string` | Yes | | URL or regular expression the recommendation applies to |
`--matching-criteria` takes `contains` (the default), `exact_match` or `regex`. With `regex`, `--url` must be a valid regular expression. The title and the URL are each unique in the workspace.
## Update a recommendation
This command changes a recommendation. Only the flags you pass change.
```bash theme={"system"}
neetokb recommendations update 6f0c3e84-d12a-4b79-9e58-a1b7c4d2e093 --url /refunds
neetokb recommendations update 6f0c3e84-d12a-4b79-9e58-a1b7c4d2e093 --clear-entities
```
**Required arguments:**
* `` - Recommendation ID from `recommendations list`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--clear-entities` | `bool` | | `false` | Remove all entities from the recommendation |
| `--entity` | `stringArray` | | `[]` | Article or category to recommend as Article:\ or Category:\; repeat for several |
| `--matching-criteria` | `string` | | | How the URL is matched: contains, exact\_match or regex |
| `--title` | `string` | | | Recommendation title, unique ignoring case |
| `--url` | `string` | | | URL or regular expression the recommendation applies to |
`--entity` replaces all entities. `--clear-entities` removes them all. Leave both out to keep them.
## Delete a recommendation
This command deletes a recommendation.
```bash theme={"system"}
neetokb recommendations delete 6f0c3e84-d12a-4b79-9e58-a1b7c4d2e093
```
**Required arguments:**
* `` - Recommendation ID from `recommendations list`
# Redirections
Source: https://apidocs.neetokb.com/cli-reference/redirections
List, create, update, and delete redirections.
A redirection sends visitors from an old path to a new path or URL. For fields and response details, see the [API reference](/api/redirections/list).
## List redirections
This command lists redirections, newest first. The domain redirection is included.
```bash theme={"system"}
neetokb redirections list
neetokb redirections list --search-term refund
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--search-term` | `string` | | | Show redirections whose from or to path contains this text |
## Show a redirection
This command shows one redirection.
```bash theme={"system"}
neetokb redirections show 5d2e8b17-6c4a-4f93-a0e1-72b9c3d8f406
```
**Required arguments:**
* `` - Redirection ID from `redirections list`
## Create a redirection
This command creates a redirection. Creating one needs the Manage redirections permission.
```bash theme={"system"}
neetokb redirections create --from-path /old-refund --to-path /refund-policy
neetokb redirections create --type domain \
--from-path https://old.example.com --to-path https://help.example.com
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--from-path` | `string` | Yes | | Old path, or a bare origin such as [https://old.example.com](https://old.example.com) for a domain redirection |
| `--to-path` | `string` | Yes | | New path or full URL |
| `--type` | `string` | | | Redirection type: page (default) or domain |
`--type` takes `page` or `domain`. It defaults to `page`. For a domain redirection, `--from-path` is a bare origin. A redirection is refused when `--to-path` is empty, `--from-path` is already used, both paths are the same, or it would chain with another.
## Update a redirection
This command changes a redirection. Only the flags you pass change.
```bash theme={"system"}
neetokb redirections update 5d2e8b17-6c4a-4f93-a0e1-72b9c3d8f406 --to-path /refunds
```
**Required arguments:**
* `` - Redirection ID from `redirections list`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--from-path` | `string` | | | Old path, or a bare origin such as [https://old.example.com](https://old.example.com) for a domain redirection |
| `--to-path` | `string` | | | New path or full URL |
| `--type` | `string` | | | Redirection type: page (default) or domain |
## Delete a redirection
This command deletes a redirection.
```bash theme={"system"}
neetokb redirections delete 5d2e8b17-6c4a-4f93-a0e1-72b9c3d8f406
```
**Required arguments:**
* `` - Redirection ID from `redirections list`
# Reports
Source: https://apidocs.neetokb.com/cli-reference/reports
Show search, invalid URL, and visit reports, and clear report data.
Reports show how visitors use your knowledge base. All commands take a period. For fields and response details, see the [API reference](/api/reports/popular-searches).
## Popular searches
This command lists the keywords visitors search for, with how often.
```bash theme={"system"}
neetokb reports popular-searches
neetokb reports popular-searches --duration last_30_days
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--duration` | `string` | | | Period: all\_time (default), last\_24\_hours, last\_7\_days, this\_week, last\_week, last\_30\_days, this\_month, last\_month, this\_quarter, last\_quarter or custom |
| `--end-date` | `string` | | | End date (ISO 8601); needed with --duration custom |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--start-date` | `string` | | | Start date (ISO 8601); needed with --duration custom |
`--duration` takes `all_time` (the default), `last_24_hours`, `last_7_days`, `this_week`, `last_week`, `last_30_days`, `this_month`, `last_month`, `this_quarter`, `last_quarter` or `custom`. With `custom`, pass both `--start-date` and `--end-date`, and the start must not be after the end.
## Failed searches
This command lists the searches that found no article. Use this to decide which articles to write next.
```bash theme={"system"}
neetokb reports failed-searches --duration last_7_days
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--duration` | `string` | | | Period: all\_time (default), last\_24\_hours, last\_7\_days, this\_week, last\_week, last\_30\_days, this\_month, last\_month, this\_quarter, last\_quarter or custom |
| `--end-date` | `string` | | | End date (ISO 8601); needed with --duration custom |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--start-date` | `string` | | | Start date (ISO 8601); needed with --duration custom |
## Invalid URLs
This command lists visited URLs that do not exist, with how often and where the visitor came from. Use this to decide which redirections to add.
```bash theme={"system"}
neetokb reports invalid-urls
neetokb reports invalid-urls --url /gone
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--duration` | `string` | | | Period: all\_time (default), last\_24\_hours, last\_7\_days, this\_week, last\_week, last\_30\_days, this\_month, last\_month, this\_quarter, last\_quarter or custom |
| `--end-date` | `string` | | | End date (ISO 8601); needed with --duration custom |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--start-date` | `string` | | | Start date (ISO 8601); needed with --duration custom |
| `--url` | `string` | | | Only include this URL |
## Visits
This command shows the visits to the knowledge base for each day, oldest first. It is not paginated.
```bash theme={"system"}
neetokb reports visits --duration this_month
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--duration` | `string` | | | Period: all\_time (default), last\_24\_hours, last\_7\_days, this\_week, last\_week, last\_30\_days, this\_month, last\_month, this\_quarter, last\_quarter or custom |
| `--end-date` | `string` | | | End date (ISO 8601); needed with --duration custom |
| `--start-date` | `string` | | | Start date (ISO 8601); needed with --duration custom |
## Clear report data
These commands delete report data. They cannot be undone. With no period, they delete everything of that kind. They return the number of rows deleted, which is 0 when nothing matched. They need the Manage articles permission.
```bash theme={"system"}
neetokb reports clear popular-searches --duration last_month
neetokb reports clear failed-searches
neetokb reports clear invalid-urls --url /gone
```
Each command takes the same period flags as its report, and `clear invalid-urls` also takes `--url`.
### Clear popular searches
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--duration` | `string` | | | Period: all\_time (default), last\_24\_hours, last\_7\_days, this\_week, last\_week, last\_30\_days, this\_month, last\_month, this\_quarter, last\_quarter or custom |
| `--end-date` | `string` | | | End date (ISO 8601); needed with --duration custom |
| `--start-date` | `string` | | | Start date (ISO 8601); needed with --duration custom |
### Clear failed searches
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--duration` | `string` | | | Period: all\_time (default), last\_24\_hours, last\_7\_days, this\_week, last\_week, last\_30\_days, this\_month, last\_month, this\_quarter, last\_quarter or custom |
| `--end-date` | `string` | | | End date (ISO 8601); needed with --duration custom |
| `--start-date` | `string` | | | Start date (ISO 8601); needed with --duration custom |
### Clear invalid URLs
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--duration` | `string` | | | Period: all\_time (default), last\_24\_hours, last\_7\_days, this\_week, last\_week, last\_30\_days, this\_month, last\_month, this\_quarter, last\_quarter or custom |
| `--end-date` | `string` | | | End date (ISO 8601); needed with --duration custom |
| `--start-date` | `string` | | | Start date (ISO 8601); needed with --duration custom |
| `--url` | `string` | | | Only include this URL |
# Tags
Source: https://apidocs.neetokb.com/cli-reference/tags
List, create, update, delete, and merge article tags.
A tag is a label you attach to articles. For fields and response details, see the [API reference](/api/tags/list).
## List tags
This command lists tags with the number of articles that use each one. Use this to find a tag ID before you update, delete, or merge it.
```bash theme={"system"}
neetokb tags list
neetokb tags list --search-term bill
neetokb tags list --sort-by articles_count
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--order-by` | `string` | | | Sort order: asc or desc |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
| `--search-term` | `string` | | | Show tags whose name contains this text |
| `--sort-by` | `string` | | | Sort field: name or articles\_count |
`--sort-by` takes `name` or `articles_count`. `--order-by` takes `asc` or `desc`. It defaults to `asc` for `name` and `desc` for `articles_count`.
## Create a tag
This command creates a tag. Tag names are unique in the workspace, ignoring case. Creating a tag needs the Manage tags permission.
```bash theme={"system"}
neetokb tags create --name Billing --style info
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--description` | `string` | | | Tag description |
| `--name` | `string` | Yes | | Tag name, unique ignoring case |
| `--style` | `string` | | | Tag colour: primary, secondary, info, success, warning or danger |
`--style` takes `primary`, `secondary`, `info`, `success`, `warning` or `danger`. It defaults to `secondary`.
## Update a tag
This command changes the name, description or style of a tag. Only the flags you pass change.
```bash theme={"system"}
neetokb tags update 7c1d9a52-3b8e-4f60-a2d4-91e5c0b7f318 --name "Payments"
```
**Required arguments:**
* `` - Tag ID from `tags list`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--description` | `string` | | | Tag description |
| `--name` | `string` | | | Tag name, unique ignoring case |
| `--style` | `string` | | | Tag colour: primary, secondary, info, success, warning or danger |
## Delete a tag
This command deletes a tag and removes it from every article. The articles are kept.
```bash theme={"system"}
neetokb tags delete 7c1d9a52-3b8e-4f60-a2d4-91e5c0b7f318
```
**Required arguments:**
* `` - Tag ID from `tags list`
## Merge tags
This command merges tags into one. Articles that carry a secondary tag get the primary tag. The secondary tags are then deleted. Use this to clean up near-duplicate tags.
```bash theme={"system"}
neetokb tags merge \
--primary-id 7c1d9a52-3b8e-4f60-a2d4-91e5c0b7f318 \
--secondary-ids 0e4b6f81-5a2c-4d97-8c13-b6a7d2e90f45,3f8a1c64-9d0b-4e72-b5a1-c8e6d4f27a09
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--primary-id` | `string` | Yes | | ID of the tag that survives |
| `--secondary-ids` | `string` | Yes | | IDs of the tags merged into the primary tag and deleted (comma-separated) |
If any tag is unknown, nothing is merged. The primary tag cannot be in `--secondary-ids`.
# Team members
Source: https://apidocs.neetokb.com/cli-reference/team-members
List, view, invite, update, and remove team members.
A team member is a user in your workspace. For fields and response details, see the [API reference](/api/team-members/list).
## List team members
This command shows the team members in your workspace. Use this when you want to see who already has access before inviting or removing someone, or to look up a member's ID.
```bash theme={"system"}
neetokb team-members list
neetokb team-members list --email oliver@example.com
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--email` | `string` | | | Filter by email |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
```json Sample output (--json) theme={"system"}
{
"data": [
{
"id": "aaaabbbb-cccc-dddd-eeee-ffff00001111",
"email": "oliver@example.com",
"first_name": "Oliver",
"last_name": "Smith",
"time_zone": "Asia/Kolkata",
"profile_image_url": null,
"active": true,
"organization_role": "Admin"
}
],
"breadcrumbs": [
{ "label": "Show", "command": "neetokb team-members show " },
{ "label": "Update", "command": "neetokb team-members update " },
{ "label": "Remove", "command": "neetokb team-members delete " }
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page_number": 1,
"page_size": 30
}
}
```
`--email` matches an address exactly; it does not search by partial address.
## Show a team member
This command shows details for one team member ID. Use this when you want to inspect a member's email, role, time zone, and active status after finding their ID from `team-members list`.
```bash theme={"system"}
neetokb team-members show aaaabbbb-cccc-dddd-eeee-ffff00001111
```
**Required arguments:**
* `` - Team member UUID
```json Sample output (--json) theme={"system"}
{
"data": {
"team_member": {
"id": "aaaabbbb-cccc-dddd-eeee-ffff00001111",
"email": "oliver@example.com",
"first_name": "Oliver",
"last_name": "Smith",
"time_zone": "Asia/Kolkata",
"profile_image_url": null,
"active": true,
"organization_role": "Admin"
}
}
}
```
## Add team members
This command invites team members to your workspace. Use this when you want to add colleagues by email and assign an organization role without opening the Team Members page in NeetoKB.
```bash theme={"system"}
neetokb team-members create \
--emails oliver@example.com,sam@example.com \
--role Standard
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--emails` | `string` | Yes | | Email addresses to invite (comma-separated) |
| `--role` | `string` | Yes | | Organization role |
| `--send-invite` | `bool` | | `true` | Send invitation email |
Invites one or more people in a single call. `--emails` takes a comma-separated list, and both it and `--role` are required. `--role` must name a role that already exists under **Settings → Roles**. Pass `--send-invite=false` to add them without sending an invitation email.
```json Sample output (--json) theme={"system"}
{
"data": {
"message": "Users added successfully"
},
"breadcrumbs": [
{ "label": "List team members", "command": "neetokb team-members list" }
]
}
```
The response confirms the request; it does not include a team member record. List the members afterwards to retrieve it.
## Update a team member
This command updates a team member's profile or role. Use this when correcting names, email, time zone, or organization role.
```bash theme={"system"}
neetokb team-members update aaaabbbb-cccc-dddd-eeee-ffff00001111 \
--first-name Oliver --role Admin
```
**Required arguments:**
* `` - Team member UUID
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--email` | `string` | | | New email address |
| `--first-name` | `string` | | | First name |
| `--last-name` | `string` | | | Last name |
| `--role` | `string` | | | Organization role |
| `--time-zone` | `string` | | | Time zone |
Only the flags you pass are changed. `--role` must name a role that already exists in the workspace.
```json Sample output (--json) theme={"system"}
{
"data": {
"team_member": {
"id": "aaaabbbb-cccc-dddd-eeee-ffff00001111",
"email": "oliver@example.com",
"first_name": "Oliver",
"last_name": "Smith",
"time_zone": "Asia/Kolkata",
"profile_image_url": null,
"active": true,
"organization_role": "Admin"
}
}
}
```
## Delete a team member
This command removes a team member from your workspace. Use this when someone should no longer have access.
```bash theme={"system"}
neetokb team-members delete aaaabbbb-cccc-dddd-eeee-ffff00001111
```
**Required arguments:**
* `` - Team member UUID
```text Sample output theme={"system"}
Team member removed.
```
With `--quiet`, this prints `success`.
# Themes
Source: https://apidocs.neetokb.com/cli-reference/themes
List, edit, clone, and publish themes, and manage their configuration and fonts.
A theme controls how your public knowledge base looks. Built-in themes cannot be changed: clone one to get a theme you can edit. Changing a theme needs the Manage themes permission. For fields and response details, see the [API reference](/api/themes/list).
## List themes
This command lists built-in themes first and then custom themes.
```bash theme={"system"}
neetokb themes list
```
## Show a theme
This command shows one theme with its colors.
```bash theme={"system"}
neetokb themes show 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257
```
**Required arguments:**
* `` - Theme ID from `themes list`
## Rename a theme
This command renames a custom theme. A built-in theme returns not found.
```bash theme={"system"}
neetokb themes update 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257 --name "Spring"
```
**Required arguments:**
* `` - Theme ID from `themes list`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--name` | `string` | Yes | | New theme name |
## Clone a theme
This command copies a built-in or custom theme into a new unpublished custom theme named ` - Clone N`.
```bash theme={"system"}
neetokb themes clone 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257
```
**Required arguments:**
* `` - Theme ID from `themes list`
## Publish a theme
This command makes a theme the one visitors see.
```bash theme={"system"}
neetokb themes publish 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257
```
**Required arguments:**
* `` - Theme ID from `themes list`
## Delete a theme
This command deletes a custom theme. The published theme cannot be deleted.
```bash theme={"system"}
neetokb themes delete 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257
```
**Required arguments:**
* `` - Theme ID from `themes list`
## Show theme configuration
This command shows the fonts, colors, images and custom CSS of a theme.
```bash theme={"system"}
neetokb themes config show 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257
```
**Required arguments:**
* `` - Theme ID from `themes list`
## Update theme configuration
This command changes the configuration of a custom theme. Only the flags you pass change.
```bash theme={"system"}
neetokb themes config update 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257 \
--color header-bg=#ffffff --color header-text=#111827 \
--brand-image ./logo.png --brand-image-height 40
```
**Required arguments:**
* `` - Theme ID from `themes list`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--body-font-id` | `string` | | | ID of a font of this theme for body text |
| `--brand-image` | `string` | | | Brand image: a local file path or the signed ID of an uploaded attachment |
| `--brand-image-height` | `int` | | `0` | Brand image height in pixels |
| `--color` | `stringArray` | | `[]` | Color as name=value, for example header-bg=#ffffff; repeat for several |
| `--custom-css` | `string` | | | Custom CSS; an empty value clears it |
| `--header-image` | `string` | | | Header image: a local file path or the signed ID of an uploaded attachment |
| `--title-font-id` | `string` | | | ID of a font of this theme for titles |
Colors are merged into the current ones, and an unknown color name is refused. `--brand-image` and `--header-image` take a local file path or the signed ID of an uploaded attachment. The CLI uploads a file for you. `--custom-css ''` clears the custom CSS. The font flags take a font ID from `themes config show`. Header text and search input text are workspace settings, so change them with [`neetokb workspace update`](/cli-reference/workspace#update-workspace-settings).
## Add a font
This command adds a Google font to a custom theme.
```bash theme={"system"}
neetokb themes fonts create 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257 --name Roboto --weights 400,700
```
**Required arguments:**
* `` - Theme ID from `themes list`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--name` | `string` | Yes | | Google font name, for example Roboto |
| `--weights` | `string` | | | Font weights (comma-separated), for example 400,700 |
## Update a font
This command changes a font of a custom theme.
```bash theme={"system"}
neetokb themes fonts update 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257 c2b8e4a7-1f03-4d59-96a2-e7d5b0c13f84 --weights 400,500,700
```
**Required arguments:**
* `` - Theme ID from `themes list`
* `` - Font ID from `themes config show`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--name` | `string` | | | Google font name |
| `--weights` | `string` | | | Font weights (comma-separated) |
## Delete a font
This command removes a font from a custom theme. A title or body font setting that points to it is not cleared.
```bash theme={"system"}
neetokb themes fonts delete 9a3f5c18-2e7b-4d06-b1c4-d8e0a6f39257 c2b8e4a7-1f03-4d59-96a2-e7d5b0c13f84
```
**Required arguments:**
* `` - Theme ID from `themes list`
* `` - Font ID from `themes config show`
# Trash
Source: https://apidocs.neetokb.com/cli-reference/trash
List, restore, and permanently delete trashed articles.
Trashed articles stay in the trash for 30 days before they are deleted for good. To move articles to the trash, use [`neetokb articles trash`](/cli-reference/articles#trash-an-article) or [`neetokb articles bulk-trash`](/cli-reference/articles#trash-articles-in-bulk). All trash commands need the Manage articles permission. For fields and response details, see the [API reference](/api/trash/list).
## List trashed articles
This command lists the articles in the trash with who trashed them and the days left before each is deleted for good.
```bash theme={"system"}
neetokb trash list
neetokb trash list --page-size 100
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
## Restore a trashed article
This command moves an article out of the trash.
```bash theme={"system"}
neetokb trash restore getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
## Delete a trashed article
This command deletes a trashed article for good. It cannot be undone.
```bash theme={"system"}
neetokb trash delete getting-started
```
**Required arguments:**
* `` - Article slug, permalink identifier (`a-XXXXXXXX`), or UUID
# Utility commands
Source: https://apidocs.neetokb.com/cli-reference/utility
Authentication, diagnostics, versioning, upgrades, AI-assistant setup, and shell completion.
These commands manage the CLI itself rather than a NeetoKB resource.
## Authentication
### login
```bash theme={"system"}
neetokb login --subdomain your-workspace
```
Opens your browser to sign in and saves credentials for the workspace. Omit `--subdomain` to be prompted.
```text Sample output theme={"system"}
Authenticated as oliver@example.com on acme.neetokb.com.
```
### logout
```bash theme={"system"}
neetokb logout --subdomain your-workspace
neetokb logout --all
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--all` | `bool` | | `false` | Sign out of every saved subdomain |
```text Sample output theme={"system"}
Signed out of acme.neetokb.com.
```
### whoami
```bash theme={"system"}
neetokb whoami
```
Lists each signed-in account and marks it `(default)` when only one is signed in. Pass `--subdomain ` to show one workspace.
```text Sample output theme={"system"}
Authenticated as oliver@example.com on acme.neetokb.com (default).
```
## Diagnostics
### doctor
```bash theme={"system"}
neetokb doctor
```
Checks authentication, API reachability, and the CLI version. See [Troubleshooting](/cli/troubleshooting). When several workspaces are signed in, pass `--subdomain `.
```text Sample output theme={"system"}
✓ Authentication: authenticated as oliver@example.com on acme.neetokb.com
✓ API connection: https://acme.neetokb.com (responding in 214ms)
✓ CLI version: 1.4.0
```
### version
```bash theme={"system"}
neetokb version
```
Prints the CLI version, commit hash, and build date.
```text Sample output theme={"system"}
neetokb 1.4.0 (commit: a1b2c3d, built: 2026-07-01)
```
### commands
```bash theme={"system"}
neetokb commands
```
Prints the complete command and flag catalog for the installed version as JSON. It is useful in scripts and with AI assistants.
```json Sample output theme={"system"}
[
{
"command": "neetokb articles",
"description": "Manage articles",
"subcommands": [
{
"command": "neetokb articles list",
"description": "List articles",
"flags": [
{ "name": "state", "type": "string", "description": "Filter by state: draft, published or all (default: published)" }
]
}
]
}
]
```
## Upgrade
### update
```bash theme={"system"}
neetokb update
```
Updates the CLI to the latest release using the method that installed it. When the binary lives in a Homebrew Cellar it runs `brew update && brew upgrade neetozone/tap/neetokb`; on other macOS and Linux installs it downloads the shell installer to a temporary file and runs it; on Windows it runs the PowerShell installer. The installers are the same ones the [Installation](/cli/installation) page uses, fetched over HTTPS. The command prints the detected method and the command it runs, and exits non-zero if that command fails.
```text Sample output theme={"system"}
Detected Homebrew install.
Running: brew update && brew upgrade neetozone/tap/neetokb
```
After upgrading, re-run `neetokb completion ` and any `neetokb setup` command you use so their files match the new version.
## AI-assistant setup
Add NeetoKB instructions to your AI coding assistant. See [AI assistants](/cli/ai-assistants) for details.
```bash theme={"system"}
neetokb setup claude
neetokb setup cursor
neetokb setup windsurf
neetokb setup copilot
neetokb setup gemini
neetokb setup codex
```
```text Sample output theme={"system"}
NeetoKB plugin extracted to /Users/oliver/.config/neetokb/claude-plugin
To finish installation, open Claude Code and run these slash commands:
/plugin marketplace add /Users/oliver/.config/neetokb/claude-plugin
/plugin install neetokb@neetokb
(Claude Code installs plugins via interactive slash commands - there is no shell equivalent today.)
```
## Shell completion
Shell completion fills in command names, subcommands, and flags when you press `Tab`. It saves you from having to remember the full command tree or look up `--help`.
`neetokb completion ` installs completion for your shell. For zsh, bash, and PowerShell it writes the script under `~/.config/neetokb/completions` and adds a marked block to `~/.zshrc`, `~/.bashrc`, or `~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1` that loads it the next time the shell starts. For fish it writes `~/.config/fish/completions/neetokb.fish`, which fish loads on its own.
```bash Zsh theme={"system"}
neetokb completion zsh
```
```bash Bash theme={"system"}
neetokb completion bash
```
```bash Fish theme={"system"}
neetokb completion fish
```
```powershell PowerShell theme={"system"}
neetokb completion powershell
```
Start a new shell (or run `source ~/.zshrc`) to enable it. After upgrading the CLI, run the command again to update the available completions. Re-running it replaces the existing script and configuration without adding duplicates.
> [!NOTE]
>
> To configure it yourself, pass `--print` to write the raw script to standard output instead of installing it:
>
> ```bash theme={"system"}
> neetokb completion zsh --print
> ```
# Webhooks
Source: https://apidocs.neetokb.com/cli-reference/webhooks
List, create, update, and delete webhooks.
A webhook sends article events to an endpoint you own. Every webhook command, reads included, needs the Manage webhooks permission. For fields and response details, see the [API reference](/api/webhooks/list).
## List webhooks
This command lists webhooks. The secret is never shown.
```bash theme={"system"}
neetokb webhooks list
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--page` | `int` | | `0` | Page number |
| `--page-size` | `int` | | `0` | Items per page (max 100) |
## Show a webhook
This command shows one webhook.
```bash theme={"system"}
neetokb webhooks show 4b7a2d90-8e15-4c36-a9f1-3d6c0e8b5274
```
**Required arguments:**
* `` - Webhook ID from `webhooks list`
## List webhook events
This command lists the events a webhook can subscribe to.
```bash theme={"system"}
neetokb webhooks events
```
## Create a webhook
This command creates a webhook.
```bash theme={"system"}
neetokb webhooks create \
--endpoint https://example.com/hook \
--secret s3cret \
--event create --event publish
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--active` | `bool` | | `false` | Send events (--active=false pauses the webhook) |
| `--endpoint` | `string` | Yes | | URL that receives the events |
| `--event` | `stringArray` | | `[]` | Event to send: create, update, delete, publish or unpublish; repeat for several |
| `--secret` | `string` | | | Signing secret; it can be set but never read back |
`--event` takes `create`, `update`, `delete`, `publish` or `unpublish`. Repeat it for several events. The endpoint is unique in the workspace. The secret can be set but never read back.
## Update a webhook
This command changes a webhook. Only the flags you pass change.
```bash theme={"system"}
neetokb webhooks update 4b7a2d90-8e15-4c36-a9f1-3d6c0e8b5274 --active=false
```
**Required arguments:**
* `` - Webhook ID from `webhooks list`
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--active` | `bool` | | `false` | Send events (--active=false pauses the webhook) |
| `--endpoint` | `string` | | | URL that receives the events |
| `--event` | `stringArray` | | `[]` | Event to send: create, update, delete, publish or unpublish; repeat for several |
| `--secret` | `string` | | | Signing secret; it can be set but never read back |
`--event` replaces the whole list of events. A webhook on a deprecated or expired payload version cannot be updated or activated. Delete it and create a new one.
## Delete a webhook
This command deletes a webhook.
```bash theme={"system"}
neetokb webhooks delete 4b7a2d90-8e15-4c36-a9f1-3d6c0e8b5274
```
**Required arguments:**
* `` - Webhook ID from `webhooks list`
# Workspace
Source: https://apidocs.neetokb.com/cli-reference/workspace
View and update the settings of the knowledge base you are signed in to.
A workspace is the NeetoKB organization behind your subdomain. For fields and response details, see the [API reference](/api/settings/get) and [Update organization settings](/api/settings/update).
## Show workspace information
This command shows your knowledge base's name and public URL. Use this to confirm which workspace a command will act on before running it, especially when several are signed in.
```bash theme={"system"}
neetokb workspace info
neetokb workspace info --subdomain acme
```
```json Sample output (--json) theme={"system"}
{
"data": {
"knowledge_base_name": "Spinkart Help Center",
"url": "https://spinkart.neetokb.com"
}
}
```
> [!TIP]
>
> To check authentication and connectivity rather than workspace settings, run [`neetokb doctor`](/cli-reference/utility#doctor).
## Update workspace settings
This command changes the knowledge base name, texts, sign-up, contact section and social sharing. Only the flags you pass change. It needs the Manage basic info permission. `--social-sharing` and `--facebook-app-id` need the Manage social sharing permission instead.
```bash theme={"system"}
neetokb workspace update --name "Acme Help" --header-text "How can we help?"
neetokb workspace update --allow-signup=false --contact-title "Need more help?" --contact-button-label "Contact us"
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--allow-signup` | `bool` | | `false` | Let visitors sign up (--allow-signup=false turns it off) |
| `--contact-button-label` | `string` | | | Contact section button label |
| `--contact-kind` | `string` | | | Contact section button kind, such as action |
| `--contact-link` | `string` | | | Contact section button link |
| `--contact-title` | `string` | | | Contact section title |
| `--copyright` | `string` | | | Copyright text in the footer |
| `--facebook-app-id` | `string` | | | Facebook app ID (letters and digits) |
| `--header-text` | `string` | | | Home page heading |
| `--name` | `string` | | | Knowledge base name (up to 80 characters) |
| `--search-input-text` | `string` | | | Search box placeholder text |
| `--show-article-nav-links` | `bool` | | `false` | Show previous and next links on articles |
| `--site-content-preference` | `string` | | | What the home page shows, such as Categories |
| `--social-sharing` | `bool` | | `false` | Enable social media sharing |
`--name` is up to 80 characters. `--facebook-app-id` takes letters and digits only. The contact section flags are merged into the current contact section. The command prints the updated settings.
## Knowledge base SEO settings
These commands show and change the SEO settings of the whole knowledge base. Both need the Manage SEO settings permission. For one article, see [`neetokb articles seo`](/cli-reference/articles#article-seo-settings).
```bash theme={"system"}
neetokb workspace seo show
```
### Update knowledge base SEO settings
Only the flags you pass change.
```bash theme={"system"}
neetokb workspace seo update --title "Acme Help" --keywords help,support --allow-crawl
```
| Flag | Type | Required | Default | Description |
| - | - | - | - | - |
| `--allow-crawl` | `bool` | | `false` | Let search engines crawl the knowledge base (--allow-crawl=false blocks them) |
| `--description` | `string` | | | Meta description |
| `--google-analytics-id` | `string` | | | Google Analytics tracking ID |
| `--keywords` | `string` | | | Keywords (comma-separated); replaces the current list |
| `--title` | `string` | | | Page title |
| `--title-suffix` | `string` | | | Text added after every page title |
`--keywords` replaces the whole list. `--allow-crawl=false` blocks search engines.
# AI assistants
Source: https://apidocs.neetokb.com/cli/ai-assistants
Set up NeetoKB for Claude, Cursor, Copilot, and other AI coding assistants.
Use the CLI with an AI coding assistant to manage NeetoKB in plain language. The `neetokb setup` commands add NeetoKB instructions for your assistant, while [`--toon`](/cli/output-formats) keeps command output compact for it to read.
## Set up your assistant
Run the subcommand for the tool you use:
| Command | What it does |
| - | - |
| `neetokb setup claude` | Extracts the NeetoKB plugin (manifest, marketplace, session-start hook, and skill) to `~/.config/neetokb/claude-plugin`, replacing any earlier copy. Requires `~/.claude/` to exist. |
| `neetokb setup cursor` | Writes `.cursor/rules/neetokb.mdc`. Overwrites the file. |
| `neetokb setup windsurf` | Writes `.windsurf/rules/neetokb.md`. Overwrites the file. |
| `neetokb setup copilot` | Adds a NeetoKB section to `.github/copilot-instructions.md`. Keeps the rest of the file. |
| `neetokb setup gemini` | Adds a NeetoKB section to `GEMINI.md`. Keeps the rest of the file. |
| `neetokb setup codex` | Adds a NeetoKB section to `AGENTS.md`. Keeps the rest of the file. |
Every subcommand except `setup claude` writes into the current directory, so run it from the root of the project the assistant works in. The `copilot`, `gemini`, and `codex` commands place their section between `` and `` markers and replace that section on re-run instead of adding a duplicate. Re-run the command after every CLI upgrade so the instructions match the installed version.
```bash theme={"system"}
neetokb setup claude
```
`setup claude` prints two slash commands to finish the installation inside Claude Code:
```text theme={"system"}
/plugin marketplace add ~/.config/neetokb/claude-plugin
/plugin install neetokb@neetokb
```
After setup, your assistant can check the commands and flags available in your installed CLI version:
```bash theme={"system"}
neetokb commands
```
The command prints the complete catalog as JSON.
## Tips for agent workflows
> [!TIP]
>
> Prefer `--toon` when the assistant needs to read a list or record, and
> `--quiet` when it needs to pipe an identifier into the next command. See
> [Output formats](/cli/output-formats).
* Authenticate once with [`neetokb login`](/cli/authentication); the assistant reuses the stored credentials.
* When several workspaces are signed in, the assistant must pass `--subdomain ` on each command.
* Run [`neetokb doctor`](/cli/troubleshooting) first to confirm the assistant is authenticated and connected.
# Authentication
Source: https://apidocs.neetokb.com/cli/authentication
Sign in through the browser and manage credentials for one or more workspaces.
The CLI uses your browser to sign you in and securely saves your session, so you never need to enter an API key.
## Sign in
```bash theme={"system"}
neetokb login --subdomain your-workspace
```
Your browser opens to complete sign-in. The CLI also prints the sign-in URL in case the browser does not open, and waits up to five minutes for you to approve. Once you approve it, the CLI saves credentials for that subdomain. If you omit `--subdomain`, the CLI prompts for it.
> [!TIP]
>
> Your subdomain is the first part of your workspace URL - for
> `https://spinkart.neetokb.com`, the subdomain is `spinkart`. See
> [Workspace subdomain](/cli/workspace-subdomain).
## Where credentials are stored
Credentials for every signed-in workspace live in a single file:
```text theme={"system"}
~/.config/neetokb/auth.json
```
Removing this file signs you out of every workspace, the same as `neetokb logout --all`.
## Check who you are
```bash theme={"system"}
neetokb whoami
```
Lists every signed-in account. When exactly one is signed in, it is marked `(default)`. Pass `--subdomain ` to show just one.
## Sign out
```bash theme={"system"}
neetokb logout --subdomain your-workspace # remove one workspace
neetokb logout --all # remove every workspace
neetokb logout # remove the only one, if a single workspace is signed in
```
## Working with multiple workspaces
You can sign in to several subdomains at once. To add another workspace, name its subdomain:
```bash theme={"system"}
neetokb login --subdomain globex
```
When more than one workspace is signed in, every command that talks to the API requires `--subdomain`. If you omit it, the CLI errors and lists the signed-in workspaces.
```bash theme={"system"}
neetokb articles list --subdomain acme
neetokb articles list --subdomain globex
```
With one signed-in workspace, it is the default and `--subdomain` stays optional.
## Environment variables
`NEETOKB_BASE_URL` overrides the server the CLI talks to. By default every command, including `login`, uses `https://.neetokb.com`. Set the variable to point the CLI at a staging or local server. Every request, including the session token saved in `~/.config/neetokb/auth.json`, goes to that server, so only point it at a server you trust:
```bash theme={"system"}
export NEETOKB_BASE_URL=https://acme.neetokb.net
neetokb login --subdomain acme
```
## Troubleshooting
If sign-in or connection problems come up, run `neetokb doctor` first. See [Troubleshooting](/cli/troubleshooting) for common issues and fixes.
# Installation
Source: https://apidocs.neetokb.com/cli/installation
Install the neetokb CLI on macOS, Linux, or Windows.
Install the `neetokb` binary with the command for your platform, then [verify it](#verify-the-installation).
```bash macOS theme={"system"}
brew trust neetozone/tap
brew install neetozone/tap/neetokb
```
```bash Linux theme={"system"}
curl -fsSL https://neetokb.com/cli/install.sh | sh
```
```powershell Windows theme={"system"}
irm https://neetokb.com/cli/install.ps1 | iex
```
The shell and Windows installers download the latest release for your architecture (`amd64` or `arm64`), extract it, and add `neetokb` to your `PATH`.
## Other install methods
> **macOS - shell script**
>
> ```bash theme={"system"}
> curl -fsSL https://neetokb.com/cli/install.sh | sh
> ```
>
> Installs to `/usr/local/bin` and may prompt for `sudo`. To update a Homebrew installation, run `brew upgrade neetokb`.
> **Windows - Command Prompt (CMD)**
>
> ```cmd theme={"system"}
> curl -fsSL https://neetokb.com/cli/install.cmd -o install.cmd && install.cmd
> ```
>
> Extracts to `%LOCALAPPDATA%\Programs\neetokb` and adds it to your user `PATH`. This is equivalent to the PowerShell method.
## Verify the installation
Restart your terminal, then run:
```bash theme={"system"}
neetokb --help
```
You should see the list of available commands. To check the installed version:
```bash theme={"system"}
neetokb version
```
## Upgrade
```bash theme={"system"}
neetokb update
```
The command detects how the CLI was installed and runs the matching upgrade: `brew update && brew upgrade neetozone/tap/neetokb` for a Homebrew install, the shell installer for other macOS and Linux installs, and the PowerShell installer on Windows. It prints the command it runs and exits non-zero if that command fails. You can also run the install command for your platform again. See [`neetokb update`](/cli-reference/utility#update).
After an upgrade, re-run `neetokb completion ` and any `neetokb setup` command you use so their files match the new version.
> [!TIP]
>
> Next, [sign in](/cli/authentication) to a workspace and run `neetokb doctor`
> to confirm the CLI can reach NeetoKB.
# NeetoKB CLI
Source: https://apidocs.neetokb.com/cli/introduction
Manage articles, categories, authors, and team members from your terminal.
The **NeetoKB CLI** (`neetokb`) lets you manage NeetoKB from your terminal. It covers the [v2 REST API](/api/introduction): list and search articles, create and publish content, browse the category tree, share unlisted links, and manage team members.
It is designed for people comfortable with a terminal or HTTP. You do not need to be a developer: run `neetokb setup` to connect an AI assistant such as Claude or Cursor, then describe the task in plain language.
## Why use the CLI?
> **Script your publishing**
>
> Create articles, update their state, and share unlisted links from shell scripts and cron jobs.
> **Audit from the terminal**
>
> Search articles or list drafts, pipe them to `jq`, and create one-off reports without leaving your shell.
> **Change things in bulk**
>
> Page through thousands of articles in one loop, update them unattended, and switch workspaces with a single flag.
> **Built for AI agents**
>
> Use token-efficient `--toon` output and one-command setup for Claude, Cursor, Copilot, and more.
## CLI vs MCP: which should I use?
NeetoKB's [MCP server](/mcp/introduction) reaches the same resources the CLI does - articles, unlisted links, categories, authors, recommendations, team members, and workspace settings. The one exception: MCP can also read a published article from a knowledge base you are not signed in to. Otherwise neither one can do more than the other, so choose on how the work reaches NeetoKB.
### Reach for the CLI when
* **No AI assistant should be in the loop.** A cron entry or a CI step runs `neetokb` with nothing but the binary and the workspace you already signed in to - no assistant open, no model account, no tokens spent per run. Over MCP, something with model access has to be running before any call happens at all.
* **The output feeds another program.** `--quiet` prints the bare article id for the next command; `--json` returns records plus pagination for `jq`, a spreadsheet, or your own script. An assistant replies in prose you would have to copy out by hand.
* **You are working through thousands of records.** Over MCP every page is a separate tool call, and a list that long crowds out the assistant's context. The CLI pages on your terms instead: `--page-size 100` with `--json` returns `total_pages` and `total_records` alongside the records, so a loop knows how many pages are left and walks all of them unattended. Each page lands in a file or goes straight into `jq`, so nothing has to be held in memory and the size of the list stops mattering.
* **You need the same run every time.** A `neetokb` command is plain text you can save. Drop it into a runbook or a pull request and anyone can read exactly what it will do before it runs, then run it later and get the identical call. An assistant works from a prompt rather than a fixed command, so the same request can come out as a different set of calls on a different day.
### Reach for MCP instead when
* **The details live in your chat, not in your head.** A support thread, a customer email, or a pasted release note turns into the article body with no retyping. The CLI cannot see any of it.
* **You have not decided the steps yet.** "Our refund window moved to 30 days - fix whatever still says 14" means looking at what is there and choosing. A command can only carry out a decision you have already made.
* **One request should cover several steps.** Find the article, rewrite the stale paragraph, publish it, and share an unlisted link, with no glue between commands.
* **The person doing it does not use a terminal.** NeetoKB hosts the server, so there is nothing to install or keep updated.
> [!TIP]
>
> You can have both. Run [`neetokb setup claude`](/cli/ai-assistants) and your
> AI assistant drives the CLI itself, so a plain-language request still ends in
> an exact command you can read, repeat, and paste into a script.
## What you need
1. Access to one or more NeetoKB workspaces.
2. Permission to manage the resources you want to work with (articles, unlisted links, team members, and so on).
3. The `neetokb` binary. See [Installation](/cli/installation).
> [!NOTE]
>
> Unlike the API, which authenticates with an `X-Api-Key` header, the CLI signs
> you in through your browser and stores credentials locally. See
> [Authentication](/cli/authentication).
# Output formats
Source: https://apidocs.neetokb.com/cli/output-formats
Pretty tables, JSON, quiet, and TOON - and when to use each.
Every command can return one of four output formats. In an interactive terminal, pretty output is the default. Use the flags below for machine-readable output.
| Format | Flag | Best for |
| - | - | - |
| Pretty | *(default in a terminal)* | Reading a result yourself. |
| JSON | `--json` | Machine-readable payloads with pagination metadata. |
| Quiet | `--quiet` | Piping an identifier into another command or `jq`. |
| TOON | `--toon` | Feeding list/show output back to an LLM (fewer tokens than JSON). |
If more than one is set, precedence is `--toon` > `--quiet` > `--json` > pretty. `--verbose` changes pretty output only, so it has no effect alongside the other three.
## Global flags
These flags work on every command:
| Flag | Description |
| - | - |
| `--json` | Output as JSON |
| `--quiet` | Output raw data only (no envelope) |
| `--toon` | Output in TOON format (token-optimized for AI agents) |
| `--verbose` | Expand every field of a record instead of a table |
| `--subdomain` | Override saved subdomain |
`--subdomain` selects the signed-in workspace a command targets. See [Authentication](/cli/authentication).
## Pretty
The default in a terminal: tables for lists and key-value pairs for a single record. It is intended for people, not scripts.
A table shows at most seven columns. The CLI picks identifier and name fields first (`id`, `name`, `title`, `email`, `slug`, `state`, and similar), fills the remaining columns alphabetically, and keeps any URL fields as the last columns without truncating them.
```bash theme={"system"}
neetokb articles list --state published
```
## Verbose
`--verbose` prints every field of every record instead of a table, one label per line, with nested objects and lists indented underneath. Use it when a table leaves out a field you need.
```bash theme={"system"}
neetokb articles list --state published --verbose
```
## JSON
JSON wraps the resource body with breadcrumbs and, for list commands, pagination details:
```json theme={"system"}
{
"data": [
{ "id": "a1b2c3d4-1111-2222-3333-444455556666", "slug": "getting-started", "title": "Getting Started Guide", "state": "published" }
],
"breadcrumbs": [{ "label": "Show", "command": "neetokb articles show " }],
"pagination": {
"total_records": 250,
"total_pages": 9,
"current_page_number": 1,
"page_size": 30
}
}
```
For list commands, `data` is the array of records; the CLI removes the API response's resource key. For `show`, `create`, and `update`, `data` holds the API response body, such as `{ "article": { ... } }`.
`breadcrumbs` is omitted when empty, and `pagination` appears only on list commands. The CLI automatically uses JSON when output is piped (a non-TTY); use `--json` to force it.
## Quiet
`--quiet` returns only the `data` payload. For `create` and `update`, it prints the resource identifier; for `delete`, it prints `success`. This is useful in scripts:
```bash theme={"system"}
neetokb articles create \
--title "Getting Started" --category "Getting Started" \
--html-content "
Welcome
" --state draft \
--quiet
# → prints the new article id
```
## TOON
`--toon` encodes the same data as [TOON](https://github.com/alpkeskin/gotoon) (Token-Optimized Output Notation). It keeps the JSON shape while compressing whitespace and keys, typically using 30-60% fewer tokens. Use it when giving list or show output to an AI assistant.
```bash theme={"system"}
neetokb search --search-term "billing" --toon
```
## Pagination
List commands return results in pages. The flags below control paging, and the JSON envelope's `pagination` block shows your position in the result set.
### Pagination parameters
**--page** `integer`
The page of results to retrieve, starting from 1.
**--page-size** `integer`
The number of records to return per page (max 100).
### Example usage
```bash theme={"system"}
neetokb articles list --page 2 --page-size 50
```
This returns the second page of articles, with 50 records per page.
### Response structure
For list commands the JSON envelope carries a `pagination` block alongside the data:
```json theme={"system"}
{
"pagination": {
"total_records": 250,
"total_pages": 5,
"current_page_number": 2,
"page_size": 50
}
}
```
**pagination.total\_records** `integer`
The total number of records across all pages.
**pagination.total\_pages** `integer`
The total number of pages available.
**pagination.current\_page\_number** `integer`
The page you are currently on.
**pagination.page\_size** `integer`
The number of records returned per page.
### Default behavior
If you omit both flags, the CLI lets the server use its defaults. Either flag overrides the defaults; `--page-size` accepts up to 100.
### Best practices
* To retrieve every page, increment `--page` until `current_page_number == total_pages`.
* Use `--json` or `--toon` in scripts when you need the `pagination` block. `--quiet` removes the envelope, so it does not include pagination metadata.
* Check `total_records` before you begin to estimate the work involved.
# Troubleshooting
Source: https://apidocs.neetokb.com/cli/troubleshooting
Diagnose authentication and connectivity issues with neetokb doctor.
## Run the doctor
When something goes wrong, start with `neetokb doctor`. It checks your authentication, API connection, and CLI version.
```bash theme={"system"}
neetokb doctor
```
When multiple workspaces are signed in, name the one to check:
```bash theme={"system"}
neetokb doctor --subdomain your-workspace
```
## Common errors
When a command fails, it prints an error message to standard error and exits with status 1. Usage errors such as an unknown flag or a missing argument add `Run 'neetokb --help' for usage.`
> **Not authenticated. Run 'neetokb login' to authenticate.**
>
> **Problem**: no workspace is signed in. \\
>
> **Solution**: run [`neetokb login --subdomain `](/cli/authentication).
> **Multiple subdomains authenticated (acme, beta); specify --subdomain.**
>
> **Problem**: more than one workspace is signed in, so the target is ambiguous. \\
>
> **Solution**: add `--subdomain ` to the command. For `logout`, `--all` signs out of every workspace.
> **Not authenticated for "foo". Authenticated subdomains: acme, beta.**
>
> **Problem**: the `--subdomain` value does not match any signed-in workspace. \\
>
> **Solution**: use one of the listed subdomains, or [sign in](/cli/authentication) to the new one.
> **Subdomain not found. Please check that you entered the correct subdomain.**
>
> **Problem**: `neetokb login` could not find a workspace at `.neetokb.com`. \\
>
> **Solution**: use the first part of your workspace URL. For `https://spinkart.neetokb.com`, enter `spinkart`.
> **Authentication session expired. Please try again.**
>
> **Problem**: the browser sign-in was not approved before the session expired. `NeetoKB CLI authentication timed out after 5 minutes. Please try again.` means the CLI stopped waiting. \\
>
> **Solution**: run `neetokb login` again and approve the sign-in in the browser. If the browser does not open, visit the URL the CLI prints.
> **Could not connect to NeetoKB. Check your internet connection**
>
> **Problem**: the CLI could not reach the API. \\
>
> **Solution**: check your network and run `neetokb doctor`. If [`NEETOKB_BASE_URL`](/cli/authentication#environment-variables) is set, confirm it points at a reachable server.
> **required flag(s) "xxx" not set**
>
> **Problem**: a required flag was omitted. \\
>
> **Solution**: check the command's [reference page](/cli-reference/overview) or run `neetokb --help` for the required flags.
> **API error (422): \**
>
> **Problem**: the server rejected the request. The CLI prints `API error (): `, one line per additional error, and a `Suggestion:` line for common statuses: 401 (sign in again), 403 (no permission), 404 (check the ID), 422 (check required fields with `--help`), and 429 (rate limited, wait and retry). \\
>
> **Solution**: follow the suggestion. For 401, run `neetokb login` to refresh the session.
> **Article must be published before an unlisted link can be generated.**
>
> **Problem**: the article is still a draft, so it has no public URL to share. \\
>
> **Solution**: publish it with `neetokb articles update --state published`, then run the [unlisted link command](/cli-reference/articles#unlisted-links) again.
> **Claude Code not found (\~/.claude/ does not exist).**
>
> **Problem**: `neetokb setup claude` requires Claude Code to have been run at least once. \\
>
> **Solution**: install and open Claude Code, then run the command again.
## Check the version
```bash theme={"system"}
neetokb version
```
Prints the CLI version, commit hash, and build date - useful when reporting an issue. To upgrade, run [`neetokb update`](/cli-reference/utility#update).
# Workspace subdomain
Source: https://apidocs.neetokb.com/cli/workspace-subdomain
Find your workspace subdomain and tell the CLI which workspace to use.
Every NeetoKB workspace has its own subdomain. It is the part of your workspace URL before `neetokb.com`. For `https://spinkart.neetokb.com`, the subdomain is `spinkart`.
The CLI uses the subdomain to know which workspace to sign in to and which workspace a command works on.
## Find your subdomain
**1. Open your workspace**
Sign in to NeetoKB in your browser and look at the address bar.
**2. Take the part before neetokb.com**
For `https://green-earth.neetokb.com`, the subdomain is `green-earth`.
## Sign in with it
Pass the subdomain to `login`:
```bash theme={"system"}
neetokb login --subdomain green-earth
```
If you omit `--subdomain`, the CLI asks for it.
## Pick a workspace for a command
With one signed-in workspace, the CLI uses it and `--subdomain` stays optional. When you sign in to more than one, add `--subdomain` to every command that talks to the API:
```bash theme={"system"}
neetokb articles list --subdomain green-earth
```
See [Authentication](/cli/authentication) for signing in to several workspaces.
# Authentication
Source: https://apidocs.neetokb.com/mcp/authentication
Connect as yourself with OAuth, or as the whole workspace with an API key.
The MCP server accepts two kinds of credentials. The one you pick decides **what the assistant can see**.
| | OAuth | API key |
| - | - | - |
| Scope | The person who approved it | The whole workspace |
| Identity | Tied to a NeetoKB user | Tied to nobody |
| Set up by | Signing in to NeetoKB from the assistant | Pasting a key into a config file |
| Used by | Every client except Antigravity | Every client except Claude and ChatGPT |
| Reaches several workspaces | Yes, tick the extra ones while approving | No, one key is one workspace |
| Revoked by | Removing the connector | Revoking the key in workspace settings |
In Claude Code, Codex, Cursor, Gemini CLI, VS Code, and Windsurf, leave the key out of the config to sign in with OAuth. Put the key in to use the API key. Both expose the same [tools](/mcp/tools).
## OAuth, scoped to you
The assistant acts as the person who approved the connection. Lists and searches show only what that person can see. An article they cannot open is refused. Articles in categories they cannot see stay hidden.
Use OAuth when a person drives the assistant. For the steps, see [Connect agent](/mcp/connect#sign-in-with-your-neetokb-account).
| Detail | Value |
| - | - |
| Metadata | `https://connect.neetokb.com/.well-known/oauth-authorization-server` |
| Grant types | `authorization_code` and `refresh_token`, with PKCE (`S256`) required |
| Scopes | `read`, `write`, `delete`, `offline_access` |
| Client registration | Dynamic, per [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591), at `https://connect.neetokb.com/mcp/oauth/register`. Loopback redirect URIs are accepted. |
| Refresh | Refresh tokens are issued, so you stay signed in |
| Revoke | Remove the connector from your assistant |
### What you approve
| Scope | Shown as | What it means | Always granted |
| - | - | - | - |
| `read` | **Read** | See everything in the connected workspaces. | Yes |
| `offline_access` | **Stay connected** | Keep working without asking you to sign in again. | Yes |
| `write` | **Create and update** | Add new items and change existing ones. | No |
| `delete` | **Delete** | Permanently delete items. This cannot be undone. | No |

The approval screen, with the scope picker and the additional workspaces list.
If you leave a scope unticked, a tool that needs it is refused with a message that names the scope. For example, a read-only connection can search and read articles but cannot create, publish, or delete anything.
One OAuth connection can reach several workspaces. Name the workspace in your prompt, or ask the assistant to list the workspaces it can reach. Every tool takes an optional `workspace` argument for this.
## API key, scoped to the workspace
An API key is not tied to a person. Every tool call reaches the whole workspace, and role checks do not run. Use a key for automation that must see every article, including drafts and private categories. Do not use one on a machine where the person should see only their own articles.
The key is the same one the [REST API](/api/authentication) uses. Put it in the server entry of the assistant's config file:
```json theme={"system"}
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
```
For the full config of each client, see [Connect agent](/mcp/connect#use-an-api-key). [Learn how to generate your API key.](https://help.neetokb.com/articles/api-keys)
> [!TIP]
>
> A key belongs to one workspace. To reach two workspaces, add the server twice, with a different key and a different server name in each entry.
> [!WARNING]
>
> An API key gives access to every article in the workspace. Treat it like a password: keep it out of shared config files and commits, and revoke it if it leaks.
## How the three interfaces authenticate
| Interface | Credential | Scope | Where it goes |
| - | - | - | - |
| [REST API](/api/authentication) | API key | Workspace | `X-Api-Key` header on each request. |
| [CLI](/cli/authentication) | Browser sign-in, stored per workspace | The signed-in user | `~/.config/neetokb/auth.json`. No API key involved. |
| MCP | OAuth, or an API key | The approving user, or the workspace | Browser approval, or an `Authorization: Bearer` header in the assistant's config file. |
# Connect agent
Source: https://apidocs.neetokb.com/mcp/connect
Step-by-step setup for Claude, ChatGPT, and other AI agents.
## Sign in with your NeetoKB account
**Claude**
1. Visit the [NeetoKB listing](https://claude.ai/directory/neetokb) in Anthropic's connector directory.

The NeetoKB listing in Anthropic's connector directory.
2. Click **Connect to Claude**.
3. Sign in to NeetoKB. See [What the sign-in looks like](#what-the-sign-in-looks-like).
NeetoKB then works in claude.ai, the Claude desktop app, Claude mobile, and Cowork.
If you see **Request** instead of **Connect to Claude**, your Team plan admin must turn NeetoKB on under **[Organization settings > Connectors](https://claude.ai/admin-settings/connectors)**. After that, click **Connect to Claude**.
To disconnect, open **[Customize > Connectors](https://claude.ai/customize/connectors)** and remove NeetoKB.
> **Add it as a custom connector instead**
>
> Use this only if your organization blocks the connector directory.
>
> 1. Open **[Customize > Connectors](https://claude.ai/customize/connectors)**, click **Add**, then click **Add custom connector**.
>
> 
>
> Add custom connector is the only item under the Add button.
>
> 2. Enter the name NeetoKB and paste the server URL.
>
> ```
> https://connect.neetokb.com/mcp/messages
> ```
>
> 
>
> The Add custom connector dialog, ready to submit.
>
> 3. Click **Continue** and sign in to NeetoKB.
**ChatGPT web app**
1. Go to [chatgpt.com](https://chatgpt.com) and open **Settings → Security and login**.
2. Scroll to the bottom of the page and turn on **Developer mode**. It is below **Lockdown mode**.

ChatGPT does not allow **Lockdown mode** and **Developer mode** at the same time. If **Lockdown mode** is on, turn it off first. If you still do not see **Developer mode**, your ChatGPT workspace admin has turned it off. Ask them to allow it.
3. Go to [chatgpt.com/plugins](https://chatgpt.com/plugins) and click the **plus** button.
4. In **New Plugin**, enter the name NeetoKB, set **Connection** to **Server URL**, and paste:
```
https://connect.neetokb.com/mcp/messages
```
5. Leave **Authentication** on **OAuth**.
6. Tick **I understand and want to continue**, then click **Create**.
7. Sign in to NeetoKB. See [What the sign-in looks like](#what-the-sign-in-looks-like).
**ChatGPT desktop app**
The desktop app does not need **Developer mode**.
1. Click your profile picture at the bottom left, then click **Settings**.

2. Click **Plugins**. Click **Add**, then click **Add MCP server**.

3. Enter the name NeetoKB and set **Type** to **Streamable HTTP**.
4. In **URL**, paste:
```
https://connect.neetokb.com/mcp/messages
```
5. Leave the other fields empty and click **Save**.

6. Click the **MCPs** tab. Next to **neetokb**, click **Authenticate**.

7. Sign in to NeetoKB. See [What the sign-in looks like](#what-the-sign-in-looks-like).
**Claude Code**
1. Add the server:
```bash theme={"system"}
claude mcp add --transport http --scope user neetokb https://connect.neetokb.com/mcp/messages
```
2. Start Claude Code and run `/mcp`.
3. Pick **neetokb** and sign in to NeetoKB in the browser.
**Cursor**
1. Add the server to `~/.cursor/mcp.json`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"url": "https://connect.neetokb.com/mcp/messages"
}
}
}
```
2. Restart Cursor.
3. Sign in to NeetoKB when Cursor asks.
**Gemini CLI**
1. Add the server to `~/.gemini/settings.json`. Use `httpUrl`, not `url`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"httpUrl": "https://connect.neetokb.com/mcp/messages"
}
}
}
```
2. Start Gemini CLI and sign in to NeetoKB when it asks.
**Codex**
1. Add the server to `~/.codex/config.toml`:
```toml theme={"system"}
[mcp_servers.neetokb]
url = "https://connect.neetokb.com/mcp/messages"
```
2. Run this command and sign in to NeetoKB in the browser:
```bash theme={"system"}
codex mcp login neetokb
```
**VS Code**
You need VS Code 1.99 or later, with GitHub Copilot in **Agent** mode.
1. Create `.vscode/mcp.json` in your workspace. Use `servers`, not `mcpServers`:
```json theme={"system"}
{
"servers": {
"neetokb": {
"type": "http",
"url": "https://connect.neetokb.com/mcp/messages"
}
}
}
```
2. Sign in to NeetoKB when VS Code asks.
**Windsurf**
1. Add the server to `~/.codeium/windsurf/mcp_config.json`. Use `serverUrl`, not `url`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"serverUrl": "https://connect.neetokb.com/mcp/messages"
}
}
}
```
2. Turn on the server under **Settings → Cascade → MCP Servers**.
3. Sign in to NeetoKB when Windsurf asks.
### What the sign-in looks like
**1. Connect your workspace**
Enter your workspace subdomain, or paste the workspace URL. For `acme.neetokb.com`, enter `acme`. The **Find your workspace subdomain** link on this screen opens the [Workspace subdomain](/mcp/workspace-subdomain) page.

The first screen of the NeetoKB sign-in.
**2. Sign in**
Sign in to that workspace, if you are not signed in already.
**3. Choose what the assistant can do**
**Read** and **Stay connected** are always on. Tick **Create and update** and **Delete** only if the assistant needs them.
One connection can reach more than one workspace at the same time. The workspace you entered is always connected. If your email belongs to other workspaces, tick any you also want under **Additional workspaces to connect**. The permissions you approve apply to all of them.

Choosing the permissions and any additional workspaces.
**4. Authorize**
Click **Authorize**.
To add a workspace or a permission later, sign in again and tick it.
## Use an API key
An API key reaches the whole workspace, not only what you can see. Use it for automation. See [Authentication](/mcp/authentication).
**Claude Code**
1. Add the server to `~/.claude.json`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"type": "http",
"url": "https://connect.neetokb.com/mcp/messages",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
2. Restart Claude Code.
**Cursor**
1. Add the server to `~/.cursor/mcp.json`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"type": "http",
"url": "https://connect.neetokb.com/mcp/messages",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
2. Restart Cursor.
**Gemini CLI**
1. Add the server to `~/.gemini/settings.json`. Use `httpUrl`, not `url`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"httpUrl": "https://connect.neetokb.com/mcp/messages",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
2. Restart Gemini CLI.
**Codex**
1. Add the server to `~/.codex/config.toml`:
```toml theme={"system"}
[mcp_servers.neetokb]
url = "https://connect.neetokb.com/mcp/messages"
bearer_token_env_var = "NEETOKB_API_KEY"
```
2. Set `NEETOKB_API_KEY` to your API key in the shell where you run Codex.
**VS Code**
You need VS Code 1.99 or later, with GitHub Copilot in **Agent** mode.
1. Create `.vscode/mcp.json` in your workspace:
```json theme={"system"}
{
"inputs": [
{
"type": "promptString",
"id": "neetokb-api-key",
"description": "NeetoKB API key",
"password": true
}
],
"servers": {
"neetokb": {
"type": "http",
"url": "https://connect.neetokb.com/mcp/messages",
"headers": {
"Authorization": "Bearer ${input:neetokb-api-key}"
}
}
}
}
```
2. Paste your API key when VS Code asks.
> [!WARNING]
>
> This file lives in your project. Do not paste the key into the file itself, or it can end up in a commit.
**Windsurf**
1. Add the server to `~/.codeium/windsurf/mcp_config.json`. Use `serverUrl`, not `url`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"serverUrl": "https://connect.neetokb.com/mcp/messages",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
2. Turn on the server under **Settings → Cascade → MCP Servers**.
**Antigravity**
1. Open **Settings → Customizations → Open MCP Config**.
2. Add the server to `mcp_config.json`. Use `serverUrl`, not `url`:
```json theme={"system"}
{
"mcpServers": {
"neetokb": {
"serverUrl": "https://connect.neetokb.com/mcp/messages",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
3. Reload Antigravity.
Replace `YOUR_API_KEY` with a key from your workspace. [Learn how to generate your API key.](https://help.neetokb.com/articles/api-keys)
## Confirm the connection
Ask the assistant *"Search my NeetoKB articles for billing."* If it answers with your articles, the connection works. For more prompts, see [Examples](/mcp/examples). If it does not work, see [Troubleshooting](/mcp/troubleshooting).
# Examples
Source: https://apidocs.neetokb.com/mcp/examples
Prompts to try once your assistant is connected to NeetoKB.
Once [connected](/mcp/connect), ask your assistant in plain language. It picks the right [tools](/mcp/tools), so you do not need to know any tool names. Try prompts like these:
## Look things up
> Search my NeetoKB articles for billing.
> Show me the Getting Started Guide article, including its HTML content.
> List every draft article in my knowledge base.
> What categories do I have, and how many articles are in each?
## Write and publish
> Draft a NeetoKB article called Refund policy under the Billing category.
> Update the Getting Started Guide with this new intro paragraph.
> Publish the Refund policy draft.
## Fill the gaps
> Show the searches that found no article in the last 30 days, then draft an article for the most common one.
> Which invalid URLs did visitors open this month? Add a redirection for each one that has an obvious new page.
## Organize
> Merge the Billing and Payments tags into Billing.
> Create a Billing category under Getting Started and put it first.
## Share and manage
> Give me an unlisted link for the Refund policy article that expires in seven days.
> Regenerate the unlisted link for Getting Started Guide - the old one leaked.
> Invite [oliver@example.com](mailto:oliver@example.com) and [sam@example.com](mailto:sam@example.com) as Standard members.
> Which articles does NeetoKB recommend for the /feedback page?
> [!TIP]
>
> Ask the assistant to confirm before it creates, publishes, or regenerates anything. MCP actions affect your live workspace, and regenerating an unlisted link breaks the previous URL immediately.
# NeetoKB MCP
Source: https://apidocs.neetokb.com/mcp/introduction
Manage your NeetoKB knowledge base from an AI assistant in plain language.
The NeetoKB **MCP server** lets your AI assistant work with your knowledge base from plain-language requests. Ask it to find an article, draft a new one, publish a change, share an unlisted link, or invite a teammate, and it works with your NeetoKB workspace for you.
[MCP](https://modelcontextprotocol.io) (Model Context Protocol) is an open standard that connects AI assistants to tools such as NeetoKB. You describe the task; the assistant uses the right tool.
## What you can do
> **Find articles**
>
> Search and browse published articles and drafts, and read their full content.
> **Write and publish**
>
> Create articles in a category, revise them, and move them between draft and published.
> **Share and manage**
>
> Generate unlisted links, browse the category tree, and invite team members.
> **Hand off the busywork**
>
> Ask your assistant to find a stale article, rewrite it, and publish it for you.
## MCP vs CLI: which should I use?
NeetoKB's [CLI](/cli/introduction) reaches the same resources MCP does - articles, unlisted links, categories, authors, recommendations, team members, and workspace settings. The one exception is small: only MCP can read a published article from a knowledge base you are not signed in to. Otherwise, neither one can do more than the other, so choose on how the work reaches NeetoKB.
### Reach for MCP when
* **The details live in your chat, not in your head.** A support thread, a customer email, or a pasted release note becomes the article body with no retyping and no hand-written markup. The CLI wants the finished HTML from you, and it cannot see the conversation it should come from.
* **You have not decided the steps yet.** "Our refund window moved to 30 days - fix whatever still says 14" means searching, reading each hit, and judging which ones are genuinely wrong. A command can only carry out a decision you have already made.
* **One request should cover several steps.** Find the article, read what it says today, rewrite only the paragraph that is stale, publish it, and hand back an unlisted link for a colleague to check. A script can pass an article id from one command to the next, but it cannot read the body and work out what to change in it.
* **The person doing it does not use a terminal.** A support lead or a writer can keep the knowledge base current from a chat window. NeetoKB hosts the server, so there is nothing to install or keep updated.
### Reach for the CLI instead when
* **No AI assistant should be in the loop.** A cron entry or a docs pipeline runs the CLI against a workspace it is already signed in to - no assistant open, no model account, no tokens spent per run. Every MCP call needs something with model access running.
* **The output feeds another program.** The CLI prints a bare article id, or raw JSON with a `pagination` block, straight into `jq`, a spreadsheet, or your own script. Here you get prose you would have to copy out by hand.
* **You are working through thousands of records.** Here every page is a separate tool call, and a thousand article titles crowd out the assistant's context long before the audit is finished. The CLI returns `total_pages` and `total_records` next to the records, so a shell loop walks every page unattended and writes each one to a file or into `jq` - the size of the knowledge base stops mattering.
* **The run has to be repeatable and reviewable.** A command is the artifact: it records exactly what ran and repeats identically in a runbook or a pull request. Ask twice here and the assistant may take a different route.
> [!TIP]
>
> You can have both. Run [`neetokb setup claude`](/cli/ai-assistants) and the
> same assistant drives the CLI for you, so a plain-language request still ends
> in an exact command you can read, repeat, and paste into a script.
> [!WARNING]
>
> Ask your assistant to show you what it plans to do before it creates, publishes, or removes anything. These tools act on your live workspace.
## What you need
* An AI assistant that supports MCP, such as Claude, ChatGPT, Claude Code, Codex, Cursor, Gemini CLI, VS Code with GitHub Copilot, Windsurf, or Antigravity.
* A NeetoKB account. You need an API key only if the assistant must reach the whole workspace, or if you use Antigravity. See [Authentication](/mcp/authentication).
[Connect your assistant](/mcp/connect) to get started.
# MCP server
Source: https://apidocs.neetokb.com/mcp/server
The NeetoKB MCP server endpoint, transport, and the sign-in options each agent supports.
NeetoKB hosts the MCP server. There is nothing to install.
| | |
| - | - |
| **Endpoint** | `https://connect.neetokb.com/mcp/messages` |
| **Transport** | HTTP |
| **Authentication** | OAuth, or `Authorization: Bearer YOUR_API_KEY` |
## How each agent connects
| Agent | Sign in with NeetoKB | API key |
| - | - | - |
| Claude, ChatGPT | Yes | No |
| Claude Code, Codex, Cursor, Gemini CLI, VS Code, Windsurf | Yes | Yes |
| Antigravity | Not documented | Yes |
When you sign in, the assistant sees only what you can see. An API key reaches the whole workspace. See [Authentication](/mcp/authentication).
For the setup steps, see [Connect agent](/mcp/connect).
# Tools
Source: https://apidocs.neetokb.com/mcp/tools
Every tool the NeetoKB MCP server exposes, grouped by resource.
You do not need these names to use the server. Ask in plain language and the assistant picks the right tool. The list is here for when you want to know exactly what a connection can do. Most tools match a [REST API](/api/introduction) endpoint and link to its reference.
Every tool takes an optional `workspace` argument, the subdomain of a connected workspace. Left out, it runs against the workspace the connection was set up with. `ListWorkspaces` reports the values you can pass.
What a tool returns depends on the credential. Over [OAuth](/mcp/authentication#oauth-scoped-to-you), lists come back filtered to the permissions of the person who approved the connection, and a record they cannot open is refused rather than returned; an [API key](/mcp/authentication#api-key-scoped-to-the-workspace) reaches the whole workspace. A tool that creates, updates, or deletes is also refused when the connection was not granted the **Create and update** or **Delete** permission.
## Workspaces
| Tool | What it does |
| - | - |
| `ListWorkspaces` | Lists the workspaces this connection can reach, with each one's name and subdomain and which is the default. Pass a subdomain as the `workspace` argument of other tools to target that workspace. |
`ListWorkspaces` has no REST endpoint, which is why it is not linked.
An OAuth grant covers every workspace ticked on the **Authorize access** screen, which can be more
than one. An API key covers the workspace it was generated in.
## Articles
| Tool | What it does |
| - | - |
| [`SearchArticles`](/api/search/get) | Full-text search across published articles, ranked by relevance, returning each match with its id, title, absolute URLs and a highlighted snippet. Paginated. |
| [`ListArticles`](/api/articles/list) | Lists articles in the workspace, with optional filters for state (draft, published, archived or all), search term and category, plus sort order and pagination. |
| [`GetArticle`](/api/articles/get) | Returns one article in full, including its HTML content, plain text content, category, author, tags, related articles, internal note, schedules and URLs. Covers drafts and published articles alike. |
| `GetPublicArticle` | Reads one published article from any workspace by its subdomain and id, without workspace access. Returns only published articles in non-private categories, from workspaces that do not require sign-in. |
| [`CreateArticle`](/api/articles/create) | Creates an article under a category path given as an array of category names, innermost first, such as `["Getting Started", "Help"]`, auto-creating any missing categories, and can attach tags, related articles (`related_article_ids`) and an internal note (`note`). Defaults to a draft; a published article is readable on the public knowledge base site. |
| [`UpdateArticle`](/api/articles/update) | Updates an article's title, HTML content, slug, state, category path (moving the article), tags, related articles or internal note. Publishing applies the changes to the live article and promotes any draft revision it was carrying. |
| `search` | Searches published articles and returns up to 20 matches, each with its id, title, an openable URL and a short extract. |
| `fetch` | Returns the full text of one published article by its id. |
| [`ArchiveArticle`](/api/articles/archive) | Archives an article: it becomes a draft and is kept out of the public knowledge base. |
| [`UnarchiveArticle`](/api/articles/unarchive) | Brings an archived article back as a draft. |
| [`DiscardArticleDraft`](/api/articles/discard-draft) | Throws away the unpublished draft changes of an article and keeps the live version. Refused for an article that is not published, because its draft is its only copy; trash that article instead. |
| [`CloneArticle`](/api/articles/clone) | Copies an article into a new draft. |
| [`BulkUpdateArticles`](/api/articles/bulk-update) | Moves up to 100 articles to a category, sets their state, or archives or unarchives them. Give exactly one of `category_id`, `state` or `status`, or the call is refused. If one article cannot be updated, none are. |
Article tools address an article by its slug, its permalink identifier (`a-XXXXXXXX`) or its UUID.
`GetPublicArticle` also needs the workspace subdomain, and it never exposes drafts or the author's
email address. It has no page in the API reference, which is why it is not linked above.
> [!NOTE]
>
> `search` and `fetch` are the two tools the
> [ChatGPT connector specification](https://developers.openai.com/api/docs/mcp) requires, so they
> overlap with `SearchArticles` and `GetArticle` rather than adding anything new. They have no
> separate REST endpoint, which is why they are not linked above.
## Trash
| Tool | What it does |
| - | - |
| [`TrashArticle`](/api/articles/trash) | Moves one article to the trash. |
| [`BulkTrashArticles`](/api/articles/bulk-trash) | Moves up to 100 articles to the trash. If one cannot be trashed, none are. |
| [`ListTrashedArticles`](/api/trash/list) | Lists the articles in the trash, with the days left before each is deleted for good. Paginated. |
| [`RestoreArticle`](/api/trash/restore) | Moves an article out of the trash. |
| [`DeleteTrashedArticle`](/api/trash/delete) | Deletes a trashed article for good. |
> [!WARNING]
>
> `DeleteTrashedArticle` cannot be undone. Confirm the article before you approve the call.
## Schedules
| Tool | What it does |
| - | - |
| [`ListArticleSchedules`](/api/articles/list-schedules) | Lists the scheduled publish and unpublish actions of an article. |
| [`ScheduleArticle`](/api/articles/create-schedule) | Schedules an article to be published or unpublished at a future time, in a given time zone. An article holds at most one schedule of each kind, and when it has both, the unpublish time must not come after the publish time. |
| [`DeleteArticleSchedule`](/api/articles/delete-schedule) | Deletes a scheduled action. |
## Article SEO
| Tool | What it does |
| - | - |
| [`GetArticleSeoSetting`](/api/articles/get-seo-setting) | Returns the SEO settings of one article: title, title suffix, description, keywords and whether search engines may crawl it. |
| [`UpdateArticleSeoSetting`](/api/articles/update-seo-setting) | Changes those settings. Only the fields you pass change, and `keywords` replaces the whole list. |
## Revisions
| Tool | What it does |
| - | - |
| [`ListArticleRevisions`](/api/articles/list-revisions) | Lists the revisions of an article, newest first. Paginated. |
| [`GetArticleRevision`](/api/articles/get-revision) | Returns one revision with the title and HTML content it held. |
| [`RestoreArticleRevision`](/api/articles/restore-revision) | Copies a revision into the article's draft. The live content does not change until the draft is published. |
## Attachments
| Tool | What it does |
| - | - |
| [`UploadAttachment`](/api/attachments/create) | Uploads a file from a public https `url` or from `content_base64` and returns its permanent `blob_url` and, for an image, its `attachable_html`, ready to paste into an article's HTML content. |
## Unlisted links
| Tool | What it does |
| - | - |
| [`GetUnlistedLink`](/api/articles/get-unlisted-link) | Returns the unlisted share link an article already has. Only published articles can have one. |
| [`RegenerateUnlistedLink`](/api/articles/regenerate-unlisted-link) | Issues a fresh unlisted link for a published article, with an optional expiry, and is how an article gets its first link. |
An unlisted link is an article's secret share URL, which lets anyone holding it read the article
without signing in. Treat the URL as sensitive.
> [!WARNING]
>
> `RegenerateUnlistedLink` replaces the token, so any previously shared URL stops working
> immediately. Confirm nobody still depends on the old link before you approve the call.
## Categories
| Tool | What it does |
| - | - |
| [`GetCategory`](/api/categories/get) | Returns one category by UUID or slug, with its parent, depth, privacy and article counts. |
| [`CreateCategory`](/api/categories/create) | Creates a category, optionally private, under a parent and at a position among its siblings. |
| [`UpdateCategory`](/api/categories/update) | Renames a category, changes its privacy, moves it to another parent or to the top level, or changes its position. |
| [`DeleteCategory`](/api/categories/delete) | Deletes a category. Its articles and subcategories move to the category you name, or to the parent. |
| [`ReorderCategoryArticles`](/api/categories/reorder-articles) | Sets the order of the articles in a category. |
| [`ListCategories`](/api/categories/list) | Lists every category the workspace holds, including private categories and categories that carry no articles yet, flattened depth first with each category's parent, depth and published article counts. |
## Tags
| Tool | What it does |
| - | - |
| [`ListTags`](/api/tags/list) | Lists tags with the number of articles each has. Can be searched and sorted. Paginated. |
| [`CreateTag`](/api/tags/create) | Creates a tag with an optional description and style. |
| [`UpdateTag`](/api/tags/update) | Changes a tag's name, description or style. |
| [`DeleteTag`](/api/tags/delete) | Deletes a tag and removes it from every article. The articles are kept. |
| [`MergeTags`](/api/tags/merge) | Merges tags into a primary tag. The primary tag stays and the secondary tags are deleted. |
## Authors
| Tool | What it does |
| - | - |
| [`ListAuthors`](/api/authors/list) | Lists the people credited on at least one article, deactivated members included, with each author's name, email address, profile image and article counts. Can be sorted by count. |
## Recommendations
| Tool | What it does |
| - | - |
| [`ListRecommendations`](/api/recommendations/get) | Lists the article recommendations configured for the workspace, each with a preview of the published articles it surfaces. Can be narrowed to the recommendations that match a page path. |
| [`GetRecommendation`](/api/recommendations/get-one) | Returns one recommendation with the articles and categories it points to. |
| [`CreateRecommendation`](/api/recommendations/create) | Creates a recommendation for pages whose URL matches, using `contains`, `exact_match` or `regex` matching. |
| [`UpdateRecommendation`](/api/recommendations/update) | Changes a recommendation. Passing `entities` replaces all of them. |
| [`DeleteRecommendation`](/api/recommendations/delete) | Deletes a recommendation. |
## Redirections
| Tool | What it does |
| - | - |
| [`ListRedirections`](/api/redirections/list) | Lists redirections, newest first, with an optional search. Paginated. |
| [`GetRedirection`](/api/redirections/get) | Returns one redirection. |
| [`CreateRedirection`](/api/redirections/create) | Creates a page or domain redirection from an old path to a new path or URL. |
| [`UpdateRedirection`](/api/redirections/update) | Changes a redirection. |
| [`DeleteRedirection`](/api/redirections/delete) | Deletes a redirection. |
## Navigation links
| Tool | What it does |
| - | - |
| [`ListNavigationLinks`](/api/navigation-links/list) | Lists the header and footer links of the public knowledge base in display order. |
| [`UpdateNavigationLinks`](/api/navigation-links/update) | Replaces the header links, the footer links or both. Each set you pass becomes exactly that list. |
## Reports
| Tool | What it does |
| - | - |
| [`ListPopularSearches`](/api/reports/popular-searches) | Lists the keywords visitors search for, with counts, for a period. Paginated. |
| [`ListFailedSearches`](/api/reports/failed-searches) | Lists the searches that found no article, with counts, for a period. Paginated. |
| [`ListInvalidUrls`](/api/reports/invalid-urls) | Lists visited URLs that do not exist, with counts and referrers. Can be narrowed to one URL. Paginated. |
| [`GetKbVisits`](/api/reports/kb-visits) | Returns the visits to the knowledge base for each day of a period. |
| [`ClearPopularSearches`](/api/reports/clear-popular-searches) | Deletes the popular searches data for a period, or all of it. |
| [`ClearFailedSearches`](/api/reports/clear-failed-searches) | Deletes the failed searches data for a period, or all of it. |
| [`ClearInvalidUrls`](/api/reports/clear-invalid-urls) | Deletes the invalid URLs data for a period or URL, or all of it. |
The report tools take `duration`, and `start_date` and `end_date` for a `custom` period. The `Clear` tools cannot be undone and return the number of rows deleted.
## Team members
| Tool | What it does |
| - | - |
| [`ListTeamMembers`](/api/team-members/list) | Lists active team members with their id, email address, name, time zone and role. Can be narrowed to one exact email address. |
| [`GetTeamMember`](/api/team-members/get) | Returns one active team member's email address, name, time zone and role. |
| [`CreateTeamMember`](/api/team-members/add) | Invites one or more people to the workspace by email, each assigned a role. An address that already belongs to the workspace is not invited again. |
| [`UpdateTeamMember`](/api/team-members/update) | Updates a team member's email address, name, time zone or role. |
| [`DeleteTeamMember`](/api/team-members/remove) | Deactivates a team member, ending their access. Their user record is kept so the articles they authored stay attributed to them. |
The team member tools also check the connected person's NeetoKB role: it must allow managing
members, and changing a member's role needs the manage-roles permission as well. These are role
permissions inside NeetoKB, separate from the **Create and update** and **Delete** permissions
ticked when approving the connection. An API key skips role checks.
## Settings
| Tool | What it does |
| - | - |
| [`GetSetting`](/api/settings/get) | Reads the knowledge base settings: its name and root URL, site content preference, sign-up, social sharing, article navigation links, header and search texts, copyright and contact section. |
| [`UpdateSetting`](/api/settings/update) | Changes those settings. Only the fields you pass change. |
| [`GetSeoSetting`](/api/seo-settings/get) | Reads the SEO settings of the whole knowledge base. |
| [`UpdateSeoSetting`](/api/seo-settings/update) | Changes the knowledge base SEO settings. `keywords` replaces the whole list. |
| [`GetMyPreferences`](/api/my-preferences/get) | Reads the signed-in user's preferences. |
| [`UpdateMyPreferences`](/api/my-preferences/update) | Changes the signed-in user's preferences, such as the monthly report email. |
| [`UpdateNeetoChatIntegration`](/api/integrations/neeto-chat) | Turns the NeetoChat integration on or off. |
`GetMyPreferences` and `UpdateMyPreferences` need a signed-in user, so they are refused over an API key.
## Themes
| Tool | What it does |
| - | - |
| [`ListThemes`](/api/themes/list) | Lists built-in and custom themes. Paginated. |
| [`GetTheme`](/api/themes/get) | Returns one theme with its colors. |
| [`UpdateTheme`](/api/themes/update) | Renames a custom theme. |
| [`DeleteTheme`](/api/themes/delete) | Deletes a custom theme. The published theme cannot be deleted. |
| [`CloneTheme`](/api/themes/clone) | Copies a built-in or custom theme into a new unpublished custom theme. |
| [`PublishTheme`](/api/themes/publish) | Makes a theme the one visitors see. |
| [`GetThemeConfiguration`](/api/themes/get-configuration) | Returns the fonts, colors, images and custom CSS of a theme. |
| [`UpdateThemeConfiguration`](/api/themes/update-configuration) | Changes the configuration of a custom theme. Colors are merged into the current ones. |
| [`CreateThemeFont`](/api/themes/create-font) | Adds a Google font to a custom theme. |
| [`UpdateThemeFont`](/api/themes/update-font) | Changes a font of a custom theme. |
| [`DeleteThemeFont`](/api/themes/delete-font) | Removes a font from a custom theme. |
Built-in themes cannot be changed. Clone one first.
## Webhooks
| Tool | What it does |
| - | - |
| [`ListWebhooks`](/api/webhooks/list) | Lists webhooks. The secret is never returned. Paginated. |
| [`GetWebhook`](/api/webhooks/get) | Returns one webhook. |
| [`CreateWebhook`](/api/webhooks/create) | Creates a webhook for an endpoint and a set of events. |
| [`UpdateWebhook`](/api/webhooks/update) | Changes a webhook. Passing `events` replaces the whole list. |
| [`DeleteWebhook`](/api/webhooks/delete) | Deletes a webhook. |
| [`ListWebhookEvents`](/api/webhooks/events) | Lists the events a webhook can subscribe to. |
# Troubleshooting
Source: https://apidocs.neetokb.com/mcp/troubleshooting
What to check when an assistant cannot reach NeetoKB.
> **The assistant does not see any NeetoKB tools**
>
> **Restart the client first.** Every client reads its MCP config at startup, and Cursor can also reload the window from the command palette. Then check the items for your kind of client.
>
> On Claude or ChatGPT, confirm that you added the connector and finished the sign-in. In ChatGPT, the plugin is created only after you tick **I understand and want to continue**.
>
> On Claude Code, Cursor, Gemini CLI, Codex, VS Code, Windsurf, or Antigravity, which read a config file:
>
> 1. **Check the config key.** Claude Code, Cursor, Gemini CLI, Windsurf, and Antigravity nest servers under `mcpServers`. VS Code uses `servers`, and Codex uses a `[mcp_servers.]` section in TOML. A server under the wrong key is ignored silently.
> 2. **Check the URL key.** Windsurf and Antigravity expect `serverUrl`, and Gemini CLI expects `httpUrl` because it reserves `url` for SSE. Claude Code, Codex, Cursor, and VS Code expect `url`.
> 3. **Check the endpoint.** It is `https://connect.neetokb.com/mcp/messages`, with no trailing slash.
> 4. **Check the syntax.** In JSON a trailing comma or an unclosed brace makes the whole file unreadable, which takes out any other servers too.
>
> Full snippets for each client are on [Connect agent](/mcp/connect).
> **ChatGPT does not show Developer mode**
>
> Go to [chatgpt.com](https://chatgpt.com) and open **Settings → Security and login**. Scroll to the bottom of the page. **Developer mode** is the last section, below **Lockdown mode**.
>
> If **Lockdown mode** is on, turn it off first. ChatGPT does not allow both at the same time. If **Developer mode** is still not there, your ChatGPT workspace admin has turned it off. Ask them to allow it, then follow the **ChatGPT web app** steps in [Connect agent](/mcp/connect).
>
> The ChatGPT desktop app does not need **Developer mode**. Follow the **ChatGPT desktop app** steps in [Connect agent](/mcp/connect) instead.
> **The connection is refused or unauthorized**
>
> On an API key connection, the `Authorization` header must read `Bearer YOUR_API_KEY`, with the word `Bearer` and a single space before the key. Confirm the key has not been revoked, and that it belongs to the workspace you expect: a key generated in one workspace does not work in another. Generate a new key from [workspace settings](https://help.neetokb.com/articles/api-keys) if you are unsure.
>
> On an OAuth connection there is no key to check. Remove the connector and add it again to run the sign-in from the start.
> **The client sends a key when you meant to sign in**
>
> A client that finds a credential in its config never starts the OAuth flow. Remove the `headers` block, or the `bearer_token_env_var` line in Codex, and restart the client. It then answers the server's 401 by opening the sign-in.
> **The client asks you to sign in when you meant to use a key**
>
> The opposite case: the credential is missing, so the client falls back to OAuth. Add the `headers` block with `"Authorization": "Bearer YOUR_API_KEY"`, or set `bearer_token_env_var = "NEETOKB_API_KEY"` in Codex and export that variable, then restart the client. Codex takes the *name* of an environment variable, not the key itself.
> **The OAuth sign-in fails at the workspace step**
>
> The first screen needs a workspace subdomain or a workspace URL, not an email address. For `acme.neetokb.com`, enter `acme`. See [Workspace subdomain](/mcp/workspace-subdomain).
> **An OAuth-connected assistant sees fewer articles than expected**
>
> That is the scoping working as intended. An OAuth connection acts as the person who approved it, so lists and searches come back filtered to your permissions, and asking for a specific article you cannot open is refused rather than answered.
>
> If the assistant genuinely needs to reach everything in the workspace, that is what an API key connection is for. See [Authentication](/mcp/authentication).
> **A tool is refused because a permission was not granted**
>
> The approval screen has two optional permissions, **Create and update** and **Delete**, and a tool that needs one you left unticked is refused with a message naming it. Nothing is broken and nothing half happened.
>
> To grant it, remove the connector and add it again, ticking the permission this time. See [Authentication](/mcp/authentication#what-you-approve). An API key connection carries every permission, so this cannot happen on one.
> **The assistant reaches the wrong workspace**
>
> An OAuth connection covers the workspaces you ticked while approving it. Name the workspace in your prompt, or ask the assistant to list the workspaces it can reach. To add another one, run the sign-in again and tick it.
>
> An API key belongs to exactly one workspace, so a key connection reaching the wrong one means the wrong key. Add the server a second time, with the other key and a different server name.
> **VS Code never offers the tools**
>
> MCP needs VS Code 1.99 or later with GitHub Copilot running in **Agent** mode. It is not available in Ask or Edit mode. Check the version, switch Copilot to Agent mode, and confirm that `.vscode/mcp.json` is in the workspace you have open. On an API key connection, VS Code prompts for the key the first time the server is used, so answer that prompt.
> **Windsurf or Antigravity connects but the tools are missing**
>
> Enable the server after saving the config: **Settings → Cascade → MCP Servers** in Windsurf, **Settings → Customizations** in Antigravity. Windsurf also caps the total number of tools at 100 across every connected server, so turn off servers you are not using and reload.
> **Claude shows the connector as unauthorized**
>
> Open **[Customize > Connectors](https://claude.ai/customize/connectors)**, remove NeetoKB, and connect it again from the [NeetoKB listing](https://claude.ai/directory/neetokb).
>
> On a Team plan, **Requested** means an admin has not turned NeetoKB on yet. An admin turns it on under **[Organization settings > Connectors](https://claude.ai/admin-settings/connectors)**.
> **An article tool reports the article is not published**
>
> Unlisted links exist only for published articles. Ask the assistant to publish the article first, then request the link again.
> **Check that the server is reachable**
>
> The server publishes its OAuth metadata without any credential, so one request tells you whether the problem is on the server or in your client:
>
> ```bash theme={"system"}
> curl -s https://connect.neetokb.com/.well-known/oauth-authorization-server
> ```
>
> A JSON document whose `issuer` is `https://connect.neetokb.com` means the host is reachable and answering, so look at the client's setup next. It does not prove that every tool call succeeds. No answer, or an error page, means the server cannot be reached from your network. Try again in a few minutes, and if it persists, tell us.
## Still stuck
Reach us through the [help center](https://help.neetokb.com), or at [support@neetokb.com](mailto:support@neetokb.com). Tell us which client you are using and what the assistant reports when it tries a NeetoKB tool.
# Workspace subdomain
Source: https://apidocs.neetokb.com/mcp/workspace-subdomain
Find your workspace subdomain and use it to connect an assistant.
Every NeetoKB workspace has its own subdomain. It is the part of your workspace URL before `neetokb.com`. For `https://spinkart.neetokb.com`, the subdomain is `spinkart`.
The MCP server URL is the same for every workspace, `https://connect.neetokb.com/mcp/messages`. The subdomain is how you tell NeetoKB which workspace the assistant can reach.
## Find your subdomain
**1. Open your workspace**
Sign in to NeetoKB in your browser and look at the address bar.
**2. Take the part before neetokb.com**
For `https://green-earth.neetokb.com`, the subdomain is `green-earth`.
## Where you use it
* **OAuth.** The first sign-in screen asks you to connect your workspace. Enter the subdomain, such as `green-earth`. You can also paste the full workspace URL, and only the subdomain is kept. An email address does not work. The screen links to this page as "Find your workspace subdomain".
* **API key.** Create the key in the workspace you want the assistant to reach. One key reaches one workspace.
See [Authentication](/mcp/authentication) for both routes.