Skip to content

API · /clean-songs

Clean Songs

degraded

Analyze customer-provided text in Portuguese and English for profanity, drugs, violence, and explicit sexual content. Get clear classifications, minimal evidence, and line numbers using deterministic rules.

api.oanor.com/clean-songs
Get an API key Try in playground → Contact provider

Machine-readable spec so AI agents can integrate this API.

/api/clean-songs/openapi.json
/api/clean-songs/llms.txt

Discovery: GET /api/index.json lists every API.

Clean Songs — live data on the oanor API marketplace

Test this API right in your browser

10 free test calls per day — pick a plan for production use.

API health

degraded
Uptime
100.00%
Server probes · 24h
Avg latency
4470 ms
Server probes · 24h
Subscribers
0
active
Total calls
12
last 7 days
status Full status page → · 2 probes/24h

Pricing

Pick a tier — billed monthly, cancel anytime.

Free

Test the API with 1,000 requests per month.

Free

  • 1,000 calls / month
  • 100 calls / day
  • 1 requests / second
  • Hard cap (429 above quota, no overage)
  • 1,000 requests per month
  • 100 requests per day
  • Up to 1 request per second
  • Portuguese and English
  • Four content categories
  • Custom terms and review phrases
  • Up to 7,000 characters per request
Sign in to subscribe

Built by

Frequently asked questions

Quick answers about pricing, quotas, and integration.

How do I get an API key for Clean Songs?
Sign up for free at oanor.com, generate an API key from the developer dashboard, and call Clean Songs with the x-oanor-key header. No credit card needed for the free tier.
What's the rate limit for Clean Songs?
Free tier allows 1 request per second. Paid plans scale up to 50 requests per second on the Mega tier. Hard limits return HTTP 429 above the quota — no surprise overage charges.
How much does Clean Songs cost?
Clean Songs has a free tier with 100 calls / month. Paid plans start at €15.00 / month with higher quotas and faster rate limits.
Can I cancel my subscription anytime?
Yes. Plans are billed monthly and you can cancel anytime from your billing dashboard. No long-term contracts and no cancellation fee.
Is Clean Songs GDPR-compliant?
All requests to Clean Songs go through our EU-based gateway. Your upstream API key never leaves our server and no personal data is shared with the upstream provider beyond the request you send.

Pick an endpoint from the list on the left to see its details and try it.

Code snippets

Sign up to get an API key, then call any path under your slug.

curl https://api.oanor.com/clean-songs/v1/health \
  -H "x-oanor-key: oanor_test_..."
const res = await fetch("https://api.oanor.com/clean-songs/v1/health", {
  headers: { "x-oanor-key": "oanor_test_..." }
});
const data = await res.json();
$ch = curl_init("https://api.oanor.com/clean-songs/v1/health");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-oanor-key: oanor_test_..."]);
$response = curl_exec($ch);
import requests
r = requests.get(
    "https://api.oanor.com/clean-songs/v1/health",
    headers={"x-oanor-key": "oanor_test_..."},
)
print(r.json())

Documentation

Clean Songs — Text Content Analysis

Analyze your own or authorized text for profanity, drug references, violence, sexual content, and custom terms. Supports Portuguese and English. No song search, lyrics retrieval, scraping, or music catalog is provided. You can also report analysis issues and submit lyrics for curation, and track both.

Authentication

Subscribe through Oanor and send your subscription key in the x-oanor-key header. Send JSON with Content-Type: application/json. Never include a provider's internal upstream token.

Analyze text

POST https://api.oanor.com/clean-songs/v1/analyze-text

{
  "text": "Uma tarde tranquila.",
  "language": "pt",
  "rules": ["profanity", "drugs", "violence", "sexual_content"],
  "custom_terms": [],
  "review_contexts": []
}

Text is required, must not be blank, and must not exceed 7,000 characters. Language is pt (default) or en; it is not detected automatically. Rules default to all four categories; when provided, select 1–4 unique categories. Each optional term list accepts up to 20 unique terms, with up to 80 characters per term. Review contexts are literal phrases, not AI instructions.

To test detection, submit "text": "Uma tarde tranquila porra." with "rules": ["profanity"]. Expect status: rejected with a profanity violation.

