$ cli-blog docs

API keys

Choose public or private organization keys, set narrow permissions, store them safely, and respond to exposure.

Every Cli Blog API key belongs to one organization. The key itself selects that organization for every content request, resource lookup, and slug namespace, so do not send an organization ID in the URL, query, or request body. A key cannot cross organization boundaries, and its type and permissions determine which content it can read or change.

For example, two organizations can each use the slug hello-world; a request for /v1/posts/hello-world searches only the organization selected by the submitted key. Responses include organization_id as metadata, not as a value for selecting another organization.

Choose a key type

Key typePrefixDescriptionAllowed environments
Publiccli_blog_pk_Reads published delivery content, public authors, categories, tags, sitemap XML, and feed XMLWebsites, browser apps, mobile apps, servers, static builds, and CI
Privatecli_blog_sk_Reads editorial data and creates, updates, publishes, schedules, uploads, or deletes content when permissions allowServers, secret managers, CI, local shells, CLIs, and trusted agent environments

Public means suitable for published-content delivery. It does not make the key organization-independent or appropriate to commit to a repository. Treat every key as a managed credential so it can be identified, limited, and rotated.

Understand permissions

Private keys receive one or more actions for the resources they need:

ResourceAvailable actionsWhat it controls
postscreate, read, update, delete, publishPosts, revisions, redirects, sitemap, and feed; publish also covers scheduled and published status changes
authorscreate, read, update, deletePublic author profiles
mediacreate, read, update, deleteUploaded assets and their editorial metadata
taxonomycreate, read, update, deleteCategories and tags

Public keys are read-only. They can read published post delivery, public authors, public categories and tags, sitemap XML, and feed XML. Published post responses can include their related media. Direct media inventory endpoints and revision history require a private key.

The person creating a key cannot grant permissions above their current organization role. Publication settings, billing, members, and organization administration remain signed-in dashboard tasks; API keys do not receive permissions for those areas.

Design one key per workflow

Avoid one long-lived private key for every application and automation. Separate keys make audit, rotation, and incident response safer.

WorkflowSuggested namePermissions
Production website deliveryproduction-web-publicPublic read access
Preview deploymentpreview-web-publicPublic read access
Release-note drafting agentrelease-agent-draftsposts:create/read/update, authors:read, taxonomy:create/read, optional media:create/read
Approved publishing jobproduction-publisherposts:read/update/publish
Media migrationmedia-migration-2026-07Only the media and post actions required for the migration; delete after completion

A key name should identify the environment, owner, and purpose. Do not put the key value, customer data, or a personal name in the label.

Keep browser and server boundaries clear

Browser code may contain a public key and make published-content requests:

const response = await fetch(
  "https://api.cli-blog.com/v1/posts?status=published&fields=summary&include=authors",
  {
    headers: {
      "x-api-key": import.meta.env.PUBLIC_CLI_BLOG_KEY,
    },
  },
);

if (!response.ok) throw new Error(`Cli Blog returned ${response.status}`);
const posts = await response.json();

Private keys belong behind a server boundary:

import { CliBlog } from "@cli-blog/node";

const blog = new CliBlog({
  apiKey: process.env.CLI_BLOG_PRIVATE_KEY!,
});

const draft = await blog.posts.create({
  title: "July release notes",
  body_markdown: "A reviewed update from the product team.",
  status: "draft",
});

Protect the route that calls this code with your own session checks, role checks, request validation, CSRF defense where applicable, input limits, and rate limiting. A private key does not authenticate your application's end users.

Do not use a client-exposed environment variable for a private key. Framework prefixes such as NEXT_PUBLIC_, VITE_, PUBLIC_, and NUXT_PUBLIC_ normally make values available to browser code.

Send a key with REST requests

Send organization keys in the x-api-key header:

curl "https://api.cli-blog.com/v1/posts?status=published&fields=summary" \
  --header "x-api-key: $CLI_BLOG_PUBLIC_KEY"

Do not put a key in a URL, query parameter, request body, analytics event, or error message. URLs are commonly stored in browser history, reverse-proxy logs, and monitoring tools.

Store keys by environment

  • Put local values in an ignored environment file or operating-system credential store.
  • Put deployment values in the platform's encrypted secret store.
  • Give CI jobs access only in the environments and branches that need the key.
  • Keep production and preview credentials separate.
  • Redact x-api-key and environment values from logs, traces, screenshots, test fixtures, and generated documentation.
  • Do not copy a private key into an agent prompt. Provide it to the trusted tool environment as a secret.

Private key values are shown when they are created. Store the value in its destination immediately; do not create an extra plaintext copy for convenience.

Respond to a suspected exposure

Treat an exposed private key as compromised even if there is no visible misuse:

  1. Delete the exposed key in the dashboard immediately.
  2. Identify where it appeared: repository history, build output, logs, screenshots, support tickets, or agent transcripts.
  3. Remove or redact the value at every source. Rewriting a repository does not replace revocation.
  4. Review recent content and organization activity for unexpected reads or changes.
  5. Create a replacement with the minimum permissions and deploy it only to the intended workload.
  6. Verify the workflow and document the cause so the same path cannot expose the replacement.

If a public key is being abused, delete it, issue a replacement, update the delivery application, and inspect traffic patterns. Public keys cannot perform writes, but rotation is still useful for isolating unexpected clients.

Diagnose key errors

StatusLikely causeResolution
401Header missing, key malformed, key deleted, or wrong environment valueCheck the x-api-key header and selected secret
403Public key used for editorial data, private key lacks an action, or creator role cannot grant itUse the correct key type and add only the required permission
404Valid key points to another organization or the resource/locale does not existCheck the key's organization, identifier, and locale
429Request or plan limit reachedHonor Retry-After when present and reduce repeated requests

Never log the key while debugging. Log the request method, path, status, safe error code, and request ID instead.

On this page