API Documentation

Complete developer guide for integrating beautiful Hindi, Marathi, Gujarati, and English calligraphy generation API. Build applications with professional Devanagari script rendering, customizable fonts, and high-quality image output.

REST API
Webhooks Support
Batch Processing
Secure & Reliable
Getting Started
1

Get API Key

Sign up and generate your Free API key for testing

Sign up for free account
2

Make First Request

Test the API with a simple generation

Generate "नमस्ते" in Hindi
3

Integrate & Build

Add calligraphy makers API to your application

Use SDKs or direct HTTP calls

Quick Test Request

curl
curl -X POST "https://api.calligraphymaker.com/api/v2/generate" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{"text": "नमस्ते", "language": "hindi", "fontStyle": "calligraphy", "imageFormat": "png"}'
Interactive API DemoTry it live

Test the Calligraphy API with different parameters and see the exact code needed for your implementation.

Demo Mode

This is an interactive demo interface. To see actual generated calligraphy, sign up for a free API key and use the real endpoint.

Authentication

API Key Authentication

All API requests require authentication using an API key sent in the request header:

http
x-api-key: your_api_key_here

API Key Permissions

CALLIGRAPHY_GENERATION

Basic text to calligraphy generation

BATCH_PROCESSING

Batch generation capabilities

Security Best Practices

  • • Never expose API keys in client-side code
  • • Use environment variables to store keys securely
  • • Rotate API keys regularly
  • • Use different keys for development and production
Generation API

Core Parameters

ParameterTypeRequiredDescription
textstringRequiredText to convert to calligraphy
languagestringRequiredLanguage: "hindi", "marathi", "gujarati", "english"
fontStylestringOptionalStyle: "calligraphy", "decorative", "publication"
fontWeightstringOptionalWeights: "regular", "light", "bold"
fontFamilystringOptionalSpecific font family name
countnumberOptionalNumber of generations (1-4, default: 4)
imageFormatstringOptionalOutput format: "png", "jpg", "webp" (default: png)

Example Request & Response

Request:

json
POST /api/v2/generate
Content-Type: application/json
x-api-key: YOUR_API_KEY

{
  "text": "नमस्ते दोस्तों",
  "language": "hindi",
  "fontStyle": "calligraphy",
  "count": 3,
  "imageFormat": "png"
}

Response:

json
{
  "success": true,
  "data": {
    "generationId": "gen_clp7x8y9z123456789",
    "images": [
      {
        "url": "https://api.calligraphymaker.com/generated/img_001.png",
        "cdnUrl": "https://cdn.calligraphymaker.com/img_001.png",
        "format": "png",
        "size": 245760,
        "fontUsed": "AMS-Abhimanyu"
      },
      {
        "url": "https://api.calligraphymaker.com/generated/img_002.png", 
        "cdnUrl": "https://cdn.calligraphymaker.com/img_002.png",
        "format": "png",
        "size": 251340,
        "fontUsed": "AMS-Chitra"
      },
      {
        "url": "https://api.calligraphymaker.com/generated/img_003.png", 
        "cdnUrl": "https://cdn.calligraphymaker.com/img_003.png",
        "format": "png",
        "size": 248920,
        "fontUsed": "AMS-Narendra"
      }
    ],
    "metadata": {
      "text": "नमस्ते दोस्तों",
      "language": "hindi",
      "processingTime": "1.847s"
    },
    "creditsUsed": 1,
    "remainingCredits": 8499
  }
}
API Endpoints
POST/api/v2/generateCore

Generate Calligraphy

Generate beautiful calligraphy images from text

POST/api/v2/download-svgSVG

Download SVG

Generate downloadable SVG from text and font name

POST/api/v2/download-imageImage

Download Image

Generate downloadable PNG/JPG images with custom dimensions

GET/api/v2/webhooksWebhooks

Get Webhooks

Retrieve configured webhook settings

POST/api/v2/webhooksWebhooks

Configure Webhooks

Set up webhook endpoints for events

SVG Download

Generate and download SVG files directly from styled text and font names. Perfect for creating high-quality vector calligraphy with specific font choices.

SVG Download Example

POST /api/v2/download-svg
Content-Type: application/json
x-api-key: YOUR_API_KEY

{
  "resultText": "ॐ॒ श॒ांत॒ि",
  "fontName": "ams-abhimanyu"
}

SVG Download Response

