Internal API Reference
Complete documentation for all Funl API endpoints with examples and parameters.
Overview
Funl provides a comprehensive REST API with 18 endpoints for programmatic funnel management. All endpoints require API key authentication with Pro plan or higher.
Authentication
Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Get your API key from Account Settings. Pro plan or higher required.
Base URL
https://funl.ad/api/internal/v1
Funnels
List Funnels
GET /funnels
Returns all funnels (projects) for the authenticated user.
Response:
{ "status": "success", "data": [ { "id": "...", "name": "...", "created_at": "2025-06-04T08:00:00+00:00", "updated_at": "2025-06-04T08:00:00+00:00", "deploy_url": "https://...", "status": "..." } ] }
Create Funnel
POST /funnels
Create a new funnel for the authenticated user. Optionally apply a template during creation.
Request Body:
{ "name": "My Funnel", "template_id": "snow-template" // optional }
Response:
{ "status": "success", "data": { "id": "...", "name": "My Funnel", "created_at": "2025-06-04T08:00:00+00:00", "updated_at": "2025-06-04T08:00:00+00:00", "deploy_url": null, "status": null } }
Get Funnel Details
GET /funnels/:id
Returns details for a single funnel owned by the authenticated user.
Response:
{ "status": "success", "data": { "id": "...", "name": "...", "created_at": "2025-06-04T08:00:00+00:00", "updated_at": "2025-06-04T08:00:00+00:00", "deploy_url": "https://...", "status": "..." } }
Update Funnel
PATCH /funnels/:id
Update funnel name.
Request Body:
{ "name": "New Funnel Name" }
Response:
{ "status": "success", "data": { "id": "...", "name": "New Funnel Name", "created_at": "2025-06-04T08:00:00+00:00", "updated_at": "2025-06-04T08:01:00+00:00", "deploy_url": "https://...", "status": "..." } }
Delete Funnel
DELETE /funnels/:id
Deletes the specified funnel.
Response:
{ "status": "success" }
Deploy Funnel
POST /funnels/:id/deploy
Deploys the specified funnel. This will trigger a deployment and update the funnel's deploy_url and status.
Response:
{ "status": "success", "data": { "id": "...", "deploy_url": "https://funl.ad/user-sites/{id}/index.html", "status": "deployed" } }
Get Funnel Content
GET /funnels/:id/content
Returns all files and content for a funnel.
Response:
{ "status": "success", "data": { "src/index.html": "<!DOCTYPE html>...", "src/css/style.css": "body { ... }", "src/js/script.js": "document.addEventListener..." }, "meta": { "funnel_id": "funnel-uuid", "last_modified": "2025-06-13T10:30:00Z", "total_files": 3 } }
Update Funnel Content
PUT /funnels/:id/content
Updates the content files for a funnel with smart file path normalization.
Request Body:
{ "files": { "src/index.html": "<!DOCTYPE html>...", "src/css/style.css": "body { ... }" }, "message": "Updated headline and styling" }
Response:
{ "status": "success", "data": { "funnel_id": "funnel-uuid", "updated_files": 2, "message": "Updated headline and styling", "timestamp": "2025-06-13T10:35:00Z" } }
Smart File Path Normalization
This endpoint features intelligent file matching:
- • Exact path matching first (
src/index.html
→src/index.html
) - • Basename matching if no exact match (
index.html
updates existingsrc/index.html
) - • Automatic directory placement for new files
- • Duplicate prevention via basename matching
Assign Custom Domain
POST /funnels/:id/assign-domain
Assigns a custom domain to a funnel for professional branding. Only available for Pro, Team, and Enterprise plans.
Request Body:
{ "domain": "example.com" }
Response:
{ "status": "success", "data": { "funnel_id": "funnel-uuid", "domain": "example.com", "assigned_at": "2025-06-15T10:30:00Z" } }
Domain Requirements
- • Domain format: example.com (no http/https or www)
- • One domain per funnel maximum
- • DNS configuration required after assignment
- • Pro plan or higher required
Remove Custom Domain
POST /funnels/:id/remove-domain
Removes a custom domain assignment from a funnel, reverting it back to the default funl.ad subdomain.
Response:
{ "status": "success", "data": { "funnel_id": "funnel-uuid", "removed_domain": "example.com", "removed_at": "2025-06-15T10:30:00Z" } }
Templates
Template ID Consistency
Both list and get template endpoints use the template's internal id
field from the JSON data, ensuring all listed templates are accessible via the get endpoint.
List Templates
GET /templates
Returns all available templates with metadata. Uses each template's internal ID field.
Response:
{ "status": "success", "data": [ { "id": "snow-template", "name": "Snow Template", "category": "Advertorials", "steps": 2, "description": "A winter-themed toothbrush funnel template", "previewImage": "snow.png" } ] }
Get Template Details
GET /templates/:id
Returns complete template data including all files. Searches by the template's internal ID field (not filename).
Response:
{ "status": "success", "data": { "id": "snow-template", "category": "Advertorials", "steps": 2, "name": "Snow Template", "description": "A winter-themed toothbrush funnel template", "previewImage": "snow.png", "files": { "src/index.html": "<!DOCTYPE html>...", "src/css/style.css": "body { ... }", "src/js/script.js": "document.addEventListener..." } } }
Images
Upload Image
POST /images/upload
Upload images to Supabase Storage for use in funnels.
Request:
Content-Type: multipart/form-data
Body: image file (PNG, JPG, GIF, WebP - max 5MB)
Response:
{ "status": "success", "data": { "id": "image-uuid", "name": "hero-image.jpg", "url": "https://storage.supabase.co/...", "size": 1024567, "mime_type": "image/jpeg", "uploaded_at": "2025-06-13T10:30:00Z" } }
Upload Image from URL
POST /images/upload-from-url
Download an image from a URL and upload it to your project storage.
Request Body:
{ "url": "https://example.com/image.jpg", "project_id": "project-uuid-123", "filename": "my-image.jpg" }
Response:
{ "status": "success", "data": { "id": "image-uuid", "name": "my-image-123456.jpg", "url": "https://storage.supabase.co/...", "size": 1024567, "mime_type": "image/jpeg", "uploaded_at": "2025-06-13T10:30:00Z", "source_url": "https://example.com/image.jpg" } }
Notes
- • Image must be publicly accessible via HTTP/HTTPS
- • Supports JPG, PNG, GIF, WebP formats
- • Maximum file size: 5MB
- •
project_id
is required - must be a valid project owned by the user - • Auto-adds timestamp to ensure uniqueness
List Images
GET /images
List all uploaded images for the authenticated user.
Response:
{ "status": "success", "data": [ { "id": "image-uuid", "name": "hero-image.jpg", "url": "https://storage.supabase.co/...", "size": 1024567, "mime_type": "image/jpeg", "uploaded_at": "2025-06-13T10:30:00Z" } ] }
Delete Image
DELETE /images/:id
Delete an uploaded image.
Response:
{ "status": "success" }
File Operations
Delete Individual File
DELETE /funnels/:id/files/:filename
Delete a specific non-image file from a funnel's file structure.
URL Parameters:
- •
:id
- Funnel ID (must be owned by authenticated user) - •
:filename
- File path to delete (URL-encoded if contains special characters)
Response:
{ "status": "success", "data": { "funnel_id": "funnel-uuid", "deleted_file": "src/old-page.html", "remaining_files": 3 } }
Important Notes
- • File deletion is permanent and cannot be undone
- • Image files are blocked - use Image API for complete image deletion
- • Filename supports URL encoding for special characters
- • Supported file types: HTML, CSS, JS, JSON, TXT, MD, XML, etc.
Rename File
PUT /funnels/:id/files/:filename/rename
Rename or move a non-image file within a funnel while preserving its content.
Request Body:
{ "new_name": "src/new-page.html" }
Response:
{ "status": "success", "data": { "funnel_id": "funnel-uuid", "old_name": "src/old-page.html", "new_name": "src/new-page.html" } }
Features
- • Both old and new filenames support URL encoding
- • Cannot rename to existing filename (prevents overwrites)
- • File content is preserved during rename operation
- • Can be used to move files between directories
Error Responses
All endpoints may return these standard error responses:
- •
401 Unauthorized
— Missing or invalid API key - •
403 Forbidden
— Revoked key or insufficient plan - •
400 Bad Request
— Missing or invalid parameters - •
404 Not Found
— Resource not found or not owned by user - •
500 Internal Server Error
— Server/database error
Plan Requirements
- • Free Plan: Basic funnel operations only
- • Starter Plan: Templates + basic file operations
- • Pro Plan: Images, domains, analytics, AI features
- • Team/Enterprise Plan: All features + collaboration