naftiko: 1.0.0-alpha2 info: label: Last.fm — Scrobbling Workflow description: Authenticated end-to-end scrobbling workflow — acquire mobile session, mark now-playing, scrobble a played track, optionally love it. tags: - Last.fm - Music - Scrobbling - AudioScrobbler created: '2026-05-29' modified: '2026-05-29' binds: - namespace: env keys: LASTFM_API_KEY: LASTFM_API_KEY LASTFM_SHARED_SECRET: LASTFM_SHARED_SECRET LASTFM_USERNAME: LASTFM_USERNAME LASTFM_PASSWORD: LASTFM_PASSWORD capability: consumes: - type: http namespace: lastfm-scrobble baseUri: https://ws.audioscrobbler.com/2.0 description: Authenticated scrobbling lifecycle for a single playback session. resources: - name: scrobble-flow path: / operations: - name: mobileSession method: POST description: Step 1 — exchange username/password for a session key (one-time per device). outputRawFormat: json inputParameters: - { name: method, in: formData, type: string, value: auth.getMobileSession } - { name: api_key, in: formData, type: string } - { name: username, in: formData, type: string } - { name: password, in: formData, type: string } - { name: api_sig, in: formData, type: string } outputParameters: - { name: sessionKey, type: string, value: $.session.key } - name: nowPlaying method: POST description: Step 2 — mark a track as currently playing for the user profile. outputRawFormat: json inputParameters: - { name: method, in: formData, type: string, value: track.updateNowPlaying } - { name: api_key, in: formData, type: string } - { name: artist, in: formData, type: string } - { name: track, in: formData, type: string } - { name: album, in: formData, type: string } - { name: duration, in: formData, type: integer } - { name: sk, in: formData, type: string } - { name: api_sig, in: formData, type: string } outputParameters: - { name: status, type: string, value: $.status } - name: scrobble method: POST description: Step 3 — scrobble the completed track (must meet 30s/half-duration threshold). outputRawFormat: json inputParameters: - { name: method, in: formData, type: string, value: track.scrobble } - { name: api_key, in: formData, type: string } - { name: artist, in: formData, type: string } - { name: track, in: formData, type: string } - { name: album, in: formData, type: string } - { name: timestamp, in: formData, type: integer } - { name: duration, in: formData, type: integer } - { name: sk, in: formData, type: string } - { name: api_sig, in: formData, type: string } outputParameters: - { name: result, type: object, value: $.scrobbles } - name: loveTrack method: POST description: Step 4 — optional love action for the just-played track. outputRawFormat: json inputParameters: - { name: method, in: formData, type: string, value: track.love } - { name: api_key, in: formData, type: string } - { name: artist, in: formData, type: string } - { name: track, in: formData, type: string } - { name: sk, in: formData, type: string } - { name: api_sig, in: formData, type: string } outputParameters: - { name: status, type: string, value: $.status }