json
{
  "success": true,
  "data": {
    "resultText": "ॐ॒ श॒ांत॒ि",
    "fontFamily": "ams-abhimanyu",
    "format": "svg",
    "svgBase64": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODAwIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDgwMCA2MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTTE1MC41MCAxNTAuMzMgTDE2Mi40NSAxNDIuODkgQzE2OC4xMiAxNTYuNzggMTc0LjIzIDE2OC40NSAxODAuODkgMTc3LjkxIEwxOTIuMzMgMTg1LjIzIEMxODguNjcgMTkyLjEyIDE4NC4zNCAxOTcuNTYgMTc5LjIzIDIwMS40NSBaIiBmaWxsPSIjMDAwMDAwIi8+Cjwvc3ZnPg==",
    "svgString": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"800\" height=\"600\" viewBox=\"0 0 800 600\" xmlns=\"http://www.w3.org/2000/svg\">\n  <path d=\"M150.50 150.33 L162.45 142.89 C168.12 156.78 174.23 168.45 180.89 177.91 L192.33 185.23 C188.67 192.12 184.34 197.56 179.23 201.45 Z\" fill=\"#000000\"/>\n</svg>",
    "dimensions": {
      "width": 800,
      "height": 600
    }
  }
}

cURL Command

bash
curl -X POST "https://api.calligraphymaker.com/api/v2/download-svg" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "resultText": "ॐ॒ श॒ांत॒ि",
    "fontName": "ams-abhimanyu",
    "svgWidth": 800,
    "svgHeight": 600,
    "fontSize": 48,
    "textColor": "#000000",
    "backgroundColor": "transparent"
  }'

Key Features

  • • Direct font-to-SVG conversion
  • • True vector paths from font glyphs
  • • Both base64 and string formats
  • • Scalable and font-independent
  • • Optimal font sizing

Use Cases

  • • Custom calligraphy downloads
  • • Print-ready vector files
  • • High-quality logos
  • • Web graphics without fonts
  • • Animation-ready paths

Parameters

resultText (string, required): The styled text to convert to SVG
fontName (string, required): The exact font name from your database (sanitized: alphanumeric, hyphen, underscore only)
Image Download

Generate and download PNG or JPG images directly from styled text and font names with customizable dimensions, quality, and colors.

Image Download Example

bash
POST /api/v2/download-image
Content-Type: application/json
x-api-key: YOUR_API_KEY

{
  "resultText": "नमस्ते दुनिया",
  "fontName": "ams-abhimanyu",
  "imageWidth": 800,
  "imageHeight": 600,
  "imageQuality": 90,
  "imageFormat": "png",
  "backgroundColor": "#ffffff",
  "textColor": "#000000"
}

Image Download Response

json
{
  "success": true,
  "data": {
    "resultText": "नमस्ते दुनिया",
    "fontName": "ams-abhimanyu",
    "format": "png",
    "imageBase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
    "dimensions": {
      "width": 800,
      "height": 600
    },
    "quality": 90,
    "backgroundColor": "#ffffff",
    "textColor": "#000000"
  }
}

cURL Command

bash
curl -X POST "https://api.calligraphymaker.com/api/v2/download-image" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "resultText": "नमस्ते दुनिया",
    "fontName": "ams-abhimanyu",
    "imageWidth": 800,
    "imageHeight": 600,
    "imageQuality": 90,
    "imageFormat": "png",
    "backgroundColor": "#ffffff",
    "textColor": "#000000"
  }'

PNG Format

  • • Supports transparency
  • • Lossless compression
  • • Best for graphics with text
  • • Higher file size

JPG Format

  • • No transparency support
  • • Adjustable quality (1-100)
  • • Smaller file size
  • • Best for photos/web use

Parameters

Required:

  • • resultText (string)
  • • fontName (string, sanitized: alphanumeric, hyphen, underscore only)

Optional:

  • • imageWidth (100-1200px, default: 800)
  • • imageHeight (100-1200px, default: 600)
  • • imageQuality (1-100, default: 90)
  • • imageFormat (png/jpg, default: png)
  • • backgroundColor (hex color, default: #ffffff)
  • • textColor (hex color, default: #000000)
Webhooks

Receive real-time notifications about generation completions, downloads, billing events, and more.

Setting Up Webhooks

POST /api/v2/webhooks
Content-Type: application/json
x-api-key: YOUR_API_KEY

{
  "url": "https://your-app.com/webhook",
  "events": [
    "generation.completed",
    "svg.downloaded",
    "image.downloaded", 
    "user.credits_low"
  ],
  "secret": "your_webhook_secret_key"
}

Available Webhook Events

generation.completed

Fired when a calligraphy generation is completed successfully

Payload: { generationId, userId, imageUrls, metadata }
generation.failed

Fired when a calligraphy generation fails

Payload: { generationId, userId, error, metadata }
svg.downloaded

Fired when an SVG is generated and downloaded

Payload: { userId, resultText, fontName, svgBase64 }
image.downloaded

Fired when an image is generated and downloaded

Payload: { userId, resultText, fontName, format, dimensions }
user.credits_low

Fired when user credits fall below threshold

Payload: { userId, creditsRemaining, threshold }
user.quota_exceeded

Fired when user exceeds their rate limit

Payload: { userId, plan, requestCount, limit }
payment.completed

Fired when a payment is successfully processed

Payload: { userId, orderId, amount, plan }

Webhook Signature Verification

// Webhook signature verification (Node.js)
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Express.js webhook handler
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-calligraphy-signature'];
  const payload = req.body;
  
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(payload);
  console.log('Received event:', event.type);
  
  res.status(200).send('OK');
});

