Difference between revisions of "API Docs/Draft"

From SponsorBlock
Jump to navigation Jump to search
(Add segmentShift)
Line 1: Line 1:
<!-- Formatting Notes:
userID instead of user ID
leave a space after the start of the comment,
public userID & local userID -->
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 :)
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 :)


Line 22: Line 27:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   videoID: string,
   videoID: string, // ID of video to pull segments for
   category: string, // Optional, defaults to "sponsor", can be repeated for multiple categories.
   category: string, // Optional, defaults to "sponsor", can be repeated for multiple categories.
     // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
     // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
Line 50: Line 55:
-----
-----
====='''GET''' <code>/api/skipSegments/:sha256HashPrefix</code>=====
====='''GET''' <code>/api/skipSegments/:sha256HashPrefix</code>=====
Get segments for a video with anonymity
Get segments for a video with extra privacy


<code>sha256HashPrefix</code> is a hash of the YouTube <code>videoID</code>. It should be the first 4 - 32 characters (4 is recommended). This provides extra privacy by potentially finding more than just the video you are looking for. This makes the server not know exactly what video you are looking for.
<code>sha256HashPrefix</code> is a hash of the YouTube <code>videoID</code>. It should be the first 4 - 32 characters (4 is recommended). This provides extra privacy by potentially finding more than just the video you are looking for. This makes the server not know exactly what video you are looking for.
Line 58: Line 63:
{
{
   category: string, // Optional, defaults to "sponsor", can be repeated for multiple categories.
   category: string, // Optional, defaults to "sponsor", can be repeated for multiple categories.
  categories: string[], // Optional, use this instead of "category" if you want multiple categories. Will look like ["sponsor","intro"]
   // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
  categories: string[], // Optional, use this instead of "category" if you want multiple categories. Will look like ["sponsor","intro"]


   requiredSegments: string[], // Optional, list of segment UUIDs to require be retrieved, even if they don't meet the minimum vote threshold, can be replaced with "requiredSegment" and repeated for multiple segments like category.
   requiredSegments: string[], // Optional, list of segment UUIDs to require be retrieved, even if they don't meet the minimum vote threshold, can be replaced with "requiredSegment" and repeated for multiple segments like category.


   service: string // Optional, default is 'YouTube'. See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
   service: string // Optional, default is 'YouTube'.
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 70: Line 76:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
[{ // Array of this object
[{ // Array of this object
   "videoID": string,
   videoID: string,
   "hash": string, // The full hash
   hash: string, // Full hash of the video ID
   "segments": [{ // Array of this object
   segments: [{ // Array of this object
       segment: float[], //[0, 15.23] start and end time in seconds
       segment: float[], // [0, 15.23] start and end time in seconds
       UUID: string,
       UUID: string,
       category: string
       category: string
Line 95: Line 101:
   endTime: float,
   endTime: float,
   category: string,
   category: string,
   userID: string, //This should be a randomly generated UUID stored locally (not the public one)
   userID: string, // This should be a randomly generated UUID stored locally (not the public one)
   userAgent: string, // "Name of Client" or "[BOT] Name of Bot"
   userAgent: string, // "Name of Client" or "[BOT] Name of Bot" ex. MeaBot/1.0.0
 
   service: string, // Optional, default is 'YouTube'.
   service: string, // Optional, default is 'YouTube'. See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
   videoDuration: float, // Optional, duration of video, will attempt to retrieve from the YouTube API if missing (to be used to determine when a submission is out of date)
   videoDuration: float, // Optional, duration of video, will attempt to retrieve from the YouTube API if missing (to be used to determine when a submission is out of date)
}
}
Line 110: Line 116:
   videoID: string,
   videoID: string,
   userID: string, // This should be a randomly generated UUID stored locally (not the public one)
   userID: string, // This should be a randomly generated UUID stored locally (not the public one)
   userAgent: string, // "Name of Client" or "[BOT] Name of Bot"
   userAgent: string, // "Name of Client" or "[BOT] Name of Bot" ex. MeaBot/1.0.0
 
   service: string, // Optional, default is 'YouTube'.
   service: string, // Optional, default is 'YouTube'. See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
   videoDuration: float, // Optional, duration of video, will attempt to retrieve from the YouTube API if missing (to be used to determine when a submission is out of date)
   videoDuration: float, // Optional, duration of video, will attempt to retrieve from the YouTube API if missing (to be used to determine when a submission is out of date)


Line 141: Line 147:
====='''POST''' <code>/api/voteOnSponsorTime</code>=====
====='''POST''' <code>/api/voteOnSponsorTime</code>=====
Vote on a segment or vote to change the category of the segment.
Vote on a segment or vote to change the category of the segment.
Creators of the segment and VIPs can remove the segment or change the category with only one vote.


'''Input: Normal Vote''' (URL Parameters):
'''Input: Normal Vote''' (URL Parameters):
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   UUID: string, //id of the sponsor being voted on
   UUID: string, // UUID of the segment being voted on
   userID: string, //the local user id
   userID: string, // Local userID
   type: int //0 for downvote, 1 for upvote
   type: int // 0 for downvote, 1 for upvote
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 156: Line 164:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   UUID: string, //id of the sponsor being voted on
   UUID: string, // UUID of the segment being voted on
   userID: string, //the local user id
   userID: string, // Local userID
   category: string //the name of the category to change this submission to
   category: string // Category to change this submission to
} </syntaxhighlight>
} </syntaxhighlight>


Line 180: Line 188:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   UUID: string
   UUID: string // UUID of segment viewed
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 201: Line 209:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string //the local user id
   userID: string // local UserID - optional if publicUserID is specified
   value: Values to get from userInfo // optional
  publicUserID: string // Public userID - optional if userID is specified
 
   value: string[] // Values to get from userInfo - optional
   // default values are:
   // default values are:
   // ["userID", "userName", "minutesSaved", "segmentCount", "ignoredSegmentCount",
   // ["userID", "userName", "minutesSaved", "segmentCount", "ignoredSegmentCount",
Line 209: Line 219:
}
}
</syntaxhighlight>
</syntaxhighlight>
'''OR'''
<syntaxhighlight lang="ts">
{
  publicUserID: string
  value: Values to get from userInfo // optional
  // default values are:
  // ["userID", "userName", "minutesSaved", "segmentCount", "ignoredSegmentCount",
  // "viewCount", "ignoredViewCount", "warnings", "warningReason", "reputation",
  // "vip", "lastSegmentID"]
}
</syntaxhighlight>
'''Response''':
'''Response''':
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string, // the public user ID
   userID: string, // Public userID
   userName: string,
   userName: string, // Public userID if not set
   minutesSaved: float,
   minutesSaved: float, // Minutes saved
   segmentCount: int,
   segmentCount: int, // Total number of segments excluding ignored/ hidden segments
   ignoredSegmentCount: int,
   ignoredSegmentCount: int, // Total number of ignored/ hidden segments
   viewCount: int,
   viewCount: int, // Total number of views excluding view on ignored/ hidden segments
   ignoredViewCount: int,
   ignoredViewCount: int, // Total number of view on ignored/ hidden segments
   warnings: int,
   warnings: int, // Currently enabled warnings
   reputation: float,
   reputation: float,  
   vip: boolean,
   vip: boolean, // VIP status
   lastSegmentID: string
   lastSegmentID: string // UUID of last submitted segment
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 248: Line 246:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string //the local user id
   userID: string // Local userID
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 269: Line 267:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string //the local user id
   userID: string // Local userID
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 276: Line 274:
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
{
{
   timeSaved: float //in minutes
   timeSaved: float // In minutes
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 290: Line 288:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string, //local user id
   userID: string, // Local userID
   username: string, //optional
   username: string, // Optional
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 301: Line 299:
'''''Admin Only'''''<syntaxhighlight lang="ts">
'''''Admin Only'''''<syntaxhighlight lang="ts">
{
{
   userID: string, //public user id
   userID: string, // Public userID
   username: string, //optional
   username: string, // Optional
   adminUserID: string //admin local user id
   adminUserID: string // Admin's local userID
}
}
</syntaxhighlight>'''Response''':
</syntaxhighlight>'''Response''':
Line 324: Line 322:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string //the local user id
   userID: string // Local userID
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 331: Line 329:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userName: string //will send back hashed userID if no username has been set
   userName: string // Public userID if no username has been set
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 357: Line 355:
   endTime: fload,
   endTime: fload,
   votes: int,
   votes: int,
   locked: int,
   locked: int, // Status of lock - If upvoted by a VIP, the segment is locked
   UUID: string,
   UUID: string,
   userID: string,
   userID: string, // PublicID of submitted
   timeSubmitted: int,
   timeSubmitted: int,
   views: int,
   views: int, // Number of reported views on the segment
   category: string,
   category: string, // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   service: string,
   service: string, // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
   videoDuration: int,
   videoDuration: int,
   hidden: int,
   hidden: int, // If the segment has 2 downvotes or was downvoted by a VIP
   reputation: int,
   reputation: int, // Reputation of submitter at time of submission
   shadowHidden: int,
   shadowHidden: int, // If the submitter is shadowbanned
   userAgent: string
   userAgent: string // userAgent of the submitter
}]
}]
</syntaxhighlight>
</syntaxhighlight>
Line 420: Line 418:
   categories: string[],
   categories: string[],
   // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   reason: string
   reason: string // Specified reason for the lock
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 431: Line 429:
-----
-----
====='''GET''' <code>/api/lockCategories/:sha256HashPrefix</code>=====
====='''GET''' <code>/api/lockCategories/:sha256HashPrefix</code>=====
Get locked caterogies for video anonymously
Get locked categories for a video with extra privacy


<code>sha256HashPrefix</code> is a hash of the YouTube <code>videoID</code>. It should be the first 4 - 32 characters (4 is recommended). This provides extra privacy by potentially finding more than just the video you are looking for. This makes the server not know exactly what video you are looking for.
<code>sha256HashPrefix</code> is a hash of the YouTube <code>videoID</code>. It should be the first 4 - 32 characters (4 is recommended). This provides extra privacy by potentially finding more than just the video you are looking for. This makes the server not know exactly what video you are looking for.
Line 438: Line 436:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   "prefix": sha256HashPrefix // optional if not sent through path
   prefix: sha256HashPrefix // Optional if not sent through path
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 445: Line 443:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
[{ // Array of this object
[{ // Array of this object
   "videoID": string,
   videoID: string,
   "hash": string, // The full hash
   hash: string, // The full hash of the videoID
   "categories": string[],
   categories": string[],
   // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   "reason": string
   reason: string // Specified reason for the lock
}]
}]
</syntaxhighlight>
</syntaxhighlight>
Line 466: Line 464:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   sortType: int //0 for by minutes saved, 1 for by view count, 2 for by total submissions
   sortType: int
  // 0 for by minutes saved
  // 1 for by view count
  // 2 for by total submissions
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 491: Line 492:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   "countContributingUsers": boolean //Optional, default false
   "countContributingUsers": boolean // Optional, default false
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 547: Line 548:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   hashedUserID: string,
   hashedUserID: string, // public userID
   vip: boolean
   vip: boolean // VIP status
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 557: Line 558:
-----
-----
====='''POST''' <code>/api/lockCategories</code>=====
====='''POST''' <code>/api/lockCategories</code>=====
Will block new segment submissions of the specified category on that video.
Create a category lock on the video, disallowing further submissions for that category


'''Input''' (Request Body):
'''Input''' (Request Body):
Line 564: Line 565:
   videoID: string,
   videoID: string,
   userID: string,
   userID: string,
   categories: string[],
   categories: string[], // Categories to lock
   reason: string
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   reason: string // Reason for lock
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 583: Line 585:
-----
-----
====='''DELETE''' <code>/api/lockCategories</code>=====
====='''DELETE''' <code>/api/lockCategories</code>=====
Will delete existing locked categories on that video
Delete existing category locks on that video


'''Input''' (Request Body):
'''Input''' (Request Body):
Line 590: Line 592:
   videoID: string,
   videoID: string,
   userID: string,
   userID: string,
   categories: string[]
   categories: string[] // Categories to remove locks for
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 613: Line 616:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string, //public userID of the user you want to shadowBan
   userID: string, // Public userID of the user you want to shadowBan
   adminUserID: string, //your userID as an admin
   adminUserID: string, // Local userID or VIP or Admin
   enabled: boolean, //optional, to be able to add and remove users
   enabled: boolean, // Optional, default true, enable or disable ban
   unHideOldSubmissions: boolean //optional, should all previous submissions be banned as well?
   unHideOldSubmissions: boolean // Optional, should all previous submissions be banned as well?
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 642: Line 645:
'''Input''' (Request Body):
'''Input''' (Request Body):
<syntaxhighlight lang="ts"> {
<syntaxhighlight lang="ts"> {
   issuerUserID: string, // your userID
   issuerUserID: string, // Issuer userID
   userID: string, // public userID you are warning
   userID: string, // Public userID you are warning
   enabled: boolean //optional, default true
   enabled: boolean // Optional, default true
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 667: Line 670:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string, // your userID
   userID: string, // Local userID
   videoID: string // video ID to clear cache of
   videoID: string
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 691: Line 694:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string, // your userID
   userID: string, // Local userID
   videoID: string // video ID to hide segments of
   videoID: string
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 715: Line 718:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   videoID: string, //local userID
   videoID: string, // Local userID
   startTime: float,
   startTime: float,
   endTime: float
   endTime: float
Line 742: Line 745:
<syntaxhighlight lang="ts">
<syntaxhighlight lang="ts">
{
{
   userID: string, //public userID of the user you want to add to the VIP list
   userID: string, // Public userID of the user you want to add to the VIP list
   adminUserID: string, //your userID as an admin
   adminUserID: string, // Admin's local userID
   enabled: boolean //optional, to be able to add and remove users
   enabled: boolean // Optional, to be able to add and remove users
}
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 06:50, 24 August 2021

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.

While this is a free unlimited use API, please don't abuse it. I have limited resources.

Database download: https://sponsor.ajay.app/database

Libraries: NPM


Online Database Explorer (By Lartza): https://sb.ltn.fi/

Database Mirror (5 min update time, provided by Lartza): https://sb.ltn.fi/database/

Database Dump | Webhook Docs


GET /api/skipSegments

Get segments for a video.

Input (URL Parameters):

{
  videoID: string, // ID of video to pull segments for
  category: string, // Optional, defaults to "sponsor", can be repeated for multiple categories.
    // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
  categories: string[], // Optional, use this instead of "category" if you want multiple categories. Will look like ["sponsor","intro"]

  requiredSegments: string[], // Optional, list of segment UUIDs to require be retrieved, even if they don't meet the minimum vote threshold, can be replaced with "requiredSegment" and repeated for multiple segments like category.

  service: string // Optional, default is 'YouTube'. See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
}

Response:

[{ // Array of this object
   segment: float[], //[0, 15.23] start and end time in seconds
   UUID: string,
   category: string,
   videoDuration: float // Duration of video when submission occurred (to be used to determine when a submission is out of date)
}]

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

404: Not Found


GET /api/skipSegments/:sha256HashPrefix

Get segments for a video with extra privacy

sha256HashPrefix is a hash of the YouTube videoID. It should be the first 4 - 32 characters (4 is recommended). This provides extra privacy by potentially finding more than just the video you are looking for. This makes the server not know exactly what video you are looking for.

Input (URL Parameters):

{
  category: string, // Optional, defaults to "sponsor", can be repeated for multiple categories.
  categories: string[], // Optional, use this instead of "category" if you want multiple categories. Will look like ["sponsor","intro"]
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category

  requiredSegments: string[], // Optional, list of segment UUIDs to require be retrieved, even if they don't meet the minimum vote threshold, can be replaced with "requiredSegment" and repeated for multiple segments like category.

  service: string // Optional, default is 'YouTube'.
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
}

Response

[{ // Array of this object
   videoID: string,
   hash: string, // Full hash of the video ID
   segments: [{ // Array of this object
       segment: float[], // [0, 15.23] start and end time in seconds
       UUID: string,
       category: string
   }]
}]

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

404: Not Found


POST /api/skipSegments

Create a segment on a video

Input (URL Parameters):

{
  videoID: string,
  startTime: float,
  endTime: float,
  category: string,
  userID: string, // This should be a randomly generated UUID stored locally (not the public one)
  userAgent: string, // "Name of Client" or "[BOT] Name of Bot" ex. MeaBot/1.0.0
  service: string, // Optional, default is 'YouTube'.
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
  videoDuration: float, // Optional, duration of video, will attempt to retrieve from the YouTube API if missing (to be used to determine when a submission is out of date)
}

OR

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" or "[BOT] Name of Bot" ex. MeaBot/1.0.0
  service: string, // Optional, default is 'YouTube'.
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
  videoDuration: float, // Optional, duration of video, will attempt to retrieve from the YouTube API if missing (to be used to determine when a submission is out of date)

  segments: [{ // Array of this object
     segment: float[], //[0, 15.23] start and end time in seconds
     category: string
  }]
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Rejected by auto moderator (Reason will be sent in the response)

429: Rate Limit (Too many for the same user or IP)

409: Duplicate


POST /api/voteOnSponsorTime

Vote on a segment or vote to change the category of the segment.

Creators of the segment and VIPs can remove the segment or change the category with only one vote.

Input: Normal Vote (URL Parameters):

{
  UUID: string, // UUID of the segment being voted on
  userID: string, // Local userID
  type: int // 0 for downvote, 1 for upvote
}

OR

Input: Category Vote (URL Parameters):

{
  UUID: string, // UUID of the segment being voted on
  userID: string, // Local userID
  category: string // Category to change this submission to
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Reason given in request (moderation)


POST /api/viewedVideoSponsorTime

Add view to segment

Input (URL Parameters):

{
  UUID: string // UUID of segment viewed
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)


GET /api/userInfo

Get information about a user

Input (URL Parameters):

{
  userID: string // local UserID - optional if publicUserID is specified
  publicUserID: string // Public userID - optional if userID is specified

  value: string[] // Values to get from userInfo - optional
  // default values are:
  // ["userID", "userName", "minutesSaved", "segmentCount", "ignoredSegmentCount",
  // "viewCount", "ignoredViewCount", "warnings", "warningReason", "reputation",
  // "vip", "lastSegmentID"]
}

Response:

{
  userID: string, // Public userID
  userName: string, // Public userID if not set
  minutesSaved: float, // Minutes saved
  segmentCount: int, // Total number of segments excluding ignored/ hidden segments
  ignoredSegmentCount: int, // Total number of ignored/ hidden segments
  viewCount: int, // Total number of views excluding view on ignored/ hidden segments
  ignoredViewCount: int, // Total number of view on ignored/ hidden segments
  warnings: int, // Currently enabled warnings
  reputation: float, 
  vip: boolean, // VIP status
  lastSegmentID: string // UUID of last submitted segment
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)


GET /api/getViewsForUser

Get the number of views a user has on all their segments

Input (URL Parameters):

{
  userID: string // Local userID
}

Response:

{
  viewCount: int
}

Error codes:

404: Not Found


GET /api/getSavedTimeForUser

Get the total time saved from all the user's segments

Input (URL Parameters):

{
  userID: string // Local userID
}

Response:

{
  timeSaved: float // In minutes
}

Error codes:

404: Not Found


POST /api/setUsername

Set a username for a userID

Input (URL Parameters): Setting username for self

{
  userID: string, // Local userID
  username: string, // Optional
}

OR

Input (URL Parameters): Setting username as admin

Admin Only

{
  userID: string, // Public userID
  username: string, // Optional
  adminUserID: string // Admin's local userID
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not an admin)


GET /api/getUsername

Get current username

Input (URL Parameters):

{
  userID: string // Local userID
}

Response:

{
  userName: string // Public userID if no username has been set
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)


GET /api/segmentInfo

Get information about segments

Input (URL Parameters):

{
  UUID: string, // Can be used instead of UUIDs, can be repeated to fetch multiple segments
  UUIDs: string[] // Can be used instead of UUID. Maximum 10 entries. Will look like ["a...0", "b...1"]
}

Response:

[{ // Array of this object
  videoID: string,
  startTime: float,
  endTime: fload,
  votes: int,
  locked: int, // Status of lock - If upvoted by a VIP, the segment is locked
  UUID: string,
  userID: string, // PublicID of submitted
  timeSubmitted: int,
  views: int, // Number of reported views on the segment
  category: string, // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
  service: string, // See https://github.com/ajayyy/SponsorBlock/wiki/Types#service
  videoDuration: int,
  hidden: int, // If the segment has 2 downvotes or was downvoted by a VIP
  reputation: int, // Reputation of submitter at time of submission
  shadowHidden: int, // If the submitter is shadowbanned
  userAgent: string // userAgent of the submitter
}]

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

404: Not Found


GET /api/userID

List all users matching the username search

Input (URL Parameters):

{
  username: string, // search string for username
  // case sensitive
  // minimum for non-exact search is 3 characters, maximum is 64 characters
  exact: boolean // if explicitly set to true, searches for exact username
}

Response:

[{ // Array of this object - maximum 10 results
  userName: string,
  userID: string
}]

Error codes:

400: Bad Request (Your inputs are wrong/impossible) or exceed the character limits

404: Not Found


GET /api/lockCategories

Get locked categories for a video

Input (URL Parameters):

{
  videoID: string
}

Response:

{
  categories: string[],
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
  reason: string // Specified reason for the lock
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

404: Not Found


GET /api/lockCategories/:sha256HashPrefix

Get locked categories for a video with extra privacy

sha256HashPrefix is a hash of the YouTube videoID. It should be the first 4 - 32 characters (4 is recommended). This provides extra privacy by potentially finding more than just the video you are looking for. This makes the server not know exactly what video you are looking for.

Input (URL Parameters):

{
  prefix: sha256HashPrefix // Optional if not sent through path
}

Response:

[{ // Array of this object
   videoID: string,
   hash: string, // The full hash of the videoID
   categories": string[],
   // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
   reason: string // Specified reason for the lock
}]

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

404: Not Found


Stats Calls

GET /api/getTopUsers

Get top submitters

Input (URL Parameters):

{
  sortType: int
  // 0 for by minutes saved
  // 1 for by view count
  // 2 for by total submissions
}

Response:

{
  userNames: string[],
  viewCounts: int[],
  totalSubmissions: int[],
  minutesSaved: float[]
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)


GET /api/getTotalStats

Get total stats

Input (URL Parameters):

{
  "countContributingUsers": boolean // Optional, default false
}

Response:

{
  userCount: int, // Only if countContributingUsers was true
  activeUsers: int, // Sum of public install stats from Chrome webstore and Firefox addons store
  apiUsers: int, // 48-hour active API users (https://github.com/ajayyy/PrivacyUserCount)
  viewCount: int,
  totalSubmissions: int,
  minutesSaved: float
}

Error codes:

None


GET /api/getDaysSavedFormatted

Get days saved by all skips

Input:

{
  Nothing
}

Response:

{
  daysSaved: float (2 decimal places)
}

Error codes:

None


VIP Calls

These can only be called by the users added to the VIP table.

GET /api/isUserVIP

If the user is a VIP

Input (URL Parameters):

{
  userID: string, // private userID
}

Response:

{
  hashedUserID: string, // public userID
  vip: boolean // VIP status
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)


POST /api/lockCategories

Create a category lock on the video, disallowing further submissions for that category

Input (Request Body):

{
  videoID: string,
  userID: string,
  categories: string[], // Categories to lock
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
  reason: string // Reason for lock
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not a VIP)


DELETE /api/lockCategories

Delete existing category locks on that video

Input (Request Body):

{
  videoID: string,
  userID: string,
  categories: string[] // Categories to remove locks for
  // See https://github.com/ajayyy/SponsorBlock/wiki/Types#category
}

Response:

{
  message: "Removed lock categories entrys for video videoID"
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not a VIP)


POST /api/shadowBanUser

Shadow banned submissions are hidden for everyone but the IP that originally submitted it. Shadow banning a user shadow bans all future submissions.

Input (URL Parameters):

{
  userID: string, // Public userID of the user you want to shadowBan
  adminUserID: string, // Local userID or VIP or Admin
  enabled: boolean, // Optional, default true, enable or disable ban
  unHideOldSubmissions: boolean // Optional, should all previous submissions be banned as well?
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not a VIP)

409: User already warned


POST /api/warnUser

Temporary ban that shows a warning asking them to contact us.

If a user is re-warned but there is still a non-expired warning, it is reenabled

Input (Request Body):

 {
  issuerUserID: string, // Issuer userID
  userID: string, // Public userID you are warning
  enabled: boolean // Optional, default true
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not a VIP)


POST /api/clearCache

Clear redis cache for video.

Input (Request Body):

{
  userID: string, // Local userID
  videoID: string
}

Response:

{
  Cache cleared on video videoID (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not a VIP)


POST /api/purgeAllSegments

Hide all segments on a video without affecting submitter's reputation

Input (Request Body):

{
  userID: string, // Local userID
  videoID: string
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not a VIP)


POST /api/segmentShift

Shift all segments on a video

Input (Request Body):

{
  videoID: string, // Local userID
  startTime: float,
  endTime: float
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not a VIP)


Admin Calls

These can only be called by the server administrator, set in the config.

POST /api/addUserAsVIP

VIPs have extra privileges and their votes count more.

Input (Request Body):

{
  userID: string, // Public userID of the user you want to add to the VIP list
  adminUserID: string, // Admin's local userID
  enabled: boolean // Optional, to be able to add and remove users
}

Response:

{
  Nothing (status code 200)
}

Error codes:

400: Bad Request (Your inputs are wrong/impossible)

403: Unauthorized (You are not an admin)


Legacy API

https://github.com/ajayyy/SponsorBlock/wiki/Legacy-API

Local userID vs Public userID

The local userID should be a randomly generated and saved client side and must be 32 characters (or more). If it is not 32 characters or more, you will not be able to vote or submit. The public userID is what is used as an identifier in the database. This is the local userID with a SHA 256 hash 5000 times.