Agent
The agents table in marketplace-fleapoai-service holds every agent's catalog listing. It is not a runtime — see Architecture.
Schema
| Column | Type | Notes |
|---|---|---|
id | UUID | Primary key |
name | text | Human-readable name |
slug | text, unique | URL slug; immutable after publish |
description | text | Marketing description (detail page hero) |
longDescription | text, nullable | Multi-paragraph body copy |
tagline | text | One-sentence pitch |
iconUrl | text, nullable | CDN-hosted icon |
photoUrls | text[] | Screenshots gallery |
status | enum | draft | active | coming_soon | inactive |
featured | bool | Homepage placement |
isNew | bool | Renders the "New" badge |
productDomain | text, nullable | Agent's frontend URL (used to validate returnUrl on checkout) |
docsUrl | text, nullable | Outbound link to agent's docs |
changelogUrl | text, nullable | Outbound link |
oauthClientId | text, unique | Reference into better-auth oauthClient row |
redirectUris | text[] | OAuth allow-list; mirrored into oauthClient |
createdBy | UUID | auth.user.id of admin who created |
publishedAt | timestamptz, nullable | Set when status flips to active |
createdAt, updatedAt | timestamptz |
Related tables
Lifecycle
status controls visibility and OAuth client enablement. See Publishing & approval.
DTO
type AgentDto = {
id: string;
slug: string;
name: string;
tagline: string;
description: string;
longDescription: string | null;
iconUrl: string | null;
photoUrls: string[];
status: "draft" | "active" | "coming_soon" | "inactive";
featured: boolean;
isNew: boolean;
publishedAt: string | null;
productDomain: string | null;
docsUrl: string | null;
changelogUrl: string | null;
oauthClientId: string;
redirectUris: string[];
capabilities: CapabilityDto[];
steps: StepDto[];
changelog: ChangelogEntryDto[];
trustSignals: string[];
tags: TagDto[];
rating: number | null; // 1-decimal avg, null if reviewCount === 0
reviewCount: number;
installs: number;
createdBy: string;
createdAt: string;
updatedAt: string;
};
The frontend converts this to a leaner Agent shape via toDisplayAgent() in src/data/agents.ts.
Endpoints
| Verb | Path | Guard |
|---|---|---|
| GET | /agents | public, paginated |
| GET | /agents/:id | public |
| GET | /agents/by-slug/:slug | public |
| POST | /agents | platform_admin |
| POST | /agents/:id | platform_admin |
| DELETE | /agents/:id | platform_admin |
| POST | /agents/:id/demo-request | bearer |
See API Reference for full schemas.
Identity bridge
When you POST /agents, the service:
- Inserts the
agentsrow. - Creates a better-auth
oauthClientrow (typepublic,tokenEndpointAuthMethod: 'none', PKCE-S256 enforced). - Mirrors
redirectUrisfrom the agent row to the client row. - Returns the new
oauthClientId.
On POST /agents/:id with a changed redirectUris[], the mirror is updated.
This is the only linkage between the catalog row and the OIDC client. There is no agent-side "key" issued by the marketplace beyond this.