New:Thread Pilot—AI follow-ups for Gmail.
Learn more
← Verify AIAPI Documentation
Dashboard

Verify AI API

Submit photos for AI-powered compliance verification. Get structured results with confidence scores, violation details, and user feedback.

Base URL: https://www.switchlabs.dev/api/verify-ai/v1

Authentication

All API requests require an API key passed via the X-API-Key header.

bash
curl https://www.switchlabs.dev/api/verify-ai/v1/verifications \
  -H "X-API-Key: vai_your_api_key_here"

Get your API key from the sign-up page or your dashboard settings.

Submit Verification

Submit a photo for AI analysis. Accepts multipart form-data or JSON with base64 image.

Request Parameters

ParameterTypeRequiredDescription
imagefile | base64YesThe image to verify (JPEG, PNG, WebP, max 10MB)
policystringYesPolicy ID (e.g., scooter_parking, damage_detection, delivery_pod)
metadataobjectNoArbitrary metadata to attach (device_id, user_id, gps, etc.)
providerstringNoAI provider override: "openai", "anthropic", or "gemini"

Example: Multipart Form-Data

bash
curl -X POST https://www.switchlabs.dev/api/verify-ai/v1/verify \
  -H "X-API-Key: vai_your_api_key" \
  -F "image=@photo.jpg" \
  -F "policy=scooter_parking" \
  -F 'metadata={"device_id":"dev_123","gps":{"lat":37.77,"lng":-122.42}}'

Example: JSON with Base64

bash
curl -X POST https://www.switchlabs.dev/api/verify-ai/v1/verify \
  -H "X-API-Key: vai_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "data:image/jpeg;base64,/9j/4AAQ...",
    "policy": "scooter_parking",
    "metadata": {"device_id": "dev_123"}
  }'

Response

json
{
  "id": "ver_8x92m4k9",
  "created_at": "2026-01-10T14:30:00Z",
  "status": "success",
  "is_compliant": false,
  "confidence": 0.98,
  "policy": "scooter_parking",
  "violation_reasons": ["blocking_sidewalk", "kickstand_up"],
  "feedback": "Please deploy the kickstand and move away from the walkway.",
  "metadata": {
    "device_id": "dev_123",
    "gps": {"lat": 37.77, "lng": -122.42}
  },
  "image_url": "https://...signed-url..."
}

List Verifications

Retrieve a paginated list of past verifications. Results are scoped to your API key.

Query Parameters

ParameterTypeRequiredDescription
limitintegerNoResults per page (default 20, max 100)
cursorstringNoPagination cursor (created_at of last item)
policystringNoFilter by policy ID
statusstringNoFilter by status (success, error)
is_compliantbooleanNoFilter by compliance result
start_dateISO dateNoFilter: created after this date
end_dateISO dateNoFilter: created before this date

Response

json
{
  "data": [
    {
      "id": "ver_8x92m4k9",
      "created_at": "2026-01-10T14:30:00Z",
      "status": "success",
      "is_compliant": false,
      "confidence": 0.98,
      "policy": "scooter_parking",
      "violation_reasons": ["blocking_sidewalk"],
      "feedback": "...",
      "metadata": {},
      "image_url": "https://...signed-url..."
    }
  ],
  "has_more": true,
  "next_cursor": "2026-01-10T14:30:00Z"
}

Get Verification

Retrieve full details of a specific verification, including a fresh signed image URL.

Example

bash
curl https://www.switchlabs.dev/api/verify-ai/v1/verifications/ver_8x92m4k9 \
  -H "X-API-Key: vai_your_api_key"

Webhooks

Configure webhooks to receive queued notifications when verifications complete. Deliveries are processed every 5 minutes from your dashboard settings.

Payload Format

json
{
  "event": "verification.completed",
  "data": {
    "id": "ver_8x92m4k9",
    "created_at": "2026-01-10T14:30:00Z",
    "status": "success",
    "is_compliant": false,
    "confidence": 0.98,
    "policy": "scooter_parking",
    "violation_reasons": ["blocking_sidewalk"],
    "feedback": "Please move away from the walkway.",
    "metadata": {},
    "image_url": "https://...signed-url..."
  }
}

