Base URL

https://sightlinks.org/api
Additional Information:
  • Maximum file size: 5GB
  • CORS enabled for all origins with credentials support
  • Preflight requests cached for 24 hours
  • Supports methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
  • Background tasks: cleanup thread for removing old files and queue processor thread for handling tasks
  • Error responses include stack traces in development mode
  • All endpoints support error handling with appropriate status codes
  • Task errors are tracked and reported via the status API endpoint
  • File operations are logged for debugging and monitoring
  • ZIP file integrity is verified before download

Data Sources and Format Requirements

Image Data with Georeferencing

Image data must include a world file (JGW) alongside each image to provide georeferencing information. World files include coordinate transformation parameters that position the image in a geographic space.

Example: if you have "image01.jpg", you must also have "image01.jgw" or "image01.jpgw" in the same directory.

GeoTIFF Format

GeoTIFF files (.tif, .tiff) contain both image data and embedded georeferencing information in a single file. These files include geographical metadata like coordinate system information, map projection, and coordinate reference points.

Recommended Sources: USGS Earth Explorer, Digimap (UK academic institutions), OpenAerialMap, and Sentinel Hub.

File Organization Recommendations

File Structure

  • Group related images together in a single ZIP file
  • Keep world files (.jgw) in the same directory as their corresponding images
  • Avoid deeply nested folder structures within ZIP files

Image Requirements

  • Ensure all images are in the same coordinate system/projection
  • For best results, use high-resolution imagery (≤ 0.5m/pixel)
  • Maintain consistent naming conventions for image and world files
  • Verify file permissions are set correctly before uploading
Best Practices
  • Use descriptive filenames that indicate location or content
  • Include metadata files when available (e.g., projection information)
  • Test with a small subset of files before processing large datasets
  • Keep backup copies of original files before processing
  • Consider using a consistent directory structure across projects

System Workflow and Specifications

File Management

  • Each task creates a unique session ID: timestamp_uuid
  • Files are uploaded to: input/{session_id}/
  • Processing results saved to: run/output/{session_id}/
  • Results are compressed into ZIP with standardized name format
  • ZIP files always download as result_YYYYMMDD.zip with current date
  • ZIP file integrity is verified after creation
  • Original directories are deleted after successful compression

Task Execution

  • Tasks use execute() function with various parameters
  • Tasks can be cancelled at any time during processing
  • Cancellation checks happen at key processing points
  • Cancelled tasks are immediately terminated
  • All resources (directories) are cleaned up after tasks
  • Output files retained for download based on configured time limit

Supported Features

Core Features

  • Maximum file size: 5GB
  • CORS enabled for all origins with credentials support
  • Preflight requests cached for 24 hours

API Features

  • Supports methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
  • Error responses include stack traces in development mode
  • ZIP file integrity is verified before download

Download Behavior

Response Types

  • When objects detected: Returns a ZIP file with results
  • When no objects detected: Returns a text file instead of ZIP
  • X-Has-Detections header indicates if objects were found
  • X-Total-Detections header provides count when available

Token Management

  • Tokens are generated using JWT with 2-hour expiration
  • Token payload includes session_id and task_id
  • Tokens are required for downloading results
  • Tokens are validated before each download

Parameter Validation

Input Configuration

  • input_type

    Must be '0' (Image Data) or '1' (GeoTIFF Data)

  • yolo_model_type

    String 'n', 's', or 'm', default 'm'

Processing Parameters

  • classification_threshold

    String representation of float, default '0.35'

  • prediction_threshold

    String representation of float, default '0.5'

Output Options

  • save_labeled_image

    String 'true' or 'false', default 'false'

  • output_type

    String '0' (JSON) or '1' (TXT), default '0'

API Endpoints

Test API

GET POST
https://sightlinks.org/api/test

Test endpoint to verify API functionality and server status

Example Request
curl -X GET 'https://sightlinks.org/api/test'
const response = await fetch('https://sightlinks.org/api/test', {
  method: 'GET'
});
import requests

response = requests.get('https://sightlinks.org/api/test')

