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.zipThe 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.zipGenerate a font
POST https://api.makeafont.com/api/v1/fonts
Content-Type: multipart/form-data
Authorization: Bearer YOUR_KEY
Idempotency-Key: a-unique-request-idGood costs 400 tokens and High detail costs 1200 tokens. The API has no extra per-request token fee.
| Value | Description |
|---|---|
mode | matching (default) for an image, or text for a description. Manual handwriting/grid imports are not part of this API. |
image | PNG or JPEG file, up to 8 MB. Required in matching mode. |
sourceText | Text mode only. A short lettering sample, 1 to 80 characters. |
sourceStyle | Text mode only. Describe the style, 1 to 500 characters. |
charset | hud (default), title, label, ascii, full or custom. Use full for uppercase, lowercase, numbers and punctuation. |
characters | Required for custom. Your exact character set. Unsupported characters are rejected before generation. |
quality | good (default) or high. The price covers the whole generation, including its automatic retries. |
name | Optional 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
| Value | Description |
|---|---|
GET /jobs/{jobId} | State, progress (0 to 1), stage, fontId and an error when generation fails. |
POST /jobs/{jobId}/cancel | 204. 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}/download | ZIP of the designer exports, including TTF, WOFF2 and glyph images. |
GET /fonts/{fontId}/font.ttf | The colour TrueType font. |
GET /fonts/{fontId}/atlas.png | The 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
| Value | Description |
|---|---|
400 / 413 / 415 | Correct the fields, file size or multipart content type. Invalid inputs do not start a paid generation. |
401 | Check the Bearer key. It may be missing, invalid or revoked. |
402 | Not enough available tokens. Top up or wait for a reservation to be released. |
404 | Check the job/font ID and the account that owns the key. |
409 | For 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. |
429 | Wait for Retry-After before retrying. Do not create a new key to work around limits. |
5xx / connection failure | Retry 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.
