cURL Examples

Complete cURL examples for testing and integrating with LoomAPI.

cURL Examples

Complete cURL command examples for testing LoomAPI endpoints, from basic verification to advanced webhook handling.

Prerequisites

All examples assume you have:

  • curl installed (comes with most systems)
  • A LoomAPI account and API key
  • Test document files (images or PDFs)
# Store your API key for reuse
export LOOM_API_KEY="your_api_key_here"

# Function to encode file to base64
encode_file() {
  base64 -w 0 "$1"  # Linux/macOS
  # On Windows: certutil -encodehex "$1" /f
}

Basic Verification

Simple Age Verification

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "passport",
    "document_data": "'$(encode_file document.jpg)'"
  }'

Expected Response:

{
  "request_id": "req_1234567890abcdef",
  "status": "verified",
  "verified_age": 25,
  "confidence_score": 0.98,
  "document_type": "passport",
  "processing_time_ms": 2340
}

Full Document Verification

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "drivers_license",
    "document_data": "'$(encode_file license.jpg)'",
    "verification_type": "full_verification"
  }'

Test Mode (No Quota Usage)

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "national_id",
    "document_data": "'$(encode_file id_card.jpg)'",
    "test_mode": true
  }'

Asynchronous Verification

With Webhook Notifications

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "passport",
    "document_data": "'$(encode_file document.jpg)'",
    "webhook_url": "https://your-app.com/webhooks/verification"
  }'

Immediate Response:

{
  "request_id": "req_1234567890abcdef",
  "status": "processing",
  "estimated_time_seconds": 30,
  "webhook_url": "https://your-app.com/webhooks/verification"
}

Later Webhook Payload:

{
  "event": "verification.completed",
  "request_id": "req_1234567890abcdef",
  "timestamp": "2024-01-15T14:30:00Z",
  "verification": {
    "status": "verified",
    "verified_age": 25,
    "confidence_score": 0.98,
    "document_type": "passport",
    "processing_time_ms": 2340
  }
}

Batch Verification

curl -X POST https://api.loomapi.com/v1/verify/batch \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "documents": [
      {
        "document_type": "passport",
        "document_data": "'$(encode_file passport1.jpg)'",
        "reference_id": "user_123"
      },
      {
        "document_type": "drivers_license",
        "document_data": "'$(encode_file license1.jpg)'",
        "reference_id": "user_456"
      }
    ],
    "webhook_url": "https://your-app.com/webhooks/batch-verification"
  }'

Error Scenarios

Invalid API Key

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer invalid_key" \
  -H "Content-Type: application/json" \
  -d '{"document_type": "passport", "document_data": "fake_data"}'

Response:

{
  "request_id": "req_1234567890abcdef",
  "error": {
    "code": "AUTH_INVALID_KEY",
    "message": "The provided API key is invalid or expired"
  }
}

Document Quality Issues

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "passport",
    "document_data": "'$(encode_file blurry_photo.jpg)'"
  }'

Response:

{
  "request_id": "req_1234567890abcdef",
  "error": {
    "code": "DOCUMENT_QUALITY_LOW",
    "message": "Document quality too low for accurate processing",
    "details": {
      "issues": ["blurry", "low_resolution"],
      "min_resolution": "300x300"
    }
  }
}

Rate Limit Exceeded

# Make many requests quickly
for i in {1..150}; do
  curl -X POST https://api.loomapi.com/v1/verify \
    -H "Authorization: Bearer $LOOM_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"document_type": "passport", "document_data": "data"}' &
done

Response:

{
  "request_id": "req_1234567890abcdef",
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again in 30 seconds.",
    "details": {
      "retry_after_seconds": 30,
      "limit": 100,
      "window_seconds": 60
    }
  }
}

Advanced Examples

Custom Request IDs

REQUEST_ID="verify_user_$(date +%s)"

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "X-Request-ID: $REQUEST_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "passport",
    "document_data": "'$(encode_file document.jpg)'",
    "metadata": {
      "user_id": "user_123",
      "source": "mobile_app",
      "version": "1.2.3"
    }
  }'

With Metadata Tracking

curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "drivers_license",
    "document_data": "'$(encode_file license.jpg)'",
    "metadata": {
      "user_id": "user_123",
      "session_id": "session_abc",
      "ip_address": "'$(curl -s ifconfig.me)'",
      "user_agent": "MyApp/1.0 (curl)",
      "source": "api_test"
    }
  }'

File Upload with Proper Encoding

