{"openapi": "3.0.3", "info": {"title": "GetZap Identity API", "version": "1.2.0", "description": "Public API for **NostrFeed** to attach a logged-in Nostr key to GetZap.\n\nOne `name@getzap.me` is: NIP-05 + Lightning address + Bitcoin deposit `bc1` + DM inbox + NWC + Cashu + Blossom. Old users are included: look up by **name or pubkey**.\n\n**NostrFeed connect (copy this)**\n\n```\nconst BASE = 'https://api.getzap.me/v1'\n\n// 1) Discovery once at app start\nconst disc = await fetch(BASE + '/connect').then(r => r.json())\n\n// 2) After the user signs in with nsec / bunker / NIP-46:\nconst pack = await fetch(BASE + '/identity?pubkey=' + hexPubkey).then(r => r.json())\n// 404 \u2192 send them to disc.signup['getzap.me'] + '?identifier=' + suggestedName\n\n// 3) Show receive methods from the pack\n//    pack.lud16                  \u2192 Lightning (kk@getzap.me)\n//    pack.bitcoin.address        \u2192 on-chain BTC (bc1\u2026)\n//    pack.well_known.lnurlp      \u2192 LNURL-pay\n//    pack.well_known.nostr_json  \u2192 NIP-05 check\n\n// 4) Sign pack.setup.kind0, kind10002, kind10050, kind10063\n//    Publish to disc.relay (wss://relay.nostrfeed.com)\n\n// 5) Write kind-0 profile fields:\n//    nip05 = pack.nip05\n//    lud16 = pack.lud16\n```\n\nCORS: `https://www.nostrfeed.com`, `https://nostrfeed.com` (credentials allowed). NWC pairing **secret is never** in this API.\n\nOld users: `GET /identities` lists every name (including aliases on ln.nostrfeed.com). Same pubkey shares one `bc1`.", "contact": {"name": "GetZap / NostrFeed", "url": "https://www.nostrfeed.com"}, "license": {"name": "Use with NostrFeed", "url": "https://api.getzap.me/docs/connect"}}, "externalDocs": {"description": "Human docs", "url": "https://api.getzap.me/docs/api"}, "servers": [{"url": "https://api.getzap.me/v1", "description": "Primary. Point NostrFeed here."}, {"url": "https://getzap.me/studio/api", "description": "Same JSON on getzap.me (after nginx deploy)"}, {"url": "https://ln.nostrfeed.com/studio/api", "description": "Same JSON on the existing NostrFeed wallet host"}], "tags": [{"name": "Discovery", "description": "What to call first from NostrFeed."}, {"name": "Identity", "description": "Resolve name@domain to Lightning, NIP-05, inbox, NWC, Cashu, Blossom."}, {"name": "Blossom", "description": "Media for active NIP-05 users. Host is the API origin, not /v1."}], "x-blossom": {"servers": ["https://api.getzap.me", "https://getzap.me/blossom"], "download": "/{sha256}", "upload": "/{sha256}", "delete": "/{sha256}", "list": "/list/{pubkey}", "auth": "Authorization: Nostr <base64-event>", "nip96": "https://api.getzap.me/.well-known/nostr/nip96.json", "max_bytes": 20971520}, "x-connect": {"client": "https://www.nostrfeed.com", "discovery": "https://api.getzap.me/v1/connect", "openapi": "https://api.getzap.me/v1/openapi.json", "swagger": "https://api.getzap.me/v1/swagger", "relay": "wss://relay.nostrfeed.com", "paid_relay": "wss://paid.nostrfeed.com", "admission": "https://paid.nostrfeed.com", "steps": ["GET /connect", "GET /identity?pubkey={hex}  (old and new users)", "GET /identity/{name} or GET /identities", "show pack.lud16 + pack.bitcoin.address", "sign setup events, publish to relay", "set nip05 + lud16 on kind 0"]}, "x-nostrfeed": {"base": "https://api.getzap.me/v1", "cors_origins": ["https://www.nostrfeed.com", "https://nostrfeed.com"], "relay": "wss://relay.nostrfeed.com", "paid_relay": "wss://paid.nostrfeed.com", "admission": {"url": "https://paid.nostrfeed.com", "check": "https://paid.nostrfeed.com/admissions/check/{pubkey}", "amount_sats": 2100, "once": true}, "well_known": {"nip05": "https://getzap.me/.well-known/nostr.json?name={name}", "lnurlp": "https://getzap.me/.well-known/lnurlp/{name}"}, "signup": {"getzap.me": "https://getzap.me/nostrnip5/signup/2sJcjWPRQEDinLcENtPtJs", "ln.nostrfeed.com": "https://ln.nostrfeed.com/nostrnip5/signup/i3KUfyMGodpcVZqFqGf2Wx"}, "old_users": {"lookup": "GET /identity?pubkey={hex} works even if they signed up on ln.nostrfeed.com or only have an LNbits account", "list": "GET /identities", "shared_pubkey": "kk, k, kaundal share one bc1 and one Lightning wallet"}, "receive": {"lightning": "pack.lud16 or pack.lightning.address", "bitcoin": "pack.bitcoin.address (bc1 p2wpkh). After 2 confirmations credited as Lightning sats", "do_not": "Do not send BTC to Phoenix swap-in. Do not invent addresses client-side."}, "events_to_publish": ["kind0", "kind10002", "kind10050", "kind10063"], "nwc": {"relay": "wss://relay.nostrfeed.com", "provider_pubkey": "482df948a04ce7ab6bce969d950be4b9a4fee9eb803d45ddce9411e99434ddc8", "ui": "https://getzap.me/nwcprovider/", "secret": "never returned by this API"}}, "paths": {"/connect": {"get": {"tags": ["Discovery"], "operationId": "getConnect", "summary": "Service discovery", "description": "First call from NostrFeed. Returns relays, signup links, NWC provider pubkey, Cashu mint, Blossom host, and every endpoint.", "responses": {"200": {"description": "Discovery document", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConnectDocument"}, "example": {"name": "GetZap", "product": "identity-pack", "domain": "getzap.me", "client": "https://www.nostrfeed.com", "relay": "wss://relay.nostrfeed.com", "inbox_relay": "wss://relay.nostrfeed.com", "paid_relay": "wss://paid.nostrfeed.com", "cashu_mint": "https://mint.nostrfeed.com", "blossom": "https://api.getzap.me", "openapi": "https://api.getzap.me/v1/openapi.json", "endpoints": {"connect": "https://api.getzap.me/v1/connect", "identity": "https://api.getzap.me/v1/identity/{name}", "identity_by_pubkey": "https://api.getzap.me/v1/identity?pubkey=", "setup": "https://api.getzap.me/v1/identity/{name}/setup", "search": "https://api.getzap.me/v1/search?q=", "openapi": "https://api.getzap.me/v1/openapi.json"}}}}}}}}, "/health": {"get": {"tags": ["Discovery"], "operationId": "getHealth", "summary": "Liveness", "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Health"}}}}}}}, "/openapi.json": {"get": {"tags": ["Discovery"], "operationId": "getOpenApi", "summary": "This OpenAPI document", "responses": {"200": {"description": "OpenAPI 3.0.3", "content": {"application/json": {"schema": {"type": "object"}}}}}}}, "/identity/{name}": {"get": {"tags": ["Identity"], "operationId": "getIdentityByName", "summary": "Identity pack by local-part", "description": "Looks up `kk` or `kk@getzap.me`. Prefers getzap.me when the name exists on both domains.", "parameters": [{"name": "name", "in": "path", "required": true, "schema": {"type": "string", "example": "kk"}, "description": "Local-part or full identity."}], "responses": {"200": {"description": "Full identity pack including unsigned setup events", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityPack"}}}}, "404": {"$ref": "#/components/responses/NotFound"}}}}, "/identity/{name}/setup": {"get": {"tags": ["Identity"], "operationId": "getIdentitySetup", "summary": "Unsigned Nostr events to publish", "description": "Same as `pack.setup`. Sign kind 0, 10002, 10050, 10063 with the user's key and publish to the inbox relay.", "parameters": [{"name": "name", "in": "path", "required": true, "schema": {"type": "string", "example": "kk"}}], "responses": {"200": {"description": "Unsigned events", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetupEvents"}}}}, "404": {"$ref": "#/components/responses/NotFound"}}}}, "/identity": {"get": {"tags": ["Identity"], "operationId": "getIdentityByQuery", "summary": "Lookup by pubkey or name", "parameters": [{"name": "pubkey", "in": "query", "schema": {"type": "string"}, "description": "32-byte hex or npub1\u2026", "example": "npub178hgrwuyxucunql6mxrcfhlfsnha6zc9009mt683dl6yj7r7t8mq7zq9kz"}, {"name": "npub", "in": "query", "schema": {"type": "string"}, "description": "Alias for pubkey"}, {"name": "name", "in": "query", "schema": {"type": "string", "example": "kk"}}], "responses": {"200": {"description": "Identity pack", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdentityPack"}}}}, "404": {"$ref": "#/components/responses/NotFound"}}}}, "/onchain": {"get": {"tags": ["Identity"], "operationId": "getOnchainStatus", "summary": "Platform BTC deposit wallet status", "responses": {"200": {"description": "xpub summary (no seed)", "content": {"application/json": {"schema": {"type": "object"}}}}}}}, "/onchain/{name}": {"get": {"tags": ["Identity"], "operationId": "getOnchainAddress", "summary": "Unique bc1 deposit address for a GetZap name", "parameters": [{"name": "name", "in": "path", "required": true, "schema": {"type": "string", "example": "kk"}}], "responses": {"200": {"description": "Deposit address and deposits", "content": {"application/json": {"schema": {"type": "object"}}}}, "404": {"$ref": "#/components/responses/NotFound"}}}}, "/identities": {"get": {"tags": ["Identity"], "operationId": "listIdentities", "summary": "All names (old and new) for NostrFeed sync", "description": "Includes ln.nostrfeed.com aliases. Each item has lud16 and bitcoin_address.", "responses": {"200": {"description": "Directory", "content": {"application/json": {"schema": {"type": "object", "properties": {"identities": {"type": "array", "items": {"$ref": "#/components/schemas/SearchHit"}}}}}}}}}}, "/onchain/scan": {"get": {"tags": ["Identity"], "operationId": "scanOnchain", "summary": "Scan mempool.space and credit confirmed deposits", "responses": {"200": {"description": "Scan result", "content": {"application/json": {"schema": {"type": "object"}}}}}}}, "/search": {"get": {"tags": ["Identity"], "operationId": "searchIdentities", "summary": "Search identities", "parameters": [{"name": "q", "in": "query", "required": true, "schema": {"type": "string"}, "example": "kk"}], "responses": {"200": {"description": "Matches", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SearchResult"}}}}}}}}, "components": {"securitySchemes": {"nostr": {"type": "apiKey", "in": "header", "name": "Authorization", "description": "NIP-98 or Blossom kind 24242: `Nostr <base64(event)>`. Required for PUT/DELETE Blossom. Pubkey must be an active NIP-05."}}, "responses": {"NotFound": {"description": "No identity for that name or pubkey", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}, "example": {"detail": "Identity not found"}}}}}, "schemas": {"Error": {"type": "object", "required": ["detail"], "properties": {"detail": {"type": "string"}}}, "Health": {"type": "object", "properties": {"ok": {"type": "boolean"}, "relay_paid": {"type": "boolean"}, "paid_relay": {"type": "string", "example": "wss://paid.nostrfeed.com"}, "admission": {"type": "string", "example": "https://paid.nostrfeed.com"}, "ts": {"type": "integer"}}}, "ConnectDocument": {"type": "object", "required": ["name", "relay", "endpoints", "client"], "properties": {"name": {"type": "string", "example": "GetZap"}, "product": {"type": "string", "example": "identity-pack"}, "domain": {"type": "string", "example": "getzap.me"}, "also": {"type": "array", "items": {"type": "string"}}, "client": {"type": "string", "format": "uri"}, "docs": {"type": "string", "format": "uri"}, "help": {"type": "string", "format": "uri"}, "connect_page": {"type": "string", "format": "uri"}, "openapi": {"type": "string", "format": "uri"}, "swagger": {"type": "string", "format": "uri"}, "relay": {"type": "string", "example": "wss://relay.nostrfeed.com"}, "inbox_relay": {"type": "string"}, "paid_relay": {"type": "string", "example": "wss://paid.nostrfeed.com"}, "admission": {"type": "object"}, "relays": {"type": "object"}, "cashu_mint": {"type": "string", "format": "uri"}, "blossom": {"type": "string", "format": "uri"}, "nwc": {"$ref": "#/components/schemas/NwcPublic"}, "bunker": {"type": "object"}, "lnbits": {"type": "object"}, "signup": {"type": "object", "additionalProperties": {"type": "string", "format": "uri"}}, "api_base": {"type": "string", "format": "uri"}, "endpoints": {"$ref": "#/components/schemas/Endpoints"}, "profile_fields": {"type": "object", "properties": {"nip05": {"type": "string"}, "lud16": {"type": "string"}}}, "kinds": {"type": "object", "properties": {"metadata": {"type": "integer", "example": 0}, "relay_list": {"type": "integer", "example": 10002}, "dm_relays": {"type": "integer", "example": 10050}, "blossom_servers": {"type": "integer", "example": 10063}}}}}, "Endpoints": {"type": "object", "properties": {"connect": {"type": "string", "format": "uri"}, "identity": {"type": "string"}, "identity_by_pubkey": {"type": "string"}, "setup": {"type": "string"}, "search": {"type": "string"}, "openapi": {"type": "string", "format": "uri"}, "swagger": {"type": "string", "format": "uri"}, "studio": {"type": "string"}, "lnurlp": {"type": "string"}, "nostr_json": {"type": "string"}, "blossom": {"type": "string", "format": "uri"}}}, "NwcPublic": {"type": "object", "description": "Public NWC provider. Pairing secret is not included.", "properties": {"available": {"type": "boolean"}, "relay": {"type": "string"}, "provider_pubkey": {"type": "string"}, "provider_npub": {"type": "string"}, "ui": {"type": "string", "format": "uri"}}}, "IdentityPack": {"type": "object", "required": ["name", "identity", "pubkey", "setup"], "properties": {"name": {"type": "string", "example": "kk"}, "identity": {"type": "string", "example": "kk@getzap.me"}, "domain": {"type": "string", "example": "getzap.me"}, "active": {"type": "boolean"}, "pubkey": {"type": "string", "minLength": 64, "maxLength": 64, "example": "f1ee81bb843731c983fad98784dfe984efdd0b057bcbb5e8f16ff449787e59f6"}, "npub": {"type": "string", "example": "npub178hgrwuyxucunql6mxrcfhlfsnha6zc9009mt683dl6yj7r7t8mq7zq9kz"}, "nip05": {"type": "string"}, "lud16": {"type": "string"}, "lightning": {"$ref": "#/components/schemas/Lightning"}, "inbox": {"$ref": "#/components/schemas/Inbox"}, "nwc": {"$ref": "#/components/schemas/NwcPublic"}, "cashu": {"type": "object", "properties": {"mint": {"type": "string", "format": "uri"}, "unit": {"type": "string", "example": "sat"}}}, "bitcoin": {"$ref": "#/components/schemas/BitcoinDeposit"}, "blossom": {"type": "object", "properties": {"server": {"type": "string", "format": "uri"}, "kind": {"type": "integer", "example": 10063}}}, "bunker": {"$ref": "#/components/schemas/NwcPublic"}, "profile": {"type": "object", "properties": {"name": {"type": "string"}, "nip05": {"type": "string"}, "lud16": {"type": "string"}}}, "relays": {"type": "object", "properties": {"read_write": {"type": "array", "items": {"type": "string"}}, "inbox": {"type": "array", "items": {"type": "string"}}}}, "well_known": {"type": "object", "properties": {"nostr_json": {"type": "string", "format": "uri"}, "lnurlp": {"type": "string", "format": "uri"}}}, "signup": {"type": "string", "format": "uri"}, "setup": {"$ref": "#/components/schemas/SetupEvents"}, "aliases": {"type": "array", "items": {"$ref": "#/components/schemas/Alias"}}, "docs": {"type": "string", "format": "uri"}, "connect": {"type": "string", "format": "uri"}, "api": {"type": "string", "format": "uri"}, "pack": {"type": "array", "items": {"type": "string"}, "description": "Ready slots vs *_setup / *_missing / *_pending."}}}, "Lightning": {"type": "object", "properties": {"address": {"type": "string"}, "lnurlp": {"type": "string", "format": "uri"}, "pay_link_id": {"type": "string"}, "zaps": {"type": "boolean"}}}, "Inbox": {"type": "object", "properties": {"relays": {"type": "array", "items": {"type": "string"}}, "kind": {"type": "integer", "example": 10050}, "note": {"type": "string"}}}, "Alias": {"type": "object", "properties": {"identity": {"type": "string"}, "active": {"type": "boolean"}, "domain": {"type": "string"}}}, "SetupEvents": {"type": "object", "description": "Unsigned events. Client adds pubkey, created_at, id, sig.", "required": ["kind0", "kind10002", "kind10050", "kind10063"], "properties": {"kind0": {"$ref": "#/components/schemas/UnsignedEvent"}, "kind10002": {"$ref": "#/components/schemas/UnsignedEvent"}, "kind10050": {"$ref": "#/components/schemas/UnsignedEvent"}, "kind10063": {"$ref": "#/components/schemas/UnsignedEvent"}}}, "UnsignedEvent": {"type": "object", "required": ["kind", "content", "tags"], "properties": {"kind": {"type": "integer"}, "content": {"type": "string"}, "tags": {"type": "array", "items": {"type": "array", "items": {"type": "string"}}}}}, "BitcoinDeposit": {"type": "object", "required": ["address", "network", "credit_as"], "properties": {"address": {"type": "string", "example": "bc1qwv75spv0hmvgulapvlhyh65rhawpjtldaw28sl", "description": "Unique BIP84 P2WPKH. Same pubkey always gets this same address."}, "network": {"type": "string", "example": "bitcoin"}, "type": {"type": "string", "example": "p2wpkh"}, "index": {"type": "integer"}, "confirmations_required": {"type": "integer", "example": 2}, "min_credit_sats": {"type": "integer", "example": 546}, "min_auto_lightning_sats": {"type": "integer", "example": 20000}, "credit_as": {"type": "string", "example": "lightning"}, "credit_ready": {"type": "boolean", "description": "False for names with no LNbits wallet yet (cannot credit)."}, "note": {"type": "string"}, "pending_sats": {"type": "integer"}, "credited_sats": {"type": "integer"}, "wallet_id": {"type": "string"}, "deposits": {"type": "array", "items": {"type": "object"}}}}, "SearchHit": {"type": "object", "properties": {"name": {"type": "string"}, "identity": {"type": "string"}, "npub": {"type": "string"}, "pubkey": {"type": "string"}, "active": {"type": "boolean"}, "lud16": {"type": "string"}, "bitcoin_address": {"type": "string"}, "api": {"type": "string", "format": "uri"}}}, "SearchResult": {"type": "object", "required": ["results"], "properties": {"results": {"type": "array", "items": {"$ref": "#/components/schemas/SearchHit"}}}}, "BlobDescriptor": {"type": "object", "properties": {"url": {"type": "string", "format": "uri"}, "sha256": {"type": "string"}, "size": {"type": "integer"}, "type": {"type": "string"}, "nip94": {"type": "array", "items": {"type": "array", "items": {"type": "string"}}}}}}}}