curl --request POST 'https://api.oanor.com/clean-songs/v1/analyze-text' \
  --header 'x-oanor-key: YOUR_OANOR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"text":"Uma tarde tranquila porra.","language":"pt","rules":["profanity"]}'

A successful analysis returns HTTP 200 and fields status, rule_version, language, violations, summary, and truncated.

StatusMeaning
approvedNo occurrence detected under the requested checks.
rejectedA rejecting occurrence was detected.
review_requiredA review condition or findings limit requires human review.

Findings include category, severity, minimal evidence, line number starting at 1, reason, and confidence. Confidence is a fixed detector score, not a calibrated probability. Up to 200 findings are returned; a truncated result is never approved. Complete JSON bodies are limited to 64 KiB. Rate and monthly limits depend on your subscription.

Detection is deterministic and lexical. It may miss expressions or flag quoted, educational, or negated references. An approved result is not a guarantee of suitability. Use human review for sensitive decisions. Custom terms and review phrases apply only to the current call and are not saved as personal rule sets.

Report an analysis issue

POST https://api.oanor.com/clean-songs/v1/reports

Submit a false positive or false negative for administrative review. This is a separate, optional submission: analysis requests do not automatically create reports.

{
  "title": "Song name",
  "artist": "Artist name",
  "language": "pt",
  "rule_version": "text-1.1/rules-2026.3",
  "rules": ["sexual_content"],
  "reported_status": "approved",
  "expected_status": "rejected",
  "feedback": "This song is offensive.",
  "consent_to_store": true
}

Reviewers see the song name, the artist and this sentence. Do not rely on the report to display technical metadata.

title and artist are required, 1–200 characters each. Use the actual rule version and status returned by your analysis. Reported and expected statuses must differ. Feedback is the complaint shown to reviewers, 5–500 characters. The optional excerpt is limited to 280 characters. Do not submit full lyrics, personal data, or secrets. The explicit boolean consent_to_store: true authorizes storage of report metadata, feedback, and the optional excerpt for review. Extra fields, including a full text field, are rejected.

curl --request POST 'https://api.oanor.com/clean-songs/v1/reports' \
  --header 'x-oanor-key: YOUR_OANOR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"title":"Song name","artist":"Artist name","language":"en","rule_version":"text-1.1/rules-2026.3","rules":["sexual_content"],"reported_status":"approved","expected_status":"rejected","feedback":"This song is offensive.","consent_to_store":true}'

A confirmed submission returns HTTP 202. tracking_token is shown once. Store it securely and do not put it in a URL, log, or support ticket. It cannot be retrieved later. The report ID alone does not authorize a status check.

{
  "report_id": "0123456789abcdef0123456789abcdef",
  "status": "pending",
  "tracking_token": "exampleTrackingToken_DoNotReuse_00000000000"
}

Keep the report ID for support. Reports are reviewed by administrators and do not automatically change detection rules. There is no public report listing and no guaranteed review time. A failed delivery returns an error rather than a false acknowledgement. Retrying an uncertain delivery may create duplicates; no idempotency guarantee is provided. Reports may count toward your subscription's call quota.

Check review status

GET https://api.oanor.com/clean-songs/v1/reports/{report_id}

Send the same x-oanor-key plus X-Report-Token from the 202 response. The tracking token does not expire: you can check the same report at any time, including after it is approved or rejected, for as long as the report is kept in the review queue. Review may take a while, so poll sparingly (for example, a few times per day).

curl --request GET 'https://api.oanor.com/clean-songs/v1/reports/0123456789abcdef0123456789abcdef' \
  --header 'x-oanor-key: YOUR_OANOR_API_KEY' \
  --header 'X-Report-Token: YOUR_REPORT_TRACKING_TOKEN'

HTTP 200 returns only:

{
  "report_id": "0123456789abcdef0123456789abcdef",
  "status": "pending"
}

pending is waiting for review. approved means an administrator accepted the report. rejected means the administrator did not confirm the reported error. Neither status publishes a rule change. The response does not include text, feedback, excerpt, internal notes, or the token. 401 means the subscription key or tracking token is missing or malformed. 404 means the report is unknown or the token does not match; those cases look the same. Reports created before tracking tokens cannot be checked with this route. Do not cache the response.

Submit lyrics for curation

POST https://api.oanor.com/clean-songs/v1/lyric-submissions

