curl --request POST \
--url https://gateway.prem.io/tools/{id} \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"cipherText": "<string>",
"encryptedParams": "<string>",
"nonce": "<string>"
}
'import requests
url = "https://gateway.prem.io/tools/{id}"
payload = {
"cipherText": "<string>",
"encryptedParams": "<string>",
"nonce": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({cipherText: '<string>', encryptedParams: '<string>', nonce: '<string>'})
};
fetch('https://gateway.prem.io/tools/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.prem.io/tools/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cipherText' => '<string>',
'encryptedParams' => '<string>',
'nonce' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.prem.io/tools/{id}"
payload := strings.NewReader("{\n \"cipherText\": \"<string>\",\n \"encryptedParams\": \"<string>\",\n \"nonce\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.prem.io/tools/{id}")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"cipherText\": \"<string>\",\n \"encryptedParams\": \"<string>\",\n \"nonce\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.prem.io/tools/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cipherText\": \"<string>\",\n \"encryptedParams\": \"<string>\",\n \"nonce\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "123"
},
"error": null,
"log": null,
"validator": null,
"support_id": null,
"message": "Resource created successfully",
"env": "development"
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 401,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 403,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 404,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}Execute Tool
Execute a specific tool by passing encrypted parameters.
curl --request POST \
--url https://gateway.prem.io/tools/{id} \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"cipherText": "<string>",
"encryptedParams": "<string>",
"nonce": "<string>"
}
'import requests
url = "https://gateway.prem.io/tools/{id}"
payload = {
"cipherText": "<string>",
"encryptedParams": "<string>",
"nonce": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({cipherText: '<string>', encryptedParams: '<string>', nonce: '<string>'})
};
fetch('https://gateway.prem.io/tools/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.prem.io/tools/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cipherText' => '<string>',
'encryptedParams' => '<string>',
'nonce' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.prem.io/tools/{id}"
payload := strings.NewReader("{\n \"cipherText\": \"<string>\",\n \"encryptedParams\": \"<string>\",\n \"nonce\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.prem.io/tools/{id}")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"cipherText\": \"<string>\",\n \"encryptedParams\": \"<string>\",\n \"nonce\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.prem.io/tools/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cipherText\": \"<string>\",\n \"encryptedParams\": \"<string>\",\n \"nonce\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "123"
},
"error": null,
"log": null,
"validator": null,
"support_id": null,
"message": "Resource created successfully",
"env": "development"
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 401,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 403,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 404,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}TypeScript SDK
The SDK is available on GitHub: premAI-io/api-sdk-tsUsage
Basic Setup
Create a client with auto-generated encryption keys:import createRvencClient from "@premai/api-sdk";
const client = await createRvencClient({
apiKey: process.env.PREM_API_KEY,
clientKEK: process.env.CLIENT_KEK
});
Pre-generate Keys
You can pre-generate encryption keys and reuse them:import createRvencClient, { generateEncryptionKeys } from "@premai/api-sdk";
const encryptionKeys = await generateEncryptionKeys();
const client = await createRvencClient({
apiKey: process.env.PREM_API_KEY,
encryptionKeys,
requestTimeoutMs: 60000, // optional
maxBufferSize: 20 * 1024 * 1024, // optional
});
// Generate an image
const image = await client.tools.generateImage({prompt: "sunset over mountains"});
console.log(image.fileName); // "generated_image.png"
console.log(image.content); // Uint8Array - save or use directly
Features
- ✅ File-Producing Tools - Generate images, audio, and custom files
- ✅ File-Processing Tools - Extract content from PDFs, images, audio, video, and other file types
- ✅ Simple Tools - Web search, time, web scraping
- ✅ RAG Tools - Search indexed documents with an optional file filter
- ✅ End-to-end Encryption - All tool calls use end-to-end encryption
- ✅ Automatic Decryption - The SDK automatically downloads and decrypts files
- ✅ TypeScript - Full type safety
Tools
All tool calls use end-to-end encryption. The SDK automatically downloads and decrypts files.File-Producing Tools
Generate files with these tools. The SDK automatically decrypts the files and returns them:import fs from "fs";
// Generate an image
const image = await client.tools.generateImage({prompt: "sunset over mountains"});
console.log(image.fileName); // "generated_image.png"
console.log(image.content); // Uint8Array - save or use directly
fs.writeFileSync(image.fileName, image.content);
// Generate audio from text
const audio = await client.tools.audioGenerateFromText({text: "Hello, world!"});
fs.writeFileSync(audio.fileName, audio.content);
// Create a custom file
const file = await client.tools.createFileForUser(
{
fileName: 'test_file',
fileExtension: 'txt',
fileContent: 'This is the content of the test file.',
mimeType: 'text/plain'
}
);
fs.writeFileSync(file.fileName, file.content);
File-Processing Tools
Process uploaded files and get the results:import fs from "fs";
// Upload a file first
const upload = await client.files.upload({
file: new Uint8Array(fs.readFileSync("./image.jpg")),
fileName: "image.jpg",
});
// Describe and caption image
const description = await client.tools.imageDescribeAndCaption({fileId: upload.id});
console.log(description);
// Extract PDF content
const pdfUpload = await client.files.upload({
file: new Uint8Array(fs.readFileSync("./doc.pdf")),
fileName: "doc.pdf",
});
const pdfContent = await client.tools.getPDFContent({fileId: pdfUpload.id});
console.log(pdfContent);
// Transcribe audio
const audioUpload = await client.files.upload({
file: new Uint8Array(fs.readFileSync("./audio.mp3")),
fileName: "audio.mp3",
});
const transcript = await client.tools.transcribeAudioToText({fileId: audioUpload.id});
console.log(transcript);
// Video description
const videoUpload = await client.files.upload({
file: new Uint8Array(fs.readFileSync("./video.mp4")),
fileName: "video.mp4",
});
const videoDesc = await client.tools.videoDescribeAndCaption({fileId: videoUpload.id});
console.log(videoDesc);
Simple Tools
These tools do not process files:// Get current time
const time = await client.tools.getTime({timezone: 'America/New_York'});
console.log(time);
// Web search
const searchResults = await client.tools.webSearchTool({query: 'latest AI news'});
console.log(searchResults);
// Web page scraper
const pageContent = await client.tools.webPageScraperTool({url: 'https://example.com', renderJs: false});
console.log(pageContent);
// RAG search across your uploaded files
const ragResults = await client.tools.searchRag({
query: 'test query',
});
console.log(ragResults);
Available Tools
File-Producing Tools
generateImage(params: { prompt: string })- Generate images from textaudioGenerateFromText(params: { text: string })- Text-to-speechcreateFileForUser(params: { fileName: string, fileExtension: string, fileContent: string, mimeType: string })- Create custom files
File-Processing Tools
imageDescribeAndCaption(params: { fileId: string })- Describe imagesimageDescribeAndCaptionFallback(params: { fileId: string })- Alternative image descriptionvideoDescribeAndCaption(params: { fileId: string })- Describe videosgetPDFContent(params: { fileId: string })- Extract PDF textgetTextDocumentContent(params: { fileId: string })- Extract document texttranscribeAudioToText(params: { fileId: string, language?: string })- Audio transcriptiontranscribeAudioWithDiarization(params: { fileId: string, language?: string })- Transcription with speakersaudioDiarization(params: { fileId: string })- Identify speakersgetFileContentOCR(params: { fileId: string })- OCR on imagesgetSpreadsheetContent(params: { fileId: string })- Extract spreadsheet datagetDataFileContent(params: { fileId: string })- Extract data file contentgetPowerPointContent(params: { fileId: string, slideNumbers?: number[] })- Extract presentation content
Simple Tools
getTime(params: { timezone: string })- Get current timewebSearchTool(params: { query: string, country?: string, searchLang?: string })- Web searchwebPageScraperTool(params: { url: string, renderJs?: boolean })- Scrape web pages
RAG Tools
searchRag(params: { query: string })- Search indexed documents with an optional file filter
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | required | Authorization token |
encryptionKeys | EncryptionKeys | auto-generated | Pre-generated ML-KEM keys |
dekStore | DEKStore | auto-generated | Data encryption keys for files |
requestTimeoutMs | number | 30000 | Request timeout in milliseconds |
maxBufferSize | number | 10485760 | Max SSE buffer size (10MB) |
Security Notes
- ⚠️ Keep your DEK store secure. The DEK store contains all of your encryption keys.
- ⚠️ Do not commit
dek-store.jsonto version control. - ⚠️ Use environment variables for API keys.
- ⚠️ Save the dekStore after each file upload. The dekStore holds the DEKs for your files.
- ⚠️ Make a backup of your dekStore. If you lose it, you lose access to your uploaded files.
TypeScript Types
import type {
RvencClient,
RvencClientOptions,
DEKStore,
EncryptionKeys,
FileUploadOptions,
UploadedFile,
DecryptedFile,
ToolsClient,
} from "@premai/api-sdk";
Authorizations
Send your access token as header Authorization: Bearer {accessToken}
Your API key that starts with sk_live or sk_test. You can create yours at go.prem.io/api-keys.
Path Parameters
The tool identifier (e.g., generateImage, audioGenerateFromText, createFileForUser)
Body
- Simple Tool Request
- File Output Tool Request
- File Input Tool Request
- RAG Tool Request
Request for simple tools that don't involve file I/O: webSearchTool, getTime, webPageScraperTool
Response
Tool executed successfully with encrypted response
Status code of the response
200, 201, 202 Response for file-producing tools (generateImage, audioGenerateFromText, createFileForUser)
- File Output Response
- Encrypted Response
Show child attributes
Show child attributes
{
"fileId": "file_encrypted_gen_019ae533-a975-7cbb-9147-4d7583a335e3",
"fileName": "de0b1a99cc4fcb45c1f236b2bb328015375cbe4f...",
"fileSize": 1057063,
"handle": "46b6fb708c5deb249130605bb16cfb98...",
"mimeType": "9b7369da092f69c6efbe24d6db6501ef...",
"s3Path": "agentCreatedFiles/file_encrypted_gen_019ae533-a975-7cbb-9147-4d7583a335e3.enc",
"success": true,
"message": "Image generated successfully and made available for download"
}
Message of the response, human readable
"Resource created successfully"
API environment
development, production Error message of the response, human readable
"Invalid email address"
Useful informaiton, not always present, to debug the response
{ "request_id": "req_1234567890" }
"Some pertinent log message"
Validator response object, each key is the field name and value is the error message
{
"email": "Invalid email address",
"password": "Password is required"
}
Support ID linked to the response, used to identify it when talking with our team
"support_uuidv7-something-else"