Skip to content

API overview

6 min read

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.

https://answers.snoowl.com/api/v1

The assistant’s Endpoint section shows this address, your keys, and copy-ready code in curl, JavaScript, Python and the OpenAI SDK.

EndpointWhat it doesKeys it accepts
POST /answerAnswers one question, with the conversation so farSecret, website, preview
POST /chat/completionsThe same, in the OpenAI chat completions format, with streamingSecret
POST /feedbackRecords a thumbs up or down on an answerSecret, website, preview
GET /widgetReturns the website widget’s lookSecret, website, preview
GET /modelsLists the model name, for OpenAI clients that askSecret

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.

Send a key in the Authorization header on every request:

Authorization: Bearer ansk_…

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 keyWebsite keyPreview key
Starts withansk_ansp_ansv_
ForYour serverThe website widgetTrying the widget on your site
Made inEndpoint › New keyWidget › Create website keyWidget › Try on your site
EndpointsAll five/answer, /feedback, /widget/answer, /feedback, /widget
WebsitesOptional 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
LastsUntil revokedUntil revoked24 hours
Default limits60 a minute, no monthly cap60 a minute, no monthly cap20 a minute, 100 answers in all

A website or preview key used on /chat/completions or /models gets a 403.

  1. In the assistant’s Endpoint section, select New key.
  2. 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.
  3. Leave Allowed websites empty for a key your server uses. Fill it only for a key used from a browser.
  4. Set Per minute and, if you want one, a Monthly cap.
  5. 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.

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.

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.

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.

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 come back as JSON in the shape OpenAI’s API uses, so OpenAI SDKs raise them as normal errors:

{
  "error": {
    "message": "Too many questions this minute for this key. Slow down, or raise its limit.",
    "type": "rate_limit_error",
    "code": 429
  }
}

code is the HTTP status as a number. message is written to be shown to a person.

StatustypeWhenmessage
400invalid_request_errorThe question is emptyAsk a question
400invalid_request_errorThe question is over 2,000 charactersKeep questions under 2000 characters
400invalid_request_error/chat/completions with no user messageSend at least one user message
400invalid_request_error/feedback with helpful that isn’t true or falseSend helpful: true or false
401authentication_errorThe header is missing or malformed, or the token isn’t a keySend your endpoint key as Authorization: Bearer ansk_…
401authentication_errorThe key is unknown or revokedThis endpoint key isn’t valid, or it was revoked
401authentication_errorA preview key is over 24 hours oldThis preview expired — make a new one in the Widget tab
401authentication_errorThe workspace was deletedThis workspace was deleted
402insufficient_quotaThe prepaid balance is used upThe workspace’s balance is used up. Add funds in Billing to keep answering.
403authentication_errorA website key on an endpoint it can’t callA widget key can’t call this. Use a secret key from your server.
403authentication_errorA preview key on an endpoint it can’t callA preview key only shows the widget. Use a secret key from your server.
403authentication_errorA website key without an Origin headerA widget key works only from its websites
403authentication_errorA browser on a site not on the key’s listThis key isn’t allowed from this website
404invalid_request_error/feedback for an unknown answer, or one past its retentionNo such answer (or it’s past this assistant’s log retention)
429rate_limit_errorOver the key’s per-minute limitToo many questions this minute for this key. Slow down, or raise its limit.
429rate_limit_errorOver the key’s monthly capThis key reached its monthly cap. Raise it in the console to keep answering.
503server_errorThe answer couldn’t be written, for example during a model outageThe assistant couldn’t answer just now. Try again.

Two errors don’t use this shape:

  • An unexpected server error returns 500 with {"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 422 with a detail field describing the problem.

Retry 503 and 500 after a short wait. Don’t retry 4xx errors unchanged.

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.

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.