Développeurs · API REST
L’API de têtes MetaHuman, conçue pour les lots.
Envoyez des photos d’une personne, recevez une réponse quand la tête est prête, récupérez le format dont vous avez besoin. Le même appel crée une tête ou cinq cents. Chaque tête est terminée : peau 4K, recommandations de grooms (pilosité MetaHuman), cou ajusté et 52 blendshapes ARKit. Une tête demande environ 4 minutes : l’API est donc asynchrone par conception.
- REST + JSON
- Clés Bearer
- Webhooks signés
- Clés d’idempotence
- OpenAPI 3.1
- llms.txt
À ne pas confondre avec les API Python et C++ de MetaHuman d’Epic, qui s’exécutent dans Unreal Engine. FaceNinja est une API web qui crée la tête que vous y importez.
POST /v1/headsphotos d’une personne- id de la tête
head.completedwebhook signé une fois terminéePOST /v1/heads/{id}/filesformat- lien signé à durée limitée
Envoyer. Être prévenu. Récupérer.
Envoyer.
POST /v1/headsavec 1 à 15 photos d’une même personne, en fichiers multipart ou en identifiants de photos envoyées au préalable. Ajoutez unIdempotency-Key: une nouvelle tentative ne crée ni ne facture jamais une seconde tête.Être prévenu.
Choisissez comment : un webhook signé vers votre serveur, un canal d’événements envoyés par le serveur, ou un long polling
?wait=60pour les scripts.Récupérer.
Demandez
glb,fbx,obj,stl,plyoumetahuman_zip, avec ou sans blendshapes ARKit. Vous obtenez un lien signé qui ne demande aucune clé. Conservez l’identifiant de la tête, pas le lien. Ce que contient chaque format
Les crédits d’une tête en échec reviennent automatiquement, et error.code en donne la raison.
Un webhook, et votre backend a tout ce qu’il lui faut.
Créez la tête, conservez son identifiant, et agissez quand nous vous appelons. Voilà toute l’intégration, en Python.
# when the user confirms their photos
head = api.post("/v1/heads", files=photos,
data={"webhook_url": "https://you.example/hooks/faceninja"},
headers={"Idempotency-Key": str(uuid4())}).json()
save(user, head["id"])
# later, FaceNinja calls you
@app.post("/hooks/faceninja")
def on_head(event = verified(request)): # check FaceNinja-Signature first
if event["type"] == "head.completed":
link = api.post(f"/v1/heads/{event['data']['id']}/files",
json={"format": "glb", "arkit": True}).json()
store_on_your_cdn(link["url"])// when the user confirms their photos
const form = new FormData();
for (const p of photos) form.append("photos", p);
form.append("webhook_url", "https://you.example/hooks/faceninja");
const head = await api.post("/v1/heads", form,
{ headers: { "Idempotency-Key": crypto.randomUUID() } });
await save(user, head.id);
// later, FaceNinja calls you
app.post("/hooks/faceninja", async (req, res) => {
const event = verified(req); // check FaceNinja-Signature first
if (event.type === "head.completed") {
const link = await api.post(`/v1/heads/${event.data.id}/files`,
{ format: "glb", arkit: true });
await storeOnYourCdn(link.url);
}
res.sendStatus(204);
});Raccourci pour la lecture. La référence EN contient la requête complète, la vérification de la signature et chaque erreur.
Un casting depuis un dossier, sans risque de le lancer deux fois.
Un lot, c’est beaucoup de créations unitaires. Donnez à chacune une clé d’idempotence tirée de vos propres données, comme le nom du dossier : vous pouvez relancer tout le script après un plantage sans créer ni payer une tête deux fois. Laissez ensuite les webhooks vous dire quelles têtes sont terminées.
for person in sorted(Path("cast").iterdir()): # one folder per person
photos = [("photos", open(p, "rb")) for p in sorted(person.glob("*.jpg"))]
api.post("/v1/heads", files=photos,
data={"name": person.name, "webhook_url": HOOK},
headers={"Idempotency-Key": f"cast-2026-10/{person.name}"})- Cadence : jusqu’à 30 créations de tête par minute et par compte. Sur un
429, attendezRetry-Aftersecondes et renvoyez la même clé. - Vérifier d’abord :
?dry_runvérifie une création et renvoie un devis sans créer de tête.GET /v1/accountaffiche le solde. - Suivre :
GET /v1/headsliste vos têtes, page par page, avec leur statut. - Une qui échoue, pas toutes : une tête qui échoue signale son propre
error.code, et ses crédits reviennent. Le reste du lot continue.
Ou laissez votre agent écrire l’intégration.
La référence de l’API, le fichier OpenAPI et llms.txt sont écrits pour les humains et pour les modèles de langage. Donnez le skill à votre agent : il peut créer des têtes directement pour vous, ou écrire et tester le script de pipeline adapté à votre stack.
Read https://faceninja.net/llms.txt and https://faceninja.net/skill/SKILL.md. Write a Python script for our pipeline: for each new folder in ./incoming, create one FaceNinja head from its photos with an Idempotency-Key derived from the folder name and a webhook_url I give you. Add a small web handler that checks the FaceNinja-Signature header, and on head.completed downloads the FBX to ./heads/<folder name>; on head.failed it logs error.code. Read the API key from FACENINJA_API_KEY. Don't run anything against my account until I say so.Gardez ce prompt en anglais : votre agent a besoin de l’adresse web exactement telle qu’elle est écrite. Vous pourrez ensuite lui parler dans votre langue.
Conçu pour les nouvelles tentatives, les files d’attente et les mauvaises photos.
Créations idempotentes
Le même Idempotency-Key sous 24 heures renvoie la même tête, jamais un second débit.
Webhooks signés
head.completed et head.failed, avec une signature HMAC dans FaceNinja-Signature.
File d’attente honnête
Pendant l’attente, une tête indique sa place dans la file et une estimation.
Des erreurs que votre code sait traiter
Des valeurs error.code stables (no_face, not_same_person, content_rejected, …) et un hint.
Remboursements sans ticket
Les crédits sont réservés à la création, débités à l’achèvement et libérés en cas d’échec ou de suppression.
Suppression à la demande
Supprimez une tête et ses photos quand vous voulez. Les fichiers expirent 30 jours après la fin de la tête.
Les chiffres à prendre en compte.
| Photos par tête | De 1 à 15, une seule personne ; JPEG, PNG, WebP, HEIC/HEIF ou AVIF, jusqu’à 25 MiB chacune |
|---|---|
| Durée par tête | Environ 4 minutes, plus l’éventuelle file d’attente |
| Long polling | ?wait jusqu’à 60 s par appel |
| Liens de téléchargement | À démarrer sous 60 s ; un téléchargement démarré va à son terme |
| Limites de débit | 600 requêtes par minute et par compte ; 30 créations de tête par minute |
| Conservation | Photos et fichiers : 30 jours après la fin de la tête |
| Prix | 1 500 crédits (15 $US) par tête, tous formats inclus |
La référence fait foi. Si un chiffre ici diffère, c’est la référence qui l’emporte.
Le visage d’un joueur dès le premier jour du fichier de sauvegarde.
Laissez les joueurs apporter leur propre visage, ou construisez un casting de PNJ à partir d’acteurs consentants. Chaque tête est le même maillage avec un visage différent : un seul rig, un seul matériau et un seul jeu d’animations conviennent à toutes. Les 52 blendshapes ARKit acceptent la synchro labiale ou la caméra du joueur.
Prévoyez l’attente. Une tête demande environ 4 minutes, pas des millisecondes. Lancez-la tôt, pendant l’onboarding ou un tutoriel, affichez une tête provisoire, et remplacez-la quand le webhook arrive.
GLB pour Unity, Godot et le web ; FBX et MetaHuman ZIP pour Unreal. L’automatisation Unreal est en accès anticipé : demandez-la.
Nos conditions exigent l’accord de la personne sur la photo et interdisent les photos d’enfants. Intégrez la même règle à votre parcours.




