Skip to content

tone-3000/api

Repository files navigation

TONE3000 API Integration Guide

This project demonstrates how to integrate with the TONE3000 API. This guide will walk you through user authentication, session management, and available API endpoints. For the complete API documentation, visit https://www.tone3000.com/api.

screenshot

Environment Setup

  1. Copy the example environment file:
cp env.example .env
  1. Configure your environment variables in .env:
VITE_TONE3000_API_DOMAIN=https://www.tone3000.com

The VITE_ prefix is required for Vite to expose the environment variable to the client-side code.

Development

  1. Clone the repository
  2. Install dependencies:
npm install
  1. Start the development server:
npm run dev

The application will be available at http://localhost:3001.

Authentication

Initial Setup

  1. Redirect users to the TONE3000 authentication page:
const redirectUrl = encodeURIComponent(APP_URL);
window.location.href = `https://www.tone3000.com/api/v1/auth?redirect_url=${redirectUrl}`;

Note: If your application only supports OTP authentication (e.g. IOT devices), include otp_only=true in the search parameters.

  1. After successful authentication, TONE3000 will redirect back to your application with an api_key parameter.

  2. Exchange the API key for session tokens:

interface Session {
  access_token: string;
  refresh_token: string;
  expires_in: number;  // seconds until token expires
  token_type: 'bearer';
}

const response = await fetch('https://www.tone3000.com/api/v1/auth/session', {
  method: 'POST',
  body: JSON.stringify({ api_key: apiKey })
});

const data = await response.json() as Session;

Session Management

  1. Initial Authentication

    • After successful authentication, you receive an access_token, refresh_token, and expires_in (seconds until token expires)
    • Store these tokens and expiration time securely (e.g., in localStorage):
    localStorage.setItem('tone3000_access_token', data.access_token);
    localStorage.setItem('tone3000_refresh_token', data.refresh_token);
    localStorage.setItem('tone3000_expires_at', String(Date.now() + (data.expires_in * 1000)));
  2. Making API Requests

    • Before making a request, check if the token is about to expire
    • If the token is expired or will expire soon (e.g., within 30 seconds), refresh it proactively
    • Include the access token in the Authorization header:
    const expiresAt = parseInt(localStorage.getItem('tone3000_expires_at') || '0');
    
    // Check if token is expired or about to expire (within 30 seconds)
    if (Date.now() > expiresAt - 30000) {
      // Refresh token before making the request
      await refreshTokens();
    }
    
    const response = await fetch(url, {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      }
    });
  3. Token Refresh Flow

    • When proactively refreshing or when an API request returns 401 (Unauthorized):
      1. Use the refresh token to get a new access token
      2. Store the new tokens and expiration time
      3. Retry the original request if needed
    const refreshResponse = await fetch('https://www.tone3000.com/api/v1/auth/session/refresh', {
      method: 'POST',
      body: JSON.stringify({
        refresh_token: refreshToken,
        access_token: accessToken
      })
    });
    
    const tokens = await refreshResponse.json() as Session;
    
    // Store new tokens and expiration
    localStorage.setItem('tone3000_access_token', tokens.access_token);
    localStorage.setItem('tone3000_refresh_token', tokens.refresh_token);
    localStorage.setItem('tone3000_expires_at', String(Date.now() + (tokens.expires_in * 1000)));
  4. Handling Refresh Failure

    • If token refresh fails:
      1. Clear all stored tokens and expiration time
      2. Redirect user to login page to restart auth flow
    localStorage.removeItem('tone3000_access_token');
    localStorage.removeItem('tone3000_refresh_token');
    localStorage.removeItem('tone3000_expires_at');
    window.location.href = `https://www.tone3000.com/api/v1/auth?redirect_url=${redirectUrl}`;

Using the t3kFetch Utility

The example t3kFetch utility handles all of this automatically, including proactive token refresh based on expiration time. Use it for all API requests:

// Example: Fetching user data
const response = await t3kFetch('https://www.tone3000.com/api/v1/user');
const userData = await response.json();

This ensures consistent token handling across your application, including:

  • Proactive token refresh before expiration
  • Automatic retry on 401 errors
  • Proper token storage and cleanup
  • Seamless user experience without token expiration interruptions

API Endpoints

User Information

GET https://www.tone3000.com/api/v1/user

interface EmbeddedUser {
  id: string;
  username: string;
  avatar_url: string | null;
  url: string;
}

// Response Type
interface User extends EmbeddedUser {
  bio: string | null;
  links: string[] | null;
  created_at: string;
  updated_at: string;
}

Tones

Get Created Tones

GET https://www.tone3000.com/api/v1/tones/created?page=1&page_size=10

interface Make {
  id: number;
  name: string;
}

interface Tag {
  id: number;
  name: string;
}

// Response Type
interface PaginatedResponse<Tone> {
  data: Tone[];
  page: number;
  page_size: number;
  total: number;
  total_pages: number;
}

interface Tone {
  id: number;
  user_id: string;
  user: EmbeddedUser;
  created_at: string;
  updated_at: string;
  title: string;
  description: string | null;
  gear: Gear;
  images: string[] | null;
  is_public: boolean | null;
  links: string[] | null;
  platform: Platform;
  license: License;
  sizes: Size[];
  makes: Make[];
  tags: Tag[];
  models_count: number;
  downloads_count: number;
  favorites_count: number;
  url: string;
}

Get Favorited Tones

GET https://www.tone3000.com/api/v1/tones/favorited?page=1&page_size=10

Models

GET https://www.tone3000.com/api/v1/models?tone_id={toneId}&page=1&page_size=10

// Response Type
interface PaginatedResponse<Model> {
  data: Model[];
  page: number;
  page_size: number;
  total: number;
  total_pages: number;
}

interface Model {
  id: number;
  created_at: string;
  updated_at: string;
  user_id: string;
  model_url: string;
  name: string;
  size: Size;
  tone_id: number;
}

Download via model URL model.model_url

GET https://https://www.tone3000.com/api/v1/models/{modelId}/download/{filename}

// Response type .nam or .wav file

Enums

Gear Types

enum Gear {
  Amp = 'amp',
  FullRig = 'full-rig',
  Pedal = 'pedal',
  Outboard = 'outboard',
  Ir = 'ir'
}

Platforms

enum Platform {
  Nam = 'nam',
  Ir = 'ir',
  AidaX = 'aida-x',
  AaSnapshot = 'aa-snapshot',
  Proteus = 'proteus'
}

Licenses

enum License {
  T3k = 't3k',
  CcBy = 'cc-by',
  CcBySa = 'cc-by-sa',
  CcByNc = 'cc-by-nc',
  CcByNcSa = 'cc-by-nc-sa',
  CcByNd = 'cc-by-nd',
  CcByNcNd = 'cc-by-nc-nd',
  Cco = 'cco'
}

Sizes

enum Size {
  Standard = 'standard',
  Lite = 'lite',
  Feather = 'feather',
  Nano = 'nano',
  Custom = 'custom'
}

About

TONE3000 API Integration Guide

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •