HTTP API reference
The Fastify API listens on port 4000 by default. In production the Next.js application proxies /api/v1/* to the private API service. JSON is used for request and response bodies.
Conventions
- Validation failures return
400with anerrorcode; some endpoints include Zoddetails. - Unconfigured or unavailable identity dependencies return
503. - Identity endpoints use the
raidz_sessioncookie. If a valid session does not exist, the API creates a user/profile/session and sends an HttpOnly, SameSite=Lax cookie, Secure in production, with a 30-day maximum age. - Challenge IDs are UUIDs and expire after five minutes.
- Current CORS configuration does not grant cross-origin browser access.
Health
GET /health
Liveness only. Does not check PostgreSQL.
{ "status": "ok" }
GET /ready
Runs dependency checks, currently PostgreSQL by default. Returns 200 {"status":"ready"} or 503 {"status":"not_ready"}. Both health endpoints set Cache-Control: no-store.
Score
POST /v1/score/preview
Calculates Raidz Score V0 without persistence. Supply eleven numeric signals, completedCampaigns, and evidence for every component.
{
"accountMaturity": 80,
"audienceQuality": 75,
"realReach": 70,
"contentQuality": 85,
"topicRelevance": 90,
"socialScale": 60,
"campaignPerformance": 0,
"conversionPerformance": 0,
"reliability": 0,
"marketplaceRatings": 0,
"verificationSignals": 0,
"completedCampaigns": 0,
"evidence": {
"accountMaturity": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0.9, "explanationReason": "Account age and continuity" },
"audienceQuality": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0.7, "explanationReason": "Sampled audience quality" },
"realReach": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0.7, "explanationReason": "Recent median reach" },
"contentQuality": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0.7, "explanationReason": "Original content review" },
"topicRelevance": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0.8, "explanationReason": "Web3 topic fit" },
"socialScale": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0.9, "explanationReason": "Normalized scale" },
"campaignPerformance": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0, "explanationReason": "No completed Raidz campaign" },
"conversionPerformance": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0, "explanationReason": "No consented outcome history" },
"reliability": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0, "explanationReason": "No platform history" },
"marketplaceRatings": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0, "explanationReason": "No platform ratings" },
"verificationSignals": { "sourceTimestamp": "2026-09-03T00:00:00.000Z", "confidence": 0, "explanationReason": "No additional verification" }
}
}
The response contains score, tier, performanceShare, all normalized components plus evidence, and version. Numeric signals are clamped to 0–100; evidence confidence is validated within 0–1.
Campaign policy
POST /v1/campaigns/preflight
{
"channel": "x",
"jurisdiction": "US",
"category": "web3 product",
"text": "Publish one original, clearly disclosed product review.",
"compensated": true
}
Channels are x, telegram, web, onchain, or event. The response is ELIGIBLE or BLOCKED, a unique list of reason codes, and the policy version.
Missions
GET /v1/missions
Currently returns an empty live dataset:
{
"data": [],
"source": "database",
"live": false,
"notice": "No funded campaigns are represented by fixtures."
}
Live Raids and creator work
GET /v1/raids
Returns the persisted Raid Radar for the current session. Each item includes public brief and aggregate fields plus session-scoped is_owner, my_application_*, and my_proof_* state. Internal owner IDs and other applicants are not returned.
POST /v1/raids/:raidId/applications
Creates one application for the current user. The API enforces the Raid's required X/Telegram connections, an active wallet link, current server-authoritative Raider Score, duplicate prevention, state, dates, and capacity.
GET /v1/raid-work
Returns only the current user's application and proof timeline, joined to its Raid brief and immutable application Score snapshot.
GET /v1/raids/:raidId
Returns the Raid dashboard. The owner can see all applications; a non-owner can see only their own application. This privacy boundary is server-side.
Proof submission accepts a platform-matching xUrl or telegramUrl, or an ipfsUri. X proofs are restricted to x.com/twitter.com; Telegram proofs to t.me/telegram.me. A verified proof creates an offchain entitlement ledger entry only. Settlement remains disabled.
Profile and providers
GET /v1/profile
Returns the current profile and provider availability. x and telegram are true only when their necessary runtime configuration exists; wallet linking is available. Telegram bot ID and username may be returned as public configuration.
PATCH /v1/profile
All fields are optional: displayName, bio, locale, jurisdiction, languages, regions, narratives, availability, and profileVisibility. Collection sizes and string lengths are bounded by the route schema.
Wallet ownership
POST /v1/auth/wallet/challenge
{ "address": "0x1111111111111111111111111111111111111111", "chainId": 4663 }
Returns challengeId, the exact message to sign, expiry, and chain ID. Any other chain returns WRONG_CHAIN.
POST /v1/auth/wallet/verify
{
"challengeId": "00000000-0000-4000-8000-000000000000",
"address": "0x1111111111111111111111111111111111111111",
"signature": "0x..."
}
The server checks the address against the challenge, verifies the EVM personal-message signature, atomically consumes the challenge, and links the checksummed address. Errors distinguish invalid input, expired/used challenge, wrong wallet, invalid signature, and replay.
X OAuth
GET /v1/auth/x/start
Creates a PKCE challenge and returns { "url": "https://x.com/i/oauth2/authorize?..." }. The browser must navigate to the returned URL.
GET /v1/auth/x/callback
X redirects here with code and compound state. The API validates session/state/PKCE, exchanges the code, reads the current profile, consumes the challenge, encrypts the token response, and redirects to the profile view with a success or error query.
Telegram Login
POST /v1/auth/telegram/verify
Accepts the Telegram Login payload fields id, auth_date, hash, and optional name, username, and photo URL. The signature and five-minute age are verified before the subject is pseudonymized and linked.
Disconnect
DELETE /v1/auth/:provider
provider is x, telegram, or wallet. Social links are deleted; active wallet links are marked revoked. Returns the updated profile.
Not yet exposed
There are no public endpoints yet for the canonical campaign/escrow workflow, claims, deliverables, verifier decisions, settlement, service bookings, reviews, Pons state, or admin operations. Consented product analytics is available through POST /v1/analytics/events; authenticated users can inspect or erase their own event summary through GET or DELETE /v1/analytics/me.

ATTENTION, WITH PROOF.