Upload new font
curl --request POST \
--url https://api.nexrender.com/api/v2/fonts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form font=@example-fileimport requests
url = "https://api.nexrender.com/api/v2/fonts"
files = { "font": ("example-file", open("example-file", "rb")) }
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('font', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.nexrender.com/api/v2/fonts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nexrender.com/api/v2/fonts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nexrender.com/api/v2/fonts"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.nexrender.com/api/v2/fonts")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nexrender.com/api/v2/fonts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"familyName": "<string>",
"fileName": "<string>",
"createdAt": "2023-11-07T05:31:56Z"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Fonts Management
Uploading Fonts
Upload custom .ttf fonts to your Nexrender team account and reference them in render jobs
POST
/
fonts
Upload new font
curl --request POST \
--url https://api.nexrender.com/api/v2/fonts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form font=@example-fileimport requests
url = "https://api.nexrender.com/api/v2/fonts"
files = { "font": ("example-file", open("example-file", "rb")) }
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('font', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.nexrender.com/api/v2/fonts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nexrender.com/api/v2/fonts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nexrender.com/api/v2/fonts"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.nexrender.com/api/v2/fonts")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nexrender.com/api/v2/fonts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"font\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"familyName": "<string>",
"fileName": "<string>",
"createdAt": "2023-11-07T05:31:56Z"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}After Effects needs fonts installed on the rendering system. If a font referenced in your template isn’t available, it will silently substitute a fallback - causing layout shifts, incorrect spacing, or broken text styling.
Upload fonts once to your team account and Nexrender installs them on the render worker before After Effects starts.
To override the auto-detected family name, include the
Always resolve missing fonts before submitting production jobs.
Supported Formats
Only.ttf (TrueType Font) files are currently supported.
Upload a Font
Fonts are uploaded asmultipart/form-data. The font field carries the file, and the optional familyName field lets you override the family name that Nexrender auto-detects from the font metadata.
curl -X POST https://api.nexrender.com/api/v2/fonts \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "font=@/path/to/Montserrat-SemiBold.ttf"
{
"id": "01JTGM9GCR71JV7EJYDF45QAFD",
"fileName": "Montserrat-SemiBold.ttf",
"familyName": "Montserrat",
"createdAt": "2025-05-05T16:25:59.961Z"
}
familyName field:
curl -X POST https://api.nexrender.com/api/v2/fonts \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "font=@/path/to/CustomFont.ttf" \
-F "familyName=My Brand Font"
Upload Fields
| Field | Type | Required | Description |
|---|---|---|---|
font | file | Yes | The .ttf font file to upload |
familyName | string | No | Override for the font family name (auto-detected from file metadata if not provided) |
Using Fonts in a Job
Reference uploaded fonts by theirfileName in the fonts array of any job payload. Nexrender installs them on the render worker before rendering begins.
{
"template": {
"id": "YOUR_TEMPLATE_ID",
"composition": "main"
},
"fonts": [
"Montserrat-SemiBold.ttf",
"Roboto-Bold.ttf"
],
"assets": []
}
Missing Fonts Warning
When you create a job, if any font listed in thefonts array hasn’t been uploaded to your team account, the API flags them in the missingFonts field of the response. The job is still created, but rendering may produce incorrect results.
{
"id": "01JTRDF7HCR8QAHYW8GPCP4S9Y",
"status": "queued",
"outputUrl": "https://nx1-outputs-eu.nexrender.com/.../job.mp4",
"missingFonts": ["Roboto-Bold.ttf"]
}
Best Practices
- Name font files clearly -
OpenSans-Bold.ttfrather thanfont1.ttf - Keep naming consistent between your After Effects project and the uploaded file
- Use preview mode to catch font issues cheaply before running full renders
- Treat
.ttffiles as versioned assets - store them in source control alongside your templates
Authorizations
Bearer token authentication using API tokens for team-based access control.
You can generate your own API token at: https://app.nexrender.com/settings/api-tokens
Body
multipart/form-data
Response
Font successfully uploaded and processed
Font file metadata for team-shared typography resources used in After Effects rendering
Unique font identifier
Font family name (e.g., "Arial", "Helvetica Neue") extracted from font metadata (or custom)
Original font file name as uploaded (supports TTF only). This is the file name referenced in pushed jobs.
ISO timestamp when the font was uploaded and processed
Was this page helpful?

