API Patterns
KillrVideo uses consistent patterns across all endpoints. Understanding these conventions will help you read the API quickly and know what to expect from any endpoint you encounter.
Base URL
All API routes are prefixed with /api/v1:
http://localhost:8000/api/v1/...
The v1 version prefix allows the API to evolve without breaking existing clients. All current endpoints are under v1.
JSON Everywhere
Every request body and response body uses application/json. Set the Content-Type: application/json header on requests that include a body (POST, PUT, PATCH). Responses always include Content-Type: application/json.
There is no XML, no form-encoded bodies, no multipart (video files are referenced by URL, not uploaded directly).
Resource Identifiers
All resources are identified by UUIDs, not integer IDs. UUIDs appear as path parameters:
GET /api/v1/videos/550e8400-e29b-41d4-a716-446655440000
GET /api/v1/users/a8098c1a-f86e-11da-bd1a-00112444be1e
UUIDs are lowercase with hyphens in the standard 8-4-4-4-12 format.
Pagination
All list endpoints return paginated results using a consistent wrapper structure:
{
"data": [
{ ... },
{ ... }
],
"pagination": {
"currentPage": 1,
"pageSize": 10,
"totalItems": 47,
"totalPages": 5
}
}
Request specific pages with query parameters:
GET /api/v1/videos/latest?page=2&pageSize=20
| Parameter | Default | Maximum | Description |
|---|---|---|---|
page |
1 | — | Page number (1-indexed) |
pageSize |
10 | 50 | Items per page |
When totalItems is 0, data is an empty array and totalPages is 0.
Error Responses
Errors follow RFC 7807 Problem+JSON. Every error response has the same shape:
{
"status": 404,
"type": "https://killrvideo.github.io/errors/not-found",
"title": "Not Found",
"detail": "Video with id '550e8400-e29b-41d4-a716-446655440000' was not found."
}
status— matches the HTTP status codetype— a URI that identifies the error class (can be used to handle specific errors programmatically)title— short, human-readable error namedetail— longer message safe to display to users
HTTP Status Codes
| Code | When it's used |
|---|---|
200 OK |
Successful GET, PUT, or PATCH |
201 Created |
Successful POST that created a resource |
204 No Content |
Successful DELETE (no body) |
400 Bad Request |
Request is malformed (missing required fields, wrong types) |
401 Unauthorized |
No token provided or token is invalid/expired |
403 Forbidden |
Valid token but insufficient role for this endpoint |
404 Not Found |
Resource does not exist |
422 Unprocessable Entity |
Pydantic validation failed (returned by FastAPI automatically) |
422 responses come from FastAPI's built-in validation and have a different shape than other errors — they include a detail array listing each field validation failure.
Authentication Header
Protected endpoints require a Bearer token:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Omitting the header on a protected endpoint returns 401. Providing a valid token with insufficient role returns 403.
Public endpoints (video feeds, search, individual video detail) do not require authentication and return the same response whether or not a token is provided.