API Documentation

The Twitch Video Navigator Pro API allows you to programmatically create and manage markers for Twitch videos. This documentation covers everything you need to know to integrate with our API.

Authentication

All API requests require authentication using an API key. You can create and manage your API keys in your API Keys dashboard.

API Key in Header

Include your API key in the Authorization header of all requests:

Authorization: Bearer YOUR_API_KEY
Important: Keep your API keys secure and never expose them in client-side code.

API Endpoints

Create a Marker

POST /api/markers/create

Request Parameters

Parameter Type Required Description
video_id string Yes The Twitch video ID
title string Yes Title of the marker
timestamp integer Yes Position in the video in seconds
description string No Description of the marker
team_id integer No Team ID to associate marker with (use -1 for personal markers)
color string No CSS color value (e.g., '#ff0000' or 'red')
video_name string No Display name of the video
thumbnail string No Base64 encoded thumbnail image

Example Request

curl -X POST \
  https://your-domain.com/api/markers/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video_id": "1234567890",
    "title": "Amazing play",
    "timestamp": 3600,
    "description": "This is where the amazing play happens",
    "team_id": 1,
    "color": "#FF5733",
    "video_name": "Stream Highlights",
    "thumbnail": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/..."
}'

Example Response

{
  "success": true,
  "message": "Marker created successfully",
  "data": {
    "marker_id": 123,
    "video_id": "1234567890",
    "title": "Amazing play",
    "timestamp": 3600,
    "description": "This is where the amazing play happens",
    "team_id": 1,
    "color": "#FF5733",
    "video_name": "Stream Highlights",
    "thumbnail": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/...",
    "created_at": "2025-05-31T10:15:30Z"
  }
}

Get Markers

GET /api/markers/get

Query Parameters

Parameter Type Required Description
video_id string No Filter by Twitch video ID
team_id integer No Filter by team ID (use -1 for personal markers)
limit integer No Maximum number of markers to return (default: 100, max: 500)

Example Request

curl -X GET \
  "https://your-domain.com/api/markers/get?video_id=1234567890" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

{
  "success": true,
  "message": "Markers retrieved successfully",
  "data": {
    "markers": [
      {
        "marker_id": 123,
        "video_id": "1234567890",
        "title": "Amazing play",
        "timestamp": 3600,
        "description": "This is where the amazing play happens",
        "team_id": 1,
        "team_name": "Pro Team",
        "created_by": "username",
        "created_at": "2025-05-31T10:15:30Z"
      },
      {
        "marker_id": 124,
        "video_id": "1234567890",
        "title": "Great goal",
        "timestamp": 4200,
        "description": "What a goal!",
        "team_id": 1,
        "team_name": "Pro Team",
        "created_by": "username2",
        "created_at": "2025-05-31T10:30:15Z"
      }
    ],
    "count": 2
  }
}

Delete a Marker

DELETE /api/markers/delete

Request Parameters

Parameter Type Required Description
marker_id integer Yes ID of the marker to delete

Example Request

curl -X DELETE \
  https://your-domain.com/api/markers/delete \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "marker_id": 123
}'

Example Response

{
  "success": true,
  "message": "Marker deleted successfully"
}

Bulk Delete Markers

DELETE /api/markers/bulkDelete

Request Parameters

Parameter Type Required Description
marker_ids array Yes Array of marker IDs to delete

Example Request

curl -X DELETE \
  https://your-domain.com/api/markers/bulkDelete \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "marker_ids": [123, 124, 125]
}'

Example Response

{
  "success": true,
  "message": "Bulk delete completed",
  "data": {
    "results": [
      {"marker_id": 123, "action": "deleted"},
      {"marker_id": 124, "action": "deleted"},
      {"marker_id": 125, "action": "skipped", "reason": "forbidden"}
    ],
    "summary": {
      "total_requested": 3,
      "deleted": 2,
      "skipped": 1
    }
  }
}

Sync Markers

POST /api/markers/sync

Request Parameters