Webhook Best Practices

  • • Always verify webhook signatures
  • • Implement idempotency for duplicate events
  • • Return HTTP 200 status for successful processing
  • • Use HTTPS endpoints for security
  • • Handle timeouts and retries gracefully
Subscriptions & Billing

Manage user subscriptions, track usage, and handle billing events programmatically.

Get Subscription Plans

GET /api/v2/subscriptions/plans
x-api-key: YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "plans": [
      {
        "id": "plan_free",
        "name": "Free Plan",
        "price": 0,
        "currency": "INR",
        "interval": "monthly",
        "credits": 100,
        "features": ["Basic generation", "Standard fonts"],
        "rateLimit": 100
      },
      {
        "id": "plan_pro", 
        "name": "Professional Plan",
        "price": {
          "usd": 29,
          "inr": 2465
        },
        "interval": "monthly", 
        "credits": 8500,
        "rateLimit": 500
      }
    ]
  }
}

Check User Credits

GET /api/v2/users/credits
x-api-key: YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "creditsRemaining": 7750,
    "creditsUsed": 750,
    "totalCredits": 8500,
    "resetDate": "2024-02-01T00:00:00Z",
    "plan": "Professional Plan"
  }
}
Error Handling

The API uses conventional HTTP response codes and provides detailed error information to help with debugging.

HTTP Status Codes

400

Bad Request

Invalid request parameters or missing required fields

Example: Missing "text" parameter

401

Unauthorized

Missing or invalid API key

Example: Invalid API key provided

403

Forbidden

API key lacks required permissions

Example: API key does not have SVG generation permission

429

Rate Limited

Too many requests, rate limit exceeded

Example: Rate limit of 100 requests/hour exceeded

500

Server Error

Internal server error, please retry

Example: Font rendering service temporarily unavailable

Error Response Format

{
  "success": false,
  "error": {
    "code": "INVALID_LANGUAGE",
    "message": "Unsupported language specified",
    "details": {
      "provided": "spanish",
      "supported": ["hindi", "marathi", "gujarati", "english"]
    },
    "requestId": "req_clp7x8y9z123456789",
    "timestamp": "2024-01-21T10:30:00Z"
  }
}

Error Handling Implementation

// Comprehensive error handling example
async function generateCalligraphy(requestData) {
  try {
    const response = await fetch('/api/v2/generate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': process.env.CALLIGRAPHY_API_KEY
      },
      body: JSON.stringify(requestData)
    });

    const data = await response.json();

    if (!data.success) {
      const error = data.error;
      
      switch (error.code) {
        case 'INVALID_API_KEY':
          throw new Error('API key is invalid or missing');
        case 'INSUFFICIENT_CREDITS':
          throw new Error('Not enough credits remaining');
        case 'INVALID_LANGUAGE':
          throw new Error(`Unsupported language: ${error.details.provided}`);
        case 'TEXT_TOO_LONG':
          throw new Error('Text exceeds maximum length limit');
        default:
          throw new Error(`API Error: ${error.message} (ID: ${error.requestId})`);
      }
    }

    return data.data;
  } catch (error) {
    console.error('Calligraphy generation failed:', error.message);
    throw error;
  }
}

Error Handling Best Practices

  • • Always check the "success" field in responses
  • • Log error requestId for support inquiries
  • • Implement specific handling for common error codes
  • • Validate input parameters before sending requests
  • • Use try-catch blocks for network errors
  • • Provide meaningful error messages to users
Rate Limits

Plan-Based Limits

Free Plan

100
requests/hour
100 generations/month

Paid Plans

500
requests/hour
8,500 - 44,500 generations/month

Enterprise

Custom
requests/hour
Custom limits available

Rate Limit Headers

Every API response includes rate limit information in the headers:

X-RateLimit-Limit: 500
X-RateLimit-Remaining: 495  
X-RateLimit-Reset: 1640995200
X-RateLimit-Window: 3600

Handling Rate Limit Exceeded (429)

