# For Builders

### **Introduction**

The **DIVS Python SDK** enables developers to integrate **trustless image claim verification** directly into their applications, bots, browser extensions, or moderation tools. This guide helps you make your **first verification request in under 5 minutes**, giving you access to decentralized image analysis powered by independent Vision-Language Model (VLM) nodes.

***

### **1️⃣ Prerequisites**

Before you start, you’ll need:

* ✅ An **account on Witness Chain:** [Sign up here](https://playgrounds.infinitywatch.ai/)
* ✅ An **API key** : Generate from this [dashboard](https://playgrounds.infinitywatch.ai/manage-apis)

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

{% hint style="info" %}
Copy the generated key (prefixed `wtns_`)
{% endhint %}

* ✅ A **Python 3.10.17+ environment**

```
python -m venv witnesschain_env
source witnesschain_env/bin/activate
python --version 
python3 --version 
pip --version
```

* ✅ A publicly accessible image URL or base64-encoded image

***

### **2️⃣ Install the SDK**

Install the official Witness SDK via PyPI

```bash
pip install witnesschain
```

Verify installation:

```bash
python -c "import witnesschain; print('witnesschain imported successfully')"
```

***

***

### 3️⃣ **Verify Your Image**

#### **Option 1 – Public Image URL**

```python
import asyncio
from infinitywatch import Infinitywatch

API_KEY = "YOUR_WITNESSCHAIN_DIVS_KEY_HERE"

async def main():
    client = Infinitywatch(api_key=API_KEY)

    async for node_response in client.query(
        "what does this image suggest?",
        models=["Qwen/Qwen2.5-VL-7B-Instruct"],
        inputs=["https://img.freepik.com/premium-psd/peanut-butter-png-transparent_955012-13366.jpg?w=360"],  # Publicly accessible URL
    ):
        print(node_response.model_response)

if __name__ == "__main__":
    asyncio.run(main())
```

***

#### **Option 2 – Local File Path (from your script's directory)** ✅

```python
import asyncio
from infinitywatch import Infinitywatch

API_KEY = "YOUR_WITNESSCHAIN_DIVS_KEY_HERE"

async def main():
    client = Infinitywatch(api_key=API_KEY)

    async for node_response in client.query(
        "what does this image suggest?",
        models=["Qwen/Qwen2.5-VL-7B-Instruct"],
        inputs=["./peanut-butter.png"],  # Local file in the same directory
    ):
        print(node_response.model_response)

if __name__ == "__main__":
    asyncio.run(main())
```

***

#### **Option 3 – Base64-Encoded Image**

```python
import asyncio
import base64
from infinitywatch import Infinitywatch

API_KEY = "YOUR_WITNESSCHAIN_DIVS_KEY_HERE"

async def main():
    client = Infinitywatch(api_key=API_KEY)

    # Convert image to base64
    with open("./peanut-butter.png", "rb") as f:
        img_base64 = base64.b64encode(f.read()).decode("utf-8")

    async for node_response in client.query(
        "what does this image suggest?",
        models=["Qwen/Qwen2.5-VL-7B-Instruct"],
        inputs=[img_base64],  # Base64 string instead of file path
    ):
        print(node_response.model_response)

if __name__ == "__main__":
    asyncio.run(main())
```

***

✅ **Key Points:**

* You can pass **URLs**, **local file paths**, or **base64 strings** interchangeably in `inputs=[...]`.
* Local files are easiest for dev environments; URLs are useful for remote images; base64 works well for in-memory or private images.

***

### 4️⃣ **Sample Output**

```
InfinitywatchNodeResponse (
   node_id='IPv4/0x0b54e605b867eba82602fee2dfcb76204177fe0a', 
   model_response='The image suggests a spoonful of peanut butter, which is often associated with    snacks or meals that include this popular spread.', 
   model='Qwen/Qwen2.5-VL-7B-Instruct', 
   challenge_id='394f4756-c390-4587-be7b-1e35c736b056'
)
```

***

### **5️⃣ Advanced Usage**

#### Verify Multiple Images

```python
async for resp in client.query(
    "Describe what’s happening in these frames.",
    models=["HuggingFaceTB/SmolVLM2-2.2B-Instruct"],
    inputs=["./frame1.jpeg", "./frame2.jpeg", "./frame3.jpeg"],
):
    ...
```

***

#### Custom options

```python
async for resp in client.query(
    "Summarize this diagram.",
    models=["THUDM/GLM-4.1V-9B-Thinking"],
    inputs=["https://example.com/image.png"],
    model_parameters = {
        max_tokens=512,              
        temperature=0.3,
    }             
):
    ...
```

***

### **6️⃣ Best Practices**

* **Cache Results:** Avoid repeated verifications for the same image+claim pair.

***

### **7️⃣ Example Use Cases**

* **Fact-checking bots:** Validate viral images before sharing.
* **News authenticity tools:** Detect manipulated or miscaptioned images.
* **Moderation pipelines:** Flag potentially misleading visuals.
* **Browser extensions:** Give end-users quick access to decentralized verification results.

***

### **8️⃣** Troubleshooting

* **`ModuleNotFoundError: No module named 'witnesschain'`** Ensure you ran `pip install witnesschain` in the same environment.
* **Authentication errors**
  * Check that `WITNESSCHAIN_API_KEY` matches exactly the string on your dashboard.
  * Confirm you haven’t accidentally revoked the key or has been expired.
* **Slow or no responses**
  * Verify your network connectivity.
  * Check the challenge\_id for more insights

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.witnesschain.com/infinity-watch/proof-of-model-testnet/for-builders.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
