Skip to content
NeuralRepo
Get Support

User & Settings

Everything under /api/v1/user acts on the authenticated account. Three of these endpoints are Pro-gated; the rest, including every export, work on any plan.

GET /api/v1/user/me

Returns the profile, the current idea count, and trial state. Encrypted provider keys are stripped and replaced by has_*_key booleans.

Terminal window
curl https://neuralrepo.com/api/v1/user/me \
-H "X-API-Key: nrp_YOUR_KEY"

Response 200 OK

{
"id": "3f2a91c47b0e4d5aa8c61e0f2b7d4c93",
"email": "you@example.com",
"display_name": "Jane Doe",
"avatar_url": "https://avatars.githubusercontent.com/u/1?v=4",
"plan": "pro",
"settings_json": "{\"preferred_ai_provider\":\"anthropic\"}",
"has_anthropic_key": true,
"has_openai_key": false,
"has_openrouter_key": false,
"trial_ends_at": "2026-04-01 00:00:00",
"trial_used": 1,
"active_idea_count": 137,
"is_trialing": true,
"trial_days_remaining": 6,
"created_at": "2026-01-15 08:00:00",
"updated_at": "2026-03-20 12:00:00"
}
FieldMeaning
planfree or pro. Trialing accounts read pro — the gates treat them as Pro
active_idea_countUnarchived ideas; compare with 50 to see how close a Free account is to its cap
is_trialingtrue only when the plan is pro, the trial has not ended, and there is no Stripe subscription
trial_days_remainingWhole days, rounded up; null when not trialing
email_capture_bare_optin1 if you opted in to the shared idea@ address for the transition, else 0. Your personal capture address is not in this response; see Email Capture Address

PATCH /api/v1/user/me

FieldTypeRequiredDescription
display_namestringNo1–100 characters
settings_jsonstringNoA JSON string, max 10,000 characters. See User Settings
Terminal window
curl -X PATCH https://neuralrepo.com/api/v1/user/me \
-H "X-API-Key: nrp_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"display_name": "Jane D.", "settings_json": "{\"search_threshold\":0.3}"}'

Response 200 OK — the updated user object, with the same stripped fields as GET /user/me but without active_idea_count and the trial fields.

GET /api/v1/user/api-keys

Returns every key on the account, newest first, with no key material — not even a masked prefix.

Response 200 OK

{
"api_keys": [
{
"id": "9c4f1b7e2d3a48f0b6e5c8d1a2f7b904",
"label": "CI Pipeline",
"scopes": null,
"source": "manual",
"last_used_at": "2026-03-24 08:12:00",
"created_at": "2026-03-20 10:00:00"
}
]
}

source is manual for keys made here and mcp for tokens minted by the MCP OAuth flow; scopes is null on every manual key, which means full access.

POST /api/v1/user/api-keys

FieldTypeRequiredDescription
labelstringNoMax 100 characters; defaults to default

Response 201 Created

{
"id": "9c4f1b7e2d3a48f0b6e5c8d1a2f7b904",
"key": "nrp_a1b2c3d4...",
"label": "CI Pipeline",
"created_at": "2026-03-24 09:00:00"
}

DELETE /api/v1/user/api-keys/:id

Revokes the key immediately, using the id from the list endpoint (a 32-character hex string, not the key itself). Works on every plan. Returns 404 if the id is not yours.

Response 200 OK

{
"success": true
}

GET /api/v1/user/mcp-tokens

Lists the tokens issued by the MCP OAuth flow when you authorize a client such as Claude. It does not create tokens — the client does that during authorization.

Response 200 OK

{
"tokens": [
{
"id": "b17d0e59a4c34f8e91d2c6b7f0a35e82",
"label": "MCP (claude-ai)",
"scopes": "ideas:read ideas:write",
"source": "mcp",
"last_used_at": "2026-03-24 08:00:00",
"created_at": "2026-03-20 10:00:00"
}
]
}

The client’s identity appears inside label; there is no separate client_id field. Revoke a token with DELETE /api/v1/user/api-keys/:id — MCP tokens live in the same store as API keys. Revoking one also revokes that client’s refresh tokens, so the client has to authorize again.

