Inicio Rápido¶
¡Comienza con SubX API en minutos! Esta guía te guiará a través de tus primeras solicitudes a la API.
Requisitos Previos¶
Antes de comenzar, asegúrate de tener:
- ✅ Creada una cuenta de SubX y generada una clave de API (ver Guía de Autenticación)
- ✅ Tu cliente HTTP favorito o lenguaje de programación listo
Tu Primera Solicitud¶
Comencemos verificando el estado de salud de la API - este es el único endpoint que no requiere autenticación:
=== "cURL"
import requests
response = requests.get("https://subx-api.duckdns.org/api/health")
print(response.json())
const response = await fetch('https://subx-api.duckdns.org/api/health');
const data = await response.json();
console.log(data);
Respuesta Esperada:
Buscar Subtítulos¶
¡Ahora busquemos subtítulos! Reemplaza {TU_CLAVE_API} con tu clave de API real.
Búsqueda por Título¶
=== "cURL"
curl -X GET "https://subx-api.duckdns.org/api/subtitles/search?title=Dexter&limit=10" \
-H "Authorization: Bearer {TU_CLAVE_API}"
import requests
headers = {"Authorization": "Bearer {TU_CLAVE_API}"}
params = {
"title": "Dexter",
"limit": 10
}
response = requests.get(
"https://subx-api.duckdns.org/api/subtitles/search",
headers=headers,
params=params
)
data = response.json()
print(f"Encontrados {data['total']} subtítulos")
for subtitle in data['items']:
print(f"- {subtitle['title']} ({subtitle['video_type']})")
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
func main() {
apiKey := "{TU_CLAVE_API}"
baseURL := "https://subx-api.duckdns.org/api/subtitles/search"
// Construir parámetros de consulta
params := url.Values{}
params.Add("title", "Dexter")
params.Add("limit", "10")
// Crear solicitud
req, _ := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
// Enviar solicitud
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// Parsear respuesta
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Encontrados %v subtítulos\n", result["total"])
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Text.Json;
class Program
{
static async Task Main()
{
var apiKey = "{TU_CLAVE_API}";
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", apiKey);
var url = "https://subx-api.duckdns.org/api/subtitles/search?title=Dexter&limit=10";
var response = await client.GetAsync(url);
var json = await response.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<JsonElement>(json);
Console.WriteLine($"Encontrados {data.GetProperty("total")} subtítulos");
}
}
Respuesta Esperada:
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"video_type": "episode",
"title": "Dexter",
"season": 1,
"episode": 1,
"imdb_id": "tt0773262",
"description": "Dexter S01E01 - Dexter",
"uploader_name": "user123",
"posted_at": "2024-01-15T10:30:00Z",
"downloads": 1250
}
],
"total": 1
}
Búsqueda por ID de IMDb¶
Si conoces el ID de IMDb, puedes buscar directamente:
=== "cURL"
curl -X GET "https://subx-api.duckdns.org/api/subtitles/search?imdb_id=tt0773262&limit=20" \
-H "Authorization: Bearer {TU_CLAVE_API}"
import requests
headers = {"Authorization": "Bearer {TU_CLAVE_API}"}
params = {
"imdb_id": "tt0773262", # Serie Dexter
"limit": 20
}
response = requests.get(
"https://subx-api.duckdns.org/api/subtitles/search",
headers=headers,
params=params
)
data = response.json()
print(f"Encontrados {data['total']} subtítulos para ID de IMDb tt0773262")
Descargar un Subtítulo¶
Una vez que hayas encontrado un subtítulo, descárgalo usando su ID:
=== "cURL"
# Descargar y guardar en archivo
curl -X GET "https://subx-api.duckdns.org/api/subtitles/550e8400-e29b-41d4-a716-446655440000/download" \
-H "Authorization: Bearer {TU_CLAVE_API}" \
-o subtitulo.srt
import requests
headers = {"Authorization": "Bearer {TU_CLAVE_API}"}
subtitle_id = "550e8400-e29b-41d4-a716-446655440000"
response = requests.get(
f"https://subx-api.duckdns.org/api/subtitles/{subtitle_id}/download",
headers=headers
)
# Guardar en archivo
with open("subtitulo.srt", "wb") as f:
f.write(response.content)
print("¡Subtítulo descargado exitosamente!")
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
apiKey := "{TU_CLAVE_API}"
subtitleID := "550e8400-e29b-41d4-a716-446655440000"
url := fmt.Sprintf("https://subx-api.duckdns.org/api/subtitles/%s/download", subtitleID)
// Crear solicitud
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
// Enviar solicitud
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// Guardar en archivo
file, _ := os.Create("subtitulo.srt")
defer file.Close()
io.Copy(file, resp.Body)
fmt.Println("¡Subtítulo descargado exitosamente!")
}
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var apiKey = "{TU_CLAVE_API}";
var subtitleId = "550e8400-e29b-41d4-a716-446655440000";
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", apiKey);
var url = $"https://subx-api.duckdns.org/api/subtitles/{subtitleId}/download";
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("subtitulo.srt", content);
Console.WriteLine("¡Subtítulo descargado exitosamente!");
}
}
Ejemplo Completo: Buscar y Descargar¶
Aquí hay un ejemplo completo que busca subtítulos y descarga el primer resultado:
=== "Python"
import requests
import os
# Configuración
API_KEY = os.getenv("SUBX_API_KEY") # Usar variable de entorno
BASE_URL = "https://subx-api.duckdns.org"
headers = {"Authorization": f"Bearer {API_KEY}"}
def search_subtitles(title, limit=10):
"""Buscar subtítulos por título."""
response = requests.get(
f"{BASE_URL}/api/subtitles/search",
headers=headers,
params={"title": title, "limit": limit}
)
response.raise_for_status()
return response.json()
def download_subtitle(subtitle_id, output_path):
"""Descargar un archivo de subtítulo."""
response = requests.get(
f"{BASE_URL}/api/subtitles/{subtitle_id}/download",
headers=headers
)
response.raise_for_status()
with open(output_path, "wb") as f:
f.write(response.content)
return output_path
# Flujo principal
if __name__ == "__main__":
# Buscar subtítulos de "Dexter"
print("Buscando subtítulos de Dexter...")
results = search_subtitles("Dexter", limit=5)
print(f"Encontrados {results['total']} subtítulos")
if results['items']:
# Descargar el primer resultado
first_subtitle = results['items'][0]
print(f"\nDescargando: {first_subtitle['title']}")
subtitle_id = first_subtitle['id']
output_file = f"{first_subtitle['title']}.srt"
download_subtitle(subtitle_id, output_file)
print(f"✓ Guardado en: {output_file}")
else:
print("No se encontraron subtítulos")
const API_KEY = process.env.SUBX_API_KEY;
const BASE_URL = 'https://subx-api.duckdns.org';
async function searchSubtitles(title, limit = 10) {
const response = await fetch(
`${BASE_URL}/api/subtitles/search?title=${encodeURIComponent(title)}&limit=${limit}`,
{
headers: { 'Authorization': `Bearer ${API_KEY}` }
}
);
if (!response.ok) throw new Error('Búsqueda fallida');
return await response.json();
}
async function downloadSubtitle(subtitleId, outputPath) {
const response = await fetch(
`${BASE_URL}/api/subtitles/${subtitleId}/download`,
{
headers: { 'Authorization': `Bearer ${API_KEY}` }
}
);
if (!response.ok) throw new Error('Descarga fallida');
const buffer = await response.arrayBuffer();
const fs = require('fs').promises;
await fs.writeFile(outputPath, Buffer.from(buffer));
return outputPath;
}
// Flujo principal
async function main() {
console.log('Buscando subtítulos de Dexter...');
const results = await searchSubtitles('Dexter', 5);
console.log(`Encontrados ${results.total} subtítulos`);
if (results.items.length > 0) {
const firstSubtitle = results.items[0];
console.log(`\nDescargando: ${firstSubtitle.title}`);
const outputFile = `${firstSubtitle.title}.srt`;
await downloadSubtitle(firstSubtitle.id, outputFile);
console.log(`✓ Guardado en: ${outputFile}`);
} else {
console.log('No se encontraron subtítulos');
}
}
main().catch(console.error);
Manejo de Errores¶
Siempre maneja los errores de manera elegante en código de producción:
=== "Python"
import requests
headers = {"Authorization": f"Bearer {API_KEY}"}
try:
response = requests.get(
"https://subx-api.duckdns.org/api/subtitles/search",
headers=headers,
params={"title": "Dexter"}
)
response.raise_for_status() # Lanzar excepción para códigos de estado 4xx/5xx
data = response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
print("❌ Clave de API inválida")
elif e.response.status_code == 429:
print("❌ Límite de tasa excedido")
else:
print(f"❌ Error HTTP: {e}")
except requests.exceptions.RequestException as e:
print(f"❌ Solicitud fallida: {e}")
Códigos de Respuesta Comunes¶
| Código | Significado | Descripción |
|---|---|---|
| 200 | OK | Solicitud exitosa |
| 400 | Solicitud Incorrecta | Parámetros inválidos |
| 401 | No Autorizado | Clave de API faltante o inválida |
| 404 | No Encontrado | Recurso no encontrado |
| 429 | Demasiadas Solicitudes | Límite de tasa excedido |
| 500 | Error Interno del Servidor | Error del servidor |
Próximos Pasos¶
Ahora que has hecho tus primeras solicitudes, explora las capacidades completas de la API:
- Referencia de la API - Documentación completa de endpoints
- Ejemplos de Código - Ejemplos más avanzados
- Límites de Tasa - Comprensión de los límites de tasa