Studio99
Studio99 API documentation

API Documentation

Exact Indic typography for your product — calligraphy generation, precise text rendering, library search, and font metadata in Hindi, Marathi, Gujarati & English, delivered as production-ready SVG and PNG.

Base URL: https://studio99.app/api/v1

All endpoints require authentication via API key, except /health.

Authentication

Include your API key in every request using the X-API-Key header:

curl https://studio99.app/api/v1/fonts \
  -H "X-API-Key: your_api_key"

Get your API key from your Dashboard. Keep it secret — don't expose it in client-side code.

Text & Unicode

The API works best when you send exact Unicode (e.g. शुभ विवाह) — you get precise, predictable output. Romanized input (e.g. shubh vivah) also works: the API auto-detects and transliterates it, but you give up control over spelling choices.

If your users type in English letters, convert to Unicode in your app first, then send the Unicode to /generate. Google Input Tools does this for free (no key) — drop this helper into your product:

JavaScript

// Romanized -> Indic Unicode via Google Input Tools (free, no key).
// lang: 'hi' (Hindi) | 'mr' (Marathi) | 'gu' (Gujarati)
async function toUnicode(text, lang = 'hi') {
  const url = `https://inputtools.google.com/request?text=${encodeURIComponent(text)}`
    + `&ime=transliteration_en_${lang}&num=1&ie=utf-8&oe=utf-8&app=jsapi`;
  const res = await fetch(url);
  const data = await res.json();
  if (data[0] !== 'SUCCESS') return text;                 // fall back to input
  return data[1].map((tok) => tok[1]?.[0] ?? '').join(''); // best of each token
}

// In your app: user types "shubh vivah" -> convert -> call Studio99.
const text = await toUnicode('shubh vivah', 'hi');        // "शुभ विवाह"
await fetch('https://studio99.app/api/v1/generate', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({ text, language: 'hindi', count: 4 }),
});

Python

import requests

# lang: 'hi' (Hindi) | 'mr' (Marathi) | 'gu' (Gujarati)
def to_unicode(text, lang='hi'):
    r = requests.get('https://inputtools.google.com/request', params={
        'text': text, 'ime': f'transliteration_en_{lang}',
        'num': 1, 'ie': 'utf-8', 'oe': 'utf-8', 'app': 'jsapi',
    })
    data = r.json()
    if data[0] != 'SUCCESS':
        return text
    return ''.join((tok[1][0] if tok[1] else '') for tok in data[1])

text = to_unicode('shubh vivah', 'hi')   # 'शुभ विवाह'
requests.post('https://studio99.app/api/v1/generate',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    json={'text': text, 'language': 'hindi', 'count': 4})

cURL (inspect the raw response)

curl "https://inputtools.google.com/request?text=shubh%20vivah&ime=transliteration_en_hi&num=5&ie=utf-8&oe=utf-8&app=jsapi"
# -> ["SUCCESS",[["shubh vivah",["शुभ विवाह","शुभ विवा", ...]]]]
# Pick a suggestion, then send it as "text" to /api/v1/generate.

Tip: show your users the suggestions and let them pick, then send the chosen Unicode. Commas and line breaks are treated as separators. You can also try this live (with your key) in the Playground on your dashboard.

POST/api/v1/generate

Generate calligraphy text. Searches the library first, then generates new results.

Request Body

FieldTypeRequiredDescription
textstringYesThe text to generate calligraphy for. Unicode text in the target language is preferred (Devanagari for Hindi/Marathi, Gujarati script, or Latin for English); romanized Latin is auto-transliterated as a fallback.
languagestringNo"hindi", "marathi", "gujarati", "english" (or hi/mr/gu/en). Auto-detected if omitted.
stylestringNo"calligraphy", "decorative", "publication"
weightstringNoBias font selection toward a weight class: "light", "regular", "bold" or "extra_bold" (case-insensitive). Omit to let the engine choose.
fontIdstringNoSpecific font ID. Auto-selects if omitted.
countnumberNoNumber of results to return, 1–6 (default: 4). 6 is the max on every plan; higher values are clamped to 6. Each returned result costs 1 credit.
formatstringNo"svg" (default) or "png". PNG is returned per result as base64, alongside the SVG.
pngWidthnumberNoTarget PNG width in px (default 1200, capped by your plan)
use_casestringNoSemantic font selection: "wedding", "invitations", "logos", "names", "posters", "greetings", "quotes", "certificates", "birthday", "religious", "festive", "formal", "casual"
moodstringNoSemantic font selection: "elegant", "festive", "playful", "romantic", "serious", "spiritual"
recipestring | arrayNoWhich typographic treatment(s) to return. Omit for the full curated slate. "plain" = clean text as-is (most legible); "flagship" = full calligraphy engine; "duo" = two-font light/bold (multiline). Pick ONE recipe + count to get that many variations of it.
linesstring | numberNoLine breaking. "auto" (default) respects your \n line breaks, else auto-splits a phrase into 2–4 balanced lines. 1 = force a single line. 2–6 = force exactly that many lines.
alignstringNoAlignment of stacked lines: "center" (default) — smart ink-nested centering; "left" / "right" — edge-aligned, still vertically nested. Ignored for single-line results.
lineGapnumberNoExtra vertical spacing between stacked lines (multiline only). Leave unset for the calibrated default.
seednumberNoReproducible output — the same seed with the same inputs returns the same result. Omit for fresh randomized variations each call.
curl -X POST https://studio99.app/api/v1/generate \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "शुभ विवाह",
    "language": "hindi",
    "count": 4,
    "format": "svg"
  }'