# Function to handle different file types
verify_document() {
  local file_path="$1"
  local doc_type="${2:-passport}"

  if [[ ! -f "$file_path" ]]; then
    echo "Error: File not found: $file_path"
    return 1
  fi

  # Check file size (10MB limit)
  local file_size=$(stat -f%z "$file_path" 2>/dev/null || stat -c%s "$file_path")
  if (( file_size > 10485760 )); then
    echo "Error: File too large (>10MB)"
    return 1
  fi

  # Encode file
  local base64_data
  if command -v base64 >/dev/null 2>&1; then
    base64_data=$(base64 -w 0 "$file_path")
  else
    echo "Error: base64 command not found"
    return 1
  fi

  # Make request
  curl -X POST https://api.loomapi.com/v1/verify \
    -H "Authorization: Bearer $LOOM_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "document_type": "'"$doc_type"'",
      "document_data": "'"$base64_data"'"
    }' | jq '.'
}

# Usage
verify_document "passport.jpg" "passport"
verify_document "license.pdf" "drivers_license"

Testing Scripts

Comprehensive Test Suite

#!/bin/bash

# LoomAPI Test Suite
# Requires: curl, jq, base64

set -e

API_KEY="${LOOM_API_KEY:?API_KEY not set}"
API_BASE="https://api.loomapi.com"

echo "๐Ÿงช Starting LoomAPI test suite..."

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log() {
  echo -e "${GREEN}[$(date +%T)] $1${NC}"
}

error() {
  echo -e "${RED}[$(date +%T)] ERROR: $1${NC}" >&2
}

warning() {
  echo -e "${YELLOW}[$(date +%T)] WARNING: $1${NC}"
}

# Test 1: Status check
log "Testing API status..."
status=$(curl -s -w "%{http_code}" -o /tmp/status.json "$API_BASE/v1/status" \
  -H "Authorization: Bearer $API_KEY")

if [[ "$status" == "200" ]]; then
  log "โœ… API status check passed"
else
  error "API status check failed with code $status"
  cat /tmp/status.json
  exit 1
fi

# Test 2: Invalid key
log "Testing invalid API key..."
invalid_response=$(curl -s "$API_BASE/v1/verify" \
  -H "Authorization: Bearer invalid_key" \
  -H "Content-Type: application/json" \
  -d '{"document_type": "passport", "document_data": "fake"}')

if echo "$invalid_response" | jq -e '.error.code == "AUTH_INVALID_KEY"' >/dev/null; then
  log "โœ… Invalid key test passed"
else
  error "Invalid key test failed"
  echo "$invalid_response"
fi

# Test 3: Test mode verification
log "Testing test mode verification..."
test_response=$(curl -s "$API_BASE/v1/verify" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "passport",
    "document_data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
    "test_mode": true
  }')

if echo "$test_response" | jq -e '.status == "verified"' >/dev/null; then
  log "โœ… Test mode verification passed"
else
  warning "Test mode verification failed or returned unexpected result"
  echo "$test_response"
fi

# Test 4: Rate limit test (optional, commented out by default)
# log "Testing rate limits..."
# for i in {1..5}; do
#   curl -s "$API_BASE/v1/verify" \
#     -H "Authorization: Bearer $API_KEY" \
#     -H "Content-Type: application/json" \
#     -d '{"document_type": "passport", "document_data": "fake"}' >/dev/null &
# done
# wait
# log "Rate limit test completed"

log "๐ŸŽ‰ All tests completed!"

Load Testing

#!/bin/bash

# Simple load test for LoomAPI
# Usage: ./load_test.sh [concurrency] [requests_per_thread]

CONCURRENCY=${1:-10}
REQUESTS=${2:-10}
API_KEY="${LOOM_API_KEY:?API_KEY not set}"

echo "๐Ÿš€ Starting load test: $CONCURRENCY threads ร— $REQUESTS requests"

make_request() {
  local thread_id=$1
  local request_id=$2

  local start_time=$(date +%s%3N)

  local response=$(curl -s -w "HTTPSTATUS:%{http_code};TIME:%{time_total}" \
    "https://api.loomapi.com/v1/verify" \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "document_type": "passport",
      "document_data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
      "test_mode": true,
      "metadata": {
        "test_id": "'$thread_id'_'$request_id'",
        "load_test": true
      }
    }')

  local end_time=$(date +%s%3N)
  local http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
  local time_total=$(echo "$response" | grep -o "TIME:[0-9.]*" | cut -d: -f2)

  echo "Thread $thread_id, Request $request_id: HTTP $http_code, Time ${time_total}s"
}

export -f make_request

