REST API Free Tier Multi-Font Detection

Font Identifier API

Identify fonts from images programmatically with a single API call. Built for developers who need accurate font recognition, style detection, and similar font suggestions at scale.

Why Use This API

AI Font Recognition

Advanced AI trained on thousands of font families. Accurately identifies typefaces from any image containing text.

Style & Weight Detection

Detects font style (Regular, Bold, Italic) and weight (100-900) for precise typography matching.

Similar Font Suggestions

Get alternative font recommendations for each identified typeface. Find free substitutes for premium fonts.

Multi-Font Detection

Detect and identify multiple different fonts within a single image. Perfect for analyzing complex designs.

Quick Start

Start identifying fonts in under a minute. Here's how:

  1. Get your API keySign up free to receive your key
  2. Send a request — POST an image containing text to the endpoint
  3. Get the result — Receive identified fonts as JSON with confidence scores
curl -X POST https://precisioncounter.com/api/v1/identify-font \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@sample.png"
import requests

response = requests.post(
    "https://precisioncounter.com/api/v1/identify-font",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    files={"image": open("sample.png", "rb")}
)

data = response.json()
for font in data["fonts"]:
    print(f"{font['name']} ({font['confidence']:.0%})")
const fs = require("fs");
const FormData = require("form-data");

const form = new FormData();
form.append("image", fs.createReadStream("sample.png"));

const response = await fetch(
  "https://precisioncounter.com/api/v1/identify-font",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      ...form.getHeaders()
    },
    body: form
  }
);

const data = await response.json();
data.fonts.forEach(f => console.log(`${f.name} (${f.confidence})`));

API Reference

Base URL

https://precisioncounter.com/api/v1

Authentication

All requests require an API key passed in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Identify Font

POST /api/v1/identify-font

Identifies fonts from an uploaded image containing text and returns matching font details as JSON.

Request Parameters

Parameter Type Description
image required file Image containing text with the font to identify. Accepted formats: PNG, JPG, JPEG, WebP. Max size: 10 MB.
max_results optional integer Max number of font matches to return. Default: 5. Range: 1-20.
include_similar optional boolean Include similar font alternatives for each match. Default: true.

Response

200 OK — Returns identified font data as JSON.

{
  "fonts": [
    {
      "name": "Helvetica Neue",
      "confidence": 0.94,
      "style": "Regular",
      "weight": 400,
      "category": "Sans-serif",
      "similar": ["Arial", "Roboto", "Inter", "SF Pro"]
    }
  ],
  "text_detected": "Sample Text",
  "processing_time_ms": 450
}

Response Headers

Header Value
Content-Type application/json
X-Credits-Remaining Number of API credits remaining
X-Processing-Time Processing time in milliseconds

Code Examples

Full Examples (with error handling)

curl -X POST https://precisioncounter.com/api/v1/identify-font \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@sample.png" \
  -F "max_results=5" \
  -F "include_similar=true"
import requests
import sys

API_KEY = "YOUR_API_KEY"
API_URL = "https://precisioncounter.com/api/v1/identify-font"

def identify_font(input_path, max_results=5):
    """Identify fonts from an image file."""
    with open(input_path, "rb") as img:
        response = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"image": img},
            data={"max_results": max_results, "include_similar": "true"}
        )

    if response.status_code == 200:
        data = response.json()
        for font in data["fonts"]:
            print(f"{font['name']} - {font['confidence']:.0%} confidence")
            print(f"  Style: {font['style']}, Weight: {font['weight']}")
            print(f"  Category: {font['category']}")
            if font.get("similar"):
                print(f"  Similar: {', '.join(font['similar'])}")
        print(f"\nText detected: {data['text_detected']}")
        print(f"Credits remaining: {response.headers.get('X-Credits-Remaining')}")
    else:
        print(f"Error {response.status_code}: {response.json()['error']}")

identify_font("sample.png")
const fs = require("fs");
const FormData = require("form-data");
const fetch = require("node-fetch");

const API_KEY = "YOUR_API_KEY";
const API_URL = "https://precisioncounter.com/api/v1/identify-font";

async function identifyFont(inputPath, maxResults = 5) {
  const form = new FormData();
  form.append("image", fs.createReadStream(inputPath));
  form.append("max_results", String(maxResults));
  form.append("include_similar", "true");

  const response = await fetch(API_URL, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      ...form.getHeaders()
    },
    body: form
  });

  if (response.ok) {
    const data = await response.json();
    data.fonts.forEach(font => {
      console.log(`${font.name} - ${(font.confidence * 100).toFixed(0)}%`);
      console.log(`  Style: ${font.style}, Weight: ${font.weight}`);
      console.log(`  Similar: ${font.similar.join(", ")}`);
    });
    console.log(`Credits: ${response.headers.get("x-credits-remaining")}`);
  } else {
    const error = await response.json();
    console.error(`Error ${response.status}: ${error.error}`);
  }
}

identifyFont("sample.png");
<?php
$api_key = "YOUR_API_KEY";
$url = "https://precisioncounter.com/api/v1/identify-font";

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $api_key"
    ],
    CURLOPT_POSTFIELDS => [
        "image" => new CURLFile("sample.png"),
        "max_results" => "5",
        "include_similar" => "true"
    ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 200) {
    $data = json_decode($response, true);
    foreach ($data["fonts"] as $font) {
        echo $font["name"] . " - " . ($font["confidence"] * 100) . "% confidence\n";
        echo "  Style: " . $font["style"] . ", Weight: " . $font["weight"] . "\n";
        echo "  Similar: " . implode(", ", $font["similar"]) . "\n";
    }
} else {
    echo "Error $httpCode: $response\n";
}
?>
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "os"
)