// Example: Exponential backoff retry strategy
async function callApiWithRetry(requestData, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch('/api/v2/generate', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': 'YOUR_API_KEY'
        },
        body: JSON.stringify(requestData)
      });

      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, attempt);
        const delay = parseInt(retryAfter) * 1000; // Convert to milliseconds
        
        if (attempt < maxRetries) {
          console.log(`Rate limited. Retrying after ${delay}ms...`);
          await new Promise(resolve => setTimeout(resolve, delay));
          continue;
        } else {
          throw new Error('Max retries exceeded');
        }
      }

      return await response.json();
    } catch (error) {
      if (attempt === maxRetries) throw error;
    }
  }
}

Rate Limiting Best Practices

  • • Use batch endpoints to reduce API calls
  • • Cache generated images when possible
  • • Monitor rate limit headers in responses
  • • Implement exponential backoff for retries
  • • Use queue systems for high-volume usage
  • • Consider upgrading plans for higher limits
Code Examples

Ready-to-use code examples for popular frameworks and platforms. Each example demonstrates best practices for integrating the Calligraphy API in your specific development environment.

cURL

Shell
bash
curl -X POST "https://api.calligraphymaker.com/api/v2/generate" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "text": "नमस्ते दोस्त",
    "language": "hindi",
    "fontStyle": "calligraphy",
    "count": 3,
    "imageFormat": "png"
  }'

JavaScript

Node.js
javascript
// Using fetch API
const response = await fetch('https://api.calligraphymaker.com/api/v2/generate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    text: "नमस्ते दोस्त",
    language: "hindi", 
    fontStyle: "calligraphy",
    count: 3,
    imageFormat: "png"
  })
});

const data = await response.json();
if (data.success) {
  console.log('Generated images:', data.data.images);
} else {
  console.error('Generation failed:', data.error);
}

Python

Python
python
import requests

url = "https://api.calligraphymaker.com/api/v2/generate"
headers = {
    "Content-Type": "application/json",
    "x-api-key": "YOUR_API_KEY"
}

payload = {
    "text": "नमस्ते दोस्त",
    "language": "hindi",
    "fontStyle": "calligraphy",
    "count": 3,
    "imageFormat": "png"
}

response = requests.post(url, json=payload, headers=headers)
data = response.json()

if data.get('success'):
    for image in data['data']['images']:
        print(f"Image URL: {image['url']}")
        print(f"Font Used: {image['fontUsed']}")
else:
    print('Generation failed:', data.get('error'))

PHP

PHP
php
<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.calligraphymaker.com/api/v2/generate",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "x-api-key: YOUR_API_KEY"
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "text" => "नमस्ते दोस्त",
        "language" => "hindi",
        "fontStyle" => "calligraphy",
        "count" => 3,
        "imageFormat" => "png"
    ])
]);

$response = curl_exec($curl);
curl_close($curl);

$data = json_decode($response, true);
if ($data['success']) {
    foreach ($data['data']['images'] as $image) {
        echo "Image URL: " . $image['url'] . "\n";
        echo "Font Used: " . $image['fontUsed'] . "\n";
    }
} else {
    echo "Generation failed: " . $data['error']['message'] . "\n";
}
?>

React Native

Mobile
javascript
// React Native Example
import React from 'react';
import { View, Image, Text, Button } from 'react-native';

const generateCalligraphy = async () => {
  try {
    const response = await fetch('https://api.calligraphymaker.com/api/v2/generate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'YOUR_API_KEY'
      },
      body: JSON.stringify({
        text: "नमस्ते दोस्त",
        language: "hindi",
        fontStyle: "calligraphy",
        count: 1,
        imageFormat: "png"
      })
    });

    const data = await response.json();
    if (data.success) {
      const imageUrl = data.data.images[0].url;
      // Use imageUrl in Image component
      return imageUrl;
    }
  } catch (error) {
    console.error('Error generating calligraphy:', error);
  }
};

// In your component
const CalligraphyDisplay = () => {
  const [imageUrl, setImageUrl] = React.useState(null);

  const handleGenerate = async () => {
    const url = await generateCalligraphy();
    setImageUrl(url);
  };

  return (
    <View>
      <Button title="Generate Calligraphy" onPress={handleGenerate} />
      {imageUrl && <Image source={{ uri: imageUrl }} style={{ width: 300, height: 150 }} />}
    </View>
  );
};

Flutter

Dart
dart
// Flutter Example
import 'package:http/http.dart' as http;
import 'dart:convert';

class CalligraphyService {
  static const String apiUrl = 'https://api.calligraphymaker.com/api/v2/generate';
  static const String apiKey = 'YOUR_API_KEY';

  static Future<String?> generateCalligraphy(String text) async {
    try {
      final response = await http.post(
        Uri.parse(apiUrl),
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': apiKey,
        },
        body: jsonEncode({
          'text': text,
          'language': 'hindi',
          'fontStyle': 'calligraphy',
          'count': 1,
          'imageFormat': 'png',
        }),
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        if (data['success']) {
          return data['data']['images'][0]['url'];
        }
      }
    } catch (e) {
      print('Error generating calligraphy: $e');
    }
    return null;
  }
}

