Get one article
:::openapi-operation GET /api/v1/workspaces/{workspace}/articles/{slug} AUTH bearerAuth :::
A renamed slug follows the slug redirect and sets redirectedFrom. An unknown slug returns 404 with up to 3 close slugs in details.suggestions. An end-to-end encrypted article returns 422 encrypted. Without a key, the 404 of an unknown slug has no suggestions. An article that an anonymous reader cannot open returns that same 404, also when it is encrypted.
:::codesamples open Code examples
curl -X GET "https://contextowl.co/api/v1/workspaces/string/articles/string?section=string" \
-H "Accept: application/json" \
-H "Authorization: Bearer <token>"
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://contextowl.co/api/v1/workspaces/string/articles/string?section=string"))
.header("Accept", "application/json")
.header("Authorization", "Bearer <token>")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}
import urllib.request
url = "https://contextowl.co/api/v1/workspaces/string/articles/string?section=string"
headers = {
"Accept": "application/json",
"Authorization": "Bearer <token>",
}
data = None
req = urllib.request.Request(url, data=data, headers=headers, method="GET")
with urllib.request.urlopen(req) as res:
print(res.status)
print(res.read().decode())
const response = await fetch("https://contextowl.co/api/v1/workspaces/string/articles/string?section=string", {
method: "GET",
headers: {
"Accept": "application/json",
"Authorization": "Bearer <token>",
}
});
console.log(response.status);
console.log(await response.json());
package main
import (
"fmt"
"io"
"net/http"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://contextowl.co/api/v1/workspaces/string/articles/string?section=string", nil)
if err != nil {
panic(err)
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "Bearer <token>")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
bodyBytes, err := io.ReadAll(io.LimitReader(res.Body, 10<<20))
if err != nil {
panic(err)
}
fmt.Println(res.StatusCode)
fmt.Println(string(bodyBytes))
}
// cargo add reqwest --features blocking
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::blocking::Client::new();
let response = client.request(reqwest::Method::GET, "https://contextowl.co/api/v1/workspaces/string/articles/string?section=string")
.header("Accept", "application/json")
.header("Authorization", "Bearer <token>")
.send()?;
println!("{}", response.status());
println!("{}", response.text()?);
Ok(())
}
:::
:::details open Parameters (3)
| NAME | IN | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|---|
workspace |
path | string | yes | Workspace id, or - for the key's bound workspace |
slug |
path | string | yes | - |
section |
query | string | no | Anchor of one heading from the outline. The markdown then holds only that heading and its text |
:::
:::details open Success responses (200)
200
Success
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
archived |
boolean | yes | - |
author |
string | yes | - |
createdAt |
string (date-time) | yes | - |
encrypted |
boolean | yes | - |
isFolder |
boolean | yes | - |
kicker |
string | yes | - |
level |
integer | yes | - |
locked |
boolean | yes | - |
markdown |
string | yes | - |
method |
string | no | - |
nav |
string | yes | - |
navLabel |
string | yes | - |
outline |
array items: Heading object | yes | - |
redirectedFrom |
string | no | - |
revision |
string | yes | - |
section |
string | yes | - |
sectionAnchor |
string | no | - |
slug |
string | yes | - |
sort |
integer | yes | - |
source |
string | no | - |
sourceRef |
string | no | - |
status |
string | yes | - |
title |
string | yes | - |
updatedAt |
string (date-time) | yes | - |
updatedLabel |
string | yes | - |
url |
string | yes | - |
views |
integer | yes | - |
visibility |
string | yes | - |
{
"archived": true,
"author": "string",
"createdAt": "string",
"encrypted": true,
"isFolder": true,
"kicker": "string",
"level": 0,
"locked": true,
"markdown": "string",
"method": "string",
"nav": "string",
"navLabel": "string",
"outline": [
{
"anchor": "string",
"level": 0,
"text": "string"
}
],
"redirectedFrom": "string",
"revision": "string",
"section": "string",
"sectionAnchor": "string",
"slug": "string",
"sort": 0,
"source": "string",
"sourceRef": "string",
"status": "string",
"title": "string",
"updatedAt": "string",
"updatedLabel": "string",
"url": "string",
"views": 0,
"visibility": "string"
}
:::
:::details Error responses (400, 401, 403, 404, 422, 429, 500)
400
invalid_request: a parameter or the body is not valid.
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
error |
object | yes | - |
{
"error": {
"code": "string",
"details": null,
"message": "string",
"status": 0
}
}
401
unauthorized: the access key is missing, invalid or expired.
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
error |
object | yes | - |
{
"error": {
"code": "string",
"details": null,
"message": "string",
"status": 0
}
}
403
permission_denied: the key lacks the permission. two_factor_required: the org requires admins to turn on two-factor authentication.
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
error |
object | yes | - |
{
"error": {
"code": "string",
"details": null,
"message": "string",
"status": 0
}
}
404
not_found: no such workspace, article or section anchor. For an unknown slug, details.suggestions lists up to 3 close articles. For an unknown anchor, details.anchors lists the valid anchors. Without a key, an article that an anonymous reader cannot open is not found, and the error has no suggestions. When GET /api/v1/me shows readsDrafts false, a DRAFT or IN REVIEW article and a slug that redirects to one are not found, and the suggestions list published articles only.
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
error |
object | yes | - |
{
"error": {
"code": "string",
"details": null,
"message": "string",
"status": 0
}
}
422
encrypted: the article is end-to-end encrypted, so its text is not available to agents. Without a key, an encrypted article returns 404.
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
error |
object | yes | - |
{
"error": {
"code": "string",
"details": null,
"message": "string",
"status": 0
}
}
429
rate_limited: too many requests. Wait for the time in the Retry-After header.
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
error |
object | yes | - |
{
"error": {
"code": "string",
"details": null,
"message": "string",
"status": 0
}
}
500
internal: the server failed.
Content-Type: application/json
| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
error |
object | yes | - |
{
"error": {
"code": "string",
"details": null,
"message": "string",
"status": 0
}
}
:::