Knowledge Base Articles

Base URL: https://api.cornerspot.net

Authentication: requests use a bearer token, for example Authorization: Bearer YOUR_API_KEY.

List articles

GET /c/api/v1/help_center/articles

Returns a paginated list of help-center articles for the team. Supports full-text search on title and excerpt via query, a status filter, and a category_id filter. Requires the kb_read scope and the Knowledge Base module.

Query parameters

FIELDTYPEDESCRIPTION
querystringFull-text search over title and excerpt.
qstringAlias for query.
statusstring
one of draft, published
Filter by publication status. draft = no published_at; published = has published_at. Omit for all.
category_idstringRestrict results to a single category.
pageinteger1-based page number.
per_pageintegerPage size (1–100, default 25).

Code samples

curl --request GET \
  --url 'https://api.cornerspot.net/c/api/v1/help_center/articles' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/help_center/articles"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, headers=headers, method="GET")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/help_center/articles")

request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/help_center/articles',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_API_KEY',
    ],
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
200 OKa page of articles
401 Unauthorizedmissing or invalid API key
402 Payment Requiredthe team's plan doesn't include the Knowledge Base module
403 Forbiddenthe key lacks the kb_read scope

Create an article

POST /c/api/v1/help_center/articles

Creates a new help-center article. title and category_id are required. If slug is omitted it is auto-generated from the title. Set published_at to a timestamp to immediately publish the article (a body_html must also be present when publishing). Requires the kb_write scope and the Knowledge Base module.

Request body

FIELDTYPEDESCRIPTION
articleobject
article.titlestring · requiredRequired.
article.category_idstring · requiredRequired — the article's category.
article.slugstringURL slug. Auto-generated from title when omitted.
article.excerptstringShort summary shown in list views (max 500 chars).
article.body_htmlstringSanitised HTML body. Required when publishing.
article.published_atstringSet to a timestamp to publish. Omit or null to keep as draft.
article.meta_titlestringSEO <title> override (max 200 chars). Falls back to the article title.
article.meta_descriptionstringSEO meta description (max 500 chars). Falls back to the excerpt.

Code samples

curl --request POST \
  --url 'https://api.cornerspot.net/c/api/v1/help_center/articles' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
  "article": {
    "title": "string",
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "slug": "string",
    "excerpt": "string",
    "body_html": "string",
    "published_at": "2026-01-15T09:30:00Z",
    "meta_title": "string",
    "meta_description": "string"
  }
}'
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "article": {
      "title": "string",
      "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "slug": "string",
      "excerpt": "string",
      "body_html": "string",
      "published_at": "2026-01-15T09:30:00Z",
      "meta_title": "string",
      "meta_description": "string"
    }
  })
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "article": {
      "title": "string",
      "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "slug": "string",
      "excerpt": "string",
      "body_html": "string",
      "published_at": "2026-01-15T09:30:00Z",
      "meta_title": "string",
      "meta_description": "string"
    }
  })
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/help_center/articles"
payload = json.dumps({
  "article": {
    "title": "string",
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "slug": "string",
    "excerpt": "string",
    "body_html": "string",
    "published_at": "2026-01-15T09:30:00Z",
    "meta_title": "string",
    "meta_description": "string"
  }
}).encode("utf-8")
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, data=payload, headers=headers, method="POST")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/help_center/articles")

request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer YOUR_API_KEY"
request.body = JSON.generate({
  "article": {
    "title": "string",
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "slug": "string",
    "excerpt": "string",
    "body_html": "string",
    "published_at": "2026-01-15T09:30:00Z",
    "meta_title": "string",
    "meta_description": "string"
  }
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/help_center/articles',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Bearer YOUR_API_KEY',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'article' => [
        'title' => 'string',
        'category_id' => '1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d',
        'slug' => 'string',
        'excerpt' => 'string',
        'body_html' => 'string',
        'published_at' => '2026-01-15T09:30:00Z',
        'meta_title' => 'string',
        'meta_description' => 'string',
    ],
]),
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
201 Createdcreated
422 Unprocessable Contentvalidation errors (e.g. missing title or invalid slug format)

Get an article

GET /c/api/v1/help_center/articles/{id}

Returns a single article including body_html. Requires kb_read.

Path parameters

FIELDTYPEDESCRIPTION
idstring · requiredArticle id (UUID).

Code samples

curl --request GET \
  --url 'https://api.cornerspot.net/c/api/v1/help_center/articles/abc123' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/abc123', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/abc123', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/help_center/articles/abc123"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, headers=headers, method="GET")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/help_center/articles/abc123")

request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/help_center/articles/abc123',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_API_KEY',
    ],
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
200 OKthe article
404 Not Foundno such article in this team

Update an article

PATCH /c/api/v1/help_center/articles/{id}

Updates article fields. Any permitted field may be patched. Requires kb_write.

Path parameters

FIELDTYPEDESCRIPTION
idstring · requiredArticle id (UUID).

Request body

FIELDTYPEDESCRIPTION
articleobject
article.titlestring
article.category_idstring
article.slugstring
article.excerptstring
article.body_htmlstring
article.published_atstring
article.meta_titlestringSEO <title> override (max 200 chars).
article.meta_descriptionstringSEO meta description (max 500 chars).

Code samples

