REST API

A conventional, versioned REST API over the same agent keys as MCP. Every MCP tool has a REST endpoint, so you can drive ContextOwl from any HTTP client without an MCP runtime. Same cowl_pat_ bearer key, same permission model (permission + role ceiling + workspace scope + plan), same audit trail and outbound webhooks.

Quick start

  1. Create an agent key in Admin > Settings > API. It starts with cowl_pat_ and is shown once, so copy it into your secret manager.
  2. Pick the workspace id you want to work in (or use - with a workspace-bound key).
  3. Call the API with the key as a bearer token:
curl -s "https://contextowl.co/api/v1/workspaces/platform/articles" \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY"

That returns the workspace's articles as JSON. Every other endpoint follows the same shape: a bearer key, a workspace in the path, JSON in and out, except image uploads, which use multipart form data.

Base URL

https://contextowl.co/api/v1

Authenticate every request with your agent key:

Authorization: Bearer cowl_pat_YOUR_KEY

The {workspace} path segment is a workspace id. A workspace-bound key may use - to mean its bound workspace; an org-wide key must name one.

OpenAPI spec

The full machine-readable contract is served (and powers the API Reference pages in this workspace):

https://developers.contextowl.co/api/v1/openapi.json
curl -s "https://contextowl.co/api/v1/workspaces/platform/search?q=agent%20keys" \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY"

Add &semantic=true for embedding-ranked results (falls back to full-text search).

Read an article

curl -s https://contextowl.co/api/v1/workspaces/platform/articles/mcp \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY"

Create a draft

curl -s -X POST https://contextowl.co/api/v1/workspaces/platform/articles \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Agent Draft","section":"Guides","markdown":"# Agent Draft\n\nDrafted over the REST API."}'

Publish an article

Changing status needs both article.update and article.publish.

curl -s -X PATCH https://contextowl.co/api/v1/workspaces/platform/articles/agent-draft \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"STABLE"}'

Upload an image

Image uploads need the upload.image permission. Send a PNG, JPEG, WebP, or GIF image up to 10 MiB as the file form field. The response's url is a same-origin path you can use in Markdown or landing-page images.

curl -s -X POST https://contextowl.co/api/v1/workspaces/platform/uploads \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY" \
  -F "file=@architecture.png"

Memory

Shared workspace memory: Markdown notes at paths, available to workspace members with memory permissions. Write with PUT; read, list, search, and delete with the note path as a query parameter.

# Write (create or update) a note
curl -s -X PUT https://contextowl.co/api/v1/workspaces/platform/memory/note \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path":"conventions/errors.md","body":"always return the error envelope","kind":"reference"}'

# Read one note, list the index, full-text search
curl -s "https://contextowl.co/api/v1/workspaces/platform/memory/note?path=conventions/errors.md" \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY"
curl -s "https://contextowl.co/api/v1/workspaces/platform/memory" \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY"
curl -s "https://contextowl.co/api/v1/workspaces/platform/memory/search?q=envelope" \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY"

# Prune a note
curl -s -X DELETE "https://contextowl.co/api/v1/workspaces/platform/memory/note?path=conventions/errors.md" \
  -H "Authorization: Bearer cowl_pat_YOUR_KEY"

A note body is capped at 16 KiB. Creating a new path counts against a per-plan quota (200 on Free) and returns 409 memory_quota_exceeded when full; updating an existing path is exempt.

Errors

Errors use the standard envelope with an HTTP status:

{"error":{"code":"permission_denied","message":"this key lacks the required permission","status":403}}

Common codes: 401 unauthorized (missing or invalid key), 403 permission_denied or plan_required, 404 not_found (also cross-org workspaces, which never leak existence), 400 invalid_request, 429 rate_limited.