API Docs/DeArrow
The DeArrow API is free to use for all non browser-extensions
If you end up using the API, I'd love to know about how you're using it. Tell me about it by making a GitHub issue or emailing me :)
The API and database follow this license unless you have explicit permission. Attribution Template
Public API available at https://sponsor.ajay.app.
Database download: https://sponsor.ajay.app/database
Database Mirror (30 min update time, provided by Lartza): https://sb.ltn.fi/database/
Database Mirror (10 min update time, provided by blab): https://mirror.sb.mchang.xyz/
Database Mirror (90 min update time, provided by mini_bomba): https://sb.minibomba.pro/mirror/
Note: Database mirrors listed above do NOT provide an API for the extensions. Setting the server address to any of these URLs will result in no segments or video details being shown.
GET /api/branding
Get submission for a video.
Note: Data is returned ordered. You can use the first element. However, you should make sure the first element has either locked = true or votes >= 0. If not, it is considered untrusted and is only to be shown in the voting box until it has been confirmed by another user.
Random time and video duration are used if you want to fallback thumbnails to a screenshot from a random time. To make thumbnail caching possible, this random time is consistent and produced by the server. The random time value is a number between 0 and 1 and must be multiplied by the video duration. For convenience, the API returns the video duration if it is known, but for most videos the server does not know the video duration. When the API returns a video duration of 0 or null, you must either not use this feature, or obtain the video duration using another method. The browser extension will fallback to fetching the video duration using other methods to always be able to use the feature.
Input (URL Parameters):
{
videoID: string,
service: string, // Optional, default is 'YouTube' [1]
returnUserID: boolean // optional, returns submitter userIDs if true, default false
}
References: [1] Response:
{
titles: Array<{
title: string,
original: boolean,
votes: number
locked: true
UUID: string
}>:
thumbnails: Array<{
timestamp: number, // Missing if original is true
original: boolean,
votes: number
locked: true
UUID: string
}>
randomTime: number,
videoDuration: number | null
}
Error codes:
400: Bad Request (Your inputs are wrong/impossible)
404: Not Found
GET /api/branding/:sha256HashPrefix
Get submissions for a video.
sha256HashPrefix
is a hash of the YouTube videoID
. It should be the first 4 characters. This provides extra privacy by potentially finding more than just the video you are looking for since the server will not know exactly what video you are looking for.
Note: Data is returned ordered. You can use the first element. However, you should make sure the first element has either locked = true or votes >= 0. If not, it is considered untrusted and is only to be shown in the voting box until it has been confirmed by another user.
Random time and video duration are used if you want to fallback thumbnails to a screenshot from a random time. To make thumbnail caching possible, this random time is consistent and produced by the server. The random time value is a number between 0 and 1 and must be multiplied by the video duration. For convenience, the API returns the video duration if it is known, but for most videos the server does not know the video duration. When the API returns a video duration of 0 or null, you must either not use this feature, or obtain the video duration using another method. The browser extension will fallback to fetching the video duration using other methods to always be able to use the feature.
Input (URL Parameters):
{
service: string // Optional, default is 'YouTube'. [1]
}
References: [1] Response
{
[videoID: string]: {
titles: Array<{
title: string,
original: boolean,
votes: number
locked: true
UUID: string
}>:
thumbnails: Array<{
timestamp: number, // Missing if original is true
original: boolean,
votes: number
locked: true
UUID: string
}>,
randomTime: number,
videoDuration: number | null
}
}
Error codes:
400: Bad Request (Your inputs are wrong/impossible)
404: Not Found
POST /api/branding
Create a submission on a video. If a duplicate submission exists, it votes on that submission.
Input (JSON Body):
{
videoID: string,
userID: string, // This should be a randomly generated UUID stored locally (not the public one)
userAgent: string, // "Name of Client/Version" or "[BOT] Name of Bot/Version" ex. "Chromium/1.0.0"
service: string, // Optional, default is 'YouTube'. [1]
title: { // Optional, you can submit either just a title, or just a thumbnail, or both
title: string,
},
thumbnail: {
timestamp: number, // Optional if original is true
original: boolean
},
}
References: [1]
Error codes:
400: Bad Request (Your inputs are wrong/impossible)
Generating a thumbnail from a timestamp
Generating thumbnails is handled by a different service. This service will generate thumbnails, and cache them for future users. It is not guaranteed to return, and uses a queuing system. The browser extension uses a fallback local rendering system to handle this, and will render it locally when the server is not able to. It does this by taking a screenshot a video element.
This service is state-less, so can easily be self-hosted without having to sync submissions from the main server.
The main instance is hosted at https://dearrow-thumb.ajay.app
The basic endpoint is as follows
GET /api/v1/getThumbnail
Get submissions for a video.
Note: Data is returned ordered. You can use the first element. However, you should make sure the first element has either locked = true or votes >= 0. If not, it is considered untrusted and is only to be shown in the voting box until it has been confirmed by another user.
Input (URL Parameters):
{
videoID: string,
time: number
}
References: [1]
Response:
A binary image response.
Response codes (PLEASE READ):
200: Ok
204: No content, failed to generate, or chose not to generate
Speeding up requests
You can speed up requests by making a request to getThumbnail
at the same time as a request to branding, but without providing a value in the time
field. The server will respond with an image if it has one. Once both requests are done, you then have to make sure the thumbnail is for the correct timestamps.
You need to check the X-Timestamp
header and verify it is the same as the branding response. If it is not, then you must make a second request with the new time.
There also is a X-Title
header that is used by the extension as a fallback in the result that the main server goes down.