Response

{
  "status": "operational",
  "version": "1.0.0",
  "timestamp": "ISO-8601 timestamp",
  "endpoints": {
    "test": "/test",
    "predict": "/predict",
    "web_predict": "/web/predict",
    "status": "/web/status/",
    "download": "/download/"
  },
  "models": {
    "yolo_n": true,
    "yolo_s": true,
    "yolo_m": true,
    "mobilenet": true,
    "vgg16": true
  },
  "directories": {
    "run_output": true,
    "run_extract": true,
    "input": true,
    "models": true
  },
  "cuda": {
    "available": true,
    "device_count": 1,
    "device_name": "NVIDIA GeForce RTX 3080"
  },
  "system": {
    "cpu_percent": 23.5,
    "memory_percent": 45.2,
    "disk_percent": 68.7
  }
}
Notes
  • If POST method is used, the response will include an "echo" field with POSTed JSON data
  • If POST method is used, the response will include a "files" array with details of uploaded files if present

Direct Processing API

POST
https://sightlinks.org/api/predict

Synchronously processes uploaded files and returns results immediately

Example Request
curl -X POST 'https://sightlinks.org/api/predict' \
  -F "files=@your_file.zip" \
  -F "input_type=0" \
  -F "classification_threshold=0.35" \
  -F "prediction_threshold=0.5" \
  -F "save_labeled_image=false" \
  -F "output_type=0" \
  -F "yolo_model_type=m"
const formData = new FormData();
formData.append('files', fileInput.files[0]);
formData.append('input_type', '0');
formData.append('classification_threshold', '0.35');
formData.append('prediction_threshold', '0.5');
formData.append('save_labeled_image', 'false');
formData.append('output_type', '0');
formData.append('yolo_model_type', 'm');

const response = await fetch('https://sightlinks.org/api/predict', {
  method: 'POST',
  body: formData
});
import requests

files = {'files': open('your_file.zip', 'rb')}
data = {
    'input_type': '0',
    'classification_threshold': '0.35',
    'prediction_threshold': '0.5',
    'save_labeled_image': 'false',
    'output_type': '0',
    'yolo_model_type': 'm'
}

response = requests.post('https://sightlinks.org/api/predict',
                        files=files,
                        data=data)

Response

{
  "status": "success",
  "message": "Processing completed",
  "output_path": "string"
}
Error Responses
400
{
  "error": "string"
}

Web Processing API (Queued)

POST
https://sightlinks.org/api/web/predict

Asynchronously processes files with progress tracking

Example Request
curl -X POST 'https://sightlinks.org/api/web/predict' \
  -F "files=@your_file.zip" \
  -F "input_type=0" \
  -F "classification_threshold=0.35" \
  -F "prediction_threshold=0.5" \
  -F "save_labeled_image=false" \
  -F "output_type=0" \
  -F "yolo_model_type=m"
const formData = new FormData();
formData.append('files', fileInput.files[0]);
formData.append('input_type', '0');
formData.append('classification_threshold', '0.35');
formData.append('prediction_threshold', '0.5');
formData.append('save_labeled_image', 'false');
formData.append('output_type', '0');
formData.append('yolo_model_type', 'm');

const response = await fetch('https://sightlinks.org/api/web/predict', {
  method: 'POST',
  body: formData
});
import requests

files = {'files': open('your_file.zip', 'rb')}
data = {
    'input_type': '0',
    'classification_threshold': '0.35',
    'prediction_threshold': '0.5',
    'save_labeled_image': 'false',
    'output_type': '0',
    'yolo_model_type': 'm'
}

response = requests.post('https://sightlinks.org/api/web/predict',
                        files=files,
                        data=data)

Response

{
  "task_id": "string",
  "message": "Task queued successfully"
}
Error Responses
503
{
  "error": "Server is busy. Please try again later."
}

Task Status

GET
https://sightlinks.org/api/web/status/{task_id}

Get task status and progress

Example Request
curl -X GET 'https://sightlinks.org/api/web/status/your_task_id'
const response = await fetch('https://sightlinks.org/api/web/status/your_task_id', {
  method: 'GET'
});
import requests

