Report a question that the docs did not answer

:::openapi-operation POST /api/v1/workspaces/{workspace}/content-gaps AUTH bearerAuth :::

Records the question for the docs team, which sees it in its content insights. Call it after a search and a read found nothing that answers the question. Send the question as the user asked it, without names, email addresses or secrets. Each call adds one report.

:::codesamples open Code examples

curl -X POST "https://contextowl.co/api/v1/workspaces/string/content-gaps" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  --data '{
  "question": "string",
  "slug": "string"
}'
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/content-gaps"))
        .header("Accept", "application/json")
        .header("Authorization", "Bearer <token>")
        .header("Content-Type", "application/json")
        .method("POST", HttpRequest.BodyPublishers.ofString("{\n  \"question\": \"string\",\n  \"slug\": \"string\"\n}"))
        .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/content-gaps"
headers = {
    "Accept": "application/json",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}
data = "{\n  \"question\": \"string\",\n  \"slug\": \"string\"\n}".encode("utf-8")
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
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/content-gaps", {
  method: "POST",
  headers: {
    "Accept": "application/json",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "question": "string",
    "slug": "string"
  })
});

console.log(response.status);
console.log(await response.json());
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

func main() {
	body := strings.NewReader(`{
  "question": "string",
  "slug": "string"
}`)
	req, err := http.NewRequest("POST", "https://contextowl.co/api/v1/workspaces/string/content-gaps", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	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::POST, "https://contextowl.co/api/v1/workspaces/string/content-gaps")
        .header("Accept", "application/json")
        .header("Authorization", "Bearer <token>")
        .header("Content-Type", "application/json")
        .body("{\n  \"question\": \"string\",\n  \"slug\": \"string\"\n}")
        .send()?;

    println!("{}", response.status());
    println!("{}", response.text()?);
    Ok(())
}

:::

:::details open Parameters (1)

NAME IN TYPE REQUIRED DESCRIPTION
workspace path string yes Workspace id, or - for the key's bound workspace

:::

:::details open Request body (required)

application/json

FIELD TYPE REQUIRED DESCRIPTION
question string no The question that the docs did not answer. The first 256 characters are kept.
slug string no Slug of the article that came closest, if one did.
{
  "question": "string",
  "slug": "string"
}

:::

:::details open Success responses (202)

202

Success

Content-Type: application/json

FIELD TYPE REQUIRED DESCRIPTION
message string yes -
reported boolean yes -
{
  "message": "string",
  "reported": true
}

:::

:::details Error responses (400, 401, 403, 404, 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: the object does not exist, or the key cannot reach it.

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
  }
}

:::