Quickstart
Get up and running in under 5 minutes.
Step 1: Get Your API Key
Sign up for a VideoConduit account, then head to your API Keys dashboard to create a key. New accounts include free credits so you can start testing immediately.
Keep Your Key Secret
Never expose API keys in client-side code or public repositories. Store them in environment variables and make API calls from your backend server.
Step 2: Extract Video Info (1 Credit)
Let's start with a quick request to verify your key works. The /v1/info endpoint
returns metadata about any video URL — just 1 credit.
curl "https://videoconduit.com/v1/info?url=https://youtube.com/watch?v=dQw4w9WgXcQ" \
-H "Authorization: Bearer vc_your_api_key"import requests
response = requests.get(
"https://videoconduit.com/v1/info",
params={"url": "https://youtube.com/watch?v=dQw4w9WgXcQ"},
headers={"Authorization": "Bearer vc_your_api_key"},
)
data = response.json()
print(data["title"], data["duration"])const response = await fetch(
"https://videoconduit.com/v1/info?url=https://youtube.com/watch?v=dQw4w9WgXcQ",
{ headers: { "Authorization": "Bearer vc_your_api_key" } }
);
const data = await response.json();
console.log(data.title, data.duration);$client = new GuzzleHttp\Client();
$response = $client->get("https://videoconduit.com/v1/info", [
"query" => ["url" => "https://youtube.com/watch?v=dQw4w9WgXcQ"],
"headers" => ["Authorization" => "Bearer vc_your_api_key"],
]);
$data = json_decode($response->getBody(), true);
echo $data["title"];req, _ := http.NewRequest("GET",
"https://videoconduit.com/v1/info?url=https://youtube.com/watch?v=dQw4w9WgXcQ", nil)
req.Header.Set("Authorization", "Bearer vc_your_api_key")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var data map[string]interface{}
json.NewDecoder(resp.Body).Decode(&data)require "net/http"
require "json"
uri = URI("https://videoconduit.com/v1/info?url=https://youtube.com/watch?v=dQw4w9WgXcQ")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer vc_your_api_key"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
puts data["title"]Response:
{
"url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up",
"duration": 212.0,
"thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
"formats": [...]
}
Try it yourself — paste any video URL below:
{# Full interactive API playground component. Full mode: include "docs/_playground_full.html" Mini mode: include "docs/_playground_full.html" with mini=True preselect_endpoint="Get Video Info" #}Step 3: Download a Video (1 Credit)
Now let's download a video. This is an async operation — you'll receive a
job_id and poll for the result.
curl -X POST "https://videoconduit.com/v1/download" \
-H "Authorization: Bearer vc_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"quality": "720p",
"format": "mp4",
"processing": ["normalize", "denoise"]
}'import requests
response = requests.post(
"https://videoconduit.com/v1/download",
headers={"Authorization": "Bearer vc_your_api_key"},
json={
"url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"quality": "720p",
"format": "mp4",
"processing": ["normalize", "denoise"],
},
)
data = response.json()
print(data["job_id"])const response = await fetch("https://videoconduit.com/v1/download", {
method: "POST",
headers: {
"Authorization": "Bearer vc_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://youtube.com/watch?v=dQw4w9WgXcQ",
quality: "720p",
format: "mp4",
processing: ["normalize", "denoise"],
}),
});
const data = await response.json();
console.log(data.job_id);$client = new GuzzleHttp\Client();
$response = $client->post("https://videoconduit.com/v1/download", [
"headers" => ["Authorization" => "Bearer vc_your_api_key"],
"json" => [
"url" => "https://youtube.com/watch?v=dQw4w9WgXcQ",
"quality" => "720p",
"format" => "mp4",
"processing" => ["normalize", "denoise"],
],
]);
$data = json_decode($response->getBody(), true);
echo $data["job_id"];body := strings.NewReader(`{
"url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"quality": "720p",
"format": "mp4",
"processing": ["normalize", "denoise"]
}`)
req, _ := http.NewRequest("POST", "https://videoconduit.com/v1/download", body)
req.Header.Set("Authorization", "Bearer vc_your_api_key")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var data map[string]interface{}
json.NewDecoder(resp.Body).Decode(&data)require "net/http"
require "json"
uri = URI("https://videoconduit.com/v1/download")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer vc_your_api_key"
req["Content-Type"] = "application/json"
req.body = {
url: "https://youtube.com/watch?v=dQw4w9WgXcQ",
quality: "720p",
format: "mp4",
processing: ["normalize", "denoise"],
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
puts data["job_id"]Response:
{
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "pending",
"credits_charged": 1
}
Step 4: Check Job Status
Poll the job endpoint until status is "completed".
Most jobs finish within a few seconds to a couple of minutes depending on the video length.
curl "https://videoconduit.com/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer vc_your_api_key"import requests
response = requests.get(
"https://videoconduit.com/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
headers={"Authorization": "Bearer vc_your_api_key"},
)
job = response.json()
print(job["status"], job.get("download_url"))const response = await fetch(
"https://videoconduit.com/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
{ headers: { "Authorization": "Bearer vc_your_api_key" } }
);
const job = await response.json();
console.log(job.status, job.download_url);$client = new GuzzleHttp\Client();
$response = $client->get("https://videoconduit.com/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890", [
"headers" => ["Authorization" => "Bearer vc_your_api_key"],
]);
$job = json_decode($response->getBody(), true);
echo $job["status"];req, _ := http.NewRequest("GET",
"https://videoconduit.com/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890", nil)
req.Header.Set("Authorization", "Bearer vc_your_api_key")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var job map[string]interface{}
json.NewDecoder(resp.Body).Decode(&job)require "net/http"
require "json"
uri = URI("https://videoconduit.com/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer vc_your_api_key"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
job = JSON.parse(res.body)
puts job["status"]Completed response:
{
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "completed",
"download_url": "https://dl.videoconduit.com/files/a1b2c3d4.mp4",
"result_data": {
"title": "Rick Astley - Never Gonna Give You Up",
"format": "mp4",
"filesize": 15234567
}
}
Step 5: Configure Webhooks (Optional)
Instead of polling, you can receive push notifications when jobs complete. Register a webhook URL in your dashboard and VideoConduit will POST a signed payload to your server whenever a job finishes. See the Webhooks guide for setup details.
Next Steps
- Authentication details — API key management and security
- Full endpoint reference — all parameters and options for /v1/download
- Webhook setup — push notifications instead of polling
- Error handling — error codes and troubleshooting