Data Contracts
Every request body and query is validated against a Zod schema, and every
response is a typed DTO. The single source of truth is the @swayzio/domain
package (packages/domain/src/schemas.ts and siblings). This page is the
field‑level reference; each API page links here.
The redaction pattern (read this first)
The most important contract rule: internal schemas carry sensitive fields;
client* / public* variants strip them at the route boundary. Specifically,
client/public DTOs .omit():
ownerId— the account id (never exposed; it’s implicit in your session)storageUri(gs://…) — raw object locations (you get a short‑lived signed URL instead)- provider / model internals —
trackingProvider,trackingSyncStatus,provider,modelVersion,sourceAssetId,chunkIndex, etc. createdByon presentation surfaces reachable by non‑owners
If you’re writing a client against a response, use the client* / public*
shape — the internal schema names below describe the full row, but the wire
format you receive has the listed fields removed.
Tracks
trackSchema → Track — id, ownerId, title, artist, isrc?, iswc?, releaseDate?, durationMs?, bpm?, musicalKey?, userTags: string[], machineTags: MachineTag[], primaryAssetId?, visibility, createdAt, updatedAt, deletedAt?.
Client surfaces omit ownerId; public presentation tracks are reduced to
{ id, title, artist, durationMs?, bpm?, musicalKey? }.
updateTrackMetadataRequestSchema—title? (1..240), artist? (≤240), isrc? (12‑char or null), iswc? (≤32 or null), releaseDate? (YYYY‑MM‑DD or null); ≥1 field. →Track.deletedTrackResponseSchema—{ id, status: "deleted" }.listTracksRequestSchema— query forGET /v1/tracks(see Tracks).machineTagSchema→MachineTag—source, provider?, modelName?, modelVersion?, type, value, confidence? (0..1), rawLabel?, curationStatus?, createdAt.
Track resources
| Schema | Shape (client variant) |
|---|---|
trackTagDetailResponseSchema | trackId, bpm?, musicalKey?, userTags[], machineTags[], groups[], latestTaggingJob? |
trackPeaksResponseSchema | trackId, assetId, signedUrl?, readStatus, payload?: { version, channels, sampleRateHz, peakCount, durationMs, peaks: number[] } |
clientTrackLyricsResponseSchema | { trackId, sections[], segments[], latestTranscriptionJob? } — strips provider, modelVersion, sourceAssetId, chunk* |
clientTrackStemsResponseSchema | { trackId, stems[], latestStemSeparationJob? } — strips storageUri, playbackUrl per stem |
clientTrackVersionsResponseSchema | { trackId, current?, versions[] } — strips playbackUrl |
clientTrackProcessingStatusSchema | { trackId, stages[], assets[] (no storageUri), remoteDispatches[], readiness } |
Readiness (trackReadinessSchema) — status, playable, waveformReady, coreTagsReady, coreReady, deepAnalysisReady, userMessage, failureReasonCode?, blockers[], warnings[], checks: { playback, waveform, tags, stems, lyrics, embeddings }. Each check: { status, label, message, reasonCode?, required, retryable }.
Rights & split‑sheets
Two parallel rights models:
- Legacy
trackRightsEntrySchema/trackRightsPayloadSchema— theGET /v1/tracks/:id/rightsplaceholder (currently returns empty). - Live split‑sheet — a discriminated union
splitSheetEntrySchemaoncategory(master | writer | publisher | sub_publisher), assembled intotrackSplitSheetPayloadSchema→{ trackId, ownerId, songTitle, address, intendedUse, master[], writers[], publishers[], status }. Status carriesmasterTotal, writerTotal, publisherTotal, compositionTotal, four*Completeflags,isComplete,validationErrors[]. Public variant omitsownerId. Replace viareplaceTrackSplitSheetRequestSchema(422on structural failure).
Packs
packSchema→Pack—id, ownerId, name, description, visibility (private|link|public), imageAssetId?, imageUrl?, type (standard|collaborative), createdAt, updatedAt.clientPackSchemaomitsownerId.clientPackPresentationResponseSchema—{ canAddToLibrary, canDownload, canSave, pack, shareSettings, trackingLink?, tracks: clientPresentationTrack[] }.packShareSettingsSchema—accessLevel, disableDownloads, disableAddToLibrary, disableSocials, disableSaving, hideSplits, hideStems, hideVersions, hasAccessCode.packAccessGrantSchema—{ id, packId, ownerId, targetUserId?, email?, accessType, inviteStatus, invitedAt, acceptedAt?, revokedAt?, latestDelivery? }; client responses stripownerIdand collapse delivery to{ deliveryStatus, sentAt? }.packTrackingLinkSchema→ clientclientPackTrackingLinkSchema(Dub link) —{ id, packId, slug, name, hasAccessCode, isDefault, shareUrl?, relativePath? }(omitsownerId, createdBy, trackingProvider, trackingSyncStatus).packAnalyticsResponseSchema— per‑pack native rollup:totals { views, plays, downloads, externalClicks, saves, shares, trackingLinkOpens, uniqueVisitors }, eventsByType[], tracks[].
Analytics (Dub)
dubAnalyticsResponseSchema—{ available, reason?, event, groupBy, range, revenueVisible, count?, timeseries?, items?, retrievedAt }. Metrics are{ clicks, leads, sales, saleAmount }; items add{ label, country?, region?, city?, linkId?, shortLink?, url?, entity? }.dubAnalyticsEventsResponseSchema—{ available, reason?, revenueVisible, events[], retrievedAt }.
revenueVisible is computed server‑side from staff status. When false,
sales and saleAmount are zeroed before the response is sent — the figures
never reach a non‑staff client. See Analytics.
Libraries & collaborators
librarySchema/clientLibrarySchema(omitsownerId);libraryShareSchema(accessType: viewer|editor|admin|revoked).collaboratorSchema→Collaborator—{ id, ownerId, name, email?, pro?, ipiNumber?, entityType?, roles: (writer|publisher|master_owner)[] };clientCollaboratorSchemaomitsownerId.collaboratorSummarySchemaaddscollaborationCount, works[].
Uploads & playback
createUploadRequestSchema—{ intent, fileName, contentType, byteSize, trackId?, parentTrackId?, packId? }with MIME/size validation (audio ≤500MB, artwork ≤25MB, document ≤100MB).clientCreateUploadResponseSchema—{ uploadId, trackId, assetId, signedUrl, method: "PUT", expiresAt, requiredHeaders, finalizeUrl }(omitsobjectName, storageUri).clientPlaybackUrlResponseSchema—{ assetId, trackId, signedUrl, method: "GET", expiresAt }(omitsstorageUri); download addsfileName.
Billing
billingStatusResponseSchema—{ customerConfigured, planId, status, stripeCustomerId?, stripeSubscriptionId?, availablePlanIds?, cancelAtPeriodEnd?, currentPeriodEnd? }.billingChangePlanResponseSchema—{ mode: checkout|switched, planId?, sessionId?, url? }.
Agent tools
agentToolContractSchema— the per‑tool governance contract (purpose, tier, read/write class, input/output schema, approval flag, limits, redaction policy).agentToolExecutionRequestSchema/agentToolExecutionResponseSchema— execute one tool and the audit envelope. See Agent Tools.
Service‑to‑service contracts
media-intelligence.ts and audio-embedding.ts define the Modal control‑plane
DTOs (create‑job, callback, lane results, error codes; embedding job + vectors).
These are versioned (mediaIntelligenceContractVersion,
CONTRACT_VERSION for embeddings) and not called by app clients — see
Internal & Services.