Signature Verification

Each delivery includes an X-VerifyAI-Signature header with format t=timestamp,v1=signature.

javascript
// Verify webhook signature (Node.js)
const crypto = require('crypto');

function verifySignature(payload, header, secret) {
  const [tPart, sigPart] = header.split(',');
  const timestamp = tPart.split('=')[1];
  const signature = sigPart.split('=')[1];

  const expected = crypto
    .createHmac('sha256', secret)
    .update(timestamp + '.' + payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Retry Behavior

Failed deliveries are retried up to 3 times: after 1 minute, 5 minutes, and 30 minutes. A delivery is considered successful if your endpoint returns a 2xx status code within 5 seconds.

Policies

Available verification policies:

scooter_parkingScooter Parking Compliance

Verifies electric scooter/bike parking meets city regulations. Checks: vehicle visible, upright, kickstand deployed, not blocking sidewalk or entrance, in designated area.

no_vehicle_visiblevehicle_fallenkickstand_upblocking_sidewalkblocking_entrancenot_designated_areain_roadwayimage_unclear
damage_detectionVehicle Damage Detection

Detects and documents damage to vehicles or equipment. Identifies type and severity of damage.

scratchesdentscracksbroken_partsflat_tiremissing_componentsstructural_damageelectrical_damage
delivery_podDelivery Proof of Delivery

Verifies package delivery placement and condition. Checks: package visible, at door, protected, upright, accessible.

no_package_visiblenot_at_doorexposed_to_weatherpackage_damagedblocking_pathimage_unclear

Code Examples

cURL

bash
curl -X POST https://www.switchlabs.dev/api/verify-ai/v1/verify \
  -H "X-API-Key: vai_your_api_key" \
  -F "image=@photo.jpg" \
  -F "policy=scooter_parking"

JavaScript (fetch)

javascript
const formData = new FormData();
formData.append('image', fileInput.files[0]);
formData.append('policy', 'scooter_parking');
formData.append('metadata', JSON.stringify({
  device_id: 'dev_123',
  user_id: 'usr_456',
}));

const response = await fetch(
  'https://www.switchlabs.dev/api/verify-ai/v1/verify',
  {
    method: 'POST',
    headers: { 'X-API-Key': 'vai_your_api_key' },
    body: formData,
  }
);

const result = await response.json();
console.log(result.is_compliant); // true or false
console.log(result.feedback);     // User-friendly message

Python (requests)

python
import requests
import json

response = requests.post(
    'https://www.switchlabs.dev/api/verify-ai/v1/verify',
    headers={'X-API-Key': 'vai_your_api_key'},
    files={'image': open('photo.jpg', 'rb')},
    data={
        'policy': 'scooter_parking',
        'metadata': json.dumps({
            'device_id': 'dev_123',
            'user_id': 'usr_456',
        }),
    },
)

result = response.json()
print(f"Compliant: {result['is_compliant']}")
print(f"Feedback: {result['feedback']}")

Errors & Rate Limits

HTTP Status Codes

CodeMeaning
200Success
400Bad request — missing required fields or invalid image format
401Unauthorized — invalid or missing API key
403Forbidden — no active subscription or wrong product
404Verification not found
429Rate limit exceeded
500Server error — AI processing failure

Rate Limits

LimitValue
Requests per minute60
Requests per hour1,000
Max image size10 MB

When rate limited, the response includes a Retry-After header with the number of seconds to wait.

Contact

Tell us what you're building and we'll get in touch fast

Ship a proof-of-concept, integrate Metro2, or hand off the workflow entirely—we respond within one business day and loop in the right Switch Labs partner for your stack.

Response Time
< 24 hours
Delivery Options
Product | Services

By submitting you agree to let Switch Labs contact you about relevant products and services.