{"_id":"@bluesky-social/api","_rev":"5-75950f3911ae523f1095b65676016b5d","name":"@bluesky-social/api","dist-tags":{"latest":"0.17.3"},"versions":{"0.15.25":{"name":"@bluesky-social/api","version":"0.15.25","keywords":["atproto","bluesky","api"],"license":"MIT","_id":"@bluesky-social/api@0.15.25","maintainers":[{"name":"openweb3.io","email":"mtsocialdao@gmail.com"},{"name":"web3km","email":"web3km@proton.me"}],"homepage":"https://atproto.com","bugs":{"url":"https://github.com/bluesky-social/atproto/issues"},"dist":{"shasum":"9f85210e4d5b789aad70577f725a83d8ffbeefad","tarball":"https://registry.npmjs.org/@bluesky-social/api/-/api-0.15.25.tgz","fileCount":1566,"integrity":"sha512-2Fo9KAZPBC1KVCCCTd+J9h4WrTqq+sSwEfQ87GrU25MZZI6T/f5xNRKLVVYSfcGsa/0q+UZ8lY3zhUBNYcRCQQ==","signatures":[{"sig":"MEQCIHLKayaEckFU6J0vydUgQ1Q8Sv0u81tjIqvyR2IbYbBDAiAcAswKGxRoR/CbCkchjNEHpk3oR0KyK2gKfaoOh/uNlQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":5924640},"main":"dist/index.js","_from":"file:bluesky-social-api-0.15.25.tgz","types":"dist/index.d.ts","scripts":{"test":"jest","build":"tsc --build tsconfig.build.json","codegen":"node ./scripts/generate-code.mjs && lex gen-api --yes ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*"},"_npmUser":{"name":"web3km","email":"web3km@proton.me"},"_resolved":"/private/var/folders/cb/7sst87dj7jd40nc7b7q7h76r0000gn/T/13d84f54fa47b3ecaf8bd735b45d6265/bluesky-social-api-0.15.25.tgz","_integrity":"sha512-2Fo9KAZPBC1KVCCCTd+J9h4WrTqq+sSwEfQ87GrU25MZZI6T/f5xNRKLVVYSfcGsa/0q+UZ8lY3zhUBNYcRCQQ==","repository":{"url":"git+https://github.com/bluesky-social/atproto.git","type":"git","directory":"packages/api"},"_npmVersion":"10.8.2","description":"Client library for atproto and Bluesky","directories":{},"_nodeVersion":"18.20.8","dependencies":{"zod":"^3.23.8","tlds":"^1.234.0","await-lock":"^2.2.2","multiformats":"^9.9.0","@bluesky-social/xrpc":"^0.7.1","@bluesky-social/syntax":"^0.4.0","@bluesky-social/lexicon":"^0.4.12","@bluesky-social/common-web":"^0.4.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.2","prettier":"^3.2.5","typescript":"^5.6.3","@bluesky-social/lex-cli":"^0.9.0"},"_npmOperationalInternal":{"tmp":"tmp/api_0.15.25_1753545366510_0.0828823381210102","host":"s3://npm-registry-packages-npm-production"}},"0.15.26":{"name":"@bluesky-social/api","version":"0.15.26","keywords":["atproto","bluesky","api"],"license":"MIT","_id":"@bluesky-social/api@0.15.26","maintainers":[{"name":"openweb3.io","email":"mtsocialdao@gmail.com"},{"name":"web3km","email":"web3km@proton.me"}],"homepage":"https://atproto.com","bugs":{"url":"https://github.com/bluesky-social/atproto/issues"},"dist":{"shasum":"079ad0ba7daab7e5ad9f8f9776ca3add8ddfdad9","tarball":"https://registry.npmjs.org/@bluesky-social/api/-/api-0.15.26.tgz","fileCount":1565,"integrity":"sha512-eZUtsVQdxah9bnO+ITOnfogDASrdSO+qBvKTk+JAzxw0dNC76VYvXDJh/tuQ4H8QEdgsvIxUXMJ/nGqk4DKefQ==","signatures":[{"sig":"MEUCIQDCi59JzMlQZAzoZYhuy2GRnbyEhWMZecCFG/SPMS3TRQIgSJV1PoSdkzCqeaSk0Gem06/ksErRZ89Z7zYwOZwJeUM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":5928218},"main":"dist/index.js","_from":"file:bluesky-social-api-0.15.26.tgz","types":"dist/index.d.ts","scripts":{"test":"jest","build":"tsc --build tsconfig.build.json","codegen":"node ./scripts/generate-code.mjs && lex gen-api --yes ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*"},"_npmUser":{"name":"web3km","email":"web3km@proton.me"},"_resolved":"/private/var/folders/cb/7sst87dj7jd40nc7b7q7h76r0000gn/T/fbdbafcf75207bf743e3389dd97278c7/bluesky-social-api-0.15.26.tgz","_integrity":"sha512-eZUtsVQdxah9bnO+ITOnfogDASrdSO+qBvKTk+JAzxw0dNC76VYvXDJh/tuQ4H8QEdgsvIxUXMJ/nGqk4DKefQ==","repository":{"url":"git+https://github.com/bluesky-social/atproto.git","type":"git","directory":"packages/api"},"_npmVersion":"10.8.2","description":"Client library for atproto and Bluesky","directories":{},"_nodeVersion":"18.20.8","dependencies":{"zod":"^3.23.8","tlds":"^1.234.0","await-lock":"^2.2.2","multiformats":"^9.9.0","@bluesky-social/xrpc":"^0.7.1","@bluesky-social/syntax":"^0.4.0","@bluesky-social/lexicon":"^0.4.12","@bluesky-social/common-web":"^0.4.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.2","prettier":"^3.2.5","typescript":"^5.6.3","@bluesky-social/lex-cli":"^0.9.0"},"_npmOperationalInternal":{"tmp":"tmp/api_0.15.26_1753712402306_0.3540052284711792","host":"s3://npm-registry-packages-npm-production"}},"0.15.27":{"name":"@bluesky-social/api","version":"0.15.27","keywords":["atproto","bluesky","api"],"license":"MIT","_id":"@bluesky-social/api@0.15.27","maintainers":[{"name":"openweb3.io","email":"mtsocialdao@gmail.com"},{"name":"web3km","email":"web3km@proton.me"}],"homepage":"https://atproto.com","bugs":{"url":"https://github.com/bluesky-social/atproto/issues"},"dist":{"shasum":"1403701b08e971d4c661939ec830fdadf9e00319","tarball":"https://registry.npmjs.org/@bluesky-social/api/-/api-0.15.27.tgz","fileCount":1565,"integrity":"sha512-re/c+iaV+HKsWrslD0PBfa2Rti3oKUUqCALKkJkcGqkLm9vpDHIFxdaAip83XnVu8cFQK5o1STnpLNgcZjlwNA==","signatures":[{"sig":"MEUCIGzTXFBCl8ZwvBM+FYjd6wPDD0SEXH10pwanyF8eWIWxAiEA8ISCtfBqeZ5WUzZbeAFeVD4HQlT0v2gcFS/22q5Cg8g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":5929383},"main":"dist/index.js","_from":"file:bluesky-social-api-0.15.27.tgz","types":"dist/index.d.ts","scripts":{"test":"jest","build":"tsc --build tsconfig.build.json","codegen":"node ./scripts/generate-code.mjs && lex gen-api --yes ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*"},"_npmUser":{"name":"web3km","email":"web3km@proton.me"},"_resolved":"/private/var/folders/cb/7sst87dj7jd40nc7b7q7h76r0000gn/T/e8a8f3ccba84d9ee16bf14adbd8b077c/bluesky-social-api-0.15.27.tgz","_integrity":"sha512-re/c+iaV+HKsWrslD0PBfa2Rti3oKUUqCALKkJkcGqkLm9vpDHIFxdaAip83XnVu8cFQK5o1STnpLNgcZjlwNA==","repository":{"url":"git+https://github.com/bluesky-social/atproto.git","type":"git","directory":"packages/api"},"_npmVersion":"10.8.2","description":"Client library for atproto and Bluesky","directories":{},"_nodeVersion":"18.20.8","dependencies":{"zod":"^3.23.8","tlds":"^1.234.0","await-lock":"^2.2.2","multiformats":"^9.9.0","@bluesky-social/xrpc":"^0.7.1","@bluesky-social/syntax":"^0.4.0","@bluesky-social/lexicon":"^0.4.12","@bluesky-social/common-web":"^0.4.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.2","prettier":"^3.2.5","typescript":"^5.6.3","@bluesky-social/lex-cli":"^0.9.0"},"_npmOperationalInternal":{"tmp":"tmp/api_0.15.27_1753800963308_0.21802864914630415","host":"s3://npm-registry-packages-npm-production"}},"0.17.2":{"name":"@bluesky-social/api","version":"0.17.2","keywords":["atproto","bluesky","api"],"license":"MIT","_id":"@bluesky-social/api@0.17.2","maintainers":[{"name":"openweb3.io","email":"mtsocialdao@gmail.com"},{"name":"web3km","email":"web3km@proton.me"}],"homepage":"https://atproto.com","bugs":{"url":"https://github.com/bluesky-social/atproto/issues"},"dist":{"shasum":"82bd7c1b9ee9816a523015c3b989da800c2904c8","tarball":"https://registry.npmjs.org/@bluesky-social/api/-/api-0.17.2.tgz","fileCount":1650,"integrity":"sha512-NG7i4q9A7sgZ9t0SNSdAQlMIfoQkeyh8S8iCdsOnM1K+h40672Vz8RGxT+CIwelPRYmgl1tEEX+hBzuUzm0SDA==","signatures":[{"sig":"MEYCIQCfr8Qq3NDLihuCem9OcgkPzgazkkCrleaQK7R9++rqGQIhALZsoIw9gi7Y1fTM/Q63h2T3xi1dCikVc1izNwn3rlg1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":7808567},"main":"dist/index.js","_from":"file:bluesky-social-api-0.17.2.tgz","types":"dist/index.d.ts","scripts":{"test":"jest","build":"tsc --build tsconfig.build.json","codegen":"node ./scripts/generate-code.mjs && lex gen-api --yes ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*"},"_npmUser":{"name":"web3km","email":"web3km@proton.me"},"_resolved":"/private/var/folders/cb/7sst87dj7jd40nc7b7q7h76r0000gn/T/870a66529fce0d8717e7639cdf814c1a/bluesky-social-api-0.17.2.tgz","_integrity":"sha512-NG7i4q9A7sgZ9t0SNSdAQlMIfoQkeyh8S8iCdsOnM1K+h40672Vz8RGxT+CIwelPRYmgl1tEEX+hBzuUzm0SDA==","repository":{"url":"git+https://github.com/bluesky-social/atproto.git","type":"git","directory":"packages/api"},"_npmVersion":"10.7.0","description":"Client library for atproto and Bluesky","directories":{},"_nodeVersion":"20.15.0","dependencies":{"zod":"^3.25.76","tlds":"^1.260.0","await-lock":"^2.2.2","multiformats":"^9.9.0","@bluesky-social/xrpc":"^0.7.5","@bluesky-social/syntax":"^0.4.1","@bluesky-social/lexicon":"^0.5.1","@bluesky-social/common-web":"^0.4.3"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","prettier":"^3.6.2","typescript":"^5.9.3","@bluesky-social/lex-cli":"^0.9.5"},"_npmOperationalInternal":{"tmp":"tmp/api_0.17.2_1761039225682_0.9559577646842667","host":"s3://npm-registry-packages-npm-production"}},"0.17.3":{"name":"@bluesky-social/api","version":"0.17.3","license":"MIT","description":"Client library for atproto and Bluesky","keywords":["atproto","bluesky","api"],"homepage":"https://atproto.com","repository":{"type":"git","url":"git+https://github.com/bluesky-social/atproto.git","directory":"packages/api"},"main":"dist/index.js","types":"dist/index.d.ts","dependencies":{"await-lock":"^2.2.2","multiformats":"^9.9.0","tlds":"^1.260.0","zod":"^3.25.76","@bluesky-social/syntax":"^0.4.1","@bluesky-social/lexicon":"^0.5.1","@bluesky-social/common-web":"^0.4.3","@bluesky-social/xrpc":"^0.7.5"},"devDependencies":{"jest":"^28.1.3","prettier":"^3.6.2","typescript":"^5.9.3","@bluesky-social/lex-cli":"^0.9.5"},"scripts":{"codegen":"node ./scripts/generate-code.mjs && lex gen-api --yes ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*","build":"tsc --build tsconfig.build.json","test":"jest"},"_id":"@bluesky-social/api@0.17.3","bugs":{"url":"https://github.com/bluesky-social/atproto/issues"},"_integrity":"sha512-er6XxUpm6qtqggywonBVtxqDmuv48EXrkxELrO6Pjq1+F9HSt5PCVzQnD0s/j4VPf/TPCJBH/jltD/KCFAdAtQ==","_resolved":"/private/var/folders/cb/7sst87dj7jd40nc7b7q7h76r0000gn/T/cc7a33a06175a83402f581beba25edcf/bluesky-social-api-0.17.3.tgz","_from":"file:bluesky-social-api-0.17.3.tgz","_nodeVersion":"18.20.8","_npmVersion":"10.8.2","dist":{"integrity":"sha512-er6XxUpm6qtqggywonBVtxqDmuv48EXrkxELrO6Pjq1+F9HSt5PCVzQnD0s/j4VPf/TPCJBH/jltD/KCFAdAtQ==","shasum":"2d0dba9b1c8ee093d42e8f4076a7e851c969c6a9","tarball":"https://registry.npmjs.org/@bluesky-social/api/-/api-0.17.3.tgz","fileCount":1651,"unpackedSize":7814757,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDBVc7RwNw9s9AWRw1D04KRwkvfCmTplPBmhH23zohDOQIhAOfSXjXW0wW/f5hOMfeSKA/5L6qndcIkDgxZ3bMIyUco"}]},"_npmUser":{"name":"web3km","email":"web3km@proton.me"},"directories":{},"maintainers":[{"name":"openweb3.io","email":"mtsocialdao@gmail.com"},{"name":"web3km","email":"web3km@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/api_0.17.3_1761053458416_0.39488595132342663"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-26T15:56:06.431Z","modified":"2025-10-21T13:30:58.973Z","0.15.25":"2025-07-26T15:56:06.853Z","0.15.26":"2025-07-28T14:20:02.568Z","0.15.27":"2025-07-29T14:56:03.637Z","0.17.2":"2025-10-21T09:33:45.941Z","0.17.3":"2025-10-21T13:30:58.766Z"},"bugs":{"url":"https://github.com/bluesky-social/atproto/issues"},"license":"MIT","homepage":"https://atproto.com","keywords":["atproto","bluesky","api"],"repository":{"type":"git","url":"git+https://github.com/bluesky-social/atproto.git","directory":"packages/api"},"description":"Client library for atproto and Bluesky","maintainers":[{"name":"openweb3.io","email":"mtsocialdao@gmail.com"},{"name":"web3km","email":"web3km@proton.me"}],"readme":"# ATP API\n\nThis API is a client for ATProtocol servers. It communicates using HTTP. It includes:\n\n- ✔️ APIs for ATProto and Bluesky.\n- ✔️ Validation and complete typescript types.\n- ✔️ Session management.\n- ✔️ A RichText library.\n\n## Getting started\n\nFirst install the package:\n\n```sh\nyarn add @bluesky-social/api\n```\n\nThen in your application:\n\n```typescript\nimport { AtpAgent } from '@bluesky-social/api'\n\nconst agent = new AtpAgent({ service: 'https://example.com' })\n```\n\n## Usage\n\n### Session management\n\nYou'll need an authenticated session for most API calls. There are two ways to\nmanage sessions:\n\n1. [App password based session management](#app-password-based-session-management)\n2. [OAuth based session management](#oauth-based-session-management)\n\n#### App password based session management\n\nUsername / password based authentication can be performed using the `AtpAgent`\nclass.\n\n> [!CAUTION]\n>\n> This method is deprecated in favor of OAuth based session management. It is\n> recommended to use OAuth based session management (through the\n> `@bluesky-social/oauth-client-*` packages).\n\n```typescript\nimport { AtpAgent, AtpSessionEvent, AtpSessionData } from '@bluesky-social/api'\n\n// configure connection to the server, without account authentication\nconst agent = new AtpAgent({\n  service: 'https://example.com',\n  persistSession: (evt: AtpSessionEvent, sess?: AtpSessionData) => {\n    // store the session-data for reuse\n  },\n})\n\n// Change the agent state to an authenticated state either by:\n\n// 1) creating a new account on the server.\nawait agent.createAccount({\n  email: 'alice@mail.com',\n  password: 'hunter2',\n  handle: 'alice.example.com',\n  inviteCode: 'some-code-12345-abcde',\n})\n\n// 2) if an existing session was securely stored previously, then reuse that to resume the session.\nawait agent.resumeSession(savedSessionData)\n\n// 3) if no old session was available, create a new one by logging in with password (App Password)\nawait agent.login({\n  identifier: 'alice@mail.com',\n  password: 'hunter2',\n})\n```\n\n#### OAuth based session management\n\nDepending on the environment used by your application, different OAuth clients\nare available:\n\n- [@bluesky-social/oauth-client-browser](https://www.npmjs.com/package/@bluesky-social/oauth-client-browser):\n  for the browser.\n- [@bluesky-social/oauth-client-node](https://www.npmjs.com/package/@bluesky-social/oauth-client-node): for\n  Node.js.\n- [@bluesky-social/oauth-client](https://www.npmjs.com/package/@bluesky-social/oauth-client):\n  Lower level; compatible with most JS engines.\n\nEvery `@bluesky-social/oauth-client-*` implementation has a different way to obtain an\n`OAuthSession` instance that can be used to instantiate an `Agent` (from\n`@bluesky-social/api`). Here is an example restoring a previously saved session:\n\n```typescript\nimport { Agent } from '@bluesky-social/api'\nimport { OAuthClient } from '@bluesky-social/oauth-client'\n\nconst oauthClient = new OAuthClient({\n  // ...\n})\n\nconst oauthSession = await oauthClient.restore('did:plc:123')\n\n// Instantiate the api Agent using an OAuthSession\nconst agent = new Agent(oauthSession)\n```\n\n### API calls\n\nThe agent includes methods for many common operations, including:\n\n```typescript\n// The DID of the user currently authenticated (or undefined)\nagent.did\nagent.accountDid // Throws if the user is not authenticated\n\n// Feeds and content\nawait agent.getTimeline(params, opts)\nawait agent.getAuthorFeed(params, opts)\nawait agent.getPostThread(params, opts)\nawait agent.getPost(params)\nawait agent.getPosts(params, opts)\nawait agent.getLikes(params, opts)\nawait agent.getRepostedBy(params, opts)\nawait agent.post(record)\nawait agent.deletePost(postUri)\nawait agent.like(uri, cid)\nawait agent.deleteLike(likeUri)\nawait agent.repost(uri, cid)\nawait agent.deleteRepost(repostUri)\nawait agent.uploadBlob(data, opts)\n\n// Social graph\nawait agent.getFollows(params, opts)\nawait agent.getFollowers(params, opts)\nawait agent.follow(did)\nawait agent.deleteFollow(followUri)\n\n// Actors\nawait agent.getProfile(params, opts)\nawait agent.upsertProfile(updateFn)\nawait agent.getProfiles(params, opts)\nawait agent.getSuggestions(params, opts)\nawait agent.searchActors(params, opts)\nawait agent.searchActorsTypeahead(params, opts)\nawait agent.mute(did)\nawait agent.unmute(did)\nawait agent.muteModList(listUri)\nawait agent.unmuteModList(listUri)\nawait agent.blockModList(listUri)\nawait agent.unblockModList(listUri)\n\n// Notifications\nawait agent.listNotifications(params, opts)\nawait agent.countUnreadNotifications(params, opts)\nawait agent.updateSeenNotifications()\n\n// Identity\nawait agent.resolveHandle(params, opts)\nawait agent.updateHandle(params, opts)\n\n// Legacy: Session management should be performed through the SessionManager\n// rather than the Agent instance.\nif (agent instanceof AtpAgent) {\n  // AtpAgent instances support using different sessions during their lifetime\n  await agent.createAccount({ ... }) // session a\n  await agent.login({ ... }) // session b\n  await agent.resumeSession(savedSession) // session c\n}\n```\n\n### Validation and types\n\nThe package includes a complete types system which includes validation and type-guards. For example, to validate a post record:\n\n```typescript\nimport { AppBskyFeedPost } from '@bluesky-social/api'\n\nconst post = {...}\nif (AppBskyFeedPost.isRecord(post)) {\n  // typescript now recognizes `post` as a AppBskyFeedPost.Record\n  // however -- we still need to validate it\n  const res = AppBskyFeedPost.validateRecord(post)\n  if (res.success) {\n    // a valid record\n  } else {\n    // something is wrong\n    console.log(res.error)\n  }\n}\n```\n\n### Rich text\n\nSome records (ie posts) use the `app.bsky.richtext` lexicon. At the moment richtext is only used for links and mentions, but it will be extended over time to include bold, italic, and so on.\n\nℹ️ It is **strongly** recommended to use this package's `RichText` library. Javascript encodes strings in utf16 while the protocol (and most other programming environments) use utf8. Converting between the two is challenging, but `RichText` handles that for you.\n\n```typescript\nimport { RichText } from '@bluesky-social/api'\n\n// creating richtext\nconst rt = new RichText({\n  text: 'Hello @alice.com, check out this link: https://example.com',\n})\nawait rt.detectFacets(agent) // automatically detects mentions and links\nconst postRecord = {\n  $type: 'app.bsky.feed.post',\n  text: rt.text,\n  facets: rt.facets,\n  createdAt: new Date().toISOString(),\n}\n\n// rendering as markdown\nlet markdown = ''\nfor (const segment of rt.segments()) {\n  if (segment.isLink()) {\n    markdown += `[${segment.text}](${segment.link?.uri})`\n  } else if (segment.isMention()) {\n    markdown += `[${segment.text}](https://my-bsky-app.com/user/${segment.mention?.did})`\n  } else {\n    markdown += segment.text\n  }\n}\n\n// calculating string lengths\nconst rt2 = new RichText({ text: 'Hello' })\nconsole.log(rt2.length) // => 5\nconsole.log(rt2.graphemeLength) // => 5\nconst rt3 = new RichText({ text: '👨‍👩‍👧‍👧' })\nconsole.log(rt3.length) // => 25\nconsole.log(rt3.graphemeLength) // => 1\n```\n\n### Moderation\n\nApplying the moderation system is a challenging task, but we've done our best to simplify it for you. The Moderation API helps handle a wide range of tasks, including:\n\n- Moderator labeling\n- User muting (including mutelists)\n- User blocking\n- Mutewords\n- Hidden posts\n\nFor more information, see the [Moderation Documentation](./docs/moderation.md).\n\n```typescript\nimport { moderatePost } from '@bluesky-social/api'\n\n// First get the user's moderation prefs and their label definitions\n// =\n\nconst prefs = await agent.getPreferences()\nconst labelDefs = await agent.getLabelDefinitions(prefs)\n\n// We call the appropriate moderation function for the content\n// =\n\nconst postMod = moderatePost(postView, {\n  userDid: agent.session.did,\n  moderationPrefs: prefs.moderationPrefs,\n  labelDefs,\n})\n\n// We then use the output to decide how to affect rendering\n// =\n\n// in feeds\nif (postMod.ui('contentList').filter) {\n  // don't include in feeds\n}\nif (postMod.ui('contentList').blur) {\n  // render the whole object behind a cover (use postMod.ui('contentList').blurs to explain)\n  if (postMod.ui('contentList').noOverride) {\n    // do not allow the cover the be removed\n  }\n}\nif (postMod.ui('contentList').alert || postMod.ui('contentList').inform) {\n  // render warnings on the post\n  // find the warnings in postMod.ui('contentList').alerts and postMod.ui('contentList').informs\n}\n\n// viewed directly\nif (postMod.ui('contentView').filter) {\n  // don't include in feeds\n}\nif (postMod.ui('contentView').blur) {\n  // render the whole object behind a cover (use postMod.ui('contentView').blurs to explain)\n  if (postMod.ui('contentView').noOverride) {\n    // do not allow the cover the be removed\n  }\n}\nif (postMod.ui('contentView').alert || postMod.ui('contentView').inform) {\n  // render warnings on the post\n  // find the warnings in postMod.ui('contentView').alerts and postMod.ui('contentView').informs\n}\n\n// post embeds in all contexts\nif (postMod.ui('contentMedia').blur) {\n  // render the whole object behind a cover (use postMod.ui('contentMedia').blurs to explain)\n  if (postMod.ui('contentMedia').noOverride) {\n    // do not allow the cover the be removed\n  }\n}\n```\n\n## Advanced\n\n### Advanced API calls\n\nThe methods above are convenience wrappers. It covers most but not all available methods.\n\nThe AT Protocol identifies methods and records with reverse-DNS names. You can use them on the agent as well:\n\n```typescript\nconst res1 = await agent.com.atproto.repo.createRecord({\n  did: alice.did,\n  collection: 'app.bsky.feed.post',\n  record: {\n    $type: 'app.bsky.feed.post',\n    text: 'Hello, world!',\n    createdAt: new Date().toISOString(),\n  },\n})\nconst res2 = await agent.com.atproto.repo.listRecords({\n  repo: alice.did,\n  collection: 'app.bsky.feed.post',\n})\n\nconst res3 = await agent.app.bsky.feed.post.create(\n  { repo: alice.did },\n  {\n    text: 'Hello, world!',\n    createdAt: new Date().toISOString(),\n  },\n)\nconst res4 = await agent.app.bsky.feed.post.list({ repo: alice.did })\n```\n\n### Non-browser configuration\n\nIf your environment doesn't have a built-in `fetch` implementation, you'll need\nto provide one. This will typically be done through a polyfill.\n\n### Bring your own fetch\n\nIf you want to provide your own `fetch` implementation, you can do so by\ninstantiating the sessionManager with a custom fetch implementation:\n\n```typescript\nimport { AtpAgent } from '@bluesky-social/api'\n\nconst myFetch = (input: RequestInfo | URL, init?: RequestInit) => {\n  console.log('requesting', input)\n  const response = await globalThis.fetch(input, init)\n  console.log('got response', response)\n  return response\n}\n\nconst agent = new AtpAgent({\n  service: 'https://example.com',\n  fetch: myFetch,\n})\n```\n\n## License\n\nThis project is dual-licensed under MIT and Apache 2.0 terms:\n\n- MIT license ([LICENSE-MIT.txt](https://github.com/bluesky-social/atproto/blob/main/LICENSE-MIT.txt) or http://opensource.org/licenses/MIT)\n- Apache License, Version 2.0, ([LICENSE-APACHE.txt](https://github.com/bluesky-social/atproto/blob/main/LICENSE-APACHE.txt) or http://www.apache.org/licenses/LICENSE-2.0)\n\nDownstream projects and end users may chose either license individually, or both together, at their discretion. The motivation for this dual-licensing is the additional software patent assurance provided by Apache 2.0.\n","readmeFilename":"README.md"}