API REFERENCE · v1

CursiveToText API documentation

Send an image of handwriting, cursive or printed text and get the recognized text back as JSON. One endpoint, one API key, predictable per-image pricing.

Base URLhttps://www.cursivetotext.com/api/v1

Overview

The API is a small REST interface over the same recognition engine that powers the cursive to text converter. It accepts JPEG, PNG, GIF and WebP images up to 10 MB and returns UTF-8 text with line breaks preserved, a confidence score from 0–100 and your remaining allowance.

  • All requests use HTTPS. Plain HTTP is not supported.
  • Responses are JSON. Every response includes an X-Request-Id header you can quote to support.
  • Images are processed in memory and never stored. Recognized text is returned to you and not kept on our servers.

Authentication

Create a key on the API keys page (sign-in required) and send it in the Authorization header:

Authorization: Bearer ctt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are shown once when created and stored only as a one-way hash, so we can’t recover a lost key — create a new one and revoke the old. You can have up to five active keys. Keep keys on your server: never ship them in browser JavaScript or mobile apps.

Quick start

  1. Sign in and create a key on the API keys page.
  2. Save it as an environment variable, for example CURSIVETOTEXT_API_KEY.
  3. Send your first image:
POST /recognize
curl https://www.cursivetotext.com/api/v1/recognize \
  -H "Authorization: Bearer $CURSIVETOTEXT_API_KEY" \
  -F "image=@letter.jpg"

Recognize text

POST/api/v1/recognize

Recognizes the text in one image. Each successful call uses one call from your API quota. Calls that fail or find no text are not charged.

Request body

Send the image in either of two ways:

Content typeFieldDescription
multipart/form-dataimage (file)Recommended. The raw image file, up to 10 MB.
application/jsonimage (string)Base64-encoded image, with or without a data:image/…;base64, prefix. Base64 adds about 33%, so keep source images under ~7 MB.
Sending base64 JSON
curl https://www.cursivetotext.com/api/v1/recognize \
  -H "Authorization: Bearer $CURSIVETOTEXT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"image\": \"$(base64 < letter.jpg | tr -d '\n')\"}"

Response

FieldTypeDescription
idstringUnique ID for this recognition.
objectstringAlways "recognition".
textstringRecognized text. Lines are separated by \n.
confidenceintegerAverage word confidence, 0–100. Below ~70 usually means the image needs a closer look.
word_countintegerNumber of words detected.
processing_msintegerRecognition time in milliseconds.
usageobjectYour allowance after this call: plan, limit, used, remaining, resets_at.
{
  "id": "rec_4f1c9a2e7b3d40c8a6e1",
  "object": "recognition",
  "text": "Dear Anna,\nLife is a beautiful journey —\nkeep writing your story.",
  "confidence": 94,
  "word_count": 11,
  "processing_ms": 1180,
  "usage": {
    "plan": "API Growth",
    "limit": 5000,
    "used": 1242,
    "remaining": 3758,
    "resets_at": "2026-11-22T13:32:01.000Z"
  }
}

Check usage

GET/api/v1/usage

Returns your current allowance without using a conversion — handy for dashboards and for checking quota before a batch job.

curl https://www.cursivetotext.com/api/v1/usage -H "Authorization: Bearer $CURSIVETOTEXT_API_KEY"

{ "object": "usage", "plan": "API Growth", "limit": 5000, "used": 1242, "remaining": 3758, "resets_at": "2026-11-22T13:32:01.000Z" }

Errors

Errors use standard HTTP status codes and a JSON body with a stable, machine-readable code:

{
  "error": {
    "code": "quota_exceeded",
    "message": "Your API calls for this period are used up. …",
    "request_id": "req_9b2d71c0e4a84f5e93aa"
  }
}
StatusCodeMeaning
400image_missingNo image was sent, or it was empty.
400invalid_imageThe "image" field is not valid base64.
400unsupported_image_typeThe file is not a JPEG, PNG, GIF or WebP image.
401missing_api_keyNo API key was sent.
401invalid_api_keyThe key is wrong or has been revoked.
402quota_exceededYour API calls for this period are used up.
404not_foundUnknown endpoint.
405method_not_allowedWrong HTTP method for this endpoint.
413image_too_largeThe image is larger than 10 MB.
415unsupported_content_typeUse application/json or multipart/form-data.
422no_text_foundNo text was detected. The call is not charged.
429rate_limitedMore than 60 requests in a minute on one key.
503service_unavailableTemporary problem on our side. Retry with backoff.

Retry 429 and 503 with exponential backoff. Do not retry 4xx errors without changing the request.

Limits

  • Formats: JPEG, PNG, GIF, WebP. To convert a PDF, export each page as an image first.
  • Size: up to 10 MB per image (about 7 MB when sent as base64).
  • Rate: 60 requests per minute per key. Need more? Contact us.
  • Timeout: most images finish in 1–3 seconds; allow up to 60 seconds in your HTTP client.
  • Languages: tuned for English handwriting and cursive; printed text in most Latin-script languages is also recognized.

Pricing & quotas

The API has its own plans and quota, separate from website conversion plans. Every account includes 25 free API calls per month for testing. API plans add a monthly allowance:

PlanCallsPrice (US)Per call
API Free25 / month$0—
API Starter1,000 / month$19 / month1.9¢
API Growth5,000 / month$49 / month~0.98¢
API Scale20,000 / month$149 / month~0.75¢

Choose or change a plan on the API keys page. Local prices apply in many countries — see pricing. For more than 20,000 calls a month, a higher rate limit or invoiced billing, see business plans.

Best practices

  • Image quality matters most. Even lighting, dark ink, the page filling the frame and 1,500px+ on the long side give the best results.
  • One page per call. Crop multi-page photos and send pages separately.
  • Use the confidence score. Route low-confidence results to a human review step.
  • Keep keys server-side and rotate them if they may have been exposed.
  • Handle 402 by prompting for an upgrade or pausing the job until resets_at.

Changelog

  • v1 released: POST /recognize, GET /usage, multipart and base64 uploads.