// API DOCUMENTATION
REST API v1 — requires Premium plan  PREMIUM

AUTHENTICATION

All API requests require your API key in the Authorization header:

Authorization: Bearer dh_your_api_key_here

Get your API key at /api-keys

BASE URL

http://ec2-98-84-96-127.compute-1.amazonaws.com

ENDPOINTS

POST/api/v1/scan
Submit an APK file for scanning. Returns a job_id immediately.
curl -X POST http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scan \
  -H "Authorization: Bearer dh_your_key" \
  -F "apk=@your_app.apk"
# Response
{"job_id": "abc-123", "status": "running"}
GET/api/v1/scan/{job_id}
Poll scan status. Call every 5-10 seconds until status is "done".
curl http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scan/abc-123 \
  -H "Authorization: Bearer dh_your_key"
# Response (running)
{"job_id": "abc-123", "status": "running", "counts": {}}

# Response (done)
{"job_id": "abc-123", "status": "done", "total_findings": 24,
 "counts": {"CRITICAL":0,"HIGH":5,"MEDIUM":8,"LOW":6,"INFO":5}}
GET/api/v1/scan/{job_id}/findings
Download full findings as JSON once scan is complete.
curl http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scan/abc-123/findings \
  -H "Authorization: Bearer dh_your_key"
GET/api/v1/scans
List all your previous scans.
curl http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scans \
  -H "Authorization: Bearer dh_your_key"

RESPONSE CODES

CodeMeaning
202Scan submitted successfully
200Success
401Invalid or missing API key
403Plan does not include API access
429Monthly scan limit reached
404Scan not found

GITHUB ACTIONS — CI/CD EXAMPLE

Add this to .github/workflows/security.yml in your repo:

name: DroidHog APK Security Scan

on:
  push:
    branches: [main]
  pull_request:

jobs:
  apk-security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build APK
        run: ./gradlew assembleRelease

      - name: Scan with DroidHog
        env:
          DROIDHOG_API_KEY: ${{ secrets.DROIDHOG_API_KEY }}
        run: |
          APK=$(find . -name "*.apk" | head -1)
          echo "Scanning $APK..."

          # Submit scan
          RESPONSE=$(curl -s -X POST \
            http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scan \
            -H "Authorization: Bearer $DROIDHOG_API_KEY" \
            -F "apk=@$APK")
          JOB_ID=$(echo $RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['job_id'])")
          echo "Job ID: $JOB_ID"

          # Poll until done
          for i in $(seq 1 60); do
            sleep 10
            STATUS=$(curl -s \
              http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scan/$JOB_ID \
              -H "Authorization: Bearer $DROIDHOG_API_KEY")
            STATE=$(echo $STATUS | python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")
            echo "Status: $STATE"
            if [ "$STATE" = "done" ]; then
              echo $STATUS | python3 -c "
import sys, json
d = json.load(sys.stdin)
c = d.get('counts', {})
print(f'CRITICAL: {c.get(\"CRITICAL\",0)}')
print(f'HIGH:     {c.get(\"HIGH\",0)}')
print(f'MEDIUM:   {c.get(\"MEDIUM\",0)}')
# Fail CI if CRITICAL or HIGH findings
if c.get('CRITICAL',0) > 0 or c.get('HIGH',0) > 0:
    sys.exit(1)
"
              break
            fi
          done

GITLAB CI EXAMPLE

# .gitlab-ci.yml
apk-security-scan:
  stage: test
  script:
    - APK=$(find . -name "*.apk" | head -1)
    - |
      RESPONSE=$(curl -s -X POST \
        http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scan \
        -H "Authorization: Bearer $DROIDHOG_API_KEY" \
        -F "apk=@$APK")
      JOB_ID=$(echo $RESPONSE | python3 -c "import sys,json; print(json.load(sys.stdin)['job_id'])")
      for i in $(seq 1 60); do
        sleep 10
        STATUS=$(curl -s \
          http://ec2-98-84-96-127.compute-1.amazonaws.com/api/v1/scan/$JOB_ID \
          -H "Authorization: Bearer $DROIDHOG_API_KEY")
        STATE=$(echo $STATUS | python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")
        [ "$STATE" = "done" ] && break
      done
      echo $STATUS | python3 -c "
import sys,json; d=json.load(sys.stdin); c=d.get('counts',{})
print(f'HIGH={c.get(\"HIGH\",0)} CRITICAL={c.get(\"CRITICAL\",0)}')
sys.exit(1 if c.get('CRITICAL',0)+c.get('HIGH',0) > 0 else 0)"
  only:
    - main
    - merge_requests

PYTHON SCRIPT EXAMPLE

import requests, time

API_KEY = "dh_your_key_here"
BASE    = "http://ec2-98-84-96-127.compute-1.amazonaws.com"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# Submit
r = requests.post(f"{BASE}/api/v1/scan",
                  headers=HEADERS,
                  files={"apk": open("app.apk", "rb")})
job_id = r.json()["job_id"]

# Poll
while True:
    time.sleep(10)
    status = requests.get(f"{BASE}/api/v1/scan/{job_id}", headers=HEADERS).json()
    if status["status"] == "done":
        break

# Get findings
findings = requests.get(f"{BASE}/api/v1/scan/{job_id}/findings", headers=HEADERS).json()
high = [f for f in findings["findings"] if f["severity"] in ("HIGH","CRITICAL")]
print(f"Found {len(high)} HIGH/CRITICAL issues")