curl --request PATCH \
  --url 'https://api.cornerspot.net/c/api/v1/help_center/articles/abc123' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
  "article": {
    "title": "string",
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "slug": "string",
    "excerpt": "string",
    "body_html": "string",
    "published_at": "2026-01-15T09:30:00Z",
    "meta_title": "string",
    "meta_description": "string"
  }
}'
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/abc123', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "article": {
      "title": "string",
      "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "slug": "string",
      "excerpt": "string",
      "body_html": "string",
      "published_at": "2026-01-15T09:30:00Z",
      "meta_title": "string",
      "meta_description": "string"
    }
  })
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/abc123', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "article": {
      "title": "string",
      "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
      "slug": "string",
      "excerpt": "string",
      "body_html": "string",
      "published_at": "2026-01-15T09:30:00Z",
      "meta_title": "string",
      "meta_description": "string"
    }
  })
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/help_center/articles/abc123"
payload = json.dumps({
  "article": {
    "title": "string",
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "slug": "string",
    "excerpt": "string",
    "body_html": "string",
    "published_at": "2026-01-15T09:30:00Z",
    "meta_title": "string",
    "meta_description": "string"
  }
}).encode("utf-8")
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, data=payload, headers=headers, method="PATCH")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/help_center/articles/abc123")

request = Net::HTTP::Patch.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer YOUR_API_KEY"
request.body = JSON.generate({
  "article": {
    "title": "string",
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "slug": "string",
    "excerpt": "string",
    "body_html": "string",
    "published_at": "2026-01-15T09:30:00Z",
    "meta_title": "string",
    "meta_description": "string"
  }
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/help_center/articles/abc123',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'PATCH',
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Bearer YOUR_API_KEY',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'article' => [
        'title' => 'string',
        'category_id' => '1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d',
        'slug' => 'string',
        'excerpt' => 'string',
        'body_html' => 'string',
        'published_at' => '2026-01-15T09:30:00Z',
        'meta_title' => 'string',
        'meta_description' => 'string',
    ],
]),
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
200 OKupdated
404 Not Foundno such article in this team
422 Unprocessable Contentvalidation errors (e.g. title blank, invalid slug, or body blank when publishing)

Delete (soft) an article

DELETE /c/api/v1/help_center/articles/{id}

Soft-deletes the article. Requires kb_write.

Path parameters

FIELDTYPEDESCRIPTION
idstring · requiredArticle id (UUID).

Code samples

curl --request DELETE \
  --url 'https://api.cornerspot.net/c/api/v1/help_center/articles/abc123' \
  --header 'Authorization: Bearer YOUR_API_KEY'
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/abc123', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/abc123', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/help_center/articles/abc123"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, headers=headers, method="DELETE")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/help_center/articles/abc123")

request = Net::HTTP::Delete.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/help_center/articles/abc123',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_API_KEY',
    ],
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
204 No Contentdeleted
404 Not Foundno such article in this team

Reorder all articles in a category

POST /c/api/v1/help_center/articles/reorder

Repositions every article in a category in one atomic write. The request body MUST contain the complete ordered list of article ids for that category — a partial list is rejected with 422 incomplete_reorder. An empty category returns 422 no_articles_in_category. Requires kb_write.

Request body

FIELDTYPEDESCRIPTION
category_idstring · requiredRequired — the category whose articles are being reordered.
ids[]array of string · requiredRequired — ALL article ids in the category, in the desired order.

Code samples

curl --request POST \
  --url 'https://api.cornerspot.net/c/api/v1/help_center/articles/reorder' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
  "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
  "ids": [
    "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d"
  ]
}'
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/reorder', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "ids": [
      "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d"
    ]
  })
});

const data = await response.json();
console.log(data);
// Node.js 18+ (native fetch)
const response = await fetch('https://api.cornerspot.net/c/api/v1/help_center/articles/reorder', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
    "ids": [
      "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d"
    ]
  })
});

if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);
import json
import urllib.request

url = "https://api.cornerspot.net/c/api/v1/help_center/articles/reorder"
payload = json.dumps({
  "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
  "ids": [
    "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d"
  ]
}).encode("utf-8")
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer YOUR_API_KEY",
}

request = urllib.request.Request(url, data=payload, headers=headers, method="POST")

with urllib.request.urlopen(request) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data)
require "json"
require "net/http"

uri = URI("https://api.cornerspot.net/c/api/v1/help_center/articles/reorder")

request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer YOUR_API_KEY"
request.body = JSON.generate({
  "category_id": "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d",
  "ids": [
    "1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d"
  ]
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

puts JSON.parse(response.body)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://api.cornerspot.net/c/api/v1/help_center/articles/reorder',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Bearer YOUR_API_KEY',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'category_id' => '1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d',
    'ids' => [
        '1f2e3d4c-5b6a-4789-9c0d-1e2f3a4b5c6d',
    ],
]),
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
print_r($data);

Responses

STATUSDESCRIPTION
200 OKreordered — returns the articles in their new order
401 Unauthorizedmissing or invalid API key
402 Payment Requiredthe team's plan doesn't include the Knowledge Base module
403 Forbiddenthe key lacks the kb_write scope
422 Unprocessable Contentids list does not match the full set of articles in the category

Was this article helpful?