Send complete lyrics with the song title and artist for review by our administrators. Lyrics submitted through this API are kept only for curation and an internal archive. They are never displayed or redistributed to app users, even when approved.

{
  "title": "Song name",
  "artist": "Artist name",
  "lyrics": "First line of the lyrics\nSecond line of the lyrics",
  "rights_confirmed": true,
  "consent_to_store": true
}

title and artist are required, 1–200 characters each. lyrics is required, up to 7,000 characters. rights_confirmed: true states that you hold the rights or license needed to submit these lyrics. consent_to_store: true authorizes storage for curation and, if approved, in the internal archive. Both must be the boolean true. Extra fields are rejected.

curl --request POST 'https://api.oanor.com/clean-songs/v1/lyric-submissions' \
  --header 'x-oanor-key: YOUR_OANOR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"title":"Song name","artist":"Artist name","lyrics":"First line\nSecond line","rights_confirmed":true,"consent_to_store":true}'

A confirmed submission returns HTTP 202 with submission_id, status: pending and a tracking_token. As with reports, the token is shown once, cannot be retrieved later and must not go in a URL, log or support ticket.

If the same lyrics for the same song are already in the queue, the API returns 409 already_submitted without a token. Title and artist are compared ignoring case, accents and extra spaces; lyrics are compared ignoring spaces at the start and end of each line. There is no guaranteed review time.

Check curation status

GET https://api.oanor.com/clean-songs/v1/lyric-submissions/{submission_id}

Send the same x-oanor-key plus X-Submission-Token with the token from the 202 response. The token does not expire: you can check the submission at any time, including long after it was approved or rejected.

curl --request GET 'https://api.oanor.com/clean-songs/v1/lyric-submissions/0123456789abcdef0123456789abcdef' \
  --header 'x-oanor-key: YOUR_OANOR_API_KEY' \
  --header 'X-Submission-Token: YOUR_SUBMISSION_TRACKING_TOKEN'

HTTP 200 returns only submission_id and status. pending is waiting for review. approved means the lyrics were accepted into the internal archive; they are still not shown to app users. rejected means they were not accepted; the lyrics are deleted 30 days after rejection, but the status stays available. The response never includes the lyrics or reviewer notes. 401 means the subscription key or tracking token is missing or malformed. 404 means the submission is unknown or the token does not match.

Errors

401: invalid authentication; 409: lyrics already submitted; 413: body too large; 415: unsupported content type or encoding; 422: invalid payload; 429: rate or quota exceeded; 500: internal error; 503: service or report delivery unavailable. Gateway errors may differ.

Privacy and content rights

The analysis backend does not persist analysis text by default. Its application logs do not include submitted content or customer credentials. Your application controls storage of its own requests and results.

Opt-in reports are an exception: report metadata, feedback, and the optional excerpt are stored in the administrative review queue until authorized manual deletion. No automatic report expiry is currently implemented. Reference your report ID when requesting support about a stored report. Do not describe reports as zero retention.

Lyric submissions are also stored: lyrics stay in the curation queue until reviewed. Approved lyrics are kept in an internal archive that is not shown to app users; rejected lyrics are deleted after 30 days. The submission status and token hash are kept so you can keep checking it.

Requests pass through Oanor and hosting infrastructure, whose retention policies also apply. End-to-end zero retention has not been independently verified.

You are responsible for having the rights and permissions to submit text and, when reporting, to retain the evidence for review. Do not use this API to retrieve or redistribute third-party lyrics, submit unauthorized content, circumvent quotas, or unlawfully process personal information.

Ratings

Sign in to rate.

No reviews yet.

Discussion

Ask questions, share usage tips, get answers from the provider and other developers. Public — anyone can read.

Sign in to start a thread or reply.

Sign in

New thread

/ 4000

📌 Pinned 🔒 Locked

·

· ·

/ 4000

🔒 This thread is locked — no new replies.

  • No threads yet — start the discussion.

Support

Private 1:1 support with the provider — billing questions, integration issues, account problems. Only you and the provider team can see these threads.

Sign in to open a support ticket.

Sign in

Open new ticket

Describe what you need help with. The provider team gets an email and replies on the ticket page.

  • No tickets yet for this API.

Subscription active — calls can start immediately.

Send your first request —

Subscription active — copy a snippet and fire off your first call.