Vous utilisez déjà une autre API photo vers MetaHuman ?
Si votre intégration crée déjà une tête, l’attend et télécharge un fichier, elle garde la même forme ici. Les chemins, les noms de champs et l’étape du fichier diffèrent, et le guide de migration les met en correspondance appel par appel.
Questions de développeurs.
- 01Y a-t-il un bac à sable ?
- Ajoutez
?dry_runà un appel de création. Il vérifie la requête et renvoie un devis sans créer de tête ni vous facturer. - 02Puis-je l’appeler depuis un navigateur ou une application mobile ?
- Non. Gardez la clé sur votre serveur. Les liens signés d’envoi et de téléchargement n’ont pas besoin de clé : un client peut donc envoyer ou télécharger directement.
- 03Quels SDK existe-t-il ?
- Du HTTP simple et un fichier OpenAPI 3.1 à partir duquel générer un client. La référence propose des exemples en curl, Node et Python. La CLI du skill d’agent est aussi un unique fichier Python que vous pouvez lire et appeler depuis vos scripts.
- 04Combien de têtes puis-je créer à la fois ?
- Jusqu’à 30 créations de tête par minute et par compte, et chacune passe par la file d’attente. Au-delà de 1 000 têtes, écrivez-nous au sujet de la facturation et de la capacité.
- 05S’agit-il de l’API MetaHuman d’Epic ?
- Non. Les API MetaHuman d’Epic pilotent MetaHuman Creator dans Unreal Engine. FaceNinja crée la tête à partir de photos, sous forme de service web, et vous remet les fichiers et le MetaHuman ZIP à importer dans Unreal.
- 06Peut-il créer une tête à partir d’un ensemble de photos ?
- Oui, en Beta : la reconstruction à partir de plusieurs photos d’une même session renvoie aussi la position de la caméra et la focale de chaque photo. Écrivez-nous si vous voulez l’essayer avec votre jeu de captures.