Quickstart
This guide takes you from nothing to a working integration in five minutes: you create an API key, check it, add a document to the knowledge base, find it and ask a question about it. Every step is one HTTP request. Pick your language once in any example; every example on the page switches with it.
The examples with a language switcher use the API address of this portal: https://api.sursa.com in the Sursa cloud,
or the API address of your own installation. Where an example shows https://api.example.com, put your API address
in its place. See API address and environments if you are not sure which one
you have.
1. Create an API key
An organization administrator creates keys in Sursa under Administration → API keys. Give the key a name that says where
it is used (for example "CRM sync"), choose its role and, if you want to narrow it further, its scopes. The key can
do what a user with that role can do, and no more than its scopes allow. For this guide, the editor role is enough.
The key is shown once. Keep it in the secret store of your system and pass it to your code in an environment variable:
export SURSA_API_KEY="kb_…"
Every request sends the key in the Authorization header as a bearer token. API keys and
scopes explains roles, scopes, expiry and rotation.
2. Set up a client
No library is needed: the API is plain HTTPS and JSON. The examples in this guide use a small helper in each language. Copy the one for your language; later guides use the same helper. The official client libraries are listed under SDKs.
# cURL needs no setup: each example below is a complete command.
export SURSA_API="https://api.example.com"3. Check the key
GET /v1/me describes the caller: the organization, the key, its role and scopes, and the
rate limit that applies to it. It works with any valid key, so it is the best first request of every integration.
curl https://api.example.com/v1/me \
-H "Authorization: Bearer $SURSA_API_KEY"{
"principal": "api_key",
"org": {"id": 1, "slug": "acme", "name": "Acme"},
"key": {"id": 42, "name": "CRM sync", "prefix": "kb_3f9c", "role": "editor"},
"user": null,
"role": "editor",
"scopes": ["cards:read", "cards:write", "search", "ask"],
"data_profile": null,
"expires_at": null,
"rate_limit": {"class": "standard", "requests_per_second": 20, "burst": 100}
}
A 401 with the code auth.not_authenticated means the key is missing, revoked
or mistyped; api_keys.expired means it has expired.
4. Find a collection
Cards live in collections. GET /v1/collections lists the collections
your key can see:
curl https://api.example.com/v1/collections \
-H "Authorization: Bearer $SURSA_API_KEY"Note the id and the name of the collection you want to work with. The examples below use the collection 3,
named support.
5. Add a document
PUT /v1/cards-by-external-id/{external_id} creates a card under
your own ID, or replaces it if the card already exists. Running the request twice is safe: the second time the
content has not changed, and the answer is skipped with the reason unchanged. Use the ID of the record in your
system as external_id.
curl -X PUT https://api.example.com/v1/cards-by-external-id/policy-refunds \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"collection_id": 3,
"title": "Refund policy",
"content_type": "markdown",
"body": "# Refund policy\n\nRefunds are processed within 14 days of the request."
}'The request returns when the card is ready to be found: 201 with "status": "ready" for a new card, 200 for a
replaced one. HTML and plain text work the same way with "content_type": "html" or "text". Files (PDF, Word,
Excel and others) go through the same endpoint as multipart/form-data; Import documents
covers files, folders, metadata and imports of many documents.
6. Search
POST /v1/search finds the passages of cards that match a query, best match first:
curl -X POST https://api.example.com/v1/search \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "refund policy", "collection": "support"}'collection takes the name of the collection. Without it, search covers the collection named default.
7. Ask a question
POST /v1/ask answers a question in plain language and returns the sources of the answer.
The assistant finds the relevant knowledge and answers only from cards the key is allowed to read.
curl -X POST https://api.example.com/v1/ask \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "How long does a refund take?", "collection": "support"}'When nothing relevant is found, the response is still 200, with "empty": "no_hits" and a short explanation in
answer. Your code decides what to show the user in that case.
Next steps
- Build a Q&A bot: stream answers as they are written and resume a dropped stream.
- Import documents or sync your system to keep the knowledge base up to date.
- Receive webhooks to react to changes in Sursa.
- Handle errors by their code, retry writes with an Idempotency-Key, and respect rate limits.
- Browse the API reference for every endpoint, object and field.