Witness API User Guide

Complete reference for authentication, endpoints, parameters, examples, and error handling.

Base URL: https://witness.report Format: JSON Auth: API key Spec: OpenAPI 3.1

Overview

This API provides people search, person detail timelines, latest event retrieval, photo search, and event listings by exact date or date range.

Official OpenAPI file: /api/openapi/openapi.yaml

Authentication

All endpoints require an API key. Recommended method is the X-API-Key header.

Accepted API key methods

Method Example Status
X-API-Key header X-API-Key: YOUR_API_KEY Recommended
Authorization: Bearer Authorization: Bearer YOUR_API_KEY Supported
apikey query/form parameter ?apikey=YOUR_API_KEY Backward compatible

If no key is provided, the API returns HTTP 400. Invalid keys return HTTP 403.

Free Test API Key (Google)

Anyone signed in with Google can request a free test API key unless they are an active Witness Report member.

  • Free test key quota: 100 requests per month.
  • Extension rule: after one free key has been issued, extension requires at least 5 AUD donation.
Sign in with Google, then click "Request Free Test Key".

Endpoints

Endpoint Purpose Required Parameters
GET /api/api.php Search people by name (full, partial, multi-token matching). name
GET /api/person.php Get one person record with tags, links, stories, and timeline events. uuid
GET /api/events.php List events on one date with optional filters. date (YYYY-MM-DD)
GET /api/events_range.php List events in a date range with optional category and filters. start, end (YYYY-MM-DD)
GET /api/latest.php Return latest events by category. limit (optional)
GET /api/photoSearch.php Proxy photo-search requests to the backend service. None
POST /api/photoSearch.php Submit an image via multipart upload or JSON base64 payload. image or imageBase64

Detailed parameters

/api/api.php

ParameterTypeNotes
namestringRequired. Persian/English name query.

/api/person.php

ParameterTypeNotes
uuidstringRequired. UUID format only.

/api/events.php

ParameterTypeNotes
datestringRequired. Format: YYYY-MM-DD.
city, countrystringOptional partial match filters.
tagsarray/stringOptional. Repeated values are OR-matched.
ageMin, ageMaxintOptional. Non-negative integers.
dedupe0/1/true/yesOptional. Returns only one most-recent event per person.
limitintOptional. Default 100, max 500.
offsetintOptional. Default 0.

/api/events_range.php

ParameterTypeNotes
start, endstringRequired. YYYY-MM-DD.
categorystringOptional. One of: detention, executed, killed, any.
city, country, tags, ageMin, ageMax, dedupe, limit, offsetmixedSame behavior as /api/events.php.

/api/latest.php

ParameterTypeNotes
categorystringOptional. detention (default), executed, killed, any.
limitintOptional. Default 10, max 50.

/api/photoSearch.php

ParameterTypeNotes
imagefileOptional multipart upload. The file is forwarded to the backend as base64.
imageBase64stringOptional JSON field containing a base64 image payload.
thresholdintOptional. Default 4, range 0..6.
maxResultsintOptional. Default 30, range 1..100.
minVectorScorefloatOptional. Default 0.68, range 0..1.
minFaceScorefloatOptional. Default 0.42, range 0..1.

Quick Examples

1) Search people by name

curl -s "https://witness.report/api/api.php?name=محمد%20فشکی" \
  -H "X-API-Key: YOUR_API_KEY"

2) Get one person with full timeline

curl -s "https://witness.report/api/person.php?uuid=123e4567-e89b-12d3-a456-426614174000" \
  -H "X-API-Key: YOUR_API_KEY"

3) Events for one date (with filters)

curl -s "https://witness.report/api/events.php?date=2026-01-20&city=Tehran&tags=Student&dedupe=1&limit=100" \
  -H "X-API-Key: YOUR_API_KEY"

4) Events in date range by category

curl -s "https://witness.report/api/events_range.php?start=2026-01-01&end=2026-01-31&category=detention&country=Iran&ageMax=17&dedupe=1" \
  -H "X-API-Key: YOUR_API_KEY"

5) Latest events

curl -s "https://witness.report/api/latest.php?category=any&limit=10" \
  -H "X-API-Key: YOUR_API_KEY"

Response events include imageUrl when a profile photo exists (otherwise null).

{
  "ok": true,
  "category": "any",
  "limit": 10,
  "count": 2,
  "events": [
    {
      "uuid": "...",
      "imageUrl": "https://witness.report/images/....jpg",
      "fullNameEn": "...",
      "nicknameEn": "...",
      "nationality": "Iranian",
      "age": 27,
      "location": "Tehran, Tehran, Iran",
      "healthStatusDisplay": "Alive",
      "detentionStatus": "Arrested",
      "tags": [{ "tagName": "Student", "tagColor": "#1d4ed8" }],
      "logId": 123
    },
    {
      "uuid": "...",
      "imageUrl": null,
      "fullNameEn": "...",
      "location": "Karaj, Alborz, Iran",
      "detentionStatus": "Imprisoned",
      "tags": [],
      "logId": 122
    }
  ]
}

6) Photo search

curl -s -X POST "https://witness.report/api/photoSearch.php" \
          -H "X-API-Key: YOUR_API_KEY" \
          -H "Content-Type: application/json" \
          --data '{"imageBase64":"BASE64_IMAGE","maxResults":10}'

Photo search matches include imageUrl when a profile photo exists (otherwise null).

{
  "count": 2,
  "items": [
    { "uuid": "...", "imageUrl": "https://witness.report/images/....jpg", "similarityScore": 0.90 },
    { "uuid": "...", "imageUrl": null, "similarityScore": 0.84 }
  ]
}

Errors

Common HTTP status codes:

  • 200 successful response.
  • 400 missing or invalid parameters.
  • 403 invalid API key.
  • 404 person not found (person endpoint).
  • 429 rate limit exceeded.
  • 500 server-side query/prepare failure.

Examples

Missing key 400

{"error":"missing parameters","apikey":""}

Invalid key 403

{"error":"invalid api key"}

Rate limit 429

{"error":"rate limit exceeded"}

Missing or invalid UUID 400

{"error":"missing or invalid uuid"}

Person not found 404

{"error":"not found"}

Rate Limits

API keys are checked against daily and monthly usage quotas. If either limit is exceeded, requests return HTTP 429.

No-match requests still consume quota.

Usage Notes

  • Use the X-API-Key header in production clients.
  • For tags, send repeated query values for OR behavior, for example: &tags=Student&tags=Journalist.
  • Use dedupe=1 when you want one row per person instead of full event history rows.
  • Use pagination with limit and offset for large datasets.
  • For strict schema details, use the OpenAPI file.

Guide Notes