The Snoowl Answers API lets your own chatbot, app or help desk tool ask your assistant questions. Each call answers from the assistant’s documents, with the same settings as the website widget and the Playground.
The assistant’s Endpoint section shows this address, your keys, and copy-ready code in curl, JavaScript, Python and the OpenAI SDK.
Endpoints
Section titled “Endpoints”| Endpoint | What it does | Keys it accepts |
|---|---|---|
POST /answer | Answers one question, with the conversation so far | Secret, website, preview |
POST /chat/completions | The same, in the OpenAI chat completions format, with streaming | Secret |
POST /feedback | Records a thumbs up or down on an answer | Secret, website, preview |
GET /widget | Returns the website widget’s look | Secret, website, preview |
GET /models | Lists the model name, for OpenAI clients that ask | Secret |
Use POST /answer if you’re writing your own integration. Use POST /chat/completions if your chatbot already speaks the OpenAI format: change its base URL and key, and it works.
Authentication
Section titled “Authentication”Send a key in the Authorization header on every request:
The header must be exactly Bearer, a space, and the key. A missing or malformed header gets a 401.
Each key belongs to one assistant. The key decides which assistant answers, so there is no assistant ID in the URL or the body.
There are three kinds of key. You can tell them apart by how they start.
| Secret key | Website key | Preview key | |
|---|---|---|---|
| Starts with | ansk_ | ansp_ | ansv_ |
| For | Your server | The website widget | Trying the widget on your site |
| Made in | Endpoint › New key | Widget › Create website key | Widget › Try on your site |
| Endpoints | All five | /answer, /feedback, /widget | /answer, /feedback, /widget |
| Websites | Optional list. Requests without an Origin header, such as calls from a server, always pass. | Required list. Requests must come from a browser on a listed site. | Any website |
| Lasts | Until revoked | Until revoked | 24 hours |
| Default limits | 60 a minute, no monthly cap | 60 a minute, no monthly cap | 20 a minute, 100 answers in all |
A website or preview key used on /chat/completions or /models gets a 403.
Create a secret key
Section titled “Create a secret key”- In the assistant’s Endpoint section, select New key.
- Give the key a Name, such as “Help-centre bot”. Use one key for each place that calls the assistant, so each can have its own limits and be revoked on its own.
- Leave Allowed websites empty for a key your server uses. Fill it only for a key used from a browser.
- Set Per minute and, if you want one, a Monthly cap.
- Select Create key, then copy the key from Copy your key now.
An assistant can have up to 10 keys at a time, secret and website keys together. Preview keys don’t count.
Allowed websites
Section titled “Allowed websites”A key’s websites are matched against the browser’s Origin header. Each entry is an address like https://www.example.com: exact, without a path or wildcards, ignoring case and a trailing slash. Entries must start with https://, apart from http://localhost addresses for testing, and a key can list up to 20.
A request from a browser on a site that isn’t listed gets a 403. A website key also refuses requests that carry no Origin header. The website list stops other people’s web pages from using your key. It doesn’t stop a server, which can send any header it likes, so a monthly cap is your real ceiling on a website key.
Change or revoke a key
Section titled “Change or revoke a key”Select Limits on a key in Endpoint to change its websites, its per-minute limit or its monthly cap. A key’s name and kind can’t be changed.
Select Revoke to stop a key. Anything using the key stops getting answers on its next request. Revoking can’t be undone.
Rate limits and monthly caps
Section titled “Rate limits and monthly caps”Every key has two limits, checked on /answer and /chat/completions:
- Per minute: answers in each clock minute (UTC), from 1 to 600. The count resets at the start of each minute; it isn’t a rolling 60 seconds.
- Monthly cap: answers in each calendar month (UTC). Optional.
Going over either one gets a 429. The response carries no Retry-After header: wait for the next minute, or the next month for a cap, or raise the limit in Endpoint.
A request counts toward the limits once its key and your balance pass, before the question itself is checked. A request that then fails, for example with a 400 for an empty question or a 503, still counts, and so does a request refused with a 429.
/feedback, /widget and /models aren’t limited and aren’t charged.
Balance
Section titled “Balance”If your workspace pays from a prepaid balance and the balance is used up, /answer and /chat/completions return a 402 until funds are added. Accounts billed by invoice never get a 402. See Billing.
Errors
Section titled “Errors”Errors come back as JSON in the shape OpenAI’s API uses, so OpenAI SDKs raise them as normal errors:
code is the HTTP status as a number. message is written to be shown to a person.
| Status | type | When | message |
|---|---|---|---|
400 | invalid_request_error | The question is empty | Ask a question |
400 | invalid_request_error | The question is over 2,000 characters | Keep questions under 2000 characters |
400 | invalid_request_error | /chat/completions with no user message | Send at least one user message |
400 | invalid_request_error | /feedback with helpful that isn’t true or false | Send helpful: true or false |
401 | authentication_error | The header is missing or malformed, or the token isn’t a key | Send your endpoint key as Authorization: Bearer ansk_… |
401 | authentication_error | The key is unknown or revoked | This endpoint key isn’t valid, or it was revoked |
401 | authentication_error | A preview key is over 24 hours old | This preview expired — make a new one in the Widget tab |
401 | authentication_error | The workspace was deleted | This workspace was deleted |
402 | insufficient_quota | The prepaid balance is used up | The workspace’s balance is used up. Add funds in Billing to keep answering. |
403 | authentication_error | A website key on an endpoint it can’t call | A widget key can’t call this. Use a secret key from your server. |
403 | authentication_error | A preview key on an endpoint it can’t call | A preview key only shows the widget. Use a secret key from your server. |
403 | authentication_error | A website key without an Origin header | A widget key works only from its websites |
403 | authentication_error | A browser on a site not on the key’s list | This key isn’t allowed from this website |
404 | invalid_request_error | /feedback for an unknown answer, or one past its retention | No such answer (or it’s past this assistant’s log retention) |
429 | rate_limit_error | Over the key’s per-minute limit | Too many questions this minute for this key. Slow down, or raise its limit. |
429 | rate_limit_error | Over the key’s monthly cap | This key reached its monthly cap. Raise it in the console to keep answering. |
503 | server_error | The answer couldn’t be written, for example during a model outage | The assistant couldn’t answer just now. Try again. |
Two errors don’t use this shape:
- An unexpected server error returns
500with{"detail": "Something went wrong on our side. We've been told and will look into it."}. - A request body that isn’t a JSON object gets a
422with adetailfield describing the problem.
Retry 503 and 500 after a short wait. Don’t retry 4xx errors unchanged.
Request IDs
Section titled “Request IDs”Every response has an X-Request-ID header with a unique ID for that request. If you contact support about a failed request, include its ID.
Calling from a browser
Section titled “Calling from a browser”The API accepts cross-origin requests from any website, with the GET, POST and OPTIONS methods and the Authorization and Content-Type headers. X-Request-ID is readable from the browser. Whether a key works from a given site is up to the key’s websites. For a chat on your own website, the website widget already does all of this.