# Run load test
for thread in $(seq 1 $CONCURRENCY); do
  for request in $(seq 1 $REQUESTS); do
    make_request "$thread" "$request" &
  done
done

wait

echo "โœ… Load test completed"

Webhook Testing

Local Webhook Server

#!/bin/bash

# Simple webhook test server
# Usage: ./webhook_server.sh [port]

PORT=${1:-3000}

echo "๐ŸŽฃ Starting webhook server on port $PORT..."

# Create a simple HTTP server using netcat or nc
while true; do
  echo "Listening on port $PORT..."
  nc -l -p $PORT -c '
    read request
    echo "HTTP/1.1 200 OK"
    echo "Content-Type: application/json"
    echo ""
    echo "{\"received\": true, \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}"
  ' 2>/dev/null || echo "Connection handled"
done

Test Webhook Delivery

# Start local webhook server in background
./webhook_server.sh 3000 &

# Make verification request with webhook
curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_type": "passport",
    "document_data": "'$(encode_file test_document.jpg)'",
    "webhook_url": "http://localhost:3000/webhook"
  }'

# Wait for webhook delivery
sleep 5

# Kill webhook server
pkill -f webhook_server.sh

echo "๐Ÿงช Webhook test completed"

Utility Scripts

Base64 Encoding Helper

#!/bin/bash

# encode_file.sh - Safely encode files for LoomAPI

set -e

if [[ $# -ne 1 ]]; then
  echo "Usage: $0 <file_path>"
  exit 1
fi

FILE_PATH="$1"

if [[ ! -f "$FILE_PATH" ]]; then
  echo "Error: File not found: $FILE_PATH"
  exit 1
fi

# Check file size (10MB = 10485760 bytes)
FILE_SIZE=$(stat -f%z "$FILE_PATH" 2>/dev/null || stat -c%s "$FILE_SIZE")
if (( FILE_SIZE > 10485760 )); then
  echo "Error: File too large (>10MB): $FILE_SIZE bytes"
  exit 1
fi

# Check MIME type
MIME_TYPE=$(file -b --mime-type "$FILE_PATH" 2>/dev/null || echo "unknown")
if [[ "$MIME_TYPE" != image/* && "$MIME_TYPE" != application/pdf ]]; then
  echo "Warning: Unsupported file type: $MIME_TYPE"
fi

# Encode and output
base64 -w 0 "$FILE_PATH"
echo "" # Add newline

Response Parser

#!/bin/bash

# parse_response.sh - Parse and format LoomAPI responses

set -e

if [[ $# -lt 1 ]]; then
  echo "Usage: $0 <response_file> [format]"
  echo "Formats: summary, full, errors"
  exit 1
fi

RESPONSE_FILE="$1"
FORMAT="${2:-summary}"

if [[ ! -f "$RESPONSE_FILE" ]]; then
  echo "Error: Response file not found: $RESPONSE_FILE"
  exit 1
fi

# Parse JSON response
if ! jq empty "$RESPONSE_FILE" 2>/dev/null; then
  echo "Error: Invalid JSON in response file"
  exit 1
fi

case "$FORMAT" in
  "summary")
    jq -r '
      if .error then
        "โŒ Error: \(.error.code) - \(.error.message)"
      elif .status == "verified" then
        "โœ… Verified: Age \(.verified_age), Confidence \(.confidence_score * 100 | round)%"
      elif .status == "processing" then
        "โณ Processing: Request \(.request_id), ETA \(.estimated_time_seconds)s"
      else
        "โ“ Unknown status: \(.status)"
      end
    ' "$RESPONSE_FILE"
    ;;

  "full")
    jq '.' "$RESPONSE_FILE"
    ;;

  "errors")
    jq -r '
      if .error then
        "Error Code: \(.error.code)\nMessage: \(.error.message)\nDetails: \(.error.details // "None")"
      else
        "No errors found"
      end
    ' "$RESPONSE_FILE"
    ;;

  *)
    echo "Unknown format: $FORMAT"
    exit 1
    ;;
esac

Usage Examples

# Encode a file
BASE64_DATA=$(./encode_file.sh document.jpg)

# Make verification request
curl -X POST https://api.loomapi.com/v1/verify \
  -H "Authorization: Bearer $LOOM_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"document_type\": \"passport\", \"document_data\": \"$BASE64_DATA\"}" \
  > response.json

# Parse response
./parse_response.sh response.json summary

# Run test suite
./test_suite.sh

# Load test
./load_test.sh 5 20  # 5 concurrent threads, 20 requests each

These cURL examples provide comprehensive testing and integration options for LoomAPI, from basic verification to advanced load testing and webhook handling.