Multi-line & recipes

Send a phrase and it auto-splits into optically-stacked lines, or use\nfor exact breaks. Pick a single recipe with acountto get that many variations of one treatment.

// Multi-line greeting, optically stacked
{ "text": "रक्षाबंधन की\nहार्दिक शुभकामनाएं", "language": "hindi" }

// 4 plain variations (different fonts), one per result
{ "text": "नमस्ते", "language": "hindi", "recipe": "plain", "count": 4 }

// Force 3 left-aligned lines
{ "text": "जय श्री राम", "language": "hindi", "lines": 3, "align": "left" }

Good to know

Output format & speed. svg is the fastest to deliver — it's returned directly. png is rasterized on our servers, so it adds a little time. On the free tier, output is a watermarked preview image; paid plans return clean, full-resolution SVG (and PNG) — so a paid plan is both higher quality and typically faster than a watermarked preview. The first request after a period of inactivity may be slower (a cold start), then subsequent requests are quick.

Advanced options degrade gracefully. recipe, style, weight, use_case and mood are treated as preferences. If a combination would return too few results, the API automatically broadens the pool so you always get a full response rather than an empty or short one. For the most predictable output, send fewer constraints (or just text + language).

Response

{
  "success": true,
  "data": {
    "libraryResults": [
      {
        "id": "art_abc123",
        "displayName": "शुभ विवाह",
        "thumbnailUrl": "https://...",
        "source": "library",
        "category": { "name": "Wedding", "slug": "wedding" }
      }
    ],
    "generatedResults": [
      {
        "id": "gen_xyz789",
        "fontId": "font-uuid",
        "fontFamily": "Calligraphy Pro",
        "resultText": "...",
        "source": "generated",
        "svg": {
          "path": "M10 20 C30 40...",
          "width": 800,
          "height": 200,
          "svgString": "<svg>...</svg>"
        },
        "png": { "base64": "iVBORw0KG...", "width": 1200, "height": 300 }
      }
    ],
    "metadata": {
      "fontSelection": { "wasAutoSelected": true, "detectedLanguage": "hindi" },
      "processingTimeMs": 245
    }
  },
  "usage": { "monthlyUsed": 42, "monthlyLimit": 5000, "remaining": 4958 }
}
POST/api/v1/render

Re-render an exact text string in a given font — no transliteration or styling intelligence. Use generate to discover styled results, then render the chosen result at any size or format (e.g. a high-resolution download).

Request Body

FieldTypeRequiredDescription
textstringYesExact text to render — typically a resultText returned by generate
fontIdstringYesFont ID (from generate results or the fonts endpoint)
fontSizenumberNoSVG coordinate scale, 8–300 (default: 72)
formatstringNo"svg" (default) or "png"
pngWidthnumberNoTarget PNG width in px (default 1200, capped by your plan)
curl -X POST https://studio99.app/api/v1/render \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "<resultText from generate>",
    "fontId": "font-uuid",
    "format": "png",
    "pngWidth": 2048
  }'

Response

// format: "svg" (default)
{
  "success": true,
  "data": { "svgString": "<svg>...</svg>", "width": 800, "height": 200, "format": "svg" }
}

// format: "png"
{
  "success": true,
  "data": {
    "png": { "base64": "iVBORw0KG...", "width": 2048, "height": 512 },
    "width": 800,
    "height": 200,
    "format": "png"
  }
}
GET/api/v1/library/{id}

Get full details of a single artwork by ID, shortId, or slug.

curl "https://studio99.app/api/v1/library/art_abc123" \
  -H "X-API-Key: your_api_key"
GET/api/v1/library/{id}/download

Get a short-lived signed download URL for an artwork file (PNG, JPG, or SVG).

curl "https://studio99.app/api/v1/library/art_abc123/download?format=PNG" \
  -H "X-API-Key: your_api_key"

// Response
{
  "success": true,
  "data": {
    "downloadUrl": "https://...",   // valid for 5 minutes
    "availableFormats": ["PNG", "JPG", "SVG"],
    "canRenderSvg": true
  }
}