response = requests.get('https://sightlinks.org/api/web/status/your_task_id')

Response

{
  "completed": false,
  "download_token": "string (included only when completed is true)",
  "has_detections": true,
  "total_detections": 42
}
Notes
  • When completed is false, the task is either queued, processing, failed, or cancelled
  • When completed is true, a download_token will be included for downloading results
  • When completed is true, has_detections indicates if any objects were found
  • When no objects are detected, a marker file is created but has_detections will be false
  • When has_detections is true, total_detections provides the count of all detected objects
  • When error is true, an error_message will explain what went wrong
Error Responses
404
{
  "error": "Task not found"
}

Download Results

GET
https://sightlinks.org/api/download/{token}

Download processed results using token

Example Request
curl -X GET 'https://sightlinks.org/api/download/your_download_token' \
  -H "Accept: application/zip"
const response = await fetch('https://sightlinks.org/api/download/your_download_token', {
  method: 'GET',
  headers: {
    'Accept': 'application/zip'
  }
});
import requests

headers = {'Accept': 'application/zip'}
response = requests.get('https://sightlinks.org/api/download/your_download_token',
                       headers=headers)

Response Headers

{
  "Content-Type": "application/zip or text/plain",
  "Content-Disposition": "attachment; filename=result_YYYYMMDD.zip or filename=result_YYYYMMDD.txt",
  "Content-Length": "file size in bytes",
  "X-Has-Detections": "true or false",
  "X-Total-Detections": "count (when available)"
}
Notes
  • Tokens are generated using JWT (JSON Web Tokens)
  • Token payload includes session_id and task_id
  • Tokens expire after 2 hours (MAX_TOKEN_AGE_HOURS)
  • Tokens are verified using auth_handler.verify_download_token
  • ZIP file integrity is verified before sending
  • When no objects are detected in any image, a text file is returned instead of a ZIP
  • The X-Has-Detections header can be used to determine if any detections were found
  • Clients should check the Task Status endpoint before downloading to know what to expect
Error Responses
401
{
  "error": "Invalid token or token payload"
}

404
{
  "error": "Task or ZIP file not found"
}

500
{
  "error": "ZIP file corrupted or empty"
}

Cancel Task

POST
https://sightlinks.org/api/web/cancel/{task_id}

Cancel a running or queued task

Example Request
curl -X POST 'https://sightlinks.org/api/web/cancel/your_task_id'
const response = await fetch('https://sightlinks.org/api/web/cancel/your_task_id', {
  method: 'POST'
});
import requests

response = requests.post('https://sightlinks.org/api/web/cancel/your_task_id')

Response

{
  "status": "success",
  "message": "Task cancelled successfully"
}
Notes
  • Sets cancellation flag on task
  • Removes task from processing queue if queued
  • Terminates execution if task is processing
  • Cleans up input/output folders for the task
  • Cleans up extract directory if it exists
  • Immediately stops any ongoing processing
Error Responses
404
{
  "error": "Task not found or cannot be cancelled"
}

Server Status

GET
https://sightlinks.org/api/server-status

Get current server status and statistics

Example Request
curl -X GET 'https://sightlinks.org/api/server-status'
const response = await fetch('https://sightlinks.org/api/server-status', {
  method: 'GET'
});
import requests

response = requests.get('https://sightlinks.org/api/server-status')

Response

{
  "uptime_seconds": 12345.67,
  "start_time": "ISO-8601 timestamp",
  "max_concurrent_tasks": 4,
  "max_queue_size": 10,
  "memory_usage_mb": 1024.5,
  "cpu_usage_percent": 45.2,
  "active_tasks": 3,
  "processing_tasks": 2,
  "queue_size": 1,
  "queued_task_ids": [
    "task_id_1"
  ],
  "processing_task_ids": [
    "task_id_2",
    "task_id_3"
  ],
  "total_tasks": 100,
  "completed_tasks": 85,
  "failed_tasks": 10,
  "cancelled_tasks": 5
}