Stage 1 — Ingest
Postcard fetches live content and metadata from the submitted URL using a strategy pattern. The system inspects the URL and delegates to the most appropriate
If a specialized client fails (403, 404, or rate limit), the pipeline automatically falls back to Jina Reader.What the ingest stage produces:The client returns a
UnifiedPostClient:| Platform | Strategy |
|---|---|
Native .json endpoint — character-perfect markdown | |
| YouTube | oEmbed API for video metadata |
| X (Twitter), TikTok, Instagram | Official oEmbed APIs — captures author names and absolute timestamps |
| Any other URL | Jina Reader — high-fidelity markdown fallback |
UnifiedPost object that standardizes the fetched data for the rest of the pipeline. It contains:platform— Detected platform (X,Reddit,YouTube,Instagram,Other, etc.)author— Post author or usernametimestamp— Absolute timestamp of the postmarkdown— Full post content rendered as Markdown
When a platform blocks access due to login walls or Cloudflare protection, Postcard surfaces the raw markdown retrieved during the attempt and returns an
insufficient_data verdict rather than silently failing.Stage 2 — Corroborate
The corroboration engine uses Gemini with Google Search grounding to find independent evidence for the post’s claims. It executes targeted Google Dork queries restricted to a curated list of trusted domains:The agent executes up to 5 search tool calls by default (configurable via
POSTCARD_MAX_TOOL_CALLS) and collects up to 10 sources (POSTCARD_MAX_SOURCES).How the confidence score is computed:Each source is classified as supporting, refuting, or neutral. The confidenceScore is derived by Gemini from the quality and relevance of the sources found. Trusted-domain sources are given higher weight.The stage produces:primarySources— Ranked list of articles with URL, title, snippet, relevance, and publication datequeriesExecuted— Every search query run and how many results it returnedverdict— One ofverified,disputed,inconclusive, orinsufficient_datacorroborationLog— Step-by-step audit trail of the agent’s reasoning
Stage 3 — Audit
The audit stage uses Gemini with Google Search to perform live site verification. The verifier agent checks two properties of the submitted URL:Origin reachability (
originScore) — Confirms that the post is still accessible at its claimed URL. The agent checks whether the URL hostname matches the declared platform (e.g., x.com for an X post). A clean match scores 1.0; a mismatch defaults to 0.5.Temporal alignment (temporalScore) — Verifies that the post’s timestamp is consistent with the reported narrative. The verifier uses Google Search to cross-check the publication date against when related content appeared in the public record. The current implementation defaults to 0.8 when no strong temporal contradiction is detected.Both scores are floating-point values between 0 and 1. They feed directly into the final weighted formula. The agent also produces an auditLog — a structured record of every check performed — which is displayed in the forensic report UI.Stage 4 — Score
Postcard combines the four subscores into a single Postcard Score using a weighted formula. The weights are calibrated to prioritize origin reachability and independent corroboration:Where:
originScore— From the Gemini verifier agent (0–1);1.0if hostname matches platform,0.5otherwisecorroborationScore— TheconfidenceScorefrom the Gemini corroboration agent (0–1)biasScore—supportingSources / totalSources, defaults to0.5when no sources are foundtemporalScore— From the Gemini verifier agent (0–1); defaults to0.8when no temporal contradiction is found
Result caching
Postcard caches completed forensic reports at the resolved post URL level using Drizzle ORM with Turso/libSQL.- Cache hit — If a completed analysis already exists for the submitted URL, Postcard increments the
hitscounter on the stored record and serves the cached report immediately — no pipeline execution needed. - Cache miss — If no completed analysis exists, Postcard runs the full pipeline and persists the result to the database.
- Force refresh — Pass
"refresh": truein aPOST /api/postcardsrequest to bypass the cache and re-run the full pipeline.
Completed forensic reports are public. Any user can view a cached report by submitting the same URL — no Gemini API key is required to read existing analyses. A key is only needed to initiate a new trace or forced refresh.
Real-time progress stages
While the pipeline runs, Postcard broadcasts progress updates that the UI polls every 3 seconds. Each update carries astage key, a human-readable message, and a progress value (0–1):
stage | message | progress |
|---|---|---|
starting | Initializing postcard… | 0 |
scraping | Fetching post content… | 0.1 |
scraped | Fetched content | 0.3 |
corroborating | Searching for primary sources… | 0.4 |
auditing | Verifying origin and temporal alignment… | 0.7 |
scoring | Calculating Postcard score… | 0.9 |
complete | Postcard complete | 1 |
Next steps
Quickstart
Verify your first post using the hosted demo or the public API
API reference
Full endpoint documentation for programmatic access