// Usage in a Flutter widget
class CalligraphyWidget extends StatefulWidget {
  @override
  _CalligraphyWidgetState createState() => _CalligraphyWidgetState();
}

class _CalligraphyWidgetState extends State<CalligraphyWidget> {
  String? _imageUrl;

  void _generateCalligraphy() async {
    final url = await CalligraphyService.generateCalligraphy('नमस्ते दोस्त');
    setState(() {
      _imageUrl = url;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: _generateCalligraphy,
          child: Text('Generate Calligraphy'),
        ),
        if (_imageUrl != null)
          Image.network(_imageUrl!),
      ],
    );
  }
}

Android

Kotlin
kotlin
// Android (Kotlin) Example with Retrofit
import retrofit2.Call
import retrofit2.http.*

// Data classes
data class CalligraphyRequest(
    val text: String,
    val language: String,
    val fontStyle: String,
    val count: Int,
    val imageFormat: String
)

data class CalligraphyResponse(
    val success: Boolean,
    val data: ResponseData
)

data class ResponseData(
    val images: List<GeneratedImage>
)

data class GeneratedImage(
    val url: String,
    val fontUsed: String,
    val width: Int,
    val height: Int
)

// Retrofit interface
interface CalligraphyApiService {
    @POST("api/v2/generate")
    @Headers("Content-Type: application/json")
    fun generateCalligraphy(
        @Header("x-api-key") apiKey: String,
        @Body request: CalligraphyRequest
    ): Call<CalligraphyResponse>
}

// Usage in Activity/Fragment
class CalligraphyActivity : AppCompatActivity() {
    private val apiKey = "YOUR_API_KEY"
    
    private fun generateCalligraphy() {
        val retrofit = Retrofit.Builder()
            .baseUrl("https://api.calligraphymaker.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        
        val service = retrofit.create(CalligraphyApiService::class.java)
        
        val request = CalligraphyRequest(
            text = "नमस्ते दोस्त",
            language = "hindi",
            fontStyle = "calligraphy",
            count = 1,
            imageFormat = "png"
        )
        
        service.generateCalligraphy(apiKey, request).enqueue(object : Callback<CalligraphyResponse> {
            override fun onResponse(call: Call<CalligraphyResponse>, response: Response<CalligraphyResponse>) {
                if (response.isSuccessful && response.body()?.success == true) {
                    val imageUrl = response.body()?.data?.images?.firstOrNull()?.url
                    // Load image using Glide or Picasso
                    imageUrl?.let { loadImage(it) }
                }
            }
            
            override fun onFailure(call: Call<CalligraphyResponse>, t: Throwable) {
                // Handle error
                Log.e("CalligraphyAPI", "Error: ${t.message}")
            }
        })
    }
}

iOS/Swift

Swift
swift
// iOS Swift Example with URLSession
import UIKit

struct CalligraphyRequest: Codable {
    let text: String
    let language: String
    let fontStyle: String
    let count: Int
    let imageFormat: String
}

struct CalligraphyResponse: Codable {
    let success: Bool
    let data: ResponseData
}

struct ResponseData: Codable {
    let images: [GeneratedImage]
}

struct GeneratedImage: Codable {
    let url: String
    let fontUsed: String
    let width: Int
    let height: Int
}

class CalligraphyService {
    static let apiKey = "YOUR_API_KEY"
    static let apiURL = "https://api.calligraphymaker.com/api/v2/generate"
    
    static func generateCalligraphy(text: String, completion: @escaping (String?) -> Void) {
        guard let url = URL(string: apiURL) else {
            completion(nil)
            return
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue(apiKey, forHTTPHeaderField: "x-api-key")
        
        let requestBody = CalligraphyRequest(
            text: text,
            language: "hindi",
            fontStyle: "calligraphy",
            count: 1,
            imageFormat: "png"
        )
        
        do {
            request.httpBody = try JSONEncoder().encode(requestBody)
        } catch {
            completion(nil)
            return
        }
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                DispatchQueue.main.async {
                    completion(nil)
                }
                return
            }
            
            do {
                let response = try JSONDecoder().decode(CalligraphyResponse.self, from: data)
                if response.success, let imageUrl = response.data.images.first?.url {
                    DispatchQueue.main.async {
                        completion(imageUrl)
                    }
                }
            } catch {
                DispatchQueue.main.async {
                    completion(nil)
                }
            }
        }.resume()
    }
}

// Usage in ViewController
class CalligraphyViewController: UIViewController {
    @IBOutlet weak var imageView: UIImageView!
    
