# 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="https://651400886-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaZ7PXq43vesxvXxlBG9x%2Fuploads%2F22G4wkW0EVLK5RMg57SE%2Fimage.png?alt=media&#x26;token=7f77176c-c879-430f-9986-867e0b707f62" 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

***
