> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gulp.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Store Knowledge

> API reference for the store knowledge endpoint

The `/store_knowledge` endpoint allows you to store agent interactions and experiences for future task enhancement.

This endpoint should be used whenever an agent is complete with a task.
If your agent spawns sub sub agents, each sub task agent should also call this endpoint once it's complete.

## Base URL

```bash
POST https://osmosis.gulp.dev/store_knowledge
```

## Authentication

<RequestHeader>
  <HeaderParameter name="Content-Type" required type="string">
    application/json
  </HeaderParameter>

  <HeaderParameter name="x-api-key" required type="string">
    Your API key
  </HeaderParameter>
</RequestHeader>

## Request Body

### Root Level Parameters

<ParamField body="tenant_id" type="string" required initialValue="your-api-key">
  Unique identifier that corresponds to a dedicated recommendation collection, enabling sub-tenancy isolation for different agentic workflows
</ParamField>

<ParamField body="query" type="string" required initialValue="Process refund request for damaged item">
  The original user query or instruction that initiated the interaction
</ParamField>

<ParamField body="turns" type="array" required>
  Array of interaction turns between the agent and the environment/user
</ParamField>

<ParamField body="success" type="boolean">
  Indicates whether the agent completed its task successfully
</ParamField>

<ParamField body="agent_type" type="string">
  Specifies the type of agent (e.g., 'browser', 'voice')
</ParamField>

<ParamField body="timestamp" type="string" required>
  When the interaction occurred (ISO format)
</ParamField>

<ParamField body="metadata" type="object">
  Additional metadata about the interaction
</ParamField>

### Turn Object Structure

Each turn in the `turns` array represents a single interaction step and contains the following fields:

<ParamField body="turn" type="number" required>
  The turn number in the interaction sequence. Must start at 1 and be sequential without gaps.
  For single-turn agents, this should be 1.
</ParamField>

<ParamField body="inputs" type="string" required>
  The flattened input the agent sees at this turn. Should include:

  * Available tools and options
  * Current observations
  * Each tool/option should be listed on a new line
</ParamField>

<ParamField body="decision" type="string" required>
  The output or action taken by the agent during this turn
</ParamField>

<ParamField body="memory" type="string">
  What the agent remembers from this turn, such as:

  * Values returned from a RAG store
  * User intent understanding
  * Key context or decisions made
</ParamField>

<ParamField body="result" type="string">
  The outcome of the agent's action, including:

  * User interruptions
  * Action success/failure
  * Any deterministic results
</ParamField>

## Example Requests

