Marketplace API
Complete Reference
RESTful API for publishing, browsing, installing, and managing agents and tools in the Ferni Marketplace.
Jump to Section
Authentication
All API requests require authentication via HTTP headers. Different endpoints require different authentication levels:
User Authentication
For install, usage, and billing endpoints:
x-user-id: user_abc123
Publisher Authentication
For submitting and managing tools/agents:
x-publisher-id: pub_xyz789
x-publisher-name: Acme Corp
Example Request
curl https://api.ferni.ai/api/marketplace/browse/tools \
-H "x-user-id: user_abc123"
Developer API
Create, manage, and publish AI personas through the developer console. All endpoints require Firebase Authentication.
Developer Authentication
Developer API uses Firebase Auth tokens. Get a token after signing in with Google or GitHub:
Authorization: Bearer <firebase-id-token>
API Keys
/api/v1/developers/keys
List all API keys (prefix only for security).
Response
{
"keys": [
{
"id": "key_abc123",
"name": "Production Key",
"prefix": "pk_live_abc1****",
"createdAt": "2026-01-03T10:00:00Z",
"lastUsedAt": "2026-01-03T15:30:00Z"
}
]
}
/api/v1/developers/keys
Create a new API key. The full key is only returned once!
Request Body
{
"name": "Production Key",
"environment": "live"
}
Response
{
"key": {
"id": "key_abc123",
"name": "Production Key",
"fullKey": "pk_live_abc123def456...",
"prefix": "pk_live_abc1****",
"createdAt": "2026-01-03T10:00:00Z"
},
"warning": "Store this key securely. It will not be shown again."
}
/api/v1/developers/keys/:id
Revoke an API key immediately.
Personas
/api/v1/developers/personas
List all personas created by the authenticated developer.
Response
{
"personas": [
{
"id": "persona_abc123",
"name": "Luna the Coach",
"tagline": "Your thoughtful companion for growth",
"status": "draft",
"category": "coaching",
"createdAt": "2026-01-03T10:00:00Z",
"updatedAt": "2026-01-03T15:30:00Z"
}
]
}
/api/v1/developers/personas
Create a new persona draft.
Request Body (Persona Manifest)
{
"manifest": {
"identity": {
"id": "luna-coach",
"name": "Luna the Coach",
"tagline": "Your thoughtful companion for growth",
"description": "A warm, insightful life coach...",
"aliases": ["Luna", "Coach Luna"]
},
"voice": {
"provider": "cartesia",
"voice_id": "a0e99841-438c-4a64-b679-ae501e7d6091"
},
"personality": {
"warmth": 0.85,
"humor_level": 0.6,
"directness": 0.7,
"formality": 0.3,
"traits": ["empathetic", "encouraging", "insightful"]
},
"knowledge": {
"category": "coaching",
"domains": ["life-coaching", "personal-growth"],
"expertise_tags": ["goal-setting", "habits", "motivation"],
"out_of_scope_topics": ["medical-advice", "legal-advice"]
},
"behaviors": {
"greetings": ["Hey! Ready to make some progress today?"],
"backchannels": ["mm-hmm", "I hear you", "go on"],
"thinking_sounds": ["hmm", "let me think..."]
}
}
}
/api/v1/developers/personas/:id
Update a draft persona. Only drafts and rejected personas can be updated.
/api/v1/developers/personas/:id/validate
Validate a persona manifest before submission.
Response
{
"valid": true,
"errors": [],
"warnings": [
"Consider adding more greeting variations for natural conversation"
]
}
/api/v1/developers/personas/:id/submit
Submit a persona for marketplace review. Must pass validation first.
Response
{
"success": true,
"status": "submitted",
"message": "Your persona has been submitted for review. This typically takes 2-5 business days."
}
/api/v1/developers/personas/:id
Delete a persona. Published personas cannot be deleted (use unpublish instead).
Voices
/api/v1/developers/voices
List curated Cartesia voices available for personas.
Query Parameters
gender- Filter by gender (male, female, neutral)category- Filter by category (conversational, professional, etc.)
Response
{
"voices": [
{
"id": "a0e99841-438c-4a64-b679-ae501e7d6091",
"name": "Sarah",
"description": "Warm and friendly female voice, perfect for coaching",
"gender": "female",
"category": "conversational",
"tags": ["warm", "friendly", "coach"]
}
]
}
/api/v1/developers/voices/preview
Generate an audio preview of a voice with custom text.
Request Body
{
"voice_id": "a0e99841-438c-4a64-b679-ae501e7d6091",
"text": "Hey! I'm so glad you're here. Let's talk about what's on your mind."
}
Response
{
"preview": {
"audioUrl": "data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAP...",
"duration": 3.2,
"text": "Hey! I'm so glad you're here..."
}
}
Persona Lifecycle
Rejected personas can be edited and resubmitted. Published personas appear in the marketplace.
Analytics
/api/v1/developers/analytics/overview
Get summary statistics with comparison to previous period.
Query Parameters
period- Time period: day, week, month, or year (default: week)
Response
{
"overview": {
"totalApiCalls": 12500,
"totalApiCallsChange": 15,
"uniqueUsers": 340,
"uniqueUsersChange": 8,
"activePersonas": 5,
"activePersonasChange": 0,
"errorRate": 0.5,
"errorRateChange": -12,
"avgResponseTime": 245,
"avgResponseTimeChange": -5
}
}
/api/v1/developers/analytics/usage
Get API call volume over time for charting.
Response
{
"usage": [
{ "date": "2026-01-01", "apiCalls": 1850, "uniqueUsers": 42, "errors": 5 },
{ "date": "2026-01-02", "apiCalls": 2100, "uniqueUsers": 48, "errors": 3 }
]
}
/api/v1/developers/analytics/personas
Get per-persona usage breakdown.
Response
{
"personas": [
{
"personaId": "persona_abc123",
"personaName": "Luna the Coach",
"totalCalls": 5200,
"avgSessionDuration": 180000,
"uniqueUsers": 150
}
]
}
/api/v1/developers/analytics/errors
Get error breakdown by type.
Response
{
"errors": [
{
"code": "RATE_LIMIT_EXCEEDED",
"message": "API rate limit exceeded",
"count": 23,
"lastOccurred": "2026-01-03T15:30:00Z"
}
]
}
Publisher API
Submit, update, and manage your published tools and agents.
/api/marketplace/publisher/submit
Submit a new tool or agent for marketplace review.
Request Body
{
"type": "tool",
"manifest": {
"id": "my-habit-tracker",
"name": "Habit Tracker Pro",
"version": "1.0.0",
"publisher": {
"id": "pub_xyz789",
"name": "Acme Corp"
},
"description": {
"short": "Track daily habits with AI insights",
"long": "A comprehensive habit tracking tool..."
},
"execution": {
"runtime": {
"type": "nodejs",
"version": "18"
}
},
"interface": {
"llmDescription": "Tracks user habits and provides insights"
}
}
}
Example Request
curl -X POST https://api.ferni.ai/api/marketplace/publisher/submit \
-H "x-publisher-id: pub_xyz789" \
-H "x-publisher-name: Acme Corp" \
-H "Content-Type: application/json" \
-d @tool-manifest.json
Response (200 OK)
{
"success": true,
"itemId": "my-habit-tracker",
"status": "pending_review",
"reviewNotes": "Your submission is being reviewed. This typically takes 2-5 business days."
}
/api/marketplace/publisher/items
List all items published by your account.
Example Request
curl https://api.ferni.ai/api/marketplace/publisher/items \
-H "x-publisher-id: pub_xyz789" \
-H "x-publisher-name: Acme Corp"
Response (200 OK)
{
"items": [
{
"id": "my-habit-tracker",
"name": "Habit Tracker Pro",
"type": "tool",
"version": "1.0.0",
"status": "approved",
"trustLevel": "community",
"publishedAt": "2025-01-15T10:30:00Z"
}
],
"totalCount": 1
}
/api/marketplace/publisher/profile
Get your publisher profile and statistics.
Response (200 OK)
{
"publisherId": "pub_xyz789",
"publisherName": "Acme Corp",
"verified": true,
"stats": {
"totalTools": 5,
"totalAgents": 2,
"approvedItems": 6,
"pendingItems": 1
}
}
/api/marketplace/publisher/:id/analytics
Get detailed analytics for a specific item.
Example Request
curl https://api.ferni.ai/api/marketplace/publisher/my-habit-tracker/analytics \
-H "x-publisher-id: pub_xyz789" \
-H "x-publisher-name: Acme Corp"
Response (200 OK)
{
"itemId": "my-habit-tracker",
"period": "30d",
"metrics": {
"totalInstalls": 150,
"activeInstalls": 120,
"totalExecutions": 2450,
"successRate": 98.5,
"avgExecutionTimeMs": 125,
"errorCount": 37,
"uniqueUsers": 115
},
"revenue": {
"totalCents": 15000,
"periodCents": 5000,
"currency": "USD"
},
"topErrors": [
{
"code": "RATE_LIMIT_EXCEEDED",
"count": 25,
"lastOccurred": "2025-01-14T18:30:00Z"
}
]
}
/api/marketplace/publisher/:id
Update an existing submission with new manifest data.
Example Request
curl -X PUT https://api.ferni.ai/api/marketplace/publisher/my-habit-tracker \
-H "x-publisher-id: pub_xyz789" \
-H "x-publisher-name: Acme Corp" \
-H "Content-Type: application/json" \
-d @updated-manifest.json
Response (200 OK)
{
"success": true,
"itemId": "my-habit-tracker",
"status": "approved"
}
/api/marketplace/publisher/:id
Delete a submission from the marketplace. Existing installations continue to work for 30 days.
Example Request
curl -X DELETE https://api.ferni.ai/api/marketplace/publisher/my-habit-tracker \
-H "x-publisher-id: pub_xyz789" \
-H "x-publisher-name: Acme Corp"
Response (200 OK)
{
"success": true,
"message": "Item scheduled for removal. Existing installations will continue to work for 30 days."
}
Browse API
Discover and retrieve information about tools and agents in the marketplace.
/api/marketplace/browse/tools
List all available tools in the marketplace.
Example Request
curl https://api.ferni.ai/api/marketplace/browse/tools
Response (200 OK)
{
"tools": [
{
"id": "habit-tracker-pro",
"name": "Habit Tracker Pro",
"description": "Track daily habits with AI insights",
"version": "1.0.0",
"publisher": {
"id": "pub_xyz789",
"name": "Acme Corp"
},
"trustLevel": "community",
"verified": true
}
],
"totalCount": 1
}
/api/marketplace/browse/agents
List all available agents in the marketplace.
Response (200 OK)
{
"agents": [
{
"id": "wellness-coach",
"name": "wellness-coach",
"displayName": "Luna the Wellness Coach",
"description": "Your guide to healthier living",
"version": "2.1.0",
"publisher": {
"id": "pub_xyz789",
"name": "Acme Corp"
},
"trustLevel": "verified",
"verified": true
}
],
"totalCount": 1
}
/api/marketplace/browse/tools/:id
Get detailed information about a specific tool.
Example Request
curl https://api.ferni.ai/api/marketplace/browse/tools/habit-tracker-pro
Response (200 OK)
{
"tool": {
"id": "habit-tracker-pro",
"name": "Habit Tracker Pro",
"version": "1.0.0",
"description": {
"short": "Track daily habits with AI insights",
"long": "A comprehensive habit tracking tool with AI-powered analytics..."
},
"publisher": {
"id": "pub_xyz789",
"name": "Acme Corp"
},
"execution": {
"runtime": {
"type": "nodejs",
"version": "18"
}
},
"interface": {
"llmDescription": "Tracks user habits and provides insights"
},
"verification": {
"trustLevel": "community",
"verified": true,
"verifiedAt": "2025-01-10T12:00:00Z"
}
}
}
/api/marketplace/browse/agents/:id
Get detailed information about a specific agent.
Example Request
curl https://api.ferni.ai/api/marketplace/browse/agents/wellness-coach
Install API
Install, uninstall, and manage marketplace items.
/api/marketplace/install/tool
Install a tool for the authenticated user.
Request Body
{
"toolId": "habit-tracker-pro",
"grantedPermissions": ["user:read", "user:write"]
}
Example Request
curl -X POST https://api.ferni.ai/api/marketplace/install/tool \
-H "x-user-id: user_abc123" \
-H "Content-Type: application/json" \
-d '{"toolId":"habit-tracker-pro","grantedPermissions":["user:read","user:write"]}'
Response (200 OK)
{
"success": true,
"installation": {
"id": "inst_def456",
"toolId": "habit-tracker-pro",
"installedAt": "2025-01-14T15:30:00Z"
}
}
/api/marketplace/install/agent
Install an agent for the authenticated user.
Request Body
{
"agentId": "wellness-coach",
"grantedPermissions": ["user:read"]
}
Response (200 OK)
{
"success": true,
"installation": {
"id": "inst_ghi789",
"agentId": "wellness-coach",
"installedAt": "2025-01-14T15:32:00Z"
}
}
/api/marketplace/install/tool/:id
Uninstall a tool.
Example Request
curl -X DELETE https://api.ferni.ai/api/marketplace/install/tool/habit-tracker-pro \
-H "x-user-id: user_abc123"
Response (200 OK)
{
"success": true
}
/api/marketplace/install/agent/:id
Uninstall an agent.
Example Request
curl -X DELETE https://api.ferni.ai/api/marketplace/install/agent/wellness-coach \
-H "x-user-id: user_abc123"
/api/marketplace/install/list
List all installations for the authenticated user.
Example Request
curl https://api.ferni.ai/api/marketplace/install/list \
-H "x-user-id: user_abc123"
Response (200 OK)
{
"installations": [
{
"id": "inst_def456",
"itemId": "habit-tracker-pro",
"itemType": "tool",
"installedAt": "2025-01-14T15:30:00Z",
"status": "active"
},
{
"id": "inst_ghi789",
"itemId": "wellness-coach",
"itemType": "agent",
"installedAt": "2025-01-14T15:32:00Z",
"status": "active"
}
],
"totalCount": 2
}
Usage & Billing API
Track usage, check quotas, and retrieve billing information.
/api/marketplace/usage/:itemId
Get usage statistics for a specific item.
Example Request
curl https://api.ferni.ai/api/marketplace/usage/habit-tracker-pro \
-H "x-user-id: user_abc123" \
-H "x-subscription-tier: pro"
Response (200 OK)
{
"itemId": "habit-tracker-pro",
"period": "2025-01",
"userId": "user_abc123",
"tier": "pro",
"totals": {
"executions": 45,
"executionTimeMs": 12500,
"quotaUsed": 45,
"quotaLimit": 1000
},
"breakdown": [
{
"date": "2025-01-14",
"executions": 5,
"executionTimeMs": 1250
}
]
}
/api/marketplace/usage/summary
Get aggregated usage across all installed items.
Example Request
curl https://api.ferni.ai/api/marketplace/usage/summary \
-H "x-user-id: user_abc123" \
-H "x-subscription-tier: pro"
Response (200 OK)
{
"period": "2025-01",
"userId": "user_abc123",
"tier": "pro",
"aggregate": {
"totalExecutions": 87,
"totalTimeMs": 24500,
"itemCount": 2
},
"items": [
{
"itemId": "habit-tracker-pro",
"totals": {
"executions": 45,
"executionTimeMs": 12500,
"quotaUsed": 45,
"quotaLimit": 1000
}
}
]
}
/api/marketplace/quota/check/:itemId
Check if user has available quota to execute an item.
Example Request
curl https://api.ferni.ai/api/marketplace/quota/check/habit-tracker-pro \
-H "x-user-id: user_abc123" \
-H "x-subscription-tier: pro"
Response (200 OK)
{
"allowed": true,
"reason": null,
"quotaUsed": 45,
"quotaLimit": 1000,
"remainingQuota": 955
}
Response (200 OK - Quota Exceeded)
{
"allowed": false,
"reason": "Monthly quota exceeded. Upgrade to Pro for higher limits.",
"quotaUsed": 100,
"quotaLimit": 100,
"remainingQuota": 0
}
Error Codes
The API uses standard HTTP status codes and returns error details in JSON format.
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid request body or parameters |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Not authorized to access resource |
| 404 | Not Found | Resource does not exist |
| 500 | Internal Server Error | Server error occurred |
Error Response Format
{
"success": false,
"error": "Validation failed",
"validationErrors": [
"Tool ID is required",
"Valid semantic version required (e.g., 1.0.0)"
]
}
Common Error Scenarios
Missing Authentication
401 Unauthorized - Include x-user-id or x-publisher-id header
Publisher ID Mismatch
403 Forbidden - Publisher ID in manifest must match authenticated publisher
Item Not Found
404 Not Found - Requested tool or agent does not exist
Invalid Manifest
400 Bad Request - Check validationErrors array for specific issues