Skip to main content
This page is for the developer who writes the client. After you read it, you know which requests are safe to send again, how long to wait for each call, how to format times, how to test, and how versions work.

Where calls come from

Priors is called from your backend, with an API key. A browser must never hold one: Priors sends no CORS headers, and a request that carries a key and a Sec-Fetch-Site header is refused with 400. Add X-SP-End-User to act for one named person on your side. See Authentication, and Call Priors from your backend for the whole integration.

When you can send a request again

The table below says, for each call, whether it is safe to send the same request a second time. For 5xx and 429: wait Retry-After seconds when the header is present. Otherwise wait one second, and double the wait after each failure. Stop after five tries. Never send a 4xx request again without a change, except 429. Two 503 messages need their own handling:
  • “Agent runtime is recovering” and “This thread is temporarily unavailable” mean the agent is being restored after a restart. Every call on that agent returns this for a few seconds, then works again.
  • “Could not persist” on a create or an observe means nothing was written. Sending the request again is safe.

The order of learning

Observations in one thread are learned in the order Priors received them. Inside one call, the order of the array is kept. Two calls that arrive at the same time have no defined order between them. To keep a strict order, wait for the 202 of each call before you send the next, or send everything in one call.

Timeouts

The table below suggests a timeout for each call in your client. A request that times out on your side can still have run. Follow the table in the previous section.

Time and text

  • Every timestamp uses the RFC 3339 format in UTC, for example 2026-09-17T10:07:00Z. Send the same format.
  • Text is UTF-8, in any language. For billing, Priors counts words by splitting on spaces.
  • Ids are strings without meaning. Do not parse them. Compare them exactly.

Reading a thread

GET .../threads/{thread_id} returns up to the 200 most recent messages. Older messages cannot be read through the API. The memory learned from them is not affected. Keep your own copy if you need the full conversation.

Errors

400 and 422 both have code: invalid_request. Handle them in the same way: read error, correct the request. Every error has a request_id. Write it to your logs. Send it to us when you report a problem.

Testing

There is no test environment. Test with an agent that you create for the test: create it with a role that marks it as a test, run your calls, then delete it. Every call is real and is charged at the normal price. A test agent counts against your 100. A test that sends 100 short observations and asks 10 questions costs about 15 credits.

Client code

There is no official SDK, and you do not need one. Both headers are literal strings: there is no signing, no HMAC, no timestamp, and no nonce, so there is nothing for a client library to compute and no clock skew to handle. https://www.sapientpriors.com/docs/openapi.yaml is a complete OpenAPI 3.0 document. Any generator produces a typed client in your language with both headers already wired up, or you can call the endpoints directly. Every reference page has examples in curl, Python, and JavaScript.

Versioning

Every path starts with /v1. Inside /v1, changes only add things: new fields and new endpoints appear, and existing ones keep their meaning. Ignore a field you do not know. A change that breaks existing clients ships under a new version prefix, and we announce it before it ships.

Support

Write to us with the request_id of the failed call, the endpoint, and the time in UTC.