<CodeGroup>
  ```bash cURL
  curl -X POST https://osmosis.gulp.dev/store_knowledge \
    -H "Content-Type: application/json" \
    -H "x-api-key: your-api-key" \
    -d '{
      "tenant_id": "your-api-key",
      "query": "Find and purchase a red Nike running shoe in size 10",
      "turns": [
        {
          "turn": 1,
          "inputs": "On shopping website homepage. Need to search for red Nike running shoes.",
          "decision": "{\\"action_type\\": \\"click\\", \\"element_name\\": \\"search_bar\\", \\"text\\": [\\"Nike red running shoes\\"], \\"element_role\\": \\"searchbox\\", \\"coords\\": [120, 35], \\"url\\": \\"https://shop.example.com\\"}",
          "result": "completed_successfully",
          "memory": "User wants red Nike running shoes. Starting search from homepage."
        }
      ],
      "success": true,
      "agent_type": "browser",
      "timestamp": "2024-03-14T10:30:00Z",
      "metadata": {
        "browser_type": "chrome",
        "site": "shopping_admin",
        "interaction_duration_seconds": 120
      }
    }'
  ```

  ```typescript TypeScript
  import axios from 'axios';

  async function storeKnowledge() {
    const apiKey = process.env.OSMOSIS_API_KEY;
    
    const decision = {
      action_type: 'click',
      element_name: 'search_bar',
      text: ['Nike red running shoes'],
      element_role: 'searchbox',
      coords: [120, 35],
      url: 'https://shop.example.com'
    };

    const payload = {
      tenant_id: apiKey,
      query: 'Find and purchase a red Nike running shoe in size 10',
      turns: [
        {
          turn: 1,
          inputs: 'On shopping website homepage. Need to search for red Nike running shoes.',
          decision: JSON.stringify(decision),
          result: 'completed_successfully',
          memory: 'User wants red Nike running shoes. Starting search from homepage.'
        }
      ],
      success: true,
      agent_type: 'browser',
      timestamp: new Date().toISOString(),
      metadata: {
        browser_type: 'chrome',
        site: 'shopping_admin',
        interaction_duration_seconds: 120
      }
    };

    const response = await axios.post('https://osmosis.gulp.dev/store_knowledge', payload, {
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      }
    });
    
    return response.data;
  }
  ```

  ```python Python
  import os
  from datetime import datetime
  import requests
  import json

  def store_knowledge():
      api_key = os.getenv('OSMOSIS_API_KEY')
      
      decision = {
          "action_type": "click",
          "element_name": "search_bar",
          "text": ["Nike red running shoes"],
          "element_role": "searchbox",
          "coords": [120, 35],
          "url": "https://shop.example.com"
      }
      
      payload = {
          "tenant_id": api_key,
          "query": "Find and purchase a red Nike running shoe in size 10",
          "turns": [
              {
                  "turn": 1,
                  "inputs": "On shopping website homepage. Need to search for red Nike running shoes.",
                  "decision": json.dumps(decision),
                  "result": "completed_successfully",
                  "memory": "User wants red Nike running shoes. Starting search from homepage."
              }
          ],
          "success": True,
          "agent_type": "browser",
          "timestamp": datetime.utcnow().isoformat() + "Z",
          "metadata": {
              "browser_type": "chrome",
              "site": "shopping_admin",
              "interaction_duration_seconds": 120
          }
      }
      
      response = requests.post(
          "https://osmosis.gulp.dev/store_knowledge",
          json=payload,
          headers={
              "Content-Type": "application/json",
              "x-api-key": api_key
          }
      )
      
      return response.json()
  ```

  ```go Go
  package main

  import (
      "bytes"
      "encoding/json"
      "net/http"
      "os"
      "time"
  )

  type Decision struct {
      ActionType  string   `json:"action_type"`
      ElementName string   `json:"element_name"`
      Text       []string `json:"text"`
      ElementRole string   `json:"element_role"`
      Coords     []int    `json:"coords"`
      URL        string   `json:"url"`
  }

  type Turn struct {
      Turn     int    `json:"turn"`
      Inputs   string `json:"inputs"`
      Decision string `json:"decision"`
      Result   string `json:"result"`
      Memory   string `json:"memory"`
  }

  type KnowledgePayload struct {
      TenantID  string                 `json:"tenant_id"`
      Query     string                 `json:"query"`
      Turns     []Turn                 `json:"turns"`
      Success   bool                   `json:"success"`
      AgentType string                 `json:"agent_type"`
      Timestamp string                 `json:"timestamp"`
      Metadata  map[string]interface{} `json:"metadata"`
  }

  func storeKnowledge() ([]byte, error) {
      apiKey := os.Getenv("OSMOSIS_API_KEY")
      
      decision := Decision{
          ActionType:  "click",
          ElementName: "search_bar",
          Text:       []string{"Nike red running shoes"},
          ElementRole: "searchbox",
          Coords:     []int{120, 35},
          URL:        "https://shop.example.com",
      }
      
      decisionJSON, err := json.Marshal(decision)
      if err != nil {
          return nil, err
      }

      payload := KnowledgePayload{
          TenantID:  apiKey,
          Query:     "Find and purchase a red Nike running shoe in size 10",
          Turns: []Turn{
              {
                  Turn:     1,
                  Inputs:   "On shopping website homepage. Need to search for red Nike running shoes.",
                  Decision: string(decisionJSON),
                  Result:   "completed_successfully",
                  Memory:   "User wants red Nike running shoes. Starting search from homepage.",
              },
          },
          Success:   true,
          AgentType: "browser",
          Timestamp: time.Now().UTC().Format(time.RFC3339),
          Metadata: map[string]interface{}{
              "browser_type":                 "chrome",
              "site":                         "shopping_admin",
              "interaction_duration_seconds": 120,
          },
      }

      jsonData, err := json.Marshal(payload)
      if err != nil {
          return nil, err
      }

      req, err := http.NewRequest("POST", "https://osmosis.gulp.dev/store_knowledge", bytes.NewBuffer(jsonData))
      if err != nil {
          return nil, err
      }

      req.Header.Set("Content-Type", "application/json")
      req.Header.Set("x-api-key", apiKey)

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          return nil, err
      }
      defer resp.Body.Close()

      return json.Marshal(resp)
  }
  ```
</CodeGroup>

## Response

### Success Response

<ResponseField name="status" type="string" required>
  Status of the request (will be "accepted")
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable status message
</ResponseField>

<ResponseField name="tenant_id" type="string" required>
  The tenant ID that was used for the request
</ResponseField>

Example success response:

```json
{
  "status": "accepted",
  "message": "Knowledge upload queued for processing",
  "tenant_id": "api_key"
}
```

### Error Response

<ResponseField name="code" type="string" required>
  Error code identifying the type of error
</ResponseField>

<ResponseField name="status" type="number" required>
  HTTP status code
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable error message
</ResponseField>

<ResponseField name="details" type="object">
  Additional error details when available
</ResponseField>

Example error response:

```json
{
  "code": "validation_error",
  "status": 400,
  "message": "Invalid request body",
  "details": {
    "field": "turns",
    "error": "Must have at least one turn"
  }
}
```

## Status Codes

<ResponseStatus code={202} status="Accepted">
  Knowledge stored successfully
</ResponseStatus>

<ResponseStatus code={400} status="Bad Request">
  Invalid request (validation error)
</ResponseStatus>

<ResponseStatus code={401} status="Unauthorized">
  Invalid or missing API key
</ResponseStatus>

<ResponseStatus code={429} status="Too Many Requests">
  Rate limit exceeded
</ResponseStatus>

<ResponseStatus code={500} status="Internal Server Error">
  Internal server error
</ResponseStatus>

## Error Codes

| Code               | Description               |
| ------------------ | ------------------------- |
| `validation_error` | Request validation failed |
| `invalid_query`    | Invalid or missing query  |
| `invalid_turns`    | Invalid turns array       |
| `invalid_metadata` | Invalid metadata format   |
| `storage_error`    | Error storing knowledge   |
| `internal_error`   | Internal server error     |

## Best Practices

1. **Turn Numbers**
   * Ensure turn numbers are sequential
   * Always start from 1
   * Avoid gaps in the sequence
   * For single-turn agents, use turn number 1

2. **Input Documentation**
   * Document all available tools and options in the `inputs` field
   * List each tool/option on a new line
   * Include relevant observations and context

3. **Memory Management**
   * Use the `memory` field to track important context
   * Include relevant RAG results
   * Document key decisions and user intent
