Skip to main content
Base URL https://api.neuroencoder.com/v1. Auth Authorization: Bearer <key>. OpenAPI: /v1/openapi.json. Responses are deterministic and nothing is stored.

POST /v1/embeddings

One 768-d embedding per 30 s window. Multipart: file (EDF, BDF, FIF, SET, VHDR, or NPY [channels, samples]), optional metadata JSON with the fields below (sfreq and channel_names are required for NPY). JSON:
array | string
required
[channels, samples] list, or base64 little-endian float32 with shape.
number
required
Sampling rate in Hz.
string[]
10-20 labels, one per channel. Unmatched channels are dropped; missing regions zero-filled. Required unless the data already has the 8 regional channels.
number
default:"1.0"
Hop between 30 s windows. Use 30 for non-overlapping epochs.
boolean
default:"true"
1-100 Hz bandpass and 50/100 Hz notch before resampling to 250 Hz.
string
default:"float"
float or base64 (float32, 4x smaller).
string
default:"epi-300k"
Only epi-300k today.
Response:

Keys

Keys look like ne_live_ followed by 48 characters (the last 6 are a checksum, so a mistyped key is rejected before any lookup). They are shown once and stored only as a keyed hash. Each key has a tier with a per-minute rate limit and a monthly quota in hours of EEG, an optional expiry, and scopes.

POST /v1/signup

Sends a single-use link (valid 30 minutes) to that address. The link opens a page with one button; pressing it (a POST /v1/verify with the token) returns the key once, plus the tier and limits. Agents can skip the page and POST /v1/verify with {"t": "<token from the email>"} directly. Three signups per address or IP per day; disposable domains are refused. Collaboration and paid keys are issued by hand through the contact form.

GET /v1/me

Your key’s tier, limits and this month’s usage: {"tier": "trial", "rate_per_min": 30, "quota_seconds_month": 360000, "usage": {"seconds_of_eeg": 1234.5, "requests": 12}}.

Headers and errors

Every response carries x-request-id, x-ratelimit-limit-requests, x-ratelimit-remaining-requests and x-ratelimit-reset-requests. A 429 carries Retry-After and one of the codes rate_limit_exceeded or quota_exceeded; 401 means the key is missing, malformed, revoked or expired (the fix field says which); 403 insufficient_scope. If a key leaks, tell us or ask for a roll: the new key is issued immediately and the old one keeps working for 12 hours.

GET /v1/models

Lists epi-300k with its dimensions (768), window (30 s) and sample rate (250 Hz).

Limits

Per-key requests per minute by tier, 512 MB per upload, 48 h of EEG per request and 384 channel-hours per request (for example 19 channels for 20 h). Uploads need a Content-Length header. Accepted files: EDF, BDF, FIF, NPY. 429 responses carry Retry-After.

Python client

embeddings uses the hosted API when NEUROENCODER_API_KEY is set and local weights otherwise (NEUROENCODER_WEIGHTS or ~/.cache/neuroencoder/epi300k.pt). Errors raise AuthenticationError, RateLimitError or APIStatusError, each with .status, .code, .param and .fix. Connection errors and 429/502/503 are retried twice with backoff.