🚀 Getting Started
SnapieAudioPlayer provides a REST API for uploading, storing, and playing audio files on the decentralized IPFS network. All audio files are stored permanently on IPFS and metadata is indexed in our MongoDB database for fast retrieval.
✓ Base URL:
https://audio.3speak.tv
Quick Start
- Get an API key (contact 3speak team)
- Upload audio via REST API
- Embed player using returned permlink or CID
- Track plays and engagement
🔐 Authentication
API keys are required for uploading audio. Include your API key in the request header:
X-API-Key: sk_your_api_key_here
Note: Reading audio metadata and playback do not require authentication. Only uploads are protected.
📺 Embedding Player
Using iFrame
<!-- Embed by permlink -->
<iframe
src="https://audio.3speak.tv/play?a=abc123xyz"
width="100%"
height="120"
frameborder="0"
allow="autoplay">
</iframe>
<!-- Embed by IPFS CID -->
<iframe
src="https://audio.3speak.tv/play?cid=QmdMsEXyDe5Z4S3n8THfYgFP1iH3ngCeCytdHnndzqdZAK"
width="100%"
height="120"
frameborder="0">
</iframe>
Display Modes
| Mode | Height | Description |
|---|---|---|
minimal |
80px | Play button, waveform, time only |
compact |
120px | Default - full controls without metadata |
full |
180px | All controls + title, owner, plays |
<iframe src="https://audio.3speak.tv/play?a=abc123&mode=minimal" height="80"></iframe>
Iframe Mode (No Scrollbars)
Add &iframe=1 for clean embedding without scrollbars - perfect for chat apps:
<!-- Clean embed with no scrollbars -->
<iframe
src="https://audio.3speak.tv/play?a=abc123&mode=compact&iframe=1"
width="100%"
height="120"
frameborder="0"
scrolling="no"
allow="autoplay">
</iframe>
💡 Tip: Use
iframe=1 to remove all padding and prevent scrollbars. Ideal for seamless integration in chat apps or tight spaces.
📤 Upload API
POST
/api/audio/upload
Upload audio files to IPFS with metadata indexing.
Headers
| Header | Required | Description |
|---|---|---|
X-API-Key |
Yes | Your API key |
X-User |
Yes | Username (required for all uploads) |
Content-Type |
Yes | multipart/form-data |
Form Data Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
audio |
File | Yes | Audio file (mp3, m4a, ogg, webm, wav) |
duration |
Number | Yes | Duration in seconds |
format |
String | Yes | File format (mp3, m4a, etc.) |
title |
String | No | Audio title |
description |
String | No | Audio description |
codec |
String | No | Audio codec (aac, mp3, etc.) |
bitrate |
Number | No | Bitrate in kbps |
sampleRate |
Number | No | Sample rate in Hz |
channels |
Number | No | Number of channels (1=mono, 2=stereo) |
waveform |
JSON | No | Waveform data object |
⚠️ File Limits & Requirements:
- Max file size: 50MB
- Supported formats: mp3, m4a, ogg, webm, wav
- Rate limit: 10 uploads per minute
- Username required: X-User header must be provided
- Banned users: Users with upload restrictions will receive 403 Forbidden
Response
{
"success": true,
"permlink": "w2ehm8pr",
"cid": "QmdMsEXyDe5Z4S3n8THfYgFP1iH3ngCeCytdHnndzqdZAK",
"playUrl": "https://audio.3speak.tv/play?a=w2ehm8pr",
"apiUrl": "https://audio.3speak.tv/api/audio?a=w2ehm8pr"
}
▶️ Playback API
GET
/api/audio
Retrieve audio metadata for playback. No authentication required.
Query Parameters
| Parameter | Description | Example |
|---|---|---|
a |
Audio permlink | ?a=w2ehm8pr |
cid |
IPFS Content ID | ?cid=QmdMsEX... |
Response
{
"permlink": "w2ehm8pr",
"owner": "meno",
"audio_cid": "QmdMsEXyDe5Z4S3n8THfYgFP1iH3ngCeCytdHnndzqdZAK",
"duration": 45,
"format": "mp3",
"bitrate": 128,
"sampleRate": 44100,
"channels": 1,
"waveform": {
"peaks": [0.05, 0.34, 0.93, ...],
"samples": 100
},
"audioUrl": "http://gateway.ipfs/ipfs/QmdMsEX...",
"audioUrlFallback": "https://ipfs.io/ipfs/QmdMsEX...",
"title": "My Audio",
"plays": 42,
"likes": 5,
"createdAt": "2025-11-27T01:22:17.053Z"
}
Track Play Count
POST
/api/audio/play
Increment play counter when audio starts playing.
POST /api/audio/play
Content-Type: application/json
{
"permlink": "w2ehm8pr"
}
Response:
{
"success": true,
"plays": 43
}
💻 Code Examples
JavaScript (Fetch API)
// Upload audio file
async function uploadAudio(file) {
const formData = new FormData();
formData.append('audio', file);
formData.append('duration', 45);
formData.append('format', 'mp3');
formData.append('title', 'My Recording');
const response = await fetch('https://audio.3speak.tv/api/audio/upload', {
method: 'POST',
headers: {
'X-API-Key': 'sk_your_api_key',
'X-User': 'username'
},
body: formData
});
return await response.json();
}
// Get audio metadata
async function getAudio(permlink) {
const response = await fetch(
`https://audio.3speak.tv/api/audio?a=${permlink}`
);
return await response.json();
}
// Track play
async function trackPlay(permlink) {
await fetch('https://audio.3speak.tv/api/audio/play', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ permlink })
});
}
cURL
# Upload audio
curl -X POST https://audio.3speak.tv/api/audio/upload \
-H "X-API-Key: sk_your_api_key" \
-H "X-User: username" \
-F "audio=@recording.mp3" \
-F "duration=45" \
-F "format=mp3" \
-F "title=My Recording"
# Get metadata
curl "https://audio.3speak.tv/api/audio?a=w2ehm8pr"
# Track play
curl -X POST https://audio.3speak.tv/api/audio/play \
-H "Content-Type: application/json" \
-d '{"permlink":"w2ehm8pr"}'
Python
import requests
# Upload audio
def upload_audio(file_path, api_key):
with open(file_path, 'rb') as f:
files = {'audio': f}
data = {
'duration': 45,
'format': 'mp3',
'title': 'My Recording'
}
headers = {
'X-API-Key': api_key,
'X-User': 'username'
}
response = requests.post(
'https://audio.3speak.tv/api/audio/upload',
files=files,
data=data,
headers=headers
)
return response.json()
# Get metadata
def get_audio(permlink):
response = requests.get(
f'https://audio.3speak.tv/api/audio?a={permlink}'
)
return response.json()
⏱️ Rate Limits
| Endpoint | Limit | Window |
|---|---|---|
Upload /api/audio/upload |
10 requests | 1 minute |
Play tracking /api/audio/play |
100 requests | 1 minute |
Metadata /api/audio |
Unlimited | - |
Rate Limit Headers:
X-RateLimit-Limit- Max requests allowedX-RateLimit-Remaining- Remaining requestsX-RateLimit-Reset- Time when limit resets (Unix timestamp)
❌ Error Handling
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
200 |
OK | Request successful |
201 |
Created | Upload successful |
400 |
Bad Request | Invalid parameters or file format |
401 |
Unauthorized | Missing or invalid API key |
403 |
Forbidden | User is banned or lacks upload permissions |
404 |
Not Found | Audio not found |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server error |
Error Response Format
{
"error": "Invalid file format",
"message": "Allowed formats: mp3, m4a, ogg, webm, wav"
}
Common Errors
Invalid API Key
{
"error": "Invalid API key",
"message": "The provided API key is not valid"
}
File Too Large
{
"error": "File too large",
"message": "Maximum file size is 50MB"
}
Rate Limit Exceeded
{
"error": "Too many requests, please try again later"
}
User Banned
{
"error": "Upload not allowed",
"message": "User is banned from uploading"
}
Missing Username
← Back to Home
{
"error": "Username required",
"message": "X-User header must be provided for uploads"
}