Managed AI support for websites, apps, portals, CRM, ERP, and WordPress
Developers

Your content, your AI,
anywhere you need it.

The AskCybex API is OpenAI-compatible. Anything already built for that format works by changing a base URL and a key — no SDK, no rewrite. Connect a CMS, a custom web app, an internal tool, an ERP or a mobile app to a chatbot trained on your own documents.

Base URL https://www.askcybex.com Auth Bearer API key Format JSON & SSE

1 Get your API key

An API key maps to exactly one deployment — one chatbot trained on one set of documents. The key alone decides which documents an answer can come from, so you never pass a deployment id separately.

  1. Create a deployment and train it In your dashboard go to Document Training, create a deployment, upload your files (PDF, DOCX, TXT, CSV) and click Train. Wait for the status to reach Completed.
  2. Open the API key page Go to API key in the sidebar, or click here if you're signed in.
  3. Generate a key for that deployment Each deployment gets its own key. Copy it immediately — it is stored hashed, so it cannot be shown again. If you lose it, delete the key and generate a new one.
  4. Keep it server-side where you can A key spends your token balance. Our chat widget uses it in the browser by necessity — if you do the same, restrict the deployment by IP in Settings → IP Restriction and watch usage under Reports.
No account yet? Create one free — you get tokens to test with, and you only pay for what you use after that.

2 Authentication

Send your key whichever way suits the client. All three are equivalent:

Authorization: Bearer YOUR_API_KEY     # preferred, used by /api/v1/*
X-API-KEY: YOUR_API_KEY                # header alternative
?api_key=YOUR_API_KEY                  # query/form field — required for SSE,
                                       # because EventSource cannot set headers

Keys are stored as SHA-256 hashes. An invalid or disabled key, or a deployment that is not published, returns 401.

3 Quickstart

Ask your first question in one request. Pick a language:

curl https://askcybex.com/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "YOUR_DEPLOYMENT_ID",
    "messages": [
      { "role": "user", "content": "What is your refund policy?" }
    ]
  }'
// Works with the official OpenAI SDK — only the baseURL changes.
import OpenAI from "openai";

const client = new OpenAI({
  apiKey:  "YOUR_API_KEY",
  baseURL: "https://askcybex.com/api/v1",
});

const res = await client.chat.completions.create({
  model: "YOUR_DEPLOYMENT_ID",
  messages: [{ role: "user", content: "What is your refund policy?" }],
});

console.log(res.choices[0].message.content);
# pip install openai
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://askcybex.com/api/v1",
)

res = client.chat.completions.create(
    model="YOUR_DEPLOYMENT_ID",
    messages=[{"role": "user", "content": "What is your refund policy?"}],
)

print(res.choices[0].message.content)
$ch = curl_init('https://askcybex.com/api/chat/');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POSTFIELDS     => http_build_query([
        'api_key'         => 'YOUR_API_KEY',
        'msg'             => 'What is your refund policy?',
        'conversation_id' => 'visitor-123',
    ]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $data['response'] ?? $data['error'];

Multi-turn conversations

Follow-up questions need the earlier turns. Pick one of two styles — don't mix them.

Watch the field you copy. Every response contains two ids: id starts with chatcmpl- and identifies that single completion. conversation_id starts with conv- and identifies the thread. Only conversation_id continues a conversation — passing the chatcmpl- id starts a brand new, empty thread, and the bot will appear to have forgotten everything.

Style A — resend the messages (OpenAI-native). Stateless, and what the OpenAI SDKs and Open WebUI do automatically:

{
  "model": "98",
  "messages": [
    { "role": "user",      "content": "What is Hogwarts?" },
    { "role": "assistant", "content": "Hogwarts is a school of witchcraft and wizardry..." },
    { "role": "user",      "content": "Who are the students there?" }
  ]
}

Style B — reuse the conversation id. Send only the new question; we rebuild the history server-side:

# Turn 1 — no id sent, so one is minted and returned
curl -X POST https://askcybex.com/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"98","messages":[{"role":"user","content":"What is Hogwarts?"}]}'

# response contains BOTH ids — copy the conv- one:
#   "id":              "chatcmpl-f616e6134ae341316ba712a9"   <- NOT this
#   "conversation_id": "conv-dc4d05c139d35b910ff4be69"       <- this one

# Turn 2 — reuse conversation_id, send only the new question
curl -X POST https://askcybex.com/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"98",
       "messages":[{"role":"user","content":"Who are the students there?"}],
       "conversation_id":"conv-dc4d05c139d35b910ff4be69"}'

If you send both, the messages history wins, so a turn is never counted twice. Both styles work identically on /chat/completions-with-sources.

