SonicAI Watermark API

Backend base URL: https://raphael-98044--sonic-watermark-web.modal.run

GET /health

Health check.

curl -X GET https://raphael-98044--sonic-watermark-web.modal.run/health

Sample response:

{
  "status": "healthy",
  "timestamp": 1726147200.123,
  "service": "watermark-decoder-api"
}

POST /decode-watermark

Decode watermark from an audio file. Optional one-off JSON overrides can be uploaded.

Request: multipart/form-data

  • file: required audio file (.wav, .mp3, .flac, .ogg, .m4a, .aac)
  • params: optional JSON file for one-off overrides. Fields: {"no_keys": number}

cURL (default config):

curl -X POST https://raphael-98044--sonic-watermark-web.modal.run/decode-watermark   -F 'file=@/path/to/audio.wav'

cURL (one-off JSON params):

curl -X POST https://raphael-98044--sonic-watermark-web.modal.run/decode-watermark   -F 'file=@/path/to/audio.wav'   -F 'params=@/path/to/overrides.json;type=application/json'

Sample response (detected):

{
  "status": "detected",
  "key": "ABCD",
  "method": "direct"
}

Sample response (not found):

{
  "status": "not_found",
  "message": "No watermark key could be extracted after all restoration attempts"
}

Python (requests):

import requests

url = 'https://raphael-98044--sonic-watermark-web.modal.run/decode-watermark'
files = {'file': open('/path/to/audio.wav', 'rb')}
r = requests.post(url, files=files, timeout=300)
print(r.status_code)
print(r.json())

Python with one-off JSON params:

import requests

url = 'https://raphael-98044--sonic-watermark-web.modal.run/decode-watermark'
files = {
  'file': open('/path/to/audio.wav', 'rb'),
  'params': ('overrides.json', open('/path/to/overrides.json', 'rb'), 'application/json')
}
r = requests.post(url, files=files, timeout=300)
print(r.status_code)
print(r.json())

POST /encode-watermark

Encode watermark into an audio file and download the encoded file. Optional one-off JSON overrides can be uploaded.

Request: multipart/form-data

  • file: required audio file (.wav, .mp3, .flac, .ogg, .m4a, .aac, .aiff)
  • params: optional JSON file for one-off overrides. Fields: {"key_strength": "low|medium|high", "key": "string"}

cURL (default config, save server-provided filename):

curl -X POST https://raphael-98044--sonic-watermark-web.modal.run/encode-watermark   -F 'file=@/path/to/audio.wav' -OJ

cURL (one-off JSON params, explicit output path):

curl -X POST https://raphael-98044--sonic-watermark-web.modal.run/encode-watermark   -F 'file=@/path/to/audio.wav'   -F 'params=@/path/to/overrides.json;type=application/json'   --output /path/to/audio_encoded.wav

Python (requests), save to disk:

import requests

url = 'https://raphael-98044--sonic-watermark-web.modal.run/encode-watermark'
files = {'file': open('/path/to/audio.wav', 'rb')}
with requests.post(url, files=files, stream=True, timeout=600) as r:
    r.raise_for_status()
    with open('/path/to/audio_encoded.wav', 'wb') as f:
        for chunk in r.iter_content(chunk_size=8192):
            if chunk:
                f.write(chunk)

Python (one-off JSON params):

import requests

url = 'https://raphael-98044--sonic-watermark-web.modal.run/encode-watermark'
files = {
  'file': open('/path/to/audio.wav', 'rb'),
  'params': ('overrides.json', open('/path/to/overrides.json', 'rb'), 'application/json')
}
with requests.post(url, files=files, stream=True, timeout=600) as r:
    r.raise_for_status()
    with open('/path/to/audio_encoded.wav', 'wb') as f:
        for chunk in r.iter_content(chunk_size=8192):
            if chunk:
                f.write(chunk)

Notes

  • Max file size: 50MB
  • Decoding timeout: 5 minutes; Encoding streams output to minimize memory
  • When a one-off config is uploaded, it is used only for that single request