Feedjoltdocs
DevelopersAPI

API authentication

Authenticate the Feedjolt API with API keys sent as a Bearer token in the Authorization header. Create, scope, and revoke keys - server-to-server only.

The API uses workspace API keys. Send the key as Authorization: Bearer <key> or as X-API-Key: <key>. Dashboard cookie sessions keep working without a key.

Creating a key

Dashboard -> Settings -> API keys -> New key.

You'll set:

  • Name - for your sanity. production-zapier, local-dev-marc. Not "key", "test", "asdf".
  • Scopes - what the key can do (stored as a JSON array on the key).

The full key is shown once when generated. Save it; we only store a hash. Lost key = make a new one.

Format

fjk_<random>

The fjk_ prefix is intentional:

  • Easy to spot in your logs (and our git-leak detection).
  • Easy to write a regex / pre-commit hook against.
  • Lets you tell at a glance "this is a Feedjolt key, not a Stripe key".

Treat the full key as a secret. Don't put keys in: client-side code, mobile apps, public repos, customer support tickets, screenshots.

Sending the key

Prefer Bearer. X-API-Key is the same credential.

Authorization: Bearer fjk_abc123...
X-API-Key: fjk_abc123...

A key is scoped to one workspace. GET /api/v1/workspaces returns that workspace.

Examples:

curl -H "Authorization: Bearer $FEEDJOLT_KEY" \
     "https://api.feedjolt.com/api/v1/workspaces"
fetch("https://api.feedjolt.com/api/v1/workspaces", {
  headers: { Authorization: `Bearer ${process.env.FEEDJOLT_KEY}` }
});
import os, httpx
r = httpx.get(
    "https://api.feedjolt.com/api/v1/workspaces",
    headers={"Authorization": f"Bearer {os.environ['FEEDJOLT_KEY']}"}
)

Scopes

Keys carry a list of scopes. The exact scope strings and the per-endpoint scope checks are documented in the OpenAPI reference under each endpoint's "security" section - that's the source of truth.

When picking scopes, default to read-only and expand only as needed. Missing-scope calls return 403.

Revoking

Settings -> API keys -> Revoke. Immediate.

If a key leaks:

  1. Revoke it.
  2. Generate a new key.
  3. Update your secret store.
  4. Redeploy.
  5. Consider rotating any data that may have been read.

Server-to-server only

There is no client-side API key flow. Keys must stay server-side. Browser calls should go through your backend.

For unauthenticated client-side access (read-only public data), use the widget or the public portal's standard URLs - they're publicly indexed and have no auth requirement.

Subscription status

API keys need an entitled plan (Startup or Scale) and an entitled status. Canceled, unpaid, incomplete, or never-paid rows return 403 SUBSCRIPTION_INACTIVE on every call, including GET. past_due keeps full access for 7 days after the first failed-renewal timestamp (past_due_since), then reads stay open and writes return the same 403. The renewed current_period_end does not extend that window. Comped workspaces are never locked. Dashboard cookie sessions stay read-only when canceled; they do not use this API-key gate.

Dashboard-only administration

Workspace membership, integration connections, API-key management, billing, and JWT configuration require a signed-in dashboard session. API keys cannot access these resources, even with all scopes enabled. A request carrying both an API key and a dashboard cookie is still restricted as an API-key request.

Use the dashboard to invite teammates or connect Slack, Linear, or GitHub. Existing scoped API access to feedback resources remains available.

On this page