Skip to content

DEVELOPERS

Verification as an API.

The same five-layer forensic engine behind Verifyco Web — C2PA provenance, metadata forensics, neural detection, temporal and frequency analysis — as a REST API. Send a file or a public link; get an evidence-led JSON report. Media is processed in temporary storage and removed by the request cleanup path.

private beta · manual review · no self-serve keys yet

CLI · LOCAL MCP · HOSTED MCP FOUNDATION

One report contract, three interfaces.

The repository includes a Python CLI and a local stdio MCP server that call this same versioned API; neither contains a second scorer. Local-file MCP tools require an explicit VERIFYCO_MCP_ALLOWED_ROOTSallowlist before startup. Packages are currently distributed to approved beta partners rather than a public package index.

local beta checkout
python -m pip install -e "./developer-tools[mcp]"
verifyco --help
verifyco-mcp
bounded local roots
# macOS / Linux
export VERIFYCO_MCP_ALLOWED_ROOTS="$HOME/verifyco-media:$HOME/verifyco-reports"

# Windows PowerShell
$env:VERIFYCO_MCP_ALLOWED_ROOTS="C:\\VerifycoMedia;C:\\VerifycoReports"

Never allow a filesystem root, home directory, repository or credential folder. The repository also contains a fail-closed, URL-only Streamable HTTP server. It requires OAuth introspection, exact resource audience, the verifyco:analyze scope and a tenant-bound subject. It exposes no remote file-path or upload tool; hosted availability begins only after Verifyco configures and deploys an authorization server.

Auth

X-API-Key header

Per-organization keys, rotatable on request.

Rate limits

Plan-based

Burst and sustained limits agreed per contract.

Media handling

Temporary processing

Files are removed by the analysis cleanup path. The caller receives the versioned JSON report.

POST/v1/analyze— analyze an uploaded image or video

Multipart upload. Accepts JPEG, PNG, WebP, HEIC, GIF, TIFF, BMP, MP4/MOV, WebM/MKV, AVI and MPEG-TS. File type is verified by magic bytes, not by extension. The current production ceiling is 500 MB per file; lower limits may apply by contract tier. Larger resumable uploads remain a roadmap item and are not promised before the storage/worker path is validated.

request · curl
curl -X POST https://verifyco-extractor.onrender.com/v1/analyze \
  -H "X-API-Key: vfy_live_xxxxxxxxxxxx" \
  -F "file=@suspicious_video.mp4"
illustrative response shape · 200
{
  "score": 75,
  "verdict": "inconclusive",
  "mediaType": "image",
  "contract": "verifyco-evidence/2.0",
  "fusion": "verifyco-fusion/3.0",
  "engine": "verifyco-engine/3.0",
  "bytes": 12873442,
  "layers": [
    { "layer": "c2pa",        "status": "unavailable", "score": 0.5, "reliability": 0.0,
      "provenanceState": "absent", "findings": ["No C2PA content credentials found; absence is neutral."],
      "providerAttestation": { "provider": "openai", "status": "not_detected",
        "signals": [{ "kind": "c2pa", "outcome": "not_detected" },
                    { "kind": "watermark", "outcome": "not_detected" }] } },
    { "layer": "metadata",    "status": "unavailable", "score": 0.5, "reliability": 0.0 },
    { "layer": "aiDetection", "status": "passed",      "score": 0.913, "reliability": 0.2,
      "calibration": "corroborating" },
    { "layer": "temporal",    "status": "not_applicable", "score": 0.5, "reliability": 0.0 },
    { "layer": "frequency",   "status": "warning",     "score": 0.8, "reliability": 0.0,
      "calibration": "experimental" }
  ],
  "providerSignals": [
    { "provider": "openai", "status": "not_detected",
      "signals": [{ "kind": "c2pa", "outcome": "not_detected" },
                  { "kind": "watermark", "outcome": "not_detected" }] }
  ],
  "advancedForensics": {
    "schema": "verifyco-advanced-forensics/1.1",
    "role": "diagnostic",
    "releaseReliability": 0.0,
    "status": "available",
    "findings": [{ "category": "container_profile", "status": "observed" }]
  }
}
POST/v1/analyze-url— analyze media at a public social link

Fetches the public media at the URL (X, TikTok, Instagram, YouTube or Facebook; other hosts are refused with 422), runs the same five-layer pipeline and deletes the download. Response shape is identical to /v1/analyze.

request · curl
curl -X POST https://verifyco-extractor.onrender.com/v1/analyze-url \
  -H "X-API-Key: vfy_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.tiktok.com/@user/video/123..."}'
POST/v1/inspect-document— bounded PDF, PSD/PSB and OOXML diagnostics

Server-key-only research endpoint for PDF structure/revision/signature-range, PSD/PSB section framing and DOCX/XLSX/PPTX-family package inventories. It does not render pages, execute actions, extract ZIP entries, validate certificate trust or issue a media verdict. Every response is explicitly diagnosticwith releaseReliability: 0.

request · curl
curl -X POST https://verifyco-extractor.onrender.com/v1/inspect-document \
  -H "X-API-Key: vfy_live_xxxxxxxxxxxx" \
  -F "file=@document.pdf"

RESPONSE SEMANTICS

score · 0–100

Weighted fusion of the available layers. Higher = more consistent with authentic capture. Neural softmax scores are not calibrated real-world probabilities; the result is evidence, never proof. The response above illustrates the schema and is not a benchmark, accuracy claim or promised outcome for a particular file.

verdict

authentic · suspicious · manipulated · inconclusive — derived from the score and layer agreement. An inconclusive score (58–77) is the evidence lean, not a verdict: higher leans toward an authentic capture, lower toward generation or editing.

layers[].status

passed · warning · failed · unavailable · not_applicable · error. Unavailable signals are declared, never silently skipped — absence of evidence is not evidence of manipulation.

advancedForensics

Optional L6 container/edit observations and L7 consistency context. In schema 1.1 every finding, measured region and graph edge is diagnostic, has releaseReliability: 0, and is excluded from the fusion score and verdict until corpus calibration passes.

providerSignals

A generator's own provenance check on an image (today OpenAI's Content Provenance API, also attached to the c2pa layer as providerAttestation): detected sets provenanceState: "provider_attested_ai" and decides the verdict like a trusted AI-generation Content Credential, not_detected is not evidence of human origin, and the array is empty when no check applies.

Errors

Standard HTTP: 401 bad key, 413 over size limit, 415 unsupported media, 429 rate limited, 5xx retry with backoff.

Building trust & safety, KYC or newsroom tooling?

Tell us your volume and use case — beta partners get direct engineering support and input on the roadmap.

Read our security & data-handling practices →