Error Handling
All errors return a JSON body with a machine-readable code. Rate limit is 120 req/min.
Failed requests return a non-2xx status and a JSON body with success: false.
{
"success": false,
"code": "INVALID_INPUT",
"error": "videoUrl is required"
}Prop
Type
Error codes
Both BAD_REQUEST and INVALID_INPUT return status 400 but mean different things. BAD_REQUEST is a schema problem: a missing required field or an unrecognized enum value. INVALID_INPUT means the body looked fine but the content was wrong, like a URL that points nowhere or a video without captions.
Prop
Type
Rate limiting
120 requests per 60 seconds per API key. Rate limit state is in the response headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per window (120) |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
When exceeded, the API returns 429 RATE_LIMITED. Wait until the reset time before retrying.
Versioning
The API is versioned in the URL path (/v1/). Breaking changes like removed fields, changed response shapes, or altered error codes will always move to a new version (/v2/) with advance notice. We may add new optional fields or new error codes to the current version without notice. Handle unknown error codes in your default or else branch so your code stays forward-compatible.
Handling errors
const res = await fetch("https://api.stophy.dev/v1/video", {
method: "POST",
headers: {
"Authorization": "Bearer st_YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ videoUrl: "https://www.youtube.com/watch?v=D7liwdjvhWc", type: "details" }),
});
if (!res.ok) {
const json = await res.json();
switch (json.code) {
case "INSUFFICIENT_CREDITS":
// top up from dashboard
break;
case "RATE_LIMITED":
// wait until X-RateLimit-Reset, then retry
break;
case "UNAUTHORIZED":
// check your API key
break;
default:
console.error(json.error);
}
return;
}
const { data } = await res.json();
console.log(data);import httpx
res = httpx.post(
"https://api.stophy.dev/v1/video",
headers={"Authorization": "Bearer st_YOUR_API_KEY"},
json={"videoUrl": "https://www.youtube.com/watch?v=D7liwdjvhWc", "type": "details"},
)
body = res.json()
if not body["success"]:
code = body.get("code")
if code == "INSUFFICIENT_CREDITS":
pass # top up from dashboard
elif code == "RATE_LIMITED":
pass # wait until reset, then retry
else:
print(body["error"])
else:
print(body["data"])Credits
One credit per successful request. No subscriptions, no expiry. Check your balance and track usage from the dashboard.
Video POST
Fetch video details, transcript, comments, or replies. Pass type: details for metadata, transcript for timestamped captions, comments for top-level comments, or replies for a comment thread (pass the repliesToken from a comment as continuationToken).