400, 401, and 404 mean.
Every request carries an API key, and the key identifies your organization, not a person. Your organization owns the agents, holds the credit, and is billed.
Get a key
An administrator of your organization mints a key in the Priors application, under Settings → API keys. There is no endpoint for it. A key reaches your whole organization, so issuing one is an act of administration, and a key that could mint another key would turn one leak into an unbounded supply. The key looks like this:Keys expire
Every key is issued with a deadline, and today that is one year. A key stops verifying the moment it passes, and nothing reaches your backend to say so. An expired key returns the same401 as an unknown one, so the first sign of a missed rotation is your own traffic failing.
Settings → API keys shows the expiry date of every key, and marks a key as expiring for the last month before its date. That page is the only warning there is. Read the date when you store the secret, and put the rotation in your calendar then.
Name one of your customers
X-SP-End-User is your own identifier for the person a request acts for: an account number, a row id, anything stable on your side. Priors does not store the value. It hashes the value together with your organization id, so two clients that send the same string are still two different people.
The last row is deliberate. “No header” means your whole organization, which is the widest reach a key has. An unmapped customer that renders as
"" must not quietly be answered with more access than you asked for.
Learned memory is shared across an agent either way. Only the thread list narrows.
Send the header on every call for that person, not only when you create the thread. It also decides which rate-limit window the call spends from. See Limits.
Keep the key on your server
A key belongs on your backend. It must never reach a browser or a mobile app. A key in front-end code is in your bundle, and anyone who loads the page can read it, whether or not the request itself succeeds. Two things stop that happening by accident:- Priors sends no CORS headers, so a browser blocks the call before it leaves the page.
- A request that carries a key and a
Sec-Fetch-Siteheader is refused with400. Only a browser sets that header, and page JavaScript can neither remove it nor forge it.
Origin or Referer. Gateways add Origin to ordinary server-to-server calls, and HTTP libraries add Referer across redirects. If your own infrastructure adds either header, nothing here minds.
If you need your own front end to call Priors directly, contact us before you build around it.
Ownership
Every agent, thread, observation, and file belongs to the organization that created it. No other organization can see it. When another caller asks for one of your ids, Priors returns404, not 403. An id never reveals that something exists.
X-SP-End-User only ever narrows that. It never widens it.
Errors
Check what your key resolves to
GET /v1/session confirms which organization your key resolves to, and returns the upload limits your organization is held to.
user.id is your organization when you send no X-SP-End-User, and the derived eu_… id for that person when you do. email is empty and display_name reads partner key, because a key names no person.
Read the max_* fields once when your client starts, and check a file against them before you upload it, rather than hardcoding the numbers.