---
title: Teal.fm
toc_min_heading_level: 2
toc_max_heading_level: 5
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
import JsonConfig from '!!raw-loader!@site/../config/tealfm.json.example';
import Bluesky from "@site/src/components/snippets/_bluesky.mdx";

:::tip[Other Uses]

To monitor and re-scrobble activity from a ATProto Profile create a [teal.fm (Source)](/configuration/sources/tealfm-source)

:::

[**teal.fm**](https://teal.fm/) is a social discovery and web viewing service for scrobbles stored/available on the ATProto network/your repository in a [PDS (Personal Data Server)](https://github.com/Bluesky-social/pds).

<details>

<summary>How does that work?</summary>

<Bluesky name="teal.fm" lexicon="fm.teal"/>

</details>

<DetailsAdmo type="warning" summary="Your Data Is Public">

The default Bluesky PDS is **public**, meaning your scrobbles are also public (read-only). This isn't any different than using Last.fm or Listenbrainz, in terms of privacy.

</DetailsAdmo>

<DetailsAdmo type="note" summary="teal.fm Is Still In Development">

[teal.fm is still in developement](https://notes.teal.fm/3lzlwe6puis2l) and does not have a true production website, yet.

To view your teal.fm scrobble data you can:

* use [teal-relay-production.up.railway.app](https://teal-relay-production.up.railway.app) or [teal-slice.wisp.place](https://tealfm-slice.wisp.place/) for a preview of teal.fm
* use [yearinmusic.teal.fm](https://yearinmusic.teal.fm) or [wrapped.baileytownsend.dev](https://wrapped.baileytownsend.dev/) for wrapped-style stats of your teal.fm scrobbles
* use [atproto.at](https://atproto.at) to view the raw data (convenience URLs are generated in multi-scrobbler, per scrobble, for you to do this)

</DetailsAdmo>

## Setup

#### Bluesky

* Create a [Bluesky](https://bsky.app) account, if you don't already have one
* Navigate to https://bsky.app/settings/app-passwords
  * Settings -> Privacy and Security -> App passwords
* Create a new **App Password** and save it somewhere, it will not be shown again

## Configuration

### Identifier

The ATPRoto identifier used with multi-scrobbler should be either:

* A valid [DID](https://atproto.com/specs/did#at-protocol-did-identifier-syntax), starting with `did:plc:...` or `did:web:...`
* Your **full** ATProto handle, including TLD

If using a handle:

* For regular Bluesky account this will be like: `alice.bsky.social`
* For Bluesky accounts that [use their domain as their account](https://bsky.social/about/blog/4-28-2023-domain-handle-tutorial) this is your domain: `mydomain.com`
* For non-Bluesky-PDS users, you probably already know your handle

If your identifier does not look like a DID and does not include a TLD then multi-scrobbler will automatically append `.bsky.social` to your handle value.

<Config config="TealClientConfig" fileContent={JsonConfig} client name="tealfm">
        | Environmental Variable | Required? | Default | Description                                                                                |
        | :--------------------- | --------- | ------- | ------------------------------------------------------------------------------------------ |
        | `TEAMFM_ID`            | Yes       |         | A unique ID                                                                                |
        | `TEALFM_IDENTIFIER`    | Yes       |         | Your **full** ATProto handle or DID. For Bluesky account this is like `myUser.bsky.social` |
        | `TEALFM_APP_PW`        | Yes       |         | Bluesky/ATProto network App Password                                                       |
        | `TEALFM_NAME`          | No        |         | A vanity name different than ID                                                            |
</Config>