For artworks where canRenderSvg is true, GET /api/v1/library/{id}/render-svg returns a freshly rendered SVG of the artwork's text:

curl "https://studio99.app/api/v1/library/art_abc123/render-svg" \
  -H "X-API-Key: your_api_key"

// Response
{
  "success": true,
  "data": { "svgString": "<svg>...</svg>", "width": 800, "height": 200, "fontFamily": "..." }
}
GET/api/v1/fonts

List all available fonts with metadata. Font files are never exposed.

curl "https://studio99.app/api/v1/fonts" \
  -H "X-API-Key: your_api_key"

Response

{
  "success": true,
  "data": {
    "fonts": [
      {
        "id": "font-uuid",
        "name": "Calligraphy Pro",
        "slug": "calligraphy-pro",
        "family": "CalligraphyPro",
        "languages": ["Hindi", "Marathi"],
        "style": "CALLIGRAPHY",
        "weight": "REGULAR",
        "categories": ["wedding", "festival"]
      }
    ]
  }
}
GET/api/v1/capabilities

Capability discovery for AI agents and developers — languages, formats, semantic vocabularies (moods, use cases), and endpoint map. No authentication required.

curl "https://studio99.app/api/v1/capabilities"

// Response (excerpt)
{
  "success": true,
  "data": {
    "category": "Indic Typography API",
    "languages": ["hindi", "marathi", "gujarati", "english"],
    "formats": ["svg", "png"],
    "supportsExactText": true,
    "semantics": {
      "moods": ["elegant", "festive", "playful", "romantic", "serious", "spiritual"],
      "useCases": ["certificates", "greetings", "invitations", "logos", "names", ...]
    },
    "mcp": "https://mcp.studio99.app/api/mcp"
  }
}

The fonts endpoint accepts the same semantic vocabulary as filters: ?language=hindi&mood=elegant&use_case=wedding&limit=8

GET/api/v1/health

Service health check. The only endpoint that requires no authentication.

curl "https://studio99.app/api/v1/health"

// Response
{ "success": true, "data": { "status": "ok", "version": "1.0" } }

Error Codes

All errors return a standard format:

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Monthly API call limit of 100 exceeded."
  }
}
CodeHTTPDescription
AUTHENTICATION_REQUIRED401Missing or invalid API key
RATE_LIMIT_EXCEEDED429Monthly quota or burst limit exceeded
INSUFFICIENT_CREDITS429Not enough credits for this request — lower count, top up, or upgrade
INVALID_INPUT400Bad request body or parameters
TEXT_TOO_LONG400Exceeds tier's max text length
FONT_NOT_FOUND404Invalid fontId or artwork not found
GENERATION_FAILED500Internal generation error

Credits & Billing

The API bills in credits. Your plan includes a monthly credit allotment; you spend credits only on successful calls.

OperationCredit cost
generate1 credit per variant returned
render (SVG or PNG)1 credit per output
library download1 credit (coming soon)
search · fonts · health · capabilitiesFree
  • One format per call. Omit format for SVG, or send format=png. Both formats = two calls.
  • Free tier is preview-only. Output is a watermarked JPG (600×400, no commercial license). Upgrade for clean full-resolution SVG/PNG with a commercial license.
  • Wallet top-ups. Paid plans can buy extra credits at ₹1/credit; purchased credits are spent after your monthly allotment and last 12 months.
  • Inkora library. Coming soon for API plans.

Every response reports your live balance:

"usage": { "unit": "credits", "monthlyUsed": 42, "monthlyLimit": 5000, "remaining": 4958 }

Rate Limits

Rate limits are applied per API key at two levels:

  • Burst limit: Requests per minute (varies by plan: 5-120 req/min)
  • Monthly limit: Credits per billing month (varies by plan: 100 to custom)

Rate limit info is included in response headers:

X-RateLimit-Limit: 20          # Max requests per minute
X-RateLimit-Remaining: 18     # Remaining in current window
X-RateLimit-Reset: 1704067200  # Window reset time (Unix)

When rate-limited, the API returns HTTP 429 with a RATE_LIMIT_EXCEEDED error. Implement exponential backoff in your client.

Licensing & Usage

Artwork you generate on a paid plan is licensed to you for commercial use. In short: use what you generate freely in your own products — just don't resell the raw output as a competing library or service.

You can

  • Use generated artwork in your apps, designs, and deliverables to your end-users
  • Use it commercially, in perpetuity — including work created while your plan was active
  • Store and integrate the output within your product

You can't

  • Resell or redistribute the raw generated assets as standalone products
  • Build a competing calligraphy/text-art generation service or asset library from our output
  • Sublicense the output as-is to third parties

Free tier output is a watermarked preview for evaluation only — no commercial use. Full terms are in our Terms of Service.

Ready to build?

Get your free API key and start generating exact Indic typography in minutes.

Need help? Contact us or check the pricing page.