Parameter Type Required Description
markers array Yes Array of marker objects to sync
team_id integer No Team ID for team markers, -1 for personal markers

Example Request

curl -X POST \
  https://your-domain.com/api/markers/sync \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "team_id": 1,
    "markers": [
      {
        "video_id": "1234567890",
        "title": "Epic moment",
        "timestamp": 3600,
        "description": "This was amazing!"
      },
      {
        "video_id": "1234567890",
        "title": "Another moment",
        "timestamp": 7200,
        "description": "Also great!"
      }
    ]
}'

Example Response

{
  "success": true,
  "message": "Markers synchronized successfully",
  "data": {
    "results": [
      {"action": "updated", "marker_id": 123},
      {"action": "created", "marker_id": 124}
    ],
    "total_processed": 2
  }
}

Get Teams

GET /api/teams/get

Example Request

curl -X GET \
  https://your-domain.com/api/teams/get \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

{
  "success": true,
  "message": "Teams retrieved successfully",
  "data": {
    "teams": [
      {
        "team_id": 1,
        "team_name": "Pro Team",
        "team_description": "Our professional team",
        "created_at": "2025-05-15T08:30:00Z",
        "role": "owner",
        "member_count": 5
      },
      {
        "team_id": 2,
        "team_name": "Community Team",
        "team_description": "Open community team",
        "created_at": "2025-05-20T14:45:00Z",
        "role": "member",
        "member_count": 12
      }
    ],
    "count": 2
  }
}

Get Team Members

GET /api/teams/members

Query Parameters

Parameter Type Required Description
team_id integer Yes ID of the team

Example Request

curl -X GET \
  "https://your-domain.com/api/teams/members?team_id=1" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

{
  "success": true,
  "message": "Team members retrieved successfully",
  "data": {
    "members": [
      {
        "user_id": 1,
        "username": "username",
        "role": "owner",
        "joined_at": "2025-05-15T08:30:00Z"
      },
      {
        "user_id": 2,
        "username": "username2",
        "role": "admin",
        "joined_at": "2025-05-16T09:45:00Z"
      },
      {
        "user_id": 3,
        "username": "username3",
        "role": "member",
        "joined_at": "2025-05-17T12:30:00Z"
      }
    ],
    "count": 3
  }
}

Create Team

POST /api/teams/create

Request Parameters

Parameter Type Required Description
team_name string Yes Name of the team (less than 100 characters)
team_description string No Description of the team

Example Request

curl -X POST \
  https://your-domain.com/api/teams/create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "team_name": "New Team",
    "team_description": "This is our new team for collaboration"
}'

Example Response

{
  "success": true,
  "message": "Team created successfully",
  "data": {
    "team_id": 3,
    "team_name": "New Team",
    "team_description": "This is our new team for collaboration",
    "created_by": 1,
    "created_at": "2025-06-01T14:30:00Z"
  }
}

Invite Team Member

POST /api/teams/invite

Request Parameters

Parameter Type Required Description
team_id integer Yes ID of the team to invite to
email string Yes Email address of user to invite

Example Request

curl -X POST \
  https://your-domain.com/api/teams/invite \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "team_id": 1,
    "email": "newmember@example.com"
}'

Example Response

{
  "success": true,
  "message": "User added to team successfully"
}

Remove Team Member

DELETE /api/teams/removeMember

Request Parameters

Parameter Type Required Description
team_id integer Yes ID of the team
user_id integer Yes ID of the user to remove

Example Request

curl -X DELETE \
  https://your-domain.com/api/teams/removeMember \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "team_id": 1,
    "user_id": 3
}'

Example Response

{
  "success": true,
  "message": "Member removed from team successfully"
}

Update Member Role

PUT /api/teams/updateRole

Request Parameters

Parameter Type Required Description
team_id integer Yes ID of the team
user_id integer Yes ID of the user to update role for
role string Yes New role for the user (admin or member)

Example Request

curl -X PUT \
  https://your-domain.com/api/teams/updateRole \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "team_id": 1,
    "user_id": 3,
    "role": "admin"
}'

