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:
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
{
"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:
| Field | Description |
|---|---|
id | Unique request identifier |
request_url | Share this link with your customer |
unique_code | Short code for manual entry at code_entry_url |
expires_at | When the request expires |
Step 2: Share the Link
Send the request_url from the response to your customer via SMS, email, or any messaging channel.
When the customer opens the link:
- They see your instructions
- Camera activates (no gallery access)
- They take the required photos
- 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:
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
{
"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:
# Download a photo
curl -O "https://storage.visiono.io/photos/xyz789.jpg"Or programmatically in your webhook handler:
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:
| Test | How to Verify |
|---|---|
| API key works | GET https://www.visiono.io/en/docs/api/v1/ping returns 200 OK |
| Request created | Response contains request_url and unique_code |
| Link accessible | Open request_url in browser, camera activates |
| Webhook configured | Create webhook in dashboard |
| Webhook receives | Test event arrives at your endpoint |
| Signature valid | Handler returns 200, not 401 |
Quick API Test
# 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:
{
"message": "pong",
"timestamp": "2024-01-15T10:00:00Z"
}Next Steps
Now that you have the basics working:
- Webhooks — Configure all available events
- Permanent Links — Create reusable links for ongoing collection
- Photo Slots — Request specific photos with instructions
- API Reference — Full endpoint documentation
Need help? Check the API Reference for detailed endpoint documentation, or configure Webhooks for all available events.