    @IBAction func generateButtonTapped(_ sender: UIButton) {
        CalligraphyService.generateCalligraphy(text: "नमस्ते दोस्त") { imageUrl in
            guard let imageUrl = imageUrl,
                  let url = URL(string: imageUrl) else { return }
            
            // Load image using URLSession or SDWebImage
            self.loadImage(from: url)
        }
    }
}

Next.js

React
typescript
// Next.js Example with API Route and Client Component
// app/api/calligraphy/route.ts
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
  try {
    const body = await request.json();
    
    const response = await fetch('https://api.calligraphymaker.com/api/v2/generate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': process.env.CALLIGRAPHY_API_KEY!
      },
      body: JSON.stringify({
        text: body.text,
        language: body.language || 'hindi',
        fontStyle: body.fontStyle || 'calligraphy',
        count: body.count || 1,
        imageFormat: body.imageFormat || 'png'
      })
    });

    const data = await response.json();
    return NextResponse.json(data);
  } catch (error) {
    return NextResponse.json(
      { success: false, error: 'Failed to generate calligraphy' },
      { status: 500 }
    );
  }
}

// app/components/CalligraphyGenerator.tsx
'use client';

import { useState } from 'react';
import Image from 'next/image';

export default function CalligraphyGenerator() {
  const [text, setText] = useState('नमस्ते दोस्त');
  const [imageUrl, setImageUrl] = useState('');
  const [loading, setLoading] = useState(false);

  const generateCalligraphy = async () => {
    setLoading(true);
    try {
      const response = await fetch('/api/calligraphy', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text })
      });

      const data = await response.json();
      if (data.success) {
        setImageUrl(data.data.images[0].url);
      }
    } catch (error) {
      console.error('Error:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="max-w-2xl mx-auto p-6">
      <h2 className="text-3xl font-bold mb-6">Calligraphy Generator</h2>
      
      <div className="space-y-4">
        <input
          type="text"
          value={text}
          onChange={(e) => setText(e.target.value)}
          className="w-full px-4 py-2 border rounded-lg"
          placeholder="Enter text for calligraphy"
        />
        
        <button
          onClick={generateCalligraphy}
          disabled={loading}
          className="w-full py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
        >
          {loading ? 'Generating...' : 'Generate Calligraphy'}
        </button>
        
        {imageUrl && (
          <div className="mt-6">
            <Image
              src={imageUrl}
              alt="Generated Calligraphy"
              width={600}
              height={300}
              className="rounded-lg shadow-lg"
            />
          </div>
        )}
      </div>
    </div>
  );
}

WordPress

PHP
php
// WordPress Plugin Example
<?php
/**
 * Plugin Name: Calligraphy Maker Integration
 * Description: Generate beautiful calligraphy using Calligraphy Maker API
 * Version: 1.0.0
 */

// Add settings page
add_action('admin_menu', 'calligraphy_maker_menu');
function calligraphy_maker_menu() {
    add_options_page(
        'Calligraphy Maker Settings',
        'Calligraphy Maker',
        'manage_options',
        'calligraphy-maker',
        'calligraphy_maker_settings_page'
    );
}

// Settings page HTML
function calligraphy_maker_settings_page() {
    ?>
    <div class="wrap">
        <h2>Calligraphy Maker Settings</h2>
        <form method="post" action="options.php">
            <?php settings_fields('calligraphy_maker_settings'); ?>
            <table class="form-table">
                <tr>
                    <th scope="row">API Key</th>
                    <td>
                        <input type="text" name="calligraphy_maker_api_key" 
                               value="<?php echo get_option('calligraphy_maker_api_key'); ?>" />
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}

// Register settings
add_action('admin_init', 'calligraphy_maker_settings_init');
function calligraphy_maker_settings_init() {
    register_setting('calligraphy_maker_settings', 'calligraphy_maker_api_key');
}