type FontResult struct {
    Name       string   `json:"name"`
    Confidence float64  `json:"confidence"`
    Style      string   `json:"style"`
    Weight     int      `json:"weight"`
    Category   string   `json:"category"`
    Similar    []string `json:"similar"`
}

type Response struct {
    Fonts          []FontResult `json:"fonts"`
    TextDetected   string       `json:"text_detected"`
    ProcessingTime int          `json:"processing_time_ms"`
}

func identifyFont(inputPath string) error {
    file, _ := os.Open(inputPath)
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    part, _ := writer.CreateFormFile("image", inputPath)
    io.Copy(part, file)
    writer.WriteField("max_results", "5")
    writer.Close()

    req, _ := http.NewRequest("POST",
        "https://precisioncounter.com/api/v1/identify-font", body)
    req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
    req.Header.Set("Content-Type", writer.FormDataContentType())

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    if resp.StatusCode == 200 {
        var result Response
        json.NewDecoder(resp.Body).Decode(&result)
        for _, font := range result.Fonts {
            fmt.Printf("%s - %.0f%% confidence\n", font.Name, font.Confidence*100)
        }
    }
    return nil
}

func main() {
    identifyFont("sample.png")
}
require "net/http"
require "uri"
require "json"

api_key = "YOUR_API_KEY"
uri = URI("https://precisioncounter.com/api/v1/identify-font")

form_data = [
  ["image", File.open("sample.png", "rb")],
  ["max_results", "5"],
  ["include_similar", "true"]
]

req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{api_key}"
req.set_form(form_data, "multipart/form-data")

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

if res.code == "200"
  data = JSON.parse(res.body)
  data["fonts"].each do |font|
    puts "#{font['name']} - #{(font['confidence'] * 100).round}% confidence"
    puts "  Style: #{font['style']}, Weight: #{font['weight']}"
    puts "  Similar: #{font['similar'].join(', ')}"
  end
else
  puts "Error #{res.code}: #{res.body}"
end
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_API_KEY");

using var form = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(File.ReadAllBytes("sample.png"));
imageContent.Headers.ContentType = new("image/png");
form.Add(imageContent, "image", "sample.png");
form.Add(new StringContent("5"), "max_results");
form.Add(new StringContent("true"), "include_similar");

var response = await client.PostAsync(
    "https://precisioncounter.com/api/v1/identify-font", form);

if (response.IsSuccessStatusCode)
{
    var json = await response.Content.ReadAsStringAsync();
    var data = JsonSerializer.Deserialize<JsonElement>(json);
    foreach (var font in data.GetProperty("fonts").EnumerateArray())
    {
        Console.WriteLine($"{font.GetProperty("name")} - {font.GetProperty("confidence")}");
    }
}

Error Handling

The API returns standard HTTP status codes with JSON error bodies:

Status Meaning Description
200 Success Fonts identified successfully. Response body contains JSON with font data.
400 Bad Request Missing image file, unsupported format, or file too large.
401 Unauthorized Missing or invalid API key.
429 Rate Limited Too many requests. Wait and retry with exponential backoff.
500 Server Error Internal processing error. Retry the request.

Error Response Format

{
  "error": "Invalid file format. Accepted: png, jpg, jpeg, webp",
  "code": "INVALID_FORMAT",
  "status": 400
}

Rate Limits

Plan Requests / Minute Max File Size Max Resolution
Free 10 10 MB 4096 x 4096 px
Pro 60 25 MB 8192 x 8192 px

Rate limit headers are included in every response:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1708646400

Use Cases

  • Design asset management
  • Brand consistency checking
  • Web scraping font detection
  • Accessibility compliance
  • Print production
  • Typography research
  • Design tool plugins
  • Font licensing verification

Pricing

Free to Start

Get free API credits when you sign up. No credit card required.

Frequently Asked Questions

What image formats does the Font Identifier API support?
The API accepts PNG, JPG, JPEG, and WebP images. Upload any image containing text and the API will analyze and identify the fonts used.
Is the Font Identifier API free?
Yes. You get free API calls to try the service when you sign up. No credit card is required to get started.
How accurate is the font identification?
The API uses advanced AI models trained on thousands of font families. Accuracy depends on image quality and text clarity, but typically achieves 90%+ confidence on clean text samples. Higher resolution images with clear, unobstructed text yield the best results.
Can the API detect multiple fonts in one image?
Yes. The API can detect and identify multiple different fonts within a single image. Use the max_results parameter to control how many font matches are returned, up to 20 per request.
Does the API return similar font alternatives?
Yes. By default, the API includes similar font alternatives for each identified font. This is useful for finding free or open-source substitutes. You can disable this with the include_similar parameter set to false.
What information does the API return for each font?
For each identified font, the API returns the font name, confidence score (0-1), style (Regular, Bold, Italic, etc.), weight (100-900), category (Sans-serif, Serif, Monospace, etc.), and optionally a list of similar font alternatives.
Does the API store my images?
No. Images are processed in memory and immediately discarded after the response is sent. We do not store, log, or share any uploaded images.