Images, videos and files uploaded to the site, stored in cloud storage and referenced by ID from pages, products and everything else.
Endpoints that need a token: the site owner creates it in their admin (Developers > API reference). AI assistants: how to ask the user for one.
72 endpoints in 6 parts: Media, File Route, Qr Code, Video, Video Interaction, AI builder.
Starts transcoding a video (media_id) to another quality (transcode). 404 "Not found.", 401 "Unauthorized." for a video the user does not own. Answers { url, media }.
Needs the token of a signed-in user.
The add media quality's media id.
The add media quality's transcode.
The add media quality's type.
curl -X POST 'http://hristovtintdetailng.com/add-media-quality?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "media_id": "...", "transcode": "...", "type": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Whether a Vimeo video has finished processing. Answers { duration } once Vimeo has processed the video.
Needs the token of a signed-in user.
The ID of the video.
curl -X GET 'http://hristovtintdetailng.com/check-video/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Creates a folder (name) in the site's cloud storage. Answers {}.
Needs the token of a signed-in user.
The storage folder's name.
curl -X POST 'http://hristovtintdetailng.com/create-storage-folder?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "name": "..." }'Downloads a media file as an attachment. A file in cloud storage answers { url } to download from; an older file stored in the database is sent directly.
Public - no token needed.
The ID of the download media.
Returns the Media object.
curl -X GET 'http://hristovtintdetailng.com/download-media/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}The CDN address media is served from; ?without_path for the bare host. Answers { media_cdn }.
Needs the token of a signed-in user.
Only media cdns with this without path.
curl -X GET 'http://hristovtintdetailng.com/get-media-cdn?ionic=true&without_path=...' \ -H 'Authorization: Bearer <TOKEN>'
A signed cloud storage URL to upload a file to directly (name, type), and the media record it will be. Answers { url, media }: PUT the file to url, and the media record is ready to use. For large files, which skip the server.
Needs the token of a signed-in user.
The media signed url's name.
The media signed url's type.
The media signed url's duration.
The media signed url's save owner.
curl -X POST 'http://hristovtintdetailng.com/get-media-upload-signed-url?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "name": "...", "type": "...", "duration": "...", "saveOwner": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A signed URL to upload a file (name, type) to the site's cloud storage. Answers { url, generated_name }.
Needs the token of a signed-in user.
The storage signed url's name.
The storage signed url's type.
curl -X POST 'http://hristovtintdetailng.com/get-storage-upload-signed-url?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "name": "...", "type": "..." }'Starts a Vimeo upload and answers its upload form. Answers { form, uri }: the browser uploads straight to Vimeo with it.
Needs the token of a signed-in user.
curl -X POST 'http://hristovtintdetailng.com/get-vimeo-form?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Imports pictures from URLs into the media library. Answers 201 with the new media ids, in the order the URLs were sent.
Needs the token of a signed-in user.
Returns the Media object.
curl -X POST 'http://hristovtintdetailng.com/import-medias?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Imports a picture from another site (media, url) into the media library. Answers 201 { id }.
Needs the token of a signed-in user.
The medias from site's media.
The ID of the medias from site.
The medias from site's URL slug, as in its address on the site.
curl -X POST 'http://hristovtintdetailng.com/import-medias-from-site?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "media": "...", "_id": "...", "url": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}The site's logo, 400px wide. At full quality. Cached for 6 minutes.
Public - no token needed.
Only logos with this size.
curl -X GET 'http://hristovtintdetailng.com/logo?ionic=true&size=...'
{
"zip_code": "example",
"city": "example",
"address": "example",
"contact": "example",
"email": "jane@example.com",
"google_app": "example",
"workhours": "example",
"logo": "6543210fedcba98765432100",
"site_name": "Example",
"domain": "example",
"stock_domain": "example",
"isMarket": false,
"forbidden_collections": [
{
"collection_id": "6543210fedcba98765432100",
"_id": "6543210fedcba98765432100"
}
],
"isInit": false,
"template": "0000",
"lang": "en",
"favicon": "6543210fedcba98765432100",
"cacheEnabled": false,
"has_completed_startup_prompt": true,
"gmb_location": "example",
"ga_property": "example",
"site_generated_at": "2026-11-04T12:00:00.000Z",
"admin_first_opened_at": "2026-11-04T12:00:00.000Z",
"admin_last_opened_at": "2026-11-04T12:00:00.000Z",
"allowedComponents": {
"services": false,
"products": false,
"blogposts": false,
"programs": false
}
}The preview picture of an imported page file. Answers the image bytes, or 404.
Public - no token needed.
The ID of the media section.
curl -X GET 'http://hristovtintdetailng.com/media-about-section-import/{id}?ionic=true'{
"title": "Example",
"url": "example-item",
"media": "example",
"metadata": "example",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Downloads the file at the URL given in the query and answers it, with open CORS. Reads no token and fetches any address it is given.
Public - no token needed.
The media instagram's URL slug, as in its address on the site.
curl -X GET 'http://hristovtintdetailng.com/media-instagram?ionic=true&url=...'
Make a scroll animation's video with AI, from an idea and up to 3 of the user's pictures. The idea is rewritten into a scroll-friendly, safe video prompt first (utils/ai-builder/scroll-sequence-ai). Answers at once with an AsyncJob to poll (GET /async-jobs/:id); when it completes, its jobContext holds { media, summary, prompt } - the video, already cut into frames - or { error, refused }.
Needs a site admin token.
The media sequence generate's idea.
The media sequence generate's media ids.
The media sequence generate's quality.
curl -X POST 'http://hristovtintdetailng.com/media-sequence-generate?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "idea": "...", "mediaIds": "...", "quality": "..." }'What an AI scroll-animation video costs, in credits, by quality - and the user's. balance (null when the wallet cannot be read).
Needs a site admin token.
curl -X GET 'http://hristovtintdetailng.com/media-sequence-generate/cost?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
The frames of a scroll animation - status, count, size and CDN. URLs. Public: the live site's player reads it.
Public - no token needed.
The ID of the media sequence.
curl -X GET 'http://hristovtintdetailng.com/media-sequence/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Cut a stored video into the still frames a scroll animation plays. Starts the build and answers 202 { status: 'processing' } at once; follow it with while a build runs, it answers the same (no second build) unless ?force.
Needs a site admin token.
The ID of the media sequence.
Only media sequences with this force.
The media sequence's trim start.
curl -X POST 'http://hristovtintdetailng.com/media-sequence/{id}?ionic=true&force=...' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "trim_start": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}The browser could not finish (and says why) - so the build is not left "processing". Answers { ok: true }.
Needs a site admin token.
The ID of the media sequence.
The media sequence's error.
curl -X POST 'http://hristovtintdetailng.com/media-sequence/{id}/client-fail?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "error": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}The frames are up: check them and mark the animation ready. Answers the frame manifest the page uses.
Needs a site admin token.
The ID of the media sequence.
curl -X POST 'http://hristovtintdetailng.com/media-sequence/{id}/client-finish?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}The admin's heartbeat while it builds: frames done so far. Answers { ok: true }.
Needs a site admin token.
The ID of the media sequence.
curl -X POST 'http://hristovtintdetailng.com/media-sequence/{id}/client-progress?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Signed upload links for every frame the admin is about to make. For the scroll animation: the admin cuts the video into frames in the browser. 404 "Video not found", 409 when it is already being processed.
Needs a site admin token.
The ID of the media sequence.
The media sequence's force.
curl -X POST 'http://hristovtintdetailng.com/media-sequence/{id}/client-start?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "force": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}The picture of a progress entry. Answers the image bytes, or 404.
Public - no token needed.
The ID of the media tracker.
curl -X GET 'http://hristovtintdetailng.com/media-tracker/{id}?ionic=true'{
"score": "example",
"user_id": "6543210fedcba98765432100",
"media": "example",
"additional_fields": {},
"goal": {},
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Creates a media record. Multipart upload of one or more files (medias). Pictures are resized and stored; answers the media record, or redirects back for a website form.
Needs the token of a signed-in user.
Only medias with this skip owner id.
The media's body.
Img alt (same as filename if not specified).
Link to the video on YouTube.
Link to the video on Vimeo.
The picture's address in cloud storage.
Returns the Media object.
curl -X POST 'http://hristovtintdetailng.com/medias?ionic=true&skip_owner_id=...' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "body": "...", "alt": "...", "youtube_url": "...", "vimeo_url": "...", "picture_gcs_url": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A picture 160px wide, as an avatar. Resized on the fly and cached for an hour; 404 when there is no such media.
Public - no token needed.
The ID of the medias avatar.
curl -X GET 'http://hristovtintdetailng.com/medias-avatar/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}How many media records the site has. Answers { videos_count, pictures_count }.
Needs the token of a signed-in user.
Returns a list of Media objects.
curl -X GET 'http://hristovtintdetailng.com/medias-count?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
[
{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}
]A file sent with a form, by its position. Answers the file bytes, or 404.
Public - no token needed.
The medias form's form id.
The medias form's img index.
Returns the Form object.
curl -X GET 'http://hristovtintdetailng.com/medias-form/{form_id}&{img_index}?ionic=true'{
"name": "Example",
"email": "jane@example.com",
"subject": "example",
"body": "Text shown on the site.",
"medias": [],
"additional": [
{
"title": "Example",
"option": "example",
"_id": "6543210fedcba98765432100"
}
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}A picture 1920px wide. Resized on the fly and cached for an hour; 404 when there is no such media.
Public - no token needed.
The ID of the medias large.
curl -X GET 'http://hristovtintdetailng.com/medias-large/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A picture for a map marker, resized (?size). Cached for an hour.
Public - no token needed.
The ID of the medias marker.
Only medias markers with this size.
curl -X GET 'http://hristovtintdetailng.com/medias-marker/{id}?ionic=true&size=...'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A picture 1280px wide. Resized on the fly and cached for an hour; 404 when there is no such media.
Public - no token needed.
The ID of the medias medium.
curl -X GET 'http://hristovtintdetailng.com/medias-medium/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Get a Media object. The media record without its file. 404 "not found".
Needs the token of a signed-in user.
The ID of the medias object.
curl -X GET 'http://hristovtintdetailng.com/medias-object/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A picture as a JPEG sized for link previews (Open Graph). 1200×630; a GIF is sent as its first frame, since link previews do not play GIFs.
Public - no token needed.
The ID of the medias og.
curl -X GET 'http://hristovtintdetailng.com/medias-og/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A picture sized for its column. 1280px wide by default; ?size scales it to the column's width (up to 2560px). Resized on the fly and cached for an hour; 404 when there is no such media.
Public - no token needed.
The ID of the medias responsive.
Only medias responsives with this size.
Only medias responsives with this is fluid.
curl -X GET 'http://hristovtintdetailng.com/medias-responsive/{id}?ionic=true&size=...&isFluid=...'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}How much storage the site's media uses. Answers the total size of the site's stored files.
Needs the token of a signed-in user.
curl -X GET 'http://hristovtintdetailng.com/medias-storage?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
A picture 400px wide, as a thumbnail. Resized on the fly and cached for an hour; 404 when there is no such media.
Public - no token needed.
The ID of the medias thumbnail.
curl -X GET 'http://hristovtintdetailng.com/medias-thumbnail/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A picture 2560px wide. At quality 85. Product answers link their pictures here. Resized on the fly and cached for an hour; 404 when there is no such media.
Public - no token needed.
The ID of the medias xlarge.
curl -X GET 'http://hristovtintdetailng.com/medias-xlarge/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A picture 860px wide. The default size for pictures in pages. Resized on the fly and cached for an hour; 404 when there is no such media.
Public - no token needed.
The ID of the media.
Returns the Media object.
curl -X GET 'http://hristovtintdetailng.com/medias/{id}?ionic=true'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Updates a media record. 404 when there is no such media.
Needs the token of a signed-in user.
The ID of the media.
Img alt (same as filename if not specified).
Name of the stored file.
Small preview of the file.
Returns the Media object.
curl -X PATCH 'http://hristovtintdetailng.com/medias/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "alt": "...", "filename": "...", "thumbnail": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Deletes a media record. Also deletes the stored file. 401 when the media belongs to another user. Records that still use it keep its id.
Needs the token of a signed-in user.
The ID of the media.
Returns an empty answer on success.
curl -X DELETE 'http://hristovtintdetailng.com/medias/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'The installable app's icon, resized (?size); ?media_id for another picture. Falls back to the site's logo when the app has no icon of its own. Cached for 6 minutes.
Public - no token needed.
Only app logos with this media id.
Only app logos with this size.
curl -X GET 'http://hristovtintdetailng.com/pwa-logo?ionic=true&media_id=...&size=...'
{
"name": "Example",
"short_name": "Example",
"logo": "6543210fedcba98765432100",
"background_color": "#3557c4",
"description": "Text shown on the site.",
"screenshots": [
{
"media": "6543210fedcba98765432100",
"is_mobile_preview": false,
"_id": "6543210fedcba98765432100"
}
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}A picture resized for the installable app (?size_x, ?size_y). Answers the image bytes, or 404.
Public - no token needed.
The ID of the app media.
Only app medias with this size x.
Only app medias with this size y.
Returns the Media object.
curl -X GET 'http://hristovtintdetailng.com/pwa-media/{id}?ionic=true&size_x=...&size_y=...'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}A ticket's QR code as a PNG. 404 when there is no such ticket.
Public - no token needed.
The ID of the QR code code media.
curl -X GET 'http://hristovtintdetailng.com/qr-code-medias/{id}?ionic=true'{
"event": "6543210fedcba98765432100",
"date": 1,
"section": 1,
"subsection": 1,
"row": 1,
"seat": 1,
"row_index_formated": 1,
"seat_index_formated": 1,
"lead_id": "6543210fedcba98765432100",
"socket_id": "example",
"status": "frozen",
"expiration_time": "2026-11-04T12:00:00.000Z",
"qr_code": "6543210fedcba98765432100",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z",
"tier": {
"name": "Example",
"price": 0
}
}Deletes one transcoded quality of a video (media_id, transcode). Answers { media }.
Needs the token of a signed-in user.
The remove media quality's media id.
The remove media quality's transcode.
curl -X PATCH 'http://hristovtintdetailng.com/remove-media-quality?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "media_id": "...", "transcode": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}Deletes a file (file) from the site's cloud storage. Only inside the site's own folder.
Needs the token of a signed-in user.
The storage file's file.
curl -X PATCH 'http://hristovtintdetailng.com/storage-file?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "file": "..." }'Files and folders in the site's cloud storage under ?folder_path. Only the site's own folder: a path cannot reach another site's files.
Needs a site admin token.
Only storage files with this folder path.
curl -X GET 'http://hristovtintdetailng.com/storage-files?ionic=true&folder_path=...' \ -H 'Authorization: Bearer <TOKEN>'
The files served at the site's root (verification files and the like). Answers an array, newest first.
Needs a site admin token.
Returns a list of FileRoute objects.
curl -X GET 'http://hristovtintdetailng.com/file-routes?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
[
{
"url": "example-item",
"content_type": "Text shown on the site.",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}
]Creates a root file route. The file must already be in the site's cloud storage (gcs_key) and be at most 2MB; url is the root path it is served at. Answers 201 { id }.
Needs a site admin token.
The file route's URL slug, as in its address on the site.
Optional content type override.
Returns the FileRoute object.
curl -X POST 'http://hristovtintdetailng.com/file-routes?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "url": "...", "content_type": "..." }'{
"url": "example-item",
"content_type": "Text shown on the site.",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Updates a root file route. The same checks as creating one. 404 when there is no such route.
Needs a site admin token.
The ID of the file route.
The file route's URL slug, as in its address on the site.
Optional content type override.
Returns the FileRoute object.
curl -X PATCH 'http://hristovtintdetailng.com/file-routes/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "url": "...", "content_type": "..." }'{
"url": "example-item",
"content_type": "Text shown on the site.",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Deletes a root file route. Answers the deleted record, or 404. Records that point to it are not changed.
Needs a site admin token.
The ID of the file route.
Returns an empty answer on success.
curl -X DELETE 'http://hristovtintdetailng.com/file-routes/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'Ticket QR codes. Answers an array of every record.
Needs a site admin token.
curl -X GET 'http://hristovtintdetailng.com/qr-code?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
Creates a ticket QR code. Answers 201 with no body.
Needs a site admin token.
curl -X POST 'http://hristovtintdetailng.com/qr-code?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
{
"ticket": "6543210fedcba98765432100",
"status": "used",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}One ticket QR code. 404 when there is no such record.
Needs a site admin token.
The ID of the QR code code.
curl -X GET 'http://hristovtintdetailng.com/qr-code/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'{
"ticket": "6543210fedcba98765432100",
"status": "used",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Updates an alert. Fields outside the allowed list are silently ignored. Answers the updated record, or 404.
Needs a site admin token.
The ID of the QR code code.
curl -X PATCH 'http://hristovtintdetailng.com/qr-code/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'{
"ticket": "6543210fedcba98765432100",
"status": "used",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}One video's page with its comments and the rest of its playlist. 404 "Not found.". Answers { video, videos, collection } with ?ionic.
Works without a token; with a user token the answer is personal.
The ID of the single video.
Returns the Video object.
curl -X GET 'http://hristovtintdetailng.com/single-video/{id}?ionic=true'{
"name": "Example",
"link": "example-item",
"collection_id": "6543210fedcba98765432100",
"media_id": "6543210fedcba98765432100",
"selected": false,
"custom_1": "example",
"custom_2": "example",
"custom_3": "example",
"suitability_price_plans": [
"6543210fedcba98765432101"
],
"isSuitable": false,
"views": [
"6543210fedcba98765432101"
],
"total_views": 0,
"times_showed": 0,
"owner_id": "6543210fedcba98765432100",
"requiresLogin": false,
"requiresSubscription": false,
"price_plan_ids": [
"example"
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}The videos page, or the videos as JSON with ?ionic: filtered by playlist and published state, and sorted. Paged with ?skip, filtered by ?collection and ?published; ?sortBy sets the order.
Needs a signed-in user whose plan grants access.
Only videos with this published.
The order of the results.
Only results in this collection.
Returns a list of Video objects.
curl -X GET 'http://hristovtintdetailng.com/videos?ionic=true&published=...&sortBy=...&collection=...' \ -H 'Authorization: Bearer <TOKEN>'
[
{
"name": "Example",
"link": "example-item",
"collection_id": "6543210fedcba98765432100",
"media_id": "6543210fedcba98765432100",
"selected": false,
"custom_1": "example",
"custom_2": "example",
"custom_3": "example",
"suitability_price_plans": [
"6543210fedcba98765432101"
],
"isSuitable": false,
"views": [
"6543210fedcba98765432101"
],
"total_views": 0,
"times_showed": 0,
"owner_id": "6543210fedcba98765432100",
"requiresLogin": false,
"requiresSubscription": false,
"price_plan_ids": [
"example"
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}
]Creates a video. Answers 201 and re-renders the home page.
Needs the token of a signed-in user.
Returns the Video object.
curl -X POST 'http://hristovtintdetailng.com/videos?ionic=true' \ -H 'Authorization: Bearer <TOKEN>'
{
"name": "Example",
"link": "example-item",
"collection_id": "6543210fedcba98765432100",
"media_id": "6543210fedcba98765432100",
"selected": false,
"custom_1": "example",
"custom_2": "example",
"custom_3": "example",
"suitability_price_plans": [
"6543210fedcba98765432101"
],
"isSuitable": false,
"views": [
"6543210fedcba98765432101"
],
"total_views": 0,
"times_showed": 0,
"owner_id": "6543210fedcba98765432100",
"requiresLogin": false,
"requiresSubscription": false,
"price_plan_ids": [
"example"
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Deletes several videos, ids comma-separated. Answers the ids that were deleted.
Needs the token of a signed-in user.
The video's delete ids.
Returns an empty answer on success.
curl -X DELETE 'http://hristovtintdetailng.com/videos-multiple/{delete_ids}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'Applies the same changes (updates) to several videos, ids comma-separated. Answers the ids that were changed.
Needs the token of a signed-in user.
The video's patch ids.
Collection.id.
The video's updates.
Returns the Video object.
curl -X PATCH 'http://hristovtintdetailng.com/videos-multiple/{patch_ids}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "collection_id": "...", "updates": "..." }'{
"name": "Example",
"link": "example-item",
"collection_id": "6543210fedcba98765432100",
"media_id": "6543210fedcba98765432100",
"selected": false,
"custom_1": "example",
"custom_2": "example",
"custom_3": "example",
"suitability_price_plans": [
"6543210fedcba98765432101"
],
"isSuitable": false,
"views": [
"6543210fedcba98765432101"
],
"total_views": 0,
"times_showed": 0,
"owner_id": "6543210fedcba98765432100",
"requiresLogin": false,
"requiresSubscription": false,
"price_plan_ids": [
"example"
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}A playlist's page with its videos. 404 when there is no such playlist. JSON with ?ionic.
Works without a token; with a user token the answer is personal.
The ID of the video.
Returns the Video object.
curl -X GET 'http://hristovtintdetailng.com/videos/{id}?ionic=true'{
"name": "Example",
"link": "example-item",
"collection_id": "6543210fedcba98765432100",
"media_id": "6543210fedcba98765432100",
"selected": false,
"custom_1": "example",
"custom_2": "example",
"custom_3": "example",
"suitability_price_plans": [
"6543210fedcba98765432101"
],
"isSuitable": false,
"views": [
"6543210fedcba98765432101"
],
"total_views": 0,
"times_showed": 0,
"owner_id": "6543210fedcba98765432100",
"requiresLogin": false,
"requiresSubscription": false,
"price_plan_ids": [
"example"
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Updates a video. Fields outside the allowed list are silently ignored. Answers the updated record, or 404.
Needs the token of a signed-in user.
The ID of the video.
Returns the Video object.
curl -X PATCH 'http://hristovtintdetailng.com/videos/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'{
"name": "Example",
"link": "example-item",
"collection_id": "6543210fedcba98765432100",
"media_id": "6543210fedcba98765432100",
"selected": false,
"custom_1": "example",
"custom_2": "example",
"custom_3": "example",
"suitability_price_plans": [
"6543210fedcba98765432101"
],
"isSuitable": false,
"views": [
"6543210fedcba98765432101"
],
"total_views": 0,
"times_showed": 0,
"owner_id": "6543210fedcba98765432100",
"requiresLogin": false,
"requiresSubscription": false,
"price_plan_ids": [
"example"
],
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}Deletes a video. Answers the deleted record, or 404. Records that point to it are not changed.
Needs the token of a signed-in user.
The ID of the video.
Returns an empty answer on success.
curl -X DELETE 'http://hristovtintdetailng.com/videos/{id}?ionic=true' \
-H 'Authorization: Bearer <TOKEN>'The playlists page. 404 when there are no playlists.
Works without a token; with a user token the answer is personal.
curl -X GET 'http://hristovtintdetailng.com/videos/playlists?ionic=true'
{
"name": "Example",
"parent_collection": "6543210fedcba98765432100",
"picture": "6543210fedcba98765432100",
"about_page": "6543210fedcba98765432100",
"match_to_option": false,
"is_color": false,
"color": "#3557c4",
"position": 1,
"items": [
"6543210fedcba98765432101"
],
"thumbnail": "6543210fedcba98765432100",
"_id": "6543210fedcba98765432100"
}Creates a video watch record. Records a stretch of watching (start, end); it feeds the long-video insights. Answers 201.
Needs the token of a signed-in user.
User.id.
Returns the VideoInteraction object.
curl -X POST 'http://hristovtintdetailng.com/video-interaction?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "video_viewer": "..." }'{
"start": 1,
"end": 1,
"watch_time": 1,
"video_viewer": "6543210fedcba98765432100",
"video_id": "6543210fedcba98765432100",
"video_owner": "6543210fedcba98765432100",
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z"
}AI: generates a picture from the owner's prompt, stores it in the media library and charges its credits. Answers { action: 'JOB', async_job } at once; the admin polls GET /async-jobs/:id, and the result arrives in the chat as a message when the job ends. The AI work is charged to the account's credits.
Needs a site admin token.
What the AI should do with the image, in plain words - any language.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
Which version of the AI builder to use; leave it out for the current one.
curl -X POST 'http://hristovtintdetailng.com/create-new-image?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "chatId": "...", "aiVersion": "..." }'{
"chat_id": "6543210fedcba98765432100",
"role": "user",
"text": "Text shown on the site.",
"target_url": "example-item",
"action": "RESPONSE",
"options": [
"example"
],
"medias": [
{
"media": "6543210fedcba98765432100",
"gcs_url": "example-item",
"gemini_uri": "example",
"gemini_interaction_id": "example",
"_id": "6543210fedcba98765432100"
}
],
"products": [
"6543210fedcba98765432101"
],
"services": [
"6543210fedcba98765432101"
],
"blogposts": [
"6543210fedcba98765432101"
],
"programs": [
"6543210fedcba98765432101"
],
"suggestions": [
{
"text": "Text shown on the site.",
"route": "example",
"item_id": "6543210fedcba98765432100",
"medias": [],
"picture": "6543210fedcba98765432100",
"_id": "6543210fedcba98765432100"
}
],
"is_system": false,
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z",
"data": {
"object": "example",
"object_type": "example",
"edit_summary": "example",
"edit_diff": "example",
"undo_record": "example",
"hero_animation_offer": "example",
"preview_state": "example",
"pending_credit_cost": 0,
"target_restore": "example",
"media_request": "example",
"item_request": "example",
"reference_request": "example"
}
}AI: generates a video from text, a picture or an earlier video, as a background job. Answers { action: 'JOB', async_job } at once; the admin polls GET /async-jobs/:id, and the result arrives in the chat as a message when the job ends. The AI work is charged to the account's credits.
Needs a site admin token.
The video's duration.
What the AI should do with the video, in plain words - any language.
The video's media ids.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
The video's aspect ratio.
Which version of the AI builder to use; leave it out for the current one.
curl -X POST 'http://hristovtintdetailng.com/create-new-video?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "duration": "...", "prompt": "...", "mediaIds": "...", "chatId": "...", "aspect_ratio": "..." }'{
"chat_id": "6543210fedcba98765432100",
"role": "user",
"text": "Text shown on the site.",
"target_url": "example-item",
"action": "RESPONSE",
"options": [
"example"
],
"medias": [
{
"media": "6543210fedcba98765432100",
"gcs_url": "example-item",
"gemini_uri": "example",
"gemini_interaction_id": "example",
"_id": "6543210fedcba98765432100"
}
],
"products": [
"6543210fedcba98765432101"
],
"services": [
"6543210fedcba98765432101"
],
"blogposts": [
"6543210fedcba98765432101"
],
"programs": [
"6543210fedcba98765432101"
],
"suggestions": [
{
"text": "Text shown on the site.",
"route": "example",
"item_id": "6543210fedcba98765432100",
"medias": [],
"picture": "6543210fedcba98765432100",
"_id": "6543210fedcba98765432100"
}
],
"is_system": false,
"_id": "6543210fedcba98765432100",
"updatedAt": "2026-11-04T12:00:00.000Z",
"createdAt": "2026-11-04T12:00:00.000Z",
"data": {
"object": "example",
"object_type": "example",
"edit_summary": "example",
"edit_diff": "example",
"undo_record": "example",
"hero_animation_offer": "example",
"preview_state": "example",
"pending_credit_cost": 0,
"target_restore": "example",
"media_request": "example",
"item_request": "example",
"reference_request": "example"
}
}AI: routes a request for a new picture to create-new-image. Does no AI work itself: answers { action: 'REDIRECT', target_url, response } and the chat client calls target_url next with response as the prompt.
Needs a site admin token.
What the AI should do with the image, in plain words - any language.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
curl -X POST 'http://hristovtintdetailng.com/generate-image?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "chatId": "..." }'AI: routes a request for a video from a picture to create-new-video. Does no AI work itself: answers { action: 'REDIRECT', target_url, response } and the chat client calls target_url next with response as the prompt.
Needs a site admin token.
What the AI should do with the image to video, in plain words - any language.
The image to video's aspect ratio.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
curl -X POST 'http://hristovtintdetailng.com/generate-image-to-video?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "aspect_ratio": "...", "chatId": "..." }'AI: routes a request for a video from text to create-new-video, if the account has credits. Does no AI work itself: answers { action: 'REDIRECT', target_url, response } and the chat client calls target_url next with response as the prompt.
Needs a site admin token.
What the AI should do with the text to video, in plain words - any language.
The text to video's aspect ratio.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
curl -X POST 'http://hristovtintdetailng.com/generate-text-to-video?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "aspect_ratio": "...", "chatId": "..." }'AI: routes a change to a video to create-new-video. Does no AI work itself: answers { action: 'REDIRECT', target_url, response } and the chat client calls target_url next with response as the prompt.
Needs a site admin token.
What the AI should do with the video to video, in plain words - any language.
The video to video's aspect ratio.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
curl -X POST 'http://hristovtintdetailng.com/generate-video-to-video?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "aspect_ratio": "...", "chatId": "..." }'AI: routes a change to a picture the AI made to update-image. Does no AI work itself: answers { action: 'REDIRECT', target_url, response } and the chat client calls target_url next with response as the prompt.
Needs a site admin token.
What the AI should do with the AI image, in plain words - any language.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
curl -X POST 'http://hristovtintdetailng.com/modify-ai-image?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "chatId": "..." }'AI: routes a change to a picture to update-image. Does no AI work itself: answers { action: 'REDIRECT', target_url, response } and the chat client calls target_url next with response as the prompt.
Needs a site admin token.
What the AI should do with the AI user image, in plain words - any language.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
curl -X POST 'http://hristovtintdetailng.com/modify-ai-user-image?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "chatId": "..." }'AI: routes a change to one of the owner's pictures to update-image. Does no AI work itself: answers { action: 'REDIRECT', target_url, response } and the chat client calls target_url next with response as the prompt.
Needs a site admin token.
What the AI should do with the user image, in plain words - any language.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
curl -X POST 'http://hristovtintdetailng.com/modify-user-image?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "chatId": "..." }'AI: edits an existing picture as the owner asked and stores the result. Answers { action: 'JOB', async_job } at once; the admin polls GET /async-jobs/:id, and the result arrives in the chat as a message when the job ends. The AI work is charged to the account's credits.
Needs a site admin token.
What the AI should do with the image, in plain words - any language.
The AI chat this request belongs to; its history and language carry over. Leave it out to start a new chat.
The image's media ids.
Which version of the AI builder to use; leave it out for the current one.
curl -X POST 'http://hristovtintdetailng.com/update-image?ionic=true' \
-H 'Authorization: Bearer <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{ "prompt": "...", "chatId": "...", "mediaIds": "...", "aiVersion": "..." }'{
"file": "example",
"file_path": "example",
"alt": "example",
"filename": "Example",
"filetype": "example",
"vimeo_uri": "example",
"vimeo_picture": "example",
"duration": 1,
"vimeo_url": "example-item",
"youtube_url": "example-item",
"youtube_picture": "example",
"thumbnail": "example",
"gcs_url": "example-item",
"gcs_480_30_url": "example-item",
"gcs_720_30_url": "example-item",
"gcs_1080_30_url": "example-item",
"picture_gcs_url": "example-item",
"transcode_status": "not_started",
"owner_id": "6543210fedcba98765432100",
"source_url": "example-item",
"source_framing": "example",
"origin": "example",
"width": 1,
"height": 1,
"sequence": {
"status": "example",
"started_at": "example",
"updated_at": "example",
"step": "example",
"done": 0,
"total": 0,
"ext": "example",
"trim_start": 0,
"trim_end": 0,
"build_id": "example",
"previous_base": "example",
"frame_count": 0
}
}