All notable changes to this project are documented here.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Lenient parsing now coerces convertible wrong-typed scalars instead of
always zeroing them: a numeric string parses into a number field
(
{"score":"85"}→ 85, floats truncate), numbers and bools render into string fields, numbers map into bool fields (!= 0), and recognized boolean strings ("true"/"1"/"yes"/"on", "false"/"0"/"no"/"off"/"", case-insensitive) map into bool fields. Unconvertible values (garbage strings, wrong-shaped objects/arrays) still degrade to the zero value — never an error, never a misleading zero from a partial parse. Numeric strings parse strictly: the whole trimmed string must be a finite number.
- Response parsing is now lenient about wrong-typed fields: a field whose
wire value has an unexpected type (e.g. a string
score, a numerictimecode) degrades to its zero value instead of failing the whole call. This applies acrossRecognition,EnterpriseMatch,Stream,LyricsResult, the provider metadata blocks, and stream callbacks/longpoll payloads. - Fixed data races: the
Streams()/CustomCatalog()/Advanced()sub-clients are initialized when theClientis constructed (concurrent first accesses were racy), andStreamsClient.DeriveLongpollCategorynow reads the API token through the guarded accessor, so it is safe alongsideSetAPIToken. RecognizeOptions.TimeoutandEnterpriseOptions.Timeoutare now applied: each bounds its call with a per-call deadline. Previously the fields were accepted but ignored.- File-path sources no longer leak a file handle per request attempt: the
transport closes the file it opened once the attempt finishes.
Caller-supplied
io.Readersources are never closed by the SDK. - The v0 compatibility shims no longer drop options:
RecognizeByUrl/RecognizeByFileforward all legacy option keys (not justmarket), and theFindLyrics/AddStreamshims forward their options maps as extra form fields. - Longpoll requests are sized to the poll timeout plus a margin, so
LongpollOptions.Timeoutvalues above 60 seconds work instead of being cut short by the standard HTTP timeout. Applies to the authenticated poller and the tokenlessLongpollConsumer. - The longpoll preflight only reports "no callback URL is configured" when
the server's error #19 actually indicates that condition; other #19
responses (e.g. maintenance) pass through unchanged. The
GetCallbackUrldoc comment now describes the real error mapping. Advanced().FindLyricserrors now carry the real HTTP status and request ID, and code-51 deprecation warnings pass through with the result, same as every other endpoint.Recognition.StreamingURL,StreamingURLs, andPreviewURLnow resolve direct provider URLs and previews from the decoded metadata blocks (apple_music,spotify,deezer,napster).
- The
OnEventinspection hook now fires for every API call — enterprise recognition, stream management, custom catalog uploads, andAdvanced()requests — not onlyRecognize.
EnterpriseMatchgainsStartSeconds/EndSeconds: file-absolute match positions computed from the chunk offset plus the fragment-relativestart_offset/end_offset.nilwhen the chunk carried no usable offset.- Enterprise requests send
accurate_offsets=trueby default; setEnterpriseOptions.AccurateOffsetsto a non-nilfalseto opt out.
- Stream callbacks and longpoll matches whose
resultsarray is absent or empty parse without error:Songstays its zero value andAlternativesis empty.
- Documentation: option docs updated to the
ReturnMetadataname. No API changes.
- The
Returnoption onRecognizeOptions/EnterpriseOptionsis renamedReturnMetadata.
- New
ExtraParameters map[string]stringonRecognizeOptions,EnterpriseOptions,AddStreamRequest, andSetCallbackUrlOptions: pass any form field the typed options don't cover. Typed fields win on collision.
- The
Returnoption is now a comma-separated string (e.g."apple_music,spotify") instead of a[]string. NewJoinProvidershelper builds the string from a list. SetCallbackUrlOptions.ReturnMetadataappends?return=<csv>to the callback URL; a URL that already carries areturnparameter combined with a non-emptyReturnMetadatareturns an error instead of silently overwriting.
- Adds the
go.modretract directive for v1.5.10. Public API matches v1.5.9.
- Retracted — use v1.5.11. Public API matches v1.5.9.
CustomCatalog.Addno longer retries by default.
- New
LongpollByRadioID/LongpollByRadioIDContext: one-step longpoll subscription from a radio ID — the SDK derives the category from the client's token locally. - The typed error and event symbols are renamed
Audd*→AudD*(AudDAPIError,AudDConnectionError,AudDSerializationError,AudDCustomCatalogAccessError,AudDEvent). The old names remain as deprecated aliases until v2.0.0.
- README: the quickstart constructor uses a
your-api-tokenplaceholder with a pointer to dashboard.audd.io.
- README: CI and contract badges.
- LICENSE copyright line updated to "AudD, LLC (https://audd.io)".
- README and example polish. No API changes.
- Internal cleanup of
LongpollPoll. No API changes.
- Longpoll rework:
Streams().Longpoll(...)andLongpollConsumer.Iterate(...)return a*LongpollPollwith typedMatches/Notifications/Errorschannels (previously a single event-channel). - Callback types renamed:
StreamCallbackMatch(withSong+Alternatives) andStreamCallbackSongreplace the previous result/payload shapes.ParseCallback/HandleCallbackare package-level functions.
- Public sub-client methods now follow the same Style B pattern as
Recognize/RecognizeContext: every method has a no-context convenience form (Foo(args)) plus an explicit-context form (FooContext(ctx, args)). Callers passingcontext.Background()to the previous ctx-taking signatures should drop the argument; callers needing cancellation should switch to the new*Contextvariant.StreamsClient.SetCallbackUrl/SetCallbackUrlContextStreamsClient.GetCallbackUrl/GetCallbackUrlContextStreamsClient.Add/AddContextStreamsClient.SetURL/SetURLContextStreamsClient.Delete/DeleteContextStreamsClient.List/ListContextStreamsClient.Longpoll/LongpollContextAdvancedClient.FindLyrics/FindLyricsContextAdvancedClient.RawRequest/RawRequestContextCustomCatalogClient.Add/AddContextLongpollConsumer.Iterate/IterateContext
- Contract tests now skip cleanly via
t.Skip()whenAUDD_OPENAPI_FIXTURESis not set, sogo test ./...in CI no longer fails on missing sibling-repo fixtures. The dedicatedcontract.ymljob still runs them by setting the env var. - Integration tests (build tag
integration) now compile against the currentRecognizeContextsignature.
README polish: tightened the Capabilities table (longpoll variants
collapsed into a single Streams row + a dedicated Streams subsection),
dropped the implementation-detail thread-safety paragraph from the intro,
removed internal design-spec breadcrumbs from user-visible doc comments,
and updated the install snippet to @v1.4.0. No API changes.
Coordinated v1.3.0 stable release across the audd-sdks family. No breaking changes; the version bump signals API stability across all nine SDKs.
The full v0.3.0 polish — env-var auto-pickup, streaming/preview helpers
with metadata fallback, onEvent inspection hook, thread-safe token
rotation, plus per-language work (JPMS module-info, Kotlin Flow<LongpollEvent>,
Swift Sendable + DocC, .NET AOT/source-gen + IServiceCollection, Rust
TLS feature flags + Serialize, PHP PSR-3 logger, Python __repr__ +
pretty_print(), Go slog example) is now the v1.3.0 baseline.
The official refreshed Go SDK. Adds namespaced sub-clients
(client.Streams(), client.CustomCatalog(), client.Advanced()),
tokenless LongpollConsumer, cost-aware retry, per-attempt source
re-opener, code-51 deprecation pass-through, HTTP-vs-JSON error
distinction, and hardened LongpollConsumer failure modes.
The existing flat API (client.RecognizeByUrl, client.AddStream,
client.FindLyrics) remains as deprecated wrappers that delegate to the
new namespaced shape. They will be removed at v2.0.0.