Skip to content

Quick Start for Developers

Create your first photo request via API in 5 minutes.

Prerequisites

Before you begin, make sure you have:

  • An active Visiono account with API access
  • An API key created
  • A webhook endpoint ready (or use webhook.site for testing)

Step 1: Create a Photo Request

Use the API to create a one-time photo request:

bash
curl -X POST "https://www.visiono.iohttps://www.visiono.io/en/docs/api/v1/photo-requests" \
  -H "X-API-Key: vsk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Please photograph the package from all sides",
    "expires_in_hours": 24
  }'

Expected Response

json
{
  "data": {
    "id": "req_abc123",
    "unique_code": "ABC123",
    "status": "pending",
    "instructions": "Please photograph the package from all sides",
    "request_url": "https://visio.now/p/abc123",
    "code_entry_url": "https://visio.now/code",
    "expires_at": "2024-01-16T10:00:00Z",
    "created_at": "2024-01-15T10:00:00Z",
    "items": []
  }
}

Key fields in the response:

FieldDescription
idUnique request identifier
request_urlShare this link with your customer
unique_codeShort code for manual entry at code_entry_url
expires_atWhen the request expires

Send the request_url from the response to your customer via SMS, email, or any messaging channel.

When the customer opens the link:

  1. They see your instructions
  2. Camera activates (no gallery access)
  3. They take the required photos
  4. Photos are submitted to your workspace

Camera-Only

Customers can only use their device camera — no gallery uploads. This ensures authentic, real-time photos.

Step 3: Receive the Webhook

When photos are submitted, Visiono sends a webhook to your configured endpoint.

Set Up Your Webhook Handler

Create a simple Express server to receive webhooks:

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

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

app.post('/webhook', (req, res) => {
  // 1. Verify signature
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);
  const expected = 'sha256=' + crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
    console.error('Invalid webhook signature');
    return res.status(401).send('Invalid signature');
  }

  // 2. Acknowledge immediately
  res.status(200).send('OK');

  // 3. Process the event
  const { event, data } = req.body;

  if (event === 'photo_request.submitted') {
    console.log('Request ID:', data.id);
    console.log('Photos received:');

    data.photos.forEach((photo, index) => {
      console.log(`  ${index + 1}. ${photo.url}`);
      if (photo.metadata?.gps_lat) {
        console.log(`     GPS: ${photo.metadata.gps_lat}, ${photo.metadata.gps_lng}`);
      }
    });
  }
});

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

Webhook Payload Example

json
{
  "event": "photo_request.submitted",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "id": "req_abc123",
    "type": "one_time",
    "instructions": "Please photograph the package from all sides",
    "photos": [
      {
        "id": "photo_xyz789",
        "url": "https://storage.visiono.io/photos/xyz789.jpg",
        "metadata": {
          "gps_lat": 45.4642,
          "gps_lng": 9.1900,
          "captured_at": "2024-01-15T10:28:00Z"
        }
      }
    ],
    "submitted_at": "2024-01-15T10:30:00Z"
  }
}

Testing Webhooks

Use webhook.site to get a temporary endpoint for testing. You can see incoming payloads in real-time without setting up a server.

Step 4: Download Photos

Photo URLs in the webhook payload are direct download links:

bash
# Download a photo
curl -O "https://storage.visiono.io/photos/xyz789.jpg"

Or programmatically in your webhook handler:

javascript
const https = require('https');
const fs = require('fs');

function downloadPhoto(url, filename) {
  const file = fs.createWriteStream(filename);
  https.get(url, (response) => {
    response.pipe(file);
    file.on('finish', () => file.close());
  });
}

// In your webhook handler
data.photos.forEach((photo, index) => {
  downloadPhoto(photo.url, `photo_${index + 1}.jpg`);
});

Test Your Setup

Use this checklist to verify everything works:

TestHow to Verify
API key worksGET https://www.visiono.io/en/docs/api/v1/ping returns 200 OK
Request createdResponse contains request_url and unique_code
Link accessibleOpen request_url in browser, camera activates
Webhook configuredCreate webhook in dashboard
Webhook receivesTest event arrives at your endpoint
Signature validHandler returns 200, not 401

Quick API Test

bash
# Test your API key
curl -X GET "https://www.visiono.iohttps://www.visiono.io/en/docs/api/v1/ping" \
  -H "X-API-Key: vsk_live_your_api_key_here"

Expected response:

json
{
  "message": "pong",
  "timestamp": "2024-01-15T10:00:00Z"
}

Next Steps

Now that you have the basics working:

Need help? Check the API Reference for detailed endpoint documentation, or configure Webhooks for all available events.

Professional Photo Documentation Platform