Example Response

{
  "success": true,
  "message": "Member role updated successfully"
}

Get User Profile

GET /api/users/me

Example Request

curl -X GET \
  https://your-domain.com/api/users/me \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

{
  "success": true,
  "message": "User profile retrieved successfully",
  "data": {
    "user_id": 1,
    "username": "username",
    "email": "user@example.com",
    "created_at": "2025-05-01T10:00:00Z",
    "last_login": "2025-05-31T09:30:00Z",
    "stats": {
      "teams_count": 2,
      "markers_count": 25,
      "api_keys_count": 3
    }
  }
}

Get User API Keys

GET /api/users/apiKeys

Example Request

curl -X GET \
  https://your-domain.com/api/users/apiKeys \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

{
  "success": true,
  "message": "API keys retrieved successfully",
  "data": {
    "api_keys": [
      {
        "key_id": 1,
        "key_name": "Browser Extension",
        "created_at": "2025-05-01T10:00:00Z",
        "last_used": "2025-05-31T09:30:00Z",
        "is_active": 1
      },
      {
        "key_id": 2,
        "key_name": "Mobile App",
        "created_at": "2025-05-15T14:20:00Z",
        "last_used": "2025-05-30T16:45:00Z",
        "is_active": 1
      }
    ],
    "count": 2
  }
}

Get User Markers

GET /api/users/markers

Query Parameters

Parameter Type Required Description
limit integer No Maximum number of markers to return (default: 100, max: 500)

Example Request

curl -X GET \
  "https://your-domain.com/api/users/markers?limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

{
  "success": true,
  "message": "User markers retrieved successfully",
  "data": {
    "markers": [
      {
        "marker_id": 123,
        "video_id": "1234567890",
        "title": "Amazing play",
        "timestamp": 3600,
        "description": "This is where the amazing play happens",
        "team_id": 1,
        "team_name": "Pro Team",
        "created_at": "2025-05-31T10:15:30Z"
      },
      {
        "marker_id": 124,
        "video_id": "9876543210",
        "title": "Great goal",
        "timestamp": 4200,
        "description": "What a goal!",
        "team_id": 1,
        "team_name": "Pro Team",
        "created_at": "2025-05-31T10:30:15Z"
      }
    ],
    "count": 25
  }
}

Get Videos with Markers

GET /api/videos/withMarkers

Query Parameters

Parameter Type Required Description
limit integer No Maximum number of videos to return (default: 10, max: 50)
team_id integer No Filter by team ID (use -1 for personal markers only)

Example Request

curl -X GET \
  "https://your-domain.com/api/videos/withMarkers?limit=5&team_id=1" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

{
  "success": true,
  "message": "Videos with markers retrieved successfully",
  "data": {
    "videos": [
      {
        "video_id": "1234567890",
        "video_name": "Stream Highlights May 30th",
        "channel_name": "ProGamer123",
        "thumbnail": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/...",
        "duration": 7200,
        "created_at": "2025-05-30T08:00:00Z",
        "updated_at": "2025-05-31T10:15:30Z",
        "markers": [
          {
            "marker_id": 123,
            "video_id": "1234567890",
            "title": "Amazing play",
            "timestamp": 3600,
            "description": "This is where the amazing play happens",
            "created_by": 1,
            "created_by_username": "username",
            "team_id": 1,
            "team_name": "Pro Team",
            "color": "#FF5733",
            "created_at": "2025-05-31T10:15:30Z"
          },
          {
            "marker_id": 124,
            "video_id": "1234567890",
            "title": "Another highlight",
            "timestamp": 5400,
            "description": "Second notable moment",
            "created_by": 2,
            "created_by_username": "username2",
            "team_id": 1,
            "team_name": "Pro Team",
            "color": "#33FF57",
            "created_at": "2025-05-31T11:20:15Z"
          }
        ]
      },
      {
        "video_id": "9876543210",
        "video_name": "Stream Highlights May 29th",
        "channel_name": "ProGamer123",
        "thumbnail": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/...",
        "duration": 6900,
        "created_at": "2025-05-29T08:00:00Z",
        "updated_at": "2025-05-30T09:25:10Z",
        "markers": [
          {
            "marker_id": 125,
            "video_id": "9876543210",
            "title": "Great goal",
            "timestamp": 4200,
            "description": "What a goal!",
            "created_by": 1,
            "created_by_username": "username",
            "team_id": 1,
            "team_name": "Pro Team",
            "color": "#5733FF",
            "created_at": "2025-05-30T09:25:10Z"
          }
        ]
      }
    ],
    "count": 10
  }
}