An MCP token stops working 30 days after it was issued. The client uses its refresh token to get a new one, and the refresh deletes the old token, so the list normally holds one token per connected client. The daily retention sweep removes tokens older than 30 days.

AI features that run on your own provider account — POST /ideas/:id/develop in this API — need a stored provider key. NeuralRepo encrypts it at rest and never returns it.

PUT /api/v1/user/byok/:provider

Pro only. :provider must be anthropic, openai, or openrouter.

FieldTypeRequiredDescription
api_keystringYesYour provider key; must be at least 10 characters
Terminal window
curl -X PUT https://neuralrepo.com/api/v1/user/byok/anthropic \
-H "X-API-Key: nrp_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"api_key": "sk-ant-..."}'

The key is stored without being tested — a typo is accepted here and fails later at develop time. Run the test endpoint below to confirm it works.

Response 200 OK

{
"success": true,
"provider": "anthropic"
}

DELETE /api/v1/user/byok/:provider

Removes the stored key. Unlike saving and testing, this is not Pro-gated — an account that lapses to Free can still delete keys it stored while on Pro.

Response 200 OK

{
"success": true,
"provider": "anthropic"
}

POST /api/v1/user/byok/:provider/test

Pro only. Decrypts the stored key and makes a minimal live call to the provider.

Terminal window
curl -X POST https://neuralrepo.com/api/v1/user/byok/anthropic/test \
-H "X-API-Key: nrp_YOUR_KEY"

Response 200 OK

{
"ok": true
}

A failure is also 200, with the reason in the body: { "ok": false, "error": "No anthropic key configured" } when nothing is stored, or the provider’s own message when the call is rejected. Check ok, not the status code.

GET /api/v1/user/byok/status

Returns which providers have keys and which one will actually be used.

Response 200 OK

{
"active_provider": "anthropic",
"has_anthropic_key": true,
"has_openai_key": false,
"has_openrouter_key": false
}

active_provider resolves as: your preferred_ai_provider setting if a key for it is stored, otherwise the first available in the fixed order Anthropic → OpenAI → OpenRouter. It is null when no keys are stored — which is when develop returns needs_byok. Setting a preference for a provider you have no key for is silently ignored rather than erroring.

GET /api/v1/user/shortcuts

Returns the iCloud Shortcut URL used for Siri capture. The same URL for every account.

Terminal window
curl https://neuralrepo.com/api/v1/user/shortcuts \
-H "X-API-Key: nrp_YOUR_KEY"

Response 200 OK

{
"quick_capture_url": "https://www.icloud.com/shortcuts/..."
}

GET /api/v1/user/support-link

Mints a single-use, pre-authenticated URL into the NeuralRepo support site for the account’s email address, so you arrive already signed in.

Response 200 OK

{
"url": "https://support.neuralrepo.com/..."
}

Returns 502 { "error": "Failed to generate support link" } if the support service is unreachable. Treat the URL as a credential — anyone holding it is signed in as you.

POST /api/v1/user/test-digest

Sends the weekly digest email to your own address immediately, and returns the rendered content so you can preview it without waiting for Sunday.

Terminal window
curl -X POST https://neuralrepo.com/api/v1/user/test-digest \
-H "X-API-Key: nrp_YOUR_KEY"

Response 200 OK

{
"success": true,
"content": "..."
}

If sending fails, the endpoint returns 500 with the underlying error message.

settings_json is a JSON string on the profile. Values outside the stated ranges are discarded when the settings are parsed, and the default applies instead — nothing reports the mistake.

FieldTypeRangeDefaultDescription
preferred_ai_providerstringanthropic, openai, openrouter—Provider for develop, if a key for it is stored
search_thresholdnumber0.1–0.90.2Semantic results must score above this
dedup_thresholdnumber0.1–0.90.75Score above which a pair is flagged as a duplicate
related_thresholdnumber0.1–0.90.55Score above which a related edge is created automatically
code_modeboolean——Exposes the MCP code-mode tool surface
weekly_digestboolean—opted inOnly an explicit false stops the Sunday digest
stale_nudgesboolean—opted inOnly an explicit false stops stale-idea nudge emails
stale_threshold_daysinteger7–18030Days before a captured idea counts as stale

