Knowledge and vector search
Ingest documents, build knowledge collections and query them by meaning.
Overview
Knowledge and vector search keeps your organization's knowledge where an application can ask it questions by meaning. It has three parts, all on https://ai.inovacc.dev:
- the Vector Database: a managed store of text passages you ingest and search, with filters, scopes and optional reranking;
- knowledge collections: send a batch of mixed files (documents, images, video) and get them processed into knowledge packages, then download the result, query it, chat with it with citations, or have a report written over it;
- knowledge jobs: turn a long recording into a knowledge base you download as one archive.
The problem it solves is everything between "we have files" and "the assistant can answer from them": extracting text, cutting it into passages, embedding, indexing, keeping the index consistent, and citing the source of every answer. Inovacc does those steps and you call a handful of endpoints.
Use it when answers must come from your own material. When you already run your own vector index, AI embeddings gives you the vectors alone. When the answer is free text with no sources, use AI chat. Each part is enabled for your organization by Inovacc; a part that is not enabled answers 403 (vector_database_disabled, collections_disabled or knowledge_disabled).
Concepts
Vector Database and its profile. Your organization creates one database with POST /v1/vector/databases, choosing an embedding profile from GET /v1/vector/profiles. A profile states the modality (text), the languages (english or multilingual), the dimensions and the distance metric; ids look like text-multilingual-1024. You choose a profile, never a model. The profile cannot change: to use another, delete the database, create a new one and ingest again.
Documents, scopes and modes. You ingest passages with your own id, their text and optional flat metadata. A passage goes to a scope: shared (every service of your organization's workspace) or local (only the API key that wrote it). Queries take a mode: shared, local, or hybrid to search both and merge by score. Six metadata keys can be filtered on: kind, source, category, tag, language, created_at. Chunks that share a document_id form a document with a generation (your version number), which lets you delete or replace a whole document at once.
Collections and their mode. A collection is created in one of three modes, fixed for its life: download (process files, download the packages, nothing stays afterwards), cloud (Inovacc keeps the processed content and its vectors so you can query, chat and run an analysis) or local_vectors (Inovacc keeps vectors only, never text: you embed your own chunks and query returns chunk ids and scores). Collections are kept 30 days by default; an organization set to zero retention has them deleted one hour after the download starts.
Items. A file joins a collection in the request (up to 16 MiB), from a completed upload (video above 16 MiB), by public URL, or by a signed URL sealed to a single-use key so that it is never stored. Each item goes queued, processing, then done or failed; a failed item does not stop the others.
Eventual consistency and searchable. The vector index applies writes asynchronously: a vector is readable some seconds, sometimes minutes, after it was written. GET /v1/vector/databases and every collection answer report searchable; a query sent while it is false may miss the latest passages. A cloud collection's indexing.complete is true only when every chunk is written and readable.
Jobs, power and budget. A knowledge job takes a completed upload of a recording, an optional transcript and notes, a power (light, medium or max) and a required max_price_usd. A job over your organization's cap is refused before any paid work.
How it works
Every call carries Authorization: Bearer <key>. Your organization comes from the key. X-Operation-Id is required on the collection, upload and job POST calls and makes them idempotent: a retry with the same id returns the first answer (X-Idempotent-Replay: true) and adds nothing; the same id with a different file is 409 operation_id_reused. On the Vector Database it is optional, because ingest and delete are idempotent by construction: ingesting an existing id replaces it.
A query (POST /v1/vector/query) takes mode, query (1 to 8,000 characters), top_k (1 to 50) and an optional filter; it returns matches best first, each with id, score, text and metadata. With "retrieval": "vector_rerank" and a rerank_profile, a wider candidate list is re-ordered by a reranking stage; the answer's retrieval object says whether the rerank applied or fell back to vector order.
A collection works in steps you can observe: create it, add items (202, queued), read it until status is complete, then download, query or chat. Reading a cloud collection also advances its indexing, a bounded amount per call, and every answer carries the indexing progress. chat answers only from the retrieved sources, numbers each citation with the item, package, chunk and locator, and says it cannot answer when the sources do not cover the question. An analysis is built over several requests: repeat POST or GET every few seconds until it answers 200 with the report.
A job is asynchronous: POST /v1/knowledge/jobs answers 202 with job_id, status_url and poll_after_seconds (also as Retry-After). Read the status when told; the platform forecasts the time to done and includes eta_seconds while it can. When state is done, download the archive; it is kept 24 hours.
What is metered: embedding tokens and vectors written for ingest and indexing, queries, reranks as their own unit, chat calls on your chat route, and jobs by their price. POST /v1/knowledge/estimates prices a recording before you upload it, at no cost.
Get started
You need an API key and the part you want enabled for your organization (Authentication).
- Create the database.
GET /v1/vector/profiles, pick a profile, thenPOST /v1/vector/databaseswith{"profile":"<id>"}. The answer is 201 with the database. - Ingest passages.
POST /v1/vector/ingestwith"scope":"shared"and two or three documents (see the samples). The answer says how many wereingestedand lists anyskippedwith a reason. - Wait for
searchable.GET /v1/vector/databasesuntilsearchableistrue. - Query.
POST /v1/vector/querywith"mode":"shared"and a question worded differently from your passages. The closest passage comes first, with itsscore. - Try a collection.
POST /v1/collectionswith{"mode":"cloud"}, add a PDF to/items, read the collection untilindexing.completeistrue, thenPOST /v1/collections/{id}/chatand check thecitations.
Use cases
An assistant grounded in your handbook. Your intranet ingests each policy page as chunks under its document_id, with category metadata. The assistant queries with a category filter and passes the top passages to its own prompt. When a page changes, it is ingested again at a higher generation, and the chunks the new version no longer has stop appearing at once.
Questions over a client's file drop. A consultant creates a cloud collection per engagement, adds the contracts and spreadsheets the client sent, and asks questions through chat. Each answer cites the item and page it rests on, so every statement can be checked before it goes into a report; analysis produces a summary, entities and contradictions across the files.
Meeting recordings to a knowledge base. After each recorded meeting, the app estimates the price, uploads the video in 64 MiB parts with the call's own transcript as a reference, and starts a job with max_price_usd. When the job is done, the archive (audio, key frames and the knowledge base) is filed with the meeting.
Limits and pricing
| Limit | Value |
|---|---|
| Vector Database request body | 1 MiB |
| Documents per ingest, ids per delete | 100 |
One document (id + text + metadata) | 10 KiB |
Query text; top_k | 8,000 characters; 50 |
Filter $in values | 20 |
| Item in a request body, or fetched by URL | 16 MiB |
| Items per collection | 100; 1 GiB of files sent in requests; 20 GiB of video by upload |
Collection query top_k; chat messages | 20; 1 to 20 messages of up to 8,000 characters |
Chunks per embed call | 100, each up to 8,000 characters |
| Analysis model calls per report | 32 |
| Upload part size | 64 MiB (every part but the last) |
| Non-video upload (transcript, notes) | 16 MiB |
| Recording upload | your organization's cap |
| Fetch keys held unused | 16, each valid once for 60 seconds |
| Job result kept | 24 hours |
| Collection retention | 30 days by default |
Pricing: on request. A recording processed by a job is priced in video minutes, and POST /v1/knowledge/estimates returns its price line by line before you upload anything. Chat over a collection is metered as AI chat on your chat route.
Errors
| Status | Code | What it means and what to do |
|---|---|---|
| 400 | invalid_body, unsupported_field | A field or value the route does not accept; check the route's fields. |
| 400 | invalid_profile | Pick a profile listed by GET /v1/vector/profiles. |
| 400 | confirmation_required | Deleting the database needs {"confirm":"delete-database-and-all-vectors"}. |
| 400 | invalid_url, signed_url_must_be_sealed | Only public https URLs on port 443; a signed URL must be sealed. |
| 400 | fetch_key_invalid, invalid_sealed_url | Request a new fetch key and seal again. |
| 403 | vector_database_disabled, collections_disabled, knowledge_disabled | That part is not enabled for your organization. |
| 403 | budget_exceeded | The job's max_price_usd is over your organization's cap. |
| 404 | collection_not_found, job_not_found, upload_not_found, analysis_not_found | Check the id; a job's download is also 404 until it is done. |
| 409 | vector_database_not_created, vector_database_exists, vector_database_deleting | Create the database first; one per organization; wait for a delete to finish. |
| 409 | mode_not_supported | The operation does not exist in this collection's mode. |
| 409 | collection_incomplete, collection_full | Wait for items to finish; the collection is at its limit. |
| 409 | upload_incomplete, operation_id_reused, operation_in_progress | Finish the upload; use a new operation id for a different file; wait. |
| 410 | collection_expired, result_expired | The retention ended; process again. |
| 413 | request_too_large, url_too_large | Use POST /v1/uploads for large files. |
| 415, 422 | unsupported_media_type, input_rejected, archive_rejected | The file type is not read, or the file was refused (reason says why). |
| 429 | too_many_fetch_keys and the quota codes | Use or let expire the keys you hold; see Errors. |
| 502, 504 | url_fetch_failed, url_fetch_timeout, upstream_error, timeout_error | The URL or the processing failed; retry. |
| 503 | service_unavailable | Retry later; nothing was guessed. |
Best practices
- Group chunks under a
document_idand bumpgenerationwhen the source changes; deletion and replacement then work per document. - Send
content_sha256with each chunk and compare it withGET /v1/vector/documentsto resync your copy without re-ingesting everything. - Check
searchable(orindexing.complete) before relying on the newest passages. - Keep the answer of a passage within its first 2,000 characters when you use reranking; only that much is read by the reranker.
- Compare
vector_rerankwith plainvectoron your own data, especially outside English, before relying on it. - Always estimate before a job and set
max_price_usd; poll atpoll_after_seconds, not faster. - Seal signed URLs; never send a URL that carries a login. Upload the bytes instead.
- Check citations: a model can cite a real source for something it does not say.
Related
- AI embeddings, AI chat
- Files: store the source files themselves
- Authentication, Errors, Limits
Authentication
Every call carries your key; your organization comes from it. See the authentication guide.
AuthorizationX-Operation-IdEndpoints
POST /v1/vector/ingest
POST /v1/vector/query
POST /v1/collections
POST /v1/collections/{id}/query
POST /v1/knowledge/jobs
Example
Language
⋮
cURL
curl -X POST "https://ai.inovacc.dev/v1/vector/ingest" \
-H "Authorization: Bearer $INOVACC_API_KEY" \
-H "X-Operation-Id: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}'curl -X POST "https://ai.inovacc.dev/v1/vector/ingest" \
-H "Authorization: Bearer $INOVACC_API_KEY" \
-H "X-Operation-Id: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}'
TypeScript
import crypto from "node:crypto";
const body: Record<string, unknown> = {
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
};
const url = "https://ai.inovacc.dev/v1/vector/ingest";
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
"X-Operation-Id": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
console.log(response.status, await response.text());import crypto from "node:crypto";
const body: Record<string, unknown> = {
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
};
const url = "https://ai.inovacc.dev/v1/vector/ingest";
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
"X-Operation-Id": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
console.log(response.status, await response.text());
Python
import json
import os
import urllib.request
import uuid
body = {
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr",
},
"document_id": "handbook-leave",
"generation": 1,
},
],
}
request = urllib.request.Request(
"https://ai.inovacc.dev/v1/vector/ingest",
data=json.dumps(body).encode(),
method="POST",
headers={
"User-Agent": "inovacc-python-sample",
"Authorization": "Bearer " + os.environ["INOVACC_API_KEY"],
"X-Operation-Id": str(uuid.uuid4()),
"Content-Type": "application/json",
},
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())import json
import os
import urllib.request
import uuid
body = {
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr",
},
"document_id": "handbook-leave",
"generation": 1,
},
],
}
request = urllib.request.Request(
"https://ai.inovacc.dev/v1/vector/ingest",
data=json.dumps(body).encode(),
method="POST",
headers={
"User-Agent": "inovacc-python-sample",
"Authorization": "Bearer " + os.environ["INOVACC_API_KEY"],
"X-Operation-Id": str(uuid.uuid4()),
"Content-Type": "application/json",
},
)
with urllib.request.urlopen(request) as response:
print(response.status, response.read().decode())
Go
package main
import (
"crypto/rand"
"fmt"
"io"
"net/http"
"os"
"strings"
)
const url = "https://ai.inovacc.dev/v1/vector/ingest"
const body = `{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}`
// newUUID returns a random (version 4) UUID, from the standard library alone.
func newUUID() string {
b := make([]byte, 16)
if _, err := rand.Read(b); err != nil {
panic(err)
}
b[6] = b[6]&0x0f | 0x40
b[8] = b[8]&0x3f | 0x80
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
}
func main() {
req, err := http.NewRequest("POST", url, strings.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INOVACC_API_KEY"))
req.Header.Set("X-Operation-Id", newUUID())
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println(res.Status, string(out))
}package main
import (
"crypto/rand"
"fmt"
"io"
"net/http"
"os"
"strings"
)
const url = "https://ai.inovacc.dev/v1/vector/ingest"
const body = `{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}`
// newUUID returns a random (version 4) UUID, from the standard library alone.
func newUUID() string {
b := make([]byte, 16)
if _, err := rand.Read(b); err != nil {
panic(err)
}
b[6] = b[6]&0x0f | 0x40
b[8] = b[8]&0x3f | 0x80
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
}
func main() {
req, err := http.NewRequest("POST", url, strings.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INOVACC_API_KEY"))
req.Header.Set("X-Operation-Id", newUUID())
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println(res.Status, string(out))
}
Rust
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// Cargo.toml: serde_json = "1"
// Cargo.toml: uuid = { version = "1", features = ["v4"] }
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = std::env::var("INOVACC_API_KEY")?;
let body = serde_json::json!({
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
});
let response = reqwest::blocking::Client::new()
.post("https://ai.inovacc.dev/v1/vector/ingest")
.bearer_auth(api_key)
.header("X-Operation-Id", uuid::Uuid::new_v4().to_string())
.json(&body)
.send()?;
println!("{} {}", response.status(), response.text()?);
Ok(())
}// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
// Cargo.toml: serde_json = "1"
// Cargo.toml: uuid = { version = "1", features = ["v4"] }
fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = std::env::var("INOVACC_API_KEY")?;
let body = serde_json::json!({
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
});
let response = reqwest::blocking::Client::new()
.post("https://ai.inovacc.dev/v1/vector/ingest")
.bearer_auth(api_key)
.header("X-Operation-Id", uuid::Uuid::new_v4().to_string())
.json(&body)
.send()?;
println!("{} {}", response.status(), response.text()?);
Ok(())
}
JavaScript
import crypto from "node:crypto";
const body = {
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
};
const url = "https://ai.inovacc.dev/v1/vector/ingest";
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
"X-Operation-Id": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
console.log(response.status, await response.text());import crypto from "node:crypto";
const body = {
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
};
const url = "https://ai.inovacc.dev/v1/vector/ingest";
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.INOVACC_API_KEY}`,
"X-Operation-Id": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
console.log(response.status, await response.text());
PHP
<?php
$body = <<<'JSON'
{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}
JSON;
function uuid4(): string
{
$bytes = random_bytes(16);
$bytes[6] = chr(ord($bytes[6]) & 0x0f | 0x40);
$bytes[8] = chr(ord($bytes[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($bytes), 4));
}
$curl = curl_init('https://ai.inovacc.dev/v1/vector/ingest');
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INOVACC_API_KEY'),
'X-Operation-Id: ' . uuid4(),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($curl);
echo curl_getinfo($curl, CURLINFO_HTTP_CODE), ' ', $response, "\n";
curl_close($curl);<?php
$body = <<<'JSON'
{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}
JSON;
function uuid4(): string
{
$bytes = random_bytes(16);
$bytes[6] = chr(ord($bytes[6]) & 0x0f | 0x40);
$bytes[8] = chr(ord($bytes[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($bytes), 4));
}
$curl = curl_init('https://ai.inovacc.dev/v1/vector/ingest');
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('INOVACC_API_KEY'),
'X-Operation-Id: ' . uuid4(),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($curl);
echo curl_getinfo($curl, CURLINFO_HTTP_CODE), ' ', $response, "\n";
curl_close($curl);
Ruby
require "net/http"
require "securerandom"
require "uri"
uri = URI('https://ai.inovacc.dev/v1/vector/ingest')
body = <<~'JSON'
{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}
JSON
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch('INOVACC_API_KEY')}"
request["X-Operation-Id"] = SecureRandom.uuid
request["Content-Type"] = "application/json"
request.body = body
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts "#{response.code} #{response.body}"require "net/http"
require "securerandom"
require "uri"
uri = URI('https://ai.inovacc.dev/v1/vector/ingest')
body = <<~'JSON'
{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}
JSON
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch('INOVACC_API_KEY')}"
request["X-Operation-Id"] = SecureRandom.uuid
request["Content-Type"] = "application/json"
request.body = body
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts "#{response.code} #{response.body}"
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.UUID;
public class Main {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("INOVACC_API_KEY");
String body = "{" +
"\"scope\": \"shared\"," +
"\"documents\": [" +
"{" +
"\"id\": \"handbook-leave-1\"," +
"\"text\": \"Employees accrue two and a half days of paid leave per month.\"," +
"\"metadata\": {" +
"\"category\": \"hr\"" +
"}," +
"\"document_id\": \"handbook-leave\"," +
"\"generation\": 1" +
"}" +
"]" +
"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://ai.inovacc.dev/v1/vector/ingest"))
.header("Authorization", "Bearer " + apiKey)
.header("X-Operation-Id", UUID.randomUUID().toString())
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.UUID;
public class Main {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("INOVACC_API_KEY");
String body = "{" +
"\"scope\": \"shared\"," +
"\"documents\": [" +
"{" +
"\"id\": \"handbook-leave-1\"," +
"\"text\": \"Employees accrue two and a half days of paid leave per month.\"," +
"\"metadata\": {" +
"\"category\": \"hr\"" +
"}," +
"\"document_id\": \"handbook-leave\"," +
"\"generation\": 1" +
"}" +
"]" +
"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://ai.inovacc.dev/v1/vector/ingest"))
.header("Authorization", "Bearer " + apiKey)
.header("X-Operation-Id", UUID.randomUUID().toString())
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}
C#
using System.Text;
var body = "{" +
"\"scope\": \"shared\"," +
"\"documents\": [" +
"{" +
"\"id\": \"handbook-leave-1\"," +
"\"text\": \"Employees accrue two and a half days of paid leave per month.\"," +
"\"metadata\": {" +
"\"category\": \"hr\"" +
"}," +
"\"document_id\": \"handbook-leave\"," +
"\"generation\": 1" +
"}" +
"]" +
"}";
var url = "https://ai.inovacc.dev/v1/vector/ingest";
var apiKey = Environment.GetEnvironmentVariable("INOVACC_API_KEY");
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Add("Authorization", $"Bearer {apiKey}");
request.Headers.Add("X-Operation-Id", Guid.NewGuid().ToString());
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");using System.Text;
var body = "{" +
"\"scope\": \"shared\"," +
"\"documents\": [" +
"{" +
"\"id\": \"handbook-leave-1\"," +
"\"text\": \"Employees accrue two and a half days of paid leave per month.\"," +
"\"metadata\": {" +
"\"category\": \"hr\"" +
"}," +
"\"document_id\": \"handbook-leave\"," +
"\"generation\": 1" +
"}" +
"]" +
"}";
var url = "https://ai.inovacc.dev/v1/vector/ingest";
var apiKey = Environment.GetEnvironmentVariable("INOVACC_API_KEY");
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Add("Authorization", $"Bearer {apiKey}");
request.Headers.Add("X-Operation-Id", Guid.NewGuid().ToString());
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");
Kotlin
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.util.UUID
fun main() {
val apiKey = System.getenv("INOVACC_API_KEY")
val body = "{" +
"\"scope\": \"shared\"," +
"\"documents\": [" +
"{" +
"\"id\": \"handbook-leave-1\"," +
"\"text\": \"Employees accrue two and a half days of paid leave per month.\"," +
"\"metadata\": {" +
"\"category\": \"hr\"" +
"}," +
"\"document_id\": \"handbook-leave\"," +
"\"generation\": 1" +
"}" +
"]" +
"}"
val request = HttpRequest.newBuilder()
.uri(URI.create("https://ai.inovacc.dev/v1/vector/ingest"))
.header("Authorization", "Bearer " + apiKey)
.header("X-Operation-Id", UUID.randomUUID().toString())
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build()
val response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString())
println("${response.statusCode()} ${response.body()}")
}import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.util.UUID
fun main() {
val apiKey = System.getenv("INOVACC_API_KEY")
val body = "{" +
"\"scope\": \"shared\"," +
"\"documents\": [" +
"{" +
"\"id\": \"handbook-leave-1\"," +
"\"text\": \"Employees accrue two and a half days of paid leave per month.\"," +
"\"metadata\": {" +
"\"category\": \"hr\"" +
"}," +
"\"document_id\": \"handbook-leave\"," +
"\"generation\": 1" +
"}" +
"]" +
"}"
val request = HttpRequest.newBuilder()
.uri(URI.create("https://ai.inovacc.dev/v1/vector/ingest"))
.header("Authorization", "Bearer " + apiKey)
.header("X-Operation-Id", UUID.randomUUID().toString())
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build()
val response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString())
println("${response.statusCode()} ${response.body()}")
}
Swift
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
let body = #"""
{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}
"""#
let apiKey = ProcessInfo.processInfo.environment["INOVACC_API_KEY"] ?? ""
let url = URL(string: "https://ai.inovacc.dev/v1/vector/ingest")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue(UUID().uuidString, forHTTPHeaderField: "X-Operation-Id")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = Data(body.utf8)
let (data, response) = try await URLSession.shared.data(for: request)
let status = (response as? HTTPURLResponse)?.statusCode ?? 0
print(status, String(decoding: data, as: UTF8.self))import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
let body = #"""
{
"scope": "shared",
"documents": [
{
"id": "handbook-leave-1",
"text": "Employees accrue two and a half days of paid leave per month.",
"metadata": {
"category": "hr"
},
"document_id": "handbook-leave",
"generation": 1
}
]
}
"""#
let apiKey = ProcessInfo.processInfo.environment["INOVACC_API_KEY"] ?? ""
let url = URL(string: "https://ai.inovacc.dev/v1/vector/ingest")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue(UUID().uuidString, forHTTPHeaderField: "X-Operation-Id")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = Data(body.utf8)
let (data, response) = try await URLSession.shared.data(for: request)
let status = (response as? HTTPURLResponse)?.statusCode ?? 0
print(status, String(decoding: data, as: UTF8.self))
Source details
- Id
- identity/component-taxonomy/capabilities#knowledge
- Repository
- identity
- Path
- contracts/component-taxonomy/catalog/capabilities.json
- Commit
- 08ef3cd75d82
- Id
- identity/component-taxonomy/quickstart#knowledge
- Repository
- identity
- Path
- contracts/component-taxonomy/catalog/capabilities.json
- Commit
- 08ef3cd75d82