Getting Started
Welcome to Ikat API
Ikat is a powerful, developer-friendly file storage API with built-in image optimization, file protection, and bucket management capabilities.
Key Features
Fast & Efficient
Automatic image optimization with WebP conversion and multiple sizes
Secure
File protection with API key authentication and origin restrictions
Organized
Bucket-based organization for easy file management
Scalable
Support for large files up to 10GB with quota management
Quick Start
- Sign up for an account at your Ikat instance
- Get your API key from the Settings page
- Start uploading files using the API endpoints below
- Monitor your usage from the Dashboard
https://your-domain.com
Keep your API key secure. Never expose it in client-side code or public repositories.
Authentication
API Authentication
All API requests require authentication using an API key passed via the x-api-key header.
Header Format
x-api-key: YOUR_API_KEY_HERE
Origin Restriction (Optional)
If you've configured allowed origins in settings, include the Origin header:
Origin: https://yourdomain.com
Example Request
curl -X GET https://your-domain.com/files/images \
-H "x-api-key: your_api_key_here" \
-H "Origin: https://yourdomain.com"
{
"success": false,
"code": "UNAUTHORIZED",
"message": "Missing API key"
}
Upload File
Upload File to Bucket
Upload files with automatic image optimization and format conversion.
Endpoint
/upload/:bucket
Supported File Types
- Images: jpg, jpeg, png, gif, webp, bmp, tiff, svg, heic, heif, avif, ico, and more
- Videos: mp4, mov, avi, mkv, wmv, webm, flv, 3gp, mpeg, and more
- Documents: pdf
- Archives: zip, rar, 7z, tar, gz
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file |
File | Yes | The file to upload (max 10GB) |
allowPublicAccess |
Boolean | No | Default: true. Set to false for protected files |
Example Request
curl -X POST https://your-domain.com/upload/profile \
-H "x-api-key: YOUR_API_KEY" \
-F "[email protected]" \
-F "allowPublicAccess=true"
Success Response (Image)
{
"success": true,
"message": "File uploaded successfully",
"url": "https://your-domain.com/userId/profile/uuid.jpg",
"file": {
"original": "photo.jpg",
"mimetype": "image/jpeg",
"size": 1234567,
"allowPublicAccess": true
}
}
Note: For images, optimized WebP versions are automatically generated and accessible at:
• Large (1920px): uuid-large.webp
• Small (800px): uuid-small.webp
• Thumb (300px): uuid-thumb.webp
Success Response (Non-Image)
{
"success": true,
"message": "File uploaded successfully",
"url": "https://your-domain.com/userId/documents/uuid.pdf",
"file": {
"original": "document.pdf",
"mimetype": "application/pdf",
"size": 987654,
"allowPublicAccess": false
}
}
{
"success": false,
"code": "QUOTA_EXCEEDED",
"message": "Storage quota exceeded"
}
Image Optimization
Automatic Image Optimization
When you upload images, Ikat automatically generates optimized WebP versions in multiple sizes.
Generated Sizes
| Version | Max Width | Format | Use Case |
|---|---|---|---|
original |
Original | Original format | Full quality display, downloads |
large |
1920px | WebP (80% quality) | Desktop displays, hero images |
small |
800px | WebP (80% quality) | Mobile devices, content images |
thumb |
300px | WebP (80% quality) | Thumbnails, previews, lists |
Benefits
- Faster Loading: WebP files are 25-35% smaller than JPEG/PNG
- Bandwidth Savings: Serve appropriate size for each use case
- Better UX: Responsive images with lazy loading support
- Original Preserved: Original file always available
Use
thumb for lists and previews, small for mobile,
large for desktop, and original for downloads.
File Protection
Protected Files
Control file access with the allowPublicAccess flag.
Access Modes
| Mode | allowPublicAccess | Authentication Required | Use Case |
|---|---|---|---|
| Public | true |
No | Public images, downloads, CDN assets |
| Protected | false |
Yes (API key or session) | Private files, user-specific content |
Upload Protected File
curl -X POST https://your-domain.com/upload/private \
-H "x-api-key: YOUR_API_KEY" \
-F "[email protected]" \
-F "allowPublicAccess=false"
Access Protected File
Protected files require authentication via:
- API Key: Include
Authorization: Bearer YOUR_API_KEYheader - Session: Must be logged in as the file owner
curl -X GET https://your-domain.com/userId/private/uuid.pdf \
-H "Authorization: Bearer YOUR_API_KEY"
Unauthorized access to protected files returns
404 Not Found
(not 401/403) to hide file existence from attackers.
List Files
List Files in Bucket
Retrieve all files in a specific bucket.
Endpoint
/files/:bucket
Example Request
curl -X GET https://your-domain.com/files/profile \
-H "x-api-key: YOUR_API_KEY"
Response
{
"success": true,
"bucket": "profile",
"files": [
{
"id": "uuid",
"original": "photo.jpg",
"key": "uuid.jpg",
"mimetype": "image/jpeg",
"size": 1234567,
"bucket": "profile",
"allowPublicAccess": true,
"createdAt": "2025-11-11T12:00:00.000Z",
"url": "https://your-domain.com/userId/profile/uuid.jpg"
}
]
}
Retrieve File
Access Files via URL
Files are accessible via direct URL based on their access mode.
URL Pattern
https://your-domain.com/:userId/:bucket/:filename
Public File (No Auth)
curl -O https://your-domain.com/userId/public/photo.jpg
Protected File (With Auth)
curl -O https://your-domain.com/userId/private/doc.pdf \
-H "Authorization: Bearer YOUR_API_KEY"
WebP Versions
For images, access optimized versions by replacing the extension:
- Original:
userId/bucket/uuid.jpg - Large:
userId/bucket/uuid-large.webp - Small:
userId/bucket/uuid-small.webp - Thumb:
userId/bucket/uuid-thumb.webp
Delete File
Delete Single File
Permanently delete a file from storage.
Endpoint
/files/delete
Request Body
{
"bucket": "profile",
"key": "uuid.jpg"
}
Example Request
curl -X POST https://your-domain.com/files/delete \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"bucket":"profile","key":"uuid.jpg"}'
Success Response
{
"success": true,
"message": "File deleted successfully",
"key": "uuid.jpg"
}
Deletion is permanent. All versions (original + WebP) are deleted.
Delete Bucket
Delete Entire Bucket
Delete all files in a bucket at once.
Endpoint
/files/delete-bucket
Request Body
{
"bucket": "old-bucket"
}
Example Request
curl -X POST https://your-domain.com/files/delete-bucket \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"bucket":"old-bucket"}'
Success Response
{
"success": true,
"message": "Bucket deleted successfully",
"bucket": "old-bucket",
"filesDeleted": 42
}
This action cannot be undone. All files and their optimized versions will be permanently deleted.
Quota & Usage
Check Storage Usage
Monitor your current storage usage and available quota.
Endpoint
/usage
Example Request
curl -X GET https://your-domain.com/usage \
-H "x-api-key: YOUR_API_KEY"
Response
{
"success": true,
"data": {
"totalQuota": 1073741824,
"usedQuota": 536870912,
"remainingQuota": 536870912,
"percentUsed": 50
}
}
All values are in bytes. Monitor usage from the Dashboard for a visual representation.
Error Codes
HTTP Status Codes & Error Responses
| Status | Code | Description |
|---|---|---|
400 |
BAD_REQUEST |
Invalid request parameters or missing required fields |
401 |
UNAUTHORIZED |
Missing or invalid API key |
403 |
QUOTA_EXCEEDED |
Storage quota limit reached |
403 |
FORBIDDEN |
Origin not allowed for this API key |
404 |
FILE_NOT_FOUND |
File or bucket not found (also returned for protected files without auth) |
429 |
RATE_LIMIT_EXCEEDED |
Too many requests, please slow down |
500 |
INTERNAL_SERVER_ERROR |
Unexpected server error |
Error Response Format
{
"success": false,
"code": "ERROR_CODE",
"message": "Human-readable error message"
}
Rate Limiting
API Rate Limits
To ensure fair usage and system stability, the following rate limits apply:
| Endpoint | Limit | Window |
|---|---|---|
POST /upload/:bucket |
120 requests | 1 minute |
GET /files/:bucket |
120 requests | 1 minute |
POST /files/delete |
50 requests | 1 minute |
GET /usage |
100 requests | 1 minute |
Rate Limit Response
{
"success": false,
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests, please try again later."
}
Implement exponential backoff in your client when receiving 429 errors.
SDK & Libraries
Client Libraries
Pre-built SDKs to integrate Ikat Storage API into your applications quickly and easily.
Currently, we provide an official TypeScript SDK for Next.js applications. More libraries coming soon!
Next.js / TypeScript SDK
Type-safe SDK with full support for all Ikat features including image optimization, file protection, and batch operations.
Installation
# Install dependencies
npm install axios form-data
# Copy the SDK file to your project
# Download from: /lib/ikat-storage.ts
Environment Setup
Create a .env.local file in your Next.js project:
STORAGE_BASE_URL=https://your-ikat-instance.com
STORAGE_SECRET_KEY=your_api_key_here
STORAGE_BUCKET_NAME=default-bucket
STORAGE_ORIGIN=https://yourapp.com # Optional
Basic Usage Example
import { uploadFile, listFiles, removeFile } from '@/lib/ikat-storage';
// Upload a public image (auto-generates webp versions: large, small, thumb)
const result = await uploadFile(imageFile);
console.log(result.url); // Original file URL
// For images, optimized versions are automatically available:
const largeUrl = result.url.replace(/\.\w+$/, '-large.webp'); // 1920px
const smallUrl = result.url.replace(/\.\w+$/, '-small.webp'); // 800px
const thumbUrl = result.url.replace(/\.\w+$/, '-thumb.webp'); // 300px
// Upload a protected file
const privateFile = await uploadFile(pdfFile, {
allowPublicAccess: false
});
// List all files in bucket
const files = await listFiles('my-bucket');
// Delete a file
await removeFile('photo.jpg');
Next.js API Route Example
// app/api/upload/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { uploadFile } from '@/lib/ikat-storage';
export async function POST(request: NextRequest) {
try {
const formData = await request.formData();
const file = formData.get('file') as File;
const isPublic = formData.get('public') === 'true';
if (!file) {
return NextResponse.json(
{ error: 'No file provided' },
{ status: 400 }
);
}
const result = await uploadFile(file, {
allowPublicAccess: isPublic
});
return NextResponse.json(result);
} catch (error) {
return NextResponse.json(
{ error: 'Upload failed' },
{ status: 500 }
);
}
}
React Client Component Example
'use client';
import { useState } from 'react';
export default function UploadForm() {
const [file, setFile] = useState<File | null>(null);
const [uploading, setUploading] = useState(false);
const [result, setResult] = useState<any>(null);
const handleUpload = async () => {
if (!file) return;
setUploading(true);
const formData = new FormData();
formData.append('file', file);
formData.append('public', 'true');
try {
const res = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
const data = await res.json();
setResult(data);
} catch (error) {
console.error('Upload error:', error);
} finally {
setUploading(false);
}
};
return (
<div>
<input
type="file"
onChange={(e) => setFile(e.target.files?.[0] || null)}
/>
<button onClick={handleUpload} disabled={!file || uploading}>
{uploading ? 'Uploading...' : 'Upload'}
</button>
{result?.url && (
<div>
<h3>Upload Successful!</h3>
{result.file.mimetype.startsWith('image/') && (
<>
<img src={result.url.replace(/\.\w+$/, '-thumb.webp')} alt="Preview" />
<p>Thumbnail: {result.url.replace(/\.\w+$/, '-thumb.webp')}</p>
<p>Small: {result.url.replace(/\.\w+$/, '-small.webp')}</p>
<p>Large: {result.url.replace(/\.\w+$/, '-large.webp')}</p>
</>
)}
<p>Original: {result.url}</p>
</div>
)}
</div>
);
}
Available Methods
| Method | Description |
|---|---|
uploadFile(file, options?) |
Upload a file with automatic image optimization |
listFiles(bucketName?) |
List all files in a bucket |
getFile(key, bucketName?) |
Get specific file metadata |
removeFile(key, bucketName?) |
Delete a file and all its versions |
removeBucket(bucketName?) |
Delete entire bucket with all files |
replaceFile(file, oldUrl?, options?) |
Replace an existing file with a new one |
uploadMultipleFiles(files, options?) |
Batch upload multiple files |
deleteMultipleFiles(keys, bucketName?) |
Batch delete multiple files |
getUsage() |
Get storage quota and usage information |
TypeScript Types
The SDK includes full TypeScript type definitions:
import {
IkatStorage,
UploadOptions,
ImageUploadResponse,
FileUploadResponse,
FileMetadata,
ListFilesResponse,
DeleteResponse,
DeleteBucketResponse,
UsageResponse
} from '@/lib/ikat-storage';
Advanced Example: Batch Upload
import { uploadMultipleFiles } from '@/lib/ikat-storage';
const files = [file1, file2, file3];
const results = await uploadMultipleFiles(files, {
allowPublicAccess: true
});
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`Uploaded: ${successful.length}`);
console.log(`Failed: ${failed.length}`);
Download SDK
Download the complete SDK with documentation: •
ikat-storage.ts - TypeScript SDK (~300 lines)•
README.md - Complete documentation with examples
The SDK is designed for server-side usage in Next.js API routes. Never expose your API key in client-side code!
Community Libraries
Want to build a client library for another language or framework?
- Follow the API endpoints documented above
- Include support for
allowPublicAccessparameter - Handle image optimization URLs (original, large, small, thumb)
- Implement proper error handling and rate limiting
- Share your library with the community!
If you've built a client library for another language/framework, please contact us at [email protected] to get it featured here!
Best Practices
Best Practices & Tips
Image Optimization
- Use
thumbfor grid listings and thumbnails (~5-10KB) - Use
smallfor mobile content images (~20-50KB) - Use
largefor desktop hero images (~100-200KB) - Keep
originalfor downloads and archival
File Organization
- Use descriptive bucket names:
profile-pictures,blog-images - Separate public and protected content into different buckets
- Clean up unused files regularly to manage quota
Security
- Never expose API keys in frontend code
- Use origin restrictions for frontend applications
- Set
allowPublicAccess=falsefor sensitive files - Rotate API keys periodically
Performance
- Use CDN or browser caching for static files
- Implement lazy loading for images
- Batch operations when deleting multiple files
- Monitor quota usage to prevent upload failures
Error Handling
- Always check
successfield in responses - Implement retry logic with exponential backoff for 429 errors
- Handle quota exceeded errors gracefully
- Log errors for debugging and monitoring
Contact support at [email protected]