Reference integrations showing how to connect your app to the TONE3000 API. TONE3000 is a tone library for guitar and audio software — visit tone3000.com/api for full API documentation.
A live example of this demo can be viewed at t3k-api-demo.vercel.app.
Run any of them locally in minutes using your own TONE3000 API key.
Best for: Plugins, DAWs, and apps where TONE3000 drives tone discovery.
Acme Inc is a guitar amp simulation plugin. When a user clicks "Browse Tones on TONE3000", they're taken to the TONE3000 catalog to browse and select a tone. Once selected, Acme Inc receives the tone and its downloadable model files.
Flow: GET /api/v1/oauth/authorize?prompt=select_tone → callback with tone_id → GET /api/v1/tones/{id} + GET /api/v1/models?tone_id={id}
Best for: Apps with saved tone references that need authentication and access checking.
Beacon Inc is a rig preset manager. It stores TONE3000 tone IDs in its presets and
loads them on demand. TONE3000 handles the auth check — if a tone is private or
deleted, the user can pick a replacement without leaving the flow. Optional gears
and platform filters scope the replacement browse view to your product's supported types.
Flow: GET /api/v1/oauth/authorize?prompt=load_tone&tone_id=42&gears=amp → callback with tone_id + code → fetch tone
Best for: Apps with a custom tone browsing and discovery experience.
Chord Inc demonstrates every documented TONE3000 endpoint: search with filters, tone detail views, user profiles, favorites, model listings, and file downloads. It's the reference implementation for a full API integration.
Endpoints used: GET /user, GET /tones/search, GET /tones/created, GET /tones/favorited,
GET /tones/{id}, GET /models/{id}, GET /models, GET /users
Best for: Headless devices, kiosks, embedded hardware with no system browser.
Devo Inc ships embedded guitar processors with a touchscreen but no system
browser and no keyboard. To connect a TONE3000 account, the device opens an
HTTP listener on its LAN IP, shows a QR pointing at TONE3000's authorize
endpoint with the LAN URI as redirect_uri, and waits. The user scans on
their phone, signs in, and TONE3000 forwards the issued code back to the
device's listener via an internal HTTPS bridge. PKCE keeps the code
unredeemable by anyone but the device.
Flow: GET /api/v1/oauth/authorize?redirect_uri=http://192.168.x.x:port/cb → user signs in on phone → /oauth/lan-bridge 307 → device's LAN listener receives code → POST /oauth/token with redirect_uri unchanged
Cross-device requirement: the phone must be on the same Wi-Fi as the
laptop/device. The demo's "device" is the laptop's Vite dev server itself —
see vite-plugin-lan-bridge.ts for how the
LAN listener is implemented in dev. In production, your firmware does this
on the embedded hardware.
- Log in to tone3000.com
- Go to Settings → API Keys
- Click Create API Key — you'll receive a
t3k_pub_…publishable key - Copy the publishable key
cp env.example .envEdit .env:
VITE_PUBLISHABLE_KEY=t3k_pub_your_key_here
VITE_REDIRECT_URI=http://localhost:3001
Registering your redirect URI: In TONE3000 Settings → API Keys, add
http://localhost:3001 to your key's allowed redirect URIs. Localhost origins
are automatically allowed during development — no registration needed.
npm install
npm run devOpen http://localhost:3001 — you'll see the demo apps. Each one opens a self-contained integration example.
The src/tone3000-client.ts file is a zero-dependency integration helper
that covers the OAuth flows and the full set of API endpoints. Use it as
inspiration for your own integration.
import { startSelectFlow, startLoadToneFlow, startStandardFlow, handleOAuthCallback, T3KClient } from './tone3000-client';
// Select Flow — user browses TONE3000 and picks a tone
await startSelectFlow(PUBLISHABLE_KEY, REDIRECT_URI);
// Load Tone Flow — TONE3000 authenticates the user and checks access to a specific tone
// Optional: pass gears/platform to filter the replacement browse view if the tone is inaccessible
await startLoadToneFlow(PUBLISHABLE_KEY, REDIRECT_URI, toneId, { gears: 'amp', platform: 'nam' });
// Standard Flow — user connects their TONE3000 account; app fetches tones programmatically
await startStandardFlow(PUBLISHABLE_KEY, REDIRECT_URI);// In your callback handler (runs when TONE3000 redirects back to your app):
const result = await handleOAuthCallback(PUBLISHABLE_KEY, REDIRECT_URI);
if (result.ok) {
client.setTokens(result.tokens);
const { toneId } = result; // present for select/load_tone flows
} else {
console.error('Auth failed:', result.error);
}const client = new T3KClient(PUBLISHABLE_KEY, () => {
// Called when tokens expire beyond refresh — restart auth
startStandardFlow(PUBLISHABLE_KEY, REDIRECT_URI);
});
// Set tokens from the callback result
client.setTokens(result.tokens);
// Fetch a tone
const tone = await client.getTone(42);
// Fetch models for a tone (each has a model_url for downloading)
const { data: models } = await client.listModels(42);
// Search tones with filters
const results = await client.searchTones({ query: 'fender', gears: [Gear.Amp], sort: TonesSort.Trending });
// Download a model file (requires Bearer auth — use this method, not fetch())
await client.downloadModel(model.model_url, model.name);Full reference: tone3000.com/api
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/oauth/authorize |
Start an OAuth flow |
| POST | /api/v1/oauth/token |
Exchange code or refresh token |
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/user |
Authenticated user profile |
| GET | /api/v1/tones/{id} |
Tone by ID |
| GET | /api/v1/tones/search |
Search and filter tones |
| GET | /api/v1/tones/created |
Tones created by the authenticated user |
| GET | /api/v1/tones/favorited |
Tones favorited by the authenticated user |
| GET | /api/v1/models/{id} |
Model by ID |
| GET | /api/v1/models |
Models for a tone |
| GET | /api/v1/users |
Public user list |
100 requests/minute. For higher limits, contact support@tone3000.com.
Questions? Email support@tone3000.com or open an issue in this repo.