Architecture
Bounty uses tRPC for type-safe API communication between the frontend and backend. This provides end-to-end type safety without code generation, ensuring that your client code is always in sync with your API.Why tRPC?
- Type Safety: Full TypeScript type inference from server to client
- No Code Generation: Types are shared directly via TypeScript
- Developer Experience: Autocomplete and type checking in your IDE
- Runtime Safety: Request validation with Zod schemas
- Performance: Optimized batching and caching
Core Concepts
Procedures
The Bounty API defines two types of procedures:Queries
Used for reading data. Queries are idempotent and cacheable.Mutations
Used for creating, updating, or deleting data. Mutations have side effects.Middleware
The API uses middleware to handle cross-cutting concerns. Seepackages/api/src/trpc.ts:1 for implementation details.
Available Procedure Types
publicProcedure
publicProcedure
No authentication required. Available to all users.Use for: Public data, health checks, unauthenticated endpoints
protectedProcedure
protectedProcedure
Requires authentication. User must have a valid session.Use for: User-specific data, authenticated operationsThrows:
UNAUTHORIZED if no session existsadminProcedure
adminProcedure
Requires admin role. Prevents access during impersonation.Use for: Admin panel operations, system managementThrows:
FORBIDDEN if user is not admin or is impersonatingearlyAccessProcedure
earlyAccessProcedure
Requires early access or admin role.Use for: Beta features, early access functionalityThrows:
FORBIDDEN if user lacks early accessorgProcedure
orgProcedure
Requires active organization membership. Provides
ctx.org and ctx.orgMembership.Use for: Team-scoped operationsThrows: BAD_REQUEST if no active organization, FORBIDDEN if not a memberorgOwnerProcedure
orgOwnerProcedure
Requires organization owner role. Extends
orgProcedure.Use for: Organization settings, billing, member managementThrows: FORBIDDEN if user is not the organization ownerAvailable Routers
The Bounty API is organized into domain-specific routers. Seepackages/api/src/routers/index.ts:1 for the complete router definition.
bounties
Bounty creation, management, applications, and submissions
user
User profile, settings, and preferences
organization
Team management, invitations, and settings
profiles
Public user profiles and reputation
notifications
User notifications and preferences
repository
GitHub repository integration and management
githubInstallation
GitHub App installation and permissions
linear
Linear integration for issue tracking
discord
Discord integration and notifications
connect
Third-party service connections
emails
Email preferences and notifications
onboarding
New user onboarding flow
featureVotes
Feature request voting system
earlyAccess
Early access program management
Utility Endpoints
The root router includes utility endpoints for health monitoring:Rate Limiting
Bounty implements distributed rate limiting using Upstash Redis with a sliding window algorithm. Seepackages/api/src/lib/ratelimiter.ts:1 for configuration.
Rate Limit Middleware
Rate-limited procedures are available for all authorization levels:rateLimitedPublicProcedure(operation)- For public endpointsrateLimitedProtectedProcedure(operation)- For authenticated endpointsrateLimitedAdminProcedure(operation)- For admin endpointsrateLimitedOrgProcedure(operation)- For organization-scoped endpoints
Operation Types
Read Operations
Read Operations
Write Operations
Write Operations
Bounty Operations
Bounty Operations
Payment Operations
Payment Operations
Rate Limit Response
When rate limited, the API returns aTOO_MANY_REQUESTS error with retry information:
Rate Limit Headers
Successful requests include rate limit information in the context:Error Handling
The API uses custom error formatting to provide detailed error information. Seepackages/api/src/trpc.ts:14 for implementation.
Error Response Format
Common Error Codes
UNAUTHORIZED- Authentication required but not providedFORBIDDEN- User lacks permission for the requested resourceBAD_REQUEST- Invalid input or missing required parametersTOO_MANY_REQUESTS- Rate limit exceededNOT_FOUND- Requested resource does not existINTERNAL_SERVER_ERROR- Unexpected server error
Context
Every procedure receives a context object with request metadata. Seepackages/api/src/context.ts:1 for implementation.
IP Detection
The context extracts the client IP from multiple sources:x-forwarded-forheaderx-real-ipheadercf-connecting-ipheader (Cloudflare)- Fallback to
'unknown'
Request Tracing
Each request receives a uniquerequestId for distributed tracing:
- Uses existing headers from upstream (
x-request-id,x-vercel-id,cf-ray) - Generates new ID if not present:
req_{timestamp}_{random}
Type Exports
The API exports TypeScript types for client usage:Next Steps
Authentication
Learn about Better Auth integration and session management
Router Reference
Explore individual router endpoints and schemas