Follow-ups that lean on context need the contextual endpoint. On /chat/completions and /chat/completions-with-sources the document search uses your question exactly as typed — history reaches the model that writes the answer, but not the search. So “and who are they?” searches for those literal words and usually finds nothing.

Two ways to fix it: keep the subject in the question (“who are the students at Hogwarts?”), or send the turn to /api/v1/chat/completions-contextual, which resolves the follow-up against the conversation before searching and tells you what it searched for.

4 Endpoint reference

Two families. Use /api/v1 when you want drop-in OpenAI compatibility, and the native endpoints when you want streaming, FAQ data or feedback.

OpenAI-compatible

GET/api/v1/models

Returns the deployment your key maps to, as an OpenAI model object. Clients such as Open WebUI call this to fill their model picker. The id it returns is what you pass as model.

POST/api/v1/chat/completions

Answers the last user message from your documents, in the standard ChatCompletion shape. Earlier messages are used as history. Supports stream, temperature and max_tokens.

POST/api/v1/chat/completions-with-sources citations

Identical, plus a sources array naming the documents behind the answer. Use it when you must show citations or audit where an answer came from.

POST/api/v1/chat/completions-contextual best for multi-turn

Searches your documents with a history-aware query. The other endpoints search using the question exactly as typed, so a follow-up like “who are the students there?” is searched literally and usually matches nothing. This one resolves it to “who are the students at Hogwarts?” first, searches with that, then answers in your original wording. Returns search_query so you can see what was searched, plus the same sources as above.

The retrieved passages (chunks) are opt-in here — send "include_chunks": true if you need them. They are verbatim text from your documents and can add tens of KB to every turn, so a chat UI that only shows document names should leave them off.

Costs one extra small model call per turn, and only when there is history to resolve — a first question costs the same as the others.

Native REST

POST/api/chat/ 60 / min

Send a message, get the full answer. Pass the same conversation_id on every turn so follow-ups like “how much does that cost?” resolve correctly. Returns chat_log_id, which you use to attach feedback.

api_keyrequired — your deployment key
msgrequired — the visitor question
conversation_idthread id, reused across turns
visitor_emailcaptured lead email, stored on the log
GET/api/stream/ SSE60 / min

The same answer, streamed token by token over Server-Sent Events so it appears as it is written. The key goes in the query string because EventSource cannot set headers.

const es = new EventSource(
  "https://askcybex.com/api/stream/?api_key=YOUR_API_KEY" +
  "&msg=" + encodeURIComponent(question) +
  "&conversation_id=" + conversationId
);

es.onmessage = (e) => {
  const d = JSON.parse(e.data);
  if (d.token) output.textContent += d.token;   // stream in
  if (d.error) console.error(d.error);
  if (d.done)  { es.close(); rate(d.chat_log_id); }
};
POST/api/faq/details/ 120 / min

Returns the deployment name and any pre-generated question/answer pairs — handy for rendering an FAQ block or suggesting questions before the visitor types.

POST/api/feedback/ 120 / min

Record whether an answer helped. Send chat_log_id and feedback (1 = helpful, 0 = not). Ratings show up in your dashboard next to the question that produced them.

5 Use it inside tools you already run

Because the API speaks the OpenAI format, most AI tooling connects without any code. For Open WebUI:

  1. Settings → Connections → OpenAI APIAdd a new connection.
  2. Base URLhttps://www.askcybex.com/api/v1
  3. API keyYour deployment key.
  4. Save, then pick your deployment from the model listIt appears by deployment id.

The same pattern works for LangChain, LlamaIndex, agent frameworks, ERP and CRM add-ons, and any internal tool that lets you set an OpenAI base URL.

6 Rate limits, errors & billing

EndpointLimit
/api/chat/, /api/stream/, /api/v1/chat/*60 requests / minute
/api/faq/details/, /api/feedback/, /api/openapi.json120 requests / minute

Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. Exceeding a limit returns 429.

StatusMeaningWhat to do
401Invalid or disabled key, or the deployment isn't publishedCheck the key; publish the deployment
402Token balance exhaustedTop up your balance
404Deployment not foundConfirm the key belongs to a trained deployment
429Rate limitedBack off and retry
One behaviour worth knowing. /api/chat/ and /api/faq/details/ answer HTTP 200 with an error field rather than an error status — the WordPress plugins have relied on that since launch and we will not break it. Always check for an error key, not just the status code. The /api/v1 endpoints use proper status codes.

Billing. Answers consume tokens from your account balance. When a question cannot be grounded in your documents, the refusal is returned before the language model is called — so a “Sorry, I don’t know” costs you nothing.

Try every endpoint in the browser

The explorer is loaded with the live spec. Click Authorize, paste your key, and send real requests against your own deployment.

© 2024 AskCybex. All rights reserved.