Community

NIPs

NIP-39: Linking Profiles to Other Platforms

NIP-39 lets a user attach proof-backed external identities to their Nostr key through kind 10011 and i tags, moving the claim out of profile metadata and into its own event.

NIP-39: Linking Profiles to Other Platforms visual
NIPs Under the hood Events, NIPs, relay behavior and the shared formats apps can trust.
Back to Nostr
NIPs Open NIP map Deep guidesConcepts, NIP pages and source checks BrowseClose
Identity and signingdraftoptionalexternal identities

NIP-39: External Identities

NIP39Statusdraft / optionalIdentity eventkind 10011Core tagiClaim examplesGitHub, Twitter/X, Mastodon, TelegramImportant change2026 moved i tags out of kind 0

A public key can point to accounts people already know

Nostr keys are strong identifiers, but most people still arrive with names and accounts from other places. They have GitHub handles, Mastodon accounts, Telegram IDs, old Twitter accounts, websites and public reputations. NIP-39 gives those links a structured proof model instead of leaving them as freeform bio text.

The important idea is control on both sides. The Nostr key publishes a claim that it controls an external identity. The external platform hosts a proof that points back to the Nostr public key. A client can then show the link with more confidence than a plain profile field.

This is not the same as universal verification. A GitHub proof proves control of a GitHub account and a Nostr key at a point in time. It does not prove legal identity, character, employment or permanence. That boundary is exactly why NIP-39 needs a careful article.

Kind 10011 and i tags for platform proofs

The current source uses kind 10011. Each identity is an i tag with two required pieces: platform:identity and a proof. The platform name is constrained to simple characters and cannot contain a colon. Clients need to tolerate extra tag values for future extensibility.

The source defines concrete claim types. A GitHub proof points to a Gist created by the claimed username and containing the Nostr public key. A Twitter/X proof points to a tweet with the expected text. A Mastodon proof points to a post by the claimed account. A Telegram proof points to a public channel or group message by the user ID.

The 2026 move away from kind 0 profile metadata matters. External identities are not just decorative profile fields. Giving them a separate kind makes the proof set easier to update, query and reason about without treating every profile edit as an identity-proof change.

The proof model got stricter as the profile model matured

NIP-39 has a visible history of adding and revising platform proof types, then narrowing the shape. PGP identity work appeared temporarily and was later removed. Shusui Moyatani clarified that i belongs in tags. In February 2026, Vitor Pamplona's PR #2216 moved i tags out of kind 0 and into kind 10011.

That change is the key history point. Kind 0 profile metadata is one of the most frequently edited Nostr events. External identity proofs deserve a cleaner home because clients may want to validate, cache or display them separately from avatar and bio changes.

The June 2026 source also reflects wider NIP formatting cleanup, but the real story is not formatting. It is the separation between profile presentation and proof-backed identity claims.

Kind movePR #2216 moved i tags out of kind 0 in 2026Current identity eventkind 10011Open Git history

A client has to verify the proof, not only render the link

Implementation is two-sided. A client can read kind 10011 and display claimed identities, but useful support means checking the external proof. For GitHub that means fetching the Gist and matching the stated Nostr key. For Mastodon or Telegram it means resolving the referenced post or message and checking the expected text and author.

Rust-nostr exposes a NIP-39 module for external identities, and Nostr Compass explains the proof model for people. Those sources are useful because they turn the markdown into a developer and product question: what counts as a live proof, and what needs to the UI show when the proof disappears?

A good product needs to distinguish claimed, checked, stale and failed identities. A deleted Gist or tweet may not erase history, but it weakens the live proof. A changed external username can also break the user's mental model even if the Nostr key did nothing wrong.

kind 10011Separate event for external identity claims.
i tagHolds platform:identity and proof.
VerifierClients need platform-specific proof checks, not only a rendered badge.
DisplayShow the difference between a claim, a live proof and a failed or stale proof.

External proof can smuggle platform authority back in

The first risk is overtrust. A GitHub or Mastodon proof can be useful, but it can also make users treat a platform account as more real than the Nostr key. The Nostr key remains the account. External identities are supporting evidence.

The second risk is decay. Proof posts can be deleted, accounts can be renamed, platforms can close API access and usernames can be reassigned. Clients need to keep the proof model visible enough that people understand what is live, what is historical and what failed.

Read NIP-39 in the wild

NIP-39 lets a Nostr profile point to external identity proofs. That can connect a key with GitHub, X, Telegram or another platform without pretending those accounts are the same identity.

External proof decays. Posts are deleted, usernames change and platforms restrict access. A good UI distinguishes live proof, stale proof and failed proof so you do not trust a ghost.

What changes when you actually use it

For you, NIP-39: Linking Profiles to Other Platforms is felt when identity stops being a username and becomes authority. A client, signer, name, proof or auth event may look like account plumbing, but it decides who can publish, approve, connect, recover or be recognized. Read NIP-01 and the adjacent source links beside it so you can tell the difference between a convenient identity surface and the key material that actually controls the account.

What changes for builders and operators

