DEVELOPER DOCUMENTATION · V1

Build with the font API.

Submit your art or a description, follow the job, then download your font. All examples run on your server.

1. Create a key

Sign in to your developer dashboard, create a named key and save it when it is shown. Keep it in your server's secret store as MAKEAFONT_API_KEY. Do not put it in client-side JavaScript, URLs, a public repository or a distributed app.

Use Authorization: Bearer YOUR_KEYon every request. Keys use your account's tokens and can download your account's fonts. Revoke a key from the dashboard to stop new requests. Already accepted jobs continue unless cancelled.

curl --fail-with-body https://api.makeafont.com/api/v1/balance \
  -H "Authorization: Bearer $MAKEAFONT_API_KEY"

2. Submit your image

Send a PNG or JPEG, up to 8 MB, as multipart form data. Use a new Idempotency-Key for each intended generation. Save that key and reuse it if you need to retry the same request.

curl --fail-with-body https://api.makeafont.com/api/v1/fonts \
  -H "Authorization: Bearer $MAKEAFONT_API_KEY" \
  -H "Idempotency-Key: my-font-001" \
  -F "image=@my-lettering.png" \
  -F "name=My lettering" \
  -F "charset=full" \
  -F "quality=good"
{
  "jobId": "job_example",
  "estimatedCredits": 400,
  "pollAfterSeconds": 2
}

HTTP 202 means the job was accepted. estimatedCredits is the token reservation, not a completed charge. Generation can take several minutes.

3. Poll, then download

curl --fail-with-body https://api.makeafont.com/api/v1/jobs/job_example \
  -H "Authorization: Bearer $MAKEAFONT_API_KEY"

Poll no faster than pollAfterSeconds. Stop when state is succeeded, failed or cancelled. On success, use the returned fontId:

curl --fail-with-body https://api.makeafont.com/api/v1/fonts/FONT_ID/download \
  -H "Authorization: Bearer $MAKEAFONT_API_KEY" \
  -o my-font.zip

The ZIP contains the font exports, including colour TTF, WOFF2, the bitmap atlas, individual PNGs and vector alternatives. Colour support differs between applications. The same font is available in your MakeAFont account.

Download the complete Node.js example →

# Node.js 22+. Set MAKEAFONT_API_KEY in your environment first.
# Reuse REQUEST_ID when retrying this generation.
REQUEST_ID=my-font-001 node makeafont-api.mjs my-lettering.png my-font.zip

Generate a font

POST https://api.makeafont.com/api/v1/fonts
Content-Type: multipart/form-data
Authorization: Bearer YOUR_KEY
Idempotency-Key: a-unique-request-id

Good costs 400 tokens and High detail costs 1200 tokens. The API has no extra per-request token fee.

ValueDescription
modematching (default) for an image, or text for a description. Manual handwriting/grid imports are not part of this API.
imagePNG or JPEG file, up to 8 MB. Required in matching mode.
sourceTextText mode only. A short lettering sample, 1 to 80 characters.
sourceStyleText mode only. Describe the style, 1 to 500 characters.
charsethud (default), title, label, ascii, full or custom. Use full for uppercase, lowercase, numbers and punctuation.
charactersRequired for custom. Your exact character set. Unsupported characters are rejected before generation.
qualitygood (default) or high. The price covers the whole generation, including its automatic retries.
nameOptional font name.

Text to font

curl --fail-with-body https://api.makeafont.com/api/v1/fonts \
  -H "Authorization: Bearer $MAKEAFONT_API_KEY" \
  -H "Idempotency-Key: my-text-font-001" \
  -F "mode=text" \
  -F "sourceText=STAR QUEST" \
  -F "sourceStyle=Rounded blue letters with a dark outline and soft glow" \
  -F "charset=full" \
  -F "quality=good"

Jobs and downloads

ValueDescription
GET /jobs/{jobId}State, progress (0 to 1), stage, fontId and an error when generation fails.
POST /jobs/{jobId}/cancel204. Cancels a queued job and releases its reservation. Once generation starts, returns 409 job_already_started: keep polling for the result. Completed jobs cannot be refunded here.
GET /fonts/{fontId}/downloadZIP of the designer exports, including TTF, WOFF2 and glyph images.
GET /fonts/{fontId}/font.ttfThe colour TrueType font.
GET /fonts/{fontId}/atlas.pngThe packed bitmap atlas.

All endpoints require your key. Jobs and fonts belonging to other accounts return 404. A failed job returns HTTP 200 with state: "failed" and an error object, so always inspect the state.

Your balance and usage

GET https://api.makeafont.com/api/v1/balance
GET https://api.makeafont.com/api/v1/usage

/balance returns total, reserved, available and current prices. Website and API share one wallet. Only available tokens can start another job.

/usage reports the last 30 days of authenticated requests, submitted jobs, HTTP errors and actual tokens spent, net of refunds. It includes the latest 50 jobs and 50 requests. Polls, downloads and failed requests count as requests, but do not themselves spend tokens.

API keys and activity remain with your account until account deletion. Logs contain route templates, timestamps, statuses and durations, not images, prompts or credential values. Account data export includes this activity.

Errors, limits and safe retries

ValueDescription
400 / 413 / 415Correct the fields, file size or multipart content type. Invalid inputs do not start a paid generation.
401Check the Bearer key. It may be missing, invalid or revoked.
402Not enough available tokens. Top up or wait for a reservation to be released.
404Check the job/font ID and the account that owns the key.
409For request_in_progress, wait and retry the same request. For idempotency_conflict, the key was reused with different inputs. For job_already_started, cancellation is unavailable; keep polling the job.
429Wait for Retry-After before retrying. Do not create a new key to work around limits.
5xx / connection failureRetry with the original Idempotency-Key and identical fields. If it persists, contact support with X-Request-Id.

Generation allows an initial burst of 6, replenishing at 1 per minute. Other requests allow an initial burst of 120, replenishing at 2 per second. These limits are shared across all your keys and our servers. Network-level flood protection also applies. Respect 429 and its Retry-After header. Requests rejected by these limits are not added to your request history.

Idempotency keys are 8 to 128 printable non-space characters and remain reserved for the life of the account. Replaying a completed submission returns the original response and Idempotency-Replayed: true. It does not restart a failed job. Use a new key when you deliberately want a new generation.

If a submission remains in progress after a service interruption, contact support before submitting with a new key. Keep request IDs for troubleshooting.