Discussions

Ask a Question

Which Coworking Companies In Gurgaon provide the best value for expanding teams?

There are a few Coworking Spaces In Gurgaon that offer expansion plans for growing teams, especially in Cyber City and Sohna Road regions. Startups look for companies that provide flexible packages, meeting rooms, and networking opportunities. The cost depends on the location and services included. Reeltor enables users to compare the best coworking companies without any hidden charges or incorrect listings.

Video agent limit

Hey Heygen development team.

v2/video/generate status 200 still shows error on panel

curl --location 'https://api.heygen.com/v2/video/generate'
--header 'accept: application/json'
--header 'content-type: application/json'
--header 'x-api-key: abcd'
--data '{
"video_inputs": [
{
"character": {
"type": "avatar",
"avatar_id": "1ee71d11eb11400a996b5861e412aed0",
"avatar_style": "normal"
},
"voice": {
"type": "text",
"input_text": "Hello how are you?",
"voice_id": "5d2fe6fd8dad41949db24f4321b6926a",
"speed": 1.1
}
}
],
"dimension": {
"width": 1280,
"height": 1920
}
}'

Need exact Video Agent generate payload to lock avatar identity + use asset_id files[]

Hi HeyGen Engineering Team,

API/ELevenLabs

Hello,
I’m on the Creator Plan with a 1-member Workspace.
My API key is valid but HeyGen returns: “missing user-read to execute this operation.”
It appears my Workspace API key does not include the user:read scope.
Can you enable full API scope permissions for my Workspace so I can integrate with HeyGen?

DIFFICULTIES TO GET GENERATED VIDEOS URL BACK IN ORDER TO DISPLAY THEM ON MY WEB APP

