No authentication.
Returns { "ok": true }.
Reference
Base URL for this deployment: http://localhost:4000. Configure NEXT_PUBLIC_ATTESTIA_API_URL in webapp/.env.local if the API runs elsewhere.
The Attestia API lets staked contributors upload media, register assets, and list their own assets, and staked verifiers discover open assets, stream new submissions, read chain time for EAS off-chain attestations, and submit scores. Roles are enforced by reading the same AttestiaStake contract as the web UI. JSON bodies use application/json unless noted.
Runtime state is kept in-memory in the webapp process. For durable score persistence/mirroring, configure immudb via IMMUDB_PG_URL.
Never send a private key to this API. You prove control of a wallet by signing a short-lived challenge (EIP-191 personal sign). The server checks the signature and verifies on-chain that the address is registered as a contributor or verifier on AttestiaStake.
GET http://localhost:4000/v1/auth/challenge?address=0xYourAddressResponse includes message, nonce, and expiresAt. The message is single-use and expires in a few minutes.
const signature = await walletClient.signMessage({
account,
message: challenge.message,
});POST http://localhost:4000/v1/auth/session
Content-Type: application/json
{
"nonce": "<nonce from step 1>",
"signature": "<0x signature from step 2>"
}On success you receive token, expiresAt (Unix seconds), address, and roles (e.g. ["submitter"] or ["attester"]). If the wallet has no on-chain role, the server returns 403.
The API server signs sessions with ATTAPI_SESSION_SECRET. For local development only, ATTAPI_ALLOW_NO_AUTH=1 can disable checks (see api/.env.example).
Send the token on every protected request:
Authorization: Bearer <token>Route requirements: submitter routes need a session whose roles include submitter (UI: contributor); attester routes need attester (UI: verifier). When a session expires, repeat the challenge and sign flow.
No authentication.
Returns { "ok": true }.
Public.
Query: address (required). Returns signing payload and metadata.
Public.
Body: nonce, signature. Returns session token and roles.
Bearer session with attester role.
Query: chainId optional (default 84532 Base Sepolia; 8453 Base mainnet). Returns latest block number and timestamp for EAS off-chain time.
Bearer session with submitter role.
multipart/form-data with field file. Pins to IPFS when Pinata env is configured. Returns contentHash, uri, etc.
Bearer session with submitter role.
JSON: ownerAddress, title, mediaContext, contentHash (bytes32), uri, contributorAttestationUid, and verificationDeadline (ISO timestamp, typically 12h after contributor attestation). ownerAddress must match the authenticated wallet (403 otherwise).
Bearer session with submitter role.
Query: owner (required). Must equal the authenticated address. Returns assets with score counts and aggregate.
Bearer session with attester role.
List of assets in open status (accepting scores).
Bearer session with attester role.
Single asset with scores and aggregate.
Bearer session with attester role.
JSON required fields: authenticityScore (0–100), deepfakeRiskBps, algorithm, offchainAttestation. Optional fields: notes, signature. The verifier wallet is taken from the session; any attesterAddress in the body is ignored for compatibility. The server always requires and verifies offchainAttestation.
Bearer session with attester role.
text/event-stream (SSE). First event snapshot with current open assets; then new-asset when new open assets appear (polled every 2s). Comment lines : ping keep the connection alive. Use EventSource in the browser or equivalent in your HTTP client.
The running API exposes machine-readable OpenAPI 3.1 and Swagger UI: