Move a generated OpenAPI page within a section

:::openapi-operation POST /api/v1/workspaces/{workspace}/openapi/pages/{slug}/placement AUTH bearerAuth :::

A published page that leaves an internal or private section other than import-staging for a more open place keeps that access as its own visibility, so the move never opens it. The response is the page with its visibility after the move. When the org reviews agent changes, a move of a published page answers 202 with a placement proposal.

:::codesamples open Code examples

curl -X POST "https://contextowl.co/api/v1/workspaces/string/openapi/pages/string/placement" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  --data '{
  "note": "string",
  "position": 0,
  "section": "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/openapi/pages/string/placement"))
        .header("Accept", "application/json")
        .header("Authorization", "Bearer <token>")
        .header("Content-Type", "application/json")
        .method("POST", HttpRequest.BodyPublishers.ofString("{\n  \"note\": \"string\",\n  \"position\": 0,\n  \"section\": \"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/openapi/pages/string/placement"
headers = {
    "Accept": "application/json",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}
data = "{\n  \"note\": \"string\",\n  \"position\": 0,\n  \"section\": \"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/openapi/pages/string/placement", {
  method: "POST",
  headers: {
    "Accept": "application/json",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "note": "string",
    "position": 0,
    "section": "string"
  })
});

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

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

func main() {
	body := strings.NewReader(`{
  "note": "string",
  "position": 0,
  "section": "string"
}`)
	req, err := http.NewRequest("POST", "https://contextowl.co/api/v1/workspaces/string/openapi/pages/string/placement", 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/openapi/pages/string/placement")
        .header("Accept", "application/json")
        .header("Authorization", "Bearer <token>")
        .header("Content-Type", "application/json")
        .body("{\n  \"note\": \"string\",\n  \"position\": 0,\n  \"section\": \"string\"\n}")
        .send()?;

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

:::

:::details open Parameters (2)

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

:::

:::details open Request body (required)

application/json

FIELD TYPE REQUIRED DESCRIPTION
note string no Note for the reviewer when the org reviews agent changes: what the change does and why. A direct write ignores it.
position integer no Zero-based position in the section. Leave it out to add the page at the end.
section string yes Key of the target section, or none to take the page out of the sidebar
{
  "note": "string",
  "position": 0,
  "section": "string"
}

:::

:::details open Success responses (200, 202)

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 -
section string yes -
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 -
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",
  "section": "string",
  "slug": "string",
  "sort": 0,
  "source": "string",
  "sourceRef": "string",
  "status": "string",
  "title": "string",
  "updatedAt": "string",
  "updatedLabel": "string",
  "views": 0,
  "visibility": "string"
}

202

The org reviews changes from agent keys, so the change waits in a proposal for an editor. Nothing changed for readers.

Content-Type: application/json

FIELD TYPE REQUIRED DESCRIPTION
message string yes What happened and what to tell the user
pendingReview boolean yes True: the org reviews changes from agent keys, so the change waits in a proposal for an editor. Nothing changed for readers.
proposal ReviewProposal object yes -
{
  "message": "string",
  "pendingReview": true,
  "proposal": {
    "baseRevision": "string",
    "entryId": 0,
    "id": 0,
    "objectType": "string",
    "outcome": "string",
    "reviewUrl": "string",
    "slug": "string",
    "status": "string",
    "summary": "string",
    "target": "string"
  }
}

:::

:::details Error responses (400, 401, 402, 403, 404, 429, 500)

400

invalid_request: no section has the key, and details.allowed lists the valid keys, or the article is not a generated page.

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

402

upgrade_required: a section that is not public needs a paid plan or an active trial.

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 or generated page.

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

:::