5.7 KiB
Phase 2 Discovery: Model Discovery APIs
Date: 2026-01-09 Level: 2 - Standard Research
Research Objectives
- Replicate model listing API endpoints and response schema
- fal.ai model discovery endpoints and response schema
- Pagination approaches for both providers
- Authentication header formats
Findings
Replicate API
Endpoint: GET https://api.replicate.com/v1/models
Authentication:
Authorization: Bearer $REPLICATE_API_TOKEN
Query Parameters:
sort_by: Sort field (default:latest_version_created_at)sort_direction:ascordesc
Response Schema:
interface ReplicateModelsResponse {
next: string | null; // URL to next page
previous: string | null; // URL to previous page
results: ReplicateModel[];
}
interface ReplicateModel {
url: string; // Web page link
owner: string; // Username/organization
name: string; // Model identifier
description: string; // Text summary
visibility: "public" | "private";
github_url?: string;
paper_url?: string;
license_url?: string;
run_count: number; // Usage statistics
cover_image_url?: string; // Thumbnail
default_example?: object; // Sample prediction
latest_version?: {
id: string;
openapi_schema: object; // Input/output specs
};
}
Pagination: Cursor-based via next/previous URLs. Follow next URL until null.
Search Endpoint (Beta):
GET https://api.replicate.com/v1/search?query=...
Returns broader search results across models.
fal.ai API
Endpoint: GET https://api.fal.ai/v1/models
Authentication (Optional - higher rate limits):
Authorization: Key $FAL_KEY
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit |
integer | Max items to return |
cursor |
string | Pagination cursor from previous response |
endpoint_id |
string/array | Specific endpoint ID(s) to retrieve |
q |
string | Free-text search query |
category |
string | Filter by category (e.g., 'text-to-image') |
status |
enum | active or deprecated |
expand |
string | Include openapi-3.0 for full schema |
Response Schema:
interface FalModelsResponse {
models: FalModel[];
next_cursor: string | null;
has_more: boolean;
}
interface FalModel {
endpoint_id: string; // e.g., "fal-ai/flux/dev"
metadata: {
display_name: string;
category: string; // e.g., "text-to-image"
description: string;
status: "active" | "deprecated";
tags: string[];
updated_at: string; // ISO8601
is_favorited: boolean | null;
thumbnail_url: string;
model_url: string;
date: string; // ISO8601
highlighted: boolean;
pinned: boolean;
thumbnail_animated_url?: string;
github_url?: string;
license_type?: "commercial" | "research" | "private";
};
openapi?: object; // When expand=openapi-3.0
}
Pagination: Cursor-based. Use next_cursor value as cursor param. Stop when has_more is false.
Categories of Interest:
text-to-imageimage-to-imagetext-to-videoimage-to-video
Mapping to ProviderModel
Both APIs need to be normalized to our ProviderModel interface:
interface ProviderModel {
id: string; // Replicate: `${owner}/${name}`, fal: endpoint_id
name: string; // Replicate: name, fal: display_name
description: string | null; // Replicate: description, fal: metadata.description
provider: ProviderType; // "replicate" | "fal"
capabilities: ModelCapability[];// Derived from run type or fal category
coverImage?: string; // Replicate: cover_image_url, fal: thumbnail_url
pricing?: { type, amount, currency };
}
Capability Mapping:
- fal.ai: Direct from
categoryfield - Replicate: Infer from model name/description or openapi_schema input/output types
Implementation Approach
Provider Module Pattern
Each provider implements ProviderInterface and self-registers:
// src/lib/providers/replicate.ts
const replicateProvider: ProviderInterface = {
id: "replicate",
name: "Replicate",
listModels: async () => { /* fetch and map */ },
searchModels: async (query) => { /* use search endpoint */ },
getModel: async (id) => { /* fetch specific model */ },
generate: async (input) => { /* create prediction */ },
isConfigured: () => !!getApiKey(),
getApiKey: () => /* from store or env */,
};
registerProvider(replicateProvider);
API Route Pattern
Expose via Next.js API routes for client access:
// src/app/api/providers/[provider]/models/route.ts
// GET /api/providers/replicate/models?search=flux
Caching Strategy
Cache model lists in memory with TTL:
- Duration: 5-15 minutes (models don't change frequently)
- Key:
${provider}:modelsor${provider}:search:${query} - Invalidation: Manual refresh button in UI
Decisions
- No SDK usage - Direct fetch calls to REST APIs as per project constraints
- Server-side fetching - API routes proxy requests (hides API keys from client)
- Initial page only - First API call fetches ~50-100 models, pagination on-demand for search
- Category filtering - Filter to image/video capabilities only (no audio, 3D, etc.)
Next Steps
- Create Replicate provider implementation with model fetching
- Create fal.ai provider implementation with model fetching
- Add API routes for client access to model lists
- Implement simple in-memory caching with TTL