API Documentation

Base URL: https://flashloanlab.com/api  ·  All responses are JSON  ·  llms.txt

Overview

The FlashLoanLab API is a JSON REST API served by a Fastify backend. It handles authentication, opportunity discovery, trade execution, auto-trading configuration, and admin management.

All timestamps are ISO 8601 strings in UTC. Chain IDs are strings (e.g. "8453"). Token amounts are strings representing the raw value in the token's smallest unit (wei for ETH-based tokens).

Request format

POST /auth/login
Content-Type: application/json
Authorization: Bearer <session_token>   // required on authenticated routes

{
  "email": "user@example.com",
  "password": "hunter2"
}

Response envelope

Successful responses return the data directly. Errors use:

{
  "error": "Invalid credentials",   // human-readable message
  "code":  "UNAUTHORIZED"           // optional machine-readable code
}

Authentication

Sessions are Bearer tokens returned on login or register. Pass the token in the Authorization header on every authenticated request. Tokens do not expire on their own — call POST /auth/logout to invalidate.

POST
/auth/register

Create a new account

POST
/auth/login

Sign in and receive a session token

POST
/auth/logout

Invalidate the current session token

POST
/auth/forgot-password

Send a password reset email (always returns 200)

POST
/auth/reset-password

Set a new password using the emailed token

Register

POST /auth/register
{
  "email":    "alice@example.com",
  "password": "at_least_8_chars",
  "name":     "Alice"             // optional
}

→ 201
{
  "user":  { "id": "...", "email": "alice@example.com", "name": "Alice", "role": "USER", "plan": "FREE" },
  "token": "fll_tok_..."
}

Login

POST /auth/login
{
  "email":    "alice@example.com",
  "password": "at_least_8_chars"
}

→ 200
{
  "user":  { "id": "...", "email": "alice@example.com", "role": "USER", "plan": "FREE" },
  "token": "fll_tok_..."
}

Reset password

// Step 1 — request a reset link
POST /auth/forgot-password
{ "email": "alice@example.com" }
→ 200 { "message": "If that address exists, a reset email has been sent." }

// Step 2 — set new password using token from email link
POST /auth/reset-password
{ "token": "<token_from_email>", "password": "new_password" }
→ 200 { "message": "Password updated successfully." }

Opportunities

Opportunities are arbitrage price discrepancies detected by the scanner. They include a confidence score (0–100), estimated profit, simulation result, and token safety data.

GET
/opportunities

List active opportunities (authenticated)

GET
/opportunities/:id

Get a single opportunity by ID

Opportunity object

{
  "id":          "opp_...",
  "chain":       "base",
  "chainId":     "8453",
  "borrowToken": "0x4200000000000000000000000000000000000006",  // WETH on Base
  "borrowAmount":"1000000000000000000",   // 1 WETH in wei
  "buyDex":      "uniswap_v3",
  "sellDex":     "uniswap_v2",
  "spread":      0.0041,                 // 0.41%
  "estimatedProfit": "3820000000000000", // ~0.00382 ETH
  "estimatedGas":    "420000",
  "score":       92,
  "simulation":  "passed",
  "tokenSafety": "safe",
  "createdAt":   "2025-11-01T12:34:56Z",
  "expiresAt":   "2025-11-01T12:35:26Z"  // 30s window
}

Execution

Execution is a two-step process. First, call /execute/:id/prepare to get the transaction parameters for FlashLoanReceiver.executeArbitrage(). Sign and broadcast the transaction yourself (MetaMask / wagmi). Then call /execute/:executionId/receipt with the tx hash so the platform can confirm the settlement on-chain.

POST
/execute/:opportunityId/prepare

Validate and return tx params

POST
/execute/:executionId/receipt

Record tx hash after broadcasting

GET
/execute/history

User's execution history

Prepare response

POST /execute/opp_.../prepare
→ 200
{
  "executionId": "exec_...",
  "contractAddress": "0x...",   // FlashLoanReceiver deployed on this chain
  "params": {
    "pool":         "0x...",    // Aave V3 pool address
    "asset":        "0x...",    // borrow token
    "amount":       "1000000000000000000",
    "buyDex":       "0x...",
    "sellDex":      "0x...",
    "feeBps":       2000,       // platform fee in basis points (20%)
    "deadline":     1730462096
  },
  "estimatedGas": "420000",
  "gasPrice":     "50000000"    // in wei, current fast price
}

Receipt

POST /execute/exec_.../receipt
{ "txHash": "0x..." }
→ 200 { "status": "confirmed", "profit": "3820000000000000" }

Auto Trading

Auto Trading runs a background worker that fires on opportunities scoring ≥90. It requires a trading wallet to be registered. All safety limits are enforced server-side — the bot will pause itself if any threshold is breached.

GET
/auto-trading/settings

Get current settings and safety limits

PATCH
/auto-trading/settings

Update risk thresholds

POST
/auto-trading/arm

Enable auto execution

POST
/auto-trading/disarm

Disable auto execution

POST
/auto-trading/emergency-stop

Immediately halt all activity

GET
/auto-trading/status

Today's trade stats

GET
/auto-trading/logs

Today's activity log

POST
/auto-trading/wallet

Register encrypted trading wallet

DELETE
/auto-trading/wallet

Remove trading wallet

Settings object

{
  "enabled":           false,
  "mode":              "paper",      // "paper" | "mainnet"
  "minScore":          90,           // only fire on opps scoring >= this
  "minProfitUsd":      5,
  "maxDailyLossUsd":   100,
  "maxTradesPerDay":   50,
  "maxFailedTxs":      3,
  "hasWallet":         true,
  "walletAddress":     "0x..."       // derived from stored key, never the key itself
}

Registering a trading wallet

The private key is encrypted with AES-256-GCM server-side before storage. It is never logged, never returned by any API endpoint, and never accessible from the frontend.

POST /auto-trading/wallet
{ "privateKey": "0x..." }
→ 200 { "walletAddress": "0x...", "message": "Wallet registered securely." }

Errors & Rate Limits

HTTP status codes

400Bad RequestValidation failed — check the error message for the field
401UnauthorizedMissing or invalid Bearer token
403ForbiddenToken valid but insufficient role/plan for this action
404Not FoundResource does not exist or you do not have access
409ConflictDuplicate — e.g. email already registered
422UnprocessableBusiness logic error — e.g. opportunity expired
429Too Many RequestsRate limit hit — back off and retry after the Retry-After header
500Server ErrorUnexpected error — please report with the request ID

Rate limits

The API is rate-limited per IP: 100 requests per minute for most routes, 10 requests per minute for auth endpoints. Exceeding the limit returns 429 with a Retry-After header.

Machine-readable reference

An LLM-optimised version of this documentation is available at /llms.txt.