Error Handling

The API uses standard HTTP status codes to indicate the success or failure of requests. In addition, error responses include details about the problem in the JSON response body.

Error Response Format

{
  "success": false,
  "message": "Error message describing what went wrong",
  "error": {
    "error": "error_code",
    "details": "Additional information about the error"
  }
}

Common Error Codes

HTTP Status Error Code Description
400 invalid_request The request was invalid or missing required parameters
400 invalid_data The provided data is invalid or improperly formatted
401 unauthorized Authentication failed or API key is invalid
401 invalid_key The provided API key is not valid
403 forbidden You don't have permission to access the requested resource
403 team_access_denied You are not a member of the specified team
404 not_found The requested resource was not found
404 user_not_found The specified user could not be found
429 rate_limit_exceeded You've made too many requests in a short period
500 server_error An error occurred on the server

Rate Limits

To ensure system stability and fair usage, API requests are subject to rate limiting.

Endpoint Rate Limit
All endpoints 60 requests per minute

When you exceed the rate limit, you'll receive a 429 Too Many Requests response. The response headers include information about when you can retry.

Rate Limit Headers

Header Description
X-RateLimit-Limit The maximum number of requests per minute
X-RateLimit-Remaining The number of remaining requests in the current window
X-RateLimit-Reset The time at which the current rate limit window resets in UTC epoch seconds

Plugin Integration

To integrate with the Twitch Video Navigator Pro plugin, you need to use the API to create and manage markers. Here's a basic example of how to integrate using JavaScript:

// Example plugin integration code
const apiKey = 'YOUR_API_KEY';
const apiBaseUrl = 'https://your-domain.com/api';

// Create a new marker
async function createMarker(videoId, title, timestamp, description, teamId = null) {
  try {
    const response = await fetch(`${apiBaseUrl}/markers/create`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        video_id: videoId,
        title: title,
        timestamp: timestamp,
        description: description,
        team_id: teamId
      })
    });
    
    const data = await response.json();
    
    if (data.success) {
      console.log('Marker created:', data.data);
      return data.data;
    } else {
      console.error('Error creating marker:', data.message);
      return null;
    }
  } catch (error) {
    console.error('API request failed:', error);
    return null;
  }
}

// Get markers for a video
async function getMarkers(videoId) {
  try {
    const response = await fetch(`${apiBaseUrl}/markers/get?video_id=${videoId}`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${apiKey}`
      }
    });
    
    const data = await response.json();
    
    if (data.success) {
      console.log('Markers retrieved:', data.data.markers);
      return data.data.markers;
    } else {
      console.error('Error getting markers:', data.message);
      return [];
    }
  } catch (error) {
    console.error('API request failed:', error);
    return [];
  }
}

// Get videos with markers
async function getVideosWithMarkers(teamId = null, limit = 10) {
  try {
    let url = `${apiBaseUrl}/videos/withMarkers?limit=${limit}`;
    if (teamId !== null) {
      url += `&team_id=${teamId}`;
    }
    
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${apiKey}`
      }
    });
    
    const data = await response.json();
    
    if (data.success) {
      console.log('Videos retrieved:', data.data.videos);
      return data.data.videos;
    } else {
      console.error('Error getting videos:', data.message);
      return [];
    }
  } catch (error) {
    console.error('API request failed:', error);
    return [];
  }
}