Neural Draft uses a single auth model for the v1 Project API: a long-lived project key passed as a Bearer token. That’s it — no OAuth dance, no short-lived JWTs, no per-user signing. One key per project per environment.Documentation Index
Fetch the complete documentation index at: https://docs.neuraldraft.io/llms.txt
Use this file to discover all available pages before exploring further.
Key format
Every key is prefixed with environment and scoped to a single project:ndsk_test_ key in your
production env is a clear bug. Our SDKs and dashboards both surface the prefix
so it’s hard to confuse the two.
Where to get a key
Open Settings → API keys
From the dashboard at app.neuraldraft.io.
Click Create key
Pick a memorable name (e.g.
vercel-prod, lovable-preview,
claude-code-laptop). Future-you reading the audit log will thank present-you.Choose the scopes
Default is read+write across CMS, blog and social. Tighten to least
privilege when the key has a known job — for example, a static-site build
only needs
content:read and blog:read.Sending the key
A standard Bearer token in theAuthorization header. No query-param fallback,
no body field. HTTPS is required.
Scopes
Scopes are wildcard-prefixed. A key withcontent:* can do every action under
content; * is full access (use it carefully — only for trusted backend
services).
| Scope | What it covers |
|---|---|
* | Full access. Equivalent to all scopes below. |
project:read | Read project metadata, usage, key list. |
project:write | Update project (e.g. webhook URL, target languages). |
project:admin | Mint/revoke API keys, change billing. |
content:read | Read translation keys, components, pages. |
content:write | Create/update/delete translations and components. |
brand:read | Read brand context (voice, colors, fonts, audience). |
brand:write | Patch brand context, upload logos. |
images:read | Read media library and resolved image URLs. |
images:write | Upload, generate, replace images. |
blog:read | Read posts, categories, tags, translations. |
blog:write | Create/update/delete posts, schedule, publish. |
social:read | Read social posts and connected accounts. |
social:write | Create/update/delete social posts. |
social:publish | Publish a social post immediately to a connected platform. |
social:connect | Initiate OAuth flow, manage connected accounts. |
booking:read | Read services, availability, bookings. |
booking:write | Create/update services, availability, bookings. |
booking:admin | Update booking settings (timezone, policies, reminders). |
commerce:read | Read products, variants, categories, orders. |
commerce:write | Create/update/delete products, variants, categories, orders. |
commerce:admin | Refunds, Stripe Connect onboarding, manual orders. |
webhooks:read | List webhook endpoints and deliveries. |
webhooks:write | Create/update/delete webhook endpoints. |
jobs:read | Read job status (returned by all async ops). |
403 Forbidden with code: "forbidden" is returned when the key lacks the
required scope; the response includes the scope you’d need.
Common errors
| Status | code | When |
|---|---|---|
401 | unauthorized | Missing, malformed, expired or revoked key. |
403 | forbidden | Key is valid but lacks the required scope. |
402 | out_of_credits | Project has 0 credits. Top up or upgrade. |
429 | rate_limited | Per-project window exhausted. See Retry-After. |
503 | service_unavailable | Backend dependency down. Retry with backoff. |
Best practices
One key per environment
One key per environment
Mint separate keys for production, staging, preview, and each developer
laptop. The audit log shows last-used timestamps per key — anomalies become
obvious.
Rotate quarterly
Rotate quarterly
Mint a new key, deploy with both old and new accepted (we accept multiple
valid keys per project), then revoke the old one once nothing 401s. The
dashboard has a one-click rotation flow that automates the overlap window.
Never commit a key
Never commit a key
Use environment variables. On Vercel/Netlify/Render, the encrypted env UI
is the right place. For local dev, a
.env file in .gitignore and
dotenv-style loading. Our CLI refuses to write a key to disk outside of
a recognised secret manager.Use least-privilege scopes
Use least-privilege scopes
A static-site builder needs
content:read and blog:read, nothing more.
A scheduler-only service needs social:write and social:publish. Keys
leak; small blast radius is the only mitigation that works at scale.Treat `ndsk_test_` as throwaway
Treat `ndsk_test_` as throwaway
Test keys are fine to share with contractors, paste into Lovable previews,
or include in a public GitHub issue when reproducing a bug. They have a
separate credit pool that resets monthly and never bills.
Watch the audit log
Watch the audit log
Every key has a
last_used_at and a per-IP usage stripe in the dashboard.
Suspicious activity = a chance to rotate before damage compounds. Suspect
leakage? Revoke immediately; it takes effect within 60 seconds globally.Revoking a key
A revoked key starts returning401 unauthorized within ~60 seconds globally.
Active jobs queued against the key continue to completion (they were
authorised at submit time); new requests fail.
Multiple keys per project
A project can hold up to 20 active keys. Use this for environment separation and friction-free rotation:| Name | Scopes | Where it lives |
|---|---|---|
prod-server | * (or write scopes) | Server-side, secret manager |
prod-builder | content:read, blog:read | CI build pipeline |
prod-mcp | * | Claude Code on dev laptops |
staging-server | * | Staging deployments |
lovable-preview | content:*, images:* | Lovable’s hosted preview env |
409 Conflict with code: "key_limit_reached" —
revoke an unused one first.
Where Sanctum and OAuth fit in
The v1 Project API documented here is API-key only. The separate Admin API — used by white-label dashboards and agencies managing multiple projects — uses scoped Sanctum tokens (tenants:read,
posts:write, …) and is documented in its own reference. If you’re building
your own admin UI on top of Neural Draft, that’s the auth model you want; for
everything else, stay here.