'Annie_expressive4_public', 'teaching' => 'Annie_expressive4_public', 'project_management'=> 'Annie_expressive4_public', 'pharmacy' => 'Annie_expressive4_public', 'agro' => 'Annie_expressive4_public', ]; $VOICE_ID = '0b41c487c6da4f5ba5782bbe462958e8'; // === UTILS === function logMessage($msg) { $logFile = __DIR__ . '/logs/avatar_gen.log'; if (!is_dir(dirname($logFile))) mkdir(dirname($logFile), 0755, true); $timestamp = date('Y-m-d H:i:s'); error_log("[$timestamp] [AvatarGen] $msg\n", 3, $logFile); echo "[$timestamp] $msg\n"; } function heyGenRequest($method, $url, $payload = null) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Accept: application/json', 'X-Api-Key: ' . HEYGEN_API_KEY ]); if ($method === 'POST' && $payload) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); } $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($error) { throw new Exception("cURL error: $error"); } // 🔍 Debug temporaire if ($http_code !== 200) { logMessage("DEBUG HTTP $http_code - URL: $url"); logMessage("DEBUG Response: " . substr($response, 0, 200)); } return [$http_code, json_decode($response, true)]; } // === ÉTAPE 1 : Lancer la génération === function generateVideo($text, $user_group) { global $AVATAR_MAP, $VOICE_ID; $avatar_id = $AVATAR_MAP[$user_group] ?? $AVATAR_MAP['default']; $payload = [ "video_inputs" => [[ "character" => [ "type" => "avatar", "avatar_id" => $avatar_id, "scale" => 1 ], "voice" => [ "type" => "text", "input_text" => $text, "voice_id" => $VOICE_ID ], "background" => ["type" => "color", "value" => "#f8fafc"] ]], "dimension" => ["width" => 1920, "height" => 1080], "test" => false, "caption" => false ]; for ($attempt = 1; $attempt <= MAX_RETRIES; $attempt++) { try { [$code, $data] = heyGenRequest('POST', HEYGEN_API_URL, $payload); if ($code === 200 && !empty($data['data']['video_id'])) { return $data['data']['video_id']; } else { $msg = "HeyGen error (attempt $attempt): HTTP $code - " . ($data['message'] ?? json_encode($data)); logMessage($msg); if ($attempt < MAX_RETRIES) sleep(RETRY_DELAY_SEC); } } catch (Exception $e) { logMessage("Exception (attempt $attempt): " . $e->getMessage()); if ($attempt < MAX_RETRIES) sleep(RETRY_DELAY_SEC); } } throw new Exception("Échec après " . MAX_RETRIES . " tentatives."); } // === ÉTAPE 2 : Attendre la fin de la génération === function waitForVideoCompletion($video_id) { $elapsed = 0; $check_interval = 5; $max_checks = MAX_WAIT_SEC / $check_interval; logMessage("⏳ Attente de la complétion de la vidéo (max " . MAX_WAIT_SEC . " sec)..."); logMessage("🔍 Video ID: $video_id"); // Délai initial plus long (HeyGen met du temps à indexer) sleep(25); for ($check = 1; $check <= $max_checks; $check++) { try { // ✅ CORRECTION DÉFINITIVE : POST avec video_id dans le body JSON (API v1) $payload = ['video_id' => $video_id]; [$code, $data] = heyGenRequest('POST', HEYGEN_STATUS_URL, $payload); if ($code === 200 && !empty($data['data'])) { $status = $data['data']['status'] ?? 'unknown'; logMessage("CallCheck #$check (elapsed: {$elapsed}s) - Statut: $status"); if ($status === 'completed') { $video_url = $data['data']['video_url'] ?? null; if ($video_url) { logMessage("✅ URL CDN trouvée : $video_url"); return $video_url; } // Recherche alternative dans assets $assets = $data['data']['assets'] ?? []; foreach ($assets as $asset) { if (isset($asset['type']) && $asset['type'] === 'video' && isset($asset['url'])) { $video_url = $asset['url']; logMessage("✅ URL trouvée dans assets : $video_url"); return $video_url; } } throw new Exception("Vidéo complétée mais URL non trouvée"); } elseif ($status === 'failed') { $reason = $data['data']['reason'] ?? 'Unknown'; throw new Exception("Échec HeyGen : $reason"); } } else { $error_msg = $data['message'] ?? json_encode($data); logMessage("⚠️ CheckCall #$check - HTTP $code - $error_msg"); } sleep($check_interval); $elapsed += $check_interval; } catch (Exception $e) { logMessage("⚠️ CheckCall #$check erreur: " . $e->getMessage()); sleep($check_interval); $elapsed += $check_interval; } } throw new Exception("Timeout après " . MAX_WAIT_SEC . " secondes"); } // === ÉTAPE 3 : Mettre à jour la base === function updateMediaUrl($conn, $content_date, $user_group, $video_url) { logMessage("💾 Mise à jour de la base de données..."); $stmt = $conn->prepare(" UPDATE daily_content SET media_url = :url, media_type = 'video' WHERE content_date = :date AND user_group = :group "); $stmt->execute([ ':url' => $video_url, ':date' => $content_date, ':group' => $user_group ]); $rows = $stmt->rowCount(); logMessage("✅ Base mise à jour : $rows ligne(s) modifiée(s) - $user_group / $content_date → $video_url"); // Vérification $verify = $conn->prepare(" SELECT media_url, media_type FROM daily_content WHERE content_date = :date AND user_group = :group "); $verify->execute([':date' => $content_date, ':group' => $user_group]); $result = $verify->fetch(PDO::FETCH_ASSOC); if ($result && !empty($result['media_url'])) { logMessage("🔍 Vérification BDD : OK → " . substr($result['media_url'], 0, 60) . "..."); } else { logMessage("⚠️ Vérification BDD : ÉCHOUÉE"); } } // === SCRIPT PRINCIPAL === try { logMessage("╔════════════════════════════════════════════════════════════╗"); logMessage("║ DÉMARRAGE GÉNÉRATION VIDÉO HEYGEN v2 ║"); logMessage("╚════════════════════════════════════════════════════════════╝"); $stmt = $conn->prepare(" SELECT id, content_date, user_group, reading_text FROM daily_content WHERE content_date = :today AND (media_url IS NULL OR media_url = '' OR media_type != 'video') AND reading_text IS NOT NULL AND TRIM(reading_text) != '' "); $stmt->execute([':today' => date('Y-m-d')]); $contents = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($contents)) { logMessage("ℹ️ Aucun contenu à traiter aujourd'hui."); exit(0); } logMessage("📋 " . count($contents) . " contenu(s) trouvé(s) à traiter"); foreach ($contents as $row) { $text = trim($row['reading_text']); $user_group = $row['user_group']; $content_date = $row['content_date']; $content_id = $row['id']; if (empty($text)) continue; logMessage("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); logMessage("🎬 Traitement : $user_group / $content_date (ID: $content_id)"); logMessage("📝 Texte (premiers 50 caractères): " . substr($text, 0, 50) . "..."); try { $video_id = generateVideo($text, $user_group); logMessage("⏳ Job HeyGen lancé : $video_id"); logMessage("🌐 Suivre sur : https://app.heygen.com/videos/$video_id"); $video_url = waitForVideoCompletion($video_id); if (empty($video_url)) { throw new Exception("URL de vidéo vide"); } updateMediaUrl($conn, $content_date, $user_group, $video_url); logMessage("✅ VIDÉO GÉNÉRÉE ET STOCKÉE !"); logMessage("🎬 URL publique : $video_url"); } catch (Exception $e) { logMessage("❌ ÉCHEC pour $user_group : " . $e->getMessage()); } } logMessage("╔════════════════════════════════════════════════════════════╗"); logMessage("║ GÉNÉRATION TERMINÉE ║"); logMessage("╚════════════════════════════════════════════════════════════╝"); logMessage("💡 Rechargez enregistrement.php pour voir la vidéo !"); } catch (Exception $e) { logMessage("🔥 ERREUR CRITIQUE : " . $e->getMessage()); exit(1); } ?>

Requests

  • Let Video Agent API to retrieve CC (subtitles) or allow for burning it into video
  • Let Video Agent API to give another prompt to edit the video
  • Allow to edit the plan with Video Agent API.

Personal Avatars, Voices, Through Video Agent API

Right now when I send a prompt to the video agent API it replies it can't access personal avatars, voices, templates, etc... Do you have any info about when that's going to be available? That would be a game-changer and I'd consider upgrading to the paid plan to be able to use that.

api use Similarity/Stability/Exaggeration possible?

When we use heygen manually we can configure Similarity/Stability/Exaggeration for a good voice and speed. Currently i am testing your api with the 100$ package and would like to use the configuration for my video/voice as same like i use it manually. I can not find in the documentation the confiration snippets. There are or you have another idea how i can adapt the same configruation of other videos to videos created by api?