// Shortcode for generating calligraphy
add_shortcode('calligraphy', 'calligraphy_maker_shortcode');
function calligraphy_maker_shortcode($atts) {
    $atts = shortcode_atts([
        'text' => 'नमस्ते',
        'language' => 'hindi',
        'fontStyle' => 'calligraphy'
    ], $atts);
    
    $api_key = get_option('calligraphy_maker_api_key');
    if (!$api_key) {
        return '<p>Please configure your Calligraphy Maker API key.</p>';
    }
    
    // Generate unique ID for this instance
    $unique_id = 'calligraphy_' . uniqid();
    
    ob_start();
    ?>
    <div id="<?php echo $unique_id; ?>" class="calligraphy-container">
        <button class="calligraphy-generate" data-text="<?php echo esc_attr($atts['text']); ?>" 
                data-language="<?php echo esc_attr($atts['language']); ?>"
                data-fontStyle="<?php echo esc_attr($atts['fontStyle']); ?>">
            Generate Calligraphy
        </button>
        <div class="calligraphy-result"></div>
    </div>
    
    <script>
    jQuery(document).ready(function($) {
        $('#<?php echo $unique_id; ?> .calligraphy-generate').click(function() {
            var button = $(this);
            var container = button.closest('.calligraphy-container');
            var resultDiv = container.find('.calligraphy-result');
            
            button.prop('disabled', true).text('Generating...');
            
            $.ajax({
                url: '<?php echo admin_url('admin-ajax.php'); ?>',
                type: 'POST',
                data: {
                    action: 'generate_calligraphy',
                    text: button.data('text'),
                    language: button.data('language'),
                    fontStyle: button.data('fontStyle'),
                    nonce: '<?php echo wp_create_nonce('calligraphy_nonce'); ?>'
                },
                success: function(response) {
                    if (response.success && response.data.imageUrl) {
                        resultDiv.html('<img src="' + response.data.imageUrl + '" alt="Calligraphy" />');
                    } else {
                        resultDiv.html('<p>Error generating calligraphy</p>');
                    }
                },
                complete: function() {
                    button.prop('disabled', false).text('Generate Calligraphy');
                }
            });
        });
    });
    </script>
    <?php
    return ob_get_clean();
}

// AJAX handler
add_action('wp_ajax_generate_calligraphy', 'handle_calligraphy_generation');
add_action('wp_ajax_nopriv_generate_calligraphy', 'handle_calligraphy_generation');
function handle_calligraphy_generation() {
    check_ajax_referer('calligraphy_nonce', 'nonce');
    
    $api_key = get_option('calligraphy_maker_api_key');
    $text = sanitize_text_field($_POST['text']);
    $language = sanitize_text_field($_POST['language']);
    $fontStyle = sanitize_text_field($_POST['fontStyle']);
    
    $response = wp_remote_post('https://api.calligraphymaker.com/api/v2/generate', [
        'headers' => [
            'Content-Type' => 'application/json',
            'x-api-key' => $api_key
        ],
        'body' => json_encode([
            'text' => $text,
            'language' => $language,
            'fontStyle' => $fontStyle,
            'count' => 1,
            'imageFormat' => 'png'
        ])
    ]);
    
    if (!is_wp_error($response)) {
        $body = json_decode(wp_remote_retrieve_body($response), true);
        if ($body['success']) {
            wp_send_json_success(['imageUrl' => $body['data']['images'][0]['url']]);
        }
    }
    
    wp_send_json_error('Failed to generate calligraphy');
}

Vue.js

Vue
javascript
// Vue.js 3 Composition API Example
<template>
  <div class="calligraphy-generator">
    <h2>Calligraphy Generator</h2>
    
    <div class="form-group">
      <label>Text:</label>
      <input v-model="text" type="text" placeholder="Enter text" />
    </div>
    
    <div class="form-group">
      <label>Language:</label>
      <select v-model="language">
        <option value="hindi">Hindi</option>
        <option value="marathi">Marathi</option>
        <option value="gujarati">Gujarati</option>
        <option value="english">English</option>
      </select>
    </div>
    
    <button @click="generateCalligraphy" :disabled="loading">
      {{ loading ? 'Generating...' : 'Generate Calligraphy' }}
    </button>
    
    <div v-if="error" class="error">{{ error }}</div>
    
    <div v-if="images.length > 0" class="results">
      <h3>Generated Images:</h3>
      <div v-for="(image, index) in images" :key="index" class="image-container">
        <img :src="image.url" :alt="'Calligraphy ' + (index + 1)" />
        <p>Font: {{ image.fontUsed }}</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import axios from 'axios'

const API_KEY = 'YOUR_API_KEY'
const API_URL = 'https://api.calligraphymaker.com/api/v2/generate'

const text = ref('नमस्ते दोस्त')
const language = ref('hindi')
const loading = ref(false)
const error = ref('')
const images = ref([])

const generateCalligraphy = async () => {
  loading.value = true
  error.value = ''
  images.value = []
  
  try {
    const response = await axios.post(API_URL, {
      text: text.value,
      language: language.value,
      fontStyle: 'calligraphy',
      count: 3,
      imageFormat: 'png'
    }, {
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY
      }
    })
    
    if (response.data.success) {
      images.value = response.data.data.images
    } else {
      error.value = response.data.error.message || 'Failed to generate calligraphy'
    }
  } catch (err) {
    error.value = err.message || 'An error occurred'
  } finally {
    loading.value = false
  }
}
</script>

