Back to Home

API keys for pet projects: HMAC and cache

The platform provides free real APIs for pet projects with user data. Uses self-sufficient keys with HMAC, two-stage validation, and LRU cache for overload protection. Playground simplifies testing without deployment.

Free API without stubs: keys with HMAC signature
Advertisement 728x90

Free API for Pet Projects: Self-Contained Keys & Rate Limiting

Developers often showcase frontend apps during interviews using data from localStorage or jsonplaceholder. This simplifies development without server costs, but results in static data and artificial delays via setTimeout. A better alternative? A platform with real APIs where you can upload your own data. Setup takes just minutes—no backend required.

The architecture uses Next.js for the web interface with SSG, Node.js/Express to manage users and keys, and a dedicated API service. Everything runs in Docker with an Nginx proxy.

Free Access Challenges & the API Key Solution

Without limits, anyone could flood the system with spam requests, quickly exhausting resources. The key strategy? Minimize database queries and filter invalid keys at parsing time.

Google AdInline article slot

Keys are self-contained, formatted as ppk_version_userId_nonce_signature. Authentication uses: Authorization: PetProjects ppk_v1_1_nonce_signature.

Validation happens in two steps:

  • Local validation: structure and HMAC signature checked without touching the database.
  • Database lookup for userId only after initial validity is confirmed.
function validateApiKey(apiKey: string): ApiKeyPayload | null {
    if (!apiKey.startsWith('ppk_')) return null;

    const parts = apiKey.split('_');
    if (parts.length !== 5) return null;

    const [, version, userIdRaw, nonce, signature] = parts;

    const userId = Number(userIdRaw);
    if (!Number.isInteger(userId)) return null;

    if (!signature || !/^[a-f0-9]{64}$/.test(signature)) return null;

    const payload = `${version}.${userId}.${nonce}`;

    const expectedSignature = crypto.createHmac('sha256', API_KEY_SECRET).update(payload).digest('hex');

    if (signature.length !== expectedSignature.length) return null;

    const isValid = crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expectedSignature, 'hex'));

    if (!isValid) return null;

    return { version, userId, nonce };
}

timingSafeEqual prevents timing attacks. Valid keys are cached in LRUCache (max: 10,000 entries, TTL: 5 minutes).

Google AdInline article slot

Caching & Performance Balance

Caching reduces latency and database load. The 5-minute TTL is a trade-off: leaked keys remain active until expiration, then require revalidation.

Limitations:

  • No instant key revocation.
  • Leaked keys stay valid until TTL expires.
  • Secrets must be protected.

Potential improvements: blacklist support, key versioning, and dynamic revocation.

Google AdInline article slot

Playground for API Testing

An interactive interface lets you send requests directly from the browser with auto-filled keys. It generates code examples for multiple languages.

Example POST:

curl -L -X POST 'https://api.pet-projects.io/rest/free' \
-H 'Authorization: PetProjects ppk_v1_1_a1b2c3d4e5_a1b2c3d4e5f6g7h8i10j11' \
-H 'Content-Type: application/json' \
-d '{"hello":"world"}'

Response in JSend format:

{
    "status": "success",
    "data": {
        "id": 99,
        "payload": {
            "hello": "world"
        },
        "createdAt": 1774297745939,
        "updatedAt": 1774297745939
    }
}

Scaling & Future Enhancements

The system minimizes database calls, resists abuse, and balances security with speed. As traffic grows, monitoring cache and key usage will become essential.

Benefits for mid/senior developers:

  • Real endpoints instead of mocks.
  • Personal data without deployment.
  • Fast HMAC validation + caching.
  • Built-in playground for debugging.
  • Docker-based architecture for scalability.

Key takeaways:

  • Self-contained keys filter out 99% of junk without DB access.
  • LRUCache with 5-minute TTL cuts database load by over 90%.
  • timingSafeEqual defends against timing attacks.
  • Two-step validation: local check + DB lookup for valid keys.
  • JSend responses standardize API behavior.

— Editorial Team

Advertisement 728x90

Read Next