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

  1. Sign up for an account at your Ikat instance
  2. Get your API key from the Settings page
  3. Start uploading files using the API endpoints below
  4. Monitor your usage from the Dashboard
Base URL:
https://your-domain.com
Important:
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"
Unauthorized Response:
{
  "success": false,
  "code": "UNAUTHORIZED",
  "message": "Missing API key"
}
Upload File

Upload File to Bucket

Upload files with automatic image optimization and format conversion.

Endpoint

POST /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
  }
}
Quota Exceeded:
{
  "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
Pro Tip:
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_KEY header
  • 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"
Security Note:
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

GET /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

POST /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"
}
Important:
Deletion is permanent. All versions (original + WebP) are deleted.
Delete Bucket

Delete Entire Bucket

Delete all files in a bucket at once.

Endpoint

POST /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
}
Warning:
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

GET /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
  }
}
Note:
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."
}
Tip:
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.

Official Support:
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

Get the SDK:
Download the complete SDK with documentation: ikat-storage.ts - TypeScript SDK (~300 lines)
README.md - Complete documentation with examples
Note:
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 allowPublicAccess parameter
  • Handle image optimization URLs (original, large, small, thumb)
  • Implement proper error handling and rate limiting
  • Share your library with the community!
Contribute:
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 thumb for grid listings and thumbnails (~5-10KB)
  • Use small for mobile content images (~20-50KB)
  • Use large for desktop hero images (~100-200KB)
  • Keep original for 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=false for 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 success field in responses
  • Implement retry logic with exponential backoff for 429 errors
  • Handle quota exceeded errors gracefully
  • Log errors for debugging and monitoring
Need Help?
Contact support at [email protected]