suno-core 0.8.0

Engine for a download-only Suno.ai library tool: feed selection, sync reconciliation, and audio tagging.
Documentation
//! Endpoints and tunables for the Suno and Clerk APIs.
//!
//! These mirror the values the Suno web client uses. The API is undocumented,
//! so they may need updating if Suno changes its endpoints.

pub(crate) const SUNO_API_BASE_URL: &str = "https://studio-api-prod.suno.com";
pub(crate) const CLERK_BASE_URL: &str = "https://clerk.suno.com";
pub(crate) const CLERK_JS_VERSION: &str = "4.72.1";
pub(crate) const CLERK_TOKEN_JS_VERSION: &str = "4.72.0-snapshot.vc141245";
pub(crate) const CDN_BASE_URL: &str = "https://cdn1.suno.ai";
/// Canonical public web URL base for a song page (`<base>/<clip id>`). Used in
/// the plain-text details sidecar so a human can open the song in a browser.
pub(crate) const SUNO_SONG_BASE_URL: &str = "https://suno.com/song";

/// Refresh a JWT this many seconds before it expires.
pub(crate) const JWT_REFRESH_BUFFER: i64 = 60;
/// Hard cap on feed pages so a runaway `has_more` cannot loop forever.
pub(crate) const MAX_PAGES: u32 = 100;
/// Clips requested per feed page. A larger page means fewer requests to walk a
/// big library, so the rate limiter is tripped less often.
pub(crate) const FEED_PAGE_SIZE: u32 = 50;
/// Wait this long between successive feed pages to pace a full-library walk
/// under Suno's rate limiter, rather than only reacting to a 429.
pub(crate) const FEED_PAGE_DELAY: std::time::Duration = std::time::Duration::from_millis(500);
/// Retry a rate-limited or transient API request this many times before failing.
pub(crate) const API_MAX_RETRIES: u32 = 3;

/// The library feed endpoint. Paged for listing, or filtered with `?ids=` to
/// gap-fill specific ancestors (including trashed ones) during lineage
/// resolution.
pub(crate) const FEED_V2_PATH: &str = "/api/feed/v2/";
/// The dedicated parent-lookup endpoint: one hop up a clip's lineage.
pub(crate) const CLIP_PARENT_PATH: &str = "/api/clips/parent";
/// The caller's own playlists, paged. Trashed and share-list playlists are
/// excluded by query so the listing is the account's authoritative own set.
pub(crate) const PLAYLIST_ME_PATH: &str = "/api/playlist/me";
/// One playlist's detail, including its ordered `playlist_clips`. The id and a
/// trailing slash are appended: `/api/playlist/{id}/`.
pub(crate) const PLAYLIST_PATH: &str = "/api/playlist/";
/// Fetch at most this many clip ids per `?ids=` request so a batch cannot build
/// an over-long URL.
pub(crate) const IDS_PER_REQUEST: usize = 40;