API Overview
The NeuralRepo API is a RESTful JSON API that lets you programmatically manage ideas, tags, relations, and user settings. Everything the web app, the CLI, and the MCP server do is done through these endpoints.
Base URL
Section titled “Base URL”All API requests are made to:
https://neuralrepo.com/api/v1The API is versioned through the URL path. The current (and only) version is v1.
Content Type
Section titled “Content Type”All request and response bodies use JSON. Set the Content-Type header on every request that includes a body:
Content-Type: application/jsonAuthentication
Section titled “Authentication”Every endpoint under /api/v1 except /api/v1/health requires authentication. Three
credentials are accepted:
| Method | Header | Format |
|---|---|---|
| API key | X-API-Key | nrp_ + 64 hexadecimal characters |
| API key or session token | Authorization | Bearer <token> |
| Session cookie | Cookie | nrepo_session=<token> — set by the web app |
The Authorization: Bearer header accepts either a session token or an API key; the
server tries the session table first and falls back to the API-key table. See
Authentication for the exact resolution order, key
generation, and scopes.
Idea identifiers
Section titled “Idea identifiers”Every idea carries two integers, and they are not interchangeable:
| Field | What it is | Where you see it |
|---|---|---|
id | Database primary key, unique across all accounts | Every :id path segment in this API |
number | Per-account counter assigned at capture time | The #42 in CLI listings and the web UI |
Every endpoint in this API keys off id. Nothing resolves a number, so passing the
#42 you read in a listing either returns someone else’s idea number range as a 404 or —
worse — silently addresses a different idea of yours.
Pagination
Section titled “Pagination”Pagination is not uniform across list endpoints — check the endpoint’s own reference page:
| Endpoint | limit | offset | Notes |
|---|---|---|---|
GET /ideas | default 20, max 100 | default 0 | has_more is true when the page is exactly limit long |
GET /ideas/search | default 20, max 100 | not supported | Keyword mode can return up to 2× limit |
GET /tags | not supported | not supported | Returns every tag |
GET /ideas/duplicates | not supported | not supported | Returns every pending detection |
GET /map | not supported | not supported | Returns the whole graph; filter with since/until |
GET /review | not supported | not supported | Returns the whole queue |
Example:
GET /api/v1/ideas?limit=50&offset=100Response Format
Section titled “Response Format”Successful responses return the resource wrapped in a named object ({ "ideas": [...] },
{ "tags": [...] }, { "relation": {...} }). Delete operations return { "success": true }.
Error responses carry an error field — but note that on validation failures error is an
object, not a string. See Error Handling.
Timestamps
Section titled “Timestamps”Every created_at and updated_at value is a UTC SQLite timestamp, not ISO-8601:
{ "created_at": "2026-03-24 09:00:00" }There is no T separator and no Z suffix. new Date("2026-03-24 09:00:00") parses as
local time in most runtimes, so append Z yourself before parsing.
Rate Limiting
Section titled “Rate Limiting”Requests authenticated with an API key or bearer token are rate-limited per user and per day —
100/day on Free, 10,000/day on Pro. Cookie-authenticated requests from the web app are exempt.
Exceeding the limit returns 429, and no Retry-After header is sent. See
Rate Limits.
Health Check
Section titled “Health Check”The health endpoint is the only unauthenticated route under /api/v1. Use it to verify the API
is reachable:
curl https://neuralrepo.com/api/v1/healthconst res = await fetch("https://neuralrepo.com/api/v1/health");const data = await res.json();console.log(data);Response 200 OK
{ "status": "ok", "environment": "production", "timestamp": "2026-03-25T12:00:00.000Z"}The health check runs a SELECT 1 against the database. If that query fails, the endpoint
returns 503 Service Unavailable with { "status": "error", "error": "Database unavailable" }.
Field Limits
Section titled “Field Limits”All input fields are validated against these maximum lengths:
| Field | Max | Behaviour when exceeded |
|---|---|---|
| Idea title | 200 characters | 400 |
| Idea body | 50,000 characters | 400 |
| Tags per idea | 20 | 400 |
| Tag name | 50 characters | 400 |
| Source URL | 2,000 characters | 400 |
| Display name | 100 characters | 400 |
| API key label | 100 characters | 400 |
| Settings JSON | 10,000 characters | 400 |
| Search query | 500 characters | 400 |
| List limit | 100 (default 20) | Clamped to 100, no error |
| Relation note | 500 characters | Silently truncated, no error |
| Bulk idea update | 50 ids | 400 |
| Bulk relation create | 50 links | 400 |
Plan gates
Section titled “Plan gates”Some endpoints require a Pro plan and return 403 with pro_required: true on Free:
| Endpoint | Gate |
|---|---|
POST /user/api-keys | Pro |
PUT/POST on /user/byok/:provider | Pro |
POST, PATCH, DELETE on /map/relations | Pro |
GET /agent/ws | Pro |
Two more limits are enforced by returning fewer results rather than an error, which is easy to mistake for a bug:
GET /ideas/duplicatesreturns{ "duplicates": [] }for every Free account.GET /ideas/searchgives Free accounts 10 semantic searches per month, then quietly serves keyword results.
And one is a hard cap on writes: POST /ideas returns 403 idea_limit_reached once a Free
account holds 50 unarchived ideas.
Versioning
Section titled “Versioning”The API is currently at v1. Breaking changes will be introduced under a new version prefix
(e.g., /api/v2). Non-breaking additions (new fields, new optional parameters) may be added to
v1 at any time.
Endpoint index
Section titled “Endpoint index”| Resource | Endpoints |
|---|---|
| Ideas | GET POST /ideas, GET PATCH DELETE /ideas/:id, PATCH /ideas/bulk, POST /ideas/:id/merge, POST /ideas/:id/develop |
| Search | GET /ideas/search |
| Duplicates | GET /ideas/duplicates, POST /ideas/duplicates/:id/dismiss, POST /ideas/duplicates/:id/merge |
| Tags | GET POST /tags, PATCH DELETE /tags/:id, GET /tags/similar |
| Links | GET POST /ideas/:id/links, DELETE /ideas/:id/links/:linkId |
| Relations | GET /ideas/:id/relations, POST /map/relations, PATCH DELETE /map/relations/:id |
| Mind Map | GET /map |
| Review Queue | GET /review, POST /review/:ideaId/keep |
| User & Settings | GET PATCH /user/me, API keys, MCP tokens, BYOK, shortcuts, support link |
| Export | POST /user/export, /user/export/csv, /user/export/markdown |
Three further routes exist under /api/v1 but are not part of the documented REST surface:
GET /agent/ws is a WebSocket upgrade used by the web app’s agent chat,
POST /user/billing/checkout and /user/billing/portal return single-use Stripe URLs for the
web app’s upgrade flow, and /api/v1/admin/* is operator-only.