For builders, NIP-39: Linking Profiles to Other Platforms means making authority visible before action. A signer prompt, name proof, delegation, encrypted key, external identity or HTTP auth event needs plain language around scope, expiry, destination and recovery. If a person has to guess what they are authorizing, the protocol has already lost the trust battle.

What the official file makes concrete

The official file is organized around Abstract, Claim types, github, twitter, mastodon, telegram. Inspect draft, platform:identity, <identity>, <instance>/@<username>, <username>@<instance>, <ref>/<id>, <id> because these are the pieces most likely to surface as product behavior.

NIP-39: Linking Profiles to Other Platforms is an authority path, not decoration. A name, key, signer, delegation or auth event decides who can act as you.

Where it breaks

The failure mode in NIP-39: Linking Profiles to Other Platforms is authority drift. A name resolves to an old key, a signer approves too broadly, an auth event gets replayed, a delegation lasts too long or a private key backup gives false comfort. The product has to keep control boundaries visible after onboarding, not only during setup.

Where this appears outside the markdown

In the ecosystem, NIP-39: Linking Profiles to Other Platforms usually appears at the doorway: account setup, profile recognition, signer approval, cross-platform proof, remote signing, HTTP auth or recovery. That doorway needs unusually clear language because identity mistakes are sticky. Once a key, signer or proof is trusted in the wrong place, every later feature inherits the confusion.

The nearby-standard trap

The nearby-standard trap in NIP-39: Linking Profiles to Other Platforms is confusing recognition with control. A name, signer, URI, encrypted key, delegation or auth signature may all sit near identity, but they answer different questions. Read NIP-01 and the adjacent source links and ask one thing each time: who can act, who can verify, and what can be revoked?

Language that keeps the feature honest

Good product copy for NIP-39: Linking Profiles to Other Platforms names the authority. It says whether you are sharing a public key, approving a signature, trusting a domain, exporting an encrypted secret, delegating power or authenticating to a service. Small labels matter because identity mistakes do not feel small after they happen.

What this page does not promise

NIP-39: Linking Profiles to Other Platforms does not make identity effortless or risk-free. It can help keys, names, signers, delegation or authentication become portable, but it cannot decide who you trust, how you back up secrets or whether a domain, app or signer deserves authority. Read NIP-01 and the adjacent source links as a control map before handing any interface the power to sign, verify or speak for you.

Read it as a field test

Start NIP-39: Linking Profiles to Other Platforms with the moment of authority: signing, naming, delegation, authentication, encryption or recovery. Then ask which key or service can act. The source terms draft, platform:identity, <identity>, <instance>/@<username>, <username>@<instance>, <ref>/<id> are useful because they turn vague identity language into concrete control points. Without that, a friendly login screen can hide the most important security decision.

Where the standard earns trust

The source links give you places to test the interpretation in public: PR #2216, rust-nostr NIP-39 module, Nostr Compass: NIP-39, Nostr Lib metadata docs. Use those links to move from the spec to live libraries, mirrors, pull requests, guides or products.

Official NIP-39 source is the anchor for exact wording, and NIP-39 commit history shows how that wording moved over time. The strongest secondary clues here are PR #2216, rust-nostr NIP-39 module, Nostr Compass: NIP-39. Treat this evidence chain as part of the article, not as footnotes. A NIP page becomes useful when you can move from claim to source to working behavior without guessing.

Keep the chain visible for NIP-39: Linking Profiles to Other Platforms: first the human promise, then draft, platform:identity, <identity>, <instance>/@<username>, <username>@<instance>, <ref>/<id>, then the implementation record, then the real-world failure case. That order keeps NIP-39 useful without turning it into marketing copy or protocol trivia.

Three questions to carry forward

  • Who gains authority when this NIP is used: your key, a signer, a domain, a delegated key, a wallet or a web service?
  • Can you revoke, rotate, back up or inspect that authority before something goes wrong?
  • Does the interface separate public recognition from private signing power in language you can act on?

What to verify before you rely on it

  • Find draft, platform:identity, <identity>, <instance>/@<username>, <username>@<instance> in the official file and check where the UI exposes the same concept.
  • Read NIP-01 and the adjacent source links as context before treating NIP-39 as a complete product story.
  • Open at least one implementation, mirror, pull request or library source from the source links before trusting that the idea is mature.
  • Test the unhappy path: missing relays, stale metadata, invalid signatures, blocked events, expired state, revoked permissions or unavailable media.
  • Write the user-facing copy in plain language. If a standard changes authority, privacy, money, moderation or recovery, say that before the click.

Direct sources

Use these sources for NIP-39: Linking Profiles to Other Platforms in that order: Official NIP-39 source for the current wording; NIP-39 commit history for the change record; PR #2216, rust-nostr NIP-39 module, Nostr Compass: NIP-39 for public context. The article gives you the consequence in plain language, but the source trail is where exact fields, status notes, unresolved debates and implementation proof stay checkable.

Back to the NIP hub
NIPs route visual cue 1
NIPs route visual cue 2
NIPs route visual cue 3
NIPs route visual cue 4
NIPs route visual cue 5