<style scoped>
.calligraphy-generator {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

.form-group {
  margin-bottom: 15px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

.form-group input,
.form-group select {
  width: 100%;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

button {
  background-color: #007bff;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
}

button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.error {
  color: #dc3545;
  margin-top: 10px;
}

.results {
  margin-top: 20px;
}

.image-container {
  margin-bottom: 20px;
  text-align: center;
}

.image-container img {
  max-width: 100%;
  height: auto;
  border: 1px solid #ddd;
  border-radius: 4px;
}
</style>

Node.js

Express
javascript
// Node.js Example with Express
const express = require('express');
const axios = require('axios');

const app = express();
app.use(express.json());

const CALLIGRAPHY_API_KEY = process.env.CALLIGRAPHY_API_KEY;
const CALLIGRAPHY_API_URL = 'https://api.calligraphymaker.com/api/v2/generate';

// Route to generate calligraphy
app.post('/generate-calligraphy', async (req, res) => {
  try {
    const { text, language = 'hindi', fontStyle = 'calligraphy' } = req.body;
    
    if (!text) {
      return res.status(400).json({ error: 'Text is required' });
    }
    
    const response = await axios.post(CALLIGRAPHY_API_URL, {
      text,
      language,
      fontStyle,
      count: 3,
      imageFormat: 'png'
    }, {
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': CALLIGRAPHY_API_KEY
      }
    });
    
    if (response.data.success) {
      res.json({
        success: true,
        images: response.data.data.images
      });
    } else {
      res.status(400).json({
        success: false,
        error: response.data.error
      });
    }
  } catch (error) {
    console.error('Calligraphy generation error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to generate calligraphy'
    });
  }
});

// Webhook endpoint to receive notifications
app.post('/webhook/calligraphy', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-calligraphy-signature'];
  const payload = req.body;
  
  // Verify webhook signature
  const crypto = require('crypto');
  const expectedSignature = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');
  
  if (signature !== expectedSignature) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(payload);
  
  // Handle different event types
  switch (event.type) {
    case 'generation.completed':
      console.log('Generation completed:', event.data);
      // Process completed generation
      break;
    case 'generation.failed':
      console.error('Generation failed:', event.data);
      // Handle failed generation
      break;
    case 'batch.completed':
      console.log('Batch completed:', event.data);
      // Process completed batch
      break;
    default:
      console.log('Unknown event type:', event.type);
  }
  
  res.status(200).send('OK');
});

// Health check endpoint
app.get('/health', (req, res) => {
  res.json({ status: 'ok', service: 'calligraphy-integration' });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

SVG Download

JavaScript
javascript
// SVG Download Example
const downloadSVG = async (resultText, fontName) => {
  try {
    const response = await fetch('https://api.calligraphymaker.com/api/v2/download-svg', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'YOUR_API_KEY'
      },
      body: JSON.stringify({
        resultText: resultText,
        fontName: fontName
      })
    });

    const data = await response.json();
    if (data.success) {
      // Download SVG as file
      const svgBlob = new Blob([data.data.svgString], { type: 'image/svg+xml' });
      const url = URL.createObjectURL(svgBlob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'calligraphy.svg';
      a.click();
      
      return data.data.svgBase64; // Return base64 for display
    }
  } catch (error) {
    console.error('SVG download failed:', error);
  }
};

Image Download

JavaScript
javascript
// Image Download Example
const downloadImage = async (resultText, fontName, format = 'png') => {
  try {
    const response = await fetch('https://api.calligraphymaker.com/api/v2/download-image', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'YOUR_API_KEY'
      },
      body: JSON.stringify({
        resultText: resultText,
        fontName: fontName,
        imageWidth: 800,
        imageHeight: 600,
        imageQuality: 90,
        imageFormat: format,
        backgroundColor: '#ffffff',
        textColor: '#000000'
      })
    });

    const data = await response.json();
    if (data.success) {
      // Download image as file
      const a = document.createElement('a');
      a.href = data.data.imageBase64;
      a.download = `calligraphy.${format}`;
      a.click();
      
      return data.data.imageBase64; // Return base64 for display
    }
  } catch (error) {
    console.error('Image download failed:', error);
  }
};

Webhook Signature

Node.js
javascript
// Webhook signature verification (Node.js)
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Express.js webhook handler
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-calligraphy-signature'];
  const payload = req.body;
  
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(payload);
  console.log('Received event:', event.type);
  
  res.status(200).send('OK');
});
Supported Languages
हिंदी
Hindi
hindi

Devanagari script

मराठी
Marathi
marathi

Devanagari script

ગુજરાતી
Gujarati
gujarati

Gujarati script

English
English
english

Latin script

Ready to ship faster?

Join 1,000+ developers already building production-ready applications with our calligraphy API. Start your integration in minutes, not hours.