Export is available on every plan, and all three endpoints are POST with no body. Each covers up to 10,000 ideas and excludes archived ideas — export before you archive, not after.

POST /api/v1/user/export

The complete dump: profile, ideas with their tags, links, and relations, plus the tag list with counts. Returned as a JSON body (not a file download), stamped with exported_at.

Terminal window
curl -X POST https://neuralrepo.com/api/v1/user/export \
-H "X-API-Key: nrp_YOUR_KEY" \
-o export.json

POST /api/v1/user/export/csv

A flat table for spreadsheets: id, number, title, body, status, tags (semicolon separated), source, created_at. Sent as a UTF-8 BOM’d text/csv attachment named neuralrepo-ideas-YYYY-MM-DD.csv. Relations and links are not included.

Terminal window
curl -X POST https://neuralrepo.com/api/v1/user/export/csv \
-H "X-API-Key: nrp_YOUR_KEY" \
-o export.csv

POST /api/v1/user/export/markdown

A ZIP of one Markdown file per idea, named NNNN-slug.md from the idea’s display number and title. Each file carries YAML frontmatter (number, title, status, source, tags, created, updated), the body, a Links section, and a Related section where relations become [[wiki-links]] — so an Obsidian vault reproduces your mind map graph.

Terminal window
curl -X POST https://neuralrepo.com/api/v1/user/export/markdown \
-H "X-API-Key: nrp_YOUR_KEY" \
-o neuralrepo-markdown.zip

The personal idea+<token>@neuralrepo.com address that email capture delivers to. These routes work on every plan, but mail is captured only on Pro.

EndpointDoes
GET /api/v1/user/email-captureReturns your address, creating it on the first call
POST /api/v1/user/email-capture/rotateReplaces the address. The old one is rejected from then on
PUT /api/v1/user/email-capture/bare-addressBody { "opt_in": true } or { "opt_in": false }: opts in to, or out of, the shared idea@ address until the cut-off

All three return the same shape:

{
"address": "idea+3f9c0a1b2c3d4e5f6a7b8c9d@neuralrepo.com",
"bare_address": "idea@neuralrepo.com",
"bare_address_opt_in": false,
"bare_address_open": true,
"bare_address_sunset": "2026-10-24T00:00:00Z"
}
FieldMeaning
addressYour personal capture address. Treat it as a secret: anyone who has it can add ideas to your repo
bare_address_opt_inWhether mail from your account email to idea@ is still captured
bare_address_openfalse once bare_address_sunset has passed; after that idea@ rejects everything
bare_address_sunsetWhen the shared address stops capturing

PUT /bare-address returns 400 opt_in (boolean) is required for a missing or non-boolean opt_in, and 409 The shared address has been retired; use your personal capture address for opt_in: true after the cut-off. Opting out always works.

DELETE /api/v1/user/me

Deletes the account and everything it owns. Delete Data lists what is removed, what is kept, and what is out of reach. Web session only: an API key or MCP token gets 403.

Request body:

{ "confirm_email": "you@example.com" }

confirm_email must match the account’s email, ignoring letter case and surrounding spaces.

Response 200 OK: { "success": true, ... }, with counts of what was deleted (rows, vectors_deleted, kv_keys_deleted), whether a subscription was canceled (subscription_canceled), and the out_of_reach list. The session cookie is cleared.

StatusBody error
400confirm_email is required, or The email you typed does not match your account
403Sign in on the web to delete your account, or The admin account cannot be deleted here
404User not found
502Account deletion did not finish. You are still signed in; try again to complete it. Nothing past the failed step was deleted, and a retry continues
StatusMeaning
200 OKSuccessful read, update, delete, account deletion, or export
201 CreatedAPI key created
400 Bad RequestValidation error, or an unknown BYOK provider
401 UnauthorizedMissing or invalid auth
403 ForbiddenPro-only endpoint on a Free plan (pro_required: true), or account deletion without a web session or on the admin account
404 Not FoundAPI key id not yours, or the user record is missing
409 ConflictOpting in to the shared idea@ address after its cut-off
500 Internal Server Errortest-digest failed to send
502 Bad GatewayThe support service could not mint a link, or account deletion did not finish