# Get Started

Explore Vorsto docs to understand how to setup an AI agent and integrate with your software

This documentation includes guides on setting up functions, configuring different response formats for your best use cases.

Integrating AI into your software will enhance automation, decision-making, and user experiences by leveraging data-driven insights, natural language processing, and machine learning algorithms. This can streamline operations, improve personalization, and drive innovation across various applications.

### Jump right in

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Create Agent</strong></td><td>Create an agent</td><td></td><td></td><td><a href="/pages/MXnOHWTAEhc3ekpOiMRM">/pages/MXnOHWTAEhc3ekpOiMRM</a></td></tr><tr><td><strong>Configure Agent</strong></td><td>Configuring your agent</td><td></td><td></td><td><a href="/pages/m0I6tfRx8u1222P5Dm7I">/pages/m0I6tfRx8u1222P5Dm7I</a></td></tr><tr><td><strong>Functions</strong></td><td>How to setup functions</td><td></td><td></td><td><a href="/pages/MKBstcH1gwROmZdNki0H">/pages/MKBstcH1gwROmZdNki0H</a></td></tr><tr><td>API</td><td>AI requests and responses</td><td></td><td></td><td></td></tr><tr><td>IP Whitelisting</td><td>IP Address whitelisting</td><td></td><td></td><td><a href="/pages/LJOENwSc02TsafBI3Uqz">/pages/LJOENwSc02TsafBI3Uqz</a></td></tr><tr><td>Models</td><td>Explore available models</td><td></td><td></td><td></td></tr></tbody></table>


# Create Agent

Create an agent  on your console

<figure><img src="/files/BVabqZB3CINAFo5fufxN" alt=""><figcaption></figcaption></figure>

Creating an AI agent requires that you give your agent a suitable name for identification. FIll in the general information about what the agent is meant for and what it an do or not do.

{% hint style="info" %}
If you plan to use functions, you can include an ordered list of steps of the functions the agent can perform. You can checkout [included examples](broken://pages/aQcVvRJWuObEl6tss6YJ) in this documentation
{% endhint %}


# Configure Agent

Explore the various fields you need to configure your agent for production use

<figure><img src="/files/KM6sPFWeAtICteTqVt6A" alt=""><figcaption></figcaption></figure>

After you have created your agent, proceed to configuring your agent to make it  usable in your software

**Output Type:** Depending on your use case, you can select text responses from the agent or  object responses (JSON) for easier intergation with your system.&#x20;

**Web Hook:** The agent send out long running function responses to the webhook url. [Read more about web hook here.](/api/api-web-hook) Non-long running responses are returned along with the api response. This is available on text responses only.

**Models:** You can use external models from top AI providers. Vorsto currently supports some of the top most intelligent AI models. You can read more on models [here](/3rd-party-models/gpt). This is available only for enterprise users.

**Model API Key:** Depending on your model of choice, you may be required to provide your model api key. Checkout out your desired model from our [supported models](/3rd-party-models/gpt) to see how to get the api key. This is available only for enterprise users.

{% hint style="info" %}
Object (JSON) responses can be configured to your desired output to ensure predictable responses at all times for seamless integration [see more details ](/api/object)
{% endhint %}


# Functions

Configure your agent to perform special functions on your system like sending and getting data in a chain process. You can chain multiple functions to fully automate a process or flow.

<figure><img src="/files/lxwTNQdsStrHTqMFEMud" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Functions are only  available when you select the text output. Functions can be long running so function responses are sent to your [configured api web hook url](/api/api-web-hook)
{% endhint %}

To configure a function, you need to define the function name, description, api and parameters.

The parameters are sent to the function api in a POST request.

The function API field requires your system api . See below the expected response of your api:

## API request format

**Sample Request  from the Agent**

**When a function is configured, the agent sends hooks to the api which includes configured input parameters from the agent gotten from an interaction with a user .**\
\
**Each function can have different apis or same api as long as each request and response is handled properly**

{% tabs %}
{% tab title="Request with parameters" %}

```javascript
// Request with parameters

{
    "function": "create_user"
    "name": "name",
    "email": "email"
}
```

{% endtab %}

{% tab title="Request with no parameter" %}

```
// Request with no parameters

{
    "function": "refresh_cache"
}
```

{% endtab %}
{% endtabs %}

## API response format

| Name                | Type                    | Required | Description                                                                                                            |
| ------------------- | ----------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `type`              | string                  | no       | Setting this allows the AI to process your response and determine the next step in your process.                       |
| `message`           | string                  | yes      | Response message from your api. This will be returned as a response                                                    |
| `data`              | Array of [items](#item) | no       | <p>JSON Array of items from your software<br>See data response parameter for actionable <a href="#item"> items</a></p> |
| data\_display\_type | string                  | no       | <p>Default is card.<br>This currently only supports "card" display for the embedded chat tool</p>                      |

{% hint style="warning" %}
The "type" field is uses the message field to instruct the agent on next steps for chain processes.  Hence, do not set the "type"  field when the data field is being returned.
{% endhint %}

### item

| Name        | Type   | Required | Decription                                        |
| ----------- | ------ | -------- | ------------------------------------------------- |
| title       | string | yes      | name of the item                                  |
| image       | string | no       | public image url of the item                      |
| information | string | no       | information/description of item                   |
| metadata    | Array  | no       | Array of key value pair of additional information |
| actions     | Array  | no       | Array of text-url pair of clickable actions       |

**Sample Response  to the Agent**

{% tabs %}
{% tab title="Text Response  " %}

<pre class="language-javascript"><code class="lang-javascript"><strong>//Text Response
</strong>{
  "message": "User profile registered"
}
</code></pre>

{% endtab %}

{% tab title="Text Response  passed with additional instructions to the agent" %}

```json
//Text Response  passed with additional instriuctions to the agent
{
  "type": "instruct",
  "message": "User profile registered, is the user eligible for credit?"
}
```

{% endtab %}

{% tab title="Response with custom data" %}

<pre class="language-javascript"><code class="lang-javascript">//Response with data from your platform
<strong>{
</strong>  "message": "here is a list of items in our inventory",
  "data_display_type": "card",
  "data": [
              {
                "title": "My First Item",
                "image": "https://link/to/my/image.extension",
                "information": "Brief information", 
                "metadata": [
                  {
                    "key1": "value1"
                  },
                  {
                    "key2": "value2"
                  }
                ], 
                "actions": [
<strong>                    {
</strong>                      "text": "Select",
                      "instruct": "User selected My First Item, Proceed to next instruction",
                    },
<strong>                    {
</strong>                      "text": "Select",
                      "link": "http://link/to/item",
                    }
                ], 
              }
          ]
}
</code></pre>

{% endtab %}
{% endtabs %}

Next, explore how to setup your function parameters for your software.


# Parameters

Function parameters are optional and are passed down to your functions from your interaction with the agent.

<figure><img src="/files/dbYkH80eNE0JXS0xzwjY" alt=""><figcaption></figcaption></figure>

Function parameters are mostly used in conversational agents for data collection to perform specialized functions. These can be useful when intergrated to chat interfaces or custom form flows.

A parameter requires the name of the parameter e.g age,  description of what the parameter is or will be used for and the data type which can be either string, number or boolean.

Once you are done configuring, You can update agent to save your configurations. You agent becomes ready for use!

Next, we explore the api, security and api documentations.


# Authentication

Api authentication using api keys

To integrate with your agent, you need a valid api key from your account.

You can generate an api key from [console](https://console.vorsto.io/settings) [> settings](https://console.vorsto.io/settings).&#x20;

To authenticate your api, you need to setting your header x-auth-key appropriately

```json
// Authentication Header
x-auth-key: api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```


# Request

Explore the api request parameters

## Agent Message API

<mark style="color:green;">`POST`</mark> `https://agent.vorsto.io/api/{agent-id}`

**Headers**

| Name         | Value                             |
| ------------ | --------------------------------- |
| Content-Type | `application/json`                |
| x-auth-key   | `api_xxxxxxxxxxxxxxxxxxxxxxxxxxx` |

**Url Parameter**

| Name     | Type   | Description                                                           |
| -------- | ------ | --------------------------------------------------------------------- |
| agent-id | string | The id of the agent. You can get this on the agent configuration form |

**Sample Request**

{% tabs %}
{% tab title="Body" %}

```json
{
    "query": "Can you analyse this data for fraud?"
}
```

{% endtab %}
{% endtabs %}

| Name  | Type   | Description                 |
| ----- | ------ | --------------------------- |
| query | string | Your instruction to the bot |


# Object Response

The Object response is a configurable JSON response for your agent. This ensures a predictable response format from your agent.&#x20;

Functions are not available on Object Responses as they are returned on every api call.&#x20;

You can configure your object response parameters on your agent configuration form as seen below.

<figure><img src="/files/tZ7cB4cpRgWSgjBV0DDe" alt=""><figcaption></figcaption></figure>

Each parameter data type can be String, Number or Boolean. A parameter name  and parameter description is required. For example, an agent meant to classify movies in genre would have a configuration like so: &#x20;

Name: Class\
Description: The genre of the movie \
Type: String&#x20;

Below is a sample response from a diagnosis fraud analysis agent

```json
{
    "message": {
        "id": "duH7f5mOItDIlpYRbMPDE",
        "role": "assistant",
        "content": {
            "fraud": false,
            "comment": "The diagnosis of Pediculus Capitis (head lice) is a valid medical condition. The details provided do not indicate any fraudulent activity."
        }
    }
}
```

\
The parameters from the above response are fraud (string) and comment (string).

{% hint style="info" %}
Object responses do not allow functions and hence non-long running.  Agent responses are returned on every requests. Your configured parameters are returned as the "content" response object.
{% endhint %}


# Text Response

Text responses allow functions to be configured and your Agent responses are not returned when you call the api.\
The request code (message id) is returned for you track the response of your request on the api web hook for recounciliation.

Text response also returns an history of the requests for context understanding.&#x20;

```json
//API Text Response
{
    "message": {
        "id": "duH7f5mOItDIlpYRbMPDE",
        "message": "your agent is processing your request."
    }
}
```

```json
// Webhook Text Response
{
    "message": {
        "id": "duH7f5mOItDIlpYRbMPDE",
        "agentId": "hyeyry3mOItehdsfp373hhs",
        "role": "assistant",
        "content": "The diagnosis of Pediculus Capitis (head lice) is a valid medical condition. The details provided do not indicate any fraudulent activity."
    }
}
```

{% hint style="info" %}
Text response are not returned with the api response. Text responses are returned as string in the "content" response object to your configured webhook url.
{% endhint %}


# API Web Hook

You need configure a webhook url for each agent you create.  Long running text responses from agents and configured functions  are sent to webhooks.

To securely consume a webhook response, you can optionally validate the webhook using the x-signature token sent with the response. The token must  be validated with the same api key  used to make the request to the agent.

```
// Header
'x-signature': xxxxxxxxxxxxxxx
```

```json
// Webhook Text Response
{
    "message": {
        "id": "duH7f5mOItDIlpYRbMPDE",
        "agentId": "hyeyry3mOItehdsfp373hhs",
        "role": "assistant",
        "content": "The diagnosis of Pediculus Capitis (head lice) is a valid medical condition. The details provided do not indicate any fraudulent activity."
    }
}
```

Here is a smaple code to securely verify your hooks

{% tabs %}
{% tab title="Node.js" %}

```javascript
const crypto = require('crypto');

function verifyWebhookSignature(req, secret) {
  const signature = req.headers['x-signature'];
  const payload = JSON.stringify(req.body);
  
  // Compute the hash using HMAC with SHA256 and the shared secret
  const hash = crypto.createHmac('sha256', secret).update(payload).digest('hex');

  // Compare the computed hash with the signature
  return hash === signature;
}

// Usage in Express.js
app.post('/webhook', (req, res) => {
  const secret = 'your_api_key';
  
  if (!verifyWebhookSignature(req, secret)) {
    return res.status(403).send('Forbidden');
  }
  
  // Handle the webhook
  res.status(200).send('Webhook received');
});

```

{% endtab %}

{% tab title="Java" %}

```java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;

public class WebhookVerifier {

    public static boolean verifyWebhookSignature(HttpServletRequest req, String secret) throws Exception {
        String signature = req.getHeader("x-signature");
        StringBuilder payload = new StringBuilder();
        
        try (BufferedReader reader = req.getReader()) {
            String line;
            while ((line = reader.readLine()) != null) {
                payload.append(line);
            }
        }

        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256HMAC.init(secretKey);
        byte[] hashBytes = sha256HMAC.doFinal(payload.toString().getBytes(StandardCharsets.UTF_8));
        String hash = bytesToHex(hashBytes);

        return hash.equals(signature);
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder(2 * bytes.length);
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
}

```

{% endtab %}

{% tab title="Python" %}

```python
import hmac
import hashlib

def verify_webhook_signature(req, secret):
    signature = req.headers.get('x-signature')
    payload = req.data.decode('utf-8')  # Assuming you're using Flask, this will give you the raw payload
    
    # Compute the HMAC SHA256 hash
    hash = hmac.new(secret.encode('utf-8'), payload.encode('utf-8'), hashlib.sha256).hexdigest()

    # Compare the computed hash with the signature
    return hash == signature

# Usage in Flask
from flask import Flask, request, abort

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    secret = 'your_shared_secret'
    
    if not verify_webhook_signature(request, secret):
        abort(403)  # Forbidden
    
    # Handle the webhook
    return 'Webhook received', 200

```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'openssl'

def verify_webhook_signature(req, secret)
  signature = req.headers['x-signature']
  payload = req.body.read
  
  # Compute the HMAC SHA256 hash
  hash = OpenSSL::HMAC.hexdigest('SHA256', secret, payload)

  # Compare the computed hash with the signature
  hash == signature
end

# Usage in Sinatra
require 'sinatra'

post '/webhook' do
  secret = 'your_shared_secret'
  
  halt 403, 'Forbidden' unless verify_webhook_signature(request, secret)
  
  # Handle the webhook
  status 200
  'Webhook received'
end

```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"io/ioutil"
	"net/http"
)

func verifyWebhookSignature(r *http.Request, secret string) bool {
	signature := r.Header.Get("x-signature")

	body, _ := ioutil.ReadAll(r.Body)
	defer r.Body.Close()

	h := hmac.New(sha256.New, []byte(secret))
	h.Write(body)
	hash := hex.EncodeToString(h.Sum(nil))

	return hash == signature
}

func webhookHandler(w http.ResponseWriter, r *http.Request) {
	secret := "your_shared_secret"
	
	if !verifyWebhookSignature(r, secret) {
		http.Error(w, "Forbidden", http.StatusForbidden)
		return
	}

	// Handle the webhook
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Webhook received"))
}

func main() {
	http.HandleFunc("/webhook", webhookHandler)
	http.ListenAndServe(":8080", nil)
}

```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

function verifyWebhookSignature($request, $secret) {
    // Get the signature from the request headers
    $signature = $request->getHeader('x-signature')[0]; // Assuming you're using PSR-7 Request
    $payload = $request->getBody()->getContents(); // Get the raw body payload

    // Compute the HMAC SHA-256 hash
    $hash = hash_hmac('sha256', $payload, $secret);

    // Compare the computed hash with the signature
    return hash_equals($hash, $signature);
}

// Usage in a PSR-7 compatible framework like Slim or Laravel (with Request injection)
$app->post('/webhook', function ($request, $response) {
    $secret = 'your_shared_secret';

    if (!verifyWebhookSignature($request, $secret)) {
        return $response->withStatus(403)->write('Forbidden');
    }

    // Handle the webhook
    return $response->withStatus(200)->write('Webhook received');
});

```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You  can optionally use this approach to seurely consume a hook, or ensure that your webhook url is on a secured https certificate.
{% endhint %}


# IP Whitelisting

For added security,  you will need to whitelist your IP addresses for you to be able to securely reach  your agent.

<figure><img src="/files/nOIJSHhl6N4iJaJIwkJL" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
For local development, whitelist 127.0.0.1 for api access on your local PC. For security,  delete the IP once development is completed.
{% endhint %}


# GPT

Vorsto support multiple GPT models from OpenAI.  To use OpenAI models, you need an API key from Open AI .

You can get your own OpenAI key here >> <https://platform.openai.com/api-keys>

You can manage your GPT tokens directly on your OpenAI dashboard.&#x20;


# Gemini

Vorsto support multiple Google Gemini models.  To use Google Gemini models, you need an API key from Google .

You can get your own Gemini key from Google's AI Studio  >> <https://aistudio.google.com/app/apikey>

You can manage your GPT tokens directly on your OpenAI dashboard.&#x20;


