API Reference
TOTPHog provides a REST API for programmatic access to TOTP tokens and codes.
Base URL: http://localhost:8045/api/v1
Interactive API Documentation
Response Format
All API responses follow a consistent JSON structure:
Error responses:
Endpoints
Health Check
Check if the service is running.
Response:
{
"status": "ok",
"service": "TOTPHog",
"version": "1.0.0",
"timestamp": "2024-01-15T10:30:00+00:00"
}
List Tokens
Get all stored TOTP tokens.
Response:
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "GitHub",
"secret": "JBSWY3DPEHPK3PXP",
"issuer": "GitHub",
"digits": 6,
"period": 30,
"algorithm": "sha1",
"created_at": "2024-01-15T10:30:00+00:00"
}
],
"count": 1
}
Create Token
Create a new TOTP token. Supports two methods:
Method 1: From OTPAuth URI
POST /tokens
Content-Type: application/json
{
"uri": "otpauth://totp/GitHub:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub"
}
Method 2: Manual Parameters
POST /tokens
Content-Type: application/json
{
"name": "GitHub",
"secret": "JBSWY3DPEHPK3PXP",
"issuer": "GitHub",
"digits": 6,
"period": 30,
"algorithm": "sha1"
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
uri |
string | No* | - | OTPAuth URI (from QR code) |
name |
string | No* | - | Token display name |
secret |
string | No* | - | Base32-encoded secret |
issuer |
string | No | TOTPHog |
Service name |
digits |
integer | No | 6 |
Code length (6 or 8) |
period |
integer | No | 30 |
Validity period (seconds) |
algorithm |
string | No | sha1 |
Hash algorithm |
*Either uri OR name+secret must be provided.
Response (201 Created):
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "GitHub",
"secret": "JBSWY3DPEHPK3PXP",
"issuer": "GitHub",
"digits": 6,
"period": 30,
"algorithm": "sha1",
"created_at": "2024-01-15T10:30:00+00:00"
}
}
Get Token
Get a single token by ID.
Response:
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "GitHub",
"secret": "JBSWY3DPEHPK3PXP",
"issuer": "GitHub",
"digits": 6,
"period": 30,
"algorithm": "sha1",
"created_at": "2024-01-15T10:30:00+00:00"
}
}
Delete Token
Delete a token by ID.
Response:
Delete All Tokens
Delete all stored tokens.
Response:
Get Current Code
Get the current TOTP code for a token.
Response:
{
"success": true,
"data": {
"code": "123456",
"remaining_seconds": 15,
"period": 30,
"generated_at": "2024-01-15T10:30:00+00:00"
}
}
Get All Codes
Get current codes for all tokens.
Response:
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "GitHub",
"secret": "JBSWY3DPEHPK3PXP",
"issuer": "GitHub",
"digits": 6,
"period": 30,
"algorithm": "sha1",
"created_at": "2024-01-15T10:30:00+00:00",
"current_code": {
"code": "123456",
"remaining_seconds": 15,
"period": 30,
"generated_at": "2024-01-15T10:30:00+00:00"
}
}
]
}
Get QR Code
Get a QR code image (PNG) for a token. This QR code can be scanned by authenticator apps.
Response: PNG image (image/png)
Error Codes
| HTTP Status | Description |
|---|---|
| 200 | Success |
| 201 | Created (new token) |
| 400 | Bad Request (invalid input) |
| 404 | Token not found |
| 500 | Server error |
Examples
cURL
# Create a token
curl -X POST http://localhost:8045/api/v1/tokens \
-H "Content-Type: application/json" \
-d '{"name": "GitHub", "secret": "JBSWY3DPEHPK3PXP"}'
# Get current code
curl http://localhost:8045/api/v1/tokens/{id}/code
# Get all codes
curl http://localhost:8045/api/v1/codes
# Delete a token
curl -X DELETE http://localhost:8045/api/v1/tokens/{id}
PHP
<?php
// Create a token
$ch = curl_init('http://localhost:8045/api/v1/tokens');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'GitHub',
'secret' => 'JBSWY3DPEHPK3PXP'
])
]);
$response = json_decode(curl_exec($ch), true);
$token = $response['data'];
curl_close($ch);
// Get current code
$ch = curl_init("http://localhost:8045/api/v1/tokens/{$token['id']}/code");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$codeResponse = json_decode(curl_exec($ch), true);
$code = $codeResponse['data']['code'];
curl_close($ch);
echo "Current code: $code\n";
JavaScript (fetch)
// Create a token
const response = await fetch('http://localhost:8045/api/v1/tokens', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'GitHub', secret: 'JBSWY3DPEHPK3PXP' })
});
const { data: token } = await response.json();
// Get current code
const codeResponse = await fetch(`http://localhost:8045/api/v1/tokens/${token.id}/code`);
const { data: { code } } = await codeResponse.json();
console.log('Current code:', code);
Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type TokenResponse struct {
Success bool `json:"success"`
Data struct {
ID string `json:"id"`
Name string `json:"name"`
Secret string `json:"secret"`
} `json:"data"`
}
type CodeResponse struct {
Success bool `json:"success"`
Data struct {
Code string `json:"code"`
RemainingSeconds int `json:"remaining_seconds"`
} `json:"data"`
}
func main() {
// Create a token
payload := []byte(`{"name": "GitHub", "secret": "JBSWY3DPEHPK3PXP"}`)
resp, _ := http.Post(
"http://localhost:8045/api/v1/tokens",
"application/json",
bytes.NewBuffer(payload),
)
defer resp.Body.Close()
var tokenResp TokenResponse
json.NewDecoder(resp.Body).Decode(&tokenResp)
// Get current code
codeResp, _ := http.Get(
fmt.Sprintf("http://localhost:8045/api/v1/tokens/%s/code", tokenResp.Data.ID),
)
defer codeResp.Body.Close()
var code CodeResponse
json.NewDecoder(codeResp.Body).Decode(&code)
fmt.Printf("Current code: %s\n", code.Data.Code)
}
OpenAPI Specification
For interactive API documentation, see the OpenAPI specification.