Submit an observation
Create a revocable key in your account, then send a protocol v2 observation with a unique idempotency key.
curl -X POST https://your-domain/api/v3/observations \
-H "Authorization: Bearer pvp_••••••" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 0c8d8b31-…" \
-H "X-PvPLogs-Agent-Version: 2.0.0" \
--data-binary @observation.jsonFree accounts can create agent keys. Pro adds read API access and higher quotas.
Core endpoints
/api/v3/characters?query=Horror-HellscreamSearch indexed characters
/api/v3/characters/us/hellscream/horrorProfile and entitled history
/api/v3/matches?limit=25&cursor=…Canonical match feed
/api/v3/matches/{matchId}Match and base tactical replay
/api/v3/observationsAuthenticated agent ingestion
/api/v3/meAccount and entitlements
Keys identify accountable upload sources
Secrets are shown once and stored only as SHA-256 hashes. Keys are scoped, rate-limited and revocable. Browser account actions use the signed-in session and same-origin checks.
Scope: upload
12 observations per minute
Scopes: upload,read
10,000 read requests per day
Send one compact perspective through API v3
New agents post only to /api/v3/observations. Each request carries a Bearer key, a stable content-derived Idempotency-Key, the agent version header, and a body no larger than 8 MB. Region, realm and observing player ID are explicit so character indexing never guesses the observer identity.
Write compact telemetry to match.tacticalReplay. The server temporarily accepts the older match.analysis.tacticalReplay shape during migration.
Persist pending jobs, honor Retry-After, retry network/429/5xx responses with jitter, and reuse the same key for the same bytes.
Legacy v2 match and character routes return 410 Gone. Existing agents must migrate before they can upload to this website.
Corroborated, not magically cheat-proof
A desktop client can never prove that every byte is truthful. PvP Logs instead binds evidence to authenticated sources, keeps raw observations immutable, validates physical and structural constraints, and builds field-level confidence from independent agreement.
- 01Server-derived source identity
Submitted
source.idvalues never decide independence. One account counts as one source. - 02Serialized canonical merge
A D1-backed lock prevents concurrent uploads from overwriting one another. Each merge creates an immutable revision.
- 03Visible disagreement
Winner, roster, deaths, tracks and copied evidence affect the contested status and confidence score.
- 04One canonical match
Arena, bracket, exact roster and start window connect uploads to one shared match ID.
Scores carry coverage, confidence and a version
PvP Logs scores only when at least two recorded telemetry domains are available. Missing health or position data is marked unavailable instead of receiving a favorable default. Advanced fields stay on the server until the current account is entitled to them.
Output, activity, control, survival and positioning are reweighted over the evidence actually present. The repository includes the complete methodology and limitations.
Stable errors and safe retries
Every API response includes a request ID. Uploads require Idempotency-Key; retrying the same bytes returns the original observation, while reusing a key for different bytes returns 409. The complete request is limited to 8 MB, 50,000 track samples, 25,000 replay events and six independent contributions per canonical match.
{
"status": "error",
"requestId": "…",
"error": {
"code": "invalid-observation",
"message": "protocolVersion 2 is required"
}
}