RaidzATTENTION, WITH PROOF.

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 400 with an error code; some endpoints include Zod details.
  • Unconfigured or unavailable identity dependencies return 503.
  • Identity endpoints use the raidz_session cookie. 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.