Repository: bluesky-social/atproto Branch: main Commit: 57ca2109f30f Files: 4261 Total size: 16.8 MB Directory structure: gitextract_m_xioowf/ ├── .changeset/ │ ├── README.md │ ├── config.json │ ├── giant-goats-repeat.md │ └── nine-eyes-switch.md ├── .dockerignore ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows/ │ ├── build-and-push-bsky-aws.yaml │ ├── build-and-push-bsky-ghcr.yaml │ ├── build-and-push-bsync-aws.yaml │ ├── build-and-push-bsync-ghcr.yaml │ ├── build-and-push-ozone-aws.yaml │ ├── build-and-push-ozone-ghcr.yaml │ ├── build-and-push-pds-aws.yaml │ ├── build-and-push-pds-ghcr.yaml │ ├── claude.yaml │ ├── publish.yaml │ ├── repo.yaml │ └── sync-internal.yaml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .vscode/ │ ├── extensions.json │ └── settings.json ├── CONTRIBUTORS.md ├── LICENSE-APACHE.txt ├── LICENSE-MIT.txt ├── LICENSE.txt ├── Makefile ├── README.md ├── SECURITY.md ├── interop-test-files/ │ ├── README.md │ ├── crypto/ │ │ ├── signature-fixtures.json │ │ ├── w3c_didkey_K256.json │ │ └── w3c_didkey_P256.json │ └── syntax/ │ ├── atidentifier_syntax_invalid.txt │ ├── atidentifier_syntax_valid.txt │ ├── aturi_syntax_invalid.txt │ ├── aturi_syntax_valid.txt │ ├── datetime_parse_invalid.txt │ ├── datetime_syntax_invalid.txt │ ├── datetime_syntax_valid.txt │ ├── did_syntax_invalid.txt │ ├── did_syntax_valid.txt │ ├── handle_syntax_invalid.txt │ ├── handle_syntax_valid.txt │ ├── nsid_syntax_invalid.txt │ ├── nsid_syntax_valid.txt │ ├── recordkey_syntax_invalid.txt │ ├── recordkey_syntax_valid.txt │ ├── tid_syntax_invalid.txt │ └── tid_syntax_valid.txt ├── jest.config.js ├── jest.setup.ts ├── lexicons/ │ ├── app/ │ │ └── bsky/ │ │ ├── actor/ │ │ │ ├── defs.json │ │ │ ├── getPreferences.json │ │ │ ├── getProfile.json │ │ │ ├── getProfiles.json │ │ │ ├── getSuggestions.json │ │ │ ├── profile.json │ │ │ ├── putPreferences.json │ │ │ ├── searchActors.json │ │ │ ├── searchActorsTypeahead.json │ │ │ └── status.json │ │ ├── ageassurance/ │ │ │ ├── begin.json │ │ │ ├── defs.json │ │ │ ├── getConfig.json │ │ │ └── getState.json │ │ ├── authCreatePosts.json │ │ ├── authDeleteContent.json │ │ ├── authFullApp.json │ │ ├── authManageFeedDeclarations.json │ │ ├── authManageLabelerService.json │ │ ├── authManageModeration.json │ │ ├── authManageNotifications.json │ │ ├── authManageProfile.json │ │ ├── authViewAll.json │ │ ├── bookmark/ │ │ │ ├── createBookmark.json │ │ │ ├── defs.json │ │ │ ├── deleteBookmark.json │ │ │ └── getBookmarks.json │ │ ├── contact/ │ │ │ ├── defs.json │ │ │ ├── dismissMatch.json │ │ │ ├── getMatches.json │ │ │ ├── getSyncStatus.json │ │ │ ├── importContacts.json │ │ │ ├── removeData.json │ │ │ ├── sendNotification.json │ │ │ ├── startPhoneVerification.json │ │ │ └── verifyPhone.json │ │ ├── draft/ │ │ │ ├── createDraft.json │ │ │ ├── defs.json │ │ │ ├── deleteDraft.json │ │ │ ├── getDrafts.json │ │ │ └── updateDraft.json │ │ ├── embed/ │ │ │ ├── defs.json │ │ │ ├── external.json │ │ │ ├── images.json │ │ │ ├── record.json │ │ │ ├── recordWithMedia.json │ │ │ └── video.json │ │ ├── feed/ │ │ │ ├── defs.json │ │ │ ├── describeFeedGenerator.json │ │ │ ├── generator.json │ │ │ ├── getActorFeeds.json │ │ │ ├── getActorLikes.json │ │ │ ├── getAuthorFeed.json │ │ │ ├── getFeed.json │ │ │ ├── getFeedGenerator.json │ │ │ ├── getFeedGenerators.json │ │ │ ├── getFeedSkeleton.json │ │ │ ├── getLikes.json │ │ │ ├── getListFeed.json │ │ │ ├── getPostThread.json │ │ │ ├── getPosts.json │ │ │ ├── getQuotes.json │ │ │ ├── getRepostedBy.json │ │ │ ├── getSuggestedFeeds.json │ │ │ ├── getTimeline.json │ │ │ ├── like.json │ │ │ ├── post.json │ │ │ ├── postgate.json │ │ │ ├── repost.json │ │ │ ├── searchPosts.json │ │ │ ├── sendInteractions.json │ │ │ └── threadgate.json │ │ ├── graph/ │ │ │ ├── block.json │ │ │ ├── defs.json │ │ │ ├── follow.json │ │ │ ├── getActorStarterPacks.json │ │ │ ├── getBlocks.json │ │ │ ├── getFollowers.json │ │ │ ├── getFollows.json │ │ │ ├── getKnownFollowers.json │ │ │ ├── getList.json │ │ │ ├── getListBlocks.json │ │ │ ├── getListMutes.json │ │ │ ├── getLists.json │ │ │ ├── getListsWithMembership.json │ │ │ ├── getMutes.json │ │ │ ├── getRelationships.json │ │ │ ├── getStarterPack.json │ │ │ ├── getStarterPacks.json │ │ │ ├── getStarterPacksWithMembership.json │ │ │ ├── getSuggestedFollowsByActor.json │ │ │ ├── list.json │ │ │ ├── listblock.json │ │ │ ├── listitem.json │ │ │ ├── muteActor.json │ │ │ ├── muteActorList.json │ │ │ ├── muteThread.json │ │ │ ├── searchStarterPacks.json │ │ │ ├── starterpack.json │ │ │ ├── unmuteActor.json │ │ │ ├── unmuteActorList.json │ │ │ ├── unmuteThread.json │ │ │ └── verification.json │ │ ├── labeler/ │ │ │ ├── defs.json │ │ │ ├── getServices.json │ │ │ └── service.json │ │ ├── notification/ │ │ │ ├── declaration.json │ │ │ ├── defs.json │ │ │ ├── getPreferences.json │ │ │ ├── getUnreadCount.json │ │ │ ├── listActivitySubscriptions.json │ │ │ ├── listNotifications.json │ │ │ ├── putActivitySubscription.json │ │ │ ├── putPreferences.json │ │ │ ├── putPreferencesV2.json │ │ │ ├── registerPush.json │ │ │ ├── unregisterPush.json │ │ │ └── updateSeen.json │ │ ├── richtext/ │ │ │ └── facet.json │ │ ├── unspecced/ │ │ │ ├── defs.json │ │ │ ├── getAgeAssuranceState.json │ │ │ ├── getConfig.json │ │ │ ├── getOnboardingSuggestedStarterPacks.json │ │ │ ├── getOnboardingSuggestedStarterPacksSkeleton.json │ │ │ ├── getOnboardingSuggestedUsersSkeleton.json │ │ │ ├── getPopularFeedGenerators.json │ │ │ ├── getPostThreadOtherV2.json │ │ │ ├── getPostThreadV2.json │ │ │ ├── getSuggestedFeeds.json │ │ │ ├── getSuggestedFeedsSkeleton.json │ │ │ ├── getSuggestedOnboardingUsers.json │ │ │ ├── getSuggestedStarterPacks.json │ │ │ ├── getSuggestedStarterPacksSkeleton.json │ │ │ ├── getSuggestedUsers.json │ │ │ ├── getSuggestedUsersSkeleton.json │ │ │ ├── getSuggestionsSkeleton.json │ │ │ ├── getTaggedSuggestions.json │ │ │ ├── getTrendingTopics.json │ │ │ ├── getTrends.json │ │ │ ├── getTrendsSkeleton.json │ │ │ ├── initAgeAssurance.json │ │ │ ├── searchActorsSkeleton.json │ │ │ ├── searchPostsSkeleton.json │ │ │ └── searchStarterPacksSkeleton.json │ │ └── video/ │ │ ├── defs.json │ │ ├── getJobStatus.json │ │ ├── getUploadLimits.json │ │ └── uploadVideo.json │ ├── chat/ │ │ └── bsky/ │ │ ├── actor/ │ │ │ ├── declaration.json │ │ │ ├── defs.json │ │ │ ├── deleteAccount.json │ │ │ └── exportAccountData.json │ │ ├── authFullChatClient.json │ │ ├── convo/ │ │ │ ├── acceptConvo.json │ │ │ ├── addReaction.json │ │ │ ├── defs.json │ │ │ ├── deleteMessageForSelf.json │ │ │ ├── getConvo.json │ │ │ ├── getConvoAvailability.json │ │ │ ├── getConvoForMembers.json │ │ │ ├── getLog.json │ │ │ ├── getMessages.json │ │ │ ├── leaveConvo.json │ │ │ ├── listConvos.json │ │ │ ├── muteConvo.json │ │ │ ├── removeReaction.json │ │ │ ├── sendMessage.json │ │ │ ├── sendMessageBatch.json │ │ │ ├── unmuteConvo.json │ │ │ ├── updateAllRead.json │ │ │ └── updateRead.json │ │ └── moderation/ │ │ ├── getActorMetadata.json │ │ ├── getMessageContext.json │ │ └── updateActorAccess.json │ ├── com/ │ │ ├── atproto/ │ │ │ ├── admin/ │ │ │ │ ├── defs.json │ │ │ │ ├── deleteAccount.json │ │ │ │ ├── disableAccountInvites.json │ │ │ │ ├── disableInviteCodes.json │ │ │ │ ├── enableAccountInvites.json │ │ │ │ ├── getAccountInfo.json │ │ │ │ ├── getAccountInfos.json │ │ │ │ ├── getInviteCodes.json │ │ │ │ ├── getSubjectStatus.json │ │ │ │ ├── searchAccounts.json │ │ │ │ ├── sendEmail.json │ │ │ │ ├── updateAccountEmail.json │ │ │ │ ├── updateAccountHandle.json │ │ │ │ ├── updateAccountPassword.json │ │ │ │ ├── updateAccountSigningKey.json │ │ │ │ └── updateSubjectStatus.json │ │ │ ├── identity/ │ │ │ │ ├── defs.json │ │ │ │ ├── getRecommendedDidCredentials.json │ │ │ │ ├── refreshIdentity.json │ │ │ │ ├── requestPlcOperationSignature.json │ │ │ │ ├── resolveDid.json │ │ │ │ ├── resolveHandle.json │ │ │ │ ├── resolveIdentity.json │ │ │ │ ├── signPlcOperation.json │ │ │ │ ├── submitPlcOperation.json │ │ │ │ └── updateHandle.json │ │ │ ├── label/ │ │ │ │ ├── defs.json │ │ │ │ ├── queryLabels.json │ │ │ │ └── subscribeLabels.json │ │ │ ├── lexicon/ │ │ │ │ ├── resolveLexicon.json │ │ │ │ └── schema.json │ │ │ ├── moderation/ │ │ │ │ ├── createReport.json │ │ │ │ └── defs.json │ │ │ ├── repo/ │ │ │ │ ├── applyWrites.json │ │ │ │ ├── createRecord.json │ │ │ │ ├── defs.json │ │ │ │ ├── deleteRecord.json │ │ │ │ ├── describeRepo.json │ │ │ │ ├── getRecord.json │ │ │ │ ├── importRepo.json │ │ │ │ ├── listMissingBlobs.json │ │ │ │ ├── listRecords.json │ │ │ │ ├── putRecord.json │ │ │ │ ├── strongRef.json │ │ │ │ └── uploadBlob.json │ │ │ ├── server/ │ │ │ │ ├── activateAccount.json │ │ │ │ ├── checkAccountStatus.json │ │ │ │ ├── confirmEmail.json │ │ │ │ ├── createAccount.json │ │ │ │ ├── createAppPassword.json │ │ │ │ ├── createInviteCode.json │ │ │ │ ├── createInviteCodes.json │ │ │ │ ├── createSession.json │ │ │ │ ├── deactivateAccount.json │ │ │ │ ├── defs.json │ │ │ │ ├── deleteAccount.json │ │ │ │ ├── deleteSession.json │ │ │ │ ├── describeServer.json │ │ │ │ ├── getAccountInviteCodes.json │ │ │ │ ├── getServiceAuth.json │ │ │ │ ├── getSession.json │ │ │ │ ├── listAppPasswords.json │ │ │ │ ├── refreshSession.json │ │ │ │ ├── requestAccountDelete.json │ │ │ │ ├── requestEmailConfirmation.json │ │ │ │ ├── requestEmailUpdate.json │ │ │ │ ├── requestPasswordReset.json │ │ │ │ ├── reserveSigningKey.json │ │ │ │ ├── resetPassword.json │ │ │ │ ├── revokeAppPassword.json │ │ │ │ └── updateEmail.json │ │ │ ├── sync/ │ │ │ │ ├── defs.json │ │ │ │ ├── getBlob.json │ │ │ │ ├── getBlocks.json │ │ │ │ ├── getCheckout.json │ │ │ │ ├── getHead.json │ │ │ │ ├── getHostStatus.json │ │ │ │ ├── getLatestCommit.json │ │ │ │ ├── getRecord.json │ │ │ │ ├── getRepo.json │ │ │ │ ├── getRepoStatus.json │ │ │ │ ├── listBlobs.json │ │ │ │ ├── listHosts.json │ │ │ │ ├── listRepos.json │ │ │ │ ├── listReposByCollection.json │ │ │ │ ├── notifyOfUpdate.json │ │ │ │ ├── requestCrawl.json │ │ │ │ └── subscribeRepos.json │ │ │ └── temp/ │ │ │ ├── addReservedHandle.json │ │ │ ├── checkHandleAvailability.json │ │ │ ├── checkSignupQueue.json │ │ │ ├── dereferenceScope.json │ │ │ ├── fetchLabels.json │ │ │ ├── requestPhoneVerification.json │ │ │ └── revokeAccountCredentials.json │ │ └── germnetwork/ │ │ └── declaration.json │ └── tools/ │ └── ozone/ │ ├── communication/ │ │ ├── createTemplate.json │ │ ├── defs.json │ │ ├── deleteTemplate.json │ │ ├── listTemplates.json │ │ └── updateTemplate.json │ ├── hosting/ │ │ └── getAccountHistory.json │ ├── moderation/ │ │ ├── cancelScheduledActions.json │ │ ├── defs.json │ │ ├── emitEvent.json │ │ ├── getAccountTimeline.json │ │ ├── getEvent.json │ │ ├── getRecord.json │ │ ├── getRecords.json │ │ ├── getRepo.json │ │ ├── getReporterStats.json │ │ ├── getRepos.json │ │ ├── getSubjects.json │ │ ├── listScheduledActions.json │ │ ├── queryEvents.json │ │ ├── queryStatuses.json │ │ ├── scheduleAction.json │ │ └── searchRepos.json │ ├── report/ │ │ └── defs.json │ ├── safelink/ │ │ ├── addRule.json │ │ ├── defs.json │ │ ├── queryEvents.json │ │ ├── queryRules.json │ │ ├── removeRule.json │ │ └── updateRule.json │ ├── server/ │ │ └── getConfig.json │ ├── set/ │ │ ├── addValues.json │ │ ├── defs.json │ │ ├── deleteSet.json │ │ ├── deleteValues.json │ │ ├── getValues.json │ │ ├── querySets.json │ │ └── upsertSet.json │ ├── setting/ │ │ ├── defs.json │ │ ├── listOptions.json │ │ ├── removeOptions.json │ │ └── upsertOption.json │ ├── signature/ │ │ ├── defs.json │ │ ├── findCorrelation.json │ │ ├── findRelatedAccounts.json │ │ └── searchAccounts.json │ ├── team/ │ │ ├── addMember.json │ │ ├── defs.json │ │ ├── deleteMember.json │ │ ├── listMembers.json │ │ └── updateMember.json │ └── verification/ │ ├── defs.json │ ├── grantVerifications.json │ ├── listVerifications.json │ └── revokeVerifications.json ├── package.json ├── packages/ │ ├── README.md │ ├── api/ │ │ ├── CHANGELOG.md │ │ ├── OAUTH.md │ │ ├── README.md │ │ ├── definitions/ │ │ │ └── labels.json │ │ ├── docs/ │ │ │ └── moderation.md │ │ ├── jest.config.js │ │ ├── jest.d.ts │ │ ├── jest.setup.ts │ │ ├── package.json │ │ ├── scripts/ │ │ │ ├── code/ │ │ │ │ └── labels.mjs │ │ │ └── generate-code.mjs │ │ ├── src/ │ │ │ ├── age-assurance.test.ts │ │ │ ├── age-assurance.ts │ │ │ ├── agent.ts │ │ │ ├── atp-agent.ts │ │ │ ├── bsky-agent.ts │ │ │ ├── client/ │ │ │ │ ├── index.ts │ │ │ │ ├── lexicons.ts │ │ │ │ ├── types/ │ │ │ │ │ ├── app/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getProfile.ts │ │ │ │ │ │ │ ├── getProfiles.ts │ │ │ │ │ │ │ ├── getSuggestions.ts │ │ │ │ │ │ │ ├── profile.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── searchActors.ts │ │ │ │ │ │ │ ├── searchActorsTypeahead.ts │ │ │ │ │ │ │ └── status.ts │ │ │ │ │ │ ├── ageassurance/ │ │ │ │ │ │ │ ├── begin.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ └── getState.ts │ │ │ │ │ │ ├── bookmark/ │ │ │ │ │ │ │ ├── createBookmark.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteBookmark.ts │ │ │ │ │ │ │ └── getBookmarks.ts │ │ │ │ │ │ ├── contact/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── dismissMatch.ts │ │ │ │ │ │ │ ├── getMatches.ts │ │ │ │ │ │ │ ├── getSyncStatus.ts │ │ │ │ │ │ │ ├── importContacts.ts │ │ │ │ │ │ │ ├── removeData.ts │ │ │ │ │ │ │ ├── sendNotification.ts │ │ │ │ │ │ │ ├── startPhoneVerification.ts │ │ │ │ │ │ │ └── verifyPhone.ts │ │ │ │ │ │ ├── draft/ │ │ │ │ │ │ │ ├── createDraft.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteDraft.ts │ │ │ │ │ │ │ ├── getDrafts.ts │ │ │ │ │ │ │ └── updateDraft.ts │ │ │ │ │ │ ├── embed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── external.ts │ │ │ │ │ │ │ ├── images.ts │ │ │ │ │ │ │ ├── record.ts │ │ │ │ │ │ │ ├── recordWithMedia.ts │ │ │ │ │ │ │ └── video.ts │ │ │ │ │ │ ├── feed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── describeFeedGenerator.ts │ │ │ │ │ │ │ ├── generator.ts │ │ │ │ │ │ │ ├── getActorFeeds.ts │ │ │ │ │ │ │ ├── getActorLikes.ts │ │ │ │ │ │ │ ├── getAuthorFeed.ts │ │ │ │ │ │ │ ├── getFeed.ts │ │ │ │ │ │ │ ├── getFeedGenerator.ts │ │ │ │ │ │ │ ├── getFeedGenerators.ts │ │ │ │ │ │ │ ├── getFeedSkeleton.ts │ │ │ │ │ │ │ ├── getLikes.ts │ │ │ │ │ │ │ ├── getListFeed.ts │ │ │ │ │ │ │ ├── getPostThread.ts │ │ │ │ │ │ │ ├── getPosts.ts │ │ │ │ │ │ │ ├── getQuotes.ts │ │ │ │ │ │ │ ├── getRepostedBy.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getTimeline.ts │ │ │ │ │ │ │ ├── like.ts │ │ │ │ │ │ │ ├── post.ts │ │ │ │ │ │ │ ├── postgate.ts │ │ │ │ │ │ │ ├── repost.ts │ │ │ │ │ │ │ ├── searchPosts.ts │ │ │ │ │ │ │ ├── sendInteractions.ts │ │ │ │ │ │ │ └── threadgate.ts │ │ │ │ │ │ ├── graph/ │ │ │ │ │ │ │ ├── block.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── follow.ts │ │ │ │ │ │ │ ├── getActorStarterPacks.ts │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ ├── getFollowers.ts │ │ │ │ │ │ │ ├── getFollows.ts │ │ │ │ │ │ │ ├── getKnownFollowers.ts │ │ │ │ │ │ │ ├── getList.ts │ │ │ │ │ │ │ ├── getListBlocks.ts │ │ │ │ │ │ │ ├── getListMutes.ts │ │ │ │ │ │ │ ├── getLists.ts │ │ │ │ │ │ │ ├── getListsWithMembership.ts │ │ │ │ │ │ │ ├── getMutes.ts │ │ │ │ │ │ │ ├── getRelationships.ts │ │ │ │ │ │ │ ├── getStarterPack.ts │ │ │ │ │ │ │ ├── getStarterPacks.ts │ │ │ │ │ │ │ ├── getStarterPacksWithMembership.ts │ │ │ │ │ │ │ ├── getSuggestedFollowsByActor.ts │ │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ │ ├── listblock.ts │ │ │ │ │ │ │ ├── listitem.ts │ │ │ │ │ │ │ ├── muteActor.ts │ │ │ │ │ │ │ ├── muteActorList.ts │ │ │ │ │ │ │ ├── muteThread.ts │ │ │ │ │ │ │ ├── searchStarterPacks.ts │ │ │ │ │ │ │ ├── starterpack.ts │ │ │ │ │ │ │ ├── unmuteActor.ts │ │ │ │ │ │ │ ├── unmuteActorList.ts │ │ │ │ │ │ │ ├── unmuteThread.ts │ │ │ │ │ │ │ └── verification.ts │ │ │ │ │ │ ├── labeler/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getServices.ts │ │ │ │ │ │ │ └── service.ts │ │ │ │ │ │ ├── notification/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getUnreadCount.ts │ │ │ │ │ │ │ ├── listActivitySubscriptions.ts │ │ │ │ │ │ │ ├── listNotifications.ts │ │ │ │ │ │ │ ├── putActivitySubscription.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── putPreferencesV2.ts │ │ │ │ │ │ │ ├── registerPush.ts │ │ │ │ │ │ │ ├── unregisterPush.ts │ │ │ │ │ │ │ └── updateSeen.ts │ │ │ │ │ │ ├── richtext/ │ │ │ │ │ │ │ └── facet.ts │ │ │ │ │ │ ├── unspecced/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getAgeAssuranceState.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getPopularFeedGenerators.ts │ │ │ │ │ │ │ ├── getPostThreadOtherV2.ts │ │ │ │ │ │ │ ├── getPostThreadV2.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getSuggestedFeedsSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedOnboardingUsers.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedUsers.ts │ │ │ │ │ │ │ ├── getSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestionsSkeleton.ts │ │ │ │ │ │ │ ├── getTaggedSuggestions.ts │ │ │ │ │ │ │ ├── getTrendingTopics.ts │ │ │ │ │ │ │ ├── getTrends.ts │ │ │ │ │ │ │ ├── getTrendsSkeleton.ts │ │ │ │ │ │ │ ├── initAgeAssurance.ts │ │ │ │ │ │ │ ├── searchActorsSkeleton.ts │ │ │ │ │ │ │ ├── searchPostsSkeleton.ts │ │ │ │ │ │ │ └── searchStarterPacksSkeleton.ts │ │ │ │ │ │ └── video/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── getJobStatus.ts │ │ │ │ │ │ ├── getUploadLimits.ts │ │ │ │ │ │ └── uploadVideo.ts │ │ │ │ │ ├── chat/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ └── exportAccountData.ts │ │ │ │ │ │ ├── convo/ │ │ │ │ │ │ │ ├── acceptConvo.ts │ │ │ │ │ │ │ ├── addReaction.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteMessageForSelf.ts │ │ │ │ │ │ │ ├── getConvo.ts │ │ │ │ │ │ │ ├── getConvoAvailability.ts │ │ │ │ │ │ │ ├── getConvoForMembers.ts │ │ │ │ │ │ │ ├── getLog.ts │ │ │ │ │ │ │ ├── getMessages.ts │ │ │ │ │ │ │ ├── leaveConvo.ts │ │ │ │ │ │ │ ├── listConvos.ts │ │ │ │ │ │ │ ├── muteConvo.ts │ │ │ │ │ │ │ ├── removeReaction.ts │ │ │ │ │ │ │ ├── sendMessage.ts │ │ │ │ │ │ │ ├── sendMessageBatch.ts │ │ │ │ │ │ │ ├── unmuteConvo.ts │ │ │ │ │ │ │ ├── updateAllRead.ts │ │ │ │ │ │ │ └── updateRead.ts │ │ │ │ │ │ └── moderation/ │ │ │ │ │ │ ├── getActorMetadata.ts │ │ │ │ │ │ ├── getMessageContext.ts │ │ │ │ │ │ └── updateActorAccess.ts │ │ │ │ │ ├── com/ │ │ │ │ │ │ ├── atproto/ │ │ │ │ │ │ │ ├── admin/ │ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ │ ├── disableAccountInvites.ts │ │ │ │ │ │ │ │ ├── disableInviteCodes.ts │ │ │ │ │ │ │ │ ├── enableAccountInvites.ts │ │ │ │ │ │ │ │ ├── getAccountInfo.ts │ │ │ │ │ │ │ │ ├── getAccountInfos.ts │ │ │ │ │ │ │ │ ├── getInviteCodes.ts │ │ │ │ │ │ │ │ ├── getSubjectStatus.ts │ │ │ │ │ │ │ │ ├── searchAccounts.ts │ │ │ │ │ │ │ │ ├── sendEmail.ts │ │ │ │ │ │ │ │ ├── updateAccountEmail.ts │ │ │ │ │ │ │ │ ├── updateAccountHandle.ts │ │ │ │ │ │ │ │ ├── updateAccountPassword.ts │ │ │ │ │ │ │ │ ├── updateAccountSigningKey.ts │ │ │ │ │ │ │ │ └── updateSubjectStatus.ts │ │ │ │ │ │ │ ├── identity/ │ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ │ ├── getRecommendedDidCredentials.ts │ │ │ │ │ │ │ │ ├── refreshIdentity.ts │ │ │ │ │ │ │ │ ├── requestPlcOperationSignature.ts │ │ │ │ │ │ │ │ ├── resolveDid.ts │ │ │ │ │ │ │ │ ├── resolveHandle.ts │ │ │ │ │ │ │ │ ├── resolveIdentity.ts │ │ │ │ │ │ │ │ ├── signPlcOperation.ts │ │ │ │ │ │ │ │ ├── submitPlcOperation.ts │ │ │ │ │ │ │ │ └── updateHandle.ts │ │ │ │ │ │ │ ├── label/ │ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ │ ├── queryLabels.ts │ │ │ │ │ │ │ │ └── subscribeLabels.ts │ │ │ │ │ │ │ ├── lexicon/ │ │ │ │ │ │ │ │ ├── resolveLexicon.ts │ │ │ │ │ │ │ │ └── schema.ts │ │ │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ │ │ ├── createReport.ts │ │ │ │ │ │ │ │ └── defs.ts │ │ │ │ │ │ │ ├── repo/ │ │ │ │ │ │ │ │ ├── applyWrites.ts │ │ │ │ │ │ │ │ ├── createRecord.ts │ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ │ ├── deleteRecord.ts │ │ │ │ │ │ │ │ ├── describeRepo.ts │ │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ │ ├── importRepo.ts │ │ │ │ │ │ │ │ ├── listMissingBlobs.ts │ │ │ │ │ │ │ │ ├── listRecords.ts │ │ │ │ │ │ │ │ ├── putRecord.ts │ │ │ │ │ │ │ │ ├── strongRef.ts │ │ │ │ │ │ │ │ └── uploadBlob.ts │ │ │ │ │ │ │ ├── server/ │ │ │ │ │ │ │ │ ├── activateAccount.ts │ │ │ │ │ │ │ │ ├── checkAccountStatus.ts │ │ │ │ │ │ │ │ ├── confirmEmail.ts │ │ │ │ │ │ │ │ ├── createAccount.ts │ │ │ │ │ │ │ │ ├── createAppPassword.ts │ │ │ │ │ │ │ │ ├── createInviteCode.ts │ │ │ │ │ │ │ │ ├── createInviteCodes.ts │ │ │ │ │ │ │ │ ├── createSession.ts │ │ │ │ │ │ │ │ ├── deactivateAccount.ts │ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ │ ├── deleteSession.ts │ │ │ │ │ │ │ │ ├── describeServer.ts │ │ │ │ │ │ │ │ ├── getAccountInviteCodes.ts │ │ │ │ │ │ │ │ ├── getServiceAuth.ts │ │ │ │ │ │ │ │ ├── getSession.ts │ │ │ │ │ │ │ │ ├── listAppPasswords.ts │ │ │ │ │ │ │ │ ├── refreshSession.ts │ │ │ │ │ │ │ │ ├── requestAccountDelete.ts │ │ │ │ │ │ │ │ ├── requestEmailConfirmation.ts │ │ │ │ │ │ │ │ ├── requestEmailUpdate.ts │ │ │ │ │ │ │ │ ├── requestPasswordReset.ts │ │ │ │ │ │ │ │ ├── reserveSigningKey.ts │ │ │ │ │ │ │ │ ├── resetPassword.ts │ │ │ │ │ │ │ │ ├── revokeAppPassword.ts │ │ │ │ │ │ │ │ └── updateEmail.ts │ │ │ │ │ │ │ ├── sync/ │ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ │ ├── getBlob.ts │ │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ │ ├── getCheckout.ts │ │ │ │ │ │ │ │ ├── getHead.ts │ │ │ │ │ │ │ │ ├── getHostStatus.ts │ │ │ │ │ │ │ │ ├── getLatestCommit.ts │ │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ │ │ ├── getRepoStatus.ts │ │ │ │ │ │ │ │ ├── listBlobs.ts │ │ │ │ │ │ │ │ ├── listHosts.ts │ │ │ │ │ │ │ │ ├── listRepos.ts │ │ │ │ │ │ │ │ ├── listReposByCollection.ts │ │ │ │ │ │ │ │ ├── notifyOfUpdate.ts │ │ │ │ │ │ │ │ ├── requestCrawl.ts │ │ │ │ │ │ │ │ └── subscribeRepos.ts │ │ │ │ │ │ │ └── temp/ │ │ │ │ │ │ │ ├── addReservedHandle.ts │ │ │ │ │ │ │ ├── checkHandleAvailability.ts │ │ │ │ │ │ │ ├── checkSignupQueue.ts │ │ │ │ │ │ │ ├── dereferenceScope.ts │ │ │ │ │ │ │ ├── fetchLabels.ts │ │ │ │ │ │ │ ├── requestPhoneVerification.ts │ │ │ │ │ │ │ └── revokeAccountCredentials.ts │ │ │ │ │ │ └── germnetwork/ │ │ │ │ │ │ └── declaration.ts │ │ │ │ │ └── tools/ │ │ │ │ │ └── ozone/ │ │ │ │ │ ├── communication/ │ │ │ │ │ │ ├── createTemplate.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteTemplate.ts │ │ │ │ │ │ ├── listTemplates.ts │ │ │ │ │ │ └── updateTemplate.ts │ │ │ │ │ ├── hosting/ │ │ │ │ │ │ └── getAccountHistory.ts │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ ├── cancelScheduledActions.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── emitEvent.ts │ │ │ │ │ │ ├── getAccountTimeline.ts │ │ │ │ │ │ ├── getEvent.ts │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ ├── getRecords.ts │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ ├── getReporterStats.ts │ │ │ │ │ │ ├── getRepos.ts │ │ │ │ │ │ ├── getSubjects.ts │ │ │ │ │ │ ├── listScheduledActions.ts │ │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ │ ├── queryStatuses.ts │ │ │ │ │ │ ├── scheduleAction.ts │ │ │ │ │ │ └── searchRepos.ts │ │ │ │ │ ├── report/ │ │ │ │ │ │ └── defs.ts │ │ │ │ │ ├── safelink/ │ │ │ │ │ │ ├── addRule.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ │ ├── queryRules.ts │ │ │ │ │ │ ├── removeRule.ts │ │ │ │ │ │ └── updateRule.ts │ │ │ │ │ ├── server/ │ │ │ │ │ │ └── getConfig.ts │ │ │ │ │ ├── set/ │ │ │ │ │ │ ├── addValues.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteSet.ts │ │ │ │ │ │ ├── deleteValues.ts │ │ │ │ │ │ ├── getValues.ts │ │ │ │ │ │ ├── querySets.ts │ │ │ │ │ │ └── upsertSet.ts │ │ │ │ │ ├── setting/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── listOptions.ts │ │ │ │ │ │ ├── removeOptions.ts │ │ │ │ │ │ └── upsertOption.ts │ │ │ │ │ ├── signature/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── findCorrelation.ts │ │ │ │ │ │ ├── findRelatedAccounts.ts │ │ │ │ │ │ └── searchAccounts.ts │ │ │ │ │ ├── team/ │ │ │ │ │ │ ├── addMember.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteMember.ts │ │ │ │ │ │ ├── listMembers.ts │ │ │ │ │ │ └── updateMember.ts │ │ │ │ │ └── verification/ │ │ │ │ │ ├── defs.ts │ │ │ │ │ ├── grantVerifications.ts │ │ │ │ │ ├── listVerifications.ts │ │ │ │ │ └── revokeVerifications.ts │ │ │ │ └── util.ts │ │ │ ├── const.ts │ │ │ ├── index.ts │ │ │ ├── mocker.ts │ │ │ ├── moderation/ │ │ │ │ ├── const/ │ │ │ │ │ └── labels.ts │ │ │ │ ├── decision.ts │ │ │ │ ├── index.ts │ │ │ │ ├── mutewords.ts │ │ │ │ ├── subjects/ │ │ │ │ │ ├── account.ts │ │ │ │ │ ├── feed-generator.ts │ │ │ │ │ ├── notification.ts │ │ │ │ │ ├── post.ts │ │ │ │ │ ├── profile.ts │ │ │ │ │ └── user-list.ts │ │ │ │ ├── types.ts │ │ │ │ ├── ui.ts │ │ │ │ └── util.ts │ │ │ ├── predicate.ts │ │ │ ├── rich-text/ │ │ │ │ ├── detection.ts │ │ │ │ ├── rich-text.ts │ │ │ │ ├── sanitization.ts │ │ │ │ ├── unicode.ts │ │ │ │ └── util.ts │ │ │ ├── session-manager.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── tests/ │ │ │ ├── atp-agent.test.ts │ │ │ ├── dispatcher.test.ts │ │ │ ├── errors.test.ts │ │ │ ├── moderation-behaviors.test.ts │ │ │ ├── moderation-custom-labels.test.ts │ │ │ ├── moderation-mutewords.test.ts │ │ │ ├── moderation-prefs.test.ts │ │ │ ├── moderation-quoteposts.test.ts │ │ │ ├── moderation.test.ts │ │ │ ├── rich-text-detection.test.ts │ │ │ ├── rich-text-sanitization.test.ts │ │ │ ├── rich-text.test.ts │ │ │ └── util/ │ │ │ ├── echo-server.ts │ │ │ └── moderation-behavior.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── aws/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── bunny.ts │ │ │ ├── cloudfront.ts │ │ │ ├── index.ts │ │ │ ├── kms.ts │ │ │ ├── s3.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── bsky/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── bin/ │ │ │ └── migration-create.ts │ │ ├── buf.gen.yaml │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── proto/ │ │ │ ├── bsky.proto │ │ │ ├── courier.proto │ │ │ └── rolodex.proto │ │ ├── src/ │ │ │ ├── api/ │ │ │ │ ├── age-assurance/ │ │ │ │ │ ├── const.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── kws/ │ │ │ │ │ │ ├── age-verified.ts │ │ │ │ │ │ ├── const.ts │ │ │ │ │ │ ├── external-payload.test.ts │ │ │ │ │ │ └── external-payload.ts │ │ │ │ │ ├── redirects/ │ │ │ │ │ │ └── kws-age-verified.ts │ │ │ │ │ ├── stash.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── util.ts │ │ │ │ │ └── webhooks/ │ │ │ │ │ └── kws-age-verified.ts │ │ │ │ ├── app/ │ │ │ │ │ └── bsky/ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ ├── getProfile.ts │ │ │ │ │ │ ├── getProfiles.ts │ │ │ │ │ │ ├── getSuggestions.ts │ │ │ │ │ │ ├── searchActors.ts │ │ │ │ │ │ └── searchActorsTypeahead.ts │ │ │ │ │ ├── ageassurance/ │ │ │ │ │ │ ├── begin.ts │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ └── getState.ts │ │ │ │ │ ├── bookmark/ │ │ │ │ │ │ ├── createBookmark.ts │ │ │ │ │ │ ├── deleteBookmark.ts │ │ │ │ │ │ ├── getBookmarks.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ ├── contact/ │ │ │ │ │ │ ├── dismissMatch.ts │ │ │ │ │ │ ├── getMatches.ts │ │ │ │ │ │ ├── getSyncStatus.ts │ │ │ │ │ │ ├── importContacts.ts │ │ │ │ │ │ ├── removeData.ts │ │ │ │ │ │ ├── sendNotification.ts │ │ │ │ │ │ ├── startPhoneVerification.ts │ │ │ │ │ │ ├── util.ts │ │ │ │ │ │ └── verifyPhone.ts │ │ │ │ │ ├── draft/ │ │ │ │ │ │ ├── createDraft.ts │ │ │ │ │ │ ├── deleteDraft.ts │ │ │ │ │ │ ├── getDrafts.ts │ │ │ │ │ │ └── updateDraft.ts │ │ │ │ │ ├── feed/ │ │ │ │ │ │ ├── getActorFeeds.ts │ │ │ │ │ │ ├── getActorLikes.ts │ │ │ │ │ │ ├── getAuthorFeed.ts │ │ │ │ │ │ ├── getFeed.ts │ │ │ │ │ │ ├── getFeedGenerator.ts │ │ │ │ │ │ ├── getFeedGenerators.ts │ │ │ │ │ │ ├── getLikes.ts │ │ │ │ │ │ ├── getListFeed.ts │ │ │ │ │ │ ├── getPostThread.ts │ │ │ │ │ │ ├── getPosts.ts │ │ │ │ │ │ ├── getQuotes.ts │ │ │ │ │ │ ├── getRepostedBy.ts │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ ├── getTimeline.ts │ │ │ │ │ │ └── searchPosts.ts │ │ │ │ │ ├── graph/ │ │ │ │ │ │ ├── getActorStarterPacks.ts │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ ├── getFollowers.ts │ │ │ │ │ │ ├── getFollows.ts │ │ │ │ │ │ ├── getKnownFollowers.ts │ │ │ │ │ │ ├── getList.ts │ │ │ │ │ │ ├── getListBlocks.ts │ │ │ │ │ │ ├── getListMutes.ts │ │ │ │ │ │ ├── getLists.ts │ │ │ │ │ │ ├── getListsWithMembership.ts │ │ │ │ │ │ ├── getMutes.ts │ │ │ │ │ │ ├── getRelationships.ts │ │ │ │ │ │ ├── getStarterPack.ts │ │ │ │ │ │ ├── getStarterPacks.ts │ │ │ │ │ │ ├── getStarterPacksWithMembership.ts │ │ │ │ │ │ ├── getSuggestedFollowsByActor.ts │ │ │ │ │ │ ├── muteActor.ts │ │ │ │ │ │ ├── muteActorList.ts │ │ │ │ │ │ ├── muteThread.ts │ │ │ │ │ │ ├── searchStarterPacks.ts │ │ │ │ │ │ ├── unmuteActor.ts │ │ │ │ │ │ ├── unmuteActorList.ts │ │ │ │ │ │ └── unmuteThread.ts │ │ │ │ │ ├── labeler/ │ │ │ │ │ │ └── getServices.ts │ │ │ │ │ ├── notification/ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ ├── getUnreadCount.ts │ │ │ │ │ │ ├── listActivitySubscriptions.ts │ │ │ │ │ │ ├── listNotifications.ts │ │ │ │ │ │ ├── putActivitySubscription.ts │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ ├── putPreferencesV2.ts │ │ │ │ │ │ ├── registerPush.ts │ │ │ │ │ │ ├── unregisterPush.ts │ │ │ │ │ │ ├── updateSeen.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ └── unspecced/ │ │ │ │ │ ├── getAgeAssuranceState.ts │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ ├── getOnboardingSuggestedStarterPacks.ts │ │ │ │ │ ├── getPopularFeedGenerators.ts │ │ │ │ │ ├── getPostThreadOtherV2.ts │ │ │ │ │ ├── getPostThreadV2.ts │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ ├── getSuggestedOnboardingUsers.ts │ │ │ │ │ ├── getSuggestedStarterPacks.ts │ │ │ │ │ ├── getSuggestedUsers.ts │ │ │ │ │ ├── getTaggedSuggestions.ts │ │ │ │ │ ├── getTrendingTopics.ts │ │ │ │ │ ├── getTrends.ts │ │ │ │ │ └── initAgeAssurance.ts │ │ │ │ ├── blob-dispatcher.ts │ │ │ │ ├── blob-resolver.ts │ │ │ │ ├── com/ │ │ │ │ │ └── atproto/ │ │ │ │ │ ├── admin/ │ │ │ │ │ │ ├── getAccountInfos.ts │ │ │ │ │ │ ├── getSubjectStatus.ts │ │ │ │ │ │ └── updateSubjectStatus.ts │ │ │ │ │ ├── identity/ │ │ │ │ │ │ └── resolveHandle.ts │ │ │ │ │ ├── label/ │ │ │ │ │ │ └── queryLabels.ts │ │ │ │ │ ├── repo/ │ │ │ │ │ │ └── getRecord.ts │ │ │ │ │ └── temp/ │ │ │ │ │ └── fetchLabels.ts │ │ │ │ ├── external.ts │ │ │ │ ├── health.ts │ │ │ │ ├── index.ts │ │ │ │ ├── kws/ │ │ │ │ │ ├── api.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── util.ts │ │ │ │ │ └── webhook.ts │ │ │ │ ├── sitemap.ts │ │ │ │ ├── util.ts │ │ │ │ └── well-known.ts │ │ │ ├── auth-verifier.ts │ │ │ ├── bsync.ts │ │ │ ├── cache/ │ │ │ │ └── read-through.ts │ │ │ ├── config.ts │ │ │ ├── context.ts │ │ │ ├── courier.ts │ │ │ ├── data-plane/ │ │ │ │ ├── bsync/ │ │ │ │ │ └── index.ts │ │ │ │ ├── client/ │ │ │ │ │ ├── hosts.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── index.ts │ │ │ │ └── server/ │ │ │ │ ├── background.ts │ │ │ │ ├── db/ │ │ │ │ │ ├── database-schema.ts │ │ │ │ │ ├── db.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── migrations/ │ │ │ │ │ │ ├── 20230309T045948368Z-init.ts │ │ │ │ │ │ ├── 20230408T152211201Z-notification-init.ts │ │ │ │ │ │ ├── 20230417T210628672Z-moderation-init.ts │ │ │ │ │ │ ├── 20230420T211446071Z-did-cache.ts │ │ │ │ │ │ ├── 20230427T194702079Z-notif-record-index.ts │ │ │ │ │ │ ├── 20230605T144730094Z-post-profile-aggs.ts │ │ │ │ │ │ ├── 20230607T211442112Z-feed-generator-init.ts │ │ │ │ │ │ ├── 20230608T155101190Z-algo-whats-hot-view.ts │ │ │ │ │ │ ├── 20230608T201813132Z-mute-lists.ts │ │ │ │ │ │ ├── 20230608T205147239Z-mutes.ts │ │ │ │ │ │ ├── 20230609T153623961Z-blocks.ts │ │ │ │ │ │ ├── 20230609T232122649Z-actor-deletion-indexes.ts │ │ │ │ │ │ ├── 20230610T203555962Z-suggested-follows.ts │ │ │ │ │ │ ├── 20230611T215300060Z-actor-state.ts │ │ │ │ │ │ ├── 20230620T161134972Z-post-langs.ts │ │ │ │ │ │ ├── 20230627T212437895Z-optional-handle.ts │ │ │ │ │ │ ├── 20230629T220835893Z-remove-post-hierarchy.ts │ │ │ │ │ │ ├── 20230703T045536691Z-feed-and-label-indices.ts │ │ │ │ │ │ ├── 20230720T164800037Z-posts-cursor-idx.ts │ │ │ │ │ │ ├── 20230807T035309811Z-feed-item-delete-invite-for-user-idx.ts │ │ │ │ │ │ ├── 20230808T172902639Z-repo-rev.ts │ │ │ │ │ │ ├── 20230810T203349843Z-action-duration.ts │ │ │ │ │ │ ├── 20230817T195936007Z-native-notifications.ts │ │ │ │ │ │ ├── 20230830T205507322Z-suggested-feeds.ts │ │ │ │ │ │ ├── 20230904T211011773Z-block-lists.ts │ │ │ │ │ │ ├── 20230906T222220386Z-thread-gating.ts │ │ │ │ │ │ ├── 20230920T213858047Z-add-tags-to-post.ts │ │ │ │ │ │ ├── 20230929T192920807Z-record-cursor-indexes.ts │ │ │ │ │ │ ├── 20231003T202833377Z-create-moderation-subject-status.ts │ │ │ │ │ │ ├── 20231220T225126090Z-blob-takedowns.ts │ │ │ │ │ │ ├── 20240124T023719200Z-tagged-suggestions.ts │ │ │ │ │ │ ├── 20240226T225725627Z-labelers.ts │ │ │ │ │ │ ├── 20240530T170337073Z-account-deactivation.ts │ │ │ │ │ │ ├── 20240606T171229898Z-thread-mutes.ts │ │ │ │ │ │ ├── 20240606T222548219Z-starter-packs.ts │ │ │ │ │ │ ├── 20240719T203853939Z-priority-notifs.ts │ │ │ │ │ │ ├── 20240723T220700077Z-quotes-post-aggs.ts │ │ │ │ │ │ ├── 20240723T220703655Z-quotes.ts │ │ │ │ │ │ ├── 20240801T193939827Z-post-gate.ts │ │ │ │ │ │ ├── 20240808T224251220Z-post-gate-flags.ts │ │ │ │ │ │ ├── 20240829T211238293Z-simplify-actor-sync.ts │ │ │ │ │ │ ├── 20240831T134810923Z-pinned-posts.ts │ │ │ │ │ │ ├── 20241114T153108102Z-add-starter-packs-name.ts │ │ │ │ │ │ ├── 20250116T222618297Z-post-embed-video.ts │ │ │ │ │ │ ├── 20250207T174822012Z-add-label-exp.ts │ │ │ │ │ │ ├── 20250404T163421487Z-verifications.ts │ │ │ │ │ │ ├── 20250526T023712742Z-like-repost-via.ts │ │ │ │ │ │ ├── 20250528T221913281Z-add-record-tags.ts │ │ │ │ │ │ ├── 20250602T190357447Z-add-private-data.ts │ │ │ │ │ │ ├── 20250611T140649895Z-add-activity-subscription.ts │ │ │ │ │ │ ├── 20250627T025331240Z-add-actor-age-assurance-columns.ts │ │ │ │ │ │ ├── 20250812T183735692Z-add-bookmarks.ts │ │ │ │ │ │ ├── 20250813T174955711Z-add-post-agg-bookmarks.ts │ │ │ │ │ │ ├── 20251120T004738098Z-update-actor-age-assurance-v2.ts │ │ │ │ │ │ ├── 20260112T133951271Z-add-drafts.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── provider.ts │ │ │ │ │ ├── pagination.ts │ │ │ │ │ ├── tables/ │ │ │ │ │ │ ├── activity-subscription.ts │ │ │ │ │ │ ├── actor-block.ts │ │ │ │ │ │ ├── actor-state.ts │ │ │ │ │ │ ├── actor-sync.ts │ │ │ │ │ │ ├── actor.ts │ │ │ │ │ │ ├── algo.ts │ │ │ │ │ │ ├── blob-takedown.ts │ │ │ │ │ │ ├── bookmark.ts │ │ │ │ │ │ ├── did-cache.ts │ │ │ │ │ │ ├── draft.ts │ │ │ │ │ │ ├── duplicate-record.ts │ │ │ │ │ │ ├── feed-generator.ts │ │ │ │ │ │ ├── feed-item.ts │ │ │ │ │ │ ├── follow.ts │ │ │ │ │ │ ├── label.ts │ │ │ │ │ │ ├── labeler.ts │ │ │ │ │ │ ├── like.ts │ │ │ │ │ │ ├── list-block.ts │ │ │ │ │ │ ├── list-item.ts │ │ │ │ │ │ ├── list-mute.ts │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ ├── mute.ts │ │ │ │ │ │ ├── notification-push-token.ts │ │ │ │ │ │ ├── notification.ts │ │ │ │ │ │ ├── post-agg.ts │ │ │ │ │ │ ├── post-embed.ts │ │ │ │ │ │ ├── post-gate.ts │ │ │ │ │ │ ├── post.ts │ │ │ │ │ │ ├── private-data.ts │ │ │ │ │ │ ├── profile-agg.ts │ │ │ │ │ │ ├── profile.ts │ │ │ │ │ │ ├── quote.ts │ │ │ │ │ │ ├── record.ts │ │ │ │ │ │ ├── repost.ts │ │ │ │ │ │ ├── starter-pack.ts │ │ │ │ │ │ ├── subscription.ts │ │ │ │ │ │ ├── suggested-feed.ts │ │ │ │ │ │ ├── suggested-follow.ts │ │ │ │ │ │ ├── tagged-suggestion.ts │ │ │ │ │ │ ├── thread-gate.ts │ │ │ │ │ │ ├── thread-mute.ts │ │ │ │ │ │ ├── verification.ts │ │ │ │ │ │ └── view-param.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── index.ts │ │ │ │ ├── indexing/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── plugins/ │ │ │ │ │ │ ├── block.ts │ │ │ │ │ │ ├── chat-declaration.ts │ │ │ │ │ │ ├── feed-generator.ts │ │ │ │ │ │ ├── follow.ts │ │ │ │ │ │ ├── germ-declaration.ts │ │ │ │ │ │ ├── labeler.ts │ │ │ │ │ │ ├── like.ts │ │ │ │ │ │ ├── list-block.ts │ │ │ │ │ │ ├── list-item.ts │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ ├── notif-declaration.ts │ │ │ │ │ │ ├── post-gate.ts │ │ │ │ │ │ ├── post.ts │ │ │ │ │ │ ├── profile.ts │ │ │ │ │ │ ├── repost.ts │ │ │ │ │ │ ├── starter-pack.ts │ │ │ │ │ │ ├── status.ts │ │ │ │ │ │ ├── thread-gate.ts │ │ │ │ │ │ └── verification.ts │ │ │ │ │ └── processor.ts │ │ │ │ ├── routes/ │ │ │ │ │ ├── activity-subscription.ts │ │ │ │ │ ├── blocks.ts │ │ │ │ │ ├── bookmarks.ts │ │ │ │ │ ├── drafts.ts │ │ │ │ │ ├── feed-gens.ts │ │ │ │ │ ├── feeds.ts │ │ │ │ │ ├── follows.ts │ │ │ │ │ ├── identity.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── interactions.ts │ │ │ │ │ ├── labels.ts │ │ │ │ │ ├── likes.ts │ │ │ │ │ ├── lists.ts │ │ │ │ │ ├── moderation.ts │ │ │ │ │ ├── mutes.ts │ │ │ │ │ ├── notifs.ts │ │ │ │ │ ├── profile.ts │ │ │ │ │ ├── quotes.ts │ │ │ │ │ ├── records.ts │ │ │ │ │ ├── relationships.ts │ │ │ │ │ ├── reposts.ts │ │ │ │ │ ├── search.ts │ │ │ │ │ ├── sitemap.ts │ │ │ │ │ ├── starter-packs.ts │ │ │ │ │ ├── suggestions.ts │ │ │ │ │ ├── sync.ts │ │ │ │ │ └── threads.ts │ │ │ │ ├── subscription.ts │ │ │ │ └── util.ts │ │ │ ├── error.ts │ │ │ ├── etcd.ts │ │ │ ├── feature-gates/ │ │ │ │ ├── README.md │ │ │ │ ├── gates.ts │ │ │ │ ├── index.ts │ │ │ │ ├── metrics.test.ts │ │ │ │ ├── metrics.ts │ │ │ │ ├── types.ts │ │ │ │ ├── utils.test.ts │ │ │ │ └── utils.ts │ │ │ ├── hydration/ │ │ │ │ ├── actor.ts │ │ │ │ ├── feed.ts │ │ │ │ ├── graph.ts │ │ │ │ ├── hydrator.ts │ │ │ │ ├── label.ts │ │ │ │ └── util.ts │ │ │ ├── image/ │ │ │ │ ├── index.ts │ │ │ │ ├── invalidator.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── server.ts │ │ │ │ ├── sharp.ts │ │ │ │ ├── uri.ts │ │ │ │ └── util.ts │ │ │ ├── index.ts │ │ │ ├── kws.ts │ │ │ ├── lexicon/ │ │ │ │ ├── index.ts │ │ │ │ ├── lexicons.ts │ │ │ │ ├── types/ │ │ │ │ │ ├── app/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getProfile.ts │ │ │ │ │ │ │ ├── getProfiles.ts │ │ │ │ │ │ │ ├── getSuggestions.ts │ │ │ │ │ │ │ ├── profile.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── searchActors.ts │ │ │ │ │ │ │ ├── searchActorsTypeahead.ts │ │ │ │ │ │ │ └── status.ts │ │ │ │ │ │ ├── ageassurance/ │ │ │ │ │ │ │ ├── begin.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ └── getState.ts │ │ │ │ │ │ ├── bookmark/ │ │ │ │ │ │ │ ├── createBookmark.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteBookmark.ts │ │ │ │ │ │ │ └── getBookmarks.ts │ │ │ │ │ │ ├── contact/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── dismissMatch.ts │ │ │ │ │ │ │ ├── getMatches.ts │ │ │ │ │ │ │ ├── getSyncStatus.ts │ │ │ │ │ │ │ ├── importContacts.ts │ │ │ │ │ │ │ ├── removeData.ts │ │ │ │ │ │ │ ├── sendNotification.ts │ │ │ │ │ │ │ ├── startPhoneVerification.ts │ │ │ │ │ │ │ └── verifyPhone.ts │ │ │ │ │ │ ├── draft/ │ │ │ │ │ │ │ ├── createDraft.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteDraft.ts │ │ │ │ │ │ │ ├── getDrafts.ts │ │ │ │ │ │ │ └── updateDraft.ts │ │ │ │ │ │ ├── embed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── external.ts │ │ │ │ │ │ │ ├── images.ts │ │ │ │ │ │ │ ├── record.ts │ │ │ │ │ │ │ ├── recordWithMedia.ts │ │ │ │ │ │ │ └── video.ts │ │ │ │ │ │ ├── feed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── describeFeedGenerator.ts │ │ │ │ │ │ │ ├── generator.ts │ │ │ │ │ │ │ ├── getActorFeeds.ts │ │ │ │ │ │ │ ├── getActorLikes.ts │ │ │ │ │ │ │ ├── getAuthorFeed.ts │ │ │ │ │ │ │ ├── getFeed.ts │ │ │ │ │ │ │ ├── getFeedGenerator.ts │ │ │ │ │ │ │ ├── getFeedGenerators.ts │ │ │ │ │ │ │ ├── getFeedSkeleton.ts │ │ │ │ │ │ │ ├── getLikes.ts │ │ │ │ │ │ │ ├── getListFeed.ts │ │ │ │ │ │ │ ├── getPostThread.ts │ │ │ │ │ │ │ ├── getPosts.ts │ │ │ │ │ │ │ ├── getQuotes.ts │ │ │ │ │ │ │ ├── getRepostedBy.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getTimeline.ts │ │ │ │ │ │ │ ├── like.ts │ │ │ │ │ │ │ ├── post.ts │ │ │ │ │ │ │ ├── postgate.ts │ │ │ │ │ │ │ ├── repost.ts │ │ │ │ │ │ │ ├── searchPosts.ts │ │ │ │ │ │ │ ├── sendInteractions.ts │ │ │ │ │ │ │ └── threadgate.ts │ │ │ │ │ │ ├── graph/ │ │ │ │ │ │ │ ├── block.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── follow.ts │ │ │ │ │ │ │ ├── getActorStarterPacks.ts │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ ├── getFollowers.ts │ │ │ │ │ │ │ ├── getFollows.ts │ │ │ │ │ │ │ ├── getKnownFollowers.ts │ │ │ │ │ │ │ ├── getList.ts │ │ │ │ │ │ │ ├── getListBlocks.ts │ │ │ │ │ │ │ ├── getListMutes.ts │ │ │ │ │ │ │ ├── getLists.ts │ │ │ │ │ │ │ ├── getListsWithMembership.ts │ │ │ │ │ │ │ ├── getMutes.ts │ │ │ │ │ │ │ ├── getRelationships.ts │ │ │ │ │ │ │ ├── getStarterPack.ts │ │ │ │ │ │ │ ├── getStarterPacks.ts │ │ │ │ │ │ │ ├── getStarterPacksWithMembership.ts │ │ │ │ │ │ │ ├── getSuggestedFollowsByActor.ts │ │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ │ ├── listblock.ts │ │ │ │ │ │ │ ├── listitem.ts │ │ │ │ │ │ │ ├── muteActor.ts │ │ │ │ │ │ │ ├── muteActorList.ts │ │ │ │ │ │ │ ├── muteThread.ts │ │ │ │ │ │ │ ├── searchStarterPacks.ts │ │ │ │ │ │ │ ├── starterpack.ts │ │ │ │ │ │ │ ├── unmuteActor.ts │ │ │ │ │ │ │ ├── unmuteActorList.ts │ │ │ │ │ │ │ ├── unmuteThread.ts │ │ │ │ │ │ │ └── verification.ts │ │ │ │ │ │ ├── labeler/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getServices.ts │ │ │ │ │ │ │ └── service.ts │ │ │ │ │ │ ├── notification/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getUnreadCount.ts │ │ │ │ │ │ │ ├── listActivitySubscriptions.ts │ │ │ │ │ │ │ ├── listNotifications.ts │ │ │ │ │ │ │ ├── putActivitySubscription.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── putPreferencesV2.ts │ │ │ │ │ │ │ ├── registerPush.ts │ │ │ │ │ │ │ ├── unregisterPush.ts │ │ │ │ │ │ │ └── updateSeen.ts │ │ │ │ │ │ ├── richtext/ │ │ │ │ │ │ │ └── facet.ts │ │ │ │ │ │ ├── unspecced/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getAgeAssuranceState.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getPopularFeedGenerators.ts │ │ │ │ │ │ │ ├── getPostThreadOtherV2.ts │ │ │ │ │ │ │ ├── getPostThreadV2.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getSuggestedFeedsSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedOnboardingUsers.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedUsers.ts │ │ │ │ │ │ │ ├── getSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestionsSkeleton.ts │ │ │ │ │ │ │ ├── getTaggedSuggestions.ts │ │ │ │ │ │ │ ├── getTrendingTopics.ts │ │ │ │ │ │ │ ├── getTrends.ts │ │ │ │ │ │ │ ├── getTrendsSkeleton.ts │ │ │ │ │ │ │ ├── initAgeAssurance.ts │ │ │ │ │ │ │ ├── searchActorsSkeleton.ts │ │ │ │ │ │ │ ├── searchPostsSkeleton.ts │ │ │ │ │ │ │ └── searchStarterPacksSkeleton.ts │ │ │ │ │ │ └── video/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── getJobStatus.ts │ │ │ │ │ │ ├── getUploadLimits.ts │ │ │ │ │ │ └── uploadVideo.ts │ │ │ │ │ ├── chat/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ └── exportAccountData.ts │ │ │ │ │ │ ├── convo/ │ │ │ │ │ │ │ ├── acceptConvo.ts │ │ │ │ │ │ │ ├── addReaction.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteMessageForSelf.ts │ │ │ │ │ │ │ ├── getConvo.ts │ │ │ │ │ │ │ ├── getConvoAvailability.ts │ │ │ │ │ │ │ ├── getConvoForMembers.ts │ │ │ │ │ │ │ ├── getLog.ts │ │ │ │ │ │ │ ├── getMessages.ts │ │ │ │ │ │ │ ├── leaveConvo.ts │ │ │ │ │ │ │ ├── listConvos.ts │ │ │ │ │ │ │ ├── muteConvo.ts │ │ │ │ │ │ │ ├── removeReaction.ts │ │ │ │ │ │ │ ├── sendMessage.ts │ │ │ │ │ │ │ ├── sendMessageBatch.ts │ │ │ │ │ │ │ ├── unmuteConvo.ts │ │ │ │ │ │ │ ├── updateAllRead.ts │ │ │ │ │ │ │ └── updateRead.ts │ │ │ │ │ │ └── moderation/ │ │ │ │ │ │ ├── getActorMetadata.ts │ │ │ │ │ │ ├── getMessageContext.ts │ │ │ │ │ │ └── updateActorAccess.ts │ │ │ │ │ └── com/ │ │ │ │ │ ├── atproto/ │ │ │ │ │ │ ├── admin/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ ├── disableAccountInvites.ts │ │ │ │ │ │ │ ├── disableInviteCodes.ts │ │ │ │ │ │ │ ├── enableAccountInvites.ts │ │ │ │ │ │ │ ├── getAccountInfo.ts │ │ │ │ │ │ │ ├── getAccountInfos.ts │ │ │ │ │ │ │ ├── getInviteCodes.ts │ │ │ │ │ │ │ ├── getSubjectStatus.ts │ │ │ │ │ │ │ ├── searchAccounts.ts │ │ │ │ │ │ │ ├── sendEmail.ts │ │ │ │ │ │ │ ├── updateAccountEmail.ts │ │ │ │ │ │ │ ├── updateAccountHandle.ts │ │ │ │ │ │ │ ├── updateAccountPassword.ts │ │ │ │ │ │ │ ├── updateAccountSigningKey.ts │ │ │ │ │ │ │ └── updateSubjectStatus.ts │ │ │ │ │ │ ├── identity/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getRecommendedDidCredentials.ts │ │ │ │ │ │ │ ├── refreshIdentity.ts │ │ │ │ │ │ │ ├── requestPlcOperationSignature.ts │ │ │ │ │ │ │ ├── resolveDid.ts │ │ │ │ │ │ │ ├── resolveHandle.ts │ │ │ │ │ │ │ ├── resolveIdentity.ts │ │ │ │ │ │ │ ├── signPlcOperation.ts │ │ │ │ │ │ │ ├── submitPlcOperation.ts │ │ │ │ │ │ │ └── updateHandle.ts │ │ │ │ │ │ ├── label/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── queryLabels.ts │ │ │ │ │ │ │ └── subscribeLabels.ts │ │ │ │ │ │ ├── lexicon/ │ │ │ │ │ │ │ ├── resolveLexicon.ts │ │ │ │ │ │ │ └── schema.ts │ │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ │ ├── createReport.ts │ │ │ │ │ │ │ └── defs.ts │ │ │ │ │ │ ├── repo/ │ │ │ │ │ │ │ ├── applyWrites.ts │ │ │ │ │ │ │ ├── createRecord.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteRecord.ts │ │ │ │ │ │ │ ├── describeRepo.ts │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ ├── importRepo.ts │ │ │ │ │ │ │ ├── listMissingBlobs.ts │ │ │ │ │ │ │ ├── listRecords.ts │ │ │ │ │ │ │ ├── putRecord.ts │ │ │ │ │ │ │ ├── strongRef.ts │ │ │ │ │ │ │ └── uploadBlob.ts │ │ │ │ │ │ ├── server/ │ │ │ │ │ │ │ ├── activateAccount.ts │ │ │ │ │ │ │ ├── checkAccountStatus.ts │ │ │ │ │ │ │ ├── confirmEmail.ts │ │ │ │ │ │ │ ├── createAccount.ts │ │ │ │ │ │ │ ├── createAppPassword.ts │ │ │ │ │ │ │ ├── createInviteCode.ts │ │ │ │ │ │ │ ├── createInviteCodes.ts │ │ │ │ │ │ │ ├── createSession.ts │ │ │ │ │ │ │ ├── deactivateAccount.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ ├── deleteSession.ts │ │ │ │ │ │ │ ├── describeServer.ts │ │ │ │ │ │ │ ├── getAccountInviteCodes.ts │ │ │ │ │ │ │ ├── getServiceAuth.ts │ │ │ │ │ │ │ ├── getSession.ts │ │ │ │ │ │ │ ├── listAppPasswords.ts │ │ │ │ │ │ │ ├── refreshSession.ts │ │ │ │ │ │ │ ├── requestAccountDelete.ts │ │ │ │ │ │ │ ├── requestEmailConfirmation.ts │ │ │ │ │ │ │ ├── requestEmailUpdate.ts │ │ │ │ │ │ │ ├── requestPasswordReset.ts │ │ │ │ │ │ │ ├── reserveSigningKey.ts │ │ │ │ │ │ │ ├── resetPassword.ts │ │ │ │ │ │ │ ├── revokeAppPassword.ts │ │ │ │ │ │ │ └── updateEmail.ts │ │ │ │ │ │ ├── sync/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getBlob.ts │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ ├── getCheckout.ts │ │ │ │ │ │ │ ├── getHead.ts │ │ │ │ │ │ │ ├── getHostStatus.ts │ │ │ │ │ │ │ ├── getLatestCommit.ts │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ │ ├── getRepoStatus.ts │ │ │ │ │ │ │ ├── listBlobs.ts │ │ │ │ │ │ │ ├── listHosts.ts │ │ │ │ │ │ │ ├── listRepos.ts │ │ │ │ │ │ │ ├── listReposByCollection.ts │ │ │ │ │ │ │ ├── notifyOfUpdate.ts │ │ │ │ │ │ │ ├── requestCrawl.ts │ │ │ │ │ │ │ └── subscribeRepos.ts │ │ │ │ │ │ └── temp/ │ │ │ │ │ │ ├── addReservedHandle.ts │ │ │ │ │ │ ├── checkHandleAvailability.ts │ │ │ │ │ │ ├── checkSignupQueue.ts │ │ │ │ │ │ ├── dereferenceScope.ts │ │ │ │ │ │ ├── fetchLabels.ts │ │ │ │ │ │ ├── requestPhoneVerification.ts │ │ │ │ │ │ └── revokeAccountCredentials.ts │ │ │ │ │ └── germnetwork/ │ │ │ │ │ └── declaration.ts │ │ │ │ └── util.ts │ │ │ ├── logger.ts │ │ │ ├── pipeline.ts │ │ │ ├── proto/ │ │ │ │ ├── bsky_connect.ts │ │ │ │ ├── bsky_pb.ts │ │ │ │ ├── bsync_connect.ts │ │ │ │ ├── bsync_pb.ts │ │ │ │ ├── courier_connect.ts │ │ │ │ ├── courier_pb.ts │ │ │ │ ├── rolodex_connect.ts │ │ │ │ └── rolodex_pb.ts │ │ │ ├── redis.ts │ │ │ ├── rolodex.ts │ │ │ ├── stash.ts │ │ │ ├── util/ │ │ │ │ ├── debug.ts │ │ │ │ ├── http.ts │ │ │ │ ├── retry.ts │ │ │ │ └── uris.ts │ │ │ ├── util.ts │ │ │ └── views/ │ │ │ ├── index.ts │ │ │ ├── threads-v2.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── test.env │ │ ├── tests/ │ │ │ ├── __snapshots__/ │ │ │ │ └── feed-generation.test.ts.snap │ │ │ ├── _util.ts │ │ │ ├── admin/ │ │ │ │ ├── admin-auth.test.ts │ │ │ │ └── moderation.test.ts │ │ │ ├── auth.test.ts │ │ │ ├── blob-resolver.test.ts │ │ │ ├── data-plane/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── indexing.test.ts.snap │ │ │ │ ├── db.test.ts │ │ │ │ ├── duplicate-records.test.ts │ │ │ │ ├── handle-invalidation.test.ts │ │ │ │ ├── indexing.test.ts │ │ │ │ ├── subscription.test.ts │ │ │ │ └── thread-mutes.test.ts │ │ │ ├── entryway-auth.test.ts │ │ │ ├── etcd.test.ts │ │ │ ├── feed-generation.test.ts │ │ │ ├── hydration/ │ │ │ │ └── util.test.ts │ │ │ ├── image/ │ │ │ │ ├── server.test.ts │ │ │ │ ├── sharp.test.ts │ │ │ │ └── uri.test.ts │ │ │ ├── label-hydration.test.ts │ │ │ ├── postgates.test.ts │ │ │ ├── query-labels.test.ts │ │ │ ├── redis-cache.test.ts │ │ │ ├── seed/ │ │ │ │ ├── feed-hidden-replies.ts │ │ │ │ ├── get-suggested-starter-packs.ts │ │ │ │ ├── get-trends.ts │ │ │ │ ├── known-followers.ts │ │ │ │ └── postgates.ts │ │ │ ├── server.test.ts │ │ │ ├── sitemap.test.ts │ │ │ ├── stash.test.ts │ │ │ ├── utils.test.ts │ │ │ └── views/ │ │ │ ├── __snapshots__/ │ │ │ │ ├── actor-search.test.ts.snap │ │ │ │ ├── author-feed.test.ts.snap │ │ │ │ ├── block-lists.test.ts.snap │ │ │ │ ├── blocks.test.ts.snap │ │ │ │ ├── bookmarks.test.ts.snap │ │ │ │ ├── follows.test.ts.snap │ │ │ │ ├── labeler-service.test.ts.snap │ │ │ │ ├── likes.test.ts.snap │ │ │ │ ├── list-feed.test.ts.snap │ │ │ │ ├── lists.test.ts.snap │ │ │ │ ├── mute-lists.test.ts.snap │ │ │ │ ├── mutes.test.ts.snap │ │ │ │ ├── notifications.test.ts.snap │ │ │ │ ├── posts.test.ts.snap │ │ │ │ ├── profile.test.ts.snap │ │ │ │ ├── quotes.test.ts.snap │ │ │ │ ├── reposts.test.ts.snap │ │ │ │ ├── starter-packs.test.ts.snap │ │ │ │ ├── thread-v2.test.ts.snap │ │ │ │ ├── thread.test.ts.snap │ │ │ │ ├── threadgating.test.ts.snap │ │ │ │ └── timeline.test.ts.snap │ │ │ ├── account-deactivation.test.ts │ │ │ ├── actor-likes.test.ts │ │ │ ├── actor-search.test.ts │ │ │ ├── age-assurance-v2.test.ts │ │ │ ├── age-assurance.test.ts │ │ │ ├── author-feed.test.ts │ │ │ ├── block-lists.test.ts │ │ │ ├── blocks.test.ts │ │ │ ├── bookmarks.test.ts │ │ │ ├── drafts.test.ts │ │ │ ├── feed-hidden-replies.test.ts │ │ │ ├── feed-view-post.test.ts │ │ │ ├── follows.test.ts │ │ │ ├── get-config.test.ts │ │ │ ├── get-suggested-onboarding-users.test.ts │ │ │ ├── get-suggested-starter-packs.test.ts │ │ │ ├── get-trends.test.ts │ │ │ ├── known-followers.test.ts │ │ │ ├── labeler-service.test.ts │ │ │ ├── labels-needs-review.test.ts │ │ │ ├── labels-takedown.test.ts │ │ │ ├── likes.test.ts │ │ │ ├── list-feed.test.ts │ │ │ ├── lists.test.ts │ │ │ ├── mute-lists.test.ts │ │ │ ├── mutes.test.ts │ │ │ ├── notifications.test.ts │ │ │ ├── post-search.test.ts │ │ │ ├── posts-debug.test.ts │ │ │ ├── posts.test.ts │ │ │ ├── profile-debug.test.ts │ │ │ ├── profile.test.ts │ │ │ ├── quotes.test.ts │ │ │ ├── reposts.test.ts │ │ │ ├── starter-packs.test.ts │ │ │ ├── suggestions.test.ts │ │ │ ├── thread-v2.test.ts │ │ │ ├── thread.test.ts │ │ │ ├── threadgating.test.ts │ │ │ ├── timeline.test.ts │ │ │ └── verification.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── bsync/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── bin/ │ │ │ └── migration-create.ts │ │ ├── buf.gen.yaml │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── proto/ │ │ │ └── bsync.proto │ │ ├── src/ │ │ │ ├── client.ts │ │ │ ├── config.ts │ │ │ ├── context.ts │ │ │ ├── db/ │ │ │ │ ├── index.ts │ │ │ │ ├── migrations/ │ │ │ │ │ ├── 20240108T220751294Z-init.ts │ │ │ │ │ ├── 20240717T224303472Z-notif-ops.ts │ │ │ │ │ ├── 20250527T022203400Z-add-operation.ts │ │ │ │ │ ├── 20250603T163446567Z-alter-operation.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── provider.ts │ │ │ │ ├── schema/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── mute_item.ts │ │ │ │ │ ├── mute_op.ts │ │ │ │ │ ├── notif_item.ts │ │ │ │ │ ├── notif_op.ts │ │ │ │ │ └── operation.ts │ │ │ │ └── types.ts │ │ │ ├── index.ts │ │ │ ├── logger.ts │ │ │ ├── proto/ │ │ │ │ ├── bsync_connect.ts │ │ │ │ └── bsync_pb.ts │ │ │ └── routes/ │ │ │ ├── add-mute-operation.ts │ │ │ ├── add-notif-operation.ts │ │ │ ├── auth.ts │ │ │ ├── delete-operations.ts │ │ │ ├── index.ts │ │ │ ├── put-operation.ts │ │ │ ├── scan-mute-operations.ts │ │ │ ├── scan-notif-operations.ts │ │ │ ├── scan-operations.ts │ │ │ └── util.ts │ │ ├── tests/ │ │ │ ├── delete-operations.test.ts │ │ │ ├── mutes.test.ts │ │ │ ├── notifications.test.ts │ │ │ └── operations.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── common/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── buffers.ts │ │ │ ├── dates.ts │ │ │ ├── env.ts │ │ │ ├── fs.ts │ │ │ ├── index.ts │ │ │ ├── ipld-multi.ts │ │ │ ├── ipld.ts │ │ │ ├── logger.ts │ │ │ ├── obfuscate.ts │ │ │ └── streams.ts │ │ ├── tests/ │ │ │ ├── ipld-multi.test.ts │ │ │ ├── ipld-vectors.ts │ │ │ ├── ipld.test.ts │ │ │ └── streams.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── common-web/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── arrays.ts │ │ │ ├── async.ts │ │ │ ├── check.ts │ │ │ ├── did-doc.ts │ │ │ ├── index.ts │ │ │ ├── ipld.ts │ │ │ ├── retry.ts │ │ │ ├── strings.ts │ │ │ ├── tid.ts │ │ │ ├── times.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── tests/ │ │ │ ├── check.test.ts │ │ │ ├── retry.test.ts │ │ │ ├── tid.test.ts │ │ │ └── util.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── crypto/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── const.ts │ │ │ ├── did.ts │ │ │ ├── index.ts │ │ │ ├── multibase.ts │ │ │ ├── p256/ │ │ │ │ ├── encoding.ts │ │ │ │ ├── keypair.ts │ │ │ │ ├── operations.ts │ │ │ │ └── plugin.ts │ │ │ ├── plugins.ts │ │ │ ├── random.ts │ │ │ ├── secp256k1/ │ │ │ │ ├── encoding.ts │ │ │ │ ├── keypair.ts │ │ │ │ ├── operations.ts │ │ │ │ └── plugin.ts │ │ │ ├── sha.ts │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ └── verify.ts │ │ ├── tests/ │ │ │ ├── did.test.ts │ │ │ ├── key-compression.test.ts │ │ │ ├── keypairs.test.ts │ │ │ ├── random.test.ts │ │ │ └── signatures.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── dev-env/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── bin.ts │ │ │ ├── bsky.ts │ │ │ ├── bsync.ts │ │ │ ├── const.ts │ │ │ ├── env.ts │ │ │ ├── feed-gen.ts │ │ │ ├── index.ts │ │ │ ├── introspect.ts │ │ │ ├── mock/ │ │ │ │ ├── data.ts │ │ │ │ ├── img/ │ │ │ │ │ ├── blur-hash-avatar-b64.ts │ │ │ │ │ └── labeled-img-b64.ts │ │ │ │ └── index.ts │ │ │ ├── moderator-client.ts │ │ │ ├── network-no-appview.ts │ │ │ ├── network.ts │ │ │ ├── ozone.ts │ │ │ ├── pds.ts │ │ │ ├── plc.ts │ │ │ ├── seed/ │ │ │ │ ├── author-feed.ts │ │ │ │ ├── basic.ts │ │ │ │ ├── client.ts │ │ │ │ ├── follows.ts │ │ │ │ ├── index.ts │ │ │ │ ├── likes.ts │ │ │ │ ├── quotes.ts │ │ │ │ ├── reposts.ts │ │ │ │ ├── thread-v2.ts │ │ │ │ ├── users-bulk.ts │ │ │ │ ├── users.ts │ │ │ │ └── verifications.ts │ │ │ ├── service-profile-lexicon.ts │ │ │ ├── service-profile-ozone.ts │ │ │ ├── service-profile.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── dev-infra/ │ │ ├── README.md │ │ ├── _common.sh │ │ ├── docker-compose.yaml │ │ ├── with-test-db.sh │ │ └── with-test-redis-and-db.sh │ ├── did/ │ │ ├── CHANGELOG.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── atproto.ts │ │ │ ├── did-document.ts │ │ │ ├── did-error.ts │ │ │ ├── did.ts │ │ │ ├── index.ts │ │ │ ├── lib/ │ │ │ │ └── uri.ts │ │ │ ├── methods/ │ │ │ │ ├── plc.ts │ │ │ │ └── web.ts │ │ │ ├── methods.ts │ │ │ └── utils.ts │ │ ├── tests/ │ │ │ └── methods/ │ │ │ ├── plc.test.ts │ │ │ └── web.test.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── identity/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── did/ │ │ │ │ ├── atproto-data.ts │ │ │ │ ├── base-resolver.ts │ │ │ │ ├── did-resolver.ts │ │ │ │ ├── index.ts │ │ │ │ ├── memory-cache.ts │ │ │ │ ├── plc-resolver.ts │ │ │ │ ├── util.ts │ │ │ │ └── web-resolver.ts │ │ │ ├── errors.ts │ │ │ ├── handle/ │ │ │ │ └── index.ts │ │ │ ├── id-resolver.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── test.env │ │ ├── tests/ │ │ │ ├── did-cache.test.ts │ │ │ ├── did-document.test.ts │ │ │ ├── did-resolver.test.ts │ │ │ ├── handle-resolver.test.ts │ │ │ └── web/ │ │ │ ├── db.ts │ │ │ └── server.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── internal/ │ │ ├── did-resolver/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── create-did-resolver.ts │ │ │ │ ├── did-cache-memory.ts │ │ │ │ ├── did-cache.ts │ │ │ │ ├── did-method.ts │ │ │ │ ├── did-resolver-base.ts │ │ │ │ ├── did-resolver-common.ts │ │ │ │ ├── did-resolver.ts │ │ │ │ ├── index.ts │ │ │ │ ├── methods/ │ │ │ │ │ ├── plc.ts │ │ │ │ │ └── web.ts │ │ │ │ ├── methods.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── fetch/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── fetch-error.ts │ │ │ │ ├── fetch-request.ts │ │ │ │ ├── fetch-response.ts │ │ │ │ ├── fetch-wrap.ts │ │ │ │ ├── fetch.ts │ │ │ │ ├── index.ts │ │ │ │ ├── transformed-response.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── fetch-node/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ ├── safe.ts │ │ │ │ ├── unicast.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── handle-resolver/ │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── atproto-doh-handle-resolver.ts │ │ │ │ ├── atproto-handle-resolver.ts │ │ │ │ ├── cached-handle-resolver.ts │ │ │ │ ├── create-handle-resolver.ts │ │ │ │ ├── handle-resolver-error.ts │ │ │ │ ├── index.ts │ │ │ │ ├── internal-resolvers/ │ │ │ │ │ ├── dns-handle-resolver.ts │ │ │ │ │ └── well-known-handler-resolver.ts │ │ │ │ ├── types.ts │ │ │ │ └── xrpc-handle-resolver.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── handle-resolver-node/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── atproto-handle-resolver-node.ts │ │ │ │ ├── index.ts │ │ │ │ └── node-resolve-txt-factory.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── identity-resolver/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── atproto-identity-resolver.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── create-identity-resolver.ts │ │ │ │ ├── identity-resolver-error.ts │ │ │ │ ├── identity-resolver.ts │ │ │ │ ├── index.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── pipe/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ ├── pipe.ts │ │ │ │ └── type.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── rollup-plugin-bundle-manifest/ │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── index.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── simple-store/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── cached-getter.ts │ │ │ │ ├── index.ts │ │ │ │ ├── simple-store.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── simple-store-memory/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── simple-store-redis/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── index.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ └── xrpc-utils/ │ │ ├── CHANGELOG.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── accept.ts │ │ │ └── index.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── lex/ │ │ ├── lex/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── bin/ │ │ │ │ └── lex │ │ │ ├── lexicons/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ ├── 4-2/ │ │ │ │ │ └── unsafeDefs.json │ │ │ │ ├── arrayLength.json │ │ │ │ ├── atIdentifier.json │ │ │ │ ├── atUri.json │ │ │ │ ├── boolConst.json │ │ │ │ ├── byteLength.json │ │ │ │ ├── cid.json │ │ │ │ ├── datetime.json │ │ │ │ ├── default.json │ │ │ │ ├── did.json │ │ │ │ ├── handle.json │ │ │ │ ├── integerConst.json │ │ │ │ ├── integerEnum.json │ │ │ │ ├── integerRange.json │ │ │ │ ├── kitchenSink.json │ │ │ │ ├── language.json │ │ │ │ ├── nsid.json │ │ │ │ ├── optional.json │ │ │ │ ├── parametersEnum.json │ │ │ │ ├── procedure.json │ │ │ │ ├── procedureKnownValues.json │ │ │ │ ├── query.json │ │ │ │ ├── stringConst.json │ │ │ │ ├── stringEnum.json │ │ │ │ ├── stringKnownValues.json │ │ │ │ ├── stringLength.json │ │ │ │ ├── stringLengthGrapheme.json │ │ │ │ ├── stringLengthNoMinLength.json │ │ │ │ ├── subscription.json │ │ │ │ ├── token.json │ │ │ │ ├── union.json │ │ │ │ ├── unknown.json │ │ │ │ └── uri.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── index.ts │ │ │ ├── tests/ │ │ │ │ ├── array.test.ts │ │ │ │ ├── boolean.test.ts │ │ │ │ ├── byte.test.ts │ │ │ │ ├── defaults.test.ts │ │ │ │ ├── integer.test.ts │ │ │ │ ├── parameters.test.ts │ │ │ │ ├── procedure.test.ts │ │ │ │ ├── query.test.ts │ │ │ │ ├── string.test.ts │ │ │ │ ├── token.test.ts │ │ │ │ ├── union.test.ts │ │ │ │ ├── unknown.test.ts │ │ │ │ └── unsafe.test.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-builder/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── filter.ts │ │ │ │ ├── filtered-indexer.test.ts │ │ │ │ ├── filtered-indexer.ts │ │ │ │ ├── formatter.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lex-builder.ts │ │ │ │ ├── lex-def-builder.ts │ │ │ │ ├── lexicon-directory-indexer.ts │ │ │ │ ├── polyfill.ts │ │ │ │ ├── ref-resolver.test.ts │ │ │ │ ├── ref-resolver.ts │ │ │ │ ├── ts-lang.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-cbor/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── encoding.ts │ │ │ │ └── index.ts │ │ │ ├── tests/ │ │ │ │ ├── codec.test.ts │ │ │ │ ├── dag-cbor.test.ts │ │ │ │ ├── data-model-fixtures.json │ │ │ │ ├── fixtures.test.ts │ │ │ │ ├── vectors.test.ts │ │ │ │ └── vectors.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ ├── vite.config.mts │ │ │ └── vitest.config.ts │ │ ├── lex-client/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── scripts/ │ │ │ │ └── lex-build.mjs │ │ │ ├── src/ │ │ │ │ ├── agent.test.ts │ │ │ │ ├── agent.ts │ │ │ │ ├── client.ts │ │ │ │ ├── errors.test.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── index.ts │ │ │ │ ├── response.ts │ │ │ │ ├── types.ts │ │ │ │ ├── util.test.ts │ │ │ │ ├── util.ts │ │ │ │ ├── www-authenticate.test.ts │ │ │ │ ├── www-authenticate.ts │ │ │ │ ├── xrpc.test.ts │ │ │ │ └── xrpc.ts │ │ │ ├── tests/ │ │ │ │ └── client.test.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-data/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── blob.test.ts │ │ │ │ ├── blob.ts │ │ │ │ ├── cid-implementation.test.ts │ │ │ │ ├── cid.test.ts │ │ │ │ ├── cid.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lex-equals.test.ts │ │ │ │ ├── lex-equals.ts │ │ │ │ ├── lex-error.test.ts │ │ │ │ ├── lex-error.ts │ │ │ │ ├── lex.test.ts │ │ │ │ ├── lex.ts │ │ │ │ ├── lib/ │ │ │ │ │ ├── nodejs-buffer.ts │ │ │ │ │ ├── util.test.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── object.test.ts │ │ │ │ ├── object.ts │ │ │ │ ├── uint8array-base64.ts │ │ │ │ ├── uint8array-concat.test.ts │ │ │ │ ├── uint8array-concat.ts │ │ │ │ ├── uint8array-from-base64.test.ts │ │ │ │ ├── uint8array-from-base64.ts │ │ │ │ ├── uint8array-to-base64.test.ts │ │ │ │ ├── uint8array-to-base64.ts │ │ │ │ ├── uint8array.test.ts │ │ │ │ ├── uint8array.ts │ │ │ │ ├── utf8-from-base64.test.ts │ │ │ │ ├── utf8-from-base64.ts │ │ │ │ ├── utf8-grapheme-len.test.ts │ │ │ │ ├── utf8-grapheme-len.ts │ │ │ │ ├── utf8-len.test.ts │ │ │ │ ├── utf8-len.ts │ │ │ │ ├── utf8-to-base64.test.ts │ │ │ │ ├── utf8-to-base64.ts │ │ │ │ └── utf8.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-document/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ ├── lexicon-document.test.ts │ │ │ │ ├── lexicon-document.ts │ │ │ │ ├── lexicon-indexer.ts │ │ │ │ ├── lexicon-iterable-indexer.ts │ │ │ │ ├── lexicon-schema-builder.test.ts │ │ │ │ └── lexicon-schema-builder.ts │ │ │ ├── tests/ │ │ │ │ ├── fixtures.test.ts │ │ │ │ ├── lexicon-invalid.json │ │ │ │ └── lexicon-valid.json │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-installer/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── fs.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lex-installer.ts │ │ │ │ ├── lexicons-manifest.test.ts │ │ │ │ ├── lexicons-manifest.ts │ │ │ │ ├── nsid-map.ts │ │ │ │ └── nsid-set.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-json/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── blob.ts │ │ │ │ ├── bytes.test.ts │ │ │ │ ├── bytes.ts │ │ │ │ ├── index.ts │ │ │ │ ├── json.ts │ │ │ │ ├── lex-json.test.ts │ │ │ │ ├── lex-json.ts │ │ │ │ └── link.ts │ │ │ ├── tests/ │ │ │ │ ├── data-model-invalid.json │ │ │ │ ├── data-model-valid.json │ │ │ │ └── fixtures.test.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-password-session/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── scripts/ │ │ │ │ └── lex-build.mjs │ │ │ ├── src/ │ │ │ │ ├── error.ts │ │ │ │ ├── index.ts │ │ │ │ ├── password-session-utils.test.ts │ │ │ │ ├── password-session.test.ts │ │ │ │ ├── password-session.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-resolver/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── scripts/ │ │ │ │ └── lex-build.mjs │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ ├── lex-resolver-error.ts │ │ │ │ └── lex-resolver.ts │ │ │ ├── tests/ │ │ │ │ └── index.test.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ ├── lex-schema/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── core/ │ │ │ │ │ ├── $type.test.ts │ │ │ │ │ ├── $type.ts │ │ │ │ │ ├── record-key.ts │ │ │ │ │ ├── result.ts │ │ │ │ │ ├── schema.ts │ │ │ │ │ ├── standard-schema.test.ts │ │ │ │ │ ├── standard-schema.ts │ │ │ │ │ ├── string-format.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── validation-error.ts │ │ │ │ │ ├── validation-issue.ts │ │ │ │ │ └── validator.ts │ │ │ │ ├── core.ts │ │ │ │ ├── external.ts │ │ │ │ ├── helpers.test.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── index.ts │ │ │ │ ├── schema/ │ │ │ │ │ ├── array.test.ts │ │ │ │ │ ├── array.ts │ │ │ │ │ ├── blob.test.ts │ │ │ │ │ ├── blob.ts │ │ │ │ │ ├── boolean.test.ts │ │ │ │ │ ├── boolean.ts │ │ │ │ │ ├── bytes.test.ts │ │ │ │ │ ├── bytes.ts │ │ │ │ │ ├── cid.test.ts │ │ │ │ │ ├── cid.ts │ │ │ │ │ ├── custom.test.ts │ │ │ │ │ ├── custom.ts │ │ │ │ │ ├── dict.test.ts │ │ │ │ │ ├── dict.ts │ │ │ │ │ ├── discriminated-union.test.ts │ │ │ │ │ ├── discriminated-union.ts │ │ │ │ │ ├── enum.test.ts │ │ │ │ │ ├── enum.ts │ │ │ │ │ ├── integer.test.ts │ │ │ │ │ ├── integer.ts │ │ │ │ │ ├── intersection.test.ts │ │ │ │ │ ├── intersection.ts │ │ │ │ │ ├── lex-map.test.ts │ │ │ │ │ ├── lex-map.ts │ │ │ │ │ ├── lex-value.test.ts │ │ │ │ │ ├── lex-value.ts │ │ │ │ │ ├── literal.test.ts │ │ │ │ │ ├── literal.ts │ │ │ │ │ ├── never.test.ts │ │ │ │ │ ├── never.ts │ │ │ │ │ ├── null.test.ts │ │ │ │ │ ├── null.ts │ │ │ │ │ ├── nullable.test.ts │ │ │ │ │ ├── nullable.ts │ │ │ │ │ ├── object.test.ts │ │ │ │ │ ├── object.ts │ │ │ │ │ ├── optional.test.ts │ │ │ │ │ ├── optional.ts │ │ │ │ │ ├── params.test.ts │ │ │ │ │ ├── params.ts │ │ │ │ │ ├── payload.test.ts │ │ │ │ │ ├── payload.ts │ │ │ │ │ ├── permission-set.test.ts │ │ │ │ │ ├── permission-set.ts │ │ │ │ │ ├── permission.test.ts │ │ │ │ │ ├── permission.ts │ │ │ │ │ ├── procedure.test.ts │ │ │ │ │ ├── procedure.ts │ │ │ │ │ ├── query.test.ts │ │ │ │ │ ├── query.ts │ │ │ │ │ ├── record.test.ts │ │ │ │ │ ├── record.ts │ │ │ │ │ ├── ref.test.ts │ │ │ │ │ ├── ref.ts │ │ │ │ │ ├── refine.test.ts │ │ │ │ │ ├── refine.ts │ │ │ │ │ ├── regexp.test.ts │ │ │ │ │ ├── regexp.ts │ │ │ │ │ ├── string.test.ts │ │ │ │ │ ├── string.ts │ │ │ │ │ ├── subscription.test.ts │ │ │ │ │ ├── subscription.ts │ │ │ │ │ ├── token.test.ts │ │ │ │ │ ├── token.ts │ │ │ │ │ ├── typed-object.test.ts │ │ │ │ │ ├── typed-object.ts │ │ │ │ │ ├── typed-ref.test.ts │ │ │ │ │ ├── typed-ref.ts │ │ │ │ │ ├── typed-union.test.ts │ │ │ │ │ ├── typed-union.ts │ │ │ │ │ ├── union.test.ts │ │ │ │ │ ├── union.ts │ │ │ │ │ ├── unknown.test.ts │ │ │ │ │ ├── unknown.ts │ │ │ │ │ └── with-default.ts │ │ │ │ ├── schema.ts │ │ │ │ └── util/ │ │ │ │ ├── array-agg.test.ts │ │ │ │ ├── array-agg.ts │ │ │ │ ├── assertion-util.ts │ │ │ │ ├── if-any.ts │ │ │ │ ├── lazy-property.ts │ │ │ │ └── memoize.ts │ │ │ ├── tests/ │ │ │ │ └── l.test.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tests.json │ │ │ └── vitest.config.ts │ │ └── lex-server/ │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── examples/ │ │ │ └── subscription.mjs │ │ ├── nodejs.d.ts │ │ ├── nodejs.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── errors.test.ts │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ ├── lex-router.test.ts │ │ │ ├── lex-router.ts │ │ │ ├── lib/ │ │ │ │ ├── drain-websocket.ts │ │ │ │ ├── sleep.ts │ │ │ │ ├── www-authenticate.test.ts │ │ │ │ └── www-authenticate.ts │ │ │ ├── nodejs.test.ts │ │ │ ├── nodejs.ts │ │ │ └── service-auth.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.examples.json │ │ ├── tsconfig.json │ │ ├── tsconfig.tests.json │ │ └── vitest.config.ts │ ├── lex-cli/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── codegen/ │ │ │ │ ├── client.ts │ │ │ │ ├── common.ts │ │ │ │ ├── lex-gen.ts │ │ │ │ ├── server.ts │ │ │ │ └── util.ts │ │ │ ├── index.ts │ │ │ ├── mdgen/ │ │ │ │ └── index.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── lexicon/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── blob-refs.ts │ │ │ ├── index.ts │ │ │ ├── lexicons.ts │ │ │ ├── serialize.ts │ │ │ ├── types.ts │ │ │ ├── util.ts │ │ │ ├── validation.ts │ │ │ └── validators/ │ │ │ ├── blob.ts │ │ │ ├── complex.ts │ │ │ ├── formats.ts │ │ │ ├── primitives.ts │ │ │ └── xrpc.ts │ │ ├── tests/ │ │ │ ├── _scaffolds/ │ │ │ │ └── lexicons.ts │ │ │ └── general.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── lexicon-resolver/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ ├── lexicon.ts │ │ │ ├── lexicons/ │ │ │ │ ├── com/ │ │ │ │ │ ├── atproto/ │ │ │ │ │ │ ├── lexicon/ │ │ │ │ │ │ │ ├── schema.defs.ts │ │ │ │ │ │ │ └── schema.ts │ │ │ │ │ │ ├── lexicon.ts │ │ │ │ │ │ ├── sync/ │ │ │ │ │ │ │ ├── getRecord.defs.ts │ │ │ │ │ │ │ └── getRecord.ts │ │ │ │ │ │ └── sync.ts │ │ │ │ │ └── atproto.ts │ │ │ │ ├── com.ts │ │ │ │ └── index.ts │ │ │ ├── record.ts │ │ │ └── util.ts │ │ ├── tests/ │ │ │ ├── lexicon.test.ts │ │ │ └── record.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── oauth/ │ │ ├── jwk/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── alg.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── index.ts │ │ │ │ ├── jwk.ts │ │ │ │ ├── jwks.ts │ │ │ │ ├── jwt-decode.ts │ │ │ │ ├── jwt-verify.ts │ │ │ │ ├── jwt.ts │ │ │ │ ├── key.ts │ │ │ │ ├── keyset.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── jwk-jose/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ ├── jose-key.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── jwk-webcrypto/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ ├── util.ts │ │ │ │ └── webcrypto-key.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── oauth-client/ │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── constants.ts │ │ │ │ ├── errors/ │ │ │ │ │ ├── auth-method-unsatisfiable-error.ts │ │ │ │ │ ├── token-invalid-error.ts │ │ │ │ │ ├── token-refresh-error.ts │ │ │ │ │ └── token-revoked-error.ts │ │ │ │ ├── fetch-dpop.ts │ │ │ │ ├── identity-resolver.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lock.ts │ │ │ │ ├── oauth-authorization-server-metadata-resolver.ts │ │ │ │ ├── oauth-callback-error.ts │ │ │ │ ├── oauth-client-auth.ts │ │ │ │ ├── oauth-client.ts │ │ │ │ ├── oauth-protected-resource-metadata-resolver.ts │ │ │ │ ├── oauth-resolver-error.ts │ │ │ │ ├── oauth-resolver.ts │ │ │ │ ├── oauth-response-error.ts │ │ │ │ ├── oauth-server-agent.ts │ │ │ │ ├── oauth-server-factory.ts │ │ │ │ ├── oauth-session.ts │ │ │ │ ├── runtime-implementation.ts │ │ │ │ ├── runtime.ts │ │ │ │ ├── session-getter.ts │ │ │ │ ├── state-store.ts │ │ │ │ ├── types.ts │ │ │ │ ├── util.ts │ │ │ │ └── validate-client-metadata.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── oauth-client-browser/ │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── browser-oauth-client.ts │ │ │ │ ├── browser-oauth-database.ts │ │ │ │ ├── browser-runtime-implementation.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── index.ts │ │ │ │ ├── indexed-db/ │ │ │ │ │ ├── README.md │ │ │ │ │ ├── db-index.ts │ │ │ │ │ ├── db-object-store.ts │ │ │ │ │ ├── db-transaction.ts │ │ │ │ │ ├── db.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── schema.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── indexed-db-store.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── oauth-client-browser-example/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── server.js │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── Home.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── AtmosphereSignInDialog.tsx │ │ │ │ │ ├── AtmosphereSignInForm.tsx │ │ │ │ │ ├── Button.tsx │ │ │ │ │ ├── ButtonDropdown.tsx │ │ │ │ │ ├── Icons.tsx │ │ │ │ │ ├── JsonQueryResult.tsx │ │ │ │ │ ├── Layout.tsx │ │ │ │ │ ├── ProfileInfo.tsx │ │ │ │ │ ├── SessionInfo.tsx │ │ │ │ │ ├── Spinner.tsx │ │ │ │ │ ├── TokenInfo.tsx │ │ │ │ │ └── UserMenu.tsx │ │ │ │ ├── constants.ts │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ ├── lexicons.ts │ │ │ │ ├── lib/ │ │ │ │ │ ├── use-abortable-effect.ts │ │ │ │ │ ├── use-blob-url.ts │ │ │ │ │ ├── use-click-outside.ts │ │ │ │ │ ├── use-escape-key.ts │ │ │ │ │ └── use-random-string.ts │ │ │ │ ├── oauthClient.ts │ │ │ │ ├── providers/ │ │ │ │ │ ├── AuthenticationProvider.tsx │ │ │ │ │ ├── BskyClientProvider.tsx │ │ │ │ │ └── OAuthProvider.tsx │ │ │ │ └── queries/ │ │ │ │ ├── use-get-token-info-query.ts │ │ │ │ ├── use-lex-query.ts │ │ │ │ └── use-lex-record.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.tools.json │ │ │ └── vite.config.mjs │ │ ├── oauth-client-expo/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── android/ │ │ │ │ ├── .editorconfig │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── expo/ │ │ │ │ └── modules/ │ │ │ │ └── atprotooauthclient/ │ │ │ │ ├── Crypto.kt │ │ │ │ ├── ExpoAtprotoOAuthClientModule.kt │ │ │ │ ├── Jose.kt │ │ │ │ └── Records.kt │ │ │ ├── expo-module.config.json │ │ │ ├── ios/ │ │ │ │ ├── Crypto.swift │ │ │ │ ├── ExpoAtprotoOAuthClient.podspec │ │ │ │ ├── ExpoAtprotoOAuthClientModule.swift │ │ │ │ ├── Jose.swift │ │ │ │ └── Records.swift │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── ExpoAtprotoOAuthClientModule.ts │ │ │ │ ├── ExpoAtprotoOAuthClientModule.types.ts │ │ │ │ ├── expo-oauth-client-interface.ts │ │ │ │ ├── expo-oauth-client-options.ts │ │ │ │ ├── expo-oauth-client.d.ts │ │ │ │ ├── expo-oauth-client.native.ts │ │ │ │ ├── expo-oauth-client.web.ts │ │ │ │ ├── index.ts │ │ │ │ ├── polyfill.d.ts │ │ │ │ ├── polyfill.native.ts │ │ │ │ ├── polyfill.web.ts │ │ │ │ └── utils/ │ │ │ │ ├── expo-key.ts │ │ │ │ ├── mmkv-simple-store-ttl.ts │ │ │ │ ├── mmkv-simple-store.ts │ │ │ │ └── stores.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── oauth-client-node/ │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.ts │ │ │ │ ├── node-dpop-store.ts │ │ │ │ ├── node-oauth-client.ts │ │ │ │ └── util.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── oauth-provider/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── access-token/ │ │ │ │ │ └── access-token-mode.ts │ │ │ │ ├── account/ │ │ │ │ │ ├── account-manager.ts │ │ │ │ │ ├── account-store.ts │ │ │ │ │ ├── sign-in-data.ts │ │ │ │ │ └── sign-up-input.ts │ │ │ │ ├── client/ │ │ │ │ │ ├── client-auth.ts │ │ │ │ │ ├── client-data.ts │ │ │ │ │ ├── client-id.ts │ │ │ │ │ ├── client-info.ts │ │ │ │ │ ├── client-manager.ts │ │ │ │ │ ├── client-store.ts │ │ │ │ │ ├── client-utils.ts │ │ │ │ │ └── client.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── customization/ │ │ │ │ │ ├── branding.ts │ │ │ │ │ ├── build-customization-css.ts │ │ │ │ │ ├── build-customization-data.ts │ │ │ │ │ ├── colors.ts │ │ │ │ │ ├── customization.ts │ │ │ │ │ └── links.ts │ │ │ │ ├── device/ │ │ │ │ │ ├── device-data.ts │ │ │ │ │ ├── device-id.ts │ │ │ │ │ ├── device-manager.ts │ │ │ │ │ ├── device-store.ts │ │ │ │ │ └── session-id.ts │ │ │ │ ├── dpop/ │ │ │ │ │ ├── dpop-manager.ts │ │ │ │ │ ├── dpop-nonce.ts │ │ │ │ │ └── dpop-proof.ts │ │ │ │ ├── errors/ │ │ │ │ │ ├── access-denied-error.ts │ │ │ │ │ ├── account-selection-required-error.ts │ │ │ │ │ ├── authorization-error.ts │ │ │ │ │ ├── consent-required-error.ts │ │ │ │ │ ├── error-parser.ts │ │ │ │ │ ├── handle-unavailable-error.ts │ │ │ │ │ ├── invalid-authorization-details-error.ts │ │ │ │ │ ├── invalid-client-error.ts │ │ │ │ │ ├── invalid-client-id-error.ts │ │ │ │ │ ├── invalid-client-metadata-error.ts │ │ │ │ │ ├── invalid-dpop-key-binding-error.ts │ │ │ │ │ ├── invalid-dpop-proof-error.ts │ │ │ │ │ ├── invalid-grant-error.ts │ │ │ │ │ ├── invalid-invite-code-error.ts │ │ │ │ │ ├── invalid-redirect-uri-error.ts │ │ │ │ │ ├── invalid-request-error.ts │ │ │ │ │ ├── invalid-scope-error.ts │ │ │ │ │ ├── invalid-token-error.ts │ │ │ │ │ ├── login-required-error.ts │ │ │ │ │ ├── oauth-error.ts │ │ │ │ │ ├── second-authentication-factor-required-error.ts │ │ │ │ │ ├── unauthorized-client-error.ts │ │ │ │ │ ├── use-dpop-nonce-error.ts │ │ │ │ │ └── www-authenticate-error.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lexicon/ │ │ │ │ │ ├── lexicon-data.ts │ │ │ │ │ ├── lexicon-getter.ts │ │ │ │ │ ├── lexicon-manager.ts │ │ │ │ │ └── lexicon-store.ts │ │ │ │ ├── lib/ │ │ │ │ │ ├── csp/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── hcaptcha.ts │ │ │ │ │ ├── html/ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── build-document.ts │ │ │ │ │ │ ├── escapers.ts │ │ │ │ │ │ ├── html.ts │ │ │ │ │ │ ├── hydration-data.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── tags.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ ├── http/ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── accept.ts │ │ │ │ │ │ ├── context.ts │ │ │ │ │ │ ├── headers.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── method.ts │ │ │ │ │ │ ├── middleware.ts │ │ │ │ │ │ ├── parser.ts │ │ │ │ │ │ ├── path.ts │ │ │ │ │ │ ├── request.ts │ │ │ │ │ │ ├── response.ts │ │ │ │ │ │ ├── route.ts │ │ │ │ │ │ ├── router.ts │ │ │ │ │ │ ├── security-headers.ts │ │ │ │ │ │ ├── stream.ts │ │ │ │ │ │ ├── types.ts │ │ │ │ │ │ └── url.ts │ │ │ │ │ ├── nsid.ts │ │ │ │ │ ├── redis.ts │ │ │ │ │ ├── util/ │ │ │ │ │ │ ├── authorization-header.ts │ │ │ │ │ │ ├── cast.ts │ │ │ │ │ │ ├── color.ts │ │ │ │ │ │ ├── crypto.ts │ │ │ │ │ │ ├── date.ts │ │ │ │ │ │ ├── error.ts │ │ │ │ │ │ ├── function.ts │ │ │ │ │ │ ├── locale.ts │ │ │ │ │ │ ├── object.ts │ │ │ │ │ │ ├── redirect-uri.ts │ │ │ │ │ │ ├── time.ts │ │ │ │ │ │ ├── type.ts │ │ │ │ │ │ ├── ui8.ts │ │ │ │ │ │ ├── well-known.ts │ │ │ │ │ │ └── zod-error.ts │ │ │ │ │ ├── write-form-redirect.ts │ │ │ │ │ └── write-html.ts │ │ │ │ ├── metadata/ │ │ │ │ │ └── build-metadata.ts │ │ │ │ ├── oauth-client.ts │ │ │ │ ├── oauth-dpop.ts │ │ │ │ ├── oauth-errors.ts │ │ │ │ ├── oauth-hooks.ts │ │ │ │ ├── oauth-middleware.ts │ │ │ │ ├── oauth-provider.ts │ │ │ │ ├── oauth-store.ts │ │ │ │ ├── oauth-verifier.ts │ │ │ │ ├── oidc/ │ │ │ │ │ └── sub.ts │ │ │ │ ├── replay/ │ │ │ │ │ ├── replay-manager.ts │ │ │ │ │ ├── replay-store-memory.ts │ │ │ │ │ ├── replay-store-redis.ts │ │ │ │ │ └── replay-store.ts │ │ │ │ ├── request/ │ │ │ │ │ ├── code.ts │ │ │ │ │ ├── request-data.ts │ │ │ │ │ ├── request-id.ts │ │ │ │ │ ├── request-manager.ts │ │ │ │ │ ├── request-store.ts │ │ │ │ │ └── request-uri.ts │ │ │ │ ├── result/ │ │ │ │ │ ├── authorization-redirect-parameters.ts │ │ │ │ │ ├── authorization-result-authorize-page.ts │ │ │ │ │ └── authorization-result-redirect.ts │ │ │ │ ├── router/ │ │ │ │ │ ├── assets/ │ │ │ │ │ │ ├── assets-manifest.ts │ │ │ │ │ │ ├── assets.ts │ │ │ │ │ │ ├── csrf.ts │ │ │ │ │ │ ├── send-account-page.ts │ │ │ │ │ │ ├── send-authorization-page.ts │ │ │ │ │ │ ├── send-cookie-error-page.ts │ │ │ │ │ │ ├── send-error-page.ts │ │ │ │ │ │ └── send-redirect.ts │ │ │ │ │ ├── create-account-page-middleware.ts │ │ │ │ │ ├── create-api-middleware.ts │ │ │ │ │ ├── create-authorization-page-middleware.ts │ │ │ │ │ ├── create-oauth-middleware.ts │ │ │ │ │ ├── error-handler.ts │ │ │ │ │ └── middleware-options.ts │ │ │ │ ├── signer/ │ │ │ │ │ ├── access-token-payload.ts │ │ │ │ │ ├── api-token-payload.ts │ │ │ │ │ └── signer.ts │ │ │ │ ├── token/ │ │ │ │ │ ├── refresh-token.ts │ │ │ │ │ ├── token-claims.ts │ │ │ │ │ ├── token-data.ts │ │ │ │ │ ├── token-id.ts │ │ │ │ │ ├── token-manager.ts │ │ │ │ │ └── token-store.ts │ │ │ │ └── types/ │ │ │ │ ├── authorization-response-error.ts │ │ │ │ ├── color-hue.ts │ │ │ │ ├── email-otp.ts │ │ │ │ ├── email.ts │ │ │ │ ├── handle.ts │ │ │ │ ├── invite-code.ts │ │ │ │ ├── par-response-error.ts │ │ │ │ ├── password.ts │ │ │ │ └── rgb-color.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── oauth-provider-api/ │ │ │ ├── CHANGELOG.md │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── api-endpoints.ts │ │ │ │ ├── contants.ts │ │ │ │ ├── customization-data.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── tsconfig.build.json │ │ │ └── tsconfig.json │ │ ├── oauth-provider-frontend/ │ │ │ ├── .gitignore │ │ │ ├── .linguirc │ │ │ ├── CHANGELOG.md │ │ │ ├── account.html │ │ │ ├── hydration-data.d.ts │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── account-page.tsx │ │ │ │ ├── api/ │ │ │ │ │ ├── api.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── json-client.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── AccountSelector.tsx │ │ │ │ │ ├── Admonition.tsx │ │ │ │ │ ├── Avatar.tsx │ │ │ │ │ ├── Button.tsx │ │ │ │ │ ├── ContentCard.tsx │ │ │ │ │ ├── Dialog.tsx │ │ │ │ │ ├── Divider.tsx │ │ │ │ │ ├── ErrorScreen.tsx │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ ├── Layout.tsx │ │ │ │ │ ├── Link.tsx │ │ │ │ │ ├── Loader.tsx │ │ │ │ │ ├── LocaleSelector.tsx │ │ │ │ │ ├── Nav.tsx │ │ │ │ │ ├── Prompt.tsx │ │ │ │ │ ├── Toast.tsx │ │ │ │ │ ├── forms/ │ │ │ │ │ │ ├── Checkbox.tsx │ │ │ │ │ │ ├── Errors.tsx │ │ │ │ │ │ ├── Fieldset.tsx │ │ │ │ │ │ ├── Item.tsx │ │ │ │ │ │ ├── Label.tsx │ │ │ │ │ │ ├── Text.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ └── util/ │ │ │ │ │ └── Palette.tsx │ │ │ │ ├── data/ │ │ │ │ │ ├── useAccountSessionsQuery.ts │ │ │ │ │ ├── useClientName.ts │ │ │ │ │ ├── useCurrentSession.ts │ │ │ │ │ ├── useCustomizationData.ts │ │ │ │ │ ├── useDeviceSessionsQuery.ts │ │ │ │ │ ├── useFriendlyClientId.ts │ │ │ │ │ ├── useHasAccounts.ts │ │ │ │ │ ├── useHydrationData.ts │ │ │ │ │ ├── useOAuthSessionsQuery.ts │ │ │ │ │ ├── usePasswordConfirmMutation.ts │ │ │ │ │ ├── usePasswordResetMutation.ts │ │ │ │ │ ├── useRevokeAccountSessionMutation.ts │ │ │ │ │ ├── useRevokeOAuthSessionMutation.ts │ │ │ │ │ ├── useSignInMutation.tsx │ │ │ │ │ └── useSignOutMutation.ts │ │ │ │ ├── locales/ │ │ │ │ │ ├── activateLocale.ts │ │ │ │ │ ├── an/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ast/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ca/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── da/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── de/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── el/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── en/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── en-GB/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── es/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── eu/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── fi/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── fr/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ga/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── gl/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── hi/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── hu/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ia/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── id/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── it/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ja/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── km/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ko/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── locales.ts │ │ │ │ │ ├── ne/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── nl/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── pl/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── pt-BR/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ro/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ru/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── setup.ts │ │ │ │ │ ├── sv/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── th/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── tr/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── uk/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── vi/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── zh-CN/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── zh-HK/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ └── zh-TW/ │ │ │ │ │ └── messages.po │ │ │ │ ├── routeTree.gen.ts │ │ │ │ ├── routes/ │ │ │ │ │ ├── __root.tsx │ │ │ │ │ └── account/ │ │ │ │ │ ├── _appLayout/ │ │ │ │ │ │ └── $sub.tsx │ │ │ │ │ ├── _appLayout.tsx │ │ │ │ │ ├── _minimalLayout/ │ │ │ │ │ │ ├── branding.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── reset-password.tsx │ │ │ │ │ │ └── sign-in.tsx │ │ │ │ │ └── _minimalLayout.tsx │ │ │ │ ├── style.css │ │ │ │ ├── styles/ │ │ │ │ │ ├── radix-dialog.css │ │ │ │ │ ├── radix-popover.css │ │ │ │ │ └── radix-toast.css │ │ │ │ └── util/ │ │ │ │ ├── cookies.ts │ │ │ │ ├── format2FACode.ts │ │ │ │ ├── getAccountName.ts │ │ │ │ ├── lang-string.tsx │ │ │ │ ├── lang.ts │ │ │ │ ├── oauth-client.ts │ │ │ │ ├── passwords.ts │ │ │ │ ├── sanitizeHandle.ts │ │ │ │ ├── sleep.ts │ │ │ │ ├── upsert.ts │ │ │ │ └── wait.ts │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.src.json │ │ │ ├── tsconfig.tools.json │ │ │ └── vite.config.mts │ │ ├── oauth-provider-ui/ │ │ │ ├── .gitignore │ │ │ ├── .linguirc │ │ │ ├── CHANGELOG.md │ │ │ ├── CONTRIBUTING.md │ │ │ ├── authorization-page.html │ │ │ ├── cookie-error-page.html │ │ │ ├── error-page.html │ │ │ ├── hydration-data.d.ts │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── authorization-page.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── forms/ │ │ │ │ │ │ ├── button-toggle-visibility.tsx │ │ │ │ │ │ ├── button.tsx │ │ │ │ │ │ ├── checkbox.tsx │ │ │ │ │ │ ├── fieldset.tsx │ │ │ │ │ │ ├── form-card-async.tsx │ │ │ │ │ │ ├── form-card.tsx │ │ │ │ │ │ ├── input-checkbox.tsx │ │ │ │ │ │ ├── input-container.tsx │ │ │ │ │ │ ├── input-email-address.tsx │ │ │ │ │ │ ├── input-new-password.tsx │ │ │ │ │ │ ├── input-password.tsx │ │ │ │ │ │ ├── input-text.tsx │ │ │ │ │ │ ├── input-token.tsx │ │ │ │ │ │ └── wizard-card.tsx │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ ├── layout-title-page.tsx │ │ │ │ │ │ └── layout-welcome.tsx │ │ │ │ │ └── utils/ │ │ │ │ │ ├── account-identifier.tsx │ │ │ │ │ ├── account-image.tsx │ │ │ │ │ ├── admonition.tsx │ │ │ │ │ ├── client-image.tsx │ │ │ │ │ ├── client-name.tsx │ │ │ │ │ ├── description-card.tsx │ │ │ │ │ ├── error-card.tsx │ │ │ │ │ ├── error-message.tsx │ │ │ │ │ ├── help-card.tsx │ │ │ │ │ ├── icons.tsx │ │ │ │ │ ├── lang-string.tsx │ │ │ │ │ ├── link-anchor.tsx │ │ │ │ │ ├── link-title.tsx │ │ │ │ │ ├── page-footer.tsx │ │ │ │ │ ├── password-strength-label.tsx │ │ │ │ │ ├── password-strength-meter.tsx │ │ │ │ │ ├── scope-description.tsx │ │ │ │ │ └── url-viewer.tsx │ │ │ │ ├── cookie-error-page.tsx │ │ │ │ ├── error-page.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ ├── use-api.ts │ │ │ │ │ ├── use-async-action.ts │ │ │ │ │ ├── use-bound-dispatch.ts │ │ │ │ │ ├── use-browser-color-scheme.ts │ │ │ │ │ ├── use-click-outside.ts │ │ │ │ │ ├── use-escape-key.ts │ │ │ │ │ ├── use-random-string.ts │ │ │ │ │ └── use-stepper.ts │ │ │ │ ├── lib/ │ │ │ │ │ ├── api.ts │ │ │ │ │ ├── cookies.ts │ │ │ │ │ ├── json-client.ts │ │ │ │ │ ├── lang.ts │ │ │ │ │ ├── oauth-client.ts │ │ │ │ │ ├── password.ts │ │ │ │ │ ├── ref.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── locales/ │ │ │ │ │ ├── an/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ast/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ca/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── da/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── de/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── el/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── en/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── en-GB/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── es/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── eu/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── fi/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── fr/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ga/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── gl/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── hi/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── hu/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ia/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── id/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── it/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ja/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── km/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ko/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── load.ts │ │ │ │ │ ├── locale-provider.tsx │ │ │ │ │ ├── locale-selector.tsx │ │ │ │ │ ├── locales.ts │ │ │ │ │ ├── ne/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── nl/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── pl/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── pt-BR/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ro/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── ru/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── sv/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── th/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── tr/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── uk/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── vi/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── zh-CN/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ ├── zh-HK/ │ │ │ │ │ │ └── messages.po │ │ │ │ │ └── zh-TW/ │ │ │ │ │ └── messages.po │ │ │ │ ├── style.css │ │ │ │ └── views/ │ │ │ │ ├── authorize/ │ │ │ │ │ ├── authorize-view.tsx │ │ │ │ │ ├── consent/ │ │ │ │ │ │ ├── consent-form.tsx │ │ │ │ │ │ └── consent-view.tsx │ │ │ │ │ ├── reset-password/ │ │ │ │ │ │ ├── reset-password-confirm-form.tsx │ │ │ │ │ │ ├── reset-password-request-form.tsx │ │ │ │ │ │ └── reset-password-view.tsx │ │ │ │ │ ├── sign-in/ │ │ │ │ │ │ ├── sign-in-form.tsx │ │ │ │ │ │ ├── sign-in-picker.tsx │ │ │ │ │ │ └── sign-in-view.tsx │ │ │ │ │ ├── sign-up/ │ │ │ │ │ │ ├── sign-up-account-form.tsx │ │ │ │ │ │ ├── sign-up-disclaimer.tsx │ │ │ │ │ │ ├── sign-up-handle-form.tsx │ │ │ │ │ │ ├── sign-up-hcaptcha-form.tsx │ │ │ │ │ │ └── sign-up-view.tsx │ │ │ │ │ └── welcome/ │ │ │ │ │ └── welcome-view.tsx │ │ │ │ └── error/ │ │ │ │ ├── cookie-error-view.tsx │ │ │ │ └── error-view.tsx │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.src.json │ │ │ ├── tsconfig.tools.json │ │ │ └── vite.config.mjs │ │ ├── oauth-scopes/ │ │ │ ├── CHANGELOG.md │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── atproto-oauth-scope.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lib/ │ │ │ │ │ ├── lexicon.ts │ │ │ │ │ ├── mime.test.ts │ │ │ │ │ ├── mime.ts │ │ │ │ │ ├── nsid.ts │ │ │ │ │ ├── parser.ts │ │ │ │ │ ├── resource-permission.ts │ │ │ │ │ ├── syntax-lexicon.ts │ │ │ │ │ ├── syntax-string.test.ts │ │ │ │ │ ├── syntax-string.ts │ │ │ │ │ ├── syntax.test.ts │ │ │ │ │ ├── syntax.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── scope-missing-error.ts │ │ │ │ ├── scope-permissions-transition.test.ts │ │ │ │ ├── scope-permissions-transition.ts │ │ │ │ ├── scope-permissions.test.ts │ │ │ │ ├── scope-permissions.ts │ │ │ │ ├── scopes/ │ │ │ │ │ ├── account-permission.test.ts │ │ │ │ │ ├── account-permission.ts │ │ │ │ │ ├── blob-permission.test.ts │ │ │ │ │ ├── blob-permission.ts │ │ │ │ │ ├── identity-permission.test.ts │ │ │ │ │ ├── identity-permission.ts │ │ │ │ │ ├── include-scope.test.ts │ │ │ │ │ ├── include-scope.ts │ │ │ │ │ ├── repo-permission.test.ts │ │ │ │ │ ├── repo-permission.ts │ │ │ │ │ ├── rpc-permission.test.ts │ │ │ │ │ └── rpc-permission.ts │ │ │ │ ├── scopes-set.test.ts │ │ │ │ └── scopes-set.ts │ │ │ ├── tsconfig.build.json │ │ │ ├── tsconfig.json │ │ │ └── tsconfig.tests.json │ │ └── oauth-types/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── atproto-loopback-client-id.ts │ │ │ ├── atproto-loopback-client-metadata.ts │ │ │ ├── atproto-loopback-client-redirect-uris.ts │ │ │ ├── atproto-oauth-scope.ts │ │ │ ├── atproto-oauth-token-response.ts │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ ├── oauth-access-token.ts │ │ │ ├── oauth-authorization-code-grant-token-request.ts │ │ │ ├── oauth-authorization-details.ts │ │ │ ├── oauth-authorization-request-jar.ts │ │ │ ├── oauth-authorization-request-par.ts │ │ │ ├── oauth-authorization-request-parameters.ts │ │ │ ├── oauth-authorization-request-query.ts │ │ │ ├── oauth-authorization-request-uri.ts │ │ │ ├── oauth-authorization-response-error.ts │ │ │ ├── oauth-authorization-server-metadata.ts │ │ │ ├── oauth-client-credentials-grant-token-request.ts │ │ │ ├── oauth-client-credentials.ts │ │ │ ├── oauth-client-id-discoverable.ts │ │ │ ├── oauth-client-id-loopback.ts │ │ │ ├── oauth-client-id.ts │ │ │ ├── oauth-client-metadata.ts │ │ │ ├── oauth-code-challenge-method.ts │ │ │ ├── oauth-endpoint-auth-method.ts │ │ │ ├── oauth-endpoint-name.ts │ │ │ ├── oauth-grant-type.ts │ │ │ ├── oauth-introspection-response.ts │ │ │ ├── oauth-issuer-identifier.ts │ │ │ ├── oauth-par-response.ts │ │ │ ├── oauth-password-grant-token-request.ts │ │ │ ├── oauth-prompt-mode.ts │ │ │ ├── oauth-protected-resource-metadata.ts │ │ │ ├── oauth-redirect-uri.ts │ │ │ ├── oauth-refresh-token-grant-token-request.ts │ │ │ ├── oauth-refresh-token.ts │ │ │ ├── oauth-request-uri.ts │ │ │ ├── oauth-response-mode.ts │ │ │ ├── oauth-response-type.ts │ │ │ ├── oauth-scope.ts │ │ │ ├── oauth-token-identification.ts │ │ │ ├── oauth-token-request.ts │ │ │ ├── oauth-token-response.ts │ │ │ ├── oauth-token-type.ts │ │ │ ├── oidc-authorization-error-response.ts │ │ │ ├── oidc-claims-parameter.ts │ │ │ ├── oidc-claims-properties.ts │ │ │ ├── oidc-entity-type.ts │ │ │ ├── oidc-userinfo.ts │ │ │ ├── uri.ts │ │ │ └── util.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── ozone/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── bin/ │ │ │ └── migration-create.ts │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── api/ │ │ │ │ ├── chat/ │ │ │ │ │ ├── getActorMetadata.ts │ │ │ │ │ ├── getMessageContext.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── communication/ │ │ │ │ │ ├── createTemplate.ts │ │ │ │ │ ├── deleteTemplate.ts │ │ │ │ │ ├── listTemplates.ts │ │ │ │ │ └── updateTemplate.ts │ │ │ │ ├── health.ts │ │ │ │ ├── index.ts │ │ │ │ ├── label/ │ │ │ │ │ ├── fetchLabels.ts │ │ │ │ │ ├── queryLabels.ts │ │ │ │ │ └── subscribeLabels.ts │ │ │ │ ├── moderation/ │ │ │ │ │ ├── cancelScheduledActions.ts │ │ │ │ │ ├── emitEvent.ts │ │ │ │ │ ├── getAccountTimeline.ts │ │ │ │ │ ├── getEvent.ts │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ ├── getRecords.ts │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ ├── getReporterStats.ts │ │ │ │ │ ├── getRepos.ts │ │ │ │ │ ├── getSubjects.ts │ │ │ │ │ ├── listScheduledActions.ts │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ ├── queryStatuses.ts │ │ │ │ │ ├── scheduleAction.ts │ │ │ │ │ ├── searchRepos.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── proxied.ts │ │ │ │ ├── report/ │ │ │ │ │ └── createReport.ts │ │ │ │ ├── safelink/ │ │ │ │ │ ├── addRule.ts │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ ├── queryRules.ts │ │ │ │ │ ├── removeRule.ts │ │ │ │ │ └── updateRule.ts │ │ │ │ ├── server/ │ │ │ │ │ └── getConfig.ts │ │ │ │ ├── set/ │ │ │ │ │ ├── addValues.ts │ │ │ │ │ ├── deleteSet.ts │ │ │ │ │ ├── deleteValues.ts │ │ │ │ │ ├── getValues.ts │ │ │ │ │ ├── querySets.ts │ │ │ │ │ └── upsertSet.ts │ │ │ │ ├── setting/ │ │ │ │ │ ├── listOptions.ts │ │ │ │ │ ├── removeOptions.ts │ │ │ │ │ └── upsertOption.ts │ │ │ │ ├── team/ │ │ │ │ │ ├── addMember.ts │ │ │ │ │ ├── deleteMember.ts │ │ │ │ │ ├── listMembers.ts │ │ │ │ │ └── updateMember.ts │ │ │ │ ├── util.ts │ │ │ │ ├── verification/ │ │ │ │ │ ├── grantVerifications.ts │ │ │ │ │ ├── listVerifications.ts │ │ │ │ │ └── revokeVerifications.ts │ │ │ │ └── well-known.ts │ │ │ ├── auth-verifier.ts │ │ │ ├── background.ts │ │ │ ├── communication-service/ │ │ │ │ ├── template.ts │ │ │ │ └── util.ts │ │ │ ├── config/ │ │ │ │ ├── config.ts │ │ │ │ ├── env.ts │ │ │ │ ├── index.ts │ │ │ │ └── secrets.ts │ │ │ ├── context.ts │ │ │ ├── daemon/ │ │ │ │ ├── blob-diverter.ts │ │ │ │ ├── context.ts │ │ │ │ ├── event-pusher.ts │ │ │ │ ├── event-reverser.ts │ │ │ │ ├── index.ts │ │ │ │ ├── materialized-view-refresher.ts │ │ │ │ ├── scheduled-action-processor.ts │ │ │ │ ├── strike-expiry-processor.ts │ │ │ │ ├── team-profile-synchronizer.ts │ │ │ │ └── verification-listener.ts │ │ │ ├── db/ │ │ │ │ ├── index.ts │ │ │ │ ├── migrations/ │ │ │ │ │ ├── 20231219T205730722Z-init.ts │ │ │ │ │ ├── 20240116T085607200Z-communication-template.ts │ │ │ │ │ ├── 20240201T051104136Z-mod-event-blobs.ts │ │ │ │ │ ├── 20240208T213404429Z-add-tags-column-to-moderation-subject.ts │ │ │ │ │ ├── 20240228T003647759Z-add-label-sigs.ts │ │ │ │ │ ├── 20240408T192432676Z-mute-reporting.ts │ │ │ │ │ ├── 20240506T225055595Z-message-subject.ts │ │ │ │ │ ├── 20240521T211332580Z-member.ts │ │ │ │ │ ├── 20240814T003647759Z-event-created-at-index.ts │ │ │ │ │ ├── 20240903T205730722Z-add-template-lang.ts │ │ │ │ │ ├── 20240904T205730722Z-add-subject-did-index.ts │ │ │ │ │ ├── 20241001T205730722Z-subject-status-review-state-index.ts │ │ │ │ │ ├── 20241008T205730722Z-sets.ts │ │ │ │ │ ├── 20241018T205730722Z-setting.ts │ │ │ │ │ ├── 20241026T205730722Z-add-hosting-status-to-subject-status.ts │ │ │ │ │ ├── 20241220T144630860Z-stats-materialized-views.ts │ │ │ │ │ ├── 20250204T003647759Z-add-subject-priority-score.ts │ │ │ │ │ ├── 20250211T003647759Z-add-reporter-stats-index.ts │ │ │ │ │ ├── 20250211T132135150Z-moderation-event-message-partial-idx.ts │ │ │ │ │ ├── 20250221T132135150Z-member-details.ts │ │ │ │ │ ├── 20250404T201720309Z-subject-status-sort-idxs.ts │ │ │ │ │ ├── 20250415T201720309Z-verification.ts │ │ │ │ │ ├── 20250417T201720309Z-firehose-cursor.ts │ │ │ │ │ ├── 20250609T110704000Z-safelink.ts │ │ │ │ │ ├── 20250618T180246000Z-add-mod-tool-to-moderation-event.ts │ │ │ │ │ ├── 20250701T000000000Z-add-age-assurance-state.ts │ │ │ │ │ ├── 20250715T000000000Z-add-mod-event-external-id.ts │ │ │ │ │ ├── 20250718T150931000Z-update-appeal-reason-stats.ts │ │ │ │ │ ├── 20250813T000000000Z-mod-tool-batch-id-index.ts │ │ │ │ │ ├── 20250923T000000000Z-scheduled-actions.ts │ │ │ │ │ ├── 20251008T120000000Z-add-strike-system.ts │ │ │ │ │ ├── 20260210T154806448Z-mod-event-created-by-indexes.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── provider.ts │ │ │ │ ├── pagination.ts │ │ │ │ ├── schema/ │ │ │ │ │ ├── account_events_stats.ts │ │ │ │ │ ├── account_record_events_stats.ts │ │ │ │ │ ├── account_record_status_stats.ts │ │ │ │ │ ├── account_strike.ts │ │ │ │ │ ├── blob_push_event.ts │ │ │ │ │ ├── communication_template.ts │ │ │ │ │ ├── firehose_cursor.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── job_cursor.ts │ │ │ │ │ ├── label.ts │ │ │ │ │ ├── member.ts │ │ │ │ │ ├── moderation_event.ts │ │ │ │ │ ├── moderation_subject_status.ts │ │ │ │ │ ├── ozone_set.ts │ │ │ │ │ ├── record_events_stats.ts │ │ │ │ │ ├── record_push_event.ts │ │ │ │ │ ├── repo_push_event.ts │ │ │ │ │ ├── safelink.ts │ │ │ │ │ ├── scheduled-action.ts │ │ │ │ │ ├── setting.ts │ │ │ │ │ ├── signing_key.ts │ │ │ │ │ └── verification.ts │ │ │ │ └── types.ts │ │ │ ├── error.ts │ │ │ ├── image-invalidator.ts │ │ │ ├── index.ts │ │ │ ├── jetstream/ │ │ │ │ └── service.ts │ │ │ ├── lexicon/ │ │ │ │ ├── index.ts │ │ │ │ ├── lexicons.ts │ │ │ │ ├── types/ │ │ │ │ │ ├── app/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getProfile.ts │ │ │ │ │ │ │ ├── getProfiles.ts │ │ │ │ │ │ │ ├── getSuggestions.ts │ │ │ │ │ │ │ ├── profile.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── searchActors.ts │ │ │ │ │ │ │ ├── searchActorsTypeahead.ts │ │ │ │ │ │ │ └── status.ts │ │ │ │ │ │ ├── ageassurance/ │ │ │ │ │ │ │ ├── begin.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ └── getState.ts │ │ │ │ │ │ ├── bookmark/ │ │ │ │ │ │ │ ├── createBookmark.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteBookmark.ts │ │ │ │ │ │ │ └── getBookmarks.ts │ │ │ │ │ │ ├── contact/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── dismissMatch.ts │ │ │ │ │ │ │ ├── getMatches.ts │ │ │ │ │ │ │ ├── getSyncStatus.ts │ │ │ │ │ │ │ ├── importContacts.ts │ │ │ │ │ │ │ ├── removeData.ts │ │ │ │ │ │ │ ├── sendNotification.ts │ │ │ │ │ │ │ ├── startPhoneVerification.ts │ │ │ │ │ │ │ └── verifyPhone.ts │ │ │ │ │ │ ├── draft/ │ │ │ │ │ │ │ ├── createDraft.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteDraft.ts │ │ │ │ │ │ │ ├── getDrafts.ts │ │ │ │ │ │ │ └── updateDraft.ts │ │ │ │ │ │ ├── embed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── external.ts │ │ │ │ │ │ │ ├── images.ts │ │ │ │ │ │ │ ├── record.ts │ │ │ │ │ │ │ ├── recordWithMedia.ts │ │ │ │ │ │ │ └── video.ts │ │ │ │ │ │ ├── feed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── describeFeedGenerator.ts │ │ │ │ │ │ │ ├── generator.ts │ │ │ │ │ │ │ ├── getActorFeeds.ts │ │ │ │ │ │ │ ├── getActorLikes.ts │ │ │ │ │ │ │ ├── getAuthorFeed.ts │ │ │ │ │ │ │ ├── getFeed.ts │ │ │ │ │ │ │ ├── getFeedGenerator.ts │ │ │ │ │ │ │ ├── getFeedGenerators.ts │ │ │ │ │ │ │ ├── getFeedSkeleton.ts │ │ │ │ │ │ │ ├── getLikes.ts │ │ │ │ │ │ │ ├── getListFeed.ts │ │ │ │ │ │ │ ├── getPostThread.ts │ │ │ │ │ │ │ ├── getPosts.ts │ │ │ │ │ │ │ ├── getQuotes.ts │ │ │ │ │ │ │ ├── getRepostedBy.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getTimeline.ts │ │ │ │ │ │ │ ├── like.ts │ │ │ │ │ │ │ ├── post.ts │ │ │ │ │ │ │ ├── postgate.ts │ │ │ │ │ │ │ ├── repost.ts │ │ │ │ │ │ │ ├── searchPosts.ts │ │ │ │ │ │ │ ├── sendInteractions.ts │ │ │ │ │ │ │ └── threadgate.ts │ │ │ │ │ │ ├── graph/ │ │ │ │ │ │ │ ├── block.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── follow.ts │ │ │ │ │ │ │ ├── getActorStarterPacks.ts │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ ├── getFollowers.ts │ │ │ │ │ │ │ ├── getFollows.ts │ │ │ │ │ │ │ ├── getKnownFollowers.ts │ │ │ │ │ │ │ ├── getList.ts │ │ │ │ │ │ │ ├── getListBlocks.ts │ │ │ │ │ │ │ ├── getListMutes.ts │ │ │ │ │ │ │ ├── getLists.ts │ │ │ │ │ │ │ ├── getListsWithMembership.ts │ │ │ │ │ │ │ ├── getMutes.ts │ │ │ │ │ │ │ ├── getRelationships.ts │ │ │ │ │ │ │ ├── getStarterPack.ts │ │ │ │ │ │ │ ├── getStarterPacks.ts │ │ │ │ │ │ │ ├── getStarterPacksWithMembership.ts │ │ │ │ │ │ │ ├── getSuggestedFollowsByActor.ts │ │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ │ ├── listblock.ts │ │ │ │ │ │ │ ├── listitem.ts │ │ │ │ │ │ │ ├── muteActor.ts │ │ │ │ │ │ │ ├── muteActorList.ts │ │ │ │ │ │ │ ├── muteThread.ts │ │ │ │ │ │ │ ├── searchStarterPacks.ts │ │ │ │ │ │ │ ├── starterpack.ts │ │ │ │ │ │ │ ├── unmuteActor.ts │ │ │ │ │ │ │ ├── unmuteActorList.ts │ │ │ │ │ │ │ ├── unmuteThread.ts │ │ │ │ │ │ │ └── verification.ts │ │ │ │ │ │ ├── labeler/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getServices.ts │ │ │ │ │ │ │ └── service.ts │ │ │ │ │ │ ├── notification/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getUnreadCount.ts │ │ │ │ │ │ │ ├── listActivitySubscriptions.ts │ │ │ │ │ │ │ ├── listNotifications.ts │ │ │ │ │ │ │ ├── putActivitySubscription.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── putPreferencesV2.ts │ │ │ │ │ │ │ ├── registerPush.ts │ │ │ │ │ │ │ ├── unregisterPush.ts │ │ │ │ │ │ │ └── updateSeen.ts │ │ │ │ │ │ ├── richtext/ │ │ │ │ │ │ │ └── facet.ts │ │ │ │ │ │ ├── unspecced/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getAgeAssuranceState.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getPopularFeedGenerators.ts │ │ │ │ │ │ │ ├── getPostThreadOtherV2.ts │ │ │ │ │ │ │ ├── getPostThreadV2.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getSuggestedFeedsSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedOnboardingUsers.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedUsers.ts │ │ │ │ │ │ │ ├── getSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestionsSkeleton.ts │ │ │ │ │ │ │ ├── getTaggedSuggestions.ts │ │ │ │ │ │ │ ├── getTrendingTopics.ts │ │ │ │ │ │ │ ├── getTrends.ts │ │ │ │ │ │ │ ├── getTrendsSkeleton.ts │ │ │ │ │ │ │ ├── initAgeAssurance.ts │ │ │ │ │ │ │ ├── searchActorsSkeleton.ts │ │ │ │ │ │ │ ├── searchPostsSkeleton.ts │ │ │ │ │ │ │ └── searchStarterPacksSkeleton.ts │ │ │ │ │ │ └── video/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── getJobStatus.ts │ │ │ │ │ │ ├── getUploadLimits.ts │ │ │ │ │ │ └── uploadVideo.ts │ │ │ │ │ ├── chat/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ └── exportAccountData.ts │ │ │ │ │ │ ├── convo/ │ │ │ │ │ │ │ ├── acceptConvo.ts │ │ │ │ │ │ │ ├── addReaction.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteMessageForSelf.ts │ │ │ │ │ │ │ ├── getConvo.ts │ │ │ │ │ │ │ ├── getConvoAvailability.ts │ │ │ │ │ │ │ ├── getConvoForMembers.ts │ │ │ │ │ │ │ ├── getLog.ts │ │ │ │ │ │ │ ├── getMessages.ts │ │ │ │ │ │ │ ├── leaveConvo.ts │ │ │ │ │ │ │ ├── listConvos.ts │ │ │ │ │ │ │ ├── muteConvo.ts │ │ │ │ │ │ │ ├── removeReaction.ts │ │ │ │ │ │ │ ├── sendMessage.ts │ │ │ │ │ │ │ ├── sendMessageBatch.ts │ │ │ │ │ │ │ ├── unmuteConvo.ts │ │ │ │ │ │ │ ├── updateAllRead.ts │ │ │ │ │ │ │ └── updateRead.ts │ │ │ │ │ │ └── moderation/ │ │ │ │ │ │ ├── getActorMetadata.ts │ │ │ │ │ │ ├── getMessageContext.ts │ │ │ │ │ │ └── updateActorAccess.ts │ │ │ │ │ ├── com/ │ │ │ │ │ │ └── atproto/ │ │ │ │ │ │ ├── admin/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ ├── disableAccountInvites.ts │ │ │ │ │ │ │ ├── disableInviteCodes.ts │ │ │ │ │ │ │ ├── enableAccountInvites.ts │ │ │ │ │ │ │ ├── getAccountInfo.ts │ │ │ │ │ │ │ ├── getAccountInfos.ts │ │ │ │ │ │ │ ├── getInviteCodes.ts │ │ │ │ │ │ │ ├── getSubjectStatus.ts │ │ │ │ │ │ │ ├── searchAccounts.ts │ │ │ │ │ │ │ ├── sendEmail.ts │ │ │ │ │ │ │ ├── updateAccountEmail.ts │ │ │ │ │ │ │ ├── updateAccountHandle.ts │ │ │ │ │ │ │ ├── updateAccountPassword.ts │ │ │ │ │ │ │ ├── updateAccountSigningKey.ts │ │ │ │ │ │ │ └── updateSubjectStatus.ts │ │ │ │ │ │ ├── identity/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getRecommendedDidCredentials.ts │ │ │ │ │ │ │ ├── refreshIdentity.ts │ │ │ │ │ │ │ ├── requestPlcOperationSignature.ts │ │ │ │ │ │ │ ├── resolveDid.ts │ │ │ │ │ │ │ ├── resolveHandle.ts │ │ │ │ │ │ │ ├── resolveIdentity.ts │ │ │ │ │ │ │ ├── signPlcOperation.ts │ │ │ │ │ │ │ ├── submitPlcOperation.ts │ │ │ │ │ │ │ └── updateHandle.ts │ │ │ │ │ │ ├── label/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── queryLabels.ts │ │ │ │ │ │ │ └── subscribeLabels.ts │ │ │ │ │ │ ├── lexicon/ │ │ │ │ │ │ │ ├── resolveLexicon.ts │ │ │ │ │ │ │ └── schema.ts │ │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ │ ├── createReport.ts │ │ │ │ │ │ │ └── defs.ts │ │ │ │ │ │ ├── repo/ │ │ │ │ │ │ │ ├── applyWrites.ts │ │ │ │ │ │ │ ├── createRecord.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteRecord.ts │ │ │ │ │ │ │ ├── describeRepo.ts │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ ├── importRepo.ts │ │ │ │ │ │ │ ├── listMissingBlobs.ts │ │ │ │ │ │ │ ├── listRecords.ts │ │ │ │ │ │ │ ├── putRecord.ts │ │ │ │ │ │ │ ├── strongRef.ts │ │ │ │ │ │ │ └── uploadBlob.ts │ │ │ │ │ │ ├── server/ │ │ │ │ │ │ │ ├── activateAccount.ts │ │ │ │ │ │ │ ├── checkAccountStatus.ts │ │ │ │ │ │ │ ├── confirmEmail.ts │ │ │ │ │ │ │ ├── createAccount.ts │ │ │ │ │ │ │ ├── createAppPassword.ts │ │ │ │ │ │ │ ├── createInviteCode.ts │ │ │ │ │ │ │ ├── createInviteCodes.ts │ │ │ │ │ │ │ ├── createSession.ts │ │ │ │ │ │ │ ├── deactivateAccount.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ ├── deleteSession.ts │ │ │ │ │ │ │ ├── describeServer.ts │ │ │ │ │ │ │ ├── getAccountInviteCodes.ts │ │ │ │ │ │ │ ├── getServiceAuth.ts │ │ │ │ │ │ │ ├── getSession.ts │ │ │ │ │ │ │ ├── listAppPasswords.ts │ │ │ │ │ │ │ ├── refreshSession.ts │ │ │ │ │ │ │ ├── requestAccountDelete.ts │ │ │ │ │ │ │ ├── requestEmailConfirmation.ts │ │ │ │ │ │ │ ├── requestEmailUpdate.ts │ │ │ │ │ │ │ ├── requestPasswordReset.ts │ │ │ │ │ │ │ ├── reserveSigningKey.ts │ │ │ │ │ │ │ ├── resetPassword.ts │ │ │ │ │ │ │ ├── revokeAppPassword.ts │ │ │ │ │ │ │ └── updateEmail.ts │ │ │ │ │ │ ├── sync/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getBlob.ts │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ ├── getCheckout.ts │ │ │ │ │ │ │ ├── getHead.ts │ │ │ │ │ │ │ ├── getHostStatus.ts │ │ │ │ │ │ │ ├── getLatestCommit.ts │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ │ ├── getRepoStatus.ts │ │ │ │ │ │ │ ├── listBlobs.ts │ │ │ │ │ │ │ ├── listHosts.ts │ │ │ │ │ │ │ ├── listRepos.ts │ │ │ │ │ │ │ ├── listReposByCollection.ts │ │ │ │ │ │ │ ├── notifyOfUpdate.ts │ │ │ │ │ │ │ ├── requestCrawl.ts │ │ │ │ │ │ │ └── subscribeRepos.ts │ │ │ │ │ │ └── temp/ │ │ │ │ │ │ ├── addReservedHandle.ts │ │ │ │ │ │ ├── checkHandleAvailability.ts │ │ │ │ │ │ ├── checkSignupQueue.ts │ │ │ │ │ │ ├── dereferenceScope.ts │ │ │ │ │ │ ├── fetchLabels.ts │ │ │ │ │ │ ├── requestPhoneVerification.ts │ │ │ │ │ │ └── revokeAccountCredentials.ts │ │ │ │ │ └── tools/ │ │ │ │ │ └── ozone/ │ │ │ │ │ ├── communication/ │ │ │ │ │ │ ├── createTemplate.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteTemplate.ts │ │ │ │ │ │ ├── listTemplates.ts │ │ │ │ │ │ └── updateTemplate.ts │ │ │ │ │ ├── hosting/ │ │ │ │ │ │ └── getAccountHistory.ts │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ ├── cancelScheduledActions.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── emitEvent.ts │ │ │ │ │ │ ├── getAccountTimeline.ts │ │ │ │ │ │ ├── getEvent.ts │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ ├── getRecords.ts │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ ├── getReporterStats.ts │ │ │ │ │ │ ├── getRepos.ts │ │ │ │ │ │ ├── getSubjects.ts │ │ │ │ │ │ ├── listScheduledActions.ts │ │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ │ ├── queryStatuses.ts │ │ │ │ │ │ ├── scheduleAction.ts │ │ │ │ │ │ └── searchRepos.ts │ │ │ │ │ ├── report/ │ │ │ │ │ │ └── defs.ts │ │ │ │ │ ├── safelink/ │ │ │ │ │ │ ├── addRule.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ │ ├── queryRules.ts │ │ │ │ │ │ ├── removeRule.ts │ │ │ │ │ │ └── updateRule.ts │ │ │ │ │ ├── server/ │ │ │ │ │ │ └── getConfig.ts │ │ │ │ │ ├── set/ │ │ │ │ │ │ ├── addValues.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteSet.ts │ │ │ │ │ │ ├── deleteValues.ts │ │ │ │ │ │ ├── getValues.ts │ │ │ │ │ │ ├── querySets.ts │ │ │ │ │ │ └── upsertSet.ts │ │ │ │ │ ├── setting/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── listOptions.ts │ │ │ │ │ │ ├── removeOptions.ts │ │ │ │ │ │ └── upsertOption.ts │ │ │ │ │ ├── signature/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── findCorrelation.ts │ │ │ │ │ │ ├── findRelatedAccounts.ts │ │ │ │ │ │ └── searchAccounts.ts │ │ │ │ │ ├── team/ │ │ │ │ │ │ ├── addMember.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteMember.ts │ │ │ │ │ │ ├── listMembers.ts │ │ │ │ │ │ └── updateMember.ts │ │ │ │ │ └── verification/ │ │ │ │ │ ├── defs.ts │ │ │ │ │ ├── grantVerifications.ts │ │ │ │ │ ├── listVerifications.ts │ │ │ │ │ └── revokeVerifications.ts │ │ │ │ └── util.ts │ │ │ ├── logger.ts │ │ │ ├── mod-service/ │ │ │ │ ├── index.ts │ │ │ │ ├── profile.ts │ │ │ │ ├── status.ts │ │ │ │ ├── strike.ts │ │ │ │ ├── subject.ts │ │ │ │ ├── types.ts │ │ │ │ ├── util.ts │ │ │ │ └── views.ts │ │ │ ├── safelink/ │ │ │ │ └── service.ts │ │ │ ├── scheduled-action/ │ │ │ │ ├── service.ts │ │ │ │ └── types.ts │ │ │ ├── sequencer/ │ │ │ │ ├── index.ts │ │ │ │ ├── outbox.ts │ │ │ │ └── sequencer.ts │ │ │ ├── set/ │ │ │ │ └── service.ts │ │ │ ├── setting/ │ │ │ │ ├── constants.ts │ │ │ │ ├── service.ts │ │ │ │ ├── types.ts │ │ │ │ └── validators.ts │ │ │ ├── tag-service/ │ │ │ │ ├── content-tagger.ts │ │ │ │ ├── embed-tagger.ts │ │ │ │ ├── index.ts │ │ │ │ ├── language-data.ts │ │ │ │ ├── language-tagger.ts │ │ │ │ └── util.ts │ │ │ ├── team/ │ │ │ │ └── index.ts │ │ │ ├── util.ts │ │ │ └── verification/ │ │ │ ├── issuer.ts │ │ │ ├── service.ts │ │ │ └── util.ts │ │ ├── test.env │ │ ├── tests/ │ │ │ ├── 3p-labeler.test.ts │ │ │ ├── __snapshots__/ │ │ │ │ ├── account-strikes.test.ts.snap │ │ │ │ ├── age-assurance.test.ts.snap │ │ │ │ ├── blob-divert.test.ts.snap │ │ │ │ ├── get-account-timeline.test.ts.snap │ │ │ │ ├── get-record.test.ts.snap │ │ │ │ ├── get-records.test.ts.snap │ │ │ │ ├── get-repo.test.ts.snap │ │ │ │ ├── get-repos.test.ts.snap │ │ │ │ ├── get-starter-pack.test.ts.snap │ │ │ │ ├── get-subjects.test.ts.snap │ │ │ │ ├── moderation-events.test.ts.snap │ │ │ │ ├── moderation-statuses.test.ts.snap │ │ │ │ ├── moderation.test.ts.snap │ │ │ │ ├── report-reason.test.ts.snap │ │ │ │ ├── safelink.test.ts.snap │ │ │ │ ├── scheduled-action.test.ts.snap │ │ │ │ ├── sets.test.ts.snap │ │ │ │ ├── settings.test.ts.snap │ │ │ │ ├── team.test.ts.snap │ │ │ │ ├── verification-listener.test.ts.snap │ │ │ │ └── verification.test.ts.snap │ │ │ ├── _util.ts │ │ │ ├── account-strikes.test.ts │ │ │ ├── ack-all-subjects-of-account.test.ts │ │ │ ├── age-assurance.test.ts │ │ │ ├── blob-divert.test.ts │ │ │ ├── communication-templates.test.ts │ │ │ ├── content-tagger.test.ts │ │ │ ├── db.test.ts │ │ │ ├── expiring-label.test.ts │ │ │ ├── get-account-timeline.test.ts │ │ │ ├── get-config.test.ts │ │ │ ├── get-lists.test.ts │ │ │ ├── get-profiles.test.ts │ │ │ ├── get-record.test.ts │ │ │ ├── get-records.test.ts │ │ │ ├── get-repo.test.ts │ │ │ ├── get-reporter-stats.test.ts │ │ │ ├── get-repos.test.ts │ │ │ ├── get-starter-pack.test.ts │ │ │ ├── get-subjects.test.ts │ │ │ ├── mod-tool.test.ts │ │ │ ├── moderation-appeals.test.ts │ │ │ ├── moderation-events.test.ts │ │ │ ├── moderation-status-tags.test.ts │ │ │ ├── moderation-statuses.test.ts │ │ │ ├── moderation.test.ts │ │ │ ├── protected-tags.test.ts │ │ │ ├── query-labels.test.ts │ │ │ ├── record-and-account-events.test.ts │ │ │ ├── repo-search.test.ts │ │ │ ├── report-muting.test.ts │ │ │ ├── report-reason.test.ts │ │ │ ├── revoke-account-credentials.test.ts │ │ │ ├── safelink.test.ts │ │ │ ├── scheduled-action-processor.test.ts │ │ │ ├── scheduled-action.test.ts │ │ │ ├── sequencer.test.ts │ │ │ ├── server.test.ts │ │ │ ├── sets.test.ts │ │ │ ├── settings.test.ts │ │ │ ├── strike-expiry-processor.test.ts │ │ │ ├── subject-priority-score.test.ts │ │ │ ├── takedown.test.ts │ │ │ ├── team.test.ts │ │ │ ├── verification-listener.test.ts │ │ │ └── verification.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── pds/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── build.templates.js │ │ ├── example.env │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── account-manager/ │ │ │ │ ├── account-manager.ts │ │ │ │ ├── db/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── migrations/ │ │ │ │ │ │ ├── 001-init.ts │ │ │ │ │ │ ├── 002-account-deactivation.ts │ │ │ │ │ │ ├── 003-privileged-app-passwords.ts │ │ │ │ │ │ ├── 004-oauth.ts │ │ │ │ │ │ ├── 005-oauth-account-management.ts │ │ │ │ │ │ ├── 006-oauth-permission-sets.ts │ │ │ │ │ │ ├── 007-lexicon-failures-index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── schema/ │ │ │ │ │ ├── account-device.ts │ │ │ │ │ ├── account.ts │ │ │ │ │ ├── actor.ts │ │ │ │ │ ├── app-password.ts │ │ │ │ │ ├── authorization-request.ts │ │ │ │ │ ├── authorized-client.ts │ │ │ │ │ ├── device.ts │ │ │ │ │ ├── email-token.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── invite-code.ts │ │ │ │ │ ├── lexicon.ts │ │ │ │ │ ├── refresh-token.ts │ │ │ │ │ ├── repo-root.ts │ │ │ │ │ ├── token.ts │ │ │ │ │ └── used-refresh-token.ts │ │ │ │ ├── helpers/ │ │ │ │ │ ├── account-device.ts │ │ │ │ │ ├── account.ts │ │ │ │ │ ├── auth.ts │ │ │ │ │ ├── authorization-request.ts │ │ │ │ │ ├── authorized-client.ts │ │ │ │ │ ├── device.ts │ │ │ │ │ ├── email-token.ts │ │ │ │ │ ├── invite.ts │ │ │ │ │ ├── lexicon.ts │ │ │ │ │ ├── password.ts │ │ │ │ │ ├── repo.ts │ │ │ │ │ ├── scrypt.ts │ │ │ │ │ ├── token.ts │ │ │ │ │ └── used-refresh-token.ts │ │ │ │ ├── oauth-store.ts │ │ │ │ └── scope-reference-getter.ts │ │ │ ├── actor-store/ │ │ │ │ ├── actor-store-reader.ts │ │ │ │ ├── actor-store-resources.ts │ │ │ │ ├── actor-store-transactor.ts │ │ │ │ ├── actor-store-writer.ts │ │ │ │ ├── actor-store.ts │ │ │ │ ├── blob/ │ │ │ │ │ ├── reader.ts │ │ │ │ │ └── transactor.ts │ │ │ │ ├── db/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── migrations/ │ │ │ │ │ │ ├── 001-init.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── schema/ │ │ │ │ │ ├── account-pref.ts │ │ │ │ │ ├── backlink.ts │ │ │ │ │ ├── blob.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── record-blob.ts │ │ │ │ │ ├── record.ts │ │ │ │ │ ├── repo-block.ts │ │ │ │ │ └── repo-root.ts │ │ │ │ ├── migrate.ts │ │ │ │ ├── preference/ │ │ │ │ │ ├── reader.ts │ │ │ │ │ ├── transactor.ts │ │ │ │ │ └── util.ts │ │ │ │ ├── record/ │ │ │ │ │ ├── reader.ts │ │ │ │ │ └── transactor.ts │ │ │ │ └── repo/ │ │ │ │ ├── reader.ts │ │ │ │ ├── sql-repo-reader.ts │ │ │ │ ├── sql-repo-transactor.ts │ │ │ │ └── transactor.ts │ │ │ ├── api/ │ │ │ │ ├── app/ │ │ │ │ │ └── bsky/ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ ├── getProfile.ts │ │ │ │ │ │ ├── getProfiles.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── putPreferences.ts │ │ │ │ │ ├── feed/ │ │ │ │ │ │ ├── getActorLikes.ts │ │ │ │ │ │ ├── getAuthorFeed.ts │ │ │ │ │ │ ├── getFeed.ts │ │ │ │ │ │ ├── getPostThread.ts │ │ │ │ │ │ ├── getTimeline.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── notification/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── registerPush.ts │ │ │ │ │ └── util/ │ │ │ │ │ └── resolver.ts │ │ │ │ ├── com/ │ │ │ │ │ └── atproto/ │ │ │ │ │ ├── admin/ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ ├── disableAccountInvites.ts │ │ │ │ │ │ ├── disableInviteCodes.ts │ │ │ │ │ │ ├── enableAccountInvites.ts │ │ │ │ │ │ ├── getAccountInfo.ts │ │ │ │ │ │ ├── getAccountInfos.ts │ │ │ │ │ │ ├── getInviteCodes.ts │ │ │ │ │ │ ├── getSubjectStatus.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── sendEmail.ts │ │ │ │ │ │ ├── updateAccountEmail.ts │ │ │ │ │ │ ├── updateAccountHandle.ts │ │ │ │ │ │ ├── updateAccountPassword.ts │ │ │ │ │ │ ├── updateSubjectStatus.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ ├── identity/ │ │ │ │ │ │ ├── getRecommendedDidCredentials.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── requestPlcOperationSignature.ts │ │ │ │ │ │ ├── resolveHandle.ts │ │ │ │ │ │ ├── signPlcOperation.ts │ │ │ │ │ │ ├── submitPlcOperation.ts │ │ │ │ │ │ └── updateHandle.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ ├── createReport.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── repo/ │ │ │ │ │ │ ├── applyWrites.ts │ │ │ │ │ │ ├── createRecord.ts │ │ │ │ │ │ ├── deleteRecord.ts │ │ │ │ │ │ ├── describeRepo.ts │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ ├── importRepo.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── listMissingBlobs.ts │ │ │ │ │ │ ├── listRecords.ts │ │ │ │ │ │ ├── putRecord.ts │ │ │ │ │ │ └── uploadBlob.ts │ │ │ │ │ ├── server/ │ │ │ │ │ │ ├── activateAccount.ts │ │ │ │ │ │ ├── checkAccountStatus.ts │ │ │ │ │ │ ├── confirmEmail.ts │ │ │ │ │ │ ├── createAccount.ts │ │ │ │ │ │ ├── createAppPassword.ts │ │ │ │ │ │ ├── createInviteCode.ts │ │ │ │ │ │ ├── createInviteCodes.ts │ │ │ │ │ │ ├── createSession.ts │ │ │ │ │ │ ├── deactivateAccount.ts │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ ├── deleteSession.ts │ │ │ │ │ │ ├── describeServer.ts │ │ │ │ │ │ ├── getAccountInviteCodes.ts │ │ │ │ │ │ ├── getServiceAuth.ts │ │ │ │ │ │ ├── getSession.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── listAppPasswords.ts │ │ │ │ │ │ ├── refreshSession.ts │ │ │ │ │ │ ├── requestAccountDelete.ts │ │ │ │ │ │ ├── requestEmailConfirmation.ts │ │ │ │ │ │ ├── requestEmailUpdate.ts │ │ │ │ │ │ ├── requestPasswordReset.ts │ │ │ │ │ │ ├── reserveSigningKey.ts │ │ │ │ │ │ ├── resetPassword.ts │ │ │ │ │ │ ├── revokeAppPassword.ts │ │ │ │ │ │ ├── updateEmail.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ ├── sync/ │ │ │ │ │ │ ├── deprecated/ │ │ │ │ │ │ │ ├── getCheckout.ts │ │ │ │ │ │ │ └── getHead.ts │ │ │ │ │ │ ├── getBlob.ts │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ ├── getLatestCommit.ts │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ ├── getRepoStatus.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── listBlobs.ts │ │ │ │ │ │ ├── listRepos.ts │ │ │ │ │ │ ├── subscribeRepos.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ └── temp/ │ │ │ │ │ ├── checkSignupQueue.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── proxy.ts │ │ │ ├── app-view.ts │ │ │ ├── auth-output.ts │ │ │ ├── auth-routes.ts │ │ │ ├── auth-scope.ts │ │ │ ├── auth-verifier.ts │ │ │ ├── background.ts │ │ │ ├── basic-routes.ts │ │ │ ├── bsky-app-view.ts │ │ │ ├── config/ │ │ │ │ ├── config.ts │ │ │ │ ├── env.ts │ │ │ │ ├── index.ts │ │ │ │ └── secrets.ts │ │ │ ├── context.ts │ │ │ ├── crawlers.ts │ │ │ ├── db/ │ │ │ │ ├── cast.ts │ │ │ │ ├── db.ts │ │ │ │ ├── index.ts │ │ │ │ ├── migrator.ts │ │ │ │ ├── pagination.ts │ │ │ │ ├── tables/ │ │ │ │ │ └── moderation.ts │ │ │ │ └── util.ts │ │ │ ├── did-cache/ │ │ │ │ ├── db/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── migrations.ts │ │ │ │ │ └── schema.ts │ │ │ │ └── index.ts │ │ │ ├── disk-blobstore.ts │ │ │ ├── error.ts │ │ │ ├── handle/ │ │ │ │ ├── explicit-slurs.ts │ │ │ │ ├── index.ts │ │ │ │ └── reserved.ts │ │ │ ├── image/ │ │ │ │ └── image-url-builder.ts │ │ │ ├── index.ts │ │ │ ├── lexicon/ │ │ │ │ ├── index.ts │ │ │ │ ├── lexicons.ts │ │ │ │ ├── types/ │ │ │ │ │ ├── app/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getProfile.ts │ │ │ │ │ │ │ ├── getProfiles.ts │ │ │ │ │ │ │ ├── getSuggestions.ts │ │ │ │ │ │ │ ├── profile.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── searchActors.ts │ │ │ │ │ │ │ ├── searchActorsTypeahead.ts │ │ │ │ │ │ │ └── status.ts │ │ │ │ │ │ ├── ageassurance/ │ │ │ │ │ │ │ ├── begin.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ └── getState.ts │ │ │ │ │ │ ├── bookmark/ │ │ │ │ │ │ │ ├── createBookmark.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteBookmark.ts │ │ │ │ │ │ │ └── getBookmarks.ts │ │ │ │ │ │ ├── contact/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── dismissMatch.ts │ │ │ │ │ │ │ ├── getMatches.ts │ │ │ │ │ │ │ ├── getSyncStatus.ts │ │ │ │ │ │ │ ├── importContacts.ts │ │ │ │ │ │ │ ├── removeData.ts │ │ │ │ │ │ │ ├── sendNotification.ts │ │ │ │ │ │ │ ├── startPhoneVerification.ts │ │ │ │ │ │ │ └── verifyPhone.ts │ │ │ │ │ │ ├── draft/ │ │ │ │ │ │ │ ├── createDraft.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteDraft.ts │ │ │ │ │ │ │ ├── getDrafts.ts │ │ │ │ │ │ │ └── updateDraft.ts │ │ │ │ │ │ ├── embed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── external.ts │ │ │ │ │ │ │ ├── images.ts │ │ │ │ │ │ │ ├── record.ts │ │ │ │ │ │ │ ├── recordWithMedia.ts │ │ │ │ │ │ │ └── video.ts │ │ │ │ │ │ ├── feed/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── describeFeedGenerator.ts │ │ │ │ │ │ │ ├── generator.ts │ │ │ │ │ │ │ ├── getActorFeeds.ts │ │ │ │ │ │ │ ├── getActorLikes.ts │ │ │ │ │ │ │ ├── getAuthorFeed.ts │ │ │ │ │ │ │ ├── getFeed.ts │ │ │ │ │ │ │ ├── getFeedGenerator.ts │ │ │ │ │ │ │ ├── getFeedGenerators.ts │ │ │ │ │ │ │ ├── getFeedSkeleton.ts │ │ │ │ │ │ │ ├── getLikes.ts │ │ │ │ │ │ │ ├── getListFeed.ts │ │ │ │ │ │ │ ├── getPostThread.ts │ │ │ │ │ │ │ ├── getPosts.ts │ │ │ │ │ │ │ ├── getQuotes.ts │ │ │ │ │ │ │ ├── getRepostedBy.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getTimeline.ts │ │ │ │ │ │ │ ├── like.ts │ │ │ │ │ │ │ ├── post.ts │ │ │ │ │ │ │ ├── postgate.ts │ │ │ │ │ │ │ ├── repost.ts │ │ │ │ │ │ │ ├── searchPosts.ts │ │ │ │ │ │ │ ├── sendInteractions.ts │ │ │ │ │ │ │ └── threadgate.ts │ │ │ │ │ │ ├── graph/ │ │ │ │ │ │ │ ├── block.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── follow.ts │ │ │ │ │ │ │ ├── getActorStarterPacks.ts │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ ├── getFollowers.ts │ │ │ │ │ │ │ ├── getFollows.ts │ │ │ │ │ │ │ ├── getKnownFollowers.ts │ │ │ │ │ │ │ ├── getList.ts │ │ │ │ │ │ │ ├── getListBlocks.ts │ │ │ │ │ │ │ ├── getListMutes.ts │ │ │ │ │ │ │ ├── getLists.ts │ │ │ │ │ │ │ ├── getListsWithMembership.ts │ │ │ │ │ │ │ ├── getMutes.ts │ │ │ │ │ │ │ ├── getRelationships.ts │ │ │ │ │ │ │ ├── getStarterPack.ts │ │ │ │ │ │ │ ├── getStarterPacks.ts │ │ │ │ │ │ │ ├── getStarterPacksWithMembership.ts │ │ │ │ │ │ │ ├── getSuggestedFollowsByActor.ts │ │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ │ ├── listblock.ts │ │ │ │ │ │ │ ├── listitem.ts │ │ │ │ │ │ │ ├── muteActor.ts │ │ │ │ │ │ │ ├── muteActorList.ts │ │ │ │ │ │ │ ├── muteThread.ts │ │ │ │ │ │ │ ├── searchStarterPacks.ts │ │ │ │ │ │ │ ├── starterpack.ts │ │ │ │ │ │ │ ├── unmuteActor.ts │ │ │ │ │ │ │ ├── unmuteActorList.ts │ │ │ │ │ │ │ ├── unmuteThread.ts │ │ │ │ │ │ │ └── verification.ts │ │ │ │ │ │ ├── labeler/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getServices.ts │ │ │ │ │ │ │ └── service.ts │ │ │ │ │ │ ├── notification/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getPreferences.ts │ │ │ │ │ │ │ ├── getUnreadCount.ts │ │ │ │ │ │ │ ├── listActivitySubscriptions.ts │ │ │ │ │ │ │ ├── listNotifications.ts │ │ │ │ │ │ │ ├── putActivitySubscription.ts │ │ │ │ │ │ │ ├── putPreferences.ts │ │ │ │ │ │ │ ├── putPreferencesV2.ts │ │ │ │ │ │ │ ├── registerPush.ts │ │ │ │ │ │ │ ├── unregisterPush.ts │ │ │ │ │ │ │ └── updateSeen.ts │ │ │ │ │ │ ├── richtext/ │ │ │ │ │ │ │ └── facet.ts │ │ │ │ │ │ ├── unspecced/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getAgeAssuranceState.ts │ │ │ │ │ │ │ ├── getConfig.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getOnboardingSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getPopularFeedGenerators.ts │ │ │ │ │ │ │ ├── getPostThreadOtherV2.ts │ │ │ │ │ │ │ ├── getPostThreadV2.ts │ │ │ │ │ │ │ ├── getSuggestedFeeds.ts │ │ │ │ │ │ │ ├── getSuggestedFeedsSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedOnboardingUsers.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacks.ts │ │ │ │ │ │ │ ├── getSuggestedStarterPacksSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestedUsers.ts │ │ │ │ │ │ │ ├── getSuggestedUsersSkeleton.ts │ │ │ │ │ │ │ ├── getSuggestionsSkeleton.ts │ │ │ │ │ │ │ ├── getTaggedSuggestions.ts │ │ │ │ │ │ │ ├── getTrendingTopics.ts │ │ │ │ │ │ │ ├── getTrends.ts │ │ │ │ │ │ │ ├── getTrendsSkeleton.ts │ │ │ │ │ │ │ ├── initAgeAssurance.ts │ │ │ │ │ │ │ ├── searchActorsSkeleton.ts │ │ │ │ │ │ │ ├── searchPostsSkeleton.ts │ │ │ │ │ │ │ └── searchStarterPacksSkeleton.ts │ │ │ │ │ │ └── video/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── getJobStatus.ts │ │ │ │ │ │ ├── getUploadLimits.ts │ │ │ │ │ │ └── uploadVideo.ts │ │ │ │ │ ├── chat/ │ │ │ │ │ │ └── bsky/ │ │ │ │ │ │ ├── actor/ │ │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ └── exportAccountData.ts │ │ │ │ │ │ ├── convo/ │ │ │ │ │ │ │ ├── acceptConvo.ts │ │ │ │ │ │ │ ├── addReaction.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteMessageForSelf.ts │ │ │ │ │ │ │ ├── getConvo.ts │ │ │ │ │ │ │ ├── getConvoAvailability.ts │ │ │ │ │ │ │ ├── getConvoForMembers.ts │ │ │ │ │ │ │ ├── getLog.ts │ │ │ │ │ │ │ ├── getMessages.ts │ │ │ │ │ │ │ ├── leaveConvo.ts │ │ │ │ │ │ │ ├── listConvos.ts │ │ │ │ │ │ │ ├── muteConvo.ts │ │ │ │ │ │ │ ├── removeReaction.ts │ │ │ │ │ │ │ ├── sendMessage.ts │ │ │ │ │ │ │ ├── sendMessageBatch.ts │ │ │ │ │ │ │ ├── unmuteConvo.ts │ │ │ │ │ │ │ ├── updateAllRead.ts │ │ │ │ │ │ │ └── updateRead.ts │ │ │ │ │ │ └── moderation/ │ │ │ │ │ │ ├── getActorMetadata.ts │ │ │ │ │ │ ├── getMessageContext.ts │ │ │ │ │ │ └── updateActorAccess.ts │ │ │ │ │ ├── com/ │ │ │ │ │ │ └── atproto/ │ │ │ │ │ │ ├── admin/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ ├── disableAccountInvites.ts │ │ │ │ │ │ │ ├── disableInviteCodes.ts │ │ │ │ │ │ │ ├── enableAccountInvites.ts │ │ │ │ │ │ │ ├── getAccountInfo.ts │ │ │ │ │ │ │ ├── getAccountInfos.ts │ │ │ │ │ │ │ ├── getInviteCodes.ts │ │ │ │ │ │ │ ├── getSubjectStatus.ts │ │ │ │ │ │ │ ├── searchAccounts.ts │ │ │ │ │ │ │ ├── sendEmail.ts │ │ │ │ │ │ │ ├── updateAccountEmail.ts │ │ │ │ │ │ │ ├── updateAccountHandle.ts │ │ │ │ │ │ │ ├── updateAccountPassword.ts │ │ │ │ │ │ │ ├── updateAccountSigningKey.ts │ │ │ │ │ │ │ └── updateSubjectStatus.ts │ │ │ │ │ │ ├── identity/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getRecommendedDidCredentials.ts │ │ │ │ │ │ │ ├── refreshIdentity.ts │ │ │ │ │ │ │ ├── requestPlcOperationSignature.ts │ │ │ │ │ │ │ ├── resolveDid.ts │ │ │ │ │ │ │ ├── resolveHandle.ts │ │ │ │ │ │ │ ├── resolveIdentity.ts │ │ │ │ │ │ │ ├── signPlcOperation.ts │ │ │ │ │ │ │ ├── submitPlcOperation.ts │ │ │ │ │ │ │ └── updateHandle.ts │ │ │ │ │ │ ├── label/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── queryLabels.ts │ │ │ │ │ │ │ └── subscribeLabels.ts │ │ │ │ │ │ ├── lexicon/ │ │ │ │ │ │ │ ├── resolveLexicon.ts │ │ │ │ │ │ │ └── schema.ts │ │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ │ ├── createReport.ts │ │ │ │ │ │ │ └── defs.ts │ │ │ │ │ │ ├── repo/ │ │ │ │ │ │ │ ├── applyWrites.ts │ │ │ │ │ │ │ ├── createRecord.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteRecord.ts │ │ │ │ │ │ │ ├── describeRepo.ts │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ ├── importRepo.ts │ │ │ │ │ │ │ ├── listMissingBlobs.ts │ │ │ │ │ │ │ ├── listRecords.ts │ │ │ │ │ │ │ ├── putRecord.ts │ │ │ │ │ │ │ ├── strongRef.ts │ │ │ │ │ │ │ └── uploadBlob.ts │ │ │ │ │ │ ├── server/ │ │ │ │ │ │ │ ├── activateAccount.ts │ │ │ │ │ │ │ ├── checkAccountStatus.ts │ │ │ │ │ │ │ ├── confirmEmail.ts │ │ │ │ │ │ │ ├── createAccount.ts │ │ │ │ │ │ │ ├── createAppPassword.ts │ │ │ │ │ │ │ ├── createInviteCode.ts │ │ │ │ │ │ │ ├── createInviteCodes.ts │ │ │ │ │ │ │ ├── createSession.ts │ │ │ │ │ │ │ ├── deactivateAccount.ts │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── deleteAccount.ts │ │ │ │ │ │ │ ├── deleteSession.ts │ │ │ │ │ │ │ ├── describeServer.ts │ │ │ │ │ │ │ ├── getAccountInviteCodes.ts │ │ │ │ │ │ │ ├── getServiceAuth.ts │ │ │ │ │ │ │ ├── getSession.ts │ │ │ │ │ │ │ ├── listAppPasswords.ts │ │ │ │ │ │ │ ├── refreshSession.ts │ │ │ │ │ │ │ ├── requestAccountDelete.ts │ │ │ │ │ │ │ ├── requestEmailConfirmation.ts │ │ │ │ │ │ │ ├── requestEmailUpdate.ts │ │ │ │ │ │ │ ├── requestPasswordReset.ts │ │ │ │ │ │ │ ├── reserveSigningKey.ts │ │ │ │ │ │ │ ├── resetPassword.ts │ │ │ │ │ │ │ ├── revokeAppPassword.ts │ │ │ │ │ │ │ └── updateEmail.ts │ │ │ │ │ │ ├── sync/ │ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ │ ├── getBlob.ts │ │ │ │ │ │ │ ├── getBlocks.ts │ │ │ │ │ │ │ ├── getCheckout.ts │ │ │ │ │ │ │ ├── getHead.ts │ │ │ │ │ │ │ ├── getHostStatus.ts │ │ │ │ │ │ │ ├── getLatestCommit.ts │ │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ │ ├── getRepoStatus.ts │ │ │ │ │ │ │ ├── listBlobs.ts │ │ │ │ │ │ │ ├── listHosts.ts │ │ │ │ │ │ │ ├── listRepos.ts │ │ │ │ │ │ │ ├── listReposByCollection.ts │ │ │ │ │ │ │ ├── notifyOfUpdate.ts │ │ │ │ │ │ │ ├── requestCrawl.ts │ │ │ │ │ │ │ └── subscribeRepos.ts │ │ │ │ │ │ └── temp/ │ │ │ │ │ │ ├── addReservedHandle.ts │ │ │ │ │ │ ├── checkHandleAvailability.ts │ │ │ │ │ │ ├── checkSignupQueue.ts │ │ │ │ │ │ ├── dereferenceScope.ts │ │ │ │ │ │ ├── fetchLabels.ts │ │ │ │ │ │ ├── requestPhoneVerification.ts │ │ │ │ │ │ └── revokeAccountCredentials.ts │ │ │ │ │ └── tools/ │ │ │ │ │ └── ozone/ │ │ │ │ │ ├── communication/ │ │ │ │ │ │ ├── createTemplate.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteTemplate.ts │ │ │ │ │ │ ├── listTemplates.ts │ │ │ │ │ │ └── updateTemplate.ts │ │ │ │ │ ├── hosting/ │ │ │ │ │ │ └── getAccountHistory.ts │ │ │ │ │ ├── moderation/ │ │ │ │ │ │ ├── cancelScheduledActions.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── emitEvent.ts │ │ │ │ │ │ ├── getAccountTimeline.ts │ │ │ │ │ │ ├── getEvent.ts │ │ │ │ │ │ ├── getRecord.ts │ │ │ │ │ │ ├── getRecords.ts │ │ │ │ │ │ ├── getRepo.ts │ │ │ │ │ │ ├── getReporterStats.ts │ │ │ │ │ │ ├── getRepos.ts │ │ │ │ │ │ ├── getSubjects.ts │ │ │ │ │ │ ├── listScheduledActions.ts │ │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ │ ├── queryStatuses.ts │ │ │ │ │ │ ├── scheduleAction.ts │ │ │ │ │ │ └── searchRepos.ts │ │ │ │ │ ├── report/ │ │ │ │ │ │ └── defs.ts │ │ │ │ │ ├── safelink/ │ │ │ │ │ │ ├── addRule.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── queryEvents.ts │ │ │ │ │ │ ├── queryRules.ts │ │ │ │ │ │ ├── removeRule.ts │ │ │ │ │ │ └── updateRule.ts │ │ │ │ │ ├── server/ │ │ │ │ │ │ └── getConfig.ts │ │ │ │ │ ├── set/ │ │ │ │ │ │ ├── addValues.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteSet.ts │ │ │ │ │ │ ├── deleteValues.ts │ │ │ │ │ │ ├── getValues.ts │ │ │ │ │ │ ├── querySets.ts │ │ │ │ │ │ └── upsertSet.ts │ │ │ │ │ ├── setting/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── listOptions.ts │ │ │ │ │ │ ├── removeOptions.ts │ │ │ │ │ │ └── upsertOption.ts │ │ │ │ │ ├── signature/ │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── findCorrelation.ts │ │ │ │ │ │ ├── findRelatedAccounts.ts │ │ │ │ │ │ └── searchAccounts.ts │ │ │ │ │ ├── team/ │ │ │ │ │ │ ├── addMember.ts │ │ │ │ │ │ ├── defs.ts │ │ │ │ │ │ ├── deleteMember.ts │ │ │ │ │ │ ├── listMembers.ts │ │ │ │ │ │ └── updateMember.ts │ │ │ │ │ └── verification/ │ │ │ │ │ ├── defs.ts │ │ │ │ │ ├── grantVerifications.ts │ │ │ │ │ ├── listVerifications.ts │ │ │ │ │ └── revokeVerifications.ts │ │ │ │ └── util.ts │ │ │ ├── logger.ts │ │ │ ├── mailer/ │ │ │ │ ├── index.ts │ │ │ │ ├── moderation.ts │ │ │ │ ├── templates/ │ │ │ │ │ ├── confirm-email.d.ts │ │ │ │ │ ├── confirm-email.hbs │ │ │ │ │ ├── delete-account.d.ts │ │ │ │ │ ├── delete-account.hbs │ │ │ │ │ ├── plc-operation.d.ts │ │ │ │ │ ├── plc-operation.hbs │ │ │ │ │ ├── reset-password.d.ts │ │ │ │ │ ├── reset-password.hbs │ │ │ │ │ ├── update-email.d.ts │ │ │ │ │ └── update-email.hbs │ │ │ │ └── templates.ts │ │ │ ├── pipethrough.ts │ │ │ ├── read-after-write/ │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ ├── util.ts │ │ │ │ └── viewer.ts │ │ │ ├── redis.ts │ │ │ ├── repo/ │ │ │ │ ├── index.ts │ │ │ │ ├── prepare.ts │ │ │ │ └── types.ts │ │ │ ├── scripts/ │ │ │ │ ├── README.md │ │ │ │ ├── index.ts │ │ │ │ ├── publish-identity.ts │ │ │ │ ├── rebuild-repo.ts │ │ │ │ ├── rotate-keys.ts │ │ │ │ ├── sequencer-recovery/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── recoverer.ts │ │ │ │ │ ├── recovery-db.ts │ │ │ │ │ ├── repair-repos.ts │ │ │ │ │ └── user-queues.ts │ │ │ │ └── util.ts │ │ │ ├── sequencer/ │ │ │ │ ├── db/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── migrations/ │ │ │ │ │ │ ├── 001-init.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── schema.ts │ │ │ │ ├── events.ts │ │ │ │ ├── index.ts │ │ │ │ ├── outbox.ts │ │ │ │ └── sequencer.ts │ │ │ ├── util/ │ │ │ │ ├── compression.ts │ │ │ │ ├── debug.ts │ │ │ │ ├── http.ts │ │ │ │ ├── params.ts │ │ │ │ └── types.ts │ │ │ └── well-known.ts │ │ ├── test.env │ │ ├── tests/ │ │ │ ├── __snapshots__/ │ │ │ │ └── takedown-appeal.test.ts.snap │ │ │ ├── _puppeteer.ts │ │ │ ├── _util.ts │ │ │ ├── account-deactivation.test.ts │ │ │ ├── account-deletion.test.ts │ │ │ ├── account-migration.test.ts │ │ │ ├── account.test.ts │ │ │ ├── app-passwords.test.ts │ │ │ ├── auth.test.ts │ │ │ ├── blob-deletes.test.ts │ │ │ ├── create-post.test.ts │ │ │ ├── crud.test.ts │ │ │ ├── db.test.ts │ │ │ ├── email-confirmation.test.ts │ │ │ ├── entryway.test.ts │ │ │ ├── file-uploads.test.ts │ │ │ ├── handle-validation.test.ts │ │ │ ├── handles.test.ts │ │ │ ├── invite-codes.test.ts │ │ │ ├── invites-admin.test.ts │ │ │ ├── moderation.test.ts │ │ │ ├── moderator-auth.test.ts │ │ │ ├── oauth.test.ts │ │ │ ├── plc-operations.test.ts │ │ │ ├── preferences.test.ts │ │ │ ├── proxied/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ ├── admin.test.ts.snap │ │ │ │ │ ├── feedgen.test.ts.snap │ │ │ │ │ └── views.test.ts.snap │ │ │ │ ├── admin.test.ts │ │ │ │ ├── feedgen.test.ts │ │ │ │ ├── notif.test.ts │ │ │ │ ├── procedures.test.ts │ │ │ │ ├── proxy-catchall.test.ts │ │ │ │ ├── proxy-header.test.ts │ │ │ │ ├── read-after-write.test.ts │ │ │ │ └── views.test.ts │ │ │ ├── races.test.ts │ │ │ ├── rate-limits.test.ts │ │ │ ├── recovery.test.ts │ │ │ ├── seeds/ │ │ │ │ ├── basic.ts │ │ │ │ ├── follows.ts │ │ │ │ ├── likes.ts │ │ │ │ ├── reposts.ts │ │ │ │ ├── thread.ts │ │ │ │ ├── users-bulk.ts │ │ │ │ └── users.ts │ │ │ ├── sequencer.test.ts │ │ │ ├── server.test.ts │ │ │ ├── sync/ │ │ │ │ ├── invertible-ops.test.ts │ │ │ │ ├── list.test.ts │ │ │ │ ├── subscribe-repos.test.ts │ │ │ │ └── sync.test.ts │ │ │ └── takedown-appeal.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── repo/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── bench/ │ │ │ ├── mst.bench.ts │ │ │ └── repo.bench.ts │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── block-map.ts │ │ │ ├── car.ts │ │ │ ├── cid-set.ts │ │ │ ├── data-diff.ts │ │ │ ├── error.ts │ │ │ ├── index.ts │ │ │ ├── logger.ts │ │ │ ├── mst/ │ │ │ │ ├── diff.ts │ │ │ │ ├── index.ts │ │ │ │ ├── mst.ts │ │ │ │ ├── util.ts │ │ │ │ └── walker.ts │ │ │ ├── parse.ts │ │ │ ├── readable-repo.ts │ │ │ ├── repo.ts │ │ │ ├── storage/ │ │ │ │ ├── index.ts │ │ │ │ ├── memory-blockstore.ts │ │ │ │ ├── readable-blockstore.ts │ │ │ │ ├── sync-storage.ts │ │ │ │ └── types.ts │ │ │ ├── sync/ │ │ │ │ ├── consumer.ts │ │ │ │ ├── index.ts │ │ │ │ └── provider.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── tests/ │ │ │ ├── _keys.ts │ │ │ ├── _util.ts │ │ │ ├── car-file-fixtures.json │ │ │ ├── car.test.ts │ │ │ ├── commit-data.test.ts │ │ │ ├── commit-proof-fixtures.json │ │ │ ├── commit-proofs.test.ts │ │ │ ├── covering-proofs.test.ts │ │ │ ├── mst.test.ts │ │ │ ├── proofs.test.ts │ │ │ ├── repo.test.ts │ │ │ └── sync.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── sync/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── events.ts │ │ │ ├── firehose/ │ │ │ │ ├── index.ts │ │ │ │ └── lexicons.ts │ │ │ ├── index.ts │ │ │ ├── runner/ │ │ │ │ ├── consecutive-list.ts │ │ │ │ ├── index.ts │ │ │ │ ├── memory-runner.ts │ │ │ │ └── types.ts │ │ │ └── util.ts │ │ ├── tests/ │ │ │ ├── firehose.test.ts │ │ │ └── runner.test.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ ├── syntax/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── benchmark.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── at-identifier.ts │ │ │ ├── aturi.ts │ │ │ ├── aturi_validation.ts │ │ │ ├── datetime.ts │ │ │ ├── did.ts │ │ │ ├── handle.ts │ │ │ ├── index.ts │ │ │ ├── language.ts │ │ │ ├── nsid.ts │ │ │ ├── recordkey.ts │ │ │ ├── tid.ts │ │ │ └── uri.ts │ │ ├── tests/ │ │ │ ├── aturi.test.ts │ │ │ ├── datetime.test.ts │ │ │ ├── did.test.ts │ │ │ ├── handle.test.ts │ │ │ ├── language.test.ts │ │ │ ├── nsid.test.ts │ │ │ ├── recordkey.test.ts │ │ │ └── tid.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ ├── tsconfig.tests.json │ │ └── vitest.config.ts │ ├── tap/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── channel.ts │ │ │ ├── client.ts │ │ │ ├── index.ts │ │ │ ├── lex-indexer.ts │ │ │ ├── simple-indexer.ts │ │ │ ├── types.ts │ │ │ └── util.ts │ │ ├── tests/ │ │ │ ├── _util.ts │ │ │ ├── channel.test.ts │ │ │ ├── client.test.ts │ │ │ ├── lex-indexer.test.ts │ │ │ ├── simple-indexer.test.ts │ │ │ └── util.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ ├── tsconfig.tests.json │ │ └── vitest.config.ts │ ├── ws-client/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── tests/ │ │ │ └── keepalive.test.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── tsconfig.tests.json │ ├── xrpc/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── client.ts │ │ │ ├── fetch-handler.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── util.ts │ │ │ └── xrpc-client.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ └── xrpc-server/ │ ├── CHANGELOG.md │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src/ │ │ ├── auth.ts │ │ ├── errors.ts │ │ ├── index.ts │ │ ├── logger.ts │ │ ├── rate-limiter.ts │ │ ├── server.ts │ │ ├── stream/ │ │ │ ├── frames.ts │ │ │ ├── index.ts │ │ │ ├── logger.ts │ │ │ ├── server.ts │ │ │ ├── stream.ts │ │ │ ├── subscription.ts │ │ │ └── types.ts │ │ ├── types.ts │ │ └── util.ts │ ├── tests/ │ │ ├── _util.ts │ │ ├── auth.test.ts │ │ ├── bodies.test.ts │ │ ├── errors.test.ts │ │ ├── frames.test.ts │ │ ├── ipld.test.ts │ │ ├── parameters.test.ts │ │ ├── parsing.test.ts │ │ ├── procedures.test.ts │ │ ├── queries.test.ts │ │ ├── rate-limiter.test.ts │ │ ├── responses.test.ts │ │ ├── stream.test.ts │ │ └── subscriptions.test.ts │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── tsconfig.tests.json ├── pnpm-workspace.yaml ├── services/ │ ├── bsky/ │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── api.js │ │ └── package.json │ ├── bsync/ │ │ ├── Dockerfile │ │ ├── index.js │ │ └── package.json │ ├── ozone/ │ │ ├── Dockerfile │ │ ├── api.js │ │ ├── daemon.js │ │ └── package.json │ └── pds/ │ ├── .gitignore │ ├── Dockerfile │ ├── index.js │ ├── package.json │ ├── run-script.js │ └── tracer.js ├── tsconfig/ │ ├── base.json │ ├── browser.json │ ├── bundler.json │ ├── expo.json │ ├── isomorphic.json │ ├── node.json │ ├── nodenext.json │ ├── tests.json │ └── vitest.json ├── tsconfig.json └── vitest.config.ts ================================================ FILE CONTENTS ================================================ ================================================ FILE: .changeset/README.md ================================================ # Changesets Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets) We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) ================================================ FILE: .changeset/config.json ================================================ { "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", "changelog": ["@changesets/changelog-github", { "repo": "bluesky-social/atproto" }], "commit": false, "fixed": [], "linked": [], "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": [] } ================================================ FILE: .changeset/giant-goats-repeat.md ================================================ --- '@atproto/bsky': patch --- Refactor `FeatureGatesClient` to add `scope()` method and docs. ================================================ FILE: .changeset/nine-eyes-switch.md ================================================ --- '@atproto/bsky': patch --- Remove feature gate for new user onboarding ================================================ FILE: .dockerignore ================================================ node_modules **/dist .DS_Store .git Dockerfile ================================================ FILE: .eslintignore ================================================ dist node_modules # buf packages/bsky/src/proto packages/bsync/src/proto # codegen packages/api/src/client packages/bsky/src/lexicon packages/pds/src/lexicon packages/ozone/src/lexicon # @atproto/lex packages/lexicon-resolver/src/lexicons packages/lex/*/src/lexicons packages/lex/*/tests/lexicons packages/oauth/oauth-client-browser-example/src/lexicons # others packages/oauth/*/src/locales/*/messages.ts packages/oauth/oauth-provider-frontend/src/routeTree.gen.ts packages/oauth/oauth-client-expo/android/build ================================================ FILE: .eslintrc ================================================ { "root": true, "extends": [ "eslint:recommended", "plugin:@typescript-eslint/base", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", "plugin:import/recommended", "plugin:import/typescript" ], "plugins": ["n"], "ignorePatterns": ["dist", "node_modules"], "rules": { "no-var": "error", "prefer-const": "warn", "no-misleading-character-class": "warn", "eqeqeq": ["error", "always", { "null": "ignore" }], "n/global-require": "error", "n/no-extraneous-import": "error", "n/prefer-node-protocol": "error", "import/extensions": ["off", "ignorePackages"], "import/export": "off", "import/namespace": "off", "import/no-deprecated": "off", "import/no-absolute-path": "error", "import/no-dynamic-require": "error", "import/no-self-import": "error", "import/order": [ "error", { "named": true, "distinctGroup": true, "alphabetize": { "order": "asc" }, "newlines-between": "never", "groups": [ "builtin", "external", "internal", "parent", ["index", "sibling"], "object" ] } ], "@typescript-eslint/no-unused-vars": [ "error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "ignoreRestSiblings": true } ], "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off" }, "overrides": [ { "files": ["jest.config.js"], "env": { "commonjs": true } }, { "files": ["vite.config.js", "vite.config.cjs", "vite.config.mjs"], "env": { "node": true } }, { "files": ["jest.setup.js"], "env": { "jest": true } }, { "files": ["*.js", "*.cjs"], "rules": { "@typescript-eslint/no-var-requires": "off" } }, { "files": ["**/*.test.ts", "**/tests/**/*.ts"], "rules": { "n/no-extraneous-import": [ "error", { "allowModules": ["@atproto/dev-env"] } ] } } ], "settings": { "node": { "version": ">=18.7.0" }, "import/internal-regex": "^@atproto(?:-labs)?/", "import/parsers": { "@typescript-eslint/parser": [".ts", ".tsx"] }, "import/resolver": { "typescript": { "project": [ "tsconfig.json", "packages/lex/*/tsconfig.json", "packages/oauth/*/tsconfig.json", "packages/oauth/*/tsconfig.src.json", "packages/internal/*/tsconfig.json", "packages/*/tsconfig.json" ] }, "node": { "extensions": [".js", ".jsx", ".json"] } } } } ================================================ FILE: .gitattributes ================================================ # buf packages/bsky/src/proto/** linguist-generated=true packages/bsync/src/proto/** linguist-generated=true # codegen packages/api/src/client/** linguist-generated=true packages/bsky/src/lexicon/** linguist-generated=true packages/pds/src/lexicon/** linguist-generated=true packages/ozone/src/lexicon/** linguist-generated=true # @atproto/lex packages/lexicon-resolver/src/lexicons/** linguist-generated=true # i18n packages/oauth/oauth-provider-ui/src/locales/**/messages.po linguist-generated=true ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** **To Reproduce** Steps to reproduce the behavior: 1. **Expected behavior** **Details** - Operating system: - Node version: **Additional context** ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: feature-request assignees: '' --- **Is your feature request related to a problem? Please describe.** **Describe the solution you'd like** **Describe alternatives you've considered** **Additional context** ================================================ FILE: .github/workflows/build-and-push-bsky-aws.yaml ================================================ name: build-and-push-bsky-aws on: push: branches: - main env: REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }} USERNAME: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_USERNAME }} PASSWORD: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_PASSWORD }} IMAGE_NAME: bsky-app-view jobs: bsky-container-aws: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/bsky/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/build-and-push-bsky-ghcr.yaml ================================================ name: build-and-push-bsky-ghcr on: push: branches: - main env: REGISTRY: ghcr.io USERNAME: ${{ github.actor }} PASSWORD: ${{ secrets.GITHUB_TOKEN }} # github.repository as / IMAGE_NAME: ${{ github.repository }} jobs: bsky-container-ghcr: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME }} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=bsky:,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/bsky/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/build-and-push-bsync-aws.yaml ================================================ name: build-and-push-bsync-aws on: push: branches: - main env: REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }} USERNAME: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_USERNAME }} PASSWORD: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_PASSWORD }} IMAGE_NAME: bsync jobs: bsync-container-aws: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/bsync/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/build-and-push-bsync-ghcr.yaml ================================================ name: build-and-push-bsync-ghcr on: push: branches: - main env: REGISTRY: ghcr.io USERNAME: ${{ github.actor }} PASSWORD: ${{ secrets.GITHUB_TOKEN }} # github.repository as / IMAGE_NAME: ${{ github.repository }} jobs: bsync-container-ghcr: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME }} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=bsync:,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/bsync/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/build-and-push-ozone-aws.yaml ================================================ name: build-and-push-ozone-aws on: push: branches: - main env: REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }} USERNAME: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_USERNAME }} PASSWORD: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_PASSWORD }} IMAGE_NAME: ozone jobs: ozone-container-aws: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/ozone/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/build-and-push-ozone-ghcr.yaml ================================================ name: build-and-push-ozone-ghcr on: push: branches: - main env: REGISTRY: ghcr.io USERNAME: ${{ github.actor }} PASSWORD: ${{ secrets.GITHUB_TOKEN }} # github.repository as / IMAGE_NAME: ${{ github.repository }} jobs: ozone-container-ghcr: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME }} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=ozone:,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/ozone/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/build-and-push-pds-aws.yaml ================================================ name: build-and-push-pds-aws on: push: branches: - main env: REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }} USERNAME: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_USERNAME }} PASSWORD: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_PASSWORD }} IMAGE_NAME: pds jobs: pds-container-aws: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME}} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/pds/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/build-and-push-pds-ghcr.yaml ================================================ name: build-and-push-pds-ghcr on: push: branches: - main env: REGISTRY: ghcr.io USERNAME: ${{ github.actor }} PASSWORD: ${{ secrets.GITHUB_TOKEN }} # github.repository as / IMAGE_NAME: ${{ github.repository }} jobs: pds-container-ghcr: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-22.04 permissions: contents: read packages: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v3 - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ env.USERNAME }} password: ${{ env.PASSWORD }} - name: Extract Docker metadata id: meta uses: docker/metadata-action@v4 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,enable=true,priority=100,prefix=pds:,suffix=,format=long - name: Build and push Docker image id: build-and-push uses: docker/build-push-action@v4 with: context: . push: ${{ github.event_name != 'pull_request' }} file: ./services/pds/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max ================================================ FILE: .github/workflows/claude.yaml ================================================ name: Claude Code on: issue_comment: types: [created] pull_request_review_comment: types: [created] issues: types: [opened, assigned] pull_request_review: types: [submitted] jobs: claude: if: | (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) runs-on: ubuntu-latest permissions: contents: read pull-requests: read issues: read id-token: write actions: read # Required for Claude to read CI results on PRs steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 1 - name: Run Claude Code id: claude uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} # This is an optional setting that allows Claude to read CI results on PRs additional_permissions: | actions: read # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. # prompt: 'Update the pull request description to include a summary of changes.' # Optional: Add claude_args to customize behavior and configuration # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md # or https://code.claude.com/docs/en/cli-reference for available options # claude_args: '--allowed-tools Bash(gh pr:*)' # NOTE(sfn): we can add a custom system prompt here claude_args: | --model claude-opus-4-5-20251101 ================================================ FILE: .github/workflows/publish.yaml ================================================ name: Publish on: push: branches: - main permissions: id-token: write contents: write pull-requests: write env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: build: name: Publish if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: cache: pnpm node-version-file: '.nvmrc' registry-url: 'https://registry.npmjs.org' - run: npm install --global npm@latest - run: pnpm install --frozen-lockfile env: PUPPETEER_SKIP_DOWNLOAD: true - name: Publish uses: changesets/action@v1 id: changesets with: publish: pnpm release version: pnpm run version-packages commit: 'Version packages' title: 'Version packages' ================================================ FILE: .github/workflows/repo.yaml ================================================ name: Repository CI on: pull_request: branches: - '*' concurrency: group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}' cancel-in-progress: true jobs: build: name: Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: cache: pnpm node-version-file: '.nvmrc' - run: pnpm install --frozen-lockfile env: PUPPETEER_SKIP_DOWNLOAD: true - run: pnpm build - uses: actions/upload-artifact@v4 with: name: dist retention-days: 2 path: | packages/*/dist packages/*/*/dist packages/lex/*/src/lexicons packages/lex/*/tests/lexicons packages/oauth/oauth-client-browser-example/src/lexicons packages/oauth/*/src/locales/*/messages.ts changeset: name: Changeset runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # needed for git diff against base branch - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: cache: pnpm node-version-file: '.nvmrc' - run: pnpm install --frozen-lockfile env: PUPPETEER_SKIP_DOWNLOAD: true - run: pnpm changeset status --since=origin/${{ github.base_ref }} test: name: Test needs: build runs-on: ubuntu-22.04 # Puppeteer does not work in recent Ubuntu versions without a workaround due # to sandboxing issues. Using "ubuntu-latest" results in the following # error: # # No usable sandbox! If you are running on Ubuntu 23.10+ or another Linux # distro that has disabled unprivileged user namespaces with AppArmor, see # https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md. # Otherwise see # https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md # for more information on developing with the (older) SUID sandbox. If you # want to live dangerously and need an immediate workaround, you can try # using --no-sandbox. strategy: fail-fast: false matrix: shard: [1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8] steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: cache: pnpm node-version-file: '.nvmrc' - run: echo "CURRENT_MONTH=$(date +'%Y-%m')" >> $GITHUB_ENV - uses: actions/cache@v4 name: Cache Puppeteer browser binaries with: path: ~/.cache/puppeteer key: ${{ env.CURRENT_MONTH }}-${{ runner.os }}-${{ runner.arch }} - run: pnpm install --frozen-lockfile - uses: actions/download-artifact@v4 with: name: dist path: packages - run: pnpm test:withFlags --maxWorkers=1 --shard=${{ matrix.shard }} --passWithNoTests verify: name: Verify needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: cache: pnpm node-version-file: '.nvmrc' - run: pnpm install --frozen-lockfile env: PUPPETEER_SKIP_DOWNLOAD: true - uses: actions/download-artifact@v4 with: name: dist path: packages - run: pnpm verify ================================================ FILE: .github/workflows/sync-internal.yaml ================================================ name: Sync to internal repo on: push: branches: [main] jobs: sync: if: github.repository == 'bluesky-social/atproto' runs-on: ubuntu-latest steps: - name: Checkout public repo uses: actions/checkout@v4 with: fetch-depth: 0 - name: Generate GitHub App Token id: app-token uses: actions/create-github-app-token@v1 with: app-id: ${{ vars.SYNC_INTERNAL_APP_ID }} private-key: ${{ secrets.SYNC_INTERNAL_PK }} repositories: atproto-internal - name: Push to internal repo env: TOKEN: ${{ steps.app-token.outputs.token }} run: | git config user.name "github-actions" git config user.email "test@users.noreply.github.com" git config --unset-all http.https://github.com/.extraheader git remote add internal https://x-access-token:${TOKEN}@github.com/bluesky-social/atproto-internal.git git push internal main --force ================================================ FILE: .gitignore ================================================ node_modules lerna-debug.log npm-debug.log yarn-error.log packages/**/dist .idea packages/*/coverage test.sqlite .DS_Store *.log *.tsbuildinfo .*.env .env.* .env \#*\# *~ *.swp .claude/ coverage ================================================ FILE: .npmrc ================================================ enable-pre-post-scripts = true include-workspace-root = true ================================================ FILE: .nvmrc ================================================ 22 ================================================ FILE: .prettierignore ================================================ node_modules interop-test-files __snapshots__ dist pnpm-lock.yaml .pnpm* .changeset CHANGELOG.md # buf packages/bsky/src/proto packages/bsync/src/proto # codegen packages/api/src/client packages/bsky/src/lexicon packages/pds/src/lexicon packages/ozone/src/lexicon # @atproto/lex packages/lexicon-resolver/src/lexicons packages/lex/*/src/lexicons packages/lex/*/tests/lexicons packages/oauth/oauth-client-browser-example/src/lexicons # others packages/oauth/*/src/locales/*/messages.ts packages/oauth/oauth-provider-frontend/src/routeTree.gen.ts packages/oauth/oauth-client-expo/android/build ================================================ FILE: .prettierrc ================================================ { "trailingComma": "all", "tabWidth": 2, "semi": false, "singleQuote": true, "plugins": ["prettier-plugin-tailwindcss"], "overrides": [ { "files": "*.hbs", "options": { "singleQuote": false } }, { "files": [".eslintrc"], "options": { "parser": "json", "trailingComma": "none" } } ] } ================================================ FILE: .vscode/extensions.json ================================================ { "recommendations": [ "dbaeumer.vscode-eslint", "wengerk.highlight-bad-chars", "esbenp.prettier-vscode", "streetsidesoftware.code-spell-checker", "vitest.explorer" ] } ================================================ FILE: .vscode/settings.json ================================================ { "cSpell.language": "en,en-US", "cSpell.words": [ "algs", "appview", "atproto", "blockstore", "bluesky", "bsky", "bsync", "cbor", "clsx", "consolas", "dpop", "googleusercontent", "hcaptcha", "hexeditor", "ingester", "insertable", "ipld", "jwks", "keypair", "kysely", "merkle", "msid", "multibase", "multiformats", "nameserver", "oidc", "pkce", "ponyfill", "proxied", "ssrf", "undici", "webcrypto", "whatwg", "xrpc" ], "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit", "source.sortImports": "never" }, "files.associations": { "**/tsconfig/*.json": "jsonc" }, "files.defaultLanguage": "ts", "files.insertFinalNewline": true, "files.trimTrailingWhitespace": true, "prettier.semi": false, "prettier.singleQuote": true, "prettier.trailingComma": "es5", "typescript.tsdk": "node_modules/typescript/lib" } ================================================ FILE: CONTRIBUTORS.md ================================================ # Contributors ATProto receives so many contributions that we could never list everyone who deserves it. However, in this document we want to give special thanks to contributors who solve particularly difficult tasks, send security disclosures, or in some way deserve recognition. ### The AT Protocol maintainers give their thanks to: #### [rmcan](https://github.com/rmcan), Security disclosure, April 2023 #### [ianklatzco](https://github.com/ianklatzco), Security disclosure, April 2023 #### lily, Security disclosure, May 2023 #### [april](https://github.com/april), Security disclosure, May 2023 #### [TowhidKashem](https://github.com/TowhidKashem), Security disclosure, May 2023 #### [DavidBuchanan314](https://github.com/DavidBuchanan314), Security disclosure, May 2023 #### [goeo\_](https://bsky.app/profile/did:web:genco.me), Security disclosure, May 2024 #### [DavidBuchanan314](https://github.com/DavidBuchanan314), Security disclosure, November 2024 #### [daniel](https://hackerone.com/daniel), Security disclosure, November 2024 #### [imax](https://github.com/imax9000), Security disclosure, January 2025 #### [avivkeller](https://github.com/avivkeller), Security disclosure, December 2025 ================================================ FILE: LICENSE-APACHE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: LICENSE-MIT.txt ================================================ MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: LICENSE.txt ================================================ Dual MIT/Apache-2.0 License Copyright (c) 2022-2026 Bluesky Social PBC, and Contributors Except as otherwise noted in individual files, this software is licensed under the MIT license (), or the Apache License, Version 2.0 (). Downstream 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. ================================================ FILE: Makefile ================================================ SHELL = /bin/bash .SHELLFLAGS = -o pipefail -c .PHONY: help help: ## Print info about all commands @echo "Helper Commands:" @echo @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[01;32m%-20s\033[0m %s\n", $$1, $$2}' @echo @echo "NOTE: dependencies between commands are not automatic. Eg, you must run 'deps' and 'build' first, and after any changes" .PHONY: build build: ## Compile all modules pnpm build .PHONY: test test: ## Run all tests pnpm test .PHONY: run-dev-env run-dev-env: ## Run a "development environment" shell cd packages/dev-env; NODE_ENV=development pnpm run start .PHONY: run-dev-env-logged run-dev-env-logged: ## Run a "development environment" shell (with logging) cd packages/dev-env; LOG_ENABLED=true NODE_ENV=development pnpm run start | pnpm exec pino-pretty .PHONY: codegen codegen: ## Re-generate packages from lexicon/ files pnpm codegen .PHONY: lint lint: ## Run style checks and verify syntax pnpm verify .PHONY: fmt fmt: ## Run syntax re-formatting pnpm format .PHONY: fmt-lexicons fmt-lexicons: ## Run syntax re-formatting, just on .json files pnpm exec eslint ./lexicons/ --ext .json --fix .PHONY: deps deps: ## Installs dependent libs using 'pnpm install' pnpm install --frozen-lockfile .PHONY: clean clean: ## Deletes all 'dist' and 'node_package' directories (including nested) rm -rf **/dist **/node_packages .PHONY: nvm-setup nvm-setup: ## Use NVM to install and activate node+pnpm nvm install 18 nvm use 18 corepack enable ================================================ FILE: README.md ================================================ # AT Protocol Reference Implementation (TypeScript) Welcome friends! This repository contains Bluesky's reference implementation of AT Protocol, and of the `app.bsky` microblogging application service backend. ## What is in here? **TypeScript Packages:** | Package | Docs | NPM | | ----------------------------------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | `@atproto/api`: client library | [README](./packages/api/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/api)](https://www.npmjs.com/package/@atproto/api) | | `@atproto/common-web`: shared code and helpers which can run in web browsers | [README](./packages/common-web/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/common-web)](https://www.npmjs.com/package/@atproto/common-web) | | `@atproto/common`: shared code and helpers which doesn't work in web browsers | [README](./packages/common/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/common)](https://www.npmjs.com/package/@atproto/common) | | `@atproto/crypto`: cryptographic signing and key serialization | [README](./packages/crypto/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/crypto)](https://www.npmjs.com/package/@atproto/crypto) | | `@atproto/identity`: DID and handle resolution | [README](./packages/identity/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/identity)](https://www.npmjs.com/package/@atproto/identity) | | `@atproto/lexicon`: schema definition language | [README](./packages/lexicon/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/lexicon)](https://www.npmjs.com/package/@atproto/lexicon) | | `@atproto/repo`: data storage structure, including MST | [README](./packages/repo/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/repo)](https://www.npmjs.com/package/@atproto/repo) | | `@atproto/syntax`: string parsers for identifiers | [README](./packages/syntax/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/syntax)](https://www.npmjs.com/package/@atproto/syntax) | | `@atproto/xrpc`: client-side HTTP API helpers | [README](./packages/xrpc/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/xrpc)](https://www.npmjs.com/package/@atproto/xrpc) | | `@atproto/xrpc-server`: server-side HTTP API helpers | [README](./packages/xrpc-server/README.md) | [![NPM](https://img.shields.io/npm/v/@atproto/xrpc-server)](https://www.npmjs.com/package/@atproto/xrpc-server) | **TypeScript Services:** - `pds`: "Personal Data Server", hosting repo content for atproto accounts. Most implementation code in `packages/pds`, with runtime wrapper in `services/pds`. See [bluesky-social/pds](https://github.com/bluesky-social/pds) for directions on self-hosting. - `bsky`: AppView implementation of the `app.bsky.*` API endpoints. Running on main network at `api.bsky.app`. Most implementation code in `packages/bsky`, with runtime wrapper in `services/bsky`. **Lexicons:** for both the `com.atproto.*` and `app.bsky.*` are canonically versioned in this repo, for now, under `./lexicons/`. These are JSON files in the [Lexicon schema definition language](https://atproto.com/specs/lexicon), similar to JSON Schema or OpenAPI. **Interoperability Test Data:** the language-neutral test files in `./interop-test-files/` may be useful for other protocol implementations to ensure that they follow the specification correctly The source code for the Bluesky Social client app (for web and mobile) can be found at [bluesky-social/social-app](https://github.com/bluesky-social/social-app). Go programming language source code is in [bluesky-social/indigo](https://github.com/bluesky-social/indigo), including the BGS implementation. ## Developer Quickstart We recommend [`nvm`](https://github.com/nvm-sh/nvm) for managing Node.js installs. This project requires Node.js version 18. `pnpm` is used to manage the workspace of multiple packages. You can install it with `npm install --global pnpm`. There is a Makefile which can help with basic development tasks: ```shell # use existing nvm to install node 18 and pnpm make nvm-setup # pull dependencies and build all local packages make deps make build # run the tests, using Docker services as needed make test # run a local PDS and AppView with fake test accounts and data # (this requires a global installation of `jq` and `docker`) make run-dev-env # show all other commands make help ``` ## About AT Protocol The Authenticated Transfer Protocol ("ATP" or "atproto") is a decentralized social media protocol, developed by [Bluesky Social PBC](https://bsky.social). Learn more at: - [Overview and Guides](https://atproto.com/guides/overview) 👈 Best starting point - [Github Discussions](https://github.com/bluesky-social/atproto/discussions) 👈 Great place to ask questions - [Protocol Specifications](https://atproto.com/specs/atp) - [Blogpost on self-authenticating data structures](https://bsky.social/about/blog/3-6-2022-a-self-authenticating-social-protocol) The Bluesky Social application encompasses a set of schemas and APIs built in the overall AT Protocol framework. The namespace for these "Lexicons" is `app.bsky.*`. ## Contributions > While we do accept contributions, we prioritize high quality issues and pull requests. Adhering to the below guidelines will ensure a more timely review. **Rules:** - We may not respond to your issue or PR. - We may close an issue or PR without much feedback. - We may lock discussions or contributions if our attention is getting DDOSed. - We do not provide support for build issues. **Guidelines:** - Check for existing issues before filing a new one, please. - Open an issue and give some time for discussion before submitting a PR. - If submitting a PR that includes a lexicon change, please get sign off on the lexicon change _before_ doing the implementation. - Issues are for bugs & feature requests related to the TypeScript implementation of atproto and related services. - For high-level discussions, please use the [Discussion Forum](https://github.com/bluesky-social/atproto/discussions). - For client issues, please use the relevant [social-app](https://github.com/bluesky-social/social-app) repo. - Stay away from PRs that: - Refactor large parts of the codebase - Add entirely new features without prior discussion - Change the tooling or frameworks used without prior discussion - Introduce new unnecessary dependencies Remember, we serve a wide community of users. Our day-to-day involves us constantly asking "which top priority is our top priority." If you submit well-written PRs that solve problems concisely, that's an awesome contribution. Otherwise, as much as we'd love to accept your ideas and contributions, we really don't have the bandwidth. ## Are you a developer interested in building on atproto? Bluesky is an open social network built on the AT Protocol, a flexible technology that will never lock developers out of the ecosystems that they help build. With atproto, third-party can be as seamless as first-party through custom feeds, federated services, clients, and more. ## Security disclosures If you discover any security issues, please send an email to security@bsky.app. The email is automatically CCed to the entire team, and we'll respond promptly. See [SECURITY.md](https://github.com/bluesky-social/atproto/blob/main/SECURITY.md) for more info. ## License This project is dual-licensed under MIT and Apache 2.0 terms: - MIT license ([LICENSE-MIT.txt](https://github.com/bluesky-social/atproto/blob/main/LICENSE-MIT.txt) or http://opensource.org/licenses/MIT) - 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) Downstream 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. Bluesky Social PBC has committed to a software patent non-aggression pledge. For details see [the original announcement](https://bsky.social/about/blog/10-01-2025-patent-pledge). ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Reporting a Vulnerability Please do NOT report possible security vulnerabilities in public channels such as GitHub Issues. If you believe you have found a security vulnerability, please email us at `security@bsky.app` with a description of the issue. We will acknowledge the vulnerability as soon as possible - within 3 business days - and follow up when a fix lands. Please avoid discussing the vulnerability until we do so. With your consent, we will add you to the repository [CONTRIBUTORS](https://github.com/bluesky-social/atproto/blob/main/CONTRIBUTORS.md) file. ================================================ FILE: interop-test-files/README.md ================================================ atproto Interop Test Files ========================== This directory contains reusable files for testing interoperability and specification compliance for atproto (AT Protocol). The protocol itself is documented at . If there are conflicts or ambiguity between these test files and the specs, the specs are the authority, and these test files should usually be corrected. These files are intended to be simple (JSON, text files, etc) and mostly self-documenting. ================================================ FILE: interop-test-files/crypto/signature-fixtures.json ================================================ [ { "comment": "valid P-256 key and signature, with low-S signature", "messageBase64": "oWVoZWxsb2V3b3JsZA", "algorithm": "ES256", "didDocSuite": "EcdsaSecp256r1VerificationKey2019", "publicKeyDid": "did:key:zDnaembgSGUhZULN2Caob4HLJPaxBh92N7rtH21TErzqf8HQo", "publicKeyMultibase": "zxdM8dSstjrpZaRUwBmDvjGXweKuEMVN95A9oJBFjkWMh", "signatureBase64": "2vZNsG3UKvvO/CDlrdvyZRISOFylinBh0Jupc6KcWoJWExHptCfduPleDbG3rko3YZnn9Lw0IjpixVmexJDegg", "validSignature": true, "tags": [] }, { "comment": "valid K-256 key and signature, with low-S signature", "messageBase64": "oWVoZWxsb2V3b3JsZA", "algorithm": "ES256K", "didDocSuite": "EcdsaSecp256k1VerificationKey2019", "publicKeyDid": "did:key:zQ3shqwJEJyMBsBXCWyCBpUBMqxcon9oHB7mCvx4sSpMdLJwc", "publicKeyMultibase": "z25z9DTpsiYYJKGsWmSPJK2NFN8PcJtZig12K59UgW7q5t", "signatureBase64": "5WpdIuEUUfVUYaozsi8G0B3cWO09cgZbIIwg1t2YKdUn/FEznOndsz/qgiYb89zwxYCbB71f7yQK5Lr7NasfoA", "validSignature": true, "tags": [] }, { "comment": "P-256 key and signature, with non-low-S signature which is invalid in atproto", "messageBase64": "oWVoZWxsb2V3b3JsZA", "algorithm": "ES256", "didDocSuite": "EcdsaSecp256r1VerificationKey2019", "publicKeyDid": "did:key:zDnaembgSGUhZULN2Caob4HLJPaxBh92N7rtH21TErzqf8HQo", "publicKeyMultibase": "zxdM8dSstjrpZaRUwBmDvjGXweKuEMVN95A9oJBFjkWMh", "signatureBase64": "2vZNsG3UKvvO/CDlrdvyZRISOFylinBh0Jupc6KcWoKp7O4VS9giSAah8k5IUbXIW00SuOrjfEqQ9HEkN9JGzw", "validSignature": false, "tags": ["high-s"] }, { "comment": "K-256 key and signature, with non-low-S signature which is invalid in atproto", "messageBase64": "oWVoZWxsb2V3b3JsZA", "algorithm": "ES256K", "didDocSuite": "EcdsaSecp256k1VerificationKey2019", "publicKeyDid": "did:key:zQ3shqwJEJyMBsBXCWyCBpUBMqxcon9oHB7mCvx4sSpMdLJwc", "publicKeyMultibase": "z25z9DTpsiYYJKGsWmSPJK2NFN8PcJtZig12K59UgW7q5t", "signatureBase64": "5WpdIuEUUfVUYaozsi8G0B3cWO09cgZbIIwg1t2YKdXYA67MYxYiTMAVfdnkDCMN9S5B3vHosRe07aORmoshoQ", "validSignature": false, "tags": ["high-s"] }, { "comment": "P-256 key and signature, with DER-encoded signature which is invalid in atproto", "messageBase64": "oWVoZWxsb2V3b3JsZA", "algorithm": "ES256", "didDocSuite": "EcdsaSecp256r1VerificationKey2019", "publicKeyDid": "did:key:zDnaeT6hL2RnTdUhAPLij1QBkhYZnmuKyM7puQLW1tkF4Zkt8", "publicKeyMultibase": "ze8N2PPxnu19hmBQ58t5P3E9Yj6CqakJmTVCaKvf9Byq2", "signatureBase64": "MEQCIFxYelWJ9lNcAVt+jK0y/T+DC/X4ohFZ+m8f9SEItkY1AiACX7eXz5sgtaRrz/SdPR8kprnbHMQVde0T2R8yOTBweA", "validSignature": false, "tags": ["der-encoded"] }, { "comment": "K-256 key and signature, with DER-encoded signature which is invalid in atproto", "messageBase64": "oWVoZWxsb2V3b3JsZA", "algorithm": "ES256K", "didDocSuite": "EcdsaSecp256k1VerificationKey2019", "publicKeyDid": "did:key:zQ3shnriYMXc8wvkbJqfNWh5GXn2bVAeqTC92YuNbek4npqGF", "publicKeyMultibase": "z22uZXWP8fdHXi4jyx8cCDiBf9qQTsAe6VcycoMQPfcMQX", "signatureBase64": "MEUCIQCWumUqJqOCqInXF7AzhIRg2MhwRz2rWZcOEsOjPmNItgIgXJH7RnqfYY6M0eg33wU0sFYDlprwdOcpRn78Sz5ePgk", "validSignature": false, "tags": ["der-encoded"] } ] ================================================ FILE: interop-test-files/crypto/w3c_didkey_K256.json ================================================ [ { "privateKeyBytesHex": "9085d2bef69286a6cbb51623c8fa258629945cd55ca705cc4e66700396894e0c", "publicDidKey": "did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme" }, { "privateKeyBytesHex": "f0f4df55a2b3ff13051ea814a8f24ad00f2e469af73c363ac7e9fb999a9072ed", "publicDidKey": "did:key:zQ3shtxV1FrJfhqE1dvxYRcCknWNjHc3c5X1y3ZSoPDi2aur2" }, { "privateKeyBytesHex": "6b0b91287ae3348f8c2f2552d766f30e3604867e34adc37ccbb74a8e6b893e02", "publicDidKey": "did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N" }, { "privateKeyBytesHex": "c0a6a7c560d37d7ba81ecee9543721ff48fea3e0fb827d42c1868226540fac15", "publicDidKey": "did:key:zQ3shadCps5JLAHcZiuX5YUtWHHL8ysBJqFLWvjZDKAWUBGzy" }, { "privateKeyBytesHex": "175a232d440be1e0788f25488a73d9416c04b6f924bea6354bf05dd2f1a75133", "publicDidKey": "did:key:zQ3shptjE6JwdkeKN4fcpnYQY3m9Cet3NiHdAfpvSUZBFoKBj" } ] ================================================ FILE: interop-test-files/crypto/w3c_didkey_P256.json ================================================ [ { "privateKeyBytesBase58": "9p4VRzdmhsnq869vQjVCTrRry7u4TtfRxhvBFJTGU2Cp", "publicDidKey": "did:key:zDnaeTiq1PdzvZXUaMdezchcMJQpBdH2VN4pgrrEhMCCbmwSb" } ] ================================================ FILE: interop-test-files/syntax/atidentifier_syntax_invalid.txt ================================================ # invalid handles did:thing.test did:thing john-.test john.0 john.- xn--bcher-.tld john..test jo_hn.test # invalid DIDs did didmethodval method:did:val did:method: didmethod:val did:methodval) :did:method:val did:method:val: did:method:val% DID:method:val # other invalid stuff email@example.com @handle@example.com @handle blah ================================================ FILE: interop-test-files/syntax/atidentifier_syntax_valid.txt ================================================ # allows valid handles XX.LCS.MIT.EDU john.test jan.test a234567890123456789.test john2.test john-john.test # allows valid DIDs did:method:val did:method:VAL did:method:val123 did:method:123 did:method:val-two ================================================ FILE: interop-test-files/syntax/aturi_syntax_invalid.txt ================================================ # enforces spec basics a://did:plc:asdf123 at//did:plc:asdf123 at:/a/did:plc:asdf123 at:/did:plc:asdf123 AT://did:plc:asdf123 http://did:plc:asdf123 ://did:plc:asdf123 at:did:plc:asdf123 at:/did:plc:asdf123 at:///did:plc:asdf123 at://:/did:plc:asdf123 at:/ /did:plc:asdf123 at://did:plc:asdf123 at://did:plc:asdf123/ at://did:plc:asdf123 at://did:plc:asdf123/com.atproto.feed.post at://did:plc:asdf123/com.atproto.feed.post# at://did:plc:asdf123/com.atproto.feed.post#/ at://did:plc:asdf123/com.atproto.feed.post#/frag at://did:plc:asdf123/com.atproto.feed.post#fr ag //did:plc:asdf123 at://name at://name.0 at://diD:plc:asdf123 at://did:plc:asdf123/com.atproto.feed.p@st at://did:plc:asdf123/com.atproto.feed.p$st at://did:plc:asdf123/com.atproto.feed.p%st at://did:plc:asdf123/com.atproto.feed.p&st at://did:plc:asdf123/com.atproto.feed.p()t at://did:plc:asdf123/com.atproto.feed_post at://did:plc:asdf123/-com.atproto.feed.post at://did:plc:asdf@123/com.atproto.feed.post at://DID:plc:asdf123 at://user.bsky.123 at://bsky at://did:plc: at://did:plc: at://frag # too long: 'at://did:plc:asdf123/com.atproto.feed.post/' + 'o'.repeat(8200) at://did:plc:asdf123/com.atproto.feed.post/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo # has specified behavior on edge cases at://user.bsky.social// at://user.bsky.social//com.atproto.feed.post at://user.bsky.social/com.atproto.feed.post// at://did:plc:asdf123/com.atproto.feed.post/asdf123/more/more', at://did:plc:asdf123/short/stuff at://did:plc:asdf123/12345 # enforces no trailing slashes at://did:plc:asdf123/ at://user.bsky.social/ at://did:plc:asdf123/com.atproto.feed.post/ at://did:plc:asdf123/com.atproto.feed.post/record/ at://did:plc:asdf123/com.atproto.feed.post/record/#/frag # enforces strict paths at://did:plc:asdf123/com.atproto.feed.post/asdf123/asdf # is very permissive about fragments at://did:plc:asdf123# at://did:plc:asdf123## #at://did:plc:asdf123 at://did:plc:asdf123#/asdf#/asdf # new less permissive about record keys for Lexicon use (with recordkey more specified) at://did:plc:asdf123/com.atproto.feed.post/%23 at://did:plc:asdf123/com.atproto.feed.post/$@!*)(:,;~.sdf123 at://did:plc:asdf123/com.atproto.feed.post/~'sdf123") at://did:plc:asdf123/com.atproto.feed.post/$ at://did:plc:asdf123/com.atproto.feed.post/@ at://did:plc:asdf123/com.atproto.feed.post/! at://did:plc:asdf123/com.atproto.feed.post/* at://did:plc:asdf123/com.atproto.feed.post/( at://did:plc:asdf123/com.atproto.feed.post/, at://did:plc:asdf123/com.atproto.feed.post/; at://did:plc:asdf123/com.atproto.feed.post/abc%30123 at://did:plc:asdf123/com.atproto.feed.post/%30 at://did:plc:asdf123/com.atproto.feed.post/%3 at://did:plc:asdf123/com.atproto.feed.post/% at://did:plc:asdf123/com.atproto.feed.post/%zz at://did:plc:asdf123/com.atproto.feed.post/%%% # disallow dot / double-dot at://did:plc:asdf123/com.atproto.feed.post/. at://did:plc:asdf123/com.atproto.feed.post/.. ================================================ FILE: interop-test-files/syntax/aturi_syntax_valid.txt ================================================ # enforces spec basics at://did:plc:asdf123 at://user.bsky.social at://did:plc:asdf123/com.atproto.feed.post at://did:plc:asdf123/com.atproto.feed.post/record # very long: 'at://did:plc:asdf123/com.atproto.feed.post/' + 'o'.repeat(512) at://did:plc:asdf123/com.atproto.feed.post/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo # enforces no trailing slashes at://did:plc:asdf123 at://user.bsky.social at://did:plc:asdf123/com.atproto.feed.post at://did:plc:asdf123/com.atproto.feed.post/record # enforces strict paths at://did:plc:asdf123/com.atproto.feed.post/asdf123 # is very permissive about record keys at://did:plc:asdf123/com.atproto.feed.post/asdf123 at://did:plc:asdf123/com.atproto.feed.post/a at://did:plc:asdf123/com.atproto.feed.post/asdf-123 at://did:abc:123 at://did:abc:123/io.nsid.someFunc/record-key at://did:abc:123/io.nsid.someFunc/self. at://did:abc:123/io.nsid.someFunc/lang: at://did:abc:123/io.nsid.someFunc/: at://did:abc:123/io.nsid.someFunc/- at://did:abc:123/io.nsid.someFunc/_ at://did:abc:123/io.nsid.someFunc/~ at://did:abc:123/io.nsid.someFunc/... at://did:plc:asdf123/com.atproto.feed.postV2 ================================================ FILE: interop-test-files/syntax/datetime_parse_invalid.txt ================================================ # superficial syntax parses ok, but are not valid datetimes for semantic reasons (eg, "month zero") 1985-00-12T23:20:50.123Z 1985-04-00T23:20:50.123Z 1985-13-12T23:20:50.123Z 1985-04-12T25:20:50.123Z 1985-04-12T23:99:50.123Z 1985-04-12T23:20:61.123Z ================================================ FILE: interop-test-files/syntax/datetime_syntax_invalid.txt ================================================ # subtle changes to: 1985-04-12T23:20:50.123Z 1985-04-12T23:20:50.123z 01985-04-12T23:20:50.123Z 985-04-12T23:20:50.123Z 1985-04-12T23:20:50.Z 1985-04-32T23;20:50.123Z 1985-04-32T23;20:50.123Z # en-dash and em-dash 1985—04-32T23;20:50.123Z 1985–04-32T23;20:50.123Z # whitespace 1985-04-12T23:20:50.123Z 1985-04-12T23:20:50.123Z 1985-04-12T 23:20:50.123Z # not enough zero padding 1985-4-12T23:20:50.123Z 1985-04-2T23:20:50.123Z 1985-04-12T3:20:50.123Z 1985-04-12T23:0:50.123Z 1985-04-12T23:20:5.123Z # too much zero padding 01985-04-12T23:20:50.123Z 1985-004-12T23:20:50.123Z 1985-04-012T23:20:50.123Z 1985-04-12T023:20:50.123Z 1985-04-12T23:020:50.123Z 1985-04-12T23:20:050.123Z # strict capitalization (ISO-8601) 1985-04-12t23:20:50.123Z 1985-04-12T23:20:50.123z # RFC-3339, but not ISO-8601 1985-04-12T23:20:50.123-00:00 1985-04-12_23:20:50.123Z 1985-04-12 23:20:50.123Z # ISO-8601, but weird 1985-04-274T23:20:50.123Z # timezone is required 1985-04-12T23:20:50.123 1985-04-12T23:20:50 1985-04-12 1985-04-12T23:20Z 1985-04-12T23:20:5Z 1985-04-12T23:20:50.123 +001985-04-12T23:20:50.123Z 23:20:50.123Z 1985-04-12T23:20:50.123+00 1985-04-12T23:20:50.123+00:0 1985-04-12T23:20:50.123+0:00 1985-04-12T23:20:50.123 1985-04-12T23:20:50.123+0000 1985-04-12T23:20:50.123+00 1985-04-12T23:20:50.123+ 1985-04-12T23:20:50.123- # ISO-8601, but normalizes to a negative time 0000-01-01T00:00:00+01:00 -000001-12-31T23:00:00.000Z ================================================ FILE: interop-test-files/syntax/datetime_syntax_valid.txt ================================================ # "preferred" 1985-04-12T23:20:50.123Z 1985-04-12T23:20:50.000Z 2000-01-01T00:00:00.000Z 1985-04-12T23:20:50.123456Z 1985-04-12T23:20:50.120Z 1985-04-12T23:20:50.120000Z # "supported" 1985-04-12T23:20:50.1235678912345Z 1985-04-12T23:20:50.100Z 1985-04-12T23:20:50Z 1985-04-12T23:20:50.0Z 1985-04-12T23:20:50.123+00:00 1985-04-12T23:20:50.123-07:00 1985-04-12T23:20:50.123+07:00 1985-04-12T23:20:50.123+01:45 0985-04-12T23:20:50.123-07:00 1985-04-12T23:20:50.123-07:00 0123-01-01T00:00:00.000Z # various precisions, up through at least 12 digits 1985-04-12T23:20:50.1Z 1985-04-12T23:20:50.12Z 1985-04-12T23:20:50.123Z 1985-04-12T23:20:50.1234Z 1985-04-12T23:20:50.12345Z 1985-04-12T23:20:50.123456Z 1985-04-12T23:20:50.1234567Z 1985-04-12T23:20:50.12345678Z 1985-04-12T23:20:50.123456789Z 1985-04-12T23:20:50.1234567890Z 1985-04-12T23:20:50.12345678901Z 1985-04-12T23:20:50.123456789012Z # extreme but currently allowed 0010-12-31T23:00:00.000Z 1000-12-31T23:00:00.000Z 1900-12-31T23:00:00.000Z 3001-12-31T23:00:00.000Z ================================================ FILE: interop-test-files/syntax/did_syntax_invalid.txt ================================================ did didmethodval method:did:val did:method: didmethod:val did:methodval) :did:method:val did.method.val did:method:val: did:method:val% DID:method:val did:METHOD:val did:m123:val did:method:val/two did:method:val?two did:method:val#two did:method:val% did:method:vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ================================================ FILE: interop-test-files/syntax/did_syntax_valid.txt ================================================ did:method:val did:method:VAL did:method:val123 did:method:123 did:method:val-two did:method:val_two did:method:val.two did:method:val:two did:method:val%BB did:method:vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv did:m:v did:method::::val did:method:- did:method:-:_:.:%ab did:method:. did:method:_ did:method::. # allows some real DID values did:onion:2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid did:example:123456789abcdefghi did:plc:7iza6de2dwap2sbkpav7c6c6 did:web:example.com did:web:localhost%3A1234 did:key:zQ3shZc2QzApp2oymGvQbzP8eKheVshBHbU4ZYjeXqwSKEn6N did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a ================================================ FILE: interop-test-files/syntax/handle_syntax_invalid.txt ================================================ # throws on invalid handles did:thing.test did:thing john-.test john.0 john.- xn--bcher-.tld john..test jo_hn.test -john.test .john.test jo!hn.test jo%hn.test jo&hn.test jo@hn.test jo*hn.test jo|hn.test jo:hn.test jo/hn.test john💩.test bücher.test john .test john.test. john john. .john john.test. .john.test john.test john.test joh-.test john.-est john.tes- # max over all handle: 'shoooort' + '.loooooooooooooooooooooooooong'.repeat(9) + '.test' shoooort.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.test # max segment: 'short.' + 'o'.repeat(64) + '.test' short.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.test # throws on "dotless" TLD handles org ai gg io # correctly validates corner cases (modern vs. old RFCs) cn.8 thing.0aa thing.0aa # does not allow IP addresses as handles 127.0.0.1 192.168.0.142 fe80::7325:8a97:c100:94b 2600:3c03::f03c:9100:feb0:af1f # examples from stackoverflow -notvalid.at-all -thing.com www.masełkowski.pl.com ================================================ FILE: interop-test-files/syntax/handle_syntax_valid.txt ================================================ # allows valid handles A.ISI.EDU XX.LCS.MIT.EDU SRI-NIC.ARPA john.test jan.test a234567890123456789.test john2.test john-john.test john.bsky.app jo.hn a.co a.org joh.n j0.h0 jaymome-johnber123456.test jay.mome-johnber123456.test john.test.bsky.app # max over all handle: 'shoooort' + '.loooooooooooooooooooooooooong'.repeat(8) + '.test' shoooort.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.loooooooooooooooooooooooooong.test # max segment: 'short.' + 'o'.repeat(63) + '.test' short.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.test # NOTE: this probably isn't ever going to be a real domain, but my read of the RFC is that it would be possible john.t # allows .local and .arpa handles (proto-level) laptop.local laptop.arpa # allows punycode handles # 💩.test xn--ls8h.test # bücher.tld xn--bcher-kva.tld xn--3jk.com xn--w3d.com xn--vqb.com xn--ppd.com xn--cs9a.com xn--8r9a.com xn--cfd.com xn--5jk.com xn--2lb.com # allows onion (Tor) handles expyuzz4wqqyqhjn.onion friend.expyuzz4wqqyqhjn.onion g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion friend.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion friend.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion 2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion friend.2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion # correctly validates corner cases (modern vs. old RFCs) 12345.test 8.cn 4chan.org 4chan.o-g blah.4chan.org thing.a01 120.0.0.1.com 0john.test 9sta--ck.com 99stack.com 0ohn.test john.t--t thing.0aa.thing # examples from stackoverflow stack.com sta-ck.com sta---ck.com sta--ck9.com stack99.com sta99ck.com google.com.uk google.co.in google.com maselkowski.pl m.maselkowski.pl xn--masekowski-d0b.pl xn--fiqa61au8b7zsevnm8ak20mc4a87e.xn--fiqs8s xn--stackoverflow.com stackoverflow.xn--com stackoverflow.co.uk xn--masekowski-d0b.pl xn--fiqa61au8b7zsevnm8ak20mc4a87e.xn--fiqs8s ================================================ FILE: interop-test-files/syntax/nsid_syntax_invalid.txt ================================================ # length checks com.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.foo com.example.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo com.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.foo # invalid examples com.example.foo.* com.example.foo.blah* com.example.foo.*blah com.exa💩ple.thing a-0.b-1.c-3 a-0.b-1.c-o 1.0.0.127.record 0two.example.foo example.com com.example a. .one.two.three one.two.three one.two..three one .two.three one.two.three com.exa💩ple.thing com.atproto.feed.p@st com.atproto.feed.p_st com.atproto.feed.p*st com.atproto.feed.po#t com.atproto.feed.p!ot com.example-.foo com.example.fooBar.2 ================================================ FILE: interop-test-files/syntax/nsid_syntax_valid.txt ================================================ # length checks com.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.foo com.example.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo com.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.foo # valid examples com.example.fooBar com.example.fooBarV2 net.users.bob.ping a.b.c m.xn--masekowski-d0b.pl one.two.three one.two.three.four-and.FiVe one.2.three a-0.b-1.c a0.b1.cc cn.8.lex.stuff test.12345.record a01.thing.record a.0.c xn--fiqs8s.xn--fiqa61au8b7zsevnm8ak20mc4a87e.record.two a0.b1.c3 com.example.f00 # allows onion (Tor) NSIDs onion.expyuzz4wqqyqhjn.spec.getThing onion.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing # allows starting-with-numeric segments (same as domains) org.4chan.lex.getThing cn.8.lex.stuff onion.2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing ================================================ FILE: interop-test-files/syntax/recordkey_syntax_invalid.txt ================================================ # specs alpha/beta . .. #extra @handle any space any+space number[3] number(3) "quote" dHJ1ZQ== # too long: 'o'.repeat(513) ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ================================================ FILE: interop-test-files/syntax/recordkey_syntax_valid.txt ================================================ # specs self example.com ~1.2-3_ dHJ1ZQ _ literal:self pre:fix # more corner-cases : - _ ~ ... self. lang: :lang # very long: 'o'.repeat(512) oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ================================================ FILE: interop-test-files/syntax/tid_syntax_invalid.txt ================================================ # not base32 3jzfcijpj2z21 0000000000000 # too long/short 3jzfcijpj2z2aa 3jzfcijpj2z2 # old dashes syntax not actually supported (TTTT-TTT-TTTT-CC) 3jzf-cij-pj2z-2a # high bit can't be high zzzzzzzzzzzzz kjzfcijpj2z2a ================================================ FILE: interop-test-files/syntax/tid_syntax_valid.txt ================================================ # 13 digits # 234567abcdefghijklmnopqrstuvwxyz 3jzfcijpj2z2a 7777777777777 3zzzzzzzzzzzz ================================================ FILE: jest.config.js ================================================ /** @type {import('jest').Config} */ module.exports = { projects: ['/packages/*/jest.config.js'], } ================================================ FILE: jest.setup.ts ================================================ import dotenv from 'dotenv' dotenv.config({ path: './test.env' }) ================================================ FILE: lexicons/app/bsky/actor/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.defs", "defs": { "profileViewBasic": { "type": "object", "required": ["did", "handle"], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" }, "displayName": { "type": "string", "maxGraphemes": 64, "maxLength": 640 }, "pronouns": { "type": "string" }, "avatar": { "type": "string", "format": "uri" }, "associated": { "type": "ref", "ref": "#profileAssociated" }, "viewer": { "type": "ref", "ref": "#viewerState" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "createdAt": { "type": "string", "format": "datetime" }, "verification": { "type": "ref", "ref": "#verificationState" }, "status": { "type": "ref", "ref": "#statusView" }, "debug": { "type": "unknown", "description": "Debug information for internal development" } } }, "profileView": { "type": "object", "required": ["did", "handle"], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" }, "displayName": { "type": "string", "maxGraphemes": 64, "maxLength": 640 }, "pronouns": { "type": "string" }, "description": { "type": "string", "maxGraphemes": 256, "maxLength": 2560 }, "avatar": { "type": "string", "format": "uri" }, "associated": { "type": "ref", "ref": "#profileAssociated" }, "indexedAt": { "type": "string", "format": "datetime" }, "createdAt": { "type": "string", "format": "datetime" }, "viewer": { "type": "ref", "ref": "#viewerState" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "verification": { "type": "ref", "ref": "#verificationState" }, "status": { "type": "ref", "ref": "#statusView" }, "debug": { "type": "unknown", "description": "Debug information for internal development" } } }, "profileViewDetailed": { "type": "object", "required": ["did", "handle"], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" }, "displayName": { "type": "string", "maxGraphemes": 64, "maxLength": 640 }, "description": { "type": "string", "maxGraphemes": 256, "maxLength": 2560 }, "pronouns": { "type": "string" }, "website": { "type": "string", "format": "uri" }, "avatar": { "type": "string", "format": "uri" }, "banner": { "type": "string", "format": "uri" }, "followersCount": { "type": "integer" }, "followsCount": { "type": "integer" }, "postsCount": { "type": "integer" }, "associated": { "type": "ref", "ref": "#profileAssociated" }, "joinedViaStarterPack": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackViewBasic" }, "indexedAt": { "type": "string", "format": "datetime" }, "createdAt": { "type": "string", "format": "datetime" }, "viewer": { "type": "ref", "ref": "#viewerState" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "pinnedPost": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, "verification": { "type": "ref", "ref": "#verificationState" }, "status": { "type": "ref", "ref": "#statusView" }, "debug": { "type": "unknown", "description": "Debug information for internal development" } } }, "profileAssociated": { "type": "object", "properties": { "lists": { "type": "integer" }, "feedgens": { "type": "integer" }, "starterPacks": { "type": "integer" }, "labeler": { "type": "boolean" }, "chat": { "type": "ref", "ref": "#profileAssociatedChat" }, "activitySubscription": { "type": "ref", "ref": "#profileAssociatedActivitySubscription" }, "germ": { "type": "ref", "ref": "#profileAssociatedGerm" } } }, "profileAssociatedChat": { "type": "object", "required": ["allowIncoming"], "properties": { "allowIncoming": { "type": "string", "knownValues": ["all", "none", "following"] } } }, "profileAssociatedGerm": { "type": "object", "required": ["showButtonTo", "messageMeUrl"], "properties": { "messageMeUrl": { "type": "string", "format": "uri" }, "showButtonTo": { "type": "string", "knownValues": ["usersIFollow", "everyone"] } } }, "profileAssociatedActivitySubscription": { "type": "object", "required": ["allowSubscriptions"], "properties": { "allowSubscriptions": { "type": "string", "knownValues": ["followers", "mutuals", "none"] } } }, "viewerState": { "type": "object", "description": "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.", "properties": { "muted": { "type": "boolean" }, "mutedByList": { "type": "ref", "ref": "app.bsky.graph.defs#listViewBasic" }, "blockedBy": { "type": "boolean" }, "blocking": { "type": "string", "format": "at-uri" }, "blockingByList": { "type": "ref", "ref": "app.bsky.graph.defs#listViewBasic" }, "following": { "type": "string", "format": "at-uri" }, "followedBy": { "type": "string", "format": "at-uri" }, "knownFollowers": { "description": "This property is present only in selected cases, as an optimization.", "type": "ref", "ref": "#knownFollowers" }, "activitySubscription": { "description": "This property is present only in selected cases, as an optimization.", "type": "ref", "ref": "app.bsky.notification.defs#activitySubscription" } } }, "knownFollowers": { "type": "object", "description": "The subject's followers whom you also follow", "required": ["count", "followers"], "properties": { "count": { "type": "integer" }, "followers": { "type": "array", "minLength": 0, "maxLength": 5, "items": { "type": "ref", "ref": "#profileViewBasic" } } } }, "verificationState": { "type": "object", "description": "Represents the verification information about the user this object is attached to.", "required": ["verifications", "verifiedStatus", "trustedVerifierStatus"], "properties": { "verifications": { "type": "array", "description": "All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included.", "items": { "type": "ref", "ref": "#verificationView" } }, "verifiedStatus": { "type": "string", "description": "The user's status as a verified account.", "knownValues": ["valid", "invalid", "none"] }, "trustedVerifierStatus": { "type": "string", "description": "The user's status as a trusted verifier.", "knownValues": ["valid", "invalid", "none"] } } }, "verificationView": { "type": "object", "description": "An individual verification for an associated subject.", "required": ["issuer", "uri", "isValid", "createdAt"], "properties": { "issuer": { "type": "string", "description": "The user who issued this verification.", "format": "did" }, "uri": { "type": "string", "description": "The AT-URI of the verification record.", "format": "at-uri" }, "isValid": { "type": "boolean", "description": "True if the verification passes validation, otherwise false." }, "createdAt": { "type": "string", "description": "Timestamp when the verification was created.", "format": "datetime" } } }, "preferences": { "type": "array", "items": { "type": "union", "refs": [ "#adultContentPref", "#contentLabelPref", "#savedFeedsPref", "#savedFeedsPrefV2", "#personalDetailsPref", "#declaredAgePref", "#feedViewPref", "#threadViewPref", "#interestsPref", "#mutedWordsPref", "#hiddenPostsPref", "#bskyAppStatePref", "#labelersPref", "#postInteractionSettingsPref", "#verificationPrefs", "#liveEventPreferences" ] } }, "adultContentPref": { "type": "object", "required": ["enabled"], "properties": { "enabled": { "type": "boolean", "default": false } } }, "contentLabelPref": { "type": "object", "required": ["label", "visibility"], "properties": { "labelerDid": { "type": "string", "description": "Which labeler does this preference apply to? If undefined, applies globally.", "format": "did" }, "label": { "type": "string" }, "visibility": { "type": "string", "knownValues": ["ignore", "show", "warn", "hide"] } } }, "savedFeed": { "type": "object", "required": ["id", "type", "value", "pinned"], "properties": { "id": { "type": "string" }, "type": { "type": "string", "knownValues": ["feed", "list", "timeline"] }, "value": { "type": "string" }, "pinned": { "type": "boolean" } } }, "savedFeedsPrefV2": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#savedFeed" } } } }, "savedFeedsPref": { "type": "object", "required": ["pinned", "saved"], "properties": { "pinned": { "type": "array", "items": { "type": "string", "format": "at-uri" } }, "saved": { "type": "array", "items": { "type": "string", "format": "at-uri" } }, "timelineIndex": { "type": "integer" } } }, "personalDetailsPref": { "type": "object", "properties": { "birthDate": { "type": "string", "format": "datetime", "description": "The birth date of account owner." } } }, "declaredAgePref": { "type": "object", "description": "Read-only preference containing value(s) inferred from the user's declared birthdate. Absence of this preference object in the response indicates that the user has not made a declaration.", "properties": { "isOverAge13": { "type": "boolean", "description": "Indicates if the user has declared that they are over 13 years of age." }, "isOverAge16": { "type": "boolean", "description": "Indicates if the user has declared that they are over 16 years of age." }, "isOverAge18": { "type": "boolean", "description": "Indicates if the user has declared that they are over 18 years of age." } } }, "feedViewPref": { "type": "object", "required": ["feed"], "properties": { "feed": { "type": "string", "description": "The URI of the feed, or an identifier which describes the feed." }, "hideReplies": { "type": "boolean", "description": "Hide replies in the feed." }, "hideRepliesByUnfollowed": { "type": "boolean", "description": "Hide replies in the feed if they are not by followed users.", "default": true }, "hideRepliesByLikeCount": { "type": "integer", "description": "Hide replies in the feed if they do not have this number of likes." }, "hideReposts": { "type": "boolean", "description": "Hide reposts in the feed." }, "hideQuotePosts": { "type": "boolean", "description": "Hide quote posts in the feed." } } }, "threadViewPref": { "type": "object", "properties": { "sort": { "type": "string", "description": "Sorting mode for threads.", "knownValues": ["oldest", "newest", "most-likes", "random", "hotness"] } } }, "interestsPref": { "type": "object", "required": ["tags"], "properties": { "tags": { "type": "array", "maxLength": 100, "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 }, "description": "A list of tags which describe the account owner's interests gathered during onboarding." } } }, "mutedWordTarget": { "type": "string", "knownValues": ["content", "tag"], "maxLength": 640, "maxGraphemes": 64 }, "mutedWord": { "type": "object", "description": "A word that the account owner has muted.", "required": ["value", "targets"], "properties": { "id": { "type": "string" }, "value": { "type": "string", "description": "The muted word itself.", "maxLength": 10000, "maxGraphemes": 1000 }, "targets": { "type": "array", "description": "The intended targets of the muted word.", "items": { "type": "ref", "ref": "app.bsky.actor.defs#mutedWordTarget" } }, "actorTarget": { "type": "string", "description": "Groups of users to apply the muted word to. If undefined, applies to all users.", "knownValues": ["all", "exclude-following"], "default": "all" }, "expiresAt": { "type": "string", "format": "datetime", "description": "The date and time at which the muted word will expire and no longer be applied." } } }, "mutedWordsPref": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#mutedWord" }, "description": "A list of words the account owner has muted." } } }, "hiddenPostsPref": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "items": { "type": "string", "format": "at-uri" }, "description": "A list of URIs of posts the account owner has hidden." } } }, "labelersPref": { "type": "object", "required": ["labelers"], "properties": { "labelers": { "type": "array", "items": { "type": "ref", "ref": "#labelerPrefItem" } } } }, "labelerPrefItem": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "bskyAppStatePref": { "description": "A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this.", "type": "object", "properties": { "activeProgressGuide": { "type": "ref", "ref": "#bskyAppProgressGuide" }, "queuedNudges": { "description": "An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user.", "type": "array", "maxLength": 1000, "items": { "type": "string", "maxLength": 100 } }, "nuxs": { "description": "Storage for NUXs the user has encountered.", "type": "array", "maxLength": 100, "items": { "type": "ref", "ref": "app.bsky.actor.defs#nux" } } } }, "bskyAppProgressGuide": { "description": "If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress.", "type": "object", "required": ["guide"], "properties": { "guide": { "type": "string", "maxLength": 100 } } }, "nux": { "type": "object", "description": "A new user experiences (NUX) storage object", "required": ["id", "completed"], "properties": { "id": { "type": "string", "maxLength": 100 }, "completed": { "type": "boolean", "default": false }, "data": { "description": "Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters.", "type": "string", "maxLength": 3000, "maxGraphemes": 300 }, "expiresAt": { "type": "string", "format": "datetime", "description": "The date and time at which the NUX will expire and should be considered completed." } } }, "verificationPrefs": { "type": "object", "description": "Preferences for how verified accounts appear in the app.", "required": [], "properties": { "hideBadges": { "description": "Hide the blue check badges for verified accounts and trusted verifiers.", "type": "boolean", "default": false } } }, "liveEventPreferences": { "type": "object", "description": "Preferences for live events.", "properties": { "hiddenFeedIds": { "description": "A list of feed IDs that the user has hidden from live events.", "type": "array", "items": { "type": "string" } }, "hideAllFeeds": { "description": "Whether to hide all feeds from live events.", "type": "boolean", "default": false } } }, "postInteractionSettingsPref": { "type": "object", "description": "Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.", "required": [], "properties": { "threadgateAllowRules": { "description": "Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.", "type": "array", "maxLength": 5, "items": { "type": "union", "refs": [ "app.bsky.feed.threadgate#mentionRule", "app.bsky.feed.threadgate#followerRule", "app.bsky.feed.threadgate#followingRule", "app.bsky.feed.threadgate#listRule" ] } }, "postgateEmbeddingRules": { "description": "Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.", "type": "array", "maxLength": 5, "items": { "type": "union", "refs": ["app.bsky.feed.postgate#disableRule"] } } } }, "statusView": { "type": "object", "required": ["status", "record"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "status": { "type": "string", "description": "The status for the account.", "knownValues": ["app.bsky.actor.status#live"] }, "record": { "type": "unknown" }, "embed": { "type": "union", "description": "An optional embed associated with the status.", "refs": ["app.bsky.embed.external#view"] }, "expiresAt": { "type": "string", "description": "The date when this status will expire. The application might choose to no longer return the status after expiration.", "format": "datetime" }, "isActive": { "type": "boolean", "description": "True if the status is not expired, false if it is expired. Only present if expiration was set." }, "isDisabled": { "type": "boolean", "description": "True if the user's go-live access has been disabled by a moderator, false otherwise." } } } } } ================================================ FILE: lexicons/app/bsky/actor/getPreferences.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.getPreferences", "defs": { "main": { "type": "query", "description": "Get private preferences attached to the current account. Expected use is synchronization between multiple devices, and import/export during account migration. Requires auth.", "parameters": { "type": "params", "properties": {} }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["preferences"], "properties": { "preferences": { "type": "ref", "ref": "app.bsky.actor.defs#preferences" } } } } } } } ================================================ FILE: lexicons/app/bsky/actor/getProfile.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.getProfile", "defs": { "main": { "type": "query", "description": "Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier", "description": "Handle or DID of account to fetch profile of." } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewDetailed" } } } } } ================================================ FILE: lexicons/app/bsky/actor/getProfiles.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.getProfiles", "defs": { "main": { "type": "query", "description": "Get detailed profile views of multiple actors.", "parameters": { "type": "params", "required": ["actors"], "properties": { "actors": { "type": "array", "items": { "type": "string", "format": "at-identifier" }, "maxLength": 25 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["profiles"], "properties": { "profiles": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewDetailed" } } } } } } } } ================================================ FILE: lexicons/app/bsky/actor/getSuggestions.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.getSuggestions", "defs": { "main": { "type": "query", "description": "Get a list of suggested actors. Expected use is discovery of accounts to follow during new account onboarding.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actors"], "properties": { "cursor": { "type": "string" }, "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } }, "recId": { "type": "integer", "description": "DEPRECATED: use recIdStr instead." }, "recIdStr": { "type": "string", "description": "Snowflake for this recommendation, use when submitting recommendation events." } } } } } } } ================================================ FILE: lexicons/app/bsky/actor/profile.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.profile", "defs": { "main": { "type": "record", "description": "A declaration of a Bluesky account profile.", "key": "literal:self", "record": { "type": "object", "properties": { "displayName": { "type": "string", "maxGraphemes": 64, "maxLength": 640 }, "description": { "type": "string", "description": "Free-form profile description text.", "maxGraphemes": 256, "maxLength": 2560 }, "pronouns": { "type": "string", "description": "Free-form pronouns text.", "maxGraphemes": 20, "maxLength": 200 }, "website": { "type": "string", "format": "uri" }, "avatar": { "type": "blob", "description": "Small image to be displayed next to posts from account. AKA, 'profile picture'", "accept": ["image/png", "image/jpeg"], "maxSize": 1000000 }, "banner": { "type": "blob", "description": "Larger horizontal image to display behind profile view.", "accept": ["image/png", "image/jpeg"], "maxSize": 1000000 }, "labels": { "type": "union", "description": "Self-label values, specific to the Bluesky application, on the overall account.", "refs": ["com.atproto.label.defs#selfLabels"] }, "joinedViaStarterPack": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, "pinnedPost": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, "createdAt": { "type": "string", "format": "datetime" } } } } } } ================================================ FILE: lexicons/app/bsky/actor/putPreferences.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.putPreferences", "defs": { "main": { "type": "procedure", "description": "Set the private preferences attached to the account.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["preferences"], "properties": { "preferences": { "type": "ref", "ref": "app.bsky.actor.defs#preferences" } } } } } } } ================================================ FILE: lexicons/app/bsky/actor/searchActors.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.searchActors", "defs": { "main": { "type": "query", "description": "Find actors (profiles) matching search criteria. Does not require auth.", "parameters": { "type": "params", "properties": { "term": { "type": "string", "description": "DEPRECATED: use 'q' instead." }, "q": { "type": "string", "description": "Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actors"], "properties": { "cursor": { "type": "string" }, "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/actor/searchActorsTypeahead.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.searchActorsTypeahead", "defs": { "main": { "type": "query", "description": "Find actor suggestions for a prefix search term. Expected use is for auto-completion during text field entry. Does not require auth.", "parameters": { "type": "params", "properties": { "term": { "type": "string", "description": "DEPRECATED: use 'q' instead." }, "q": { "type": "string", "description": "Search query prefix; not a full query string." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actors"], "properties": { "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic" } } } } } } } } ================================================ FILE: lexicons/app/bsky/actor/status.json ================================================ { "lexicon": 1, "id": "app.bsky.actor.status", "defs": { "main": { "type": "record", "description": "A declaration of a Bluesky account status.", "key": "literal:self", "record": { "type": "object", "required": ["status", "createdAt"], "properties": { "status": { "type": "string", "description": "The status for the account.", "knownValues": ["app.bsky.actor.status#live"] }, "embed": { "type": "union", "description": "An optional embed associated with the status.", "refs": ["app.bsky.embed.external"] }, "durationMinutes": { "type": "integer", "description": "The duration of the status in minutes. Applications can choose to impose minimum and maximum limits.", "minimum": 1 }, "createdAt": { "type": "string", "format": "datetime" } } } }, "live": { "type": "token", "description": "Advertises an account as currently offering live content." } } } ================================================ FILE: lexicons/app/bsky/ageassurance/begin.json ================================================ { "lexicon": 1, "id": "app.bsky.ageassurance.begin", "defs": { "main": { "type": "procedure", "description": "Initiate Age Assurance for an account.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["email", "language", "countryCode"], "properties": { "email": { "type": "string", "description": "The user's email address to receive Age Assurance instructions." }, "language": { "type": "string", "description": "The user's preferred language for communication during the Age Assurance process." }, "countryCode": { "type": "string", "description": "An ISO 3166-1 alpha-2 code of the user's location." }, "regionCode": { "type": "string", "description": "An optional ISO 3166-2 code of the user's region or state within the country." } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "app.bsky.ageassurance.defs#state" } }, "errors": [ { "name": "InvalidEmail" }, { "name": "DidTooLong" }, { "name": "InvalidInitiation" }, { "name": "RegionNotSupported" } ] } } } ================================================ FILE: lexicons/app/bsky/ageassurance/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.ageassurance.defs", "defs": { "access": { "description": "The access level granted based on Age Assurance data we've processed.", "type": "string", "knownValues": ["unknown", "none", "safe", "full"] }, "status": { "type": "string", "description": "The status of the Age Assurance process.", "knownValues": ["unknown", "pending", "assured", "blocked"] }, "state": { "type": "object", "description": "The user's computed Age Assurance state.", "required": ["status", "access"], "properties": { "lastInitiatedAt": { "type": "string", "format": "datetime", "description": "The timestamp when this state was last updated." }, "status": { "type": "ref", "ref": "app.bsky.ageassurance.defs#status" }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "stateMetadata": { "type": "object", "description": "Additional metadata needed to compute Age Assurance state client-side.", "required": [], "properties": { "accountCreatedAt": { "type": "string", "format": "datetime", "description": "The account creation timestamp." } } }, "config": { "type": "object", "description": "", "required": ["regions"], "properties": { "regions": { "type": "array", "description": "The per-region Age Assurance configuration.", "items": { "type": "ref", "ref": "app.bsky.ageassurance.defs#configRegion" } } } }, "configRegion": { "type": "object", "description": "The Age Assurance configuration for a specific region.", "required": ["countryCode", "minAccessAge", "rules"], "properties": { "countryCode": { "type": "string", "description": "The ISO 3166-1 alpha-2 country code this configuration applies to." }, "regionCode": { "type": "string", "description": "The ISO 3166-2 region code this configuration applies to. If omitted, the configuration applies to the entire country." }, "minAccessAge": { "type": "integer", "description": "The minimum age (as a whole integer) required to use Bluesky in this region." }, "rules": { "type": "array", "description": "The ordered list of Age Assurance rules that apply to this region. Rules should be applied in order, and the first matching rule determines the access level granted. The rules array should always include a default rule as the last item.", "items": { "type": "union", "refs": [ "#configRegionRuleDefault", "#configRegionRuleIfDeclaredOverAge", "#configRegionRuleIfDeclaredUnderAge", "#configRegionRuleIfAssuredOverAge", "#configRegionRuleIfAssuredUnderAge", "#configRegionRuleIfAccountNewerThan", "#configRegionRuleIfAccountOlderThan" ] } } } }, "configRegionRuleDefault": { "type": "object", "description": "Age Assurance rule that applies by default.", "required": ["access"], "properties": { "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "configRegionRuleIfDeclaredOverAge": { "type": "object", "description": "Age Assurance rule that applies if the user has declared themselves equal-to or over a certain age.", "required": ["age", "access"], "properties": { "age": { "type": "integer", "description": "The age threshold as a whole integer." }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "configRegionRuleIfDeclaredUnderAge": { "type": "object", "description": "Age Assurance rule that applies if the user has declared themselves under a certain age.", "required": ["age", "access"], "properties": { "age": { "type": "integer", "description": "The age threshold as a whole integer." }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "configRegionRuleIfAssuredOverAge": { "type": "object", "description": "Age Assurance rule that applies if the user has been assured to be equal-to or over a certain age.", "required": ["age", "access"], "properties": { "age": { "type": "integer", "description": "The age threshold as a whole integer." }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "configRegionRuleIfAssuredUnderAge": { "type": "object", "description": "Age Assurance rule that applies if the user has been assured to be under a certain age.", "required": ["age", "access"], "properties": { "age": { "type": "integer", "description": "The age threshold as a whole integer." }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "configRegionRuleIfAccountNewerThan": { "type": "object", "description": "Age Assurance rule that applies if the account is equal-to or newer than a certain date.", "required": ["date", "access"], "properties": { "date": { "type": "string", "format": "datetime", "description": "The date threshold as a datetime string." }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "configRegionRuleIfAccountOlderThan": { "type": "object", "description": "Age Assurance rule that applies if the account is older than a certain date.", "required": ["date", "access"], "properties": { "date": { "type": "string", "format": "datetime", "description": "The date threshold as a datetime string." }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" } } }, "event": { "type": "object", "description": "Object used to store Age Assurance data in stash.", "required": ["createdAt", "status", "access", "attemptId", "countryCode"], "properties": { "createdAt": { "type": "string", "format": "datetime", "description": "The date and time of this write operation." }, "attemptId": { "type": "string", "description": "The unique identifier for this instance of the Age Assurance flow, in UUID format." }, "status": { "type": "string", "description": "The status of the Age Assurance process.", "knownValues": ["unknown", "pending", "assured", "blocked"] }, "access": { "description": "The access level granted based on Age Assurance data we've processed.", "type": "string", "knownValues": ["unknown", "none", "safe", "full"] }, "countryCode": { "type": "string", "description": "The ISO 3166-1 alpha-2 country code provided when beginning the Age Assurance flow." }, "regionCode": { "type": "string", "description": "The ISO 3166-2 region code provided when beginning the Age Assurance flow." }, "email": { "type": "string", "description": "The email used for Age Assurance." }, "initIp": { "type": "string", "description": "The IP address used when initiating the Age Assurance flow." }, "initUa": { "type": "string", "description": "The user agent used when initiating the Age Assurance flow." }, "completeIp": { "type": "string", "description": "The IP address used when completing the Age Assurance flow." }, "completeUa": { "type": "string", "description": "The user agent used when completing the Age Assurance flow." } } } } } ================================================ FILE: lexicons/app/bsky/ageassurance/getConfig.json ================================================ { "lexicon": 1, "id": "app.bsky.ageassurance.getConfig", "defs": { "main": { "type": "query", "description": "Returns Age Assurance configuration for use on the client.", "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "app.bsky.ageassurance.defs#config" } } } } } ================================================ FILE: lexicons/app/bsky/ageassurance/getState.json ================================================ { "lexicon": 1, "id": "app.bsky.ageassurance.getState", "defs": { "main": { "type": "query", "description": "Returns server-computed Age Assurance state, if available, and any additional metadata needed to compute Age Assurance state client-side.", "parameters": { "type": "params", "required": ["countryCode"], "properties": { "countryCode": { "type": "string" }, "regionCode": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["state", "metadata"], "properties": { "state": { "type": "ref", "ref": "app.bsky.ageassurance.defs#state" }, "metadata": { "type": "ref", "ref": "app.bsky.ageassurance.defs#stateMetadata" } } } } } } } ================================================ FILE: lexicons/app/bsky/authCreatePosts.json ================================================ { "lexicon": 1, "id": "app.bsky.authCreatePosts", "defs": { "main": { "type": "permission-set", "title": "Create Bluesky Posts", "title:lang": {}, "detail": "Can not update or delete posts.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "rpc", "inheritAud": true, "lxm": [ "app.bsky.video.uploadVideo", "app.bsky.video.getJobStatus", "app.bsky.video.getUploadLimits" ] }, { "type": "permission", "resource": "repo", "action": ["create"], "collection": [ "app.bsky.feed.post", "app.bsky.feed.postgate", "app.bsky.feed.threadgate" ] } ] } } } ================================================ FILE: lexicons/app/bsky/authDeleteContent.json ================================================ { "lexicon": 1, "id": "app.bsky.authDeleteContent", "defs": { "main": { "type": "permission-set", "title": "Delete Bluesky Content", "title:lang": {}, "detail": "Clean up public account history: posts, reposts, and likes.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "repo", "action": ["delete"], "collection": [ "app.bsky.feed.like", "app.bsky.feed.post", "app.bsky.feed.postgate", "app.bsky.feed.repost", "app.bsky.feed.threadgate" ] } ] } } } ================================================ FILE: lexicons/app/bsky/authFullApp.json ================================================ { "lexicon": 1, "id": "app.bsky.authFullApp", "defs": { "main": { "type": "permission-set", "title": "Full Bluesky Social App Permissions", "title:lang": {}, "detail": "Manage all public content and interactions, private preferences and subscriptions, and other Bluesky-specific app features and data.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "rpc", "inheritAud": true, "lxm": [ "app.bsky.actor.getPreferences", "app.bsky.actor.getProfile", "app.bsky.actor.getProfiles", "app.bsky.actor.getSuggestions", "app.bsky.actor.putPreferences", "app.bsky.actor.searchActors", "app.bsky.actor.searchActorsTypeahead", "app.bsky.bookmark.createBookmark", "app.bsky.bookmark.deleteBookmark", "app.bsky.bookmark.getBookmarks", "app.bsky.contact.dismissMatch", "app.bsky.contact.getMatches", "app.bsky.contact.getSyncStatus", "app.bsky.contact.importContacts", "app.bsky.contact.removeData", "app.bsky.contact.startPhoneVerification", "app.bsky.contact.verifyPhone", "app.bsky.feed.describeFeedGenerator", "app.bsky.feed.getActorFeeds", "app.bsky.feed.getActorLikes", "app.bsky.feed.getAuthorFeed", "app.bsky.feed.getFeed", "app.bsky.feed.getFeedGenerator", "app.bsky.feed.getFeedGenerators", "app.bsky.feed.getFeedSkeleton", "app.bsky.feed.getLikes", "app.bsky.feed.getListFeed", "app.bsky.feed.getPostThread", "app.bsky.feed.getPosts", "app.bsky.feed.getQuotes", "app.bsky.feed.getRepostedBy", "app.bsky.feed.getSuggestedFeeds", "app.bsky.feed.getTimeline", "app.bsky.feed.searchPosts", "app.bsky.feed.sendInteractions", "app.bsky.graph.getActorStarterPacks", "app.bsky.graph.getBlocks", "app.bsky.graph.getFollowers", "app.bsky.graph.getFollows", "app.bsky.graph.getKnownFollowers", "app.bsky.graph.getList", "app.bsky.graph.getListBlocks", "app.bsky.graph.getListMutes", "app.bsky.graph.getLists", "app.bsky.graph.getListsWithMembership", "app.bsky.graph.getMutes", "app.bsky.graph.getRelationships", "app.bsky.graph.getStarterPack", "app.bsky.graph.getStarterPacks", "app.bsky.graph.getStarterPacksWithMembership", "app.bsky.graph.getSuggestedFollowsByActor", "app.bsky.graph.muteActor", "app.bsky.graph.muteActorList", "app.bsky.graph.muteThread", "app.bsky.graph.searchStarterPacks", "app.bsky.graph.unmuteActor", "app.bsky.graph.unmuteActorList", "app.bsky.graph.unmuteThread", "app.bsky.labeler.getServices", "app.bsky.notification.getPreferences", "app.bsky.notification.getUnreadCount", "app.bsky.notification.listActivitySubscriptions", "app.bsky.notification.listNotifications", "app.bsky.notification.putActivitySubscription", "app.bsky.notification.putPreferences", "app.bsky.notification.putPreferencesV2", "app.bsky.notification.registerPush", "app.bsky.notification.unregisterPush", "app.bsky.notification.updateSeen", "app.bsky.unspecced.getAgeAssuranceState", "app.bsky.unspecced.getConfig", "app.bsky.unspecced.getOnboardingSuggestedStarterPacks", "app.bsky.unspecced.getPopularFeedGenerators", "app.bsky.unspecced.getPostThreadOtherV2", "app.bsky.unspecced.getPostThreadV2", "app.bsky.unspecced.getSuggestedFeeds", "app.bsky.unspecced.getSuggestedFeedsSkeleton", "app.bsky.unspecced.getSuggestedStarterPacks", "app.bsky.unspecced.getSuggestedStarterPacksSkeleton", "app.bsky.unspecced.getSuggestedUsers", "app.bsky.unspecced.getSuggestedUsersSkeleton", "app.bsky.unspecced.getSuggestionsSkeleton", "app.bsky.unspecced.getTaggedSuggestions", "app.bsky.unspecced.getTrendingTopics", "app.bsky.unspecced.getTrends", "app.bsky.unspecced.getTrendsSkeleton", "app.bsky.unspecced.initAgeAssurance", "app.bsky.unspecced.searchActorsSkeleton", "app.bsky.unspecced.searchPostsSkeleton", "app.bsky.unspecced.searchStarterPacksSkeleton", "app.bsky.video.getJobStatus", "app.bsky.video.getUploadLimits", "app.bsky.video.uploadVideo" ] }, { "type": "permission", "resource": "repo", "action": ["create", "update", "delete"], "collection": [ "app.bsky.actor.profile", "app.bsky.actor.status", "app.bsky.feed.like", "app.bsky.feed.post", "app.bsky.feed.postgate", "app.bsky.feed.repost", "app.bsky.feed.threadgate", "app.bsky.graph.block", "app.bsky.graph.follow", "app.bsky.graph.list", "app.bsky.graph.listblock", "app.bsky.graph.listitem", "app.bsky.graph.starterpack", "app.bsky.notification.declaration" ] } ] } } } ================================================ FILE: lexicons/app/bsky/authManageFeedDeclarations.json ================================================ { "lexicon": 1, "id": "app.bsky.authManageFeedDeclarations", "defs": { "main": { "type": "permission-set", "title": "Manage Hosted Feeds", "title:lang": {}, "detail": "Configure feed generator declaration records.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "repo", "action": ["create", "update", "delete"], "collection": ["app.bsky.feed.generator"] } ] } } } ================================================ FILE: lexicons/app/bsky/authManageLabelerService.json ================================================ { "lexicon": 1, "id": "app.bsky.authManageLabelerService", "defs": { "main": { "type": "permission-set", "title": "Manage Hosted Labeling Service", "title:lang": {}, "detail": "Configure labeler declaration records.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "repo", "action": ["create", "update", "delete"], "collection": ["app.bsky.labeler.service"] } ] } } } ================================================ FILE: lexicons/app/bsky/authManageModeration.json ================================================ { "lexicon": 1, "id": "app.bsky.authManageModeration", "defs": { "main": { "type": "permission-set", "title": "Manage Personal Moderation", "title:lang": {}, "detail": "Control over blocks, mutes, mod lists, mod services, and preferences.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "rpc", "inheritAud": true, "lxm": [ "app.bsky.actor.getPreferences", "app.bsky.actor.putPreferences", "app.bsky.graph.muteActor", "app.bsky.graph.muteActorList", "app.bsky.graph.muteThread", "app.bsky.graph.unmuteActor", "app.bsky.graph.unmuteActorList", "app.bsky.graph.unmuteThread" ] }, { "type": "permission", "resource": "repo", "action": ["create", "update", "delete"], "collection": ["app.bsky.graph.block", "app.bsky.graph.listblock"] } ] } } } ================================================ FILE: lexicons/app/bsky/authManageNotifications.json ================================================ { "lexicon": 1, "id": "app.bsky.authManageNotifications", "defs": { "main": { "type": "permission-set", "title": "Manage Bluesky Notifications", "title:lang": {}, "detail": "View and configure notifications for the Bluesky app.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "rpc", "inheritAud": true, "lxm": [ "app.bsky.notification.getPreferences", "app.bsky.notification.getUnreadCount", "app.bsky.notification.listActivitySubscriptions", "app.bsky.notification.listNotifications", "app.bsky.notification.putActivitySubscription", "app.bsky.notification.putPreferences", "app.bsky.notification.putPreferencesV2", "app.bsky.notification.registerPush", "app.bsky.notification.unregisterPush", "app.bsky.notification.updateSeen" ] } ] } } } ================================================ FILE: lexicons/app/bsky/authManageProfile.json ================================================ { "lexicon": 1, "id": "app.bsky.authManageProfile", "defs": { "main": { "type": "permission-set", "title": "Manage Bluesky Profile", "title:lang": {}, "detail": "Update profile data, as well as status and public chat visibility.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "repo", "action": ["create", "update", "delete"], "collection": [ "app.bsky.actor.profile", "app.bsky.actor.status", "app.bsky.notification.declaration" ] } ] } } } ================================================ FILE: lexicons/app/bsky/authViewAll.json ================================================ { "lexicon": 1, "id": "app.bsky.authViewAll", "defs": { "main": { "type": "permission-set", "title": "Read-only access to all content", "title:lang": {}, "detail": "View Bluesky network content from account perspective, and read all notifications and preferences.", "detail:lang": {}, "permissions": [ { "type": "permission", "resource": "rpc", "inheritAud": true, "lxm": [ "app.bsky.actor.getPreferences", "app.bsky.actor.getProfile", "app.bsky.actor.getProfiles", "app.bsky.actor.getSuggestions", "app.bsky.actor.searchActors", "app.bsky.actor.searchActorsTypeahead", "app.bsky.bookmark.getBookmarks", "app.bsky.feed.describeFeedGenerator", "app.bsky.feed.getActorFeeds", "app.bsky.feed.getActorLikes", "app.bsky.feed.getAuthorFeed", "app.bsky.feed.getFeed", "app.bsky.feed.getFeedGenerator", "app.bsky.feed.getFeedGenerators", "app.bsky.feed.getFeedSkeleton", "app.bsky.feed.getLikes", "app.bsky.feed.getListFeed", "app.bsky.feed.getPostThread", "app.bsky.feed.getPosts", "app.bsky.feed.getQuotes", "app.bsky.feed.getRepostedBy", "app.bsky.feed.getSuggestedFeeds", "app.bsky.feed.getTimeline", "app.bsky.feed.searchPosts", "app.bsky.graph.getActorStarterPacks", "app.bsky.graph.getBlocks", "app.bsky.graph.getFollowers", "app.bsky.graph.getFollows", "app.bsky.graph.getKnownFollowers", "app.bsky.graph.getListBlocks", "app.bsky.graph.getListMutes", "app.bsky.graph.getLists", "app.bsky.graph.getListsWithMembership", "app.bsky.graph.getMutes", "app.bsky.graph.getRelationships", "app.bsky.graph.getStarterPack", "app.bsky.graph.getStarterPacks", "app.bsky.graph.getStarterPacksWithMembership", "app.bsky.graph.getSuggestedFollowsByActor", "app.bsky.graph.searchStarterPacks", "app.bsky.labeler.getServices", "app.bsky.notification.getPreferences", "app.bsky.notification.getUnreadCount", "app.bsky.notification.listActivitySubscriptions", "app.bsky.notification.listNotifications", "app.bsky.notification.updateSeen", "app.bsky.unspecced.getAgeAssuranceState", "app.bsky.unspecced.getConfig", "app.bsky.unspecced.getOnboardingSuggestedStarterPacks", "app.bsky.unspecced.getPopularFeedGenerators", "app.bsky.unspecced.getPostThreadOtherV2", "app.bsky.unspecced.getPostThreadV2", "app.bsky.unspecced.getSuggestedFeeds", "app.bsky.unspecced.getSuggestedFeedsSkeleton", "app.bsky.unspecced.getSuggestedStarterPacks", "app.bsky.unspecced.getSuggestedStarterPacksSkeleton", "app.bsky.unspecced.getSuggestedUsers", "app.bsky.unspecced.getSuggestedUsersSkeleton", "app.bsky.unspecced.getSuggestionsSkeleton", "app.bsky.unspecced.getTaggedSuggestions", "app.bsky.unspecced.getTrendingTopics", "app.bsky.unspecced.getTrends", "app.bsky.unspecced.getTrendsSkeleton", "app.bsky.unspecced.searchActorsSkeleton", "app.bsky.unspecced.searchPostsSkeleton", "app.bsky.unspecced.searchStarterPacksSkeleton", "app.bsky.video.getUploadLimits" ] } ] } } } ================================================ FILE: lexicons/app/bsky/bookmark/createBookmark.json ================================================ { "lexicon": 1, "id": "app.bsky.bookmark.createBookmark", "defs": { "main": { "type": "procedure", "description": "Creates a private bookmark for the specified record. Currently, only `app.bsky.feed.post` records are supported. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri", "cid"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" } } } }, "errors": [ { "name": "UnsupportedCollection", "description": "The URI to be bookmarked is for an unsupported collection." } ] } } } ================================================ FILE: lexicons/app/bsky/bookmark/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.bookmark.defs", "defs": { "bookmark": { "description": "Object used to store bookmark data in stash.", "type": "object", "required": ["subject"], "properties": { "subject": { "description": "A strong ref to the record to be bookmarked. Currently, only `app.bsky.feed.post` records are supported.", "type": "ref", "ref": "com.atproto.repo.strongRef" } } }, "bookmarkView": { "type": "object", "required": ["subject", "item"], "properties": { "subject": { "description": "A strong ref to the bookmarked record.", "type": "ref", "ref": "com.atproto.repo.strongRef" }, "createdAt": { "type": "string", "format": "datetime" }, "item": { "type": "union", "refs": [ "app.bsky.feed.defs#blockedPost", "app.bsky.feed.defs#notFoundPost", "app.bsky.feed.defs#postView" ] } } } } } ================================================ FILE: lexicons/app/bsky/bookmark/deleteBookmark.json ================================================ { "lexicon": 1, "id": "app.bsky.bookmark.deleteBookmark", "defs": { "main": { "type": "procedure", "description": "Deletes a private bookmark for the specified record. Currently, only `app.bsky.feed.post` records are supported. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri" } } } }, "errors": [ { "name": "UnsupportedCollection", "description": "The URI to be bookmarked is for an unsupported collection." } ] } } } ================================================ FILE: lexicons/app/bsky/bookmark/getBookmarks.json ================================================ { "lexicon": 1, "id": "app.bsky.bookmark.getBookmarks", "defs": { "main": { "type": "query", "description": "Gets views of records bookmarked by the authenticated user. Requires authentication.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["bookmarks"], "properties": { "cursor": { "type": "string" }, "bookmarks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.bookmark.defs#bookmarkView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/contact/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.defs", "defs": { "matchAndContactIndex": { "description": "Associates a profile with the positional index of the contact import input in the call to `app.bsky.contact.importContacts`, so clients can know which phone caused a particular match.", "type": "object", "required": ["match", "contactIndex"], "properties": { "match": { "description": "Profile of the matched user.", "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "contactIndex": { "description": "The index of this match in the import contact input.", "type": "integer", "minimum": 0, "maximum": 999 } } }, "syncStatus": { "type": "object", "required": ["syncedAt", "matchesCount"], "properties": { "syncedAt": { "description": "Last date when contacts where imported.", "type": "string", "format": "datetime" }, "matchesCount": { "description": "Number of existing contact matches resulting of the user imports and of their imported contacts having imported the user. Matches stop being counted when the user either follows the matched contact or dismisses the match.", "type": "integer", "minimum": 0 } } }, "notification": { "description": "A stash object to be sent via bsync representing a notification to be created.", "type": "object", "required": ["from", "to"], "properties": { "from": { "description": "The DID of who this notification comes from.", "type": "string", "format": "did" }, "to": { "description": "The DID of who this notification should go to.", "type": "string", "format": "did" } } } } } ================================================ FILE: lexicons/app/bsky/contact/dismissMatch.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.dismissMatch", "defs": { "main": { "type": "procedure", "description": "Removes a match that was found via contact import. It shouldn't appear again if the same contact is re-imported. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject"], "properties": { "subject": { "description": "The subject's DID to dismiss the match with.", "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, "errors": [ { "name": "InvalidDid" }, { "name": "InternalError" } ] } } } ================================================ FILE: lexicons/app/bsky/contact/getMatches.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.getMatches", "defs": { "main": { "type": "query", "description": "Returns the matched contacts (contacts that were mutually imported). Excludes dismissed matches. Requires authentication.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["matches"], "properties": { "cursor": { "type": "string" }, "matches": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } }, "errors": [ { "name": "InvalidDid" }, { "name": "InvalidLimit" }, { "name": "InvalidCursor" }, { "name": "InternalError" } ] } } } ================================================ FILE: lexicons/app/bsky/contact/getSyncStatus.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.getSyncStatus", "defs": { "main": { "type": "query", "description": "Gets the user's current contact import status. Requires authentication.", "parameters": { "type": "params", "properties": {} }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": { "syncStatus": { "description": "If present, indicates the user has imported their contacts. If not present, indicates the user never used the feature or called `app.bsky.contact.removeData` and didn't import again since.", "type": "ref", "ref": "app.bsky.contact.defs#syncStatus" } } } }, "errors": [ { "name": "InvalidDid" }, { "name": "InternalError" } ] } } } ================================================ FILE: lexicons/app/bsky/contact/importContacts.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.importContacts", "defs": { "main": { "type": "procedure", "description": "Import contacts for securely matching with other users. This follows the protocol explained in https://docs.bsky.app/blog/contact-import-rfc. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["token", "contacts"], "properties": { "token": { "description": "JWT to authenticate the call. Use the JWT received as a response to the call to `app.bsky.contact.verifyPhone`.", "type": "string" }, "contacts": { "description": "List of phone numbers in global E.164 format (e.g., '+12125550123'). Phone numbers that cannot be normalized into a valid phone number will be discarded. Should not repeat the 'phone' input used in `app.bsky.contact.verifyPhone`.", "type": "array", "items": { "type": "string" }, "minLength": 1, "maxLength": 1000 } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["matchesAndContactIndexes"], "properties": { "matchesAndContactIndexes": { "description": "The users that matched during import and their indexes on the input contacts, so the client can correlate with its local list.", "type": "array", "items": { "type": "ref", "ref": "app.bsky.contact.defs#matchAndContactIndex" } } } } }, "errors": [ { "name": "InvalidDid" }, { "name": "InvalidContacts" }, { "name": "TooManyContacts" }, { "name": "InvalidToken" }, { "name": "InternalError" } ] } } } ================================================ FILE: lexicons/app/bsky/contact/removeData.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.removeData", "defs": { "main": { "type": "procedure", "description": "Removes all stored hashes used for contact matching, existing matches, and sync status. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, "errors": [ { "name": "InvalidDid" }, { "name": "InternalError" } ] } } } ================================================ FILE: lexicons/app/bsky/contact/sendNotification.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.sendNotification", "defs": { "main": { "type": "procedure", "description": "System endpoint to send notifications related to contact imports. Requires role authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["from", "to"], "properties": { "from": { "description": "The DID of who this notification comes from.", "type": "string", "format": "did" }, "to": { "description": "The DID of who this notification should go to.", "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } } } } ================================================ FILE: lexicons/app/bsky/contact/startPhoneVerification.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.startPhoneVerification", "defs": { "main": { "type": "procedure", "description": "Starts a phone verification flow. The phone passed will receive a code via SMS that should be passed to `app.bsky.contact.verifyPhone`. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["phone"], "properties": { "phone": { "description": "The phone number to receive the code via SMS.", "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, "errors": [ { "name": "RateLimitExceeded" }, { "name": "InvalidDid" }, { "name": "InvalidPhone" }, { "name": "InternalError" } ] } } } ================================================ FILE: lexicons/app/bsky/contact/verifyPhone.json ================================================ { "lexicon": 1, "id": "app.bsky.contact.verifyPhone", "defs": { "main": { "type": "procedure", "description": "Verifies control over a phone number with a code received via SMS and starts a contact import session. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["phone", "code"], "properties": { "phone": { "description": "The phone number to verify. Should be the same as the one passed to `app.bsky.contact.startPhoneVerification`.", "type": "string" }, "code": { "description": "The code received via SMS as a result of the call to `app.bsky.contact.startPhoneVerification`.", "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["token"], "properties": { "token": { "description": "JWT to be used in a call to `app.bsky.contact.importContacts`. It is only valid for a single call.", "type": "string" } } } }, "errors": [ { "name": "RateLimitExceeded" }, { "name": "InvalidDid" }, { "name": "InvalidPhone" }, { "name": "InvalidCode" }, { "name": "InternalError" } ] } } } ================================================ FILE: lexicons/app/bsky/draft/createDraft.json ================================================ { "lexicon": 1, "id": "app.bsky.draft.createDraft", "defs": { "main": { "type": "procedure", "description": "Inserts a draft using private storage (stash). An upper limit of drafts might be enforced. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["draft"], "properties": { "draft": { "type": "ref", "ref": "app.bsky.draft.defs#draft" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["id"], "properties": { "id": { "type": "string", "description": "The ID of the created draft." } } } }, "errors": [ { "name": "DraftLimitReached", "description": "Trying to insert a new draft when the limit was already reached." } ] } } } ================================================ FILE: lexicons/app/bsky/draft/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.draft.defs", "defs": { "draftWithId": { "description": "A draft with an identifier, used to store drafts in private storage (stash).", "type": "object", "required": ["id", "draft"], "properties": { "id": { "description": "A TID to be used as a draft identifier.", "type": "string", "format": "tid" }, "draft": { "type": "ref", "ref": "#draft" } } }, "draft": { "description": "A draft containing an array of draft posts.", "type": "object", "required": ["posts"], "properties": { "deviceId": { "type": "string", "description": "UUIDv4 identifier of the device that created this draft.", "maxLength": 100 }, "deviceName": { "type": "string", "description": "The device and/or platform on which the draft was created.", "maxLength": 100 }, "posts": { "description": "Array of draft posts that compose this draft.", "type": "array", "minLength": 1, "maxLength": 100, "items": { "type": "ref", "ref": "#draftPost" } }, "langs": { "type": "array", "description": "Indicates human language of posts primary text content.", "maxLength": 3, "items": { "type": "string", "format": "language" } }, "postgateEmbeddingRules": { "description": "Embedding rules for the postgates to be created when this draft is published.", "type": "array", "maxLength": 5, "items": { "type": "union", "refs": ["app.bsky.feed.postgate#disableRule"] } }, "threadgateAllow": { "description": "Allow-rules for the threadgate to be created when this draft is published.", "type": "array", "maxLength": 5, "items": { "type": "union", "refs": [ "app.bsky.feed.threadgate#mentionRule", "app.bsky.feed.threadgate#followerRule", "app.bsky.feed.threadgate#followingRule", "app.bsky.feed.threadgate#listRule" ] } } } }, "draftPost": { "description": "One of the posts that compose a draft.", "type": "object", "required": ["text"], "properties": { "text": { "type": "string", "maxLength": 10000, "maxGraphemes": 1000, "description": "The primary post content. It has a higher limit than post contents to allow storing a larger text that can later be refined into smaller posts." }, "labels": { "type": "union", "description": "Self-label values for this post. Effectively content warnings.", "refs": ["com.atproto.label.defs#selfLabels"] }, "embedImages": { "type": "array", "items": { "type": "ref", "ref": "#draftEmbedImage" }, "maxLength": 4 }, "embedVideos": { "type": "array", "items": { "type": "ref", "ref": "#draftEmbedVideo" }, "maxLength": 1 }, "embedExternals": { "type": "array", "items": { "type": "ref", "ref": "#draftEmbedExternal" }, "maxLength": 1 }, "embedRecords": { "type": "array", "items": { "type": "ref", "ref": "#draftEmbedRecord" }, "maxLength": 1 } } }, "draftView": { "description": "View to present drafts data to users.", "type": "object", "required": ["id", "draft", "createdAt", "updatedAt"], "properties": { "id": { "description": "A TID to be used as a draft identifier.", "type": "string", "format": "tid" }, "draft": { "type": "ref", "ref": "#draft" }, "createdAt": { "description": "The time the draft was created.", "type": "string", "format": "datetime" }, "updatedAt": { "description": "The time the draft was last updated.", "type": "string", "format": "datetime" } } }, "draftEmbedLocalRef": { "type": "object", "required": ["path"], "properties": { "path": { "type": "string", "description": "Local, on-device ref to file to be embedded. Embeds are currently device-bound for drafts.", "minLength": 1, "maxLength": 1024 } } }, "draftEmbedCaption": { "type": "object", "required": ["lang", "content"], "properties": { "lang": { "type": "string", "format": "language" }, "content": { "type": "string", "maxLength": 10000 } } }, "draftEmbedImage": { "type": "object", "required": ["localRef"], "properties": { "localRef": { "type": "ref", "ref": "#draftEmbedLocalRef" }, "alt": { "type": "string", "maxGraphemes": 2000 } } }, "draftEmbedVideo": { "type": "object", "required": ["localRef"], "properties": { "localRef": { "type": "ref", "ref": "#draftEmbedLocalRef" }, "alt": { "type": "string", "maxGraphemes": 2000 }, "captions": { "type": "array", "items": { "type": "ref", "ref": "#draftEmbedCaption" }, "maxLength": 20 } } }, "draftEmbedExternal": { "type": "object", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "uri" } } }, "draftEmbedRecord": { "type": "object", "required": ["record"], "properties": { "record": { "type": "ref", "ref": "com.atproto.repo.strongRef" } } } } } ================================================ FILE: lexicons/app/bsky/draft/deleteDraft.json ================================================ { "lexicon": 1, "id": "app.bsky.draft.deleteDraft", "defs": { "main": { "type": "procedure", "description": "Deletes a draft by ID. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["id"], "properties": { "id": { "type": "string", "format": "tid" } } } } } } } ================================================ FILE: lexicons/app/bsky/draft/getDrafts.json ================================================ { "lexicon": 1, "id": "app.bsky.draft.getDrafts", "defs": { "main": { "type": "query", "description": "Gets views of user drafts. Requires authentication.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["drafts"], "properties": { "cursor": { "type": "string" }, "drafts": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.draft.defs#draftView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/draft/updateDraft.json ================================================ { "lexicon": 1, "id": "app.bsky.draft.updateDraft", "defs": { "main": { "type": "procedure", "description": "Updates a draft using private storage (stash). If the draft ID points to a non-existing ID, the update will be silently ignored. This is done because updates don't enforce draft limit, so it accepts all writes, but will ignore invalid ones. Requires authentication.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["draft"], "properties": { "draft": { "type": "ref", "ref": "app.bsky.draft.defs#draftWithId" } } } } } } } ================================================ FILE: lexicons/app/bsky/embed/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.embed.defs", "defs": { "aspectRatio": { "type": "object", "description": "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.", "required": ["width", "height"], "properties": { "width": { "type": "integer", "minimum": 1 }, "height": { "type": "integer", "minimum": 1 } } } } } ================================================ FILE: lexicons/app/bsky/embed/external.json ================================================ { "lexicon": 1, "id": "app.bsky.embed.external", "defs": { "main": { "type": "object", "description": "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).", "required": ["external"], "properties": { "external": { "type": "ref", "ref": "#external" } } }, "external": { "type": "object", "required": ["uri", "title", "description"], "properties": { "uri": { "type": "string", "format": "uri" }, "title": { "type": "string" }, "description": { "type": "string" }, "thumb": { "type": "blob", "accept": ["image/*"], "maxSize": 1000000 } } }, "view": { "type": "object", "required": ["external"], "properties": { "external": { "type": "ref", "ref": "#viewExternal" } } }, "viewExternal": { "type": "object", "required": ["uri", "title", "description"], "properties": { "uri": { "type": "string", "format": "uri" }, "title": { "type": "string" }, "description": { "type": "string" }, "thumb": { "type": "string", "format": "uri" } } } } } ================================================ FILE: lexicons/app/bsky/embed/images.json ================================================ { "lexicon": 1, "id": "app.bsky.embed.images", "description": "A set of images embedded in a Bluesky record (eg, a post).", "defs": { "main": { "type": "object", "required": ["images"], "properties": { "images": { "type": "array", "items": { "type": "ref", "ref": "#image" }, "maxLength": 4 } } }, "image": { "type": "object", "required": ["image", "alt"], "properties": { "image": { "type": "blob", "accept": ["image/*"], "maxSize": 1000000 }, "alt": { "type": "string", "description": "Alt text description of the image, for accessibility." }, "aspectRatio": { "type": "ref", "ref": "app.bsky.embed.defs#aspectRatio" } } }, "view": { "type": "object", "required": ["images"], "properties": { "images": { "type": "array", "items": { "type": "ref", "ref": "#viewImage" }, "maxLength": 4 } } }, "viewImage": { "type": "object", "required": ["thumb", "fullsize", "alt"], "properties": { "thumb": { "type": "string", "format": "uri", "description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View." }, "fullsize": { "type": "string", "format": "uri", "description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View." }, "alt": { "type": "string", "description": "Alt text description of the image, for accessibility." }, "aspectRatio": { "type": "ref", "ref": "app.bsky.embed.defs#aspectRatio" } } } } } ================================================ FILE: lexicons/app/bsky/embed/record.json ================================================ { "lexicon": 1, "id": "app.bsky.embed.record", "description": "A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.", "defs": { "main": { "type": "object", "required": ["record"], "properties": { "record": { "type": "ref", "ref": "com.atproto.repo.strongRef" } } }, "view": { "type": "object", "required": ["record"], "properties": { "record": { "type": "union", "refs": [ "#viewRecord", "#viewNotFound", "#viewBlocked", "#viewDetached", "app.bsky.feed.defs#generatorView", "app.bsky.graph.defs#listView", "app.bsky.labeler.defs#labelerView", "app.bsky.graph.defs#starterPackViewBasic" ] } } }, "viewRecord": { "type": "object", "required": ["uri", "cid", "author", "value", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "author": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic" }, "value": { "type": "unknown", "description": "The record data itself." }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "replyCount": { "type": "integer" }, "repostCount": { "type": "integer" }, "likeCount": { "type": "integer" }, "quoteCount": { "type": "integer" }, "embeds": { "type": "array", "items": { "type": "union", "refs": [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", "app.bsky.embed.external#view", "app.bsky.embed.record#view", "app.bsky.embed.recordWithMedia#view" ] } }, "indexedAt": { "type": "string", "format": "datetime" } } }, "viewNotFound": { "type": "object", "required": ["uri", "notFound"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "notFound": { "type": "boolean", "const": true } } }, "viewBlocked": { "type": "object", "required": ["uri", "blocked", "author"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "blocked": { "type": "boolean", "const": true }, "author": { "type": "ref", "ref": "app.bsky.feed.defs#blockedAuthor" } } }, "viewDetached": { "type": "object", "required": ["uri", "detached"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "detached": { "type": "boolean", "const": true } } } } } ================================================ FILE: lexicons/app/bsky/embed/recordWithMedia.json ================================================ { "lexicon": 1, "id": "app.bsky.embed.recordWithMedia", "description": "A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.", "defs": { "main": { "type": "object", "required": ["record", "media"], "properties": { "record": { "type": "ref", "ref": "app.bsky.embed.record" }, "media": { "type": "union", "refs": [ "app.bsky.embed.images", "app.bsky.embed.video", "app.bsky.embed.external" ] } } }, "view": { "type": "object", "required": ["record", "media"], "properties": { "record": { "type": "ref", "ref": "app.bsky.embed.record#view" }, "media": { "type": "union", "refs": [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", "app.bsky.embed.external#view" ] } } } } } ================================================ FILE: lexicons/app/bsky/embed/video.json ================================================ { "lexicon": 1, "id": "app.bsky.embed.video", "description": "A video embedded in a Bluesky record (eg, a post).", "defs": { "main": { "type": "object", "required": ["video"], "properties": { "video": { "type": "blob", "description": "The mp4 video file. May be up to 100mb, formerly limited to 50mb.", "accept": ["video/mp4"], "maxSize": 100000000 }, "captions": { "type": "array", "items": { "type": "ref", "ref": "#caption" }, "maxLength": 20 }, "alt": { "type": "string", "description": "Alt text description of the video, for accessibility.", "maxGraphemes": 1000, "maxLength": 10000 }, "aspectRatio": { "type": "ref", "ref": "app.bsky.embed.defs#aspectRatio" }, "presentation": { "type": "string", "description": "A hint to the client about how to present the video.", "knownValues": ["default", "gif"] } } }, "caption": { "type": "object", "required": ["lang", "file"], "properties": { "lang": { "type": "string", "format": "language" }, "file": { "type": "blob", "accept": ["text/vtt"], "maxSize": 20000 } } }, "view": { "type": "object", "required": ["cid", "playlist"], "properties": { "cid": { "type": "string", "format": "cid" }, "playlist": { "type": "string", "format": "uri" }, "thumbnail": { "type": "string", "format": "uri" }, "alt": { "type": "string", "maxGraphemes": 1000, "maxLength": 10000 }, "aspectRatio": { "type": "ref", "ref": "app.bsky.embed.defs#aspectRatio" }, "presentation": { "type": "string", "description": "A hint to the client about how to present the video.", "knownValues": ["default", "gif"] } } } } } ================================================ FILE: lexicons/app/bsky/feed/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.defs", "defs": { "postView": { "type": "object", "required": ["uri", "cid", "author", "record", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "author": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic" }, "record": { "type": "unknown" }, "embed": { "type": "union", "refs": [ "app.bsky.embed.images#view", "app.bsky.embed.video#view", "app.bsky.embed.external#view", "app.bsky.embed.record#view", "app.bsky.embed.recordWithMedia#view" ] }, "bookmarkCount": { "type": "integer" }, "replyCount": { "type": "integer" }, "repostCount": { "type": "integer" }, "likeCount": { "type": "integer" }, "quoteCount": { "type": "integer" }, "indexedAt": { "type": "string", "format": "datetime" }, "viewer": { "type": "ref", "ref": "#viewerState" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "threadgate": { "type": "ref", "ref": "#threadgateView" }, "debug": { "type": "unknown", "description": "Debug information for internal development" } } }, "viewerState": { "type": "object", "description": "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.", "properties": { "repost": { "type": "string", "format": "at-uri" }, "like": { "type": "string", "format": "at-uri" }, "bookmarked": { "type": "boolean" }, "threadMuted": { "type": "boolean" }, "replyDisabled": { "type": "boolean" }, "embeddingDisabled": { "type": "boolean" }, "pinned": { "type": "boolean" } } }, "threadContext": { "type": "object", "description": "Metadata about this post within the context of the thread it is in.", "properties": { "rootAuthorLike": { "type": "string", "format": "at-uri" } } }, "feedViewPost": { "type": "object", "required": ["post"], "properties": { "post": { "type": "ref", "ref": "#postView" }, "reply": { "type": "ref", "ref": "#replyRef" }, "reason": { "type": "union", "refs": ["#reasonRepost", "#reasonPin"] }, "feedContext": { "type": "string", "description": "Context provided by feed generator that may be passed back alongside interactions.", "maxLength": 2000 }, "reqId": { "type": "string", "description": "Unique identifier per request that may be passed back alongside interactions.", "maxLength": 100 } } }, "replyRef": { "type": "object", "required": ["root", "parent"], "properties": { "root": { "type": "union", "refs": ["#postView", "#notFoundPost", "#blockedPost"] }, "parent": { "type": "union", "refs": ["#postView", "#notFoundPost", "#blockedPost"] }, "grandparentAuthor": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic", "description": "When parent is a reply to another post, this is the author of that post." } } }, "reasonRepost": { "type": "object", "required": ["by", "indexedAt"], "properties": { "by": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic" }, "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "indexedAt": { "type": "string", "format": "datetime" } } }, "reasonPin": { "type": "object", "properties": {} }, "threadViewPost": { "type": "object", "required": ["post"], "properties": { "post": { "type": "ref", "ref": "#postView" }, "parent": { "type": "union", "refs": ["#threadViewPost", "#notFoundPost", "#blockedPost"] }, "replies": { "type": "array", "items": { "type": "union", "refs": ["#threadViewPost", "#notFoundPost", "#blockedPost"] } }, "threadContext": { "type": "ref", "ref": "#threadContext" } } }, "notFoundPost": { "type": "object", "required": ["uri", "notFound"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "notFound": { "type": "boolean", "const": true } } }, "blockedPost": { "type": "object", "required": ["uri", "blocked", "author"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "blocked": { "type": "boolean", "const": true }, "author": { "type": "ref", "ref": "#blockedAuthor" } } }, "blockedAuthor": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" }, "viewer": { "type": "ref", "ref": "app.bsky.actor.defs#viewerState" } } }, "generatorView": { "type": "object", "required": ["uri", "cid", "did", "creator", "displayName", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "did": { "type": "string", "format": "did" }, "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "displayName": { "type": "string" }, "description": { "type": "string", "maxGraphemes": 300, "maxLength": 3000 }, "descriptionFacets": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "avatar": { "type": "string", "format": "uri" }, "likeCount": { "type": "integer", "minimum": 0 }, "acceptsInteractions": { "type": "boolean" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "viewer": { "type": "ref", "ref": "#generatorViewerState" }, "contentMode": { "type": "string", "knownValues": [ "app.bsky.feed.defs#contentModeUnspecified", "app.bsky.feed.defs#contentModeVideo" ] }, "indexedAt": { "type": "string", "format": "datetime" } } }, "generatorViewerState": { "type": "object", "properties": { "like": { "type": "string", "format": "at-uri" } } }, "skeletonFeedPost": { "type": "object", "required": ["post"], "properties": { "post": { "type": "string", "format": "at-uri" }, "reason": { "type": "union", "refs": ["#skeletonReasonRepost", "#skeletonReasonPin"] }, "feedContext": { "type": "string", "description": "Context that will be passed through to client and may be passed to feed generator back alongside interactions.", "maxLength": 2000 } } }, "skeletonReasonRepost": { "type": "object", "required": ["repost"], "properties": { "repost": { "type": "string", "format": "at-uri" } } }, "skeletonReasonPin": { "type": "object", "properties": {} }, "threadgateView": { "type": "object", "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "record": { "type": "unknown" }, "lists": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#listViewBasic" } } } }, "interaction": { "type": "object", "properties": { "item": { "type": "string", "format": "at-uri" }, "event": { "type": "string", "knownValues": [ "app.bsky.feed.defs#requestLess", "app.bsky.feed.defs#requestMore", "app.bsky.feed.defs#clickthroughItem", "app.bsky.feed.defs#clickthroughAuthor", "app.bsky.feed.defs#clickthroughReposter", "app.bsky.feed.defs#clickthroughEmbed", "app.bsky.feed.defs#interactionSeen", "app.bsky.feed.defs#interactionLike", "app.bsky.feed.defs#interactionRepost", "app.bsky.feed.defs#interactionReply", "app.bsky.feed.defs#interactionQuote", "app.bsky.feed.defs#interactionShare" ] }, "feedContext": { "type": "string", "description": "Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton.", "maxLength": 2000 }, "reqId": { "type": "string", "description": "Unique identifier per request that may be passed back alongside interactions.", "maxLength": 100 } } }, "requestLess": { "type": "token", "description": "Request that less content like the given feed item be shown in the feed" }, "requestMore": { "type": "token", "description": "Request that more content like the given feed item be shown in the feed" }, "clickthroughItem": { "type": "token", "description": "User clicked through to the feed item" }, "clickthroughAuthor": { "type": "token", "description": "User clicked through to the author of the feed item" }, "clickthroughReposter": { "type": "token", "description": "User clicked through to the reposter of the feed item" }, "clickthroughEmbed": { "type": "token", "description": "User clicked through to the embedded content of the feed item" }, "contentModeUnspecified": { "type": "token", "description": "Declares the feed generator returns any types of posts." }, "contentModeVideo": { "type": "token", "description": "Declares the feed generator returns posts containing app.bsky.embed.video embeds." }, "interactionSeen": { "type": "token", "description": "Feed item was seen by user" }, "interactionLike": { "type": "token", "description": "User liked the feed item" }, "interactionRepost": { "type": "token", "description": "User reposted the feed item" }, "interactionReply": { "type": "token", "description": "User replied to the feed item" }, "interactionQuote": { "type": "token", "description": "User quoted the feed item" }, "interactionShare": { "type": "token", "description": "User shared the feed item" } } } ================================================ FILE: lexicons/app/bsky/feed/describeFeedGenerator.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.describeFeedGenerator", "defs": { "main": { "type": "query", "description": "Get information about a feed generator, including policies and offered feed URIs. Does not require auth; implemented by Feed Generator services (not App View).", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "feeds"], "properties": { "did": { "type": "string", "format": "did" }, "feeds": { "type": "array", "items": { "type": "ref", "ref": "#feed" } }, "links": { "type": "ref", "ref": "#links" } } } } }, "feed": { "type": "object", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri" } } }, "links": { "type": "object", "properties": { "privacyPolicy": { "type": "string" }, "termsOfService": { "type": "string" } } } } } ================================================ FILE: lexicons/app/bsky/feed/generator.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.generator", "defs": { "main": { "type": "record", "description": "Record declaring of the existence of a feed generator, and containing metadata about it. The record can exist in any repository.", "key": "any", "record": { "type": "object", "required": ["did", "displayName", "createdAt"], "properties": { "did": { "type": "string", "format": "did" }, "displayName": { "type": "string", "maxGraphemes": 24, "maxLength": 240 }, "description": { "type": "string", "maxGraphemes": 300, "maxLength": 3000 }, "descriptionFacets": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "avatar": { "type": "blob", "accept": ["image/png", "image/jpeg"], "maxSize": 1000000 }, "acceptsInteractions": { "type": "boolean", "description": "Declaration that a feed accepts feedback interactions from a client through app.bsky.feed.sendInteractions" }, "labels": { "type": "union", "description": "Self-label values", "refs": ["com.atproto.label.defs#selfLabels"] }, "contentMode": { "type": "string", "knownValues": [ "app.bsky.feed.defs#contentModeUnspecified", "app.bsky.feed.defs#contentModeVideo" ] }, "createdAt": { "type": "string", "format": "datetime" } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getActorFeeds.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getActorFeeds", "defs": { "main": { "type": "query", "description": "Get a list of feeds (feed generator records) created by the actor (in the actor's repo).", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feeds"], "properties": { "cursor": { "type": "string" }, "feeds": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#generatorView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getActorLikes.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getActorLikes", "defs": { "main": { "type": "query", "description": "Get a list of posts liked by an actor. Requires auth, actor must be the requesting account.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feed"], "properties": { "cursor": { "type": "string" }, "feed": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#feedViewPost" } } } } }, "errors": [{ "name": "BlockedActor" }, { "name": "BlockedByActor" }] } } } ================================================ FILE: lexicons/app/bsky/feed/getAuthorFeed.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getAuthorFeed", "defs": { "main": { "type": "query", "description": "Get a view of an actor's 'author feed' (post and reposts by the author). Does not require auth.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "filter": { "type": "string", "description": "Combinations of post/repost types to include in response.", "knownValues": [ "posts_with_replies", "posts_no_replies", "posts_with_media", "posts_and_author_threads", "posts_with_video" ], "default": "posts_with_replies" }, "includePins": { "type": "boolean", "default": false } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feed"], "properties": { "cursor": { "type": "string" }, "feed": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#feedViewPost" } } } } }, "errors": [{ "name": "BlockedActor" }, { "name": "BlockedByActor" }] } } } ================================================ FILE: lexicons/app/bsky/feed/getFeed.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getFeed", "defs": { "main": { "type": "query", "description": "Get a hydrated feed from an actor's selected feed generator. Implemented by App View.", "parameters": { "type": "params", "required": ["feed"], "properties": { "feed": { "type": "string", "format": "at-uri" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feed"], "properties": { "cursor": { "type": "string" }, "feed": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#feedViewPost" } } } } }, "errors": [{ "name": "UnknownFeed" }] } } } ================================================ FILE: lexicons/app/bsky/feed/getFeedGenerator.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getFeedGenerator", "defs": { "main": { "type": "query", "description": "Get information about a feed generator. Implemented by AppView.", "parameters": { "type": "params", "required": ["feed"], "properties": { "feed": { "type": "string", "format": "at-uri", "description": "AT-URI of the feed generator record." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["view", "isOnline", "isValid"], "properties": { "view": { "type": "ref", "ref": "app.bsky.feed.defs#generatorView" }, "isOnline": { "type": "boolean", "description": "Indicates whether the feed generator service has been online recently, or else seems to be inactive." }, "isValid": { "type": "boolean", "description": "Indicates whether the feed generator service is compatible with the record declaration." } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getFeedGenerators.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getFeedGenerators", "defs": { "main": { "type": "query", "description": "Get information about a list of feed generators.", "parameters": { "type": "params", "required": ["feeds"], "properties": { "feeds": { "type": "array", "items": { "type": "string", "format": "at-uri" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feeds"], "properties": { "feeds": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#generatorView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getFeedSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getFeedSkeleton", "defs": { "main": { "type": "query", "description": "Get a skeleton of a feed provided by a feed generator. Auth is optional, depending on provider requirements, and provides the DID of the requester. Implemented by Feed Generator Service.", "parameters": { "type": "params", "required": ["feed"], "properties": { "feed": { "type": "string", "format": "at-uri", "description": "Reference to feed generator record describing the specific feed being requested." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feed"], "properties": { "cursor": { "type": "string" }, "feed": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#skeletonFeedPost" } }, "reqId": { "type": "string", "description": "Unique identifier per request that may be passed back alongside interactions.", "maxLength": 100 } } } }, "errors": [{ "name": "UnknownFeed" }] } } } ================================================ FILE: lexicons/app/bsky/feed/getLikes.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getLikes", "defs": { "main": { "type": "query", "description": "Get like records which reference a subject (by AT-URI and CID).", "parameters": { "type": "params", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri", "description": "AT-URI of the subject (eg, a post record)." }, "cid": { "type": "string", "format": "cid", "description": "CID of the subject record (aka, specific version of record), to filter likes." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri", "likes"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "cursor": { "type": "string" }, "likes": { "type": "array", "items": { "type": "ref", "ref": "#like" } } } } } }, "like": { "type": "object", "required": ["indexedAt", "createdAt", "actor"], "properties": { "indexedAt": { "type": "string", "format": "datetime" }, "createdAt": { "type": "string", "format": "datetime" }, "actor": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } ================================================ FILE: lexicons/app/bsky/feed/getListFeed.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getListFeed", "defs": { "main": { "type": "query", "description": "Get a feed of recent posts from a list (posts and reposts from any actors on the list). Does not require auth.", "parameters": { "type": "params", "required": ["list"], "properties": { "list": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to the list record." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feed"], "properties": { "cursor": { "type": "string" }, "feed": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#feedViewPost" } } } } }, "errors": [{ "name": "UnknownList" }] } } } ================================================ FILE: lexicons/app/bsky/feed/getPostThread.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getPostThread", "defs": { "main": { "type": "query", "description": "Get posts in a thread. Does not require auth, but additional metadata and filtering will be applied for authed requests.", "parameters": { "type": "params", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to post record." }, "depth": { "type": "integer", "description": "How many levels of reply depth should be included in response.", "default": 6, "minimum": 0, "maximum": 1000 }, "parentHeight": { "type": "integer", "description": "How many levels of parent (and grandparent, etc) post to include.", "default": 80, "minimum": 0, "maximum": 1000 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["thread"], "properties": { "thread": { "type": "union", "refs": [ "app.bsky.feed.defs#threadViewPost", "app.bsky.feed.defs#notFoundPost", "app.bsky.feed.defs#blockedPost" ] }, "threadgate": { "type": "ref", "ref": "app.bsky.feed.defs#threadgateView" } } } }, "errors": [{ "name": "NotFound" }] } } } ================================================ FILE: lexicons/app/bsky/feed/getPosts.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getPosts", "defs": { "main": { "type": "query", "description": "Gets post views for a specified list of posts (by AT-URI). This is sometimes referred to as 'hydrating' a 'feed skeleton'.", "parameters": { "type": "params", "required": ["uris"], "properties": { "uris": { "type": "array", "description": "List of post AT-URIs to return hydrated views for.", "items": { "type": "string", "format": "at-uri" }, "maxLength": 25 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["posts"], "properties": { "posts": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#postView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getQuotes.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getQuotes", "defs": { "main": { "type": "query", "description": "Get a list of quotes for a given post.", "parameters": { "type": "params", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) of post record" }, "cid": { "type": "string", "format": "cid", "description": "If supplied, filters to quotes of specific version (by CID) of the post record." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri", "posts"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "cursor": { "type": "string" }, "posts": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#postView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getRepostedBy.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getRepostedBy", "defs": { "main": { "type": "query", "description": "Get a list of reposts for a given post.", "parameters": { "type": "params", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) of post record" }, "cid": { "type": "string", "format": "cid", "description": "If supplied, filters to reposts of specific version (by CID) of the post record." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri", "repostedBy"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "cursor": { "type": "string" }, "repostedBy": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getSuggestedFeeds.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getSuggestedFeeds", "defs": { "main": { "type": "query", "description": "Get a list of suggested feeds (feed generators) for the requesting account.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feeds"], "properties": { "cursor": { "type": "string" }, "feeds": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#generatorView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/getTimeline.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.getTimeline", "defs": { "main": { "type": "query", "description": "Get a view of the requesting account's home timeline. This is expected to be some form of reverse-chronological feed.", "parameters": { "type": "params", "properties": { "algorithm": { "type": "string", "description": "Variant 'algorithm' for timeline. Implementation-specific. NOTE: most feed flexibility has been moved to feed generator mechanism." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feed"], "properties": { "cursor": { "type": "string" }, "feed": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#feedViewPost" } } } } } } } } ================================================ FILE: lexicons/app/bsky/feed/like.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.like", "defs": { "main": { "type": "record", "description": "Record declaring a 'like' of a piece of subject content.", "key": "tid", "record": { "type": "object", "required": ["subject", "createdAt"], "properties": { "subject": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, "createdAt": { "type": "string", "format": "datetime" }, "via": { "type": "ref", "ref": "com.atproto.repo.strongRef" } } } } } } ================================================ FILE: lexicons/app/bsky/feed/post.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.post", "defs": { "main": { "type": "record", "description": "Record containing a Bluesky post.", "key": "tid", "record": { "type": "object", "required": ["text", "createdAt"], "properties": { "text": { "type": "string", "maxLength": 3000, "maxGraphemes": 300, "description": "The primary post content. May be an empty string, if there are embeds." }, "entities": { "type": "array", "description": "DEPRECATED: replaced by app.bsky.richtext.facet.", "items": { "type": "ref", "ref": "#entity" } }, "facets": { "type": "array", "description": "Annotations of text (mentions, URLs, hashtags, etc)", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "reply": { "type": "ref", "ref": "#replyRef" }, "embed": { "type": "union", "refs": [ "app.bsky.embed.images", "app.bsky.embed.video", "app.bsky.embed.external", "app.bsky.embed.record", "app.bsky.embed.recordWithMedia" ] }, "langs": { "type": "array", "description": "Indicates human language of post primary text content.", "maxLength": 3, "items": { "type": "string", "format": "language" } }, "labels": { "type": "union", "description": "Self-label values for this post. Effectively content warnings.", "refs": ["com.atproto.label.defs#selfLabels"] }, "tags": { "type": "array", "description": "Additional hashtags, in addition to any included in post text and facets.", "maxLength": 8, "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 } }, "createdAt": { "type": "string", "format": "datetime", "description": "Client-declared timestamp when this post was originally created." } } } }, "replyRef": { "type": "object", "required": ["root", "parent"], "properties": { "root": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, "parent": { "type": "ref", "ref": "com.atproto.repo.strongRef" } } }, "entity": { "type": "object", "description": "Deprecated: use facets instead.", "required": ["index", "type", "value"], "properties": { "index": { "type": "ref", "ref": "#textSlice" }, "type": { "type": "string", "description": "Expected values are 'mention' and 'link'." }, "value": { "type": "string" } } }, "textSlice": { "type": "object", "description": "Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.", "required": ["start", "end"], "properties": { "start": { "type": "integer", "minimum": 0 }, "end": { "type": "integer", "minimum": 0 } } } } } ================================================ FILE: lexicons/app/bsky/feed/postgate.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.postgate", "defs": { "main": { "type": "record", "key": "tid", "description": "Record defining interaction rules for a post. The record key (rkey) of the postgate record must match the record key of the post, and that record must be in the same repository.", "record": { "type": "object", "required": ["post", "createdAt"], "properties": { "createdAt": { "type": "string", "format": "datetime" }, "post": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to the post record." }, "detachedEmbeddingUris": { "type": "array", "maxLength": 50, "items": { "type": "string", "format": "at-uri" }, "description": "List of AT-URIs embedding this post that the author has detached from." }, "embeddingRules": { "description": "List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.", "type": "array", "maxLength": 5, "items": { "type": "union", "refs": ["#disableRule"] } } } } }, "disableRule": { "type": "object", "description": "Disables embedding of this post.", "properties": {} } } } ================================================ FILE: lexicons/app/bsky/feed/repost.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.repost", "defs": { "main": { "description": "Record representing a 'repost' of an existing Bluesky post.", "type": "record", "key": "tid", "record": { "type": "object", "required": ["subject", "createdAt"], "properties": { "subject": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, "createdAt": { "type": "string", "format": "datetime" }, "via": { "type": "ref", "ref": "com.atproto.repo.strongRef" } } } } } } ================================================ FILE: lexicons/app/bsky/feed/searchPosts.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.searchPosts", "defs": { "main": { "type": "query", "description": "Find posts matching search criteria, returning views of those posts. Note that this API endpoint may require authentication (eg, not public) for some service providers and implementations.", "parameters": { "type": "params", "required": ["q"], "properties": { "q": { "type": "string", "description": "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended." }, "sort": { "type": "string", "knownValues": ["top", "latest"], "default": "latest", "description": "Specifies the ranking order of results." }, "since": { "type": "string", "description": "Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD)." }, "until": { "type": "string", "description": "Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD)." }, "mentions": { "type": "string", "format": "at-identifier", "description": "Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions." }, "author": { "type": "string", "format": "at-identifier", "description": "Filter to posts by the given account. Handles are resolved to DID before query-time." }, "lang": { "type": "string", "format": "language", "description": "Filter to posts in the given language. Expected to be based on post language field, though server may override language detection." }, "domain": { "type": "string", "description": "Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization." }, "url": { "type": "string", "format": "uri", "description": "Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching." }, "tag": { "type": "array", "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 }, "description": "Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }, "cursor": { "type": "string", "description": "Optional pagination mechanism; may not necessarily allow scrolling through entire result set." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["posts"], "properties": { "cursor": { "type": "string" }, "hitsTotal": { "type": "integer", "description": "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits." }, "posts": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#postView" } } } } }, "errors": [{ "name": "BadQueryString" }] } } } ================================================ FILE: lexicons/app/bsky/feed/sendInteractions.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.sendInteractions", "defs": { "main": { "type": "procedure", "description": "Send information about interactions with feed items back to the feed generator that served them.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["interactions"], "properties": { "feed": { "type": "string", "format": "at-uri" }, "interactions": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#interaction" } } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } } } } ================================================ FILE: lexicons/app/bsky/feed/threadgate.json ================================================ { "lexicon": 1, "id": "app.bsky.feed.threadgate", "defs": { "main": { "type": "record", "key": "tid", "description": "Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository.", "record": { "type": "object", "required": ["post", "createdAt"], "properties": { "post": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to the post record." }, "allow": { "description": "List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.", "type": "array", "maxLength": 5, "items": { "type": "union", "refs": [ "#mentionRule", "#followerRule", "#followingRule", "#listRule" ] } }, "createdAt": { "type": "string", "format": "datetime" }, "hiddenReplies": { "type": "array", "maxLength": 300, "items": { "type": "string", "format": "at-uri" }, "description": "List of hidden reply URIs." } } } }, "mentionRule": { "type": "object", "description": "Allow replies from actors mentioned in your post.", "properties": {} }, "followerRule": { "type": "object", "description": "Allow replies from actors who follow you.", "properties": {} }, "followingRule": { "type": "object", "description": "Allow replies from actors you follow.", "properties": {} }, "listRule": { "type": "object", "description": "Allow replies from actors on a list.", "required": ["list"], "properties": { "list": { "type": "string", "format": "at-uri" } } } } } ================================================ FILE: lexicons/app/bsky/graph/block.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.block", "defs": { "main": { "type": "record", "description": "Record declaring a 'block' relationship against another account. NOTE: blocks are public in Bluesky; see blog posts for details.", "key": "tid", "record": { "type": "object", "required": ["subject", "createdAt"], "properties": { "subject": { "type": "string", "format": "did", "description": "DID of the account to be blocked." }, "createdAt": { "type": "string", "format": "datetime" } } } } } } ================================================ FILE: lexicons/app/bsky/graph/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.defs", "defs": { "listViewBasic": { "type": "object", "required": ["uri", "cid", "name", "purpose"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "name": { "type": "string", "maxLength": 64, "minLength": 1 }, "purpose": { "type": "ref", "ref": "#listPurpose" }, "avatar": { "type": "string", "format": "uri" }, "listItemCount": { "type": "integer", "minimum": 0 }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "viewer": { "type": "ref", "ref": "#listViewerState" }, "indexedAt": { "type": "string", "format": "datetime" } } }, "listView": { "type": "object", "required": ["uri", "cid", "creator", "name", "purpose", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "name": { "type": "string", "maxLength": 64, "minLength": 1 }, "purpose": { "type": "ref", "ref": "#listPurpose" }, "description": { "type": "string", "maxGraphemes": 300, "maxLength": 3000 }, "descriptionFacets": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "avatar": { "type": "string", "format": "uri" }, "listItemCount": { "type": "integer", "minimum": 0 }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "viewer": { "type": "ref", "ref": "#listViewerState" }, "indexedAt": { "type": "string", "format": "datetime" } } }, "listItemView": { "type": "object", "required": ["uri", "subject"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "subject": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } }, "starterPackView": { "type": "object", "required": ["uri", "cid", "record", "creator", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "record": { "type": "unknown" }, "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic" }, "list": { "type": "ref", "ref": "#listViewBasic" }, "listItemsSample": { "type": "array", "maxLength": 12, "items": { "type": "ref", "ref": "#listItemView" } }, "feeds": { "type": "array", "maxLength": 3, "items": { "type": "ref", "ref": "app.bsky.feed.defs#generatorView" } }, "joinedWeekCount": { "type": "integer", "minimum": 0 }, "joinedAllTimeCount": { "type": "integer", "minimum": 0 }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "indexedAt": { "type": "string", "format": "datetime" } } }, "starterPackViewBasic": { "type": "object", "required": ["uri", "cid", "record", "creator", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "record": { "type": "unknown" }, "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic" }, "listItemCount": { "type": "integer", "minimum": 0 }, "joinedWeekCount": { "type": "integer", "minimum": 0 }, "joinedAllTimeCount": { "type": "integer", "minimum": 0 }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "indexedAt": { "type": "string", "format": "datetime" } } }, "listPurpose": { "type": "string", "knownValues": [ "app.bsky.graph.defs#modlist", "app.bsky.graph.defs#curatelist", "app.bsky.graph.defs#referencelist" ] }, "modlist": { "type": "token", "description": "A list of actors to apply an aggregate moderation action (mute/block) on." }, "curatelist": { "type": "token", "description": "A list of actors used for curation purposes such as list feeds or interaction gating." }, "referencelist": { "type": "token", "description": "A list of actors used for only for reference purposes such as within a starter pack." }, "listViewerState": { "type": "object", "properties": { "muted": { "type": "boolean" }, "blocked": { "type": "string", "format": "at-uri" } } }, "notFoundActor": { "type": "object", "description": "indicates that a handle or DID could not be resolved", "required": ["actor", "notFound"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "notFound": { "type": "boolean", "const": true } } }, "relationship": { "type": "object", "description": "lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" }, "following": { "type": "string", "format": "at-uri", "description": "if the actor follows this DID, this is the AT-URI of the follow record" }, "followedBy": { "type": "string", "format": "at-uri", "description": "if the actor is followed by this DID, contains the AT-URI of the follow record" }, "blocking": { "type": "string", "format": "at-uri", "description": "if the actor blocks this DID, this is the AT-URI of the block record" }, "blockedBy": { "type": "string", "format": "at-uri", "description": "if the actor is blocked by this DID, contains the AT-URI of the block record" }, "blockingByList": { "type": "string", "format": "at-uri", "description": "if the actor blocks this DID via a block list, this is the AT-URI of the listblock record" }, "blockedByList": { "type": "string", "format": "at-uri", "description": "if the actor is blocked by this DID via a block list, contains the AT-URI of the listblock record" } } } } } ================================================ FILE: lexicons/app/bsky/graph/follow.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.follow", "defs": { "main": { "type": "record", "description": "Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView.", "key": "tid", "record": { "type": "object", "required": ["subject", "createdAt"], "properties": { "subject": { "type": "string", "format": "did" }, "createdAt": { "type": "string", "format": "datetime" }, "via": { "type": "ref", "ref": "com.atproto.repo.strongRef" } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getActorStarterPacks.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getActorStarterPacks", "defs": { "main": { "type": "query", "description": "Get a list of starter packs created by the actor.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "cursor": { "type": "string" }, "starterPacks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackViewBasic" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getBlocks.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getBlocks", "defs": { "main": { "type": "query", "description": "Enumerates which accounts the requesting account is currently blocking. Requires auth.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["blocks"], "properties": { "cursor": { "type": "string" }, "blocks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getFollowers.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getFollowers", "defs": { "main": { "type": "query", "description": "Enumerates accounts which follow a specified account (actor).", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject", "followers"], "properties": { "subject": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "cursor": { "type": "string" }, "followers": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getFollows.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getFollows", "defs": { "main": { "type": "query", "description": "Enumerates accounts which a specified account (actor) follows.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject", "follows"], "properties": { "subject": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "cursor": { "type": "string" }, "follows": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getKnownFollowers.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getKnownFollowers", "defs": { "main": { "type": "query", "description": "Enumerates accounts which follow a specified account (actor) and are followed by the viewer.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject", "followers"], "properties": { "subject": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "cursor": { "type": "string" }, "followers": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getList.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getList", "defs": { "main": { "type": "query", "description": "Gets a 'view' (with additional context) of a specified list.", "parameters": { "type": "params", "required": ["list"], "properties": { "list": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) of the list record to hydrate." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["list", "items"], "properties": { "cursor": { "type": "string" }, "list": { "type": "ref", "ref": "app.bsky.graph.defs#listView" }, "items": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#listItemView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getListBlocks.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getListBlocks", "defs": { "main": { "type": "query", "description": "Get mod lists that the requesting account (actor) is blocking. Requires auth.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["lists"], "properties": { "cursor": { "type": "string" }, "lists": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#listView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getListMutes.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getListMutes", "defs": { "main": { "type": "query", "description": "Enumerates mod lists that the requesting account (actor) currently has muted. Requires auth.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["lists"], "properties": { "cursor": { "type": "string" }, "lists": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#listView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getLists.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getLists", "defs": { "main": { "type": "query", "description": "Enumerates the lists created by a specified account (actor).", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier", "description": "The account (actor) to enumerate lists from." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "purposes": { "type": "array", "description": "Optional filter by list purpose. If not specified, all supported types are returned.", "items": { "type": "string", "knownValues": ["modlist", "curatelist"] } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["lists"], "properties": { "cursor": { "type": "string" }, "lists": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#listView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getListsWithMembership.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getListsWithMembership", "defs": { "main": { "type": "query", "description": "Enumerates the lists created by the session user, and includes membership information about `actor` in those lists. Only supports curation and moderation lists (no reference lists, used in starter packs). Requires auth.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier", "description": "The account (actor) to check for membership." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "purposes": { "type": "array", "description": "Optional filter by list purpose. If not specified, all supported types are returned.", "items": { "type": "string", "knownValues": ["modlist", "curatelist"] } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["listsWithMembership"], "properties": { "cursor": { "type": "string" }, "listsWithMembership": { "type": "array", "items": { "type": "ref", "ref": "#listWithMembership" } } } } } }, "listWithMembership": { "description": "A list and an optional list item indicating membership of a target user to that list.", "type": "object", "required": ["list"], "properties": { "list": { "type": "ref", "ref": "app.bsky.graph.defs#listView" }, "listItem": { "type": "ref", "ref": "app.bsky.graph.defs#listItemView" } } } } } ================================================ FILE: lexicons/app/bsky/graph/getMutes.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getMutes", "defs": { "main": { "type": "query", "description": "Enumerates accounts that the requesting account (actor) currently has muted. Requires auth.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["mutes"], "properties": { "cursor": { "type": "string" }, "mutes": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getRelationships.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getRelationships", "defs": { "main": { "type": "query", "description": "Enumerates public relationships between one account, and a list of other accounts. Does not require auth.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier", "description": "Primary account requesting relationships for." }, "others": { "type": "array", "description": "List of 'other' accounts to be related back to the primary.", "maxLength": 30, "items": { "type": "string", "format": "at-identifier" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["relationships"], "properties": { "actor": { "type": "string", "format": "did" }, "relationships": { "type": "array", "items": { "type": "union", "refs": [ "app.bsky.graph.defs#relationship", "app.bsky.graph.defs#notFoundActor" ] } } } } }, "errors": [ { "name": "ActorNotFound", "description": "the primary actor at-identifier could not be resolved" } ] } } } ================================================ FILE: lexicons/app/bsky/graph/getStarterPack.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getStarterPack", "defs": { "main": { "type": "query", "description": "Gets a view of a starter pack.", "parameters": { "type": "params", "required": ["starterPack"], "properties": { "starterPack": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) of the starter pack record." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPack"], "properties": { "starterPack": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackView" } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getStarterPacks.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getStarterPacks", "defs": { "main": { "type": "query", "description": "Get views for a list of starter packs.", "parameters": { "type": "params", "required": ["uris"], "properties": { "uris": { "type": "array", "items": { "type": "string", "format": "at-uri" }, "maxLength": 25 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "starterPacks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackViewBasic" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/getStarterPacksWithMembership.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getStarterPacksWithMembership", "defs": { "main": { "type": "query", "description": "Enumerates the starter packs created by the session user, and includes membership information about `actor` in those starter packs. Requires auth.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier", "description": "The account (actor) to check for membership." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacksWithMembership"], "properties": { "cursor": { "type": "string" }, "starterPacksWithMembership": { "type": "array", "items": { "type": "ref", "ref": "#starterPackWithMembership" } } } } } }, "starterPackWithMembership": { "description": "A starter pack and an optional list item indicating membership of a target user to that starter pack.", "type": "object", "required": ["starterPack"], "properties": { "starterPack": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackView" }, "listItem": { "type": "ref", "ref": "app.bsky.graph.defs#listItemView" } } } } } ================================================ FILE: lexicons/app/bsky/graph/getSuggestedFollowsByActor.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.getSuggestedFollowsByActor", "defs": { "main": { "type": "query", "description": "Enumerates follows similar to a given account (actor). Expected use is to recommend additional accounts immediately after following one account.", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["suggestions"], "properties": { "suggestions": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } }, "recIdStr": { "type": "string", "description": "Snowflake for this recommendation, use when submitting recommendation events." }, "isFallback": { "type": "boolean", "description": "DEPRECATED, unused. Previously: if true, response has fallen-back to generic results, and is not scoped using relativeToDid", "default": false }, "recId": { "type": "integer", "description": "DEPRECATED: use recIdStr instead." } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/list.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.list", "defs": { "main": { "type": "record", "description": "Record representing a list of accounts (actors). Scope includes both moderation-oriented lists and curration-oriented lists.", "key": "tid", "record": { "type": "object", "required": ["name", "purpose", "createdAt"], "properties": { "purpose": { "type": "ref", "description": "Defines the purpose of the list (aka, moderation-oriented or curration-oriented)", "ref": "app.bsky.graph.defs#listPurpose" }, "name": { "type": "string", "maxLength": 64, "minLength": 1, "description": "Display name for list; can not be empty." }, "description": { "type": "string", "maxGraphemes": 300, "maxLength": 3000 }, "descriptionFacets": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "avatar": { "type": "blob", "accept": ["image/png", "image/jpeg"], "maxSize": 1000000 }, "labels": { "type": "union", "refs": ["com.atproto.label.defs#selfLabels"] }, "createdAt": { "type": "string", "format": "datetime" } } } } } } ================================================ FILE: lexicons/app/bsky/graph/listblock.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.listblock", "defs": { "main": { "type": "record", "description": "Record representing a block relationship against an entire an entire list of accounts (actors).", "key": "tid", "record": { "type": "object", "required": ["subject", "createdAt"], "properties": { "subject": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to the mod list record." }, "createdAt": { "type": "string", "format": "datetime" } } } } } } ================================================ FILE: lexicons/app/bsky/graph/listitem.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.listitem", "defs": { "main": { "type": "record", "description": "Record representing an account's inclusion on a specific list. The AppView will ignore duplicate listitem records.", "key": "tid", "record": { "type": "object", "required": ["subject", "list", "createdAt"], "properties": { "subject": { "type": "string", "format": "did", "description": "The account which is included on the list." }, "list": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to the list record (app.bsky.graph.list)." }, "createdAt": { "type": "string", "format": "datetime" } } } } } } ================================================ FILE: lexicons/app/bsky/graph/muteActor.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.muteActor", "defs": { "main": { "type": "procedure", "description": "Creates a mute relationship for the specified account. Mutes are private in Bluesky. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/muteActorList.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.muteActorList", "defs": { "main": { "type": "procedure", "description": "Creates a mute relationship for the specified list of accounts. Mutes are private in Bluesky. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["list"], "properties": { "list": { "type": "string", "format": "at-uri" } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/muteThread.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.muteThread", "defs": { "main": { "type": "procedure", "description": "Mutes a thread preventing notifications from the thread and any of its children. Mutes are private in Bluesky. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["root"], "properties": { "root": { "type": "string", "format": "at-uri" } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/searchStarterPacks.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.searchStarterPacks", "defs": { "main": { "type": "query", "description": "Find starter packs matching search criteria. Does not require auth.", "parameters": { "type": "params", "required": ["q"], "properties": { "q": { "type": "string", "description": "Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "cursor": { "type": "string" }, "starterPacks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackViewBasic" } } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/starterpack.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.starterpack", "defs": { "main": { "type": "record", "description": "Record defining a starter pack of actors and feeds for new users.", "key": "tid", "record": { "type": "object", "required": ["name", "list", "createdAt"], "properties": { "name": { "type": "string", "maxGraphemes": 50, "maxLength": 500, "minLength": 1, "description": "Display name for starter pack; can not be empty." }, "description": { "type": "string", "maxGraphemes": 300, "maxLength": 3000 }, "descriptionFacets": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "list": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to the list record." }, "feeds": { "type": "array", "maxLength": 3, "items": { "type": "ref", "ref": "#feedItem" } }, "createdAt": { "type": "string", "format": "datetime" } } } }, "feedItem": { "type": "object", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri" } } } } } ================================================ FILE: lexicons/app/bsky/graph/unmuteActor.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.unmuteActor", "defs": { "main": { "type": "procedure", "description": "Unmutes the specified account. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "at-identifier" } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/unmuteActorList.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.unmuteActorList", "defs": { "main": { "type": "procedure", "description": "Unmutes the specified list of accounts. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["list"], "properties": { "list": { "type": "string", "format": "at-uri" } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/unmuteThread.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.unmuteThread", "defs": { "main": { "type": "procedure", "description": "Unmutes the specified thread. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["root"], "properties": { "root": { "type": "string", "format": "at-uri" } } } } } } } ================================================ FILE: lexicons/app/bsky/graph/verification.json ================================================ { "lexicon": 1, "id": "app.bsky.graph.verification", "defs": { "main": { "type": "record", "description": "Record declaring a verification relationship between two accounts. Verifications are only considered valid by an app if issued by an account the app considers trusted.", "key": "tid", "record": { "type": "object", "required": ["subject", "handle", "displayName", "createdAt"], "properties": { "subject": { "description": "DID of the subject the verification applies to.", "type": "string", "format": "did" }, "handle": { "description": "Handle of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current handle matches the one at the time of verifying.", "type": "string", "format": "handle" }, "displayName": { "description": "Display name of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current displayName matches the one at the time of verifying.", "type": "string" }, "createdAt": { "description": "Date of when the verification was created.", "type": "string", "format": "datetime" } } } } } } ================================================ FILE: lexicons/app/bsky/labeler/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.labeler.defs", "defs": { "labelerView": { "type": "object", "required": ["uri", "cid", "creator", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "likeCount": { "type": "integer", "minimum": 0 }, "viewer": { "type": "ref", "ref": "#labelerViewerState" }, "indexedAt": { "type": "string", "format": "datetime" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } } } }, "labelerViewDetailed": { "type": "object", "required": ["uri", "cid", "creator", "policies", "indexedAt"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "policies": { "type": "ref", "ref": "app.bsky.labeler.defs#labelerPolicies" }, "likeCount": { "type": "integer", "minimum": 0 }, "viewer": { "type": "ref", "ref": "#labelerViewerState" }, "indexedAt": { "type": "string", "format": "datetime" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "reasonTypes": { "description": "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", "type": "array", "items": { "type": "ref", "ref": "com.atproto.moderation.defs#reasonType" } }, "subjectTypes": { "description": "The set of subject types (account, record, etc) this service accepts reports on.", "type": "array", "items": { "type": "ref", "ref": "com.atproto.moderation.defs#subjectType" } }, "subjectCollections": { "type": "array", "description": "Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.", "items": { "type": "string", "format": "nsid" } } } }, "labelerViewerState": { "type": "object", "properties": { "like": { "type": "string", "format": "at-uri" } } }, "labelerPolicies": { "type": "object", "required": ["labelValues"], "properties": { "labelValues": { "type": "array", "description": "The label values which this labeler publishes. May include global or custom labels.", "items": { "type": "ref", "ref": "com.atproto.label.defs#labelValue" } }, "labelValueDefinitions": { "type": "array", "description": "Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler.", "items": { "type": "ref", "ref": "com.atproto.label.defs#labelValueDefinition" } } } } } } ================================================ FILE: lexicons/app/bsky/labeler/getServices.json ================================================ { "lexicon": 1, "id": "app.bsky.labeler.getServices", "defs": { "main": { "type": "query", "description": "Get information about a list of labeler services.", "parameters": { "type": "params", "required": ["dids"], "properties": { "dids": { "type": "array", "items": { "type": "string", "format": "did" } }, "detailed": { "type": "boolean", "default": false } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["views"], "properties": { "views": { "type": "array", "items": { "type": "union", "refs": [ "app.bsky.labeler.defs#labelerView", "app.bsky.labeler.defs#labelerViewDetailed" ] } } } } } } } } ================================================ FILE: lexicons/app/bsky/labeler/service.json ================================================ { "lexicon": 1, "id": "app.bsky.labeler.service", "defs": { "main": { "type": "record", "description": "A declaration of the existence of labeler service.", "key": "literal:self", "record": { "type": "object", "required": ["policies", "createdAt"], "properties": { "policies": { "type": "ref", "ref": "app.bsky.labeler.defs#labelerPolicies" }, "labels": { "type": "union", "refs": ["com.atproto.label.defs#selfLabels"] }, "createdAt": { "type": "string", "format": "datetime" }, "reasonTypes": { "description": "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", "type": "array", "items": { "type": "ref", "ref": "com.atproto.moderation.defs#reasonType" } }, "subjectTypes": { "description": "The set of subject types (account, record, etc) this service accepts reports on.", "type": "array", "items": { "type": "ref", "ref": "com.atproto.moderation.defs#subjectType" } }, "subjectCollections": { "type": "array", "description": "Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.", "items": { "type": "string", "format": "nsid" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/declaration.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.declaration", "defs": { "main": { "type": "record", "description": "A declaration of the user's choices related to notifications that can be produced by them.", "key": "literal:self", "record": { "type": "object", "required": ["allowSubscriptions"], "properties": { "allowSubscriptions": { "type": "string", "description": "A declaration of the user's preference for allowing activity subscriptions from other users. Absence of a record implies 'followers'.", "knownValues": ["followers", "mutuals", "none"] } } } } } } ================================================ FILE: lexicons/app/bsky/notification/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.defs", "defs": { "recordDeleted": { "type": "object", "properties": {} }, "chatPreference": { "type": "object", "required": ["include", "push"], "properties": { "include": { "type": "string", "knownValues": ["all", "accepted"] }, "push": { "type": "boolean" } } }, "filterablePreference": { "type": "object", "required": ["include", "list", "push"], "properties": { "include": { "type": "string", "knownValues": ["all", "follows"] }, "list": { "type": "boolean" }, "push": { "type": "boolean" } } }, "preference": { "type": "object", "required": ["list", "push"], "properties": { "list": { "type": "boolean" }, "push": { "type": "boolean" } } }, "preferences": { "type": "object", "required": [ "chat", "follow", "like", "likeViaRepost", "mention", "quote", "reply", "repost", "repostViaRepost", "starterpackJoined", "subscribedPost", "unverified", "verified" ], "properties": { "chat": { "type": "ref", "ref": "#chatPreference" }, "follow": { "type": "ref", "ref": "#filterablePreference" }, "like": { "type": "ref", "ref": "#filterablePreference" }, "likeViaRepost": { "type": "ref", "ref": "#filterablePreference" }, "mention": { "type": "ref", "ref": "#filterablePreference" }, "quote": { "type": "ref", "ref": "#filterablePreference" }, "reply": { "type": "ref", "ref": "#filterablePreference" }, "repost": { "type": "ref", "ref": "#filterablePreference" }, "repostViaRepost": { "type": "ref", "ref": "#filterablePreference" }, "starterpackJoined": { "type": "ref", "ref": "#preference" }, "subscribedPost": { "type": "ref", "ref": "#preference" }, "unverified": { "type": "ref", "ref": "#preference" }, "verified": { "type": "ref", "ref": "#preference" } } }, "activitySubscription": { "type": "object", "required": ["post", "reply"], "properties": { "post": { "type": "boolean" }, "reply": { "type": "boolean" } } }, "subjectActivitySubscription": { "description": "Object used to store activity subscription data in stash.", "type": "object", "required": ["subject", "activitySubscription"], "properties": { "subject": { "type": "string", "format": "did" }, "activitySubscription": { "type": "ref", "ref": "#activitySubscription" } } } } } ================================================ FILE: lexicons/app/bsky/notification/getPreferences.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.getPreferences", "defs": { "main": { "type": "query", "description": "Get notification-related preferences for an account. Requires auth.", "parameters": { "type": "params", "properties": {} }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["preferences"], "properties": { "preferences": { "type": "ref", "ref": "app.bsky.notification.defs#preferences" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/getUnreadCount.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.getUnreadCount", "defs": { "main": { "type": "query", "description": "Count the number of unread notifications for the requesting account. Requires auth.", "parameters": { "type": "params", "properties": { "priority": { "type": "boolean" }, "seenAt": { "type": "string", "format": "datetime" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["count"], "properties": { "count": { "type": "integer" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/listActivitySubscriptions.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.listActivitySubscriptions", "defs": { "main": { "type": "query", "description": "Enumerate all accounts to which the requesting account is subscribed to receive notifications for. Requires auth.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subscriptions"], "properties": { "cursor": { "type": "string" }, "subscriptions": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/listNotifications.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.listNotifications", "defs": { "main": { "type": "query", "description": "Enumerate notifications for the requesting account. Requires auth.", "parameters": { "type": "params", "properties": { "reasons": { "description": "Notification reasons to include in response.", "type": "array", "items": { "type": "string", "description": "A reason that matches the reason property of #notification." } }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "priority": { "type": "boolean" }, "cursor": { "type": "string" }, "seenAt": { "type": "string", "format": "datetime" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["notifications"], "properties": { "cursor": { "type": "string" }, "notifications": { "type": "array", "items": { "type": "ref", "ref": "#notification" } }, "priority": { "type": "boolean" }, "seenAt": { "type": "string", "format": "datetime" } } } } }, "notification": { "type": "object", "required": [ "uri", "cid", "author", "reason", "record", "isRead", "indexedAt" ], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "author": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, "reason": { "type": "string", "description": "The reason why this notification was delivered - e.g. your post was liked, or you received a new follower.", "knownValues": [ "like", "repost", "follow", "mention", "reply", "quote", "starterpack-joined", "verified", "unverified", "like-via-repost", "repost-via-repost", "subscribed-post", "contact-match" ] }, "reasonSubject": { "type": "string", "format": "at-uri" }, "record": { "type": "unknown" }, "isRead": { "type": "boolean" }, "indexedAt": { "type": "string", "format": "datetime" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } } } } } } ================================================ FILE: lexicons/app/bsky/notification/putActivitySubscription.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.putActivitySubscription", "defs": { "main": { "type": "procedure", "description": "Puts an activity subscription entry. The key should be omitted for creation and provided for updates. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject", "activitySubscription"], "properties": { "subject": { "type": "string", "format": "did" }, "activitySubscription": { "type": "ref", "ref": "app.bsky.notification.defs#activitySubscription" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject"], "properties": { "subject": { "type": "string", "format": "did" }, "activitySubscription": { "type": "ref", "ref": "app.bsky.notification.defs#activitySubscription" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/putPreferences.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.putPreferences", "defs": { "main": { "type": "procedure", "description": "Set notification-related preferences for an account. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["priority"], "properties": { "priority": { "type": "boolean" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/putPreferencesV2.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.putPreferencesV2", "defs": { "main": { "type": "procedure", "description": "Set notification-related preferences for an account. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "chat": { "type": "ref", "ref": "app.bsky.notification.defs#chatPreference" }, "follow": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "like": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "likeViaRepost": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "mention": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "quote": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "reply": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "repost": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "repostViaRepost": { "type": "ref", "ref": "app.bsky.notification.defs#filterablePreference" }, "starterpackJoined": { "type": "ref", "ref": "app.bsky.notification.defs#preference" }, "subscribedPost": { "type": "ref", "ref": "app.bsky.notification.defs#preference" }, "unverified": { "type": "ref", "ref": "app.bsky.notification.defs#preference" }, "verified": { "type": "ref", "ref": "app.bsky.notification.defs#preference" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["preferences"], "properties": { "preferences": { "type": "ref", "ref": "app.bsky.notification.defs#preferences" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/registerPush.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.registerPush", "defs": { "main": { "type": "procedure", "description": "Register to receive push notifications, via a specified service, for the requesting account. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["serviceDid", "token", "platform", "appId"], "properties": { "serviceDid": { "type": "string", "format": "did" }, "token": { "type": "string" }, "platform": { "type": "string", "knownValues": ["ios", "android", "web"] }, "appId": { "type": "string" }, "ageRestricted": { "type": "boolean", "description": "Set to true when the actor is age restricted" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/unregisterPush.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.unregisterPush", "defs": { "main": { "type": "procedure", "description": "The inverse of registerPush - inform a specified service that push notifications should no longer be sent to the given token for the requesting account. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["serviceDid", "token", "platform", "appId"], "properties": { "serviceDid": { "type": "string", "format": "did" }, "token": { "type": "string" }, "platform": { "type": "string", "knownValues": ["ios", "android", "web"] }, "appId": { "type": "string" } } } } } } } ================================================ FILE: lexicons/app/bsky/notification/updateSeen.json ================================================ { "lexicon": 1, "id": "app.bsky.notification.updateSeen", "defs": { "main": { "type": "procedure", "description": "Notify server that the requesting account has seen notifications. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["seenAt"], "properties": { "seenAt": { "type": "string", "format": "datetime" } } } } } } } ================================================ FILE: lexicons/app/bsky/richtext/facet.json ================================================ { "lexicon": 1, "id": "app.bsky.richtext.facet", "defs": { "main": { "type": "object", "description": "Annotation of a sub-string within rich text.", "required": ["index", "features"], "properties": { "index": { "type": "ref", "ref": "#byteSlice" }, "features": { "type": "array", "items": { "type": "union", "refs": ["#mention", "#link", "#tag"] } } } }, "mention": { "type": "object", "description": "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "link": { "type": "object", "description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "uri" } } }, "tag": { "type": "object", "description": "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').", "required": ["tag"], "properties": { "tag": { "type": "string", "maxLength": 640, "maxGraphemes": 64 } } }, "byteSlice": { "type": "object", "description": "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.", "required": ["byteStart", "byteEnd"], "properties": { "byteStart": { "type": "integer", "minimum": 0 }, "byteEnd": { "type": "integer", "minimum": 0 } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.defs", "defs": { "skeletonSearchPost": { "type": "object", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri" } } }, "skeletonSearchActor": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "skeletonSearchStarterPack": { "type": "object", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri" } } }, "trendingTopic": { "type": "object", "required": ["topic", "link"], "properties": { "topic": { "type": "string" }, "displayName": { "type": "string" }, "description": { "type": "string" }, "link": { "type": "string" } } }, "skeletonTrend": { "type": "object", "required": [ "topic", "displayName", "link", "startedAt", "postCount", "dids" ], "properties": { "topic": { "type": "string" }, "displayName": { "type": "string" }, "link": { "type": "string" }, "startedAt": { "type": "string", "format": "datetime" }, "postCount": { "type": "integer" }, "status": { "type": "string", "knownValues": ["hot"] }, "category": { "type": "string" }, "dids": { "type": "array", "items": { "type": "string", "format": "did" } } } }, "trendView": { "type": "object", "required": [ "topic", "displayName", "link", "startedAt", "postCount", "actors" ], "properties": { "topic": { "type": "string" }, "displayName": { "type": "string" }, "link": { "type": "string" }, "startedAt": { "type": "string", "format": "datetime" }, "postCount": { "type": "integer" }, "status": { "type": "string", "knownValues": ["hot"] }, "category": { "type": "string" }, "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewBasic" } } } }, "threadItemPost": { "type": "object", "required": [ "post", "moreParents", "moreReplies", "opThread", "hiddenByThreadgate", "mutedByViewer" ], "properties": { "post": { "type": "ref", "ref": "app.bsky.feed.defs#postView" }, "moreParents": { "type": "boolean", "description": "This post has more parents that were not present in the response. This is just a boolean, without the number of parents." }, "moreReplies": { "type": "integer", "description": "This post has more replies that were not present in the response. This is a numeric value, which is best-effort and might not be accurate." }, "opThread": { "type": "boolean", "description": "This post is part of a contiguous thread by the OP from the thread root. Many different OP threads can happen in the same thread." }, "hiddenByThreadgate": { "type": "boolean", "description": "The threadgate created by the author indicates this post as a reply to be hidden for everyone consuming the thread." }, "mutedByViewer": { "type": "boolean", "description": "This is by an account muted by the viewer requesting it." } } }, "threadItemNoUnauthenticated": { "type": "object", "properties": {} }, "threadItemNotFound": { "type": "object", "properties": {} }, "threadItemBlocked": { "type": "object", "required": ["author"], "properties": { "author": { "type": "ref", "ref": "app.bsky.feed.defs#blockedAuthor" } } }, "ageAssuranceState": { "type": "object", "description": "The computed state of the age assurance process, returned to the user in question on certain authenticated requests.", "required": ["status"], "properties": { "lastInitiatedAt": { "type": "string", "format": "datetime", "description": "The timestamp when this state was last updated." }, "status": { "type": "string", "description": "The status of the age assurance process.", "knownValues": ["unknown", "pending", "assured", "blocked"] } } }, "ageAssuranceEvent": { "type": "object", "description": "Object used to store age assurance data in stash.", "required": ["createdAt", "status", "attemptId"], "properties": { "createdAt": { "type": "string", "format": "datetime", "description": "The date and time of this write operation." }, "status": { "type": "string", "description": "The status of the age assurance process.", "knownValues": ["unknown", "pending", "assured"] }, "attemptId": { "type": "string", "description": "The unique identifier for this instance of the age assurance flow, in UUID format." }, "email": { "type": "string", "description": "The email used for AA." }, "initIp": { "type": "string", "description": "The IP address used when initiating the AA flow." }, "initUa": { "type": "string", "description": "The user agent used when initiating the AA flow." }, "completeIp": { "type": "string", "description": "The IP address used when completing the AA flow." }, "completeUa": { "type": "string", "description": "The user agent used when completing the AA flow." } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getAgeAssuranceState.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getAgeAssuranceState", "defs": { "main": { "type": "query", "description": "Returns the current state of the age assurance process for an account. This is used to check if the user has completed age assurance or if further action is required.", "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "app.bsky.unspecced.defs#ageAssuranceState" } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getConfig.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getConfig", "defs": { "main": { "type": "query", "description": "Get miscellaneous runtime configuration.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": [], "properties": { "checkEmailConfirmed": { "type": "boolean" }, "liveNow": { "type": "array", "items": { "type": "ref", "ref": "#liveNowConfig" } } } } } }, "liveNowConfig": { "type": "object", "required": ["did", "domains"], "properties": { "did": { "type": "string", "format": "did" }, "domains": { "type": "array", "items": { "type": "string" } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getOnboardingSuggestedStarterPacks", "defs": { "main": { "type": "query", "description": "Get a list of suggested starterpacks for onboarding", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "starterPacks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton", "defs": { "main": { "type": "query", "description": "Get a skeleton of suggested starterpacks for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getOnboardingSuggestedStarterPacks", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries)." }, "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "starterPacks": { "type": "array", "items": { "type": "string", "format": "at-uri" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton", "defs": { "main": { "type": "query", "description": "Get a skeleton of suggested users for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedOnboardingUsers", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries)." }, "category": { "type": "string", "description": "Category of users to get suggestions for." }, "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 25 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["dids"], "properties": { "dids": { "type": "array", "items": { "type": "string", "format": "did" } }, "recId": { "type": "string", "description": "DEPRECATED: use recIdStr instead." }, "recIdStr": { "type": "string", "description": "Snowflake for this recommendation, use when submitting recommendation events." } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getPopularFeedGenerators.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getPopularFeedGenerators", "defs": { "main": { "type": "query", "description": "An unspecced view of globally popular feed generators.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "query": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feeds"], "properties": { "cursor": { "type": "string" }, "feeds": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#generatorView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getPostThreadOtherV2.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getPostThreadOtherV2", "defs": { "main": { "type": "query", "description": "(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get additional posts under a thread e.g. replies hidden by threadgate. Based on an anchor post at any depth of the tree, returns top-level replies below that anchor. It does not include ancestors nor the anchor itself. This should be called after exhausting `app.bsky.unspecced.getPostThreadV2`. Does not require auth, but additional metadata and filtering will be applied for authed requests.", "parameters": { "type": "params", "required": ["anchor"], "properties": { "anchor": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to post record. This is the anchor post." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["thread"], "properties": { "thread": { "type": "array", "description": "A flat list of other thread items. The depth of each item is indicated by the depth property inside the item.", "items": { "type": "ref", "ref": "#threadItem" } } } } } }, "threadItem": { "type": "object", "required": ["uri", "depth", "value"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "depth": { "type": "integer", "description": "The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths." }, "value": { "type": "union", "refs": ["app.bsky.unspecced.defs#threadItemPost"] } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getPostThreadV2.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getPostThreadV2", "defs": { "main": { "type": "query", "description": "(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get posts in a thread. It is based in an anchor post at any depth of the tree, and returns posts above it (recursively resolving the parent, without further branching to their replies) and below it (recursive replies, with branching to their replies). Does not require auth, but additional metadata and filtering will be applied for authed requests.", "parameters": { "type": "params", "required": ["anchor"], "properties": { "anchor": { "type": "string", "format": "at-uri", "description": "Reference (AT-URI) to post record. This is the anchor post, and the thread will be built around it. It can be any post in the tree, not necessarily a root post." }, "above": { "type": "boolean", "description": "Whether to include parents above the anchor.", "default": true }, "below": { "type": "integer", "description": "How many levels of replies to include below the anchor.", "default": 6, "minimum": 0, "maximum": 20 }, "branchingFactor": { "type": "integer", "description": "Maximum of replies to include at each level of the thread, except for the direct replies to the anchor, which are (NOTE: currently, during unspecced phase) all returned (NOTE: later they might be paginated).", "default": 10, "minimum": 0, "maximum": 100 }, "sort": { "type": "string", "description": "Sorting for the thread replies.", "knownValues": ["newest", "oldest", "top"], "default": "oldest" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["thread", "hasOtherReplies"], "properties": { "thread": { "type": "array", "description": "A flat list of thread items. The depth of each item is indicated by the depth property inside the item.", "items": { "type": "ref", "ref": "#threadItem" } }, "threadgate": { "type": "ref", "ref": "app.bsky.feed.defs#threadgateView" }, "hasOtherReplies": { "type": "boolean", "description": "Whether this thread has additional replies. If true, a call can be made to the `getPostThreadOtherV2` endpoint to retrieve them." } } } } }, "threadItem": { "type": "object", "required": ["uri", "depth", "value"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "depth": { "type": "integer", "description": "The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths." }, "value": { "type": "union", "refs": [ "app.bsky.unspecced.defs#threadItemPost", "app.bsky.unspecced.defs#threadItemNoUnauthenticated", "app.bsky.unspecced.defs#threadItemNotFound", "app.bsky.unspecced.defs#threadItemBlocked" ] } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestedFeeds.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestedFeeds", "defs": { "main": { "type": "query", "description": "Get a list of suggested feeds", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feeds"], "properties": { "feeds": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.feed.defs#generatorView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestedFeedsSkeleton", "defs": { "main": { "type": "query", "description": "Get a skeleton of suggested feeds. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedFeeds", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries)." }, "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["feeds"], "properties": { "feeds": { "type": "array", "items": { "type": "string", "format": "at-uri" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestedOnboardingUsers.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestedOnboardingUsers", "defs": { "main": { "type": "query", "description": "Get a list of suggested users for onboarding", "parameters": { "type": "params", "properties": { "category": { "type": "string", "description": "Category of users to get suggestions for." }, "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 25 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actors"], "properties": { "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } }, "recId": { "type": "string", "description": "DEPRECATED: use recIdStr instead." }, "recIdStr": { "type": "string", "description": "Snowflake for this recommendation, use when submitting recommendation events." } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestedStarterPacks.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestedStarterPacks", "defs": { "main": { "type": "query", "description": "Get a list of suggested starterpacks", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "starterPacks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.graph.defs#starterPackView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestedStarterPacksSkeleton", "defs": { "main": { "type": "query", "description": "Get a skeleton of suggested starterpacks. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedStarterpacks", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries)." }, "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "starterPacks": { "type": "array", "items": { "type": "string", "format": "at-uri" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestedUsers.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestedUsers", "defs": { "main": { "type": "query", "description": "Get a list of suggested users", "parameters": { "type": "params", "properties": { "category": { "type": "string", "description": "Category of users to get suggestions for." }, "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 25 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actors"], "properties": { "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" } }, "recId": { "type": "string", "description": "DEPRECATED: use recIdStr instead." }, "recIdStr": { "type": "string", "description": "Snowflake for this recommendation, use when submitting recommendation events." } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestedUsersSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestedUsersSkeleton", "defs": { "main": { "type": "query", "description": "Get a skeleton of suggested users. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedUsers", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries)." }, "category": { "type": "string", "description": "Category of users to get suggestions for." }, "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 25 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["dids"], "properties": { "dids": { "type": "array", "items": { "type": "string", "format": "did" } }, "recId": { "type": "string", "description": "DEPRECATED: use recIdStr instead." }, "recIdStr": { "type": "string", "description": "Snowflake for this recommendation, use when submitting recommendation events." } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getSuggestionsSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getSuggestionsSkeleton", "defs": { "main": { "type": "query", "description": "Get a skeleton of suggested actors. Intended to be called and then hydrated through app.bsky.actor.getSuggestions", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "relativeToDid": { "type": "string", "format": "did", "description": "DID of the account to get suggestions relative to. If not provided, suggestions will be based on the viewer." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actors"], "properties": { "cursor": { "type": "string" }, "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#skeletonSearchActor" } }, "relativeToDid": { "type": "string", "format": "did", "description": "DID of the account these suggestions are relative to. If this is returned undefined, suggestions are based on the viewer." }, "recId": { "type": "integer", "description": "DEPRECATED: use recIdStr instead." }, "recIdStr": { "type": "string", "description": "Snowflake for this recommendation, use when submitting recommendation events." } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getTaggedSuggestions.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getTaggedSuggestions", "defs": { "main": { "type": "query", "description": "Get a list of suggestions (feeds and users) tagged with categories", "parameters": { "type": "params", "properties": {} }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["suggestions"], "properties": { "suggestions": { "type": "array", "items": { "type": "ref", "ref": "#suggestion" } } } } } }, "suggestion": { "type": "object", "required": ["tag", "subjectType", "subject"], "properties": { "tag": { "type": "string" }, "subjectType": { "type": "string", "knownValues": ["actor", "feed"] }, "subject": { "type": "string", "format": "uri" } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getTrendingTopics.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getTrendingTopics", "defs": { "main": { "type": "query", "description": "Get a list of trending topics", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking." }, "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["topics", "suggested"], "properties": { "topics": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#trendingTopic" } }, "suggested": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#trendingTopic" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getTrends.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getTrends", "defs": { "main": { "type": "query", "description": "Get the current trends on the network", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["trends"], "properties": { "trends": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#trendView" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/getTrendsSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.getTrendsSkeleton", "defs": { "main": { "type": "query", "description": "Get the skeleton of trends on the network. Intended to be called and then hydrated through app.bsky.unspecced.getTrends", "parameters": { "type": "params", "properties": { "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries)." }, "limit": { "type": "integer", "minimum": 1, "maximum": 25, "default": 10 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["trends"], "properties": { "trends": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#skeletonTrend" } } } } } } } } ================================================ FILE: lexicons/app/bsky/unspecced/initAgeAssurance.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.initAgeAssurance", "defs": { "main": { "type": "procedure", "description": "Initiate age assurance for an account. This is a one-time action that will start the process of verifying the user's age.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["email", "language", "countryCode"], "properties": { "email": { "type": "string", "description": "The user's email address to receive assurance instructions." }, "language": { "type": "string", "description": "The user's preferred language for communication during the assurance process." }, "countryCode": { "type": "string", "description": "An ISO 3166-1 alpha-2 code of the user's location." } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "app.bsky.unspecced.defs#ageAssuranceState" } }, "errors": [ { "name": "InvalidEmail" }, { "name": "DidTooLong" }, { "name": "InvalidInitiation" } ] } } } ================================================ FILE: lexicons/app/bsky/unspecced/searchActorsSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.searchActorsSkeleton", "defs": { "main": { "type": "query", "description": "Backend Actors (profile) search, returns only skeleton.", "parameters": { "type": "params", "required": ["q"], "properties": { "q": { "type": "string", "description": "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. For typeahead search, only simple term match is supported, not full syntax." }, "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking." }, "typeahead": { "type": "boolean", "description": "If true, acts as fast/simple 'typeahead' query." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }, "cursor": { "type": "string", "description": "Optional pagination mechanism; may not necessarily allow scrolling through entire result set." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actors"], "properties": { "cursor": { "type": "string" }, "hitsTotal": { "type": "integer", "description": "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits." }, "actors": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#skeletonSearchActor" } } } } }, "errors": [{ "name": "BadQueryString" }] } } } ================================================ FILE: lexicons/app/bsky/unspecced/searchPostsSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.searchPostsSkeleton", "defs": { "main": { "type": "query", "description": "Backend Posts search, returns only skeleton", "parameters": { "type": "params", "required": ["q"], "properties": { "q": { "type": "string", "description": "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended." }, "sort": { "type": "string", "knownValues": ["top", "latest"], "default": "latest", "description": "Specifies the ranking order of results." }, "since": { "type": "string", "description": "Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD)." }, "until": { "type": "string", "description": "Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD)." }, "mentions": { "type": "string", "format": "at-identifier", "description": "Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions." }, "author": { "type": "string", "format": "at-identifier", "description": "Filter to posts by the given account. Handles are resolved to DID before query-time." }, "lang": { "type": "string", "format": "language", "description": "Filter to posts in the given language. Expected to be based on post language field, though server may override language detection." }, "domain": { "type": "string", "description": "Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization." }, "url": { "type": "string", "format": "uri", "description": "Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching." }, "tag": { "type": "array", "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 }, "description": "Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching." }, "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries). Used for 'from:me' queries." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }, "cursor": { "type": "string", "description": "Optional pagination mechanism; may not necessarily allow scrolling through entire result set." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["posts"], "properties": { "cursor": { "type": "string" }, "hitsTotal": { "type": "integer", "description": "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits." }, "posts": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#skeletonSearchPost" } } } } }, "errors": [{ "name": "BadQueryString" }] } } } ================================================ FILE: lexicons/app/bsky/unspecced/searchStarterPacksSkeleton.json ================================================ { "lexicon": 1, "id": "app.bsky.unspecced.searchStarterPacksSkeleton", "defs": { "main": { "type": "query", "description": "Backend Starter Pack search, returns only skeleton.", "parameters": { "type": "params", "required": ["q"], "properties": { "q": { "type": "string", "description": "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended." }, "viewer": { "type": "string", "format": "did", "description": "DID of the account making the request (not included for public/unauthenticated queries)." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }, "cursor": { "type": "string", "description": "Optional pagination mechanism; may not necessarily allow scrolling through entire result set." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["starterPacks"], "properties": { "cursor": { "type": "string" }, "hitsTotal": { "type": "integer", "description": "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits." }, "starterPacks": { "type": "array", "items": { "type": "ref", "ref": "app.bsky.unspecced.defs#skeletonSearchStarterPack" } } } } }, "errors": [ { "name": "BadQueryString" } ] } } } ================================================ FILE: lexicons/app/bsky/video/defs.json ================================================ { "lexicon": 1, "id": "app.bsky.video.defs", "defs": { "jobStatus": { "type": "object", "required": ["jobId", "did", "state"], "properties": { "jobId": { "type": "string" }, "did": { "type": "string", "format": "did" }, "state": { "type": "string", "description": "The state of the video processing job. All values not listed as a known value indicate that the job is in process.", "knownValues": ["JOB_STATE_COMPLETED", "JOB_STATE_FAILED"] }, "progress": { "type": "integer", "minimum": 0, "maximum": 100, "description": "Progress within the current processing state." }, "blob": { "type": "blob" }, "error": { "type": "string" }, "message": { "type": "string" } } } } } ================================================ FILE: lexicons/app/bsky/video/getJobStatus.json ================================================ { "lexicon": 1, "id": "app.bsky.video.getJobStatus", "defs": { "main": { "type": "query", "description": "Get status details for a video processing job.", "parameters": { "type": "params", "required": ["jobId"], "properties": { "jobId": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["jobStatus"], "properties": { "jobStatus": { "type": "ref", "ref": "app.bsky.video.defs#jobStatus" } } } } } } } ================================================ FILE: lexicons/app/bsky/video/getUploadLimits.json ================================================ { "lexicon": 1, "id": "app.bsky.video.getUploadLimits", "defs": { "main": { "type": "query", "description": "Get video upload limits for the authenticated user.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["canUpload"], "properties": { "canUpload": { "type": "boolean" }, "remainingDailyVideos": { "type": "integer" }, "remainingDailyBytes": { "type": "integer" }, "message": { "type": "string" }, "error": { "type": "string" } } } } } } } ================================================ FILE: lexicons/app/bsky/video/uploadVideo.json ================================================ { "lexicon": 1, "id": "app.bsky.video.uploadVideo", "defs": { "main": { "type": "procedure", "description": "Upload a video to be processed then stored on the PDS.", "input": { "encoding": "video/mp4" }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["jobStatus"], "properties": { "jobStatus": { "type": "ref", "ref": "app.bsky.video.defs#jobStatus" } } } } } } } ================================================ FILE: lexicons/chat/bsky/actor/declaration.json ================================================ { "lexicon": 1, "id": "chat.bsky.actor.declaration", "defs": { "main": { "type": "record", "description": "A declaration of a Bluesky chat account.", "key": "literal:self", "record": { "type": "object", "required": ["allowIncoming"], "properties": { "allowIncoming": { "type": "string", "knownValues": ["all", "none", "following"] } } } } } } ================================================ FILE: lexicons/chat/bsky/actor/defs.json ================================================ { "lexicon": 1, "id": "chat.bsky.actor.defs", "defs": { "profileViewBasic": { "type": "object", "required": ["did", "handle"], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" }, "displayName": { "type": "string", "maxGraphemes": 64, "maxLength": 640 }, "avatar": { "type": "string", "format": "uri" }, "associated": { "type": "ref", "ref": "app.bsky.actor.defs#profileAssociated" }, "viewer": { "type": "ref", "ref": "app.bsky.actor.defs#viewerState" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "chatDisabled": { "type": "boolean", "description": "Set to true when the actor cannot actively participate in conversations" }, "verification": { "type": "ref", "ref": "app.bsky.actor.defs#verificationState" } } } } } ================================================ FILE: lexicons/chat/bsky/actor/deleteAccount.json ================================================ { "lexicon": 1, "id": "chat.bsky.actor.deleteAccount", "defs": { "main": { "type": "procedure", "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } } } } ================================================ FILE: lexicons/chat/bsky/actor/exportAccountData.json ================================================ { "lexicon": 1, "id": "chat.bsky.actor.exportAccountData", "defs": { "main": { "type": "query", "output": { "encoding": "application/jsonl" } } } } ================================================ FILE: lexicons/chat/bsky/authFullChatClient.json ================================================ { "lexicon": 1, "id": "chat.bsky.authFullChatClient", "defs": { "main": { "type": "permission-set", "title": "Full Chat Client (All Conversations)", "title:lang": {}, "detail": "Control of all chat conversations and configuration management.", "detail:lang": { "en": "All Chat Conversations" }, "permissions": [ { "type": "permission", "resource": "rpc", "inheritAud": true, "lxm": [ "chat.bsky.actor.deleteAccount", "chat.bsky.actor.exportAccountData", "chat.bsky.convo.acceptConvo", "chat.bsky.convo.addReaction", "chat.bsky.convo.deleteMessageForSelf", "chat.bsky.convo.getConvo", "chat.bsky.convo.getConvoAvailability", "chat.bsky.convo.getConvoForMembers", "chat.bsky.convo.getLog", "chat.bsky.convo.getMessages", "chat.bsky.convo.leaveConvo", "chat.bsky.convo.listConvos", "chat.bsky.convo.muteConvo", "chat.bsky.convo.removeReaction", "chat.bsky.convo.sendMessage", "chat.bsky.convo.sendMessageBatch", "chat.bsky.convo.unmuteConvo", "chat.bsky.convo.updateAllRead", "chat.bsky.convo.updateRead" ] }, { "type": "permission", "resource": "repo", "action": ["create", "update", "delete"], "collection": ["chat.bsky.actor.declaration"] } ] } } } ================================================ FILE: lexicons/chat/bsky/convo/acceptConvo.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.acceptConvo", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId"], "properties": { "convoId": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": { "rev": { "description": "Rev when the convo was accepted. If not present, the convo was already accepted.", "type": "string" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/addReaction.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.addReaction", "defs": { "main": { "type": "procedure", "description": "Adds an emoji reaction to a message. Requires authentication. It is idempotent, so multiple calls from the same user with the same emoji result in a single reaction.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId", "messageId", "value"], "properties": { "convoId": { "type": "string" }, "messageId": { "type": "string" }, "value": { "type": "string", "minLength": 1, "maxLength": 64, "minGraphemes": 1, "maxGraphemes": 1 } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["message"], "properties": { "message": { "type": "ref", "ref": "chat.bsky.convo.defs#messageView" } } } }, "errors": [ { "name": "ReactionMessageDeleted", "description": "Indicates that the message has been deleted and reactions can no longer be added/removed." }, { "name": "ReactionLimitReached", "description": "Indicates that the message has the maximum number of reactions allowed for a single user, and the requested reaction wasn't yet present. If it was already present, the request will not fail since it is idempotent." }, { "name": "ReactionInvalidValue", "description": "Indicates the value for the reaction is not acceptable. In general, this means it is not an emoji." } ] } } } ================================================ FILE: lexicons/chat/bsky/convo/defs.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.defs", "defs": { "messageRef": { "type": "object", "required": ["did", "messageId", "convoId"], "properties": { "did": { "type": "string", "format": "did" }, "convoId": { "type": "string" }, "messageId": { "type": "string" } } }, "messageInput": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string", "maxLength": 10000, "maxGraphemes": 1000 }, "facets": { "type": "array", "description": "Annotations of text (mentions, URLs, hashtags, etc)", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "embed": { "type": "union", "refs": ["app.bsky.embed.record"] } } }, "messageView": { "type": "object", "required": ["id", "rev", "text", "sender", "sentAt"], "properties": { "id": { "type": "string" }, "rev": { "type": "string" }, "text": { "type": "string", "maxLength": 10000, "maxGraphemes": 1000 }, "facets": { "type": "array", "description": "Annotations of text (mentions, URLs, hashtags, etc)", "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } }, "embed": { "type": "union", "refs": ["app.bsky.embed.record#view"] }, "reactions": { "type": "array", "description": "Reactions to this message, in ascending order of creation time.", "items": { "type": "ref", "ref": "#reactionView" } }, "sender": { "type": "ref", "ref": "#messageViewSender" }, "sentAt": { "type": "string", "format": "datetime" } } }, "deletedMessageView": { "type": "object", "required": ["id", "rev", "sender", "sentAt"], "properties": { "id": { "type": "string" }, "rev": { "type": "string" }, "sender": { "type": "ref", "ref": "#messageViewSender" }, "sentAt": { "type": "string", "format": "datetime" } } }, "messageViewSender": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "reactionView": { "type": "object", "required": ["value", "sender", "createdAt"], "properties": { "value": { "type": "string" }, "sender": { "type": "ref", "ref": "#reactionViewSender" }, "createdAt": { "type": "string", "format": "datetime" } } }, "reactionViewSender": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "messageAndReactionView": { "type": "object", "required": ["message", "reaction"], "properties": { "message": { "type": "ref", "ref": "#messageView" }, "reaction": { "type": "ref", "ref": "#reactionView" } } }, "convoView": { "type": "object", "required": ["id", "rev", "members", "muted", "unreadCount"], "properties": { "id": { "type": "string" }, "rev": { "type": "string" }, "members": { "type": "array", "items": { "type": "ref", "ref": "chat.bsky.actor.defs#profileViewBasic" } }, "lastMessage": { "type": "union", "refs": ["#messageView", "#deletedMessageView"] }, "lastReaction": { "type": "union", "refs": ["#messageAndReactionView"] }, "muted": { "type": "boolean" }, "status": { "type": "string", "knownValues": ["request", "accepted"] }, "unreadCount": { "type": "integer" } } }, "logBeginConvo": { "type": "object", "required": ["rev", "convoId"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" } } }, "logAcceptConvo": { "type": "object", "required": ["rev", "convoId"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" } } }, "logLeaveConvo": { "type": "object", "required": ["rev", "convoId"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" } } }, "logMuteConvo": { "type": "object", "required": ["rev", "convoId"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" } } }, "logUnmuteConvo": { "type": "object", "required": ["rev", "convoId"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" } } }, "logCreateMessage": { "type": "object", "required": ["rev", "convoId", "message"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" }, "message": { "type": "union", "refs": ["#messageView", "#deletedMessageView"] } } }, "logDeleteMessage": { "type": "object", "required": ["rev", "convoId", "message"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" }, "message": { "type": "union", "refs": ["#messageView", "#deletedMessageView"] } } }, "logReadMessage": { "type": "object", "required": ["rev", "convoId", "message"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" }, "message": { "type": "union", "refs": ["#messageView", "#deletedMessageView"] } } }, "logAddReaction": { "type": "object", "required": ["rev", "convoId", "message", "reaction"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" }, "message": { "type": "union", "refs": ["#messageView", "#deletedMessageView"] }, "reaction": { "type": "ref", "ref": "#reactionView" } } }, "logRemoveReaction": { "type": "object", "required": ["rev", "convoId", "message", "reaction"], "properties": { "rev": { "type": "string" }, "convoId": { "type": "string" }, "message": { "type": "union", "refs": ["#messageView", "#deletedMessageView"] }, "reaction": { "type": "ref", "ref": "#reactionView" } } } } } ================================================ FILE: lexicons/chat/bsky/convo/deleteMessageForSelf.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.deleteMessageForSelf", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId", "messageId"], "properties": { "convoId": { "type": "string" }, "messageId": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "chat.bsky.convo.defs#deletedMessageView" } } } } } ================================================ FILE: lexicons/chat/bsky/convo/getConvo.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.getConvo", "defs": { "main": { "type": "query", "parameters": { "type": "params", "required": ["convoId"], "properties": { "convoId": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["convo"], "properties": { "convo": { "type": "ref", "ref": "chat.bsky.convo.defs#convoView" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/getConvoAvailability.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.getConvoAvailability", "defs": { "main": { "type": "query", "description": "Get whether the requester and the other members can chat. If an existing convo is found for these members, it is returned.", "parameters": { "type": "params", "required": ["members"], "properties": { "members": { "type": "array", "minLength": 1, "maxLength": 10, "items": { "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["canChat"], "properties": { "canChat": { "type": "boolean" }, "convo": { "type": "ref", "ref": "chat.bsky.convo.defs#convoView" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/getConvoForMembers.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.getConvoForMembers", "defs": { "main": { "type": "query", "parameters": { "type": "params", "required": ["members"], "properties": { "members": { "type": "array", "minLength": 1, "maxLength": 10, "items": { "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["convo"], "properties": { "convo": { "type": "ref", "ref": "chat.bsky.convo.defs#convoView" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/getLog.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.getLog", "defs": { "main": { "type": "query", "parameters": { "type": "params", "required": [], "properties": { "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["logs"], "properties": { "cursor": { "type": "string" }, "logs": { "type": "array", "items": { "type": "union", "refs": [ "chat.bsky.convo.defs#logBeginConvo", "chat.bsky.convo.defs#logAcceptConvo", "chat.bsky.convo.defs#logLeaveConvo", "chat.bsky.convo.defs#logMuteConvo", "chat.bsky.convo.defs#logUnmuteConvo", "chat.bsky.convo.defs#logCreateMessage", "chat.bsky.convo.defs#logDeleteMessage", "chat.bsky.convo.defs#logReadMessage", "chat.bsky.convo.defs#logAddReaction", "chat.bsky.convo.defs#logRemoveReaction" ] } } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/getMessages.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.getMessages", "defs": { "main": { "type": "query", "parameters": { "type": "params", "required": ["convoId"], "properties": { "convoId": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["messages"], "properties": { "cursor": { "type": "string" }, "messages": { "type": "array", "items": { "type": "union", "refs": [ "chat.bsky.convo.defs#messageView", "chat.bsky.convo.defs#deletedMessageView" ] } } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/leaveConvo.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.leaveConvo", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId"], "properties": { "convoId": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId", "rev"], "properties": { "convoId": { "type": "string" }, "rev": { "type": "string" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/listConvos.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.listConvos", "defs": { "main": { "type": "query", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "readState": { "type": "string", "knownValues": ["unread"] }, "status": { "type": "string", "knownValues": ["request", "accepted"] } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["convos"], "properties": { "cursor": { "type": "string" }, "convos": { "type": "array", "items": { "type": "ref", "ref": "chat.bsky.convo.defs#convoView" } } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/muteConvo.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.muteConvo", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId"], "properties": { "convoId": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["convo"], "properties": { "convo": { "type": "ref", "ref": "chat.bsky.convo.defs#convoView" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/removeReaction.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.removeReaction", "defs": { "main": { "type": "procedure", "description": "Removes an emoji reaction from a message. Requires authentication. It is idempotent, so multiple calls from the same user with the same emoji result in that reaction not being present, even if it already wasn't.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId", "messageId", "value"], "properties": { "convoId": { "type": "string" }, "messageId": { "type": "string" }, "value": { "type": "string", "minLength": 1, "maxLength": 64, "minGraphemes": 1, "maxGraphemes": 1 } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["message"], "properties": { "message": { "type": "ref", "ref": "chat.bsky.convo.defs#messageView" } } } }, "errors": [ { "name": "ReactionMessageDeleted", "description": "Indicates that the message has been deleted and reactions can no longer be added/removed." }, { "name": "ReactionInvalidValue", "description": "Indicates the value for the reaction is not acceptable. In general, this means it is not an emoji." } ] } } } ================================================ FILE: lexicons/chat/bsky/convo/sendMessage.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.sendMessage", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId", "message"], "properties": { "convoId": { "type": "string" }, "message": { "type": "ref", "ref": "chat.bsky.convo.defs#messageInput" } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "chat.bsky.convo.defs#messageView" } } } } } ================================================ FILE: lexicons/chat/bsky/convo/sendMessageBatch.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.sendMessageBatch", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "maxLength": 100, "items": { "type": "ref", "ref": "#batchItem" } } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "items": { "type": "ref", "ref": "chat.bsky.convo.defs#messageView" } } } } } }, "batchItem": { "type": "object", "required": ["convoId", "message"], "properties": { "convoId": { "type": "string" }, "message": { "type": "ref", "ref": "chat.bsky.convo.defs#messageInput" } } } } } ================================================ FILE: lexicons/chat/bsky/convo/unmuteConvo.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.unmuteConvo", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId"], "properties": { "convoId": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["convo"], "properties": { "convo": { "type": "ref", "ref": "chat.bsky.convo.defs#convoView" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/updateAllRead.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.updateAllRead", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "status": { "type": "string", "knownValues": ["request", "accepted"] } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["updatedCount"], "properties": { "updatedCount": { "description": "The count of updated convos.", "type": "integer" } } } } } } } ================================================ FILE: lexicons/chat/bsky/convo/updateRead.json ================================================ { "lexicon": 1, "id": "chat.bsky.convo.updateRead", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["convoId"], "properties": { "convoId": { "type": "string" }, "messageId": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["convo"], "properties": { "convo": { "type": "ref", "ref": "chat.bsky.convo.defs#convoView" } } } } } } } ================================================ FILE: lexicons/chat/bsky/moderation/getActorMetadata.json ================================================ { "lexicon": 1, "id": "chat.bsky.moderation.getActorMetadata", "defs": { "main": { "type": "query", "parameters": { "type": "params", "required": ["actor"], "properties": { "actor": { "type": "string", "format": "did" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["day", "month", "all"], "properties": { "day": { "type": "ref", "ref": "#metadata" }, "month": { "type": "ref", "ref": "#metadata" }, "all": { "type": "ref", "ref": "#metadata" } } } } }, "metadata": { "type": "object", "required": [ "messagesSent", "messagesReceived", "convos", "convosStarted" ], "properties": { "messagesSent": { "type": "integer" }, "messagesReceived": { "type": "integer" }, "convos": { "type": "integer" }, "convosStarted": { "type": "integer" } } } } } ================================================ FILE: lexicons/chat/bsky/moderation/getMessageContext.json ================================================ { "lexicon": 1, "id": "chat.bsky.moderation.getMessageContext", "defs": { "main": { "type": "query", "parameters": { "type": "params", "required": ["messageId"], "properties": { "convoId": { "type": "string", "description": "Conversation that the message is from. NOTE: this field will eventually be required." }, "messageId": { "type": "string" }, "before": { "type": "integer", "default": 5 }, "after": { "type": "integer", "default": 5 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["messages"], "properties": { "messages": { "type": "array", "items": { "type": "union", "refs": [ "chat.bsky.convo.defs#messageView", "chat.bsky.convo.defs#deletedMessageView" ] } } } } } } } } ================================================ FILE: lexicons/chat/bsky/moderation/updateActorAccess.json ================================================ { "lexicon": 1, "id": "chat.bsky.moderation.updateActorAccess", "defs": { "main": { "type": "procedure", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["actor", "allowAccess"], "properties": { "actor": { "type": "string", "format": "did" }, "allowAccess": { "type": "boolean" }, "ref": { "type": "string" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/defs.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.defs", "defs": { "statusAttr": { "type": "object", "required": ["applied"], "properties": { "applied": { "type": "boolean" }, "ref": { "type": "string" } } }, "accountView": { "type": "object", "required": ["did", "handle", "indexedAt"], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" }, "email": { "type": "string" }, "relatedRecords": { "type": "array", "items": { "type": "unknown" } }, "indexedAt": { "type": "string", "format": "datetime" }, "invitedBy": { "type": "ref", "ref": "com.atproto.server.defs#inviteCode" }, "invites": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.server.defs#inviteCode" } }, "invitesDisabled": { "type": "boolean" }, "emailConfirmedAt": { "type": "string", "format": "datetime" }, "inviteNote": { "type": "string" }, "deactivatedAt": { "type": "string", "format": "datetime" }, "threatSignatures": { "type": "array", "items": { "type": "ref", "ref": "#threatSignature" } } } }, "repoRef": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "repoBlobRef": { "type": "object", "required": ["did", "cid"], "properties": { "did": { "type": "string", "format": "did" }, "cid": { "type": "string", "format": "cid" }, "recordUri": { "type": "string", "format": "at-uri" } } }, "threatSignature": { "type": "object", "required": ["property", "value"], "properties": { "property": { "type": "string" }, "value": { "type": "string" } } } } } ================================================ FILE: lexicons/com/atproto/admin/deleteAccount.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.deleteAccount", "defs": { "main": { "type": "procedure", "description": "Delete a user account as an administrator.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/disableAccountInvites.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.disableAccountInvites", "defs": { "main": { "type": "procedure", "description": "Disable an account from receiving new invite codes, but does not invalidate existing codes.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["account"], "properties": { "account": { "type": "string", "format": "did" }, "note": { "type": "string", "description": "Optional reason for disabled invites." } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/disableInviteCodes.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.disableInviteCodes", "defs": { "main": { "type": "procedure", "description": "Disable some set of codes and/or all codes associated with a set of users.", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "codes": { "type": "array", "items": { "type": "string" } }, "accounts": { "type": "array", "items": { "type": "string" } } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/enableAccountInvites.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.enableAccountInvites", "defs": { "main": { "type": "procedure", "description": "Re-enable an account's ability to receive invite codes.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["account"], "properties": { "account": { "type": "string", "format": "did" }, "note": { "type": "string", "description": "Optional reason for enabled invites." } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/getAccountInfo.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.getAccountInfo", "defs": { "main": { "type": "query", "description": "Get details about an account.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "com.atproto.admin.defs#accountView" } } } } } ================================================ FILE: lexicons/com/atproto/admin/getAccountInfos.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.getAccountInfos", "defs": { "main": { "type": "query", "description": "Get details about some accounts.", "parameters": { "type": "params", "required": ["dids"], "properties": { "dids": { "type": "array", "items": { "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["infos"], "properties": { "infos": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.admin.defs#accountView" } } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/getInviteCodes.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.getInviteCodes", "defs": { "main": { "type": "query", "description": "Get an admin view of invite codes.", "parameters": { "type": "params", "properties": { "sort": { "type": "string", "knownValues": ["recent", "usage"], "default": "recent" }, "limit": { "type": "integer", "minimum": 1, "maximum": 500, "default": 100 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["codes"], "properties": { "cursor": { "type": "string" }, "codes": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.server.defs#inviteCode" } } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/getSubjectStatus.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.getSubjectStatus", "defs": { "main": { "type": "query", "description": "Get the service-specific admin status of a subject (account, record, or blob).", "parameters": { "type": "params", "properties": { "did": { "type": "string", "format": "did" }, "uri": { "type": "string", "format": "at-uri" }, "blob": { "type": "string", "format": "cid" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject"], "properties": { "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef", "com.atproto.admin.defs#repoBlobRef" ] }, "takedown": { "type": "ref", "ref": "com.atproto.admin.defs#statusAttr" }, "deactivated": { "type": "ref", "ref": "com.atproto.admin.defs#statusAttr" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/searchAccounts.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.searchAccounts", "defs": { "main": { "type": "query", "description": "Get list of accounts that matches your search query.", "parameters": { "type": "params", "properties": { "email": { "type": "string" }, "cursor": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["accounts"], "properties": { "cursor": { "type": "string" }, "accounts": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.admin.defs#accountView" } } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/sendEmail.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.sendEmail", "defs": { "main": { "type": "procedure", "description": "Send email to a user's account email address.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["recipientDid", "content", "senderDid"], "properties": { "recipientDid": { "type": "string", "format": "did" }, "content": { "type": "string" }, "subject": { "type": "string" }, "senderDid": { "type": "string", "format": "did" }, "comment": { "type": "string", "description": "Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["sent"], "properties": { "sent": { "type": "boolean" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/updateAccountEmail.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.updateAccountEmail", "defs": { "main": { "type": "procedure", "description": "Administrative action to update an account's email.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["account", "email"], "properties": { "account": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo." }, "email": { "type": "string" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/updateAccountHandle.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.updateAccountHandle", "defs": { "main": { "type": "procedure", "description": "Administrative action to update an account's handle.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "handle"], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/updateAccountPassword.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.updateAccountPassword", "defs": { "main": { "type": "procedure", "description": "Update the password for a user account as an administrator.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "password"], "properties": { "did": { "type": "string", "format": "did" }, "password": { "type": "string" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/updateAccountSigningKey.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.updateAccountSigningKey", "defs": { "main": { "type": "procedure", "description": "Administrative action to update an account's signing key in their Did document.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "signingKey"], "properties": { "did": { "type": "string", "format": "did" }, "signingKey": { "type": "string", "format": "did", "description": "Did-key formatted public key" } } } } } } } ================================================ FILE: lexicons/com/atproto/admin/updateSubjectStatus.json ================================================ { "lexicon": 1, "id": "com.atproto.admin.updateSubjectStatus", "defs": { "main": { "type": "procedure", "description": "Update the service-specific admin status of a subject (account, record, or blob).", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject"], "properties": { "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef", "com.atproto.admin.defs#repoBlobRef" ] }, "takedown": { "type": "ref", "ref": "com.atproto.admin.defs#statusAttr" }, "deactivated": { "type": "ref", "ref": "com.atproto.admin.defs#statusAttr" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject"], "properties": { "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef", "com.atproto.admin.defs#repoBlobRef" ] }, "takedown": { "type": "ref", "ref": "com.atproto.admin.defs#statusAttr" } } } } } } } ================================================ FILE: lexicons/com/atproto/identity/defs.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.defs", "defs": { "identityInfo": { "type": "object", "required": ["did", "handle", "didDoc"], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle", "description": "The validated handle of the account; or 'handle.invalid' if the handle did not bi-directionally match the DID document." }, "didDoc": { "type": "unknown", "description": "The complete DID document for the identity." } } } } } ================================================ FILE: lexicons/com/atproto/identity/getRecommendedDidCredentials.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.getRecommendedDidCredentials", "defs": { "main": { "type": "query", "description": "Describe the credentials that should be included in the DID doc of an account that is migrating to this service.", "output": { "encoding": "application/json", "schema": { "type": "object", "properties": { "rotationKeys": { "description": "Recommended rotation keys for PLC dids. Should be undefined (or ignored) for did:webs.", "type": "array", "items": { "type": "string" } }, "alsoKnownAs": { "type": "array", "items": { "type": "string" } }, "verificationMethods": { "type": "unknown" }, "services": { "type": "unknown" } } } } } } } ================================================ FILE: lexicons/com/atproto/identity/refreshIdentity.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.refreshIdentity", "defs": { "main": { "type": "procedure", "description": "Request that the server re-resolve an identity (DID and handle). The server may ignore this request, or require authentication, depending on the role, implementation, and policy of the server.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["identifier"], "properties": { "identifier": { "type": "string", "format": "at-identifier" } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "com.atproto.identity.defs#identityInfo" } }, "errors": [ { "name": "HandleNotFound", "description": "The resolution process confirmed that the handle does not resolve to any DID." }, { "name": "DidNotFound", "description": "The DID resolution process confirmed that there is no current DID." }, { "name": "DidDeactivated", "description": "The DID previously existed, but has been deactivated." } ] } } } ================================================ FILE: lexicons/com/atproto/identity/requestPlcOperationSignature.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.requestPlcOperationSignature", "defs": { "main": { "type": "procedure", "description": "Request an email with a code to in order to request a signed PLC operation. Requires Auth." } } } ================================================ FILE: lexicons/com/atproto/identity/resolveDid.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.resolveDid", "defs": { "main": { "type": "query", "description": "Resolves DID to DID document. Does not bi-directionally verify handle.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did", "description": "DID to resolve." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["didDoc"], "properties": { "didDoc": { "type": "unknown", "description": "The complete DID document for the identity." } } } }, "errors": [ { "name": "DidNotFound", "description": "The DID resolution process confirmed that there is no current DID." }, { "name": "DidDeactivated", "description": "The DID previously existed, but has been deactivated." } ] } } } ================================================ FILE: lexicons/com/atproto/identity/resolveHandle.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.resolveHandle", "defs": { "main": { "type": "query", "description": "Resolves an atproto handle (hostname) to a DID. Does not necessarily bi-directionally verify against the the DID document.", "parameters": { "type": "params", "required": ["handle"], "properties": { "handle": { "type": "string", "format": "handle", "description": "The handle to resolve." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } } }, "errors": [ { "name": "HandleNotFound", "description": "The resolution process confirmed that the handle does not resolve to any DID." } ] } } } ================================================ FILE: lexicons/com/atproto/identity/resolveIdentity.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.resolveIdentity", "defs": { "main": { "type": "query", "description": "Resolves an identity (DID or Handle) to a full identity (DID document and verified handle).", "parameters": { "type": "params", "required": ["identifier"], "properties": { "identifier": { "type": "string", "format": "at-identifier", "description": "Handle or DID to resolve." } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "com.atproto.identity.defs#identityInfo" } }, "errors": [ { "name": "HandleNotFound", "description": "The resolution process confirmed that the handle does not resolve to any DID." }, { "name": "DidNotFound", "description": "The DID resolution process confirmed that there is no current DID." }, { "name": "DidDeactivated", "description": "The DID previously existed, but has been deactivated." } ] } } } ================================================ FILE: lexicons/com/atproto/identity/signPlcOperation.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.signPlcOperation", "defs": { "main": { "type": "procedure", "description": "Signs a PLC operation to update some value(s) in the requesting DID's document.", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "token": { "description": "A token received through com.atproto.identity.requestPlcOperationSignature", "type": "string" }, "rotationKeys": { "type": "array", "items": { "type": "string" } }, "alsoKnownAs": { "type": "array", "items": { "type": "string" } }, "verificationMethods": { "type": "unknown" }, "services": { "type": "unknown" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["operation"], "properties": { "operation": { "type": "unknown", "description": "A signed DID PLC operation." } } } } } } } ================================================ FILE: lexicons/com/atproto/identity/submitPlcOperation.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.submitPlcOperation", "defs": { "main": { "type": "procedure", "description": "Validates a PLC operation to ensure that it doesn't violate a service's constraints or get the identity into a bad state, then submits it to the PLC registry", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["operation"], "properties": { "operation": { "type": "unknown" } } } } } } } ================================================ FILE: lexicons/com/atproto/identity/updateHandle.json ================================================ { "lexicon": 1, "id": "com.atproto.identity.updateHandle", "defs": { "main": { "type": "procedure", "description": "Updates the current account's handle. Verifies handle validity, and updates did:plc document if necessary. Implemented by PDS, and requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["handle"], "properties": { "handle": { "type": "string", "format": "handle", "description": "The new handle." } } } } } } } ================================================ FILE: lexicons/com/atproto/label/defs.json ================================================ { "lexicon": 1, "id": "com.atproto.label.defs", "defs": { "label": { "type": "object", "description": "Metadata tag on an atproto resource (eg, repo or record).", "required": ["src", "uri", "val", "cts"], "properties": { "ver": { "type": "integer", "description": "The AT Protocol version of the label object." }, "src": { "type": "string", "format": "did", "description": "DID of the actor who created this label." }, "uri": { "type": "string", "format": "uri", "description": "AT URI of the record, repository (account), or other resource that this label applies to." }, "cid": { "type": "string", "format": "cid", "description": "Optionally, CID specifying the specific version of 'uri' resource this label applies to." }, "val": { "type": "string", "maxLength": 128, "description": "The short string name of the value or type of this label." }, "neg": { "type": "boolean", "description": "If true, this is a negation label, overwriting a previous label." }, "cts": { "type": "string", "format": "datetime", "description": "Timestamp when this label was created." }, "exp": { "type": "string", "format": "datetime", "description": "Timestamp at which this label expires (no longer applies)." }, "sig": { "type": "bytes", "description": "Signature of dag-cbor encoded label." } } }, "selfLabels": { "type": "object", "description": "Metadata tags on an atproto record, published by the author within the record.", "required": ["values"], "properties": { "values": { "type": "array", "items": { "type": "ref", "ref": "#selfLabel" }, "maxLength": 10 } } }, "selfLabel": { "type": "object", "description": "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.", "required": ["val"], "properties": { "val": { "type": "string", "maxLength": 128, "description": "The short string name of the value or type of this label." } } }, "labelValueDefinition": { "type": "object", "description": "Declares a label value and its expected interpretations and behaviors.", "required": ["identifier", "severity", "blurs", "locales"], "properties": { "identifier": { "type": "string", "description": "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", "maxLength": 100, "maxGraphemes": 100 }, "severity": { "type": "string", "description": "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", "knownValues": ["inform", "alert", "none"] }, "blurs": { "type": "string", "description": "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", "knownValues": ["content", "media", "none"] }, "defaultSetting": { "type": "string", "description": "The default setting for this label.", "knownValues": ["ignore", "warn", "hide"], "default": "warn" }, "adultOnly": { "type": "boolean", "description": "Does the user need to have adult content enabled in order to configure this label?" }, "locales": { "type": "array", "items": { "type": "ref", "ref": "#labelValueDefinitionStrings" } } } }, "labelValueDefinitionStrings": { "type": "object", "description": "Strings which describe the label in the UI, localized into a specific language.", "required": ["lang", "name", "description"], "properties": { "lang": { "type": "string", "description": "The code of the language these strings are written in.", "format": "language" }, "name": { "type": "string", "description": "A short human-readable name for the label.", "maxGraphemes": 64, "maxLength": 640 }, "description": { "type": "string", "description": "A longer description of what the label means and why it might be applied.", "maxGraphemes": 10000, "maxLength": 100000 } } }, "labelValue": { "type": "string", "knownValues": [ "!hide", "!warn", "!no-unauthenticated", "porn", "sexual", "nudity", "graphic-media", "bot" ] } } } ================================================ FILE: lexicons/com/atproto/label/queryLabels.json ================================================ { "lexicon": 1, "id": "com.atproto.label.queryLabels", "defs": { "main": { "type": "query", "description": "Find labels relevant to the provided AT-URI patterns. Public endpoint for moderation services, though may return different or additional results with auth.", "parameters": { "type": "params", "required": ["uriPatterns"], "properties": { "uriPatterns": { "type": "array", "items": { "type": "string" }, "description": "List of AT URI patterns to match (boolean 'OR'). Each may be a prefix (ending with '*'; will match inclusive of the string leading to '*'), or a full URI." }, "sources": { "type": "array", "items": { "type": "string", "format": "did" }, "description": "Optional list of label sources (DIDs) to filter on." }, "limit": { "type": "integer", "minimum": 1, "maximum": 250, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["labels"], "properties": { "cursor": { "type": "string" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } } } } } } } } ================================================ FILE: lexicons/com/atproto/label/subscribeLabels.json ================================================ { "lexicon": 1, "id": "com.atproto.label.subscribeLabels", "defs": { "main": { "type": "subscription", "description": "Subscribe to stream of labels (and negations). Public endpoint implemented by mod services. Uses same sequencing scheme as repo event stream.", "parameters": { "type": "params", "properties": { "cursor": { "type": "integer", "description": "The last known event seq number to backfill from." } } }, "message": { "schema": { "type": "union", "refs": ["#labels", "#info"] } }, "errors": [{ "name": "FutureCursor" }] }, "labels": { "type": "object", "required": ["seq", "labels"], "properties": { "seq": { "type": "integer" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } } } }, "info": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "knownValues": ["OutdatedCursor"] }, "message": { "type": "string" } } } } } ================================================ FILE: lexicons/com/atproto/lexicon/resolveLexicon.json ================================================ { "lexicon": 1, "id": "com.atproto.lexicon.resolveLexicon", "defs": { "main": { "type": "query", "description": "Resolves an atproto lexicon (NSID) to a schema.", "parameters": { "type": "params", "properties": { "nsid": { "format": "nsid", "type": "string", "description": "The lexicon NSID to resolve." } }, "required": ["nsid"] }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": { "cid": { "type": "string", "format": "cid", "description": "The CID of the lexicon schema record." }, "schema": { "type": "ref", "ref": "com.atproto.lexicon.schema#main", "description": "The resolved lexicon schema record." }, "uri": { "type": "string", "format": "at-uri", "description": "The AT-URI of the lexicon schema record." } }, "required": ["uri", "cid", "schema"] } }, "errors": [ { "description": "No lexicon was resolved for the NSID.", "name": "LexiconNotFound" } ] } } } ================================================ FILE: lexicons/com/atproto/lexicon/schema.json ================================================ { "lexicon": 1, "id": "com.atproto.lexicon.schema", "defs": { "main": { "type": "record", "description": "Representation of Lexicon schemas themselves, when published as atproto records. Note that the schema language is not defined in Lexicon; this meta schema currently only includes a single version field ('lexicon'). See the atproto specifications for description of the other expected top-level fields ('id', 'defs', etc).", "key": "nsid", "record": { "type": "object", "required": ["lexicon"], "properties": { "lexicon": { "type": "integer", "description": "Indicates the 'version' of the Lexicon language. Must be '1' for the current atproto/Lexicon schema system." } } } } } } ================================================ FILE: lexicons/com/atproto/moderation/createReport.json ================================================ { "lexicon": 1, "id": "com.atproto.moderation.createReport", "defs": { "main": { "type": "procedure", "description": "Submit a moderation report regarding an atproto account or record. Implemented by moderation services (with PDS proxying), and requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["reasonType", "subject"], "properties": { "reasonType": { "type": "ref", "description": "Indicates the broad category of violation the report is for.", "ref": "com.atproto.moderation.defs#reasonType" }, "reason": { "type": "string", "maxGraphemes": 2000, "maxLength": 20000, "description": "Additional context about the content and violation." }, "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef" ] }, "modTool": { "type": "ref", "ref": "#modTool" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": [ "id", "reasonType", "subject", "reportedBy", "createdAt" ], "properties": { "id": { "type": "integer" }, "reasonType": { "type": "ref", "ref": "com.atproto.moderation.defs#reasonType" }, "reason": { "type": "string", "maxGraphemes": 2000, "maxLength": 20000 }, "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef" ] }, "reportedBy": { "type": "string", "format": "did" }, "createdAt": { "type": "string", "format": "datetime" } } } } }, "modTool": { "type": "object", "description": "Moderation tool information for tracing the source of the action", "required": ["name"], "properties": { "name": { "type": "string", "description": "Name/identifier of the source (e.g., 'bsky-app/android', 'bsky-web/chrome')" }, "meta": { "type": "unknown", "description": "Additional arbitrary metadata about the source" } } } } } ================================================ FILE: lexicons/com/atproto/moderation/defs.json ================================================ { "lexicon": 1, "id": "com.atproto.moderation.defs", "defs": { "reasonType": { "type": "string", "knownValues": [ "com.atproto.moderation.defs#reasonSpam", "com.atproto.moderation.defs#reasonViolation", "com.atproto.moderation.defs#reasonMisleading", "com.atproto.moderation.defs#reasonSexual", "com.atproto.moderation.defs#reasonRude", "com.atproto.moderation.defs#reasonOther", "com.atproto.moderation.defs#reasonAppeal", "tools.ozone.report.defs#reasonAppeal", "tools.ozone.report.defs#reasonOther", "tools.ozone.report.defs#reasonViolenceAnimal", "tools.ozone.report.defs#reasonViolenceThreats", "tools.ozone.report.defs#reasonViolenceGraphicContent", "tools.ozone.report.defs#reasonViolenceGlorification", "tools.ozone.report.defs#reasonViolenceExtremistContent", "tools.ozone.report.defs#reasonViolenceTrafficking", "tools.ozone.report.defs#reasonViolenceOther", "tools.ozone.report.defs#reasonSexualAbuseContent", "tools.ozone.report.defs#reasonSexualNCII", "tools.ozone.report.defs#reasonSexualDeepfake", "tools.ozone.report.defs#reasonSexualAnimal", "tools.ozone.report.defs#reasonSexualUnlabeled", "tools.ozone.report.defs#reasonSexualOther", "tools.ozone.report.defs#reasonChildSafetyCSAM", "tools.ozone.report.defs#reasonChildSafetyGroom", "tools.ozone.report.defs#reasonChildSafetyPrivacy", "tools.ozone.report.defs#reasonChildSafetyHarassment", "tools.ozone.report.defs#reasonChildSafetyOther", "tools.ozone.report.defs#reasonHarassmentTroll", "tools.ozone.report.defs#reasonHarassmentTargeted", "tools.ozone.report.defs#reasonHarassmentHateSpeech", "tools.ozone.report.defs#reasonHarassmentDoxxing", "tools.ozone.report.defs#reasonHarassmentOther", "tools.ozone.report.defs#reasonMisleadingBot", "tools.ozone.report.defs#reasonMisleadingImpersonation", "tools.ozone.report.defs#reasonMisleadingSpam", "tools.ozone.report.defs#reasonMisleadingScam", "tools.ozone.report.defs#reasonMisleadingElections", "tools.ozone.report.defs#reasonMisleadingOther", "tools.ozone.report.defs#reasonRuleSiteSecurity", "tools.ozone.report.defs#reasonRuleProhibitedSales", "tools.ozone.report.defs#reasonRuleBanEvasion", "tools.ozone.report.defs#reasonRuleOther", "tools.ozone.report.defs#reasonSelfHarmContent", "tools.ozone.report.defs#reasonSelfHarmED", "tools.ozone.report.defs#reasonSelfHarmStunts", "tools.ozone.report.defs#reasonSelfHarmSubstances", "tools.ozone.report.defs#reasonSelfHarmOther" ] }, "reasonSpam": { "type": "token", "description": "Spam: frequent unwanted promotion, replies, mentions. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingSpam`." }, "reasonViolation": { "type": "token", "description": "Direct violation of server rules, laws, terms of service. Prefer new lexicon definition `tools.ozone.report.defs#reasonRuleOther`." }, "reasonMisleading": { "type": "token", "description": "Misleading identity, affiliation, or content. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingOther`." }, "reasonSexual": { "type": "token", "description": "Unwanted or mislabeled sexual content. Prefer new lexicon definition `tools.ozone.report.defs#reasonSexualUnlabeled`." }, "reasonRude": { "type": "token", "description": "Rude, harassing, explicit, or otherwise unwelcoming behavior. Prefer new lexicon definition `tools.ozone.report.defs#reasonHarassmentOther`." }, "reasonOther": { "type": "token", "description": "Reports not falling under another report category. Prefer new lexicon definition `tools.ozone.report.defs#reasonOther`." }, "reasonAppeal": { "type": "token", "description": "Appeal a previously taken moderation action" }, "subjectType": { "type": "string", "description": "Tag describing a type of subject that might be reported.", "knownValues": ["account", "record", "chat"] } } } ================================================ FILE: lexicons/com/atproto/repo/applyWrites.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.applyWrites", "defs": { "main": { "type": "procedure", "description": "Apply a batch transaction of repository creates, updates, and deletes. Requires auth, implemented by PDS.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["repo", "writes"], "properties": { "repo": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo (aka, current account)." }, "validate": { "type": "boolean", "description": "Can be set to 'false' to skip Lexicon schema validation of record data across all operations, 'true' to require it, or leave unset to validate only for known Lexicons." }, "writes": { "type": "array", "items": { "type": "union", "refs": ["#create", "#update", "#delete"], "closed": true } }, "swapCommit": { "type": "string", "description": "If provided, the entire operation will fail if the current repo commit CID does not match this value. Used to prevent conflicting repo mutations.", "format": "cid" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": [], "properties": { "commit": { "type": "ref", "ref": "com.atproto.repo.defs#commitMeta" }, "results": { "type": "array", "items": { "type": "union", "refs": ["#createResult", "#updateResult", "#deleteResult"], "closed": true } } } } }, "errors": [ { "name": "InvalidSwap", "description": "Indicates that the 'swapCommit' parameter did not match current commit." } ] }, "create": { "type": "object", "description": "Operation which creates a new record.", "required": ["collection", "value"], "properties": { "collection": { "type": "string", "format": "nsid" }, "rkey": { "type": "string", "maxLength": 512, "format": "record-key", "description": "NOTE: maxLength is redundant with record-key format. Keeping it temporarily to ensure backwards compatibility." }, "value": { "type": "unknown" } } }, "update": { "type": "object", "description": "Operation which updates an existing record.", "required": ["collection", "rkey", "value"], "properties": { "collection": { "type": "string", "format": "nsid" }, "rkey": { "type": "string", "format": "record-key" }, "value": { "type": "unknown" } } }, "delete": { "type": "object", "description": "Operation which deletes an existing record.", "required": ["collection", "rkey"], "properties": { "collection": { "type": "string", "format": "nsid" }, "rkey": { "type": "string", "format": "record-key" } } }, "createResult": { "type": "object", "required": ["uri", "cid"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "validationStatus": { "type": "string", "knownValues": ["valid", "unknown"] } } }, "updateResult": { "type": "object", "required": ["uri", "cid"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "validationStatus": { "type": "string", "knownValues": ["valid", "unknown"] } } }, "deleteResult": { "type": "object", "required": [], "properties": {} } } } ================================================ FILE: lexicons/com/atproto/repo/createRecord.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.createRecord", "defs": { "main": { "type": "procedure", "description": "Create a single new repository record. Requires auth, implemented by PDS.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["repo", "collection", "record"], "properties": { "repo": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo (aka, current account)." }, "collection": { "type": "string", "format": "nsid", "description": "The NSID of the record collection." }, "rkey": { "type": "string", "format": "record-key", "description": "The Record Key.", "maxLength": 512 }, "validate": { "type": "boolean", "description": "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons." }, "record": { "type": "unknown", "description": "The record itself. Must contain a $type field." }, "swapCommit": { "type": "string", "format": "cid", "description": "Compare and swap with the previous commit by CID." } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri", "cid"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "commit": { "type": "ref", "ref": "com.atproto.repo.defs#commitMeta" }, "validationStatus": { "type": "string", "knownValues": ["valid", "unknown"] } } } }, "errors": [ { "name": "InvalidSwap", "description": "Indicates that 'swapCommit' didn't match current repo commit." } ] } } } ================================================ FILE: lexicons/com/atproto/repo/defs.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.defs", "defs": { "commitMeta": { "type": "object", "required": ["cid", "rev"], "properties": { "cid": { "type": "string", "format": "cid" }, "rev": { "type": "string", "format": "tid" } } } } } ================================================ FILE: lexicons/com/atproto/repo/deleteRecord.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.deleteRecord", "defs": { "main": { "type": "procedure", "description": "Delete a repository record, or ensure it doesn't exist. Requires auth, implemented by PDS.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["repo", "collection", "rkey"], "properties": { "repo": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo (aka, current account)." }, "collection": { "type": "string", "format": "nsid", "description": "The NSID of the record collection." }, "rkey": { "type": "string", "format": "record-key", "description": "The Record Key." }, "swapRecord": { "type": "string", "format": "cid", "description": "Compare and swap with the previous record by CID." }, "swapCommit": { "type": "string", "format": "cid", "description": "Compare and swap with the previous commit by CID." } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": { "commit": { "type": "ref", "ref": "com.atproto.repo.defs#commitMeta" } } } }, "errors": [{ "name": "InvalidSwap" }] } } } ================================================ FILE: lexicons/com/atproto/repo/describeRepo.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.describeRepo", "defs": { "main": { "type": "query", "description": "Get information about an account and repository, including the list of collections. Does not require auth.", "parameters": { "type": "params", "required": ["repo"], "properties": { "repo": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": [ "handle", "did", "didDoc", "collections", "handleIsCorrect" ], "properties": { "handle": { "type": "string", "format": "handle" }, "did": { "type": "string", "format": "did" }, "didDoc": { "type": "unknown", "description": "The complete DID document for this account." }, "collections": { "type": "array", "description": "List of all the collections (NSIDs) for which this repo contains at least one record.", "items": { "type": "string", "format": "nsid" } }, "handleIsCorrect": { "type": "boolean", "description": "Indicates if handle is currently valid (resolves bi-directionally)" } } } } } } } ================================================ FILE: lexicons/com/atproto/repo/getRecord.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.getRecord", "defs": { "main": { "type": "query", "description": "Get a single record from a repository. Does not require auth.", "parameters": { "type": "params", "required": ["repo", "collection", "rkey"], "properties": { "repo": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo." }, "collection": { "type": "string", "format": "nsid", "description": "The NSID of the record collection." }, "rkey": { "type": "string", "description": "The Record Key.", "format": "record-key" }, "cid": { "type": "string", "format": "cid", "description": "The CID of the version of the record. If not specified, then return the most recent version." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri", "value"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "value": { "type": "unknown" } } } }, "errors": [{ "name": "RecordNotFound" }] } } } ================================================ FILE: lexicons/com/atproto/repo/importRepo.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.importRepo", "defs": { "main": { "type": "procedure", "description": "Import a repo in the form of a CAR file. Requires Content-Length HTTP header to be set.", "input": { "encoding": "application/vnd.ipld.car" } } } } ================================================ FILE: lexicons/com/atproto/repo/listMissingBlobs.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.listMissingBlobs", "defs": { "main": { "type": "query", "description": "Returns a list of missing blobs for the requesting account. Intended to be used in the account migration flow.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 500 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["blobs"], "properties": { "cursor": { "type": "string" }, "blobs": { "type": "array", "items": { "type": "ref", "ref": "#recordBlob" } } } } } }, "recordBlob": { "type": "object", "required": ["cid", "recordUri"], "properties": { "cid": { "type": "string", "format": "cid" }, "recordUri": { "type": "string", "format": "at-uri" } } } } } ================================================ FILE: lexicons/com/atproto/repo/listRecords.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.listRecords", "defs": { "main": { "type": "query", "description": "List a range of records in a repository, matching a specific collection. Does not require auth.", "parameters": { "type": "params", "required": ["repo", "collection"], "properties": { "repo": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo." }, "collection": { "type": "string", "format": "nsid", "description": "The NSID of the record type." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50, "description": "The number of records to return." }, "cursor": { "type": "string" }, "reverse": { "type": "boolean", "description": "Flag to reverse the order of the returned records." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["records"], "properties": { "cursor": { "type": "string" }, "records": { "type": "array", "items": { "type": "ref", "ref": "#record" } } } } } }, "record": { "type": "object", "required": ["uri", "cid", "value"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "value": { "type": "unknown" } } } } } ================================================ FILE: lexicons/com/atproto/repo/putRecord.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.putRecord", "defs": { "main": { "type": "procedure", "description": "Write a repository record, creating or updating it as needed. Requires auth, implemented by PDS.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["repo", "collection", "rkey", "record"], "nullable": ["swapRecord"], "properties": { "repo": { "type": "string", "format": "at-identifier", "description": "The handle or DID of the repo (aka, current account)." }, "collection": { "type": "string", "format": "nsid", "description": "The NSID of the record collection." }, "rkey": { "type": "string", "format": "record-key", "description": "The Record Key.", "maxLength": 512 }, "validate": { "type": "boolean", "description": "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons." }, "record": { "type": "unknown", "description": "The record to write." }, "swapRecord": { "type": "string", "format": "cid", "description": "Compare and swap with the previous record by CID. WARNING: nullable and optional field; may cause problems with golang implementation" }, "swapCommit": { "type": "string", "format": "cid", "description": "Compare and swap with the previous commit by CID." } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["uri", "cid"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "commit": { "type": "ref", "ref": "com.atproto.repo.defs#commitMeta" }, "validationStatus": { "type": "string", "knownValues": ["valid", "unknown"] } } } }, "errors": [{ "name": "InvalidSwap" }] } } } ================================================ FILE: lexicons/com/atproto/repo/strongRef.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.strongRef", "description": "A URI with a content-hash fingerprint.", "defs": { "main": { "type": "object", "required": ["uri", "cid"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" } } } } } ================================================ FILE: lexicons/com/atproto/repo/uploadBlob.json ================================================ { "lexicon": 1, "id": "com.atproto.repo.uploadBlob", "defs": { "main": { "type": "procedure", "description": "Upload a new blob, to be referenced from a repository record. The blob will be deleted if it is not referenced within a time window (eg, minutes). Blob restrictions (mimetype, size, etc) are enforced when the reference is created. Requires auth, implemented by PDS.", "input": { "encoding": "*/*" }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["blob"], "properties": { "blob": { "type": "blob" } } } } } } } ================================================ FILE: lexicons/com/atproto/server/activateAccount.json ================================================ { "lexicon": 1, "id": "com.atproto.server.activateAccount", "defs": { "main": { "type": "procedure", "description": "Activates a currently deactivated account. Used to finalize account migration after the account's repo is imported and identity is setup." } } } ================================================ FILE: lexicons/com/atproto/server/checkAccountStatus.json ================================================ { "lexicon": 1, "id": "com.atproto.server.checkAccountStatus", "defs": { "main": { "type": "query", "description": "Returns the status of an account, especially as pertaining to import or recovery. Can be called many times over the course of an account migration. Requires auth and can only be called pertaining to oneself.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": [ "activated", "validDid", "repoCommit", "repoRev", "repoBlocks", "indexedRecords", "privateStateValues", "expectedBlobs", "importedBlobs" ], "properties": { "activated": { "type": "boolean" }, "validDid": { "type": "boolean" }, "repoCommit": { "type": "string", "format": "cid" }, "repoRev": { "type": "string" }, "repoBlocks": { "type": "integer" }, "indexedRecords": { "type": "integer" }, "privateStateValues": { "type": "integer" }, "expectedBlobs": { "type": "integer" }, "importedBlobs": { "type": "integer" } } } } } } } ================================================ FILE: lexicons/com/atproto/server/confirmEmail.json ================================================ { "lexicon": 1, "id": "com.atproto.server.confirmEmail", "defs": { "main": { "type": "procedure", "description": "Confirm an email using a token from com.atproto.server.requestEmailConfirmation.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["email", "token"], "properties": { "email": { "type": "string" }, "token": { "type": "string" } } } }, "errors": [ { "name": "AccountNotFound" }, { "name": "ExpiredToken" }, { "name": "InvalidToken" }, { "name": "InvalidEmail" } ] } } } ================================================ FILE: lexicons/com/atproto/server/createAccount.json ================================================ { "lexicon": 1, "id": "com.atproto.server.createAccount", "defs": { "main": { "type": "procedure", "description": "Create an account. Implemented by PDS.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["handle"], "properties": { "email": { "type": "string" }, "handle": { "type": "string", "format": "handle", "description": "Requested handle for the account." }, "did": { "type": "string", "format": "did", "description": "Pre-existing atproto DID, being imported to a new account." }, "inviteCode": { "type": "string" }, "verificationCode": { "type": "string" }, "verificationPhone": { "type": "string" }, "password": { "type": "string", "description": "Initial account password. May need to meet instance-specific password strength requirements." }, "recoveryKey": { "type": "string", "description": "DID PLC rotation key (aka, recovery key) to be included in PLC creation operation." }, "plcOp": { "type": "unknown", "description": "A signed DID PLC operation to be submitted as part of importing an existing account to this instance. NOTE: this optional field may be updated when full account migration is implemented." } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "description": "Account login session returned on successful account creation.", "required": ["accessJwt", "refreshJwt", "handle", "did"], "properties": { "accessJwt": { "type": "string" }, "refreshJwt": { "type": "string" }, "handle": { "type": "string", "format": "handle" }, "did": { "type": "string", "format": "did", "description": "The DID of the new account." }, "didDoc": { "type": "unknown", "description": "Complete DID document." } } } }, "errors": [ { "name": "InvalidHandle" }, { "name": "InvalidPassword" }, { "name": "InvalidInviteCode" }, { "name": "HandleNotAvailable" }, { "name": "UnsupportedDomain" }, { "name": "UnresolvableDid" }, { "name": "IncompatibleDidDoc" } ] } } } ================================================ FILE: lexicons/com/atproto/server/createAppPassword.json ================================================ { "lexicon": 1, "id": "com.atproto.server.createAppPassword", "defs": { "main": { "type": "procedure", "description": "Create an App Password.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "description": "A short name for the App Password, to help distinguish them." }, "privileged": { "type": "boolean", "description": "If an app password has 'privileged' access to possibly sensitive account state. Meant for use with trusted clients." } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "#appPassword" } }, "errors": [{ "name": "AccountTakedown" }] }, "appPassword": { "type": "object", "required": ["name", "password", "createdAt"], "properties": { "name": { "type": "string" }, "password": { "type": "string" }, "createdAt": { "type": "string", "format": "datetime" }, "privileged": { "type": "boolean" } } } } } ================================================ FILE: lexicons/com/atproto/server/createInviteCode.json ================================================ { "lexicon": 1, "id": "com.atproto.server.createInviteCode", "defs": { "main": { "type": "procedure", "description": "Create an invite code.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["useCount"], "properties": { "useCount": { "type": "integer" }, "forAccount": { "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["code"], "properties": { "code": { "type": "string" } } } } } } } ================================================ FILE: lexicons/com/atproto/server/createInviteCodes.json ================================================ { "lexicon": 1, "id": "com.atproto.server.createInviteCodes", "defs": { "main": { "type": "procedure", "description": "Create invite codes.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["codeCount", "useCount"], "properties": { "codeCount": { "type": "integer", "default": 1 }, "useCount": { "type": "integer" }, "forAccounts": { "type": "array", "items": { "type": "string", "format": "did" } } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["codes"], "properties": { "codes": { "type": "array", "items": { "type": "ref", "ref": "#accountCodes" } } } } } }, "accountCodes": { "type": "object", "required": ["account", "codes"], "properties": { "account": { "type": "string" }, "codes": { "type": "array", "items": { "type": "string" } } } } } } ================================================ FILE: lexicons/com/atproto/server/createSession.json ================================================ { "lexicon": 1, "id": "com.atproto.server.createSession", "defs": { "main": { "type": "procedure", "description": "Create an authentication session.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["identifier", "password"], "properties": { "identifier": { "type": "string", "description": "Handle or other identifier supported by the server for the authenticating user." }, "password": { "type": "string" }, "authFactorToken": { "type": "string" }, "allowTakendown": { "type": "boolean", "description": "When true, instead of throwing error for takendown accounts, a valid response with a narrow scoped token will be returned" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["accessJwt", "refreshJwt", "handle", "did"], "properties": { "accessJwt": { "type": "string" }, "refreshJwt": { "type": "string" }, "handle": { "type": "string", "format": "handle" }, "did": { "type": "string", "format": "did" }, "didDoc": { "type": "unknown" }, "email": { "type": "string" }, "emailConfirmed": { "type": "boolean" }, "emailAuthFactor": { "type": "boolean" }, "active": { "type": "boolean" }, "status": { "type": "string", "description": "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", "knownValues": ["takendown", "suspended", "deactivated"] } } } }, "errors": [ { "name": "AccountTakedown" }, { "name": "AuthFactorTokenRequired" } ] } } } ================================================ FILE: lexicons/com/atproto/server/deactivateAccount.json ================================================ { "lexicon": 1, "id": "com.atproto.server.deactivateAccount", "defs": { "main": { "type": "procedure", "description": "Deactivates a currently active account. Stops serving of repo, and future writes to repo until reactivated. Used to finalize account migration with the old host after the account has been activated on the new host.", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "deleteAfter": { "type": "string", "format": "datetime", "description": "A recommendation to server as to how long they should hold onto the deactivated account before deleting." } } } } } } } ================================================ FILE: lexicons/com/atproto/server/defs.json ================================================ { "lexicon": 1, "id": "com.atproto.server.defs", "defs": { "inviteCode": { "type": "object", "required": [ "code", "available", "disabled", "forAccount", "createdBy", "createdAt", "uses" ], "properties": { "code": { "type": "string" }, "available": { "type": "integer" }, "disabled": { "type": "boolean" }, "forAccount": { "type": "string" }, "createdBy": { "type": "string" }, "createdAt": { "type": "string", "format": "datetime" }, "uses": { "type": "array", "items": { "type": "ref", "ref": "#inviteCodeUse" } } } }, "inviteCodeUse": { "type": "object", "required": ["usedBy", "usedAt"], "properties": { "usedBy": { "type": "string", "format": "did" }, "usedAt": { "type": "string", "format": "datetime" } } } } } ================================================ FILE: lexicons/com/atproto/server/deleteAccount.json ================================================ { "lexicon": 1, "id": "com.atproto.server.deleteAccount", "defs": { "main": { "type": "procedure", "description": "Delete an actor's account with a token and password. Can only be called after requesting a deletion token. Requires auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "password", "token"], "properties": { "did": { "type": "string", "format": "did" }, "password": { "type": "string" }, "token": { "type": "string" } } } }, "errors": [{ "name": "ExpiredToken" }, { "name": "InvalidToken" }] } } } ================================================ FILE: lexicons/com/atproto/server/deleteSession.json ================================================ { "lexicon": 1, "id": "com.atproto.server.deleteSession", "defs": { "main": { "type": "procedure", "description": "Delete the current session. Requires auth using the 'refreshJwt' (not the 'accessJwt').", "errors": [{ "name": "InvalidToken" }, { "name": "ExpiredToken" }] } } } ================================================ FILE: lexicons/com/atproto/server/describeServer.json ================================================ { "lexicon": 1, "id": "com.atproto.server.describeServer", "defs": { "main": { "type": "query", "description": "Describes the server's account creation requirements and capabilities. Implemented by PDS.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "availableUserDomains"], "properties": { "inviteCodeRequired": { "type": "boolean", "description": "If true, an invite code must be supplied to create an account on this instance." }, "phoneVerificationRequired": { "type": "boolean", "description": "If true, a phone verification token must be supplied to create an account on this instance." }, "availableUserDomains": { "type": "array", "description": "List of domain suffixes that can be used in account handles.", "items": { "type": "string" } }, "links": { "type": "ref", "description": "URLs of service policy documents.", "ref": "#links" }, "contact": { "type": "ref", "description": "Contact information", "ref": "#contact" }, "did": { "type": "string", "format": "did" } } } } }, "links": { "type": "object", "properties": { "privacyPolicy": { "type": "string", "format": "uri" }, "termsOfService": { "type": "string", "format": "uri" } } }, "contact": { "type": "object", "properties": { "email": { "type": "string" } } } } } ================================================ FILE: lexicons/com/atproto/server/getAccountInviteCodes.json ================================================ { "lexicon": 1, "id": "com.atproto.server.getAccountInviteCodes", "defs": { "main": { "type": "query", "description": "Get all invite codes for the current account. Requires auth.", "parameters": { "type": "params", "properties": { "includeUsed": { "type": "boolean", "default": true }, "createAvailable": { "type": "boolean", "default": true, "description": "Controls whether any new 'earned' but not 'created' invites should be created." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["codes"], "properties": { "codes": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.server.defs#inviteCode" } } } } }, "errors": [{ "name": "DuplicateCreate" }] } } } ================================================ FILE: lexicons/com/atproto/server/getServiceAuth.json ================================================ { "lexicon": 1, "id": "com.atproto.server.getServiceAuth", "defs": { "main": { "type": "query", "description": "Get a signed token on behalf of the requesting DID for the requested service.", "parameters": { "type": "params", "required": ["aud"], "properties": { "aud": { "type": "string", "format": "did", "description": "The DID of the service that the token will be used to authenticate with" }, "exp": { "type": "integer", "description": "The time in Unix Epoch seconds that the JWT expires. Defaults to 60 seconds in the future. The service may enforce certain time bounds on tokens depending on the requested scope." }, "lxm": { "type": "string", "format": "nsid", "description": "Lexicon (XRPC) method to bind the requested token to" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["token"], "properties": { "token": { "type": "string" } } } }, "errors": [ { "name": "BadExpiration", "description": "Indicates that the requested expiration date is not a valid. May be in the past or may be reliant on the requested scopes." } ] } } } ================================================ FILE: lexicons/com/atproto/server/getSession.json ================================================ { "lexicon": 1, "id": "com.atproto.server.getSession", "defs": { "main": { "type": "query", "description": "Get information about the current auth session. Requires auth.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["handle", "did"], "properties": { "handle": { "type": "string", "format": "handle" }, "did": { "type": "string", "format": "did" }, "didDoc": { "type": "unknown" }, "email": { "type": "string" }, "emailConfirmed": { "type": "boolean" }, "emailAuthFactor": { "type": "boolean" }, "active": { "type": "boolean" }, "status": { "type": "string", "description": "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", "knownValues": ["takendown", "suspended", "deactivated"] } } } } } } } ================================================ FILE: lexicons/com/atproto/server/listAppPasswords.json ================================================ { "lexicon": 1, "id": "com.atproto.server.listAppPasswords", "defs": { "main": { "type": "query", "description": "List all App Passwords.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["passwords"], "properties": { "passwords": { "type": "array", "items": { "type": "ref", "ref": "#appPassword" } } } } }, "errors": [{ "name": "AccountTakedown" }] }, "appPassword": { "type": "object", "required": ["name", "createdAt"], "properties": { "name": { "type": "string" }, "createdAt": { "type": "string", "format": "datetime" }, "privileged": { "type": "boolean" } } } } } ================================================ FILE: lexicons/com/atproto/server/refreshSession.json ================================================ { "lexicon": 1, "id": "com.atproto.server.refreshSession", "defs": { "main": { "type": "procedure", "description": "Refresh an authentication session. Requires auth using the 'refreshJwt' (not the 'accessJwt').", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["accessJwt", "refreshJwt", "handle", "did"], "properties": { "accessJwt": { "type": "string" }, "refreshJwt": { "type": "string" }, "handle": { "type": "string", "format": "handle" }, "did": { "type": "string", "format": "did" }, "didDoc": { "type": "unknown" }, "email": { "type": "string" }, "emailConfirmed": { "type": "boolean" }, "emailAuthFactor": { "type": "boolean" }, "active": { "type": "boolean" }, "status": { "type": "string", "description": "Hosting status of the account. If not specified, then assume 'active'.", "knownValues": ["takendown", "suspended", "deactivated"] } } } }, "errors": [ { "name": "AccountTakedown" }, { "name": "InvalidToken" }, { "name": "ExpiredToken" } ] } } } ================================================ FILE: lexicons/com/atproto/server/requestAccountDelete.json ================================================ { "lexicon": 1, "id": "com.atproto.server.requestAccountDelete", "defs": { "main": { "type": "procedure", "description": "Initiate a user account deletion via email." } } } ================================================ FILE: lexicons/com/atproto/server/requestEmailConfirmation.json ================================================ { "lexicon": 1, "id": "com.atproto.server.requestEmailConfirmation", "defs": { "main": { "type": "procedure", "description": "Request an email with a code to confirm ownership of email." } } } ================================================ FILE: lexicons/com/atproto/server/requestEmailUpdate.json ================================================ { "lexicon": 1, "id": "com.atproto.server.requestEmailUpdate", "defs": { "main": { "type": "procedure", "description": "Request a token in order to update email.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["tokenRequired"], "properties": { "tokenRequired": { "type": "boolean" } } } } } } } ================================================ FILE: lexicons/com/atproto/server/requestPasswordReset.json ================================================ { "lexicon": 1, "id": "com.atproto.server.requestPasswordReset", "defs": { "main": { "type": "procedure", "description": "Initiate a user account password reset via email.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string" } } } } } } } ================================================ FILE: lexicons/com/atproto/server/reserveSigningKey.json ================================================ { "lexicon": 1, "id": "com.atproto.server.reserveSigningKey", "defs": { "main": { "type": "procedure", "description": "Reserve a repo signing key, for use with account creation. Necessary so that a DID PLC update operation can be constructed during an account migraiton. Public and does not require auth; implemented by PDS. NOTE: this endpoint may change when full account migration is implemented.", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "did": { "type": "string", "format": "did", "description": "The DID to reserve a key for." } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["signingKey"], "properties": { "signingKey": { "type": "string", "description": "The public key for the reserved signing key, in did:key serialization." } } } } } } } ================================================ FILE: lexicons/com/atproto/server/resetPassword.json ================================================ { "lexicon": 1, "id": "com.atproto.server.resetPassword", "defs": { "main": { "type": "procedure", "description": "Reset a user account password using a token.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["token", "password"], "properties": { "token": { "type": "string" }, "password": { "type": "string" } } } }, "errors": [{ "name": "ExpiredToken" }, { "name": "InvalidToken" }] } } } ================================================ FILE: lexicons/com/atproto/server/revokeAppPassword.json ================================================ { "lexicon": 1, "id": "com.atproto.server.revokeAppPassword", "defs": { "main": { "type": "procedure", "description": "Revoke an App Password by name.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string" } } } } } } } ================================================ FILE: lexicons/com/atproto/server/updateEmail.json ================================================ { "lexicon": 1, "id": "com.atproto.server.updateEmail", "defs": { "main": { "type": "procedure", "description": "Update an account's email.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string" }, "emailAuthFactor": { "type": "boolean" }, "token": { "type": "string", "description": "Requires a token from com.atproto.sever.requestEmailUpdate if the account's email has been confirmed." } } } }, "errors": [ { "name": "ExpiredToken" }, { "name": "InvalidToken" }, { "name": "TokenRequired" } ] } } } ================================================ FILE: lexicons/com/atproto/sync/defs.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.defs", "defs": { "hostStatus": { "type": "string", "knownValues": ["active", "idle", "offline", "throttled", "banned"] } } } ================================================ FILE: lexicons/com/atproto/sync/getBlob.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getBlob", "defs": { "main": { "type": "query", "description": "Get a blob associated with a given account. Returns the full blob as originally uploaded. Does not require auth; implemented by PDS.", "parameters": { "type": "params", "required": ["did", "cid"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the account." }, "cid": { "type": "string", "format": "cid", "description": "The CID of the blob to fetch" } } }, "output": { "encoding": "*/*" }, "errors": [ { "name": "BlobNotFound" }, { "name": "RepoNotFound" }, { "name": "RepoTakendown" }, { "name": "RepoSuspended" }, { "name": "RepoDeactivated" } ] } } } ================================================ FILE: lexicons/com/atproto/sync/getBlocks.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getBlocks", "defs": { "main": { "type": "query", "description": "Get data blocks from a given repo, by CID. For example, intermediate MST nodes, or records. Does not require auth; implemented by PDS.", "parameters": { "type": "params", "required": ["did", "cids"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." }, "cids": { "type": "array", "items": { "type": "string", "format": "cid" } } } }, "output": { "encoding": "application/vnd.ipld.car" }, "errors": [ { "name": "BlockNotFound" }, { "name": "RepoNotFound" }, { "name": "RepoTakendown" }, { "name": "RepoSuspended" }, { "name": "RepoDeactivated" } ] } } } ================================================ FILE: lexicons/com/atproto/sync/getCheckout.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getCheckout", "defs": { "main": { "type": "query", "description": "DEPRECATED - please use com.atproto.sync.getRepo instead", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." } } }, "output": { "encoding": "application/vnd.ipld.car" } } } } ================================================ FILE: lexicons/com/atproto/sync/getHead.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getHead", "defs": { "main": { "type": "query", "description": "DEPRECATED - please use com.atproto.sync.getLatestCommit instead", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["root"], "properties": { "root": { "type": "string", "format": "cid" } } } }, "errors": [{ "name": "HeadNotFound" }] } } } ================================================ FILE: lexicons/com/atproto/sync/getHostStatus.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getHostStatus", "defs": { "main": { "type": "query", "description": "Returns information about a specified upstream host, as consumed by the server. Implemented by relays.", "parameters": { "type": "params", "required": ["hostname"], "properties": { "hostname": { "type": "string", "description": "Hostname of the host (eg, PDS or relay) being queried." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["hostname"], "properties": { "hostname": { "type": "string" }, "seq": { "type": "integer", "description": "Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor)." }, "accountCount": { "type": "integer", "description": "Number of accounts on the server which are associated with the upstream host. Note that the upstream may actually have more accounts." }, "status": { "type": "ref", "ref": "com.atproto.sync.defs#hostStatus" } } } }, "errors": [{ "name": "HostNotFound" }] } } } ================================================ FILE: lexicons/com/atproto/sync/getLatestCommit.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getLatestCommit", "defs": { "main": { "type": "query", "description": "Get the current commit CID & revision of the specified repo. Does not require auth.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["cid", "rev"], "properties": { "cid": { "type": "string", "format": "cid" }, "rev": { "type": "string", "format": "tid" } } } }, "errors": [ { "name": "RepoNotFound" }, { "name": "RepoTakendown" }, { "name": "RepoSuspended" }, { "name": "RepoDeactivated" } ] } } } ================================================ FILE: lexicons/com/atproto/sync/getRecord.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getRecord", "defs": { "main": { "type": "query", "description": "Get data blocks needed to prove the existence or non-existence of record in the current version of repo. Does not require auth.", "parameters": { "type": "params", "required": ["did", "collection", "rkey"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." }, "collection": { "type": "string", "format": "nsid" }, "rkey": { "type": "string", "description": "Record Key", "format": "record-key" } } }, "output": { "encoding": "application/vnd.ipld.car" }, "errors": [ { "name": "RecordNotFound" }, { "name": "RepoNotFound" }, { "name": "RepoTakendown" }, { "name": "RepoSuspended" }, { "name": "RepoDeactivated" } ] } } } ================================================ FILE: lexicons/com/atproto/sync/getRepo.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getRepo", "defs": { "main": { "type": "query", "description": "Download a repository export as CAR file. Optionally only a 'diff' since a previous revision. Does not require auth; implemented by PDS.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." }, "since": { "type": "string", "format": "tid", "description": "The revision ('rev') of the repo to create a diff from." } } }, "output": { "encoding": "application/vnd.ipld.car" }, "errors": [ { "name": "RepoNotFound" }, { "name": "RepoTakendown" }, { "name": "RepoSuspended" }, { "name": "RepoDeactivated" } ] } } } ================================================ FILE: lexicons/com/atproto/sync/getRepoStatus.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.getRepoStatus", "defs": { "main": { "type": "query", "description": "Get the hosting status for a repository, on this server. Expected to be implemented by PDS and Relay.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "active"], "properties": { "did": { "type": "string", "format": "did" }, "active": { "type": "boolean" }, "status": { "type": "string", "description": "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", "knownValues": [ "takendown", "suspended", "deleted", "deactivated", "desynchronized", "throttled" ] }, "rev": { "type": "string", "format": "tid", "description": "Optional field, the current rev of the repo, if active=true" } } } }, "errors": [{ "name": "RepoNotFound" }] } } } ================================================ FILE: lexicons/com/atproto/sync/listBlobs.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.listBlobs", "defs": { "main": { "type": "query", "description": "List blob CIDs for an account, since some repo revision. Does not require auth; implemented by PDS.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did", "description": "The DID of the repo." }, "since": { "type": "string", "format": "tid", "description": "Optional revision of the repo to list blobs since." }, "limit": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 500 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["cids"], "properties": { "cursor": { "type": "string" }, "cids": { "type": "array", "items": { "type": "string", "format": "cid" } } } } }, "errors": [ { "name": "RepoNotFound" }, { "name": "RepoTakendown" }, { "name": "RepoSuspended" }, { "name": "RepoDeactivated" } ] } } } ================================================ FILE: lexicons/com/atproto/sync/listHosts.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.listHosts", "defs": { "main": { "type": "query", "description": "Enumerates upstream hosts (eg, PDS or relay instances) that this service consumes from. Implemented by relays.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 200 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["hosts"], "properties": { "cursor": { "type": "string" }, "hosts": { "type": "array", "items": { "type": "ref", "ref": "#host" }, "description": "Sort order is not formally specified. Recommended order is by time host was first seen by the server, with oldest first." } } } } }, "host": { "type": "object", "required": ["hostname"], "properties": { "hostname": { "type": "string", "description": "hostname of server; not a URL (no scheme)" }, "seq": { "type": "integer", "description": "Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor)." }, "accountCount": { "type": "integer" }, "status": { "type": "ref", "ref": "com.atproto.sync.defs#hostStatus" } } } } } ================================================ FILE: lexicons/com/atproto/sync/listRepos.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.listRepos", "defs": { "main": { "type": "query", "description": "Enumerates all the DID, rev, and commit CID for all repos hosted by this service. Does not require auth; implemented by PDS and Relay.", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 500 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["repos"], "properties": { "cursor": { "type": "string" }, "repos": { "type": "array", "items": { "type": "ref", "ref": "#repo" } } } } } }, "repo": { "type": "object", "required": ["did", "head", "rev"], "properties": { "did": { "type": "string", "format": "did" }, "head": { "type": "string", "format": "cid", "description": "Current repo commit CID" }, "rev": { "type": "string", "format": "tid" }, "active": { "type": "boolean" }, "status": { "type": "string", "description": "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", "knownValues": [ "takendown", "suspended", "deleted", "deactivated", "desynchronized", "throttled" ] } } } } } ================================================ FILE: lexicons/com/atproto/sync/listReposByCollection.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.listReposByCollection", "defs": { "main": { "type": "query", "description": "Enumerates all the DIDs which have records with the given collection NSID.", "parameters": { "type": "params", "required": ["collection"], "properties": { "collection": { "type": "string", "format": "nsid" }, "limit": { "type": "integer", "description": "Maximum size of response set. Recommend setting a large maximum (1000+) when enumerating large DID lists.", "minimum": 1, "maximum": 2000, "default": 500 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["repos"], "properties": { "cursor": { "type": "string" }, "repos": { "type": "array", "items": { "type": "ref", "ref": "#repo" } } } } } }, "repo": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } } } } ================================================ FILE: lexicons/com/atproto/sync/notifyOfUpdate.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.notifyOfUpdate", "defs": { "main": { "type": "procedure", "description": "Notify a crawling service of a recent update, and that crawling should resume. Intended use is after a gap between repo stream events caused the crawling service to disconnect. Does not require auth; implemented by Relay. DEPRECATED: just use com.atproto.sync.requestCrawl", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["hostname"], "properties": { "hostname": { "type": "string", "description": "Hostname of the current service (usually a PDS) that is notifying of update." } } } } } } } ================================================ FILE: lexicons/com/atproto/sync/requestCrawl.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.requestCrawl", "defs": { "main": { "type": "procedure", "description": "Request a service to persistently crawl hosted repos. Expected use is new PDS instances declaring their existence to Relays. Does not require auth.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["hostname"], "properties": { "hostname": { "type": "string", "description": "Hostname of the current service (eg, PDS) that is requesting to be crawled." } } } }, "errors": [{ "name": "HostBanned" }] } } } ================================================ FILE: lexicons/com/atproto/sync/subscribeRepos.json ================================================ { "lexicon": 1, "id": "com.atproto.sync.subscribeRepos", "defs": { "main": { "type": "subscription", "description": "Repository event stream, aka Firehose endpoint. Outputs repo commits with diff data, and identity update events, for all repositories on the current server. See the atproto specifications for details around stream sequencing, repo versioning, CAR diff format, and more. Public and does not require auth; implemented by PDS and Relay.", "parameters": { "type": "params", "properties": { "cursor": { "type": "integer", "description": "The last known event seq number to backfill from." } } }, "message": { "schema": { "type": "union", "refs": ["#commit", "#sync", "#identity", "#account", "#info"] } }, "errors": [ { "name": "FutureCursor" }, { "name": "ConsumerTooSlow", "description": "If the consumer of the stream can not keep up with events, and a backlog gets too large, the server will drop the connection." } ] }, "commit": { "type": "object", "description": "Represents an update of repository state. Note that empty commits are allowed, which include no repo data changes, but an update to rev and signature.", "required": [ "seq", "rebase", "tooBig", "repo", "commit", "rev", "since", "blocks", "ops", "blobs", "time" ], "nullable": ["since"], "properties": { "seq": { "type": "integer", "description": "The stream sequence number of this message." }, "rebase": { "type": "boolean", "description": "DEPRECATED -- unused" }, "tooBig": { "type": "boolean", "description": "DEPRECATED -- replaced by #sync event and data limits. Indicates that this commit contained too many ops, or data size was too large. Consumers will need to make a separate request to get missing data." }, "repo": { "type": "string", "format": "did", "description": "The repo this event comes from. Note that all other message types name this field 'did'." }, "commit": { "type": "cid-link", "description": "Repo commit object CID." }, "rev": { "type": "string", "format": "tid", "description": "The rev of the emitted commit. Note that this information is also in the commit object included in blocks, unless this is a tooBig event." }, "since": { "type": "string", "format": "tid", "description": "The rev of the last emitted commit from this repo (if any)." }, "blocks": { "type": "bytes", "description": "CAR file containing relevant blocks, as a diff since the previous repo state. The commit must be included as a block, and the commit block CID must be the first entry in the CAR header 'roots' list.", "maxLength": 2000000 }, "ops": { "type": "array", "items": { "type": "ref", "ref": "#repoOp", "description": "List of repo mutation operations in this commit (eg, records created, updated, or deleted)." }, "maxLength": 200 }, "blobs": { "type": "array", "items": { "type": "cid-link", "description": "DEPRECATED -- will soon always be empty. List of new blobs (by CID) referenced by records in this commit." } }, "prevData": { "type": "cid-link", "description": "The root CID of the MST tree for the previous commit from this repo (indicated by the 'since' revision field in this message). Corresponds to the 'data' field in the repo commit object. NOTE: this field is effectively required for the 'inductive' version of firehose." }, "time": { "type": "string", "format": "datetime", "description": "Timestamp of when this message was originally broadcast." } } }, "sync": { "type": "object", "description": "Updates the repo to a new state, without necessarily including that state on the firehose. Used to recover from broken commit streams, data loss incidents, or in situations where upstream host does not know recent state of the repository.", "required": ["seq", "did", "blocks", "rev", "time"], "properties": { "seq": { "type": "integer", "description": "The stream sequence number of this message." }, "did": { "type": "string", "format": "did", "description": "The account this repo event corresponds to. Must match that in the commit object." }, "blocks": { "type": "bytes", "description": "CAR file containing the commit, as a block. The CAR header must include the commit block CID as the first 'root'.", "maxLength": 10000 }, "rev": { "type": "string", "description": "The rev of the commit. This value must match that in the commit object." }, "time": { "type": "string", "format": "datetime", "description": "Timestamp of when this message was originally broadcast." } } }, "identity": { "type": "object", "description": "Represents a change to an account's identity. Could be an updated handle, signing key, or pds hosting endpoint. Serves as a prod to all downstream services to refresh their identity cache.", "required": ["seq", "did", "time"], "properties": { "seq": { "type": "integer" }, "did": { "type": "string", "format": "did" }, "time": { "type": "string", "format": "datetime" }, "handle": { "type": "string", "format": "handle", "description": "The current handle for the account, or 'handle.invalid' if validation fails. This field is optional, might have been validated or passed-through from an upstream source. Semantics and behaviors for PDS vs Relay may evolve in the future; see atproto specs for more details." } } }, "account": { "type": "object", "description": "Represents a change to an account's status on a host (eg, PDS or Relay). The semantics of this event are that the status is at the host which emitted the event, not necessarily that at the currently active PDS. Eg, a Relay takedown would emit a takedown with active=false, even if the PDS is still active.", "required": ["seq", "did", "time", "active"], "properties": { "seq": { "type": "integer" }, "did": { "type": "string", "format": "did" }, "time": { "type": "string", "format": "datetime" }, "active": { "type": "boolean", "description": "Indicates that the account has a repository which can be fetched from the host that emitted this event." }, "status": { "type": "string", "description": "If active=false, this optional field indicates a reason for why the account is not active.", "knownValues": [ "takendown", "suspended", "deleted", "deactivated", "desynchronized", "throttled" ] } } }, "info": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "knownValues": ["OutdatedCursor"] }, "message": { "type": "string" } } }, "repoOp": { "type": "object", "description": "A repo operation, ie a mutation of a single record.", "required": ["action", "path", "cid"], "nullable": ["cid"], "properties": { "action": { "type": "string", "knownValues": ["create", "update", "delete"] }, "path": { "type": "string" }, "cid": { "type": "cid-link", "description": "For creates and updates, the new record CID. For deletions, null." }, "prev": { "type": "cid-link", "description": "For updates and deletes, the previous record CID (required for inductive firehose). For creations, field should not be defined." } } } } } ================================================ FILE: lexicons/com/atproto/temp/addReservedHandle.json ================================================ { "lexicon": 1, "id": "com.atproto.temp.addReservedHandle", "defs": { "main": { "type": "procedure", "description": "Add a handle to the set of reserved handles.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["handle"], "properties": { "handle": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } } } } ================================================ FILE: lexicons/com/atproto/temp/checkHandleAvailability.json ================================================ { "lexicon": 1, "id": "com.atproto.temp.checkHandleAvailability", "defs": { "main": { "type": "query", "description": "Checks whether the provided handle is available. If the handle is not available, available suggestions will be returned. Optional inputs will be used to generate suggestions.", "parameters": { "type": "params", "required": ["handle"], "properties": { "handle": { "type": "string", "format": "handle", "description": "Tentative handle. Will be checked for availability or used to build handle suggestions." }, "email": { "type": "string", "description": "User-provided email. Might be used to build handle suggestions." }, "birthDate": { "type": "string", "format": "datetime", "description": "User-provided birth date. Might be used to build handle suggestions." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["handle", "result"], "properties": { "handle": { "type": "string", "format": "handle", "description": "Echo of the input handle." }, "result": { "type": "union", "refs": ["#resultAvailable", "#resultUnavailable"] } } } }, "errors": [ { "name": "InvalidEmail", "description": "An invalid email was provided." } ] }, "resultAvailable": { "type": "object", "description": "Indicates the provided handle is available.", "properties": {} }, "resultUnavailable": { "type": "object", "description": "Indicates the provided handle is unavailable and gives suggestions of available handles.", "required": ["suggestions"], "properties": { "suggestions": { "type": "array", "description": "List of suggested handles based on the provided inputs.", "items": { "type": "ref", "ref": "#suggestion" } } } }, "suggestion": { "type": "object", "required": ["handle", "method"], "properties": { "handle": { "type": "string", "format": "handle" }, "method": { "type": "string", "description": "Method used to build this suggestion. Should be considered opaque to clients. Can be used for metrics." } } } } } ================================================ FILE: lexicons/com/atproto/temp/checkSignupQueue.json ================================================ { "lexicon": 1, "id": "com.atproto.temp.checkSignupQueue", "defs": { "main": { "type": "query", "description": "Check accounts location in signup queue.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["activated"], "properties": { "activated": { "type": "boolean" }, "placeInQueue": { "type": "integer" }, "estimatedTimeMs": { "type": "integer" } } } } } } } ================================================ FILE: lexicons/com/atproto/temp/dereferenceScope.json ================================================ { "lexicon": 1, "id": "com.atproto.temp.dereferenceScope", "defs": { "main": { "type": "query", "description": "Allows finding the oauth permission scope from a reference", "parameters": { "type": "params", "required": ["scope"], "properties": { "scope": { "type": "string", "description": "The scope reference (starts with 'ref:')" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["scope"], "properties": { "scope": { "type": "string", "description": "The full oauth permission scope" } } } }, "errors": [ { "name": "InvalidScopeReference", "description": "An invalid scope reference was provided." } ] } } } ================================================ FILE: lexicons/com/atproto/temp/fetchLabels.json ================================================ { "lexicon": 1, "id": "com.atproto.temp.fetchLabels", "defs": { "main": { "type": "query", "description": "DEPRECATED: use queryLabels or subscribeLabels instead -- Fetch all labels from a labeler created after a certain date.", "parameters": { "type": "params", "properties": { "since": { "type": "integer" }, "limit": { "type": "integer", "minimum": 1, "maximum": 250, "default": 50 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["labels"], "properties": { "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } } } } } } } } ================================================ FILE: lexicons/com/atproto/temp/requestPhoneVerification.json ================================================ { "lexicon": 1, "id": "com.atproto.temp.requestPhoneVerification", "defs": { "main": { "type": "procedure", "description": "Request a verification code to be sent to the supplied phone number", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["phoneNumber"], "properties": { "phoneNumber": { "type": "string" } } } } } } } ================================================ FILE: lexicons/com/atproto/temp/revokeAccountCredentials.json ================================================ { "lexicon": 1, "id": "com.atproto.temp.revokeAccountCredentials", "defs": { "main": { "type": "procedure", "description": "Revoke sessions, password, and app passwords associated with account. May be resolved by a password reset.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["account"], "properties": { "account": { "type": "string", "format": "at-identifier" } } } } } } } ================================================ FILE: lexicons/com/germnetwork/declaration.json ================================================ { "lexicon": 1, "id": "com.germnetwork.declaration", "defs": { "main": { "type": "record", "description": "A declaration of a Germ Network account", "key": "literal:self", "record": { "type": "object", "required": ["version", "currentKey"], "properties": { "version": { "type": "string", "description": "Semver version number, without pre-release or build information, for the format of opaque content", "minLength": 5, "maxLength": 14 }, "currentKey": { "type": "bytes", "description": "Opaque value, an ed25519 public key prefixed with a byte enum" }, "messageMe": { "type": "ref", "description": "Controls who can message this account", "ref": "#messageMe" }, "keyPackage": { "type": "bytes", "description": "Opaque value, contains MLS KeyPackage(s), and other signature data, and is signed by the currentKey" }, "continuityProofs": { "type": "array", "description": "Array of opaque values to allow for key rolling", "items": { "type": "bytes" }, "maxLength": 1000 } } } }, "messageMe": { "type": "object", "required": ["showButtonTo", "messageMeUrl"], "properties": { "messageMeUrl": { "type": "string", "description": "A URL to present to an account that does not have its own com.germnetwork.declaration record, must have an empty fragment component, where the app should fill in the fragment component with the DIDs of the two accounts who wish to message each other", "format": "uri", "minLength": 1, "maxLength": 2047 }, "showButtonTo": { "type": "string", "knownValues": ["none", "usersIFollow", "everyone"], "description": "The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer.", "minLength": 1, "maxLength": 100 } } } } } ================================================ FILE: lexicons/tools/ozone/communication/createTemplate.json ================================================ { "lexicon": 1, "id": "tools.ozone.communication.createTemplate", "defs": { "main": { "type": "procedure", "description": "Administrative action to create a new, re-usable communication (email for now) template.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["subject", "contentMarkdown", "name"], "properties": { "name": { "type": "string", "description": "Name of the template." }, "contentMarkdown": { "type": "string", "description": "Content of the template, markdown supported, can contain variable placeholders." }, "subject": { "type": "string", "description": "Subject of the message, used in emails." }, "lang": { "type": "string", "format": "language", "description": "Message language." }, "createdBy": { "type": "string", "format": "did", "description": "DID of the user who is creating the template." } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.communication.defs#templateView" } }, "errors": [{ "name": "DuplicateTemplateName" }] } } } ================================================ FILE: lexicons/tools/ozone/communication/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.communication.defs", "defs": { "templateView": { "type": "object", "required": [ "id", "name", "contentMarkdown", "disabled", "lastUpdatedBy", "createdAt", "updatedAt" ], "properties": { "id": { "type": "string" }, "name": { "type": "string", "description": "Name of the template." }, "subject": { "type": "string", "description": "Content of the template, can contain markdown and variable placeholders." }, "contentMarkdown": { "type": "string", "description": "Subject of the message, used in emails." }, "disabled": { "type": "boolean" }, "lang": { "type": "string", "format": "language", "description": "Message language." }, "lastUpdatedBy": { "type": "string", "format": "did", "description": "DID of the user who last updated the template." }, "createdAt": { "type": "string", "format": "datetime" }, "updatedAt": { "type": "string", "format": "datetime" } } } } } ================================================ FILE: lexicons/tools/ozone/communication/deleteTemplate.json ================================================ { "lexicon": 1, "id": "tools.ozone.communication.deleteTemplate", "defs": { "main": { "type": "procedure", "description": "Delete a communication template.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["id"], "properties": { "id": { "type": "string" } } } } } } } ================================================ FILE: lexicons/tools/ozone/communication/listTemplates.json ================================================ { "lexicon": 1, "id": "tools.ozone.communication.listTemplates", "defs": { "main": { "type": "query", "description": "Get list of all communication templates.", "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["communicationTemplates"], "properties": { "communicationTemplates": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.communication.defs#templateView" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/communication/updateTemplate.json ================================================ { "lexicon": 1, "id": "tools.ozone.communication.updateTemplate", "defs": { "main": { "type": "procedure", "description": "Administrative action to update an existing communication template. Allows passing partial fields to patch specific fields only.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["id"], "properties": { "id": { "type": "string", "description": "ID of the template to be updated." }, "name": { "type": "string", "description": "Name of the template." }, "lang": { "type": "string", "format": "language", "description": "Message language." }, "contentMarkdown": { "type": "string", "description": "Content of the template, markdown supported, can contain variable placeholders." }, "subject": { "type": "string", "description": "Subject of the message, used in emails." }, "updatedBy": { "type": "string", "format": "did", "description": "DID of the user who is updating the template." }, "disabled": { "type": "boolean" } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.communication.defs#templateView" } }, "errors": [{ "name": "DuplicateTemplateName" }] } } } ================================================ FILE: lexicons/tools/ozone/hosting/getAccountHistory.json ================================================ { "lexicon": 1, "id": "tools.ozone.hosting.getAccountHistory", "defs": { "main": { "type": "query", "description": "Get account history, e.g. log of updated email addresses or other identity information.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" }, "events": { "type": "array", "items": { "type": "string", "knownValues": [ "accountCreated", "emailUpdated", "emailConfirmed", "passwordUpdated", "handleUpdated" ] } }, "cursor": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["events"], "properties": { "cursor": { "type": "string" }, "events": { "type": "array", "items": { "type": "ref", "ref": "#event" } } } } } }, "event": { "type": "object", "required": ["details", "createdBy", "createdAt"], "properties": { "details": { "type": "union", "refs": [ "#accountCreated", "#emailUpdated", "#emailConfirmed", "#passwordUpdated", "#handleUpdated" ] }, "createdBy": { "type": "string" }, "createdAt": { "type": "string", "format": "datetime" } } }, "accountCreated": { "type": "object", "required": [], "properties": { "email": { "type": "string" }, "handle": { "type": "string", "format": "handle" } } }, "emailUpdated": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string" } } }, "emailConfirmed": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string" } } }, "passwordUpdated": { "type": "object", "required": [], "properties": {} }, "handleUpdated": { "type": "object", "required": ["handle"], "properties": { "handle": { "type": "string", "format": "handle" } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/cancelScheduledActions.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.cancelScheduledActions", "defs": { "main": { "type": "procedure", "description": "Cancel all pending scheduled moderation actions for specified subjects", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["subjects"], "properties": { "subjects": { "type": "array", "maxLength": 100, "items": { "type": "string", "format": "did" }, "description": "Array of DID subjects to cancel scheduled actions for" }, "comment": { "type": "string", "description": "Optional comment describing the reason for cancellation" } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "#cancellationResults" } } }, "cancellationResults": { "type": "object", "required": ["succeeded", "failed"], "properties": { "succeeded": { "type": "array", "items": { "type": "string", "format": "did" }, "description": "DIDs for which all pending scheduled actions were successfully cancelled" }, "failed": { "type": "array", "items": { "type": "ref", "ref": "#failedCancellation" }, "description": "DIDs for which cancellation failed with error details" } } }, "failedCancellation": { "type": "object", "required": ["did", "error"], "properties": { "did": { "type": "string", "format": "did" }, "error": { "type": "string" }, "errorCode": { "type": "string" } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.defs", "defs": { "modEventView": { "type": "object", "required": [ "id", "event", "subject", "subjectBlobCids", "createdBy", "createdAt" ], "properties": { "id": { "type": "integer" }, "event": { "type": "union", "refs": [ "#modEventTakedown", "#modEventReverseTakedown", "#modEventComment", "#modEventReport", "#modEventLabel", "#modEventAcknowledge", "#modEventEscalate", "#modEventMute", "#modEventUnmute", "#modEventMuteReporter", "#modEventUnmuteReporter", "#modEventEmail", "#modEventResolveAppeal", "#modEventDivert", "#modEventTag", "#accountEvent", "#identityEvent", "#recordEvent", "#modEventPriorityScore", "#ageAssuranceEvent", "#ageAssuranceOverrideEvent", "#ageAssurancePurgeEvent", "#revokeAccountCredentialsEvent", "#scheduleTakedownEvent", "#cancelScheduledTakedownEvent" ] }, "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef", "chat.bsky.convo.defs#messageRef" ] }, "subjectBlobCids": { "type": "array", "items": { "type": "string" } }, "createdBy": { "type": "string", "format": "did" }, "createdAt": { "type": "string", "format": "datetime" }, "creatorHandle": { "type": "string" }, "subjectHandle": { "type": "string" }, "modTool": { "type": "ref", "ref": "#modTool" } } }, "modEventViewDetail": { "type": "object", "required": [ "id", "event", "subject", "subjectBlobs", "createdBy", "createdAt" ], "properties": { "id": { "type": "integer" }, "event": { "type": "union", "refs": [ "#modEventTakedown", "#modEventReverseTakedown", "#modEventComment", "#modEventReport", "#modEventLabel", "#modEventAcknowledge", "#modEventEscalate", "#modEventMute", "#modEventUnmute", "#modEventMuteReporter", "#modEventUnmuteReporter", "#modEventEmail", "#modEventResolveAppeal", "#modEventDivert", "#modEventTag", "#accountEvent", "#identityEvent", "#recordEvent", "#modEventPriorityScore", "#ageAssuranceEvent", "#ageAssuranceOverrideEvent", "#ageAssurancePurgeEvent", "#revokeAccountCredentialsEvent", "#scheduleTakedownEvent", "#cancelScheduledTakedownEvent" ] }, "subject": { "type": "union", "refs": [ "#repoView", "#repoViewNotFound", "#recordView", "#recordViewNotFound" ] }, "subjectBlobs": { "type": "array", "items": { "type": "ref", "ref": "#blobView" } }, "createdBy": { "type": "string", "format": "did" }, "createdAt": { "type": "string", "format": "datetime" }, "modTool": { "type": "ref", "ref": "#modTool" } } }, "subjectStatusView": { "type": "object", "required": ["id", "subject", "createdAt", "updatedAt", "reviewState"], "properties": { "id": { "type": "integer" }, "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef", "chat.bsky.convo.defs#messageRef" ] }, "hosting": { "type": "union", "refs": ["#accountHosting", "#recordHosting"] }, "subjectBlobCids": { "type": "array", "items": { "type": "string", "format": "cid" } }, "subjectRepoHandle": { "type": "string" }, "updatedAt": { "type": "string", "format": "datetime", "description": "Timestamp referencing when the last update was made to the moderation status of the subject" }, "createdAt": { "type": "string", "format": "datetime", "description": "Timestamp referencing the first moderation status impacting event was emitted on the subject" }, "reviewState": { "type": "ref", "ref": "#subjectReviewState" }, "comment": { "type": "string", "description": "Sticky comment on the subject." }, "priorityScore": { "type": "integer", "description": "Numeric value representing the level of priority. Higher score means higher priority.", "minimum": 0, "maximum": 100 }, "muteUntil": { "type": "string", "format": "datetime" }, "muteReportingUntil": { "type": "string", "format": "datetime" }, "lastReviewedBy": { "type": "string", "format": "did" }, "lastReviewedAt": { "type": "string", "format": "datetime" }, "lastReportedAt": { "type": "string", "format": "datetime" }, "lastAppealedAt": { "type": "string", "format": "datetime", "description": "Timestamp referencing when the author of the subject appealed a moderation action" }, "takendown": { "type": "boolean" }, "appealed": { "type": "boolean", "description": "True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators." }, "suspendUntil": { "type": "string", "format": "datetime" }, "tags": { "type": "array", "items": { "type": "string" } }, "accountStats": { "description": "Statistics related to the account subject", "type": "ref", "ref": "#accountStats" }, "recordsStats": { "description": "Statistics related to the record subjects authored by the subject's account", "type": "ref", "ref": "#recordsStats" }, "accountStrike": { "description": "Strike information for the account (account-level only)", "type": "ref", "ref": "#accountStrike" }, "ageAssuranceState": { "type": "string", "description": "Current age assurance state of the subject.", "knownValues": ["pending", "assured", "unknown", "reset", "blocked"] }, "ageAssuranceUpdatedBy": { "type": "string", "description": "Whether or not the last successful update to age assurance was made by the user or admin.", "knownValues": ["admin", "user"] } } }, "subjectView": { "description": "Detailed view of a subject. For record subjects, the author's repo and profile will be returned.", "type": "object", "required": ["type", "subject"], "properties": { "type": { "type": "ref", "ref": "com.atproto.moderation.defs#subjectType" }, "subject": { "type": "string" }, "status": { "type": "ref", "ref": "#subjectStatusView" }, "repo": { "type": "ref", "ref": "#repoViewDetail" }, "profile": { "type": "union", "refs": [] }, "record": { "type": "ref", "ref": "#recordViewDetail" } } }, "accountStats": { "description": "Statistics about a particular account subject", "type": "object", "properties": { "reportCount": { "description": "Total number of reports on the account", "type": "integer" }, "appealCount": { "description": "Total number of appeals against a moderation action on the account", "type": "integer" }, "suspendCount": { "description": "Number of times the account was suspended", "type": "integer" }, "escalateCount": { "description": "Number of times the account was escalated", "type": "integer" }, "takedownCount": { "description": "Number of times the account was taken down", "type": "integer" } } }, "recordsStats": { "description": "Statistics about a set of record subject items", "type": "object", "properties": { "totalReports": { "description": "Cumulative sum of the number of reports on the items in the set", "type": "integer" }, "reportedCount": { "description": "Number of items that were reported at least once", "type": "integer" }, "escalatedCount": { "description": "Number of items that were escalated at least once", "type": "integer" }, "appealedCount": { "description": "Number of items that were appealed at least once", "type": "integer" }, "subjectCount": { "description": "Total number of item in the set", "type": "integer" }, "pendingCount": { "description": "Number of item currently in \"reviewOpen\" or \"reviewEscalated\" state", "type": "integer" }, "processedCount": { "description": "Number of item currently in \"reviewNone\" or \"reviewClosed\" state", "type": "integer" }, "takendownCount": { "description": "Number of item currently taken down", "type": "integer" } } }, "accountStrike": { "description": "Strike information for an account", "type": "object", "properties": { "activeStrikeCount": { "description": "Current number of active strikes (excluding expired strikes)", "type": "integer" }, "totalStrikeCount": { "description": "Total number of strikes ever received (including expired strikes)", "type": "integer" }, "firstStrikeAt": { "description": "Timestamp of the first strike received", "type": "string", "format": "datetime" }, "lastStrikeAt": { "description": "Timestamp of the most recent strike received", "type": "string", "format": "datetime" } } }, "subjectReviewState": { "type": "string", "knownValues": [ "tools.ozone.moderation.defs#reviewOpen", "tools.ozone.moderation.defs#reviewEscalated", "tools.ozone.moderation.defs#reviewClosed", "tools.ozone.moderation.defs#reviewNone" ] }, "reviewOpen": { "type": "token", "description": "Moderator review status of a subject: Open. Indicates that the subject needs to be reviewed by a moderator" }, "reviewEscalated": { "type": "token", "description": "Moderator review status of a subject: Escalated. Indicates that the subject was escalated for review by a moderator" }, "reviewClosed": { "type": "token", "description": "Moderator review status of a subject: Closed. Indicates that the subject was already reviewed and resolved by a moderator" }, "reviewNone": { "type": "token", "description": "Moderator review status of a subject: Unnecessary. Indicates that the subject does not need a review at the moment but there is probably some moderation related metadata available for it" }, "modEventTakedown": { "type": "object", "description": "Take down a subject permanently or temporarily", "properties": { "comment": { "type": "string" }, "durationInHours": { "type": "integer", "description": "Indicates how long the takedown should be in effect before automatically expiring." }, "acknowledgeAccountSubjects": { "type": "boolean", "description": "If true, all other reports on content authored by this account will be resolved (acknowledged)." }, "policies": { "type": "array", "maxLength": 5, "items": { "type": "string" }, "description": "Names/Keywords of the policies that drove the decision." }, "severityLevel": { "type": "string", "description": "Severity level of the violation (e.g., 'sev-0', 'sev-1', 'sev-2', etc.)." }, "targetServices": { "type": "array", "items": { "type": "string", "knownValues": ["appview", "pds"] }, "description": "List of services where the takedown should be applied. If empty or not provided, takedown is applied on all configured services." }, "strikeCount": { "type": "integer", "description": "Number of strikes to assign to the user for this violation." }, "strikeExpiresAt": { "type": "string", "format": "datetime", "description": "When the strike should expire. If not provided, the strike never expires." } } }, "modEventReverseTakedown": { "type": "object", "description": "Revert take down action on a subject", "properties": { "comment": { "type": "string", "description": "Describe reasoning behind the reversal." }, "policies": { "type": "array", "maxLength": 5, "items": { "type": "string" }, "description": "Names/Keywords of the policy infraction for which takedown is being reversed." }, "severityLevel": { "type": "string", "description": "Severity level of the violation. Usually set from the last policy infraction's severity." }, "strikeCount": { "type": "integer", "description": "Number of strikes to subtract from the user's strike count. Usually set from the last policy infraction's severity." } } }, "modEventResolveAppeal": { "type": "object", "description": "Resolve appeal on a subject", "properties": { "comment": { "type": "string", "description": "Describe resolution." } } }, "modEventComment": { "type": "object", "description": "Add a comment to a subject. An empty comment will clear any previously set sticky comment.", "properties": { "comment": { "type": "string" }, "sticky": { "type": "boolean", "description": "Make the comment persistent on the subject" } } }, "modEventReport": { "type": "object", "description": "Report a subject", "required": ["reportType"], "properties": { "comment": { "type": "string" }, "isReporterMuted": { "type": "boolean", "description": "Set to true if the reporter was muted from reporting at the time of the event. These reports won't impact the reviewState of the subject." }, "reportType": { "type": "ref", "ref": "com.atproto.moderation.defs#reasonType" } } }, "modEventLabel": { "type": "object", "description": "Apply/Negate labels on a subject", "required": ["createLabelVals", "negateLabelVals"], "properties": { "comment": { "type": "string" }, "createLabelVals": { "type": "array", "items": { "type": "string" } }, "negateLabelVals": { "type": "array", "items": { "type": "string" } }, "durationInHours": { "type": "integer", "description": "Indicates how long the label will remain on the subject. Only applies on labels that are being added." } } }, "modEventPriorityScore": { "type": "object", "description": "Set priority score of the subject. Higher score means higher priority.", "required": ["score"], "properties": { "comment": { "type": "string" }, "score": { "type": "integer", "minimum": 0, "maximum": 100 } } }, "ageAssuranceEvent": { "type": "object", "description": "Age assurance info coming directly from users. Only works on DID subjects.", "required": ["createdAt", "status", "attemptId"], "properties": { "createdAt": { "type": "string", "format": "datetime", "description": "The date and time of this write operation." }, "attemptId": { "type": "string", "description": "The unique identifier for this instance of the age assurance flow, in UUID format." }, "status": { "type": "string", "description": "The status of the Age Assurance process.", "knownValues": ["unknown", "pending", "assured"] }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" }, "countryCode": { "type": "string", "description": "The ISO 3166-1 alpha-2 country code provided when beginning the Age Assurance flow." }, "regionCode": { "type": "string", "description": "The ISO 3166-2 region code provided when beginning the Age Assurance flow." }, "initIp": { "type": "string", "description": "The IP address used when initiating the AA flow." }, "initUa": { "type": "string", "description": "The user agent used when initiating the AA flow." }, "completeIp": { "type": "string", "description": "The IP address used when completing the AA flow." }, "completeUa": { "type": "string", "description": "The user agent used when completing the AA flow." } } }, "ageAssuranceOverrideEvent": { "type": "object", "description": "Age assurance status override by moderators. Only works on DID subjects.", "required": ["comment", "status"], "properties": { "status": { "type": "string", "description": "The status to be set for the user decided by a moderator, overriding whatever value the user had previously. Use reset to default to original state.", "knownValues": ["assured", "reset", "blocked"] }, "access": { "type": "ref", "ref": "app.bsky.ageassurance.defs#access" }, "comment": { "type": "string", "minLength": 1, "description": "Comment describing the reason for the override." } } }, "ageAssurancePurgeEvent": { "type": "object", "description": "Purges all age assurance events for the subject. Only works on DID subjects. Moderator-only.", "required": ["comment"], "properties": { "comment": { "type": "string", "minLength": 1, "description": "Comment describing the reason for the purge." } } }, "revokeAccountCredentialsEvent": { "type": "object", "description": "Account credentials revocation by moderators. Only works on DID subjects.", "required": ["comment"], "properties": { "comment": { "minLength": 1, "type": "string", "description": "Comment describing the reason for the revocation." } } }, "modEventAcknowledge": { "type": "object", "properties": { "comment": { "type": "string" }, "acknowledgeAccountSubjects": { "type": "boolean", "description": "If true, all other reports on content authored by this account will be resolved (acknowledged)." } } }, "modEventEscalate": { "type": "object", "properties": { "comment": { "type": "string" } } }, "modEventMute": { "type": "object", "description": "Mute incoming reports on a subject", "required": ["durationInHours"], "properties": { "comment": { "type": "string" }, "durationInHours": { "type": "integer", "description": "Indicates how long the subject should remain muted." } } }, "modEventUnmute": { "type": "object", "description": "Unmute action on a subject", "properties": { "comment": { "type": "string", "description": "Describe reasoning behind the reversal." } } }, "modEventMuteReporter": { "type": "object", "description": "Mute incoming reports from an account", "properties": { "comment": { "type": "string" }, "durationInHours": { "type": "integer", "description": "Indicates how long the account should remain muted. Falsy value here means a permanent mute." } } }, "modEventUnmuteReporter": { "type": "object", "description": "Unmute incoming reports from an account", "properties": { "comment": { "type": "string", "description": "Describe reasoning behind the reversal." } } }, "modEventEmail": { "type": "object", "description": "Keep a log of outgoing email to a user", "required": ["subjectLine"], "properties": { "subjectLine": { "type": "string", "description": "The subject line of the email sent to the user." }, "content": { "type": "string", "description": "The content of the email sent to the user." }, "comment": { "type": "string", "description": "Additional comment about the outgoing comm." }, "policies": { "type": "array", "maxLength": 5, "items": { "type": "string" }, "description": "Names/Keywords of the policies that necessitated the email." }, "severityLevel": { "type": "string", "description": "Severity level of the violation. Normally 'sev-1' that adds strike on repeat offense" }, "strikeCount": { "type": "integer", "description": "Number of strikes to assign to the user for this violation. Normally 0 as an indicator of a warning and only added as a strike on a repeat offense." }, "strikeExpiresAt": { "type": "string", "format": "datetime", "description": "When the strike should expire. If not provided, the strike never expires." }, "isDelivered": { "type": "boolean", "description": "Indicates whether the email was successfully delivered to the user's inbox." } } }, "modEventDivert": { "type": "object", "description": "Divert a record's blobs to a 3rd party service for further scanning/tagging", "properties": { "comment": { "type": "string" } } }, "modEventTag": { "type": "object", "description": "Add/Remove a tag on a subject", "required": ["add", "remove"], "properties": { "add": { "type": "array", "items": { "type": "string" }, "description": "Tags to be added to the subject. If already exists, won't be duplicated." }, "remove": { "type": "array", "items": { "type": "string" }, "description": "Tags to be removed to the subject. Ignores a tag If it doesn't exist, won't be duplicated." }, "comment": { "type": "string", "description": "Additional comment about added/removed tags." } } }, "accountEvent": { "type": "object", "description": "Logs account status related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.", "required": ["timestamp", "active"], "properties": { "comment": { "type": "string" }, "active": { "type": "boolean", "description": "Indicates that the account has a repository which can be fetched from the host that emitted this event." }, "status": { "type": "string", "knownValues": [ "unknown", "deactivated", "deleted", "takendown", "suspended", "tombstoned" ] }, "timestamp": { "type": "string", "format": "datetime" } } }, "identityEvent": { "type": "object", "description": "Logs identity related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.", "required": ["timestamp"], "properties": { "comment": { "type": "string" }, "handle": { "type": "string", "format": "handle" }, "pdsHost": { "type": "string", "format": "uri" }, "tombstone": { "type": "boolean" }, "timestamp": { "type": "string", "format": "datetime" } } }, "recordEvent": { "type": "object", "description": "Logs lifecycle event on a record subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.", "required": ["timestamp", "op"], "properties": { "comment": { "type": "string" }, "op": { "type": "string", "knownValues": ["create", "update", "delete"] }, "cid": { "type": "string", "format": "cid" }, "timestamp": { "type": "string", "format": "datetime" } } }, "scheduleTakedownEvent": { "type": "object", "description": "Logs a scheduled takedown action for an account.", "properties": { "comment": { "type": "string" }, "executeAt": { "type": "string", "format": "datetime" }, "executeAfter": { "type": "string", "format": "datetime" }, "executeUntil": { "type": "string", "format": "datetime" } } }, "cancelScheduledTakedownEvent": { "type": "object", "description": "Logs cancellation of a scheduled takedown action for an account.", "properties": { "comment": { "type": "string" } } }, "repoView": { "type": "object", "required": [ "did", "handle", "relatedRecords", "indexedAt", "moderation" ], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" }, "email": { "type": "string" }, "relatedRecords": { "type": "array", "items": { "type": "unknown" } }, "indexedAt": { "type": "string", "format": "datetime" }, "moderation": { "type": "ref", "ref": "#moderation" }, "invitedBy": { "type": "ref", "ref": "com.atproto.server.defs#inviteCode" }, "invitesDisabled": { "type": "boolean" }, "inviteNote": { "type": "string" }, "deactivatedAt": { "type": "string", "format": "datetime" }, "threatSignatures": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.admin.defs#threatSignature" } } } }, "repoViewDetail": { "type": "object", "required": [ "did", "handle", "relatedRecords", "indexedAt", "moderation" ], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "format": "handle" }, "email": { "type": "string" }, "relatedRecords": { "type": "array", "items": { "type": "unknown" } }, "indexedAt": { "type": "string", "format": "datetime" }, "moderation": { "type": "ref", "ref": "#moderationDetail" }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "invitedBy": { "type": "ref", "ref": "com.atproto.server.defs#inviteCode" }, "invites": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.server.defs#inviteCode" } }, "invitesDisabled": { "type": "boolean" }, "inviteNote": { "type": "string" }, "emailConfirmedAt": { "type": "string", "format": "datetime" }, "deactivatedAt": { "type": "string", "format": "datetime" }, "threatSignatures": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.admin.defs#threatSignature" } } } }, "repoViewNotFound": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "recordView": { "type": "object", "required": [ "uri", "cid", "value", "blobCids", "indexedAt", "moderation", "repo" ], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "value": { "type": "unknown" }, "blobCids": { "type": "array", "items": { "type": "string", "format": "cid" } }, "indexedAt": { "type": "string", "format": "datetime" }, "moderation": { "type": "ref", "ref": "#moderation" }, "repo": { "type": "ref", "ref": "#repoView" } } }, "recordViewDetail": { "type": "object", "required": [ "uri", "cid", "value", "blobs", "indexedAt", "moderation", "repo" ], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" }, "value": { "type": "unknown" }, "blobs": { "type": "array", "items": { "type": "ref", "ref": "#blobView" } }, "labels": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } }, "indexedAt": { "type": "string", "format": "datetime" }, "moderation": { "type": "ref", "ref": "#moderationDetail" }, "repo": { "type": "ref", "ref": "#repoView" } } }, "recordViewNotFound": { "type": "object", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri" } } }, "moderation": { "type": "object", "properties": { "subjectStatus": { "type": "ref", "ref": "#subjectStatusView" } } }, "moderationDetail": { "type": "object", "properties": { "subjectStatus": { "type": "ref", "ref": "#subjectStatusView" } } }, "blobView": { "type": "object", "required": ["cid", "mimeType", "size", "createdAt"], "properties": { "cid": { "type": "string", "format": "cid" }, "mimeType": { "type": "string" }, "size": { "type": "integer" }, "createdAt": { "type": "string", "format": "datetime" }, "details": { "type": "union", "refs": ["#imageDetails", "#videoDetails"] }, "moderation": { "type": "ref", "ref": "#moderation" } } }, "imageDetails": { "type": "object", "required": ["width", "height"], "properties": { "width": { "type": "integer" }, "height": { "type": "integer" } } }, "videoDetails": { "type": "object", "required": ["width", "height", "length"], "properties": { "width": { "type": "integer" }, "height": { "type": "integer" }, "length": { "type": "integer" } } }, "accountHosting": { "type": "object", "required": ["status"], "properties": { "status": { "type": "string", "knownValues": [ "takendown", "suspended", "deleted", "deactivated", "unknown" ] }, "updatedAt": { "type": "string", "format": "datetime" }, "createdAt": { "type": "string", "format": "datetime" }, "deletedAt": { "type": "string", "format": "datetime" }, "deactivatedAt": { "type": "string", "format": "datetime" }, "reactivatedAt": { "type": "string", "format": "datetime" } } }, "recordHosting": { "type": "object", "required": ["status"], "properties": { "status": { "type": "string", "knownValues": ["deleted", "unknown"] }, "updatedAt": { "type": "string", "format": "datetime" }, "createdAt": { "type": "string", "format": "datetime" }, "deletedAt": { "type": "string", "format": "datetime" } } }, "reporterStats": { "type": "object", "required": [ "did", "accountReportCount", "recordReportCount", "reportedAccountCount", "reportedRecordCount", "takendownAccountCount", "takendownRecordCount", "labeledAccountCount", "labeledRecordCount" ], "properties": { "did": { "type": "string", "format": "did" }, "accountReportCount": { "type": "integer", "description": "The total number of reports made by the user on accounts." }, "recordReportCount": { "type": "integer", "description": "The total number of reports made by the user on records." }, "reportedAccountCount": { "type": "integer", "description": "The total number of accounts reported by the user." }, "reportedRecordCount": { "type": "integer", "description": "The total number of records reported by the user." }, "takendownAccountCount": { "type": "integer", "description": "The total number of accounts taken down as a result of the user's reports." }, "takendownRecordCount": { "type": "integer", "description": "The total number of records taken down as a result of the user's reports." }, "labeledAccountCount": { "type": "integer", "description": "The total number of accounts labeled as a result of the user's reports." }, "labeledRecordCount": { "type": "integer", "description": "The total number of records labeled as a result of the user's reports." } } }, "modTool": { "type": "object", "description": "Moderation tool information for tracing the source of the action", "required": ["name"], "properties": { "name": { "type": "string", "description": "Name/identifier of the source (e.g., 'automod', 'ozone/workspace')" }, "meta": { "type": "unknown", "description": "Additional arbitrary metadata about the source" } } }, "timelineEventPlcCreate": { "type": "token", "description": "Moderation event timeline event for a PLC create operation" }, "timelineEventPlcOperation": { "type": "token", "description": "Moderation event timeline event for generic PLC operation" }, "timelineEventPlcTombstone": { "type": "token", "description": "Moderation event timeline event for a PLC tombstone operation" }, "scheduledActionView": { "type": "object", "description": "View of a scheduled moderation action", "required": ["id", "action", "did", "createdBy", "createdAt", "status"], "properties": { "id": { "type": "integer", "description": "Auto-incrementing row ID" }, "action": { "type": "string", "knownValues": ["takedown"], "description": "Type of action to be executed" }, "eventData": { "type": "unknown", "description": "Serialized event object that will be propagated to the event when performed" }, "did": { "type": "string", "format": "did", "description": "Subject DID for the action" }, "executeAt": { "type": "string", "format": "datetime", "description": "Exact time to execute the action" }, "executeAfter": { "type": "string", "format": "datetime", "description": "Earliest time to execute the action (for randomized scheduling)" }, "executeUntil": { "type": "string", "format": "datetime", "description": "Latest time to execute the action (for randomized scheduling)" }, "randomizeExecution": { "type": "boolean", "description": "Whether execution time should be randomized within the specified range" }, "createdBy": { "type": "string", "format": "did", "description": "DID of the user who created this scheduled action" }, "createdAt": { "type": "string", "format": "datetime", "description": "When the scheduled action was created" }, "updatedAt": { "type": "string", "format": "datetime", "description": "When the scheduled action was last updated" }, "status": { "type": "string", "knownValues": ["pending", "executed", "cancelled", "failed"], "description": "Current status of the scheduled action" }, "lastExecutedAt": { "type": "string", "format": "datetime", "description": "When the action was last attempted to be executed" }, "lastFailureReason": { "type": "string", "description": "Reason for the last execution failure" }, "executionEventId": { "type": "integer", "description": "ID of the moderation event created when action was successfully executed" } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/emitEvent.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.emitEvent", "defs": { "main": { "type": "procedure", "description": "Take a moderation action on an actor.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["event", "subject", "createdBy"], "properties": { "event": { "type": "union", "refs": [ "tools.ozone.moderation.defs#modEventTakedown", "tools.ozone.moderation.defs#modEventAcknowledge", "tools.ozone.moderation.defs#modEventEscalate", "tools.ozone.moderation.defs#modEventComment", "tools.ozone.moderation.defs#modEventLabel", "tools.ozone.moderation.defs#modEventReport", "tools.ozone.moderation.defs#modEventMute", "tools.ozone.moderation.defs#modEventUnmute", "tools.ozone.moderation.defs#modEventMuteReporter", "tools.ozone.moderation.defs#modEventUnmuteReporter", "tools.ozone.moderation.defs#modEventReverseTakedown", "tools.ozone.moderation.defs#modEventResolveAppeal", "tools.ozone.moderation.defs#modEventEmail", "tools.ozone.moderation.defs#modEventDivert", "tools.ozone.moderation.defs#modEventTag", "tools.ozone.moderation.defs#accountEvent", "tools.ozone.moderation.defs#identityEvent", "tools.ozone.moderation.defs#recordEvent", "tools.ozone.moderation.defs#modEventPriorityScore", "tools.ozone.moderation.defs#ageAssuranceEvent", "tools.ozone.moderation.defs#ageAssuranceOverrideEvent", "tools.ozone.moderation.defs#ageAssurancePurgeEvent", "tools.ozone.moderation.defs#revokeAccountCredentialsEvent", "tools.ozone.moderation.defs#scheduleTakedownEvent", "tools.ozone.moderation.defs#cancelScheduledTakedownEvent" ] }, "subject": { "type": "union", "refs": [ "com.atproto.admin.defs#repoRef", "com.atproto.repo.strongRef" ] }, "subjectBlobCids": { "type": "array", "items": { "type": "string", "format": "cid" } }, "createdBy": { "type": "string", "format": "did" }, "modTool": { "type": "ref", "ref": "tools.ozone.moderation.defs#modTool" }, "externalId": { "type": "string", "description": "An optional external ID for the event, used to deduplicate events from external systems. Fails when an event of same type with the same external ID exists for the same subject." } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.moderation.defs#modEventView" } }, "errors": [ { "name": "SubjectHasAction" }, { "name": "DuplicateExternalId", "description": "An event with the same external ID already exists for the subject." } ] } } } ================================================ FILE: lexicons/tools/ozone/moderation/getAccountTimeline.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getAccountTimeline", "defs": { "main": { "type": "query", "description": "Get timeline of all available events of an account. This includes moderation events, account history and did history.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["timeline"], "properties": { "timeline": { "type": "array", "items": { "type": "ref", "ref": "#timelineItem" } } } } }, "errors": [ { "name": "RepoNotFound" } ] }, "timelineItem": { "type": "object", "required": ["day", "summary"], "properties": { "day": { "type": "string" }, "summary": { "type": "array", "items": { "type": "ref", "ref": "#timelineItemSummary" } } } }, "timelineItemSummary": { "type": "object", "required": ["eventSubjectType", "eventType", "count"], "properties": { "eventSubjectType": { "type": "string", "knownValues": ["account", "record", "chat"] }, "eventType": { "type": "string", "knownValues": [ "tools.ozone.moderation.defs#modEventTakedown", "tools.ozone.moderation.defs#modEventReverseTakedown", "tools.ozone.moderation.defs#modEventComment", "tools.ozone.moderation.defs#modEventReport", "tools.ozone.moderation.defs#modEventLabel", "tools.ozone.moderation.defs#modEventAcknowledge", "tools.ozone.moderation.defs#modEventEscalate", "tools.ozone.moderation.defs#modEventMute", "tools.ozone.moderation.defs#modEventUnmute", "tools.ozone.moderation.defs#modEventMuteReporter", "tools.ozone.moderation.defs#modEventUnmuteReporter", "tools.ozone.moderation.defs#modEventEmail", "tools.ozone.moderation.defs#modEventResolveAppeal", "tools.ozone.moderation.defs#modEventDivert", "tools.ozone.moderation.defs#modEventTag", "tools.ozone.moderation.defs#accountEvent", "tools.ozone.moderation.defs#identityEvent", "tools.ozone.moderation.defs#recordEvent", "tools.ozone.moderation.defs#modEventPriorityScore", "tools.ozone.moderation.defs#revokeAccountCredentialsEvent", "tools.ozone.moderation.defs#ageAssuranceEvent", "tools.ozone.moderation.defs#ageAssuranceOverrideEvent", "tools.ozone.moderation.defs#timelineEventPlcCreate", "tools.ozone.moderation.defs#timelineEventPlcOperation", "tools.ozone.moderation.defs#timelineEventPlcTombstone", "tools.ozone.hosting.getAccountHistory#accountCreated", "tools.ozone.hosting.getAccountHistory#emailConfirmed", "tools.ozone.hosting.getAccountHistory#passwordUpdated", "tools.ozone.hosting.getAccountHistory#handleUpdated", "tools.ozone.moderation.defs#scheduleTakedownEvent", "tools.ozone.moderation.defs#cancelScheduledTakedownEvent" ] }, "count": { "type": "integer" } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/getEvent.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getEvent", "defs": { "main": { "type": "query", "description": "Get details about a moderation event.", "parameters": { "type": "params", "required": ["id"], "properties": { "id": { "type": "integer" } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.moderation.defs#modEventViewDetail" } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/getRecord.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getRecord", "defs": { "main": { "type": "query", "description": "Get details about a record.", "parameters": { "type": "params", "required": ["uri"], "properties": { "uri": { "type": "string", "format": "at-uri" }, "cid": { "type": "string", "format": "cid" } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.moderation.defs#recordViewDetail" } }, "errors": [{ "name": "RecordNotFound" }] } } } ================================================ FILE: lexicons/tools/ozone/moderation/getRecords.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getRecords", "defs": { "main": { "type": "query", "description": "Get details about some records.", "parameters": { "type": "params", "required": ["uris"], "properties": { "uris": { "type": "array", "maxLength": 100, "items": { "type": "string", "format": "at-uri" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["records"], "properties": { "records": { "type": "array", "items": { "type": "union", "refs": [ "tools.ozone.moderation.defs#recordViewDetail", "tools.ozone.moderation.defs#recordViewNotFound" ] } } } } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/getRepo.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getRepo", "defs": { "main": { "type": "query", "description": "Get details about a repository.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.moderation.defs#repoViewDetail" } }, "errors": [{ "name": "RepoNotFound" }] } } } ================================================ FILE: lexicons/tools/ozone/moderation/getReporterStats.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getReporterStats", "defs": { "main": { "type": "query", "description": "Get reporter stats for a list of users.", "parameters": { "type": "params", "required": ["dids"], "properties": { "dids": { "type": "array", "maxLength": 100, "items": { "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["stats"], "properties": { "stats": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.moderation.defs#reporterStats" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/getRepos.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getRepos", "defs": { "main": { "type": "query", "description": "Get details about some repositories.", "parameters": { "type": "params", "required": ["dids"], "properties": { "dids": { "type": "array", "maxLength": 100, "items": { "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["repos"], "properties": { "repos": { "type": "array", "items": { "type": "union", "refs": [ "tools.ozone.moderation.defs#repoViewDetail", "tools.ozone.moderation.defs#repoViewNotFound" ] } } } } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/getSubjects.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.getSubjects", "defs": { "main": { "type": "query", "description": "Get details about subjects.", "parameters": { "type": "params", "required": ["subjects"], "properties": { "subjects": { "type": "array", "maxLength": 100, "minLength": 1, "items": { "type": "string" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subjects"], "properties": { "subjects": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.moderation.defs#subjectView" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/listScheduledActions.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.listScheduledActions", "defs": { "main": { "type": "procedure", "description": "List scheduled moderation actions with optional filtering", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["statuses"], "properties": { "startsAfter": { "type": "string", "format": "datetime", "description": "Filter actions scheduled to execute after this time" }, "endsBefore": { "type": "string", "format": "datetime", "description": "Filter actions scheduled to execute before this time" }, "subjects": { "type": "array", "maxLength": 100, "items": { "type": "string", "format": "did" }, "description": "Filter actions for specific DID subjects" }, "statuses": { "type": "array", "minLength": 1, "items": { "type": "string", "knownValues": ["pending", "executed", "cancelled", "failed"] }, "description": "Filter actions by status" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50, "description": "Maximum number of results to return" }, "cursor": { "type": "string", "description": "Cursor for pagination" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["actions"], "properties": { "actions": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.moderation.defs#scheduledActionView" } }, "cursor": { "type": "string", "description": "Cursor for next page of results" } } } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/queryEvents.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.queryEvents", "defs": { "main": { "type": "query", "description": "List moderation events related to a subject.", "parameters": { "type": "params", "properties": { "types": { "type": "array", "items": { "type": "string" }, "description": "The types of events (fully qualified string in the format of tools.ozone.moderation.defs#modEvent) to filter by. If not specified, all events are returned." }, "createdBy": { "type": "string", "format": "did" }, "sortDirection": { "type": "string", "default": "desc", "enum": ["asc", "desc"], "description": "Sort direction for the events. Defaults to descending order of created at timestamp." }, "createdAfter": { "type": "string", "format": "datetime", "description": "Retrieve events created after a given timestamp" }, "createdBefore": { "type": "string", "format": "datetime", "description": "Retrieve events created before a given timestamp" }, "subject": { "type": "string", "format": "uri" }, "collections": { "type": "array", "maxLength": 20, "description": "If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored.", "items": { "type": "string", "format": "nsid" } }, "subjectType": { "type": "string", "description": "If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored.", "knownValues": ["account", "record"] }, "includeAllUserRecords": { "type": "boolean", "default": false, "description": "If true, events on all record types (posts, lists, profile etc.) or records from given 'collections' param, owned by the did are returned." }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "hasComment": { "type": "boolean", "description": "If true, only events with comments are returned" }, "comment": { "type": "string", "description": "If specified, only events with comments containing the keyword are returned. Apply || separator to use multiple keywords and match using OR condition." }, "addedLabels": { "type": "array", "items": { "type": "string" }, "description": "If specified, only events where all of these labels were added are returned" }, "removedLabels": { "type": "array", "items": { "type": "string" }, "description": "If specified, only events where all of these labels were removed are returned" }, "addedTags": { "type": "array", "items": { "type": "string" }, "description": "If specified, only events where all of these tags were added are returned" }, "removedTags": { "type": "array", "items": { "type": "string" }, "description": "If specified, only events where all of these tags were removed are returned" }, "reportTypes": { "type": "array", "items": { "type": "string" } }, "policies": { "type": "array", "items": { "type": "string", "description": "If specified, only events where the action policies match any of the given policies are returned" } }, "modTool": { "type": "array", "items": { "type": "string" }, "description": "If specified, only events where the modTool name matches any of the given values are returned" }, "batchId": { "type": "string", "description": "If specified, only events where the batchId matches the given value are returned" }, "ageAssuranceState": { "type": "string", "description": "If specified, only events where the age assurance state matches the given value are returned", "knownValues": ["pending", "assured", "unknown", "reset", "blocked"] }, "withStrike": { "type": "boolean", "description": "If specified, only events where strikeCount value is set are returned." }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["events"], "properties": { "cursor": { "type": "string" }, "events": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.moderation.defs#modEventView" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/queryStatuses.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.queryStatuses", "defs": { "main": { "type": "query", "description": "View moderation statuses of subjects (record or repo).", "parameters": { "type": "params", "properties": { "queueCount": { "type": "integer", "description": "Number of queues being used by moderators. Subjects will be split among all queues." }, "queueIndex": { "type": "integer", "description": "Index of the queue to fetch subjects from. Works only when queueCount value is specified." }, "queueSeed": { "type": "string", "description": "A seeder to shuffle/balance the queue items." }, "includeAllUserRecords": { "type": "boolean", "description": "All subjects, or subjects from given 'collections' param, belonging to the account specified in the 'subject' param will be returned." }, "subject": { "type": "string", "format": "uri", "description": "The subject to get the status for." }, "comment": { "type": "string", "description": "Search subjects by keyword from comments" }, "reportedAfter": { "type": "string", "format": "datetime", "description": "Search subjects reported after a given timestamp" }, "reportedBefore": { "type": "string", "format": "datetime", "description": "Search subjects reported before a given timestamp" }, "reviewedAfter": { "type": "string", "format": "datetime", "description": "Search subjects reviewed after a given timestamp" }, "hostingDeletedAfter": { "type": "string", "format": "datetime", "description": "Search subjects where the associated record/account was deleted after a given timestamp" }, "hostingDeletedBefore": { "type": "string", "format": "datetime", "description": "Search subjects where the associated record/account was deleted before a given timestamp" }, "hostingUpdatedAfter": { "type": "string", "format": "datetime", "description": "Search subjects where the associated record/account was updated after a given timestamp" }, "hostingUpdatedBefore": { "type": "string", "format": "datetime", "description": "Search subjects where the associated record/account was updated before a given timestamp" }, "hostingStatuses": { "type": "array", "items": { "type": "string" }, "description": "Search subjects by the status of the associated record/account" }, "reviewedBefore": { "type": "string", "format": "datetime", "description": "Search subjects reviewed before a given timestamp" }, "includeMuted": { "type": "boolean", "description": "By default, we don't include muted subjects in the results. Set this to true to include them." }, "onlyMuted": { "type": "boolean", "description": "When set to true, only muted subjects and reporters will be returned." }, "reviewState": { "type": "string", "description": "Specify when fetching subjects in a certain state", "knownValues": [ "tools.ozone.moderation.defs#reviewOpen", "tools.ozone.moderation.defs#reviewClosed", "tools.ozone.moderation.defs#reviewEscalated", "tools.ozone.moderation.defs#reviewNone" ] }, "ignoreSubjects": { "type": "array", "items": { "type": "string", "format": "uri" } }, "lastReviewedBy": { "type": "string", "format": "did", "description": "Get all subject statuses that were reviewed by a specific moderator" }, "sortField": { "type": "string", "default": "lastReportedAt", "enum": [ "lastReviewedAt", "lastReportedAt", "reportedRecordsCount", "takendownRecordsCount", "priorityScore" ] }, "sortDirection": { "type": "string", "default": "desc", "enum": ["asc", "desc"] }, "takendown": { "type": "boolean", "description": "Get subjects that were taken down" }, "appealed": { "type": "boolean", "description": "Get subjects in unresolved appealed status" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "tags": { "type": "array", "maxLength": 25, "items": { "type": "string", "description": "Items in this array are applied with OR filters. To apply AND filter, put all tags in the same string and separate using && characters" } }, "excludeTags": { "type": "array", "items": { "type": "string" } }, "cursor": { "type": "string" }, "collections": { "type": "array", "maxLength": 20, "description": "If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored.", "items": { "type": "string", "format": "nsid" } }, "subjectType": { "type": "string", "description": "If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored.", "knownValues": ["account", "record"] }, "minAccountSuspendCount": { "type": "integer", "description": "If specified, only subjects that belong to an account that has at least this many suspensions will be returned." }, "minReportedRecordsCount": { "type": "integer", "description": "If specified, only subjects that belong to an account that has at least this many reported records will be returned." }, "minTakendownRecordsCount": { "type": "integer", "description": "If specified, only subjects that belong to an account that has at least this many taken down records will be returned." }, "minPriorityScore": { "minimum": 0, "maximum": 100, "type": "integer", "description": "If specified, only subjects that have priority score value above the given value will be returned." }, "minStrikeCount": { "type": "integer", "minimum": 1, "description": "If specified, only subjects that belong to an account that has at least this many active strikes will be returned." }, "ageAssuranceState": { "type": "string", "description": "If specified, only subjects with the given age assurance state will be returned.", "knownValues": ["pending", "assured", "unknown", "reset", "blocked"] } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["subjectStatuses"], "properties": { "cursor": { "type": "string" }, "subjectStatuses": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.moderation.defs#subjectStatusView" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/scheduleAction.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.scheduleAction", "defs": { "main": { "type": "procedure", "description": "Schedule a moderation action to be executed at a future time", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["action", "subjects", "createdBy", "scheduling"], "properties": { "action": { "type": "union", "refs": ["#takedown"] }, "subjects": { "type": "array", "maxLength": 100, "items": { "type": "string", "format": "did" }, "description": "Array of DID subjects to schedule the action for" }, "createdBy": { "type": "string", "format": "did" }, "scheduling": { "type": "ref", "ref": "#schedulingConfig" }, "modTool": { "type": "ref", "ref": "tools.ozone.moderation.defs#modTool", "description": "This will be propagated to the moderation event when it is applied" } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "#scheduledActionResults" } } }, "takedown": { "type": "object", "description": "Schedule a takedown action", "properties": { "comment": { "type": "string" }, "durationInHours": { "type": "integer", "description": "Indicates how long the takedown should be in effect before automatically expiring." }, "acknowledgeAccountSubjects": { "type": "boolean", "description": "If true, all other reports on content authored by this account will be resolved (acknowledged)." }, "policies": { "type": "array", "maxLength": 5, "items": { "type": "string" }, "description": "Names/Keywords of the policies that drove the decision." }, "severityLevel": { "type": "string", "description": "Severity level of the violation (e.g., 'sev-0', 'sev-1', 'sev-2', etc.)." }, "strikeCount": { "type": "integer", "description": "Number of strikes to assign to the user when takedown is applied." }, "strikeExpiresAt": { "type": "string", "format": "datetime", "description": "When the strike should expire. If not provided, the strike never expires." }, "emailContent": { "type": "string", "description": "Email content to be sent to the user upon takedown." }, "emailSubject": { "type": "string", "description": "Subject of the email to be sent to the user upon takedown." } } }, "schedulingConfig": { "type": "object", "description": "Configuration for when the action should be executed", "properties": { "executeAt": { "type": "string", "format": "datetime", "description": "Exact time to execute the action" }, "executeAfter": { "type": "string", "format": "datetime", "description": "Earliest time to execute the action (for randomized scheduling)" }, "executeUntil": { "type": "string", "format": "datetime", "description": "Latest time to execute the action (for randomized scheduling)" } } }, "scheduledActionResults": { "type": "object", "required": ["succeeded", "failed"], "properties": { "succeeded": { "type": "array", "items": { "type": "string", "format": "did" } }, "failed": { "type": "array", "items": { "type": "ref", "ref": "#failedScheduling" } } } }, "failedScheduling": { "type": "object", "required": ["subject", "error"], "properties": { "subject": { "type": "string", "format": "did" }, "error": { "type": "string" }, "errorCode": { "type": "string" } } } } } ================================================ FILE: lexicons/tools/ozone/moderation/searchRepos.json ================================================ { "lexicon": 1, "id": "tools.ozone.moderation.searchRepos", "defs": { "main": { "type": "query", "description": "Find repositories based on a search term.", "parameters": { "type": "params", "properties": { "term": { "type": "string", "description": "DEPRECATED: use 'q' instead" }, "q": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["repos"], "properties": { "cursor": { "type": "string" }, "repos": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.moderation.defs#repoView" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/report/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.report.defs", "defs": { "reasonType": { "type": "string", "knownValues": [ "tools.ozone.report.defs#reasonAppeal", "tools.ozone.report.defs#reasonOther", "tools.ozone.report.defs#reasonViolenceAnimal", "tools.ozone.report.defs#reasonViolenceThreats", "tools.ozone.report.defs#reasonViolenceGraphicContent", "tools.ozone.report.defs#reasonViolenceGlorification", "tools.ozone.report.defs#reasonViolenceExtremistContent", "tools.ozone.report.defs#reasonViolenceTrafficking", "tools.ozone.report.defs#reasonViolenceOther", "tools.ozone.report.defs#reasonSexualAbuseContent", "tools.ozone.report.defs#reasonSexualNCII", "tools.ozone.report.defs#reasonSexualDeepfake", "tools.ozone.report.defs#reasonSexualAnimal", "tools.ozone.report.defs#reasonSexualUnlabeled", "tools.ozone.report.defs#reasonSexualOther", "tools.ozone.report.defs#reasonChildSafetyCSAM", "tools.ozone.report.defs#reasonChildSafetyGroom", "tools.ozone.report.defs#reasonChildSafetyPrivacy", "tools.ozone.report.defs#reasonChildSafetyHarassment", "tools.ozone.report.defs#reasonChildSafetyOther", "tools.ozone.report.defs#reasonHarassmentTroll", "tools.ozone.report.defs#reasonHarassmentTargeted", "tools.ozone.report.defs#reasonHarassmentHateSpeech", "tools.ozone.report.defs#reasonHarassmentDoxxing", "tools.ozone.report.defs#reasonHarassmentOther", "tools.ozone.report.defs#reasonMisleadingBot", "tools.ozone.report.defs#reasonMisleadingImpersonation", "tools.ozone.report.defs#reasonMisleadingSpam", "tools.ozone.report.defs#reasonMisleadingScam", "tools.ozone.report.defs#reasonMisleadingElections", "tools.ozone.report.defs#reasonMisleadingOther", "tools.ozone.report.defs#reasonRuleSiteSecurity", "tools.ozone.report.defs#reasonRuleProhibitedSales", "tools.ozone.report.defs#reasonRuleBanEvasion", "tools.ozone.report.defs#reasonRuleOther", "tools.ozone.report.defs#reasonSelfHarmContent", "tools.ozone.report.defs#reasonSelfHarmED", "tools.ozone.report.defs#reasonSelfHarmStunts", "tools.ozone.report.defs#reasonSelfHarmSubstances", "tools.ozone.report.defs#reasonSelfHarmOther" ] }, "reasonAppeal": { "type": "token", "description": "Appeal a previously taken moderation action" }, "reasonOther": { "type": "token", "description": "An issue not included in these options" }, "reasonViolenceAnimal": { "type": "token", "description": "Animal welfare violations" }, "reasonViolenceThreats": { "type": "token", "description": "Threats or incitement" }, "reasonViolenceGraphicContent": { "type": "token", "description": "Graphic violent content" }, "reasonViolenceGlorification": { "type": "token", "description": "Glorification of violence" }, "reasonViolenceExtremistContent": { "type": "token", "description": "Extremist content. These reports will be sent only be sent to the application's Moderation Authority." }, "reasonViolenceTrafficking": { "type": "token", "description": "Human trafficking" }, "reasonViolenceOther": { "type": "token", "description": "Other violent content" }, "reasonSexualAbuseContent": { "type": "token", "description": "Adult sexual abuse content" }, "reasonSexualNCII": { "type": "token", "description": "Non-consensual intimate imagery" }, "reasonSexualDeepfake": { "type": "token", "description": "Deepfake adult content" }, "reasonSexualAnimal": { "type": "token", "description": "Animal sexual abuse" }, "reasonSexualUnlabeled": { "type": "token", "description": "Unlabelled adult content" }, "reasonSexualOther": { "type": "token", "description": "Other sexual violence content" }, "reasonChildSafetyCSAM": { "type": "token", "description": "Child sexual abuse material (CSAM). These reports will be sent only be sent to the application's Moderation Authority." }, "reasonChildSafetyGroom": { "type": "token", "description": "Grooming or predatory behavior. These reports will be sent only be sent to the application's Moderation Authority." }, "reasonChildSafetyPrivacy": { "type": "token", "description": "Privacy violation involving a minor" }, "reasonChildSafetyHarassment": { "type": "token", "description": "Harassment or bullying of minors" }, "reasonChildSafetyOther": { "type": "token", "description": "Other child safety. These reports will be sent only be sent to the application's Moderation Authority." }, "reasonHarassmentTroll": { "type": "token", "description": "Trolling" }, "reasonHarassmentTargeted": { "type": "token", "description": "Targeted harassment" }, "reasonHarassmentHateSpeech": { "type": "token", "description": "Hate speech" }, "reasonHarassmentDoxxing": { "type": "token", "description": "Doxxing" }, "reasonHarassmentOther": { "type": "token", "description": "Other harassing or hateful content" }, "reasonMisleadingBot": { "type": "token", "description": "Fake account or bot" }, "reasonMisleadingImpersonation": { "type": "token", "description": "Impersonation" }, "reasonMisleadingSpam": { "type": "token", "description": "Spam" }, "reasonMisleadingScam": { "type": "token", "description": "Scam" }, "reasonMisleadingElections": { "type": "token", "description": "False information about elections" }, "reasonMisleadingOther": { "type": "token", "description": "Other misleading content" }, "reasonRuleSiteSecurity": { "type": "token", "description": "Hacking or system attacks" }, "reasonRuleProhibitedSales": { "type": "token", "description": "Promoting or selling prohibited items or services" }, "reasonRuleBanEvasion": { "type": "token", "description": "Banned user returning" }, "reasonRuleOther": { "type": "token", "description": "Other" }, "reasonSelfHarmContent": { "type": "token", "description": "Content promoting or depicting self-harm" }, "reasonSelfHarmED": { "type": "token", "description": "Eating disorders" }, "reasonSelfHarmStunts": { "type": "token", "description": "Dangerous challenges or activities" }, "reasonSelfHarmSubstances": { "type": "token", "description": "Dangerous substances or drug abuse" }, "reasonSelfHarmOther": { "type": "token", "description": "Other dangerous content" } } } ================================================ FILE: lexicons/tools/ozone/safelink/addRule.json ================================================ { "lexicon": 1, "id": "tools.ozone.safelink.addRule", "defs": { "main": { "type": "procedure", "description": "Add a new URL safety rule", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["url", "pattern", "action", "reason"], "properties": { "url": { "type": "string", "description": "The URL or domain to apply the rule to" }, "pattern": { "type": "ref", "ref": "tools.ozone.safelink.defs#patternType" }, "action": { "type": "ref", "ref": "tools.ozone.safelink.defs#actionType" }, "reason": { "type": "ref", "ref": "tools.ozone.safelink.defs#reasonType" }, "comment": { "type": "string", "description": "Optional comment about the decision" }, "createdBy": { "type": "string", "format": "did", "description": "Author DID. Only respected when using admin auth" } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.safelink.defs#event" } }, "errors": [ { "name": "InvalidUrl", "description": "The provided URL is invalid" }, { "name": "RuleAlreadyExists", "description": "A rule for this URL/domain already exists" } ] } } } ================================================ FILE: lexicons/tools/ozone/safelink/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.safelink.defs", "defs": { "event": { "type": "object", "description": "An event for URL safety decisions", "required": [ "id", "eventType", "url", "pattern", "action", "reason", "createdBy", "createdAt" ], "properties": { "id": { "type": "integer", "description": "Auto-incrementing row ID" }, "eventType": { "type": "ref", "ref": "#eventType" }, "url": { "type": "string", "description": "The URL that this rule applies to" }, "pattern": { "type": "ref", "ref": "#patternType" }, "action": { "type": "ref", "ref": "#actionType" }, "reason": { "type": "ref", "ref": "#reasonType" }, "createdBy": { "type": "string", "format": "did", "description": "DID of the user who created this rule" }, "createdAt": { "type": "string", "format": "datetime" }, "comment": { "type": "string", "description": "Optional comment about the decision" } } }, "eventType": { "type": "string", "knownValues": ["addRule", "updateRule", "removeRule"] }, "patternType": { "type": "string", "knownValues": ["domain", "url"] }, "actionType": { "type": "string", "knownValues": ["block", "warn", "whitelist"] }, "reasonType": { "type": "string", "knownValues": ["csam", "spam", "phishing", "none"] }, "urlRule": { "type": "object", "description": "Input for creating a URL safety rule", "required": [ "url", "pattern", "action", "reason", "createdBy", "createdAt", "updatedAt" ], "properties": { "url": { "type": "string", "description": "The URL or domain to apply the rule to" }, "pattern": { "type": "ref", "ref": "#patternType" }, "action": { "type": "ref", "ref": "#actionType" }, "reason": { "type": "ref", "ref": "#reasonType" }, "comment": { "type": "string", "description": "Optional comment about the decision" }, "createdBy": { "type": "string", "format": "did", "description": "DID of the user added the rule." }, "createdAt": { "type": "string", "format": "datetime", "description": "Timestamp when the rule was created" }, "updatedAt": { "type": "string", "format": "datetime", "description": "Timestamp when the rule was last updated" } } } } } ================================================ FILE: lexicons/tools/ozone/safelink/queryEvents.json ================================================ { "lexicon": 1, "id": "tools.ozone.safelink.queryEvents", "defs": { "main": { "type": "procedure", "description": "Query URL safety audit events", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for pagination" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50, "description": "Maximum number of results to return" }, "urls": { "type": "array", "items": { "type": "string" }, "description": "Filter by specific URLs or domains" }, "patternType": { "type": "string", "description": "Filter by pattern type" }, "sortDirection": { "type": "string", "knownValues": ["asc", "desc"], "default": "desc", "description": "Sort direction" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["events"], "properties": { "cursor": { "type": "string", "description": "Next cursor for pagination. Only present if there are more results." }, "events": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.safelink.defs#event" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/safelink/queryRules.json ================================================ { "lexicon": 1, "id": "tools.ozone.safelink.queryRules", "defs": { "main": { "type": "procedure", "description": "Query URL safety rules", "input": { "encoding": "application/json", "schema": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for pagination" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50, "description": "Maximum number of results to return" }, "urls": { "type": "array", "items": { "type": "string" }, "description": "Filter by specific URLs or domains" }, "patternType": { "type": "string", "description": "Filter by pattern type" }, "actions": { "type": "array", "items": { "type": "string" }, "description": "Filter by action types" }, "reason": { "type": "string", "description": "Filter by reason type" }, "createdBy": { "type": "string", "format": "did", "description": "Filter by rule creator" }, "sortDirection": { "type": "string", "knownValues": ["asc", "desc"], "default": "desc", "description": "Sort direction" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["rules"], "properties": { "cursor": { "type": "string", "description": "Next cursor for pagination. Only present if there are more results." }, "rules": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.safelink.defs#urlRule" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/safelink/removeRule.json ================================================ { "lexicon": 1, "id": "tools.ozone.safelink.removeRule", "defs": { "main": { "type": "procedure", "description": "Remove an existing URL safety rule", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["url", "pattern"], "properties": { "url": { "type": "string", "description": "The URL or domain to remove the rule for" }, "pattern": { "type": "ref", "ref": "tools.ozone.safelink.defs#patternType" }, "comment": { "type": "string", "description": "Optional comment about why the rule is being removed" }, "createdBy": { "type": "string", "format": "did", "description": "Optional DID of the user. Only respected when using admin auth." } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.safelink.defs#event" } }, "errors": [ { "name": "RuleNotFound", "description": "No active rule found for this URL/domain" } ] } } } ================================================ FILE: lexicons/tools/ozone/safelink/updateRule.json ================================================ { "lexicon": 1, "id": "tools.ozone.safelink.updateRule", "defs": { "main": { "type": "procedure", "description": "Update an existing URL safety rule", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["url", "pattern", "action", "reason"], "properties": { "url": { "type": "string", "description": "The URL or domain to update the rule for" }, "pattern": { "type": "ref", "ref": "tools.ozone.safelink.defs#patternType" }, "action": { "type": "ref", "ref": "tools.ozone.safelink.defs#actionType" }, "reason": { "type": "ref", "ref": "tools.ozone.safelink.defs#reasonType" }, "comment": { "type": "string", "description": "Optional comment about the update" }, "createdBy": { "type": "string", "format": "did", "description": "Optional DID to credit as the creator. Only respected for admin_token authentication." } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.safelink.defs#event" } }, "errors": [ { "name": "RuleNotFound", "description": "No active rule found for this URL/domain" } ] } } } ================================================ FILE: lexicons/tools/ozone/server/getConfig.json ================================================ { "lexicon": 1, "id": "tools.ozone.server.getConfig", "defs": { "main": { "type": "query", "description": "Get details about ozone's server configuration.", "output": { "encoding": "application/json", "schema": { "type": "object", "properties": { "appview": { "type": "ref", "ref": "#serviceConfig" }, "pds": { "type": "ref", "ref": "#serviceConfig" }, "blobDivert": { "type": "ref", "ref": "#serviceConfig" }, "chat": { "type": "ref", "ref": "#serviceConfig" }, "viewer": { "type": "ref", "ref": "#viewerConfig" }, "verifierDid": { "type": "string", "format": "did", "description": "The did of the verifier used for verification." } } } } }, "serviceConfig": { "type": "object", "properties": { "url": { "type": "string", "format": "uri" } } }, "viewerConfig": { "type": "object", "properties": { "role": { "type": "string", "knownValues": [ "tools.ozone.team.defs#roleAdmin", "tools.ozone.team.defs#roleModerator", "tools.ozone.team.defs#roleTriage", "tools.ozone.team.defs#roleVerifier" ] } } } } } ================================================ FILE: lexicons/tools/ozone/set/addValues.json ================================================ { "lexicon": 1, "id": "tools.ozone.set.addValues", "defs": { "main": { "type": "procedure", "description": "Add values to a specific set. Attempting to add values to a set that does not exist will result in an error.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["name", "values"], "properties": { "name": { "type": "string", "description": "Name of the set to add values to" }, "values": { "type": "array", "minLength": 1, "maxLength": 1000, "items": { "type": "string" }, "description": "Array of string values to add to the set" } } } } } } } ================================================ FILE: lexicons/tools/ozone/set/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.set.defs", "defs": { "set": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "minLength": 3, "maxLength": 128 }, "description": { "type": "string", "maxGraphemes": 1024, "maxLength": 10240 } } }, "setView": { "type": "object", "required": ["name", "setSize", "createdAt", "updatedAt"], "properties": { "name": { "type": "string", "minLength": 3, "maxLength": 128 }, "description": { "type": "string", "maxGraphemes": 1024, "maxLength": 10240 }, "setSize": { "type": "integer" }, "createdAt": { "type": "string", "format": "datetime" }, "updatedAt": { "type": "string", "format": "datetime" } } } } } ================================================ FILE: lexicons/tools/ozone/set/deleteSet.json ================================================ { "lexicon": 1, "id": "tools.ozone.set.deleteSet", "defs": { "main": { "type": "procedure", "description": "Delete an entire set. Attempting to delete a set that does not exist will result in an error.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "description": "Name of the set to delete" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } }, "errors": [ { "name": "SetNotFound", "description": "set with the given name does not exist" } ] } } } ================================================ FILE: lexicons/tools/ozone/set/deleteValues.json ================================================ { "lexicon": 1, "id": "tools.ozone.set.deleteValues", "defs": { "main": { "type": "procedure", "description": "Delete values from a specific set. Attempting to delete values that are not in the set will not result in an error", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["name", "values"], "properties": { "name": { "type": "string", "description": "Name of the set to delete values from" }, "values": { "type": "array", "minLength": 1, "items": { "type": "string" }, "description": "Array of string values to delete from the set" } } } }, "errors": [ { "name": "SetNotFound", "description": "set with the given name does not exist" } ] } } } ================================================ FILE: lexicons/tools/ozone/set/getValues.json ================================================ { "lexicon": 1, "id": "tools.ozone.set.getValues", "defs": { "main": { "type": "query", "description": "Get a specific set and its values", "parameters": { "type": "params", "required": ["name"], "properties": { "name": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["set", "values"], "properties": { "set": { "type": "ref", "ref": "tools.ozone.set.defs#setView" }, "values": { "type": "array", "items": { "type": "string" } }, "cursor": { "type": "string" } } } }, "errors": [ { "name": "SetNotFound", "description": "set with the given name does not exist" } ] } } } ================================================ FILE: lexicons/tools/ozone/set/querySets.json ================================================ { "lexicon": 1, "id": "tools.ozone.set.querySets", "defs": { "main": { "type": "query", "description": "Query available sets", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "namePrefix": { "type": "string" }, "sortBy": { "type": "string", "enum": ["name", "createdAt", "updatedAt"], "default": "name" }, "sortDirection": { "type": "string", "default": "asc", "enum": ["asc", "desc"], "description": "Defaults to ascending order of name field." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["sets"], "properties": { "sets": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.set.defs#setView" } }, "cursor": { "type": "string" } } } } } } } ================================================ FILE: lexicons/tools/ozone/set/upsertSet.json ================================================ { "lexicon": 1, "id": "tools.ozone.set.upsertSet", "defs": { "main": { "type": "procedure", "description": "Create or update set metadata", "input": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.set.defs#set" } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.set.defs#setView" } } } } } ================================================ FILE: lexicons/tools/ozone/setting/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.setting.defs", "defs": { "option": { "type": "object", "required": [ "key", "value", "did", "scope", "createdBy", "lastUpdatedBy" ], "properties": { "key": { "type": "string", "format": "nsid" }, "did": { "type": "string", "format": "did" }, "value": { "type": "unknown" }, "description": { "type": "string", "maxGraphemes": 1024, "maxLength": 10240 }, "createdAt": { "type": "string", "format": "datetime" }, "updatedAt": { "type": "string", "format": "datetime" }, "managerRole": { "type": "string", "knownValues": [ "tools.ozone.team.defs#roleModerator", "tools.ozone.team.defs#roleTriage", "tools.ozone.team.defs#roleAdmin", "tools.ozone.team.defs#roleVerifier" ] }, "scope": { "type": "string", "knownValues": ["instance", "personal"] }, "createdBy": { "type": "string", "format": "did" }, "lastUpdatedBy": { "type": "string", "format": "did" } } } } } ================================================ FILE: lexicons/tools/ozone/setting/listOptions.json ================================================ { "lexicon": 1, "id": "tools.ozone.setting.listOptions", "defs": { "main": { "type": "query", "description": "List settings with optional filtering", "parameters": { "type": "params", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" }, "scope": { "type": "string", "knownValues": ["instance", "personal"], "default": "instance" }, "prefix": { "type": "string", "description": "Filter keys by prefix" }, "keys": { "type": "array", "maxLength": 100, "items": { "type": "string", "format": "nsid" }, "description": "Filter for only the specified keys. Ignored if prefix is provided" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["options"], "properties": { "cursor": { "type": "string" }, "options": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.setting.defs#option" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/setting/removeOptions.json ================================================ { "lexicon": 1, "id": "tools.ozone.setting.removeOptions", "defs": { "main": { "type": "procedure", "description": "Delete settings by key", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["keys", "scope"], "properties": { "keys": { "type": "array", "minLength": 1, "maxLength": 200, "items": { "type": "string", "format": "nsid" } }, "scope": { "type": "string", "knownValues": ["instance", "personal"] } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "properties": {} } } } } } ================================================ FILE: lexicons/tools/ozone/setting/upsertOption.json ================================================ { "lexicon": 1, "id": "tools.ozone.setting.upsertOption", "defs": { "main": { "type": "procedure", "description": "Create or update setting option", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["key", "scope", "value"], "properties": { "key": { "type": "string", "format": "nsid" }, "scope": { "type": "string", "knownValues": ["instance", "personal"] }, "value": { "type": "unknown" }, "description": { "type": "string", "maxLength": 2000 }, "managerRole": { "type": "string", "knownValues": [ "tools.ozone.team.defs#roleModerator", "tools.ozone.team.defs#roleTriage", "tools.ozone.team.defs#roleVerifier", "tools.ozone.team.defs#roleAdmin" ] } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["option"], "properties": { "option": { "type": "ref", "ref": "tools.ozone.setting.defs#option" } } } } } } } ================================================ FILE: lexicons/tools/ozone/signature/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.signature.defs", "defs": { "sigDetail": { "type": "object", "required": ["property", "value"], "properties": { "property": { "type": "string" }, "value": { "type": "string" } } } } } ================================================ FILE: lexicons/tools/ozone/signature/findCorrelation.json ================================================ { "lexicon": 1, "id": "tools.ozone.signature.findCorrelation", "defs": { "main": { "type": "query", "description": "Find all correlated threat signatures between 2 or more accounts.", "parameters": { "type": "params", "required": ["dids"], "properties": { "dids": { "type": "array", "items": { "type": "string", "format": "did" } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["details"], "properties": { "details": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.signature.defs#sigDetail" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/signature/findRelatedAccounts.json ================================================ { "lexicon": 1, "id": "tools.ozone.signature.findRelatedAccounts", "defs": { "main": { "type": "query", "description": "Get accounts that share some matching threat signatures with the root account.", "parameters": { "type": "params", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" }, "cursor": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["accounts"], "properties": { "cursor": { "type": "string" }, "accounts": { "type": "array", "items": { "type": "ref", "ref": "#relatedAccount" } } } } } }, "relatedAccount": { "type": "object", "required": ["account"], "properties": { "account": { "type": "ref", "ref": "com.atproto.admin.defs#accountView" }, "similarities": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.signature.defs#sigDetail" } } } } } } ================================================ FILE: lexicons/tools/ozone/signature/searchAccounts.json ================================================ { "lexicon": 1, "id": "tools.ozone.signature.searchAccounts", "defs": { "main": { "type": "query", "description": "Search for accounts that match one or more threat signature values.", "parameters": { "type": "params", "required": ["values"], "properties": { "values": { "type": "array", "items": { "type": "string" } }, "cursor": { "type": "string" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["accounts"], "properties": { "cursor": { "type": "string" }, "accounts": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.admin.defs#accountView" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/team/addMember.json ================================================ { "lexicon": 1, "id": "tools.ozone.team.addMember", "defs": { "main": { "type": "procedure", "description": "Add a member to the ozone team. Requires admin role.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did", "role"], "properties": { "did": { "type": "string", "format": "did" }, "role": { "type": "string", "knownValues": [ "tools.ozone.team.defs#roleAdmin", "tools.ozone.team.defs#roleModerator", "tools.ozone.team.defs#roleVerifier", "tools.ozone.team.defs#roleTriage" ] } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.team.defs#member" } }, "errors": [ { "name": "MemberAlreadyExists", "description": "Member already exists in the team." } ] } } } ================================================ FILE: lexicons/tools/ozone/team/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.team.defs", "defs": { "member": { "type": "object", "required": ["did", "role"], "properties": { "did": { "type": "string", "format": "did" }, "disabled": { "type": "boolean" }, "profile": { "type": "ref", "ref": "app.bsky.actor.defs#profileViewDetailed" }, "createdAt": { "type": "string", "format": "datetime" }, "updatedAt": { "type": "string", "format": "datetime" }, "lastUpdatedBy": { "type": "string" }, "role": { "type": "string", "knownValues": [ "tools.ozone.team.defs#roleAdmin", "tools.ozone.team.defs#roleModerator", "tools.ozone.team.defs#roleTriage", "tools.ozone.team.defs#roleVerifier" ] } } }, "roleAdmin": { "type": "token", "description": "Admin role. Highest level of access, can perform all actions." }, "roleModerator": { "type": "token", "description": "Moderator role. Can perform most actions." }, "roleTriage": { "type": "token", "description": "Triage role. Mostly intended for monitoring and escalating issues." }, "roleVerifier": { "type": "token", "description": "Verifier role. Only allowed to issue verifications." } } } ================================================ FILE: lexicons/tools/ozone/team/deleteMember.json ================================================ { "lexicon": 1, "id": "tools.ozone.team.deleteMember", "defs": { "main": { "type": "procedure", "description": "Delete a member from ozone team. Requires admin role.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" } } } }, "errors": [ { "name": "MemberNotFound", "description": "The member being deleted does not exist" }, { "name": "CannotDeleteSelf", "description": "You can not delete yourself from the team" } ] } } } ================================================ FILE: lexicons/tools/ozone/team/listMembers.json ================================================ { "lexicon": 1, "id": "tools.ozone.team.listMembers", "defs": { "main": { "type": "query", "description": "List all members with access to the ozone service.", "parameters": { "type": "params", "properties": { "q": { "type": "string" }, "disabled": { "type": "boolean" }, "roles": { "type": "array", "items": { "type": "string" } }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "cursor": { "type": "string" } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["members"], "properties": { "cursor": { "type": "string" }, "members": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.team.defs#member" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/team/updateMember.json ================================================ { "lexicon": 1, "id": "tools.ozone.team.updateMember", "defs": { "main": { "type": "procedure", "description": "Update a member in the ozone service. Requires admin role.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["did"], "properties": { "did": { "type": "string", "format": "did" }, "disabled": { "type": "boolean" }, "role": { "type": "string", "knownValues": [ "tools.ozone.team.defs#roleAdmin", "tools.ozone.team.defs#roleModerator", "tools.ozone.team.defs#roleVerifier", "tools.ozone.team.defs#roleTriage" ] } } } }, "output": { "encoding": "application/json", "schema": { "type": "ref", "ref": "tools.ozone.team.defs#member" } }, "errors": [ { "name": "MemberNotFound", "description": "The member being updated does not exist in the team" } ] } } } ================================================ FILE: lexicons/tools/ozone/verification/defs.json ================================================ { "lexicon": 1, "id": "tools.ozone.verification.defs", "defs": { "verificationView": { "type": "object", "description": "Verification data for the associated subject.", "required": [ "issuer", "uri", "subject", "handle", "displayName", "createdAt" ], "properties": { "issuer": { "type": "string", "description": "The user who issued this verification.", "format": "did" }, "uri": { "type": "string", "description": "The AT-URI of the verification record.", "format": "at-uri" }, "subject": { "type": "string", "format": "did", "description": "The subject of the verification." }, "handle": { "type": "string", "description": "Handle of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current handle matches the one at the time of verifying.", "format": "handle" }, "displayName": { "type": "string", "description": "Display name of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current displayName matches the one at the time of verifying." }, "createdAt": { "type": "string", "description": "Timestamp when the verification was created.", "format": "datetime" }, "revokeReason": { "type": "string", "description": "Describes the reason for revocation, also indicating that the verification is no longer valid." }, "revokedAt": { "type": "string", "description": "Timestamp when the verification was revoked.", "format": "datetime" }, "revokedBy": { "type": "string", "description": "The user who revoked this verification.", "format": "did" }, "subjectProfile": { "type": "union", "refs": [] }, "issuerProfile": { "type": "union", "refs": [] }, "subjectRepo": { "type": "union", "refs": [ "tools.ozone.moderation.defs#repoViewDetail", "tools.ozone.moderation.defs#repoViewNotFound" ] }, "issuerRepo": { "type": "union", "refs": [ "tools.ozone.moderation.defs#repoViewDetail", "tools.ozone.moderation.defs#repoViewNotFound" ] } } } } } ================================================ FILE: lexicons/tools/ozone/verification/grantVerifications.json ================================================ { "lexicon": 1, "id": "tools.ozone.verification.grantVerifications", "defs": { "main": { "type": "procedure", "description": "Grant verifications to multiple subjects. Allows batch processing of up to 100 verifications at once.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["verifications"], "properties": { "verifications": { "type": "array", "description": "Array of verification requests to process", "maxLength": 100, "items": { "type": "ref", "ref": "#verificationInput" } } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["verifications", "failedVerifications"], "properties": { "verifications": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.verification.defs#verificationView" } }, "failedVerifications": { "type": "array", "items": { "type": "ref", "ref": "#grantError" } } } } } }, "verificationInput": { "type": "object", "required": ["subject", "handle", "displayName"], "properties": { "subject": { "type": "string", "description": "The did of the subject being verified", "format": "did" }, "handle": { "type": "string", "description": "Handle of the subject the verification applies to at the moment of verifying.", "format": "handle" }, "displayName": { "type": "string", "description": "Display name of the subject the verification applies to at the moment of verifying." }, "createdAt": { "type": "string", "format": "datetime", "description": "Timestamp for verification record. Defaults to current time when not specified." } } }, "grantError": { "type": "object", "description": "Error object for failed verifications.", "required": ["error", "subject"], "properties": { "error": { "type": "string", "description": "Error message describing the reason for failure." }, "subject": { "type": "string", "description": "The did of the subject being verified", "format": "did" } } } } } ================================================ FILE: lexicons/tools/ozone/verification/listVerifications.json ================================================ { "lexicon": 1, "id": "tools.ozone.verification.listVerifications", "defs": { "main": { "type": "query", "description": "List verifications", "parameters": { "type": "params", "properties": { "cursor": { "type": "string", "description": "Pagination cursor" }, "limit": { "type": "integer", "description": "Maximum number of results to return", "minimum": 1, "maximum": 100, "default": 50 }, "createdAfter": { "type": "string", "format": "datetime", "description": "Filter to verifications created after this timestamp" }, "createdBefore": { "type": "string", "format": "datetime", "description": "Filter to verifications created before this timestamp" }, "issuers": { "type": "array", "maxLength": 100, "description": "Filter to verifications from specific issuers", "items": { "type": "string", "format": "did" } }, "subjects": { "type": "array", "description": "Filter to specific verified DIDs", "maxLength": 100, "items": { "type": "string", "format": "did" } }, "sortDirection": { "type": "string", "description": "Sort direction for creation date", "enum": ["asc", "desc"], "default": "desc" }, "isRevoked": { "type": "boolean", "description": "Filter to verifications that are revoked or not. By default, includes both." } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["verifications"], "properties": { "cursor": { "type": "string" }, "verifications": { "type": "array", "items": { "type": "ref", "ref": "tools.ozone.verification.defs#verificationView" } } } } } } } } ================================================ FILE: lexicons/tools/ozone/verification/revokeVerifications.json ================================================ { "lexicon": 1, "id": "tools.ozone.verification.revokeVerifications", "defs": { "main": { "type": "procedure", "description": "Revoke previously granted verifications in batches of up to 100.", "input": { "encoding": "application/json", "schema": { "type": "object", "required": ["uris"], "properties": { "uris": { "type": "array", "description": "Array of verification record uris to revoke", "maxLength": 100, "items": { "type": "string", "description": "The AT-URI of the verification record to revoke.", "format": "at-uri" } }, "revokeReason": { "type": "string", "description": "Reason for revoking the verification. This is optional and can be omitted if not needed.", "maxLength": 1000 } } } }, "output": { "encoding": "application/json", "schema": { "type": "object", "required": ["revokedVerifications", "failedRevocations"], "properties": { "revokedVerifications": { "type": "array", "description": "List of verification uris successfully revoked", "items": { "type": "string", "format": "at-uri" } }, "failedRevocations": { "type": "array", "description": "List of verification uris that couldn't be revoked, including failure reasons", "items": { "type": "ref", "ref": "#revokeError" } } } } } }, "revokeError": { "type": "object", "description": "Error object for failed revocations", "required": ["uri", "error"], "properties": { "uri": { "type": "string", "description": "The AT-URI of the verification record that failed to revoke.", "format": "at-uri" }, "error": { "type": "string", "description": "Description of the error that occurred during revocation." } } } } } ================================================ FILE: package.json ================================================ { "name": "atp", "version": "0.0.1", "repository": "git@github.com:bluesky-social/atproto.git", "author": "Bluesky Social PBC ", "license": "MIT", "private": true, "engines": { "node": ">=18.7.0" }, "packageManager": "pnpm@8.15.9+sha512.499434c9d8fdd1a2794ebf4552b3b25c0a633abcee5bb15e7b5de90f32f47b513aca98cd5cfd001c31f0db454bc3804edccd578501e4ca293a6816166bbd9f81", "scripts": { "lint:fix": "pnpm lint --fix", "lint": "NODE_OPTIONS=--max_old_space_size=4096 eslint . --ext .ts,.js,.tsx,.jsx", "style:fix": "prettier --write .", "style": "prettier --check .", "verify": "pnpm --stream '/^verify:.+$/'", "verify:style": "pnpm run style", "verify:lint": "pnpm lint", "verify:types": "tsc --build tsconfig.json", "format": "pnpm lint:fix && pnpm style:fix", "precodegen": "pnpm run --recursive --stream --filter '@atproto/lex-cli...' --filter '@atproto/lex...' build --force", "codegen": "pnpm run --sort --recursive --stream --parallel codegen", "build": "pnpm run --sort --recursive --stream build", "i18n": "pnpm run --parallel i18n:extract", "dev": "NODE_ENV=development pnpm run --recursive --parallel --stream '/^(dev|dev:.+)$/'", "dev:tsc": "tsc --build tsconfig.json --preserveWatchOutput --watch", "test": "LOG_ENABLED=false ./packages/dev-infra/with-test-redis-and-db.sh pnpm test --stream --recursive", "test:withFlags": "pnpm run test --", "changeset": "changeset", "release": "pnpm build && changeset publish", "version-packages": "changeset version && git add ." }, "devDependencies": { "@atproto/dev-env": "workspace:^", "@changesets/changelog-github": "^0.5.1", "@changesets/cli": "^2.29.7", "@swc/core": "^1.3.42", "@swc/jest": "^0.2.24", "@types/jest": "^28.1.4", "@types/node": "^18.19.67", "@typescript-eslint/eslint-plugin": "^7.4.0", "@typescript-eslint/parser": "^7.4.0", "@vitest/coverage-v8": "4.0.16", "dotenv": "^16.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.7.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-n": "^17.15.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^28.1.2", "node-gyp": "^9.3.1", "pino-pretty": "^9.1.0", "prettier": "^3.2.5", "prettier-config-standard": "^7.0.0", "prettier-plugin-tailwindcss": "^0.6.11", "typescript": "^5.8.3", "vitest": "^4.0.16" }, "pnpm": { "overrides": { "cookie": "^0.7.2" } }, "workspace": [ "packages/*", "packages/lex/*", "packages/oauth/*", "packages/internal/*" ], "workspaces": { "packages": [ "packages/*", "packages/lex/*", "packages/oauth/*", "packages/internal/*" ] } } ================================================ FILE: packages/README.md ================================================ # Packages ## Applications - [PDS](./pds): The Personal Data Server (PDS). This is atproto's main server-side implementation. - [Dev Env](./dev-env): A command-line application for developers to construct and manage development environments. - [Lexicon CLI](./lex-cli/): A command-line application for generating code and documentation from Lexicon schemas. ## Libraries - [API](./api): A library for communicating with atproto servers. - [Common](./common): A library containing code which is shared between atproto packages. - [Crypto](./crypto): Atproto's common cryptographic operations. - [Syntax](./syntax): A library for identifier syntax: NSID, AT URI, handles, etc. - [Lexicon](./lexicon): A library for validating data using atproto's schema system. - [OAuth Provider](./oauth/oauth-provider): A library for supporting ATPROTO's OAuth. - [Repo](./repo): The "atproto repository" core implementation (a Merkle Search Tree). - [WebSocket Client](./ws-client): A library for working with long-lived WebSocket client connections. - [XRPC](./xrpc): An XRPC client implementation. - [XRPC Server](./xrpc-server): An XRPC server implementation. ## Benchmarking and profiling Only applicable to packages which contain benchmarks(`jest.bench.config.js`). You can run benchmarks with `pnpm bench`. ### Attaching a profiler Running `pnpm bench:profile` will launch `bench` with `--inspect-brk` flag. Execution will be paused until a debugger is attached, you can read more about node debuggers [here](https://nodejs.org/en/docs/guides/debugging-getting-started#inspector-clients) An easy way to profile is: 1. open `about://inspect` in chrome 2. select which process to connect to(there will probably only be one) 3. go to performance tab 4. press record, this will unpause execution 5. wait for the benches to run 6. finish recording ================================================ FILE: packages/api/CHANGELOG.md ================================================ # @atproto/api ## 0.19.4 ### Patch Changes - [#4709](https://github.com/bluesky-social/atproto/pull/4709) [`9f9f71a`](https://github.com/bluesky-social/atproto/commit/9f9f71a6a3e58ccbd5e6d3ee079b570096cb11fa) Thanks [@foysalit](https://github.com/foysalit)! - Introduce a purge event to remove ozone's data on age assurance - Updated dependencies [[`67eb0c1`](https://github.com/bluesky-social/atproto/commit/67eb0c19ac415e762e221b2ccda9f0bcf7b3dd6f)]: - @atproto/syntax@0.5.1 ## 0.19.3 ### Patch Changes - [#4717](https://github.com/bluesky-social/atproto/pull/4717) [`76ab6ea`](https://github.com/bluesky-social/atproto/commit/76ab6eaa7bfa49fc218299d09446bb339c700bb5) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Trust `status` returned from `refreshSession` and do not fall back to a potentially stale value from `this.session`. ## 0.19.2 ### Patch Changes - [#4683](https://github.com/bluesky-social/atproto/pull/4683) [`6634140`](https://github.com/bluesky-social/atproto/commit/66341400d49d1210619b000a040852d87085c32c) Thanks [@ds-boyce](https://github.com/ds-boyce)! - Introduce recIdStr field - [#4713](https://github.com/bluesky-social/atproto/pull/4713) [`0e5df95`](https://github.com/bluesky-social/atproto/commit/0e5df95e3a8d81931524848d301cd43d1f12fb78) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Make sure to always trigger a `refreshSession` when `resumeSession()` is called ## 0.19.1 ### Patch Changes - [#4704](https://github.com/bluesky-social/atproto/pull/4704) [`137065b`](https://github.com/bluesky-social/atproto/commit/137065b333b8c9b97e6b3b2ac6147c7509a1ae42) Thanks [@ds-boyce](https://github.com/ds-boyce)! - Add feed to sendInteractions input - Updated dependencies [[`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd)]: - @atproto/syntax@0.5.0 - @atproto/common-web@0.4.18 - @atproto/lexicon@0.6.2 ## 0.19.0 ### Minor Changes - [#4631](https://github.com/bluesky-social/atproto/pull/4631) [`450f085`](https://github.com/bluesky-social/atproto/commit/450f0856630fa08c20dc60fef8b5d2a07b9a2552) Thanks [@LotharieSlayer](https://github.com/LotharieSlayer)! - Updating atproto app password based session example in README ## 0.18.21 ### Patch Changes - [#4633](https://github.com/bluesky-social/atproto/pull/4633) [`60f84eb`](https://github.com/bluesky-social/atproto/commit/60f84ebe47016828add07b143c403e331c58ee78) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Increase draft char limit from 300 to 1000 - [#4632](https://github.com/bluesky-social/atproto/pull/4632) [`50dfbec`](https://github.com/bluesky-social/atproto/commit/50dfbec512682d35e8108b952e8f0533da71beef) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add app.bsky.unspecced.getSuggestedOnboardingUser and app.bsky.unspecced.getSuggestedOnboardingUsersSkeleton - [#4594](https://github.com/bluesky-social/atproto/pull/4594) [`f8c84eb`](https://github.com/bluesky-social/atproto/commit/f8c84ebd3db960234cbd72dae6d1ab57d9361317) Thanks [@bnewbold](https://github.com/bnewbold)! - update germ networks lexicon - [#4594](https://github.com/bluesky-social/atproto/pull/4594) [`f8c84eb`](https://github.com/bluesky-social/atproto/commit/f8c84ebd3db960234cbd72dae6d1ab57d9361317) Thanks [@bnewbold](https://github.com/bnewbold)! - add `none` to germ declaration record ## 0.18.20 ### Patch Changes - [#4591](https://github.com/bluesky-social/atproto/pull/4591) [`4f5c400`](https://github.com/bluesky-social/atproto/commit/4f5c4001271bbf38b30506efd30ebdabb969878f) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Rename `platform` to `deviceName` on `draft` view, add maxLength. ## 0.18.19 ### Patch Changes - [#4590](https://github.com/bluesky-social/atproto/pull/4590) [`25cea46`](https://github.com/bluesky-social/atproto/commit/25cea46aaa3d84521d1e977b67d3ac3581304ba1) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `deviceId` and `platform` to drafts as optional props - Updated dependencies []: - @atproto/common-web@0.4.15 ## 0.18.18 ### Patch Changes - [#4581](https://github.com/bluesky-social/atproto/pull/4581) [`2830dae`](https://github.com/bluesky-social/atproto/commit/2830daeaa6f580fbf777a0f832d64a6579616dc7) Thanks [@mozzius](https://github.com/mozzius)! - Add `presentation` to video embed as a hint to the client about how to display the video - Updated dependencies [[`d54d707`](https://github.com/bluesky-social/atproto/commit/d54d7077eb32041e1f61c312efa1dd0d768c774e), [`d54d707`](https://github.com/bluesky-social/atproto/commit/d54d7077eb32041e1f61c312efa1dd0d768c774e), [`d54d707`](https://github.com/bluesky-social/atproto/commit/d54d7077eb32041e1f61c312efa1dd0d768c774e)]: - @atproto/common-web@0.4.14 ## 0.18.17 ### Patch Changes - [#4565](https://github.com/bluesky-social/atproto/pull/4565) [`cbd5837`](https://github.com/bluesky-social/atproto/commit/cbd5837f015e6b5e098a60098faea82e7f9419f3) Thanks [@cuducos](https://github.com/cuducos)! - Re-add `recId` to suggested users (now, as string) - [#4547](https://github.com/bluesky-social/atproto/pull/4547) [`d8e5363`](https://github.com/bluesky-social/atproto/commit/d8e53636c84da6dd3dd69e1d260f4fa617f3883c) Thanks [@cuducos](https://github.com/cuducos)! - Removes `recId` from suggested users — we need it as a string, so we're gonna re-add it as string (instead of integer) later. - [#4415](https://github.com/bluesky-social/atproto/pull/4415) [`9bdd358`](https://github.com/bluesky-social/atproto/commit/9bdd35881aa7efce6595ef708ba13d99c473d114) Thanks [@bnewbold](https://github.com/bnewbold)! - support for Germ Networks chat declaration records - Updated dependencies [[`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101), [`7310b97`](https://github.com/bluesky-social/atproto/commit/7310b9704de678a3b389a741784d58bb7f79b10b), [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101), [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101), [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101), [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101)]: - @atproto/syntax@0.4.3 - @atproto/common-web@0.4.13 - @atproto/lexicon@0.6.1 ## 0.18.16 ### Patch Changes - [#4552](https://github.com/bluesky-social/atproto/pull/4552) [`ccd8964`](https://github.com/bluesky-social/atproto/commit/ccd89643313799f47c2f009c5c9dca48540275f1) Thanks [@mozzius](https://github.com/mozzius)! - Add `draft` lexicons ## 0.18.15 ### Patch Changes - [#4543](https://github.com/bluesky-social/atproto/pull/4543) [`f58029b`](https://github.com/bluesky-social/atproto/commit/f58029ba54305bed361c834a42bd96022b5b3c59) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `liveEventPreferences` to user preferences, add `updateLiveEventPreferences` to API SDK ## 0.18.14 ### Patch Changes - [#4539](https://github.com/bluesky-social/atproto/pull/4539) [`3ffebd0`](https://github.com/bluesky-social/atproto/commit/3ffebd0bf25776308e06e4b083dc2d0e156d9ac0) Thanks [@mozzius](https://github.com/mozzius)! - Add $cashtag support to the Rich Text facet detection - Updated dependencies []: - @atproto/common-web@0.4.12 ## 0.18.13 ### Patch Changes - [#4520](https://github.com/bluesky-social/atproto/pull/4520) [`d2ed731`](https://github.com/bluesky-social/atproto/commit/d2ed7311a20b8c990003628c932e3e5aa6569086) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `isDisabled` to `#statusView` ## 0.18.12 ### Patch Changes - [#4516](https://github.com/bluesky-social/atproto/pull/4516) [`7750b91`](https://github.com/bluesky-social/atproto/commit/7750b91500eef6965a17bc8ec0b3ddfd6327485a) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `uri` and `cid` to `#statusView` ## 0.18.11 ### Patch Changes - [#4513](https://github.com/bluesky-social/atproto/pull/4513) [`7ef8935`](https://github.com/bluesky-social/atproto/commit/7ef893563b25252ecf246e0d75e17855a7284e53) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds `minAccessAge` to Age Assurance regional configs. ## 0.18.10 ### Patch Changes - [#4440](https://github.com/bluesky-social/atproto/pull/4440) [`63f97ae`](https://github.com/bluesky-social/atproto/commit/63f97ae9c1f57def2d489ab8ce7f83a84a7d1ba1) Thanks [@iwsmith](https://github.com/iwsmith)! - Add `recID` field to `getSuggestedUsers` and `getSuggestedUsersSkeleton` ## 0.18.9 ### Patch Changes - [#4470](https://github.com/bluesky-social/atproto/pull/4470) [`10cf1c1`](https://github.com/bluesky-social/atproto/commit/10cf1c10188596724b0c38a5af507d95a382a164) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Use 401 status code as signal that the credentials are invalid and should no longer be used. - [#4470](https://github.com/bluesky-social/atproto/pull/4470) [`10cf1c1`](https://github.com/bluesky-social/atproto/commit/10cf1c10188596724b0c38a5af507d95a382a164) Thanks [@matthieusieben](https://github.com/matthieusieben)! - The `CredentialSession.resumeSession()` method now leverages full session data to restore user sessions in a single HTTP call (instead of up to three before). Servers that do not return `email` and `emailConfirmed` session fields will still be supported, but will cause an additional request to `com.atproto.server.getSession` to fetch the missing data. - Updated dependencies []: - @atproto/common-web@0.4.8 ## 0.18.8 ### Patch Changes - [#4452](https://github.com/bluesky-social/atproto/pull/4452) [`2e5a24c`](https://github.com/bluesky-social/atproto/commit/2e5a24cb875650120365e3f5c23a041e61a5f9c4) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Remove WARNING from contact lexicons - [#4445](https://github.com/bluesky-social/atproto/pull/4445) [`5622bcf`](https://github.com/bluesky-social/atproto/commit/5622bcf02315f9f24940a32aa3a6d9341c646c59) Thanks [@mozzius](https://github.com/mozzius)! - Add XRPC errors for `contact` APIs ## 0.18.7 ### Patch Changes - [#4436](https://github.com/bluesky-social/atproto/pull/4436) [`e266405`](https://github.com/bluesky-social/atproto/commit/e266405a89cd081ff96d36a784a31dd917c60a15) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add "contact-match" to listNotification reasons ## 0.18.6 ### Patch Changes - [#4432](https://github.com/bluesky-social/atproto/pull/4432) [`39fa570`](https://github.com/bluesky-social/atproto/commit/39fa57080fa04aa547b093cfeaaced3e2e62fc41) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add new read-only `#declaredAgePref` with computed age flags e.g. `isOverAge18`. - [#4430](https://github.com/bluesky-social/atproto/pull/4430) [`f4cef84`](https://github.com/bluesky-social/atproto/commit/f4cef84494114ca927c66428920ca3dc24ad2b1e) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add app.bsky.contact.sendNotification endpoint ## 0.18.5 ### Patch Changes - [#4393](https://github.com/bluesky-social/atproto/pull/4393) [`380aa3b`](https://github.com/bluesky-social/atproto/commit/380aa3bfe73b5c4e59961c27ae988786b69c129d) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add app.bsky.contact.\* lexicons, still without error handling. This is unstable and should not be used at this state. - [#4418](https://github.com/bluesky-social/atproto/pull/4418) [`308f432`](https://github.com/bluesky-social/atproto/commit/308f432f7aef196b4df0a6dc7c5367ab5a8b8964) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Expand return type of relationships in app.bsky.graph.getRelationships - [#4423](https://github.com/bluesky-social/atproto/pull/4423) [`a6e16cd`](https://github.com/bluesky-social/atproto/commit/a6e16cd0cd3029caf63ce2312dc5207532654763) Thanks [@foysalit](https://github.com/foysalit)! - Add min length for required comment fields in ozone events - Updated dependencies [[`d551b0e`](https://github.com/bluesky-social/atproto/commit/d551b0e3527714c111c3ec6e4c90ad7f46369fab), [`693784c`](https://github.com/bluesky-social/atproto/commit/693784c3a0dee4b6a29aa1e018fce682dcae148f)]: - @atproto/lexicon@0.6.0 - @atproto/common-web@0.4.7 - @atproto/xrpc@0.7.7 ## 0.18.4 ### Patch Changes - [#4407](https://github.com/bluesky-social/atproto/pull/4407) [`90f1569`](https://github.com/bluesky-social/atproto/commit/90f15698ee63d9a7374f1206754eda5d530873d7) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds ageassurance namespace, methods, and utils for Age Assurance V2 - Updated dependencies [[`bcae2b7`](https://github.com/bluesky-social/atproto/commit/bcae2b77b68da6dc2ec202651c8bf41fd5769f69)]: - @atproto/syntax@0.4.2 - @atproto/common-web@0.4.6 ## 0.18.3 ### Patch Changes - [#4347](https://github.com/bluesky-social/atproto/pull/4347) [`69f53d6`](https://github.com/bluesky-social/atproto/commit/69f53d632d84f255cafa8b10698184048a71b97b) Thanks [@bnewbold](https://github.com/bnewbold)! - lexicon updates to have fully-qualified token refs in knownValue lists - Updated dependencies []: - @atproto/common-web@0.4.5 ## 0.18.2 ### Patch Changes - Updated dependencies [[`261968fd6`](https://github.com/bluesky-social/atproto/commit/261968fd65014ded613e2bf085d61a7864b8fba7), [`261968fd6`](https://github.com/bluesky-social/atproto/commit/261968fd65014ded613e2bf085d61a7864b8fba7), [`261968fd6`](https://github.com/bluesky-social/atproto/commit/261968fd65014ded613e2bf085d61a7864b8fba7)]: - @atproto/common-web@0.4.4 - @atproto/lexicon@0.5.2 - @atproto/xrpc@0.7.6 ## 0.18.1 ### Patch Changes - [#4340](https://github.com/bluesky-social/atproto/pull/4340) [`032abf6b5`](https://github.com/bluesky-social/atproto/commit/032abf6b500fd36f3c0fc1af83bf62caae44fa6e) Thanks [@foysalit](https://github.com/foysalit)! - Add optional email data to scheduled action api in ozone - [#4344](https://github.com/bluesky-social/atproto/pull/4344) [`9115325c7`](https://github.com/bluesky-social/atproto/commit/9115325c7b36f0293f87f79bb8edb49f72fec2bc) Thanks [@foysalit](https://github.com/foysalit)! - Add targetServices param to takedown events allowing mods to specify which service to apply takedown on ## 0.18.0 ### Minor Changes - [#4227](https://github.com/bluesky-social/atproto/pull/4227) [`94ddc8219`](https://github.com/bluesky-social/atproto/commit/94ddc8219c144475df622137ab88895255136eda) Thanks [@bnewbold](https://github.com/bnewbold)! - Introduce `com.atproto.lexicon.resolveLexicon` lexicon method ### Patch Changes - [#4269](https://github.com/bluesky-social/atproto/pull/4269) [`39b5c08e0`](https://github.com/bluesky-social/atproto/commit/39b5c08e0799468eba0c3bf50f4f5a8104c35f34) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Deprecate and remove `prioritizeFollowedUsers` setting from preferences response types and `getPostThreadV2` query params. ## 0.17.7 ### Patch Changes - [#4317](https://github.com/bluesky-social/atproto/pull/4317) [`15fe80c39`](https://github.com/bluesky-social/atproto/commit/15fe80c39ff428652dfaa6b30c0bdb59a145aac6) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `via` to `follow` record to mirror `like` records and provide a way to reference the starter pack that the follow originated from. ## 0.17.6 ### Patch Changes - [#4314](https://github.com/bluesky-social/atproto/pull/4314) [`7c1429fe3`](https://github.com/bluesky-social/atproto/commit/7c1429fe36226d0d57e57c037ba4221d2fbd57ee) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add debug field to `PostView` and `ProfileView*` (see cdb6b27fc6be1e858476d8c55fd0c37561b972b4) ## 0.17.5 ### Patch Changes - [#4279](https://github.com/bluesky-social/atproto/pull/4279) [`601401afc`](https://github.com/bluesky-social/atproto/commit/601401afce9f4da2e8a257f8dcca996dd64e6031) Thanks [@foysalit](https://github.com/foysalit)! - Add strike system to ozone ## 0.17.4 ### Patch Changes - [#4299](https://github.com/bluesky-social/atproto/pull/4299) [`a8e307ef4`](https://github.com/bluesky-social/atproto/commit/a8e307ef4851b164ee38bb5149343631e329f143) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Record types are now exported as both `.Record` (as they used to) and `.Main` (for consistency) ## 0.17.3 ### Patch Changes - [#4268](https://github.com/bluesky-social/atproto/pull/4268) [`386f583cf`](https://github.com/bluesky-social/atproto/commit/386f583cffa2c596a12be4e98dde498f3b8670f6) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Bump threadgate `hiddenReplies` field `maxLength` to 300. ## 0.17.2 ### Patch Changes - [#4262](https://github.com/bluesky-social/atproto/pull/4262) [`1cb5b9b80`](https://github.com/bluesky-social/atproto/commit/1cb5b9b80c20a054f7fbacd89d0d440dc2241d81) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Finalize report reason lexicons, update migration map in Ozone ## 0.17.1 ### Patch Changes - [#4216](https://github.com/bluesky-social/atproto/pull/4216) [`09439d7d6`](https://github.com/bluesky-social/atproto/commit/09439d7d688294ad1a0c78a74b901ba2f7c5f4c3) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Create a dedicated type for the `proxy` property - [#4216](https://github.com/bluesky-social/atproto/pull/4216) [`09439d7d6`](https://github.com/bluesky-social/atproto/commit/09439d7d688294ad1a0c78a74b901ba2f7c5f4c3) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Improve validation when setting an `Agent`'s `proxy` property - [#4241](https://github.com/bluesky-social/atproto/pull/4241) [`591de1952`](https://github.com/bluesky-social/atproto/commit/591de19524639341a7dd64ee75c482c645c186fd) Thanks [@foysalit](https://github.com/foysalit)! - Add scheduled action api to ozone ## 0.17.0 ### Minor Changes - [#4238](https://github.com/bluesky-social/atproto/pull/4238) [`dba2d30e2`](https://github.com/bluesky-social/atproto/commit/dba2d30e2c4ce0eb624f2139b485719d14474940) Thanks [@gaearon](https://github.com/gaearon)! - Don't clear session in resumeSession on transient network errors ### Patch Changes - [#4232](https://github.com/bluesky-social/atproto/pull/4232) [`7f38ee03c`](https://github.com/bluesky-social/atproto/commit/7f38ee03c01357686a4ce54cdf8eed4e37074a58) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add `pronouns` to `profileView` and `profileViewBasic` ## 0.16.11 ### Patch Changes - [#4228](https://github.com/bluesky-social/atproto/pull/4228) [`1a5d7427b`](https://github.com/bluesky-social/atproto/commit/1a5d7427bf5811a019e7b50c7c2af711b8f2dd33) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add app.bsky.unspecced.getOnboardingSuggestedStarterPacks - [#4228](https://github.com/bluesky-social/atproto/pull/4228) [`1a5d7427b`](https://github.com/bluesky-social/atproto/commit/1a5d7427bf5811a019e7b50c7c2af711b8f2dd33) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton ## 0.16.10 ### Patch Changes - [#4224](https://github.com/bluesky-social/atproto/pull/4224) [`8dc4caf55`](https://github.com/bluesky-social/atproto/commit/8dc4caf55840578c835b4c851d4a599c15627a78) Thanks [@rafaeleyng](https://github.com/rafaeleyng)! - Add `pronouns` and `website` to `app.bsky.actor.profile` ## 0.16.9 ### Patch Changes - [#4189](https://github.com/bluesky-social/atproto/pull/4189) [`ff30786af`](https://github.com/bluesky-social/atproto/commit/ff30786af6f72ad6506939bfca01a3f55a096c1c) Thanks [@foysalit](https://github.com/foysalit)! - Add revoke credentials moderation event type to lexicons ## 0.16.8 ### Patch Changes - [#3881](https://github.com/bluesky-social/atproto/pull/3881) [`a5b20f021`](https://github.com/bluesky-social/atproto/commit/a5b20f0218bd13e3c5d7681de2263dcc850b7523) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add expanded moderation report reasons as outlined in [RFC-0009](https://github.com/bluesky-social/proposals/tree/main/0009-mod-report-granularity) - Updated dependencies [[`055a413fb`](https://github.com/bluesky-social/atproto/commit/055a413fba4fab510ec899377154f1204ab12099)]: - @atproto/common-web@0.4.3 - @atproto/lexicon@0.5.1 - @atproto/xrpc@0.7.5 ## 0.16.7 ### Patch Changes - [#4164](https://github.com/bluesky-social/atproto/pull/4164) [`09717f29a`](https://github.com/bluesky-social/atproto/commit/09717f29ac7ca742c9c3310980dbe4d112b7597f) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add bookmarks lexicons ## 0.16.6 ### Patch Changes - Updated dependencies [[`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d), [`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d), [`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d), [`f9dc9aa4c`](https://github.com/bluesky-social/atproto/commit/f9dc9aa4c9eaf2f82d140fbf011a9015e7f1a00d)]: - @atproto/lexicon@0.5.0 - @atproto/syntax@0.4.1 - @atproto/xrpc@0.7.4 ## 0.16.5 ### Patch Changes - [#4142](https://github.com/bluesky-social/atproto/pull/4142) [`66dbf8db6`](https://github.com/bluesky-social/atproto/commit/66dbf8db6dd9defeee140accd2e7b25d13feb8b6) Thanks [@DavidBuchanan314](https://github.com/DavidBuchanan314)! - add com.atproto.temp.revokeAccountCredentials lexicon schema ## 0.16.4 ### Patch Changes - Updated dependencies [[`2104d9033`](https://github.com/bluesky-social/atproto/commit/2104d9033e2e1a3a7b821c1f0c5c8ffac5832d59)]: - @atproto/lexicon@0.4.14 - @atproto/xrpc@0.7.3 ## 0.16.3 ### Patch Changes - [#4109](https://github.com/bluesky-social/atproto/pull/4109) [`3156ddf61`](https://github.com/bluesky-social/atproto/commit/3156ddf61519fede9ed148478f082184a1e3242e) Thanks [@foysalit](https://github.com/foysalit)! - Add batchId filter to tools.ozone.moderation.queryEvents endpoint - Updated dependencies [[`331a356ce`](https://github.com/bluesky-social/atproto/commit/331a356ce27ff1d0b24747b0c16f3b54b07a0a12)]: - @atproto/lexicon@0.4.13 - @atproto/xrpc@0.7.2 ## 0.16.2 ### Patch Changes - [#4081](https://github.com/bluesky-social/atproto/pull/4081) [`c370d933b`](https://github.com/bluesky-social/atproto/commit/c370d933b76b4e15b83a82b40d1b6a32bd54add6) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Adds `purpose` filtering to `app.bsky.graph.getLists`. Adds `app.bsky.graph.getListsWithMembership`. Adds `app.bsky.graph.getStarterPacksWithMembership`. ## 0.16.1 ### Patch Changes - [#3927](https://github.com/bluesky-social/atproto/pull/3927) [`171efadb4`](https://github.com/bluesky-social/atproto/commit/171efadb49f842aa8ff3bf9d790caa6e0e0456ef) Thanks [@foysalit](https://github.com/foysalit)! - Introduces ozone event timeline lexicons ## 0.16.0 ### Minor Changes - [#4072](https://github.com/bluesky-social/atproto/pull/4072) [`9751eebd7`](https://github.com/bluesky-social/atproto/commit/9751eebd718066984a91046b63e410caecd64022) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Remove app.bsky.unspecced.checkHandleAvailability, add com.atproto.temp.checkHandleAvailability ## 0.15.27 ### Patch Changes - [#4058](https://github.com/bluesky-social/atproto/pull/4058) [`8787fd9de`](https://github.com/bluesky-social/atproto/commit/8787fd9dea769716412c9883e355cd496664bc6e) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Only allow initiating age assurance flow from certain states, return `InvalidInitiation` error if violated. - [#4049](https://github.com/bluesky-social/atproto/pull/4049) [`dc84906c8`](https://github.com/bluesky-social/atproto/commit/dc84906c865e8a97939a909dd3f75decde538363) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - app.bsky.unspecced.checkHandleAvailability lexicon ## 0.15.26 ### Patch Changes - [#4041](https://github.com/bluesky-social/atproto/pull/4041) [`083566ddf`](https://github.com/bluesky-social/atproto/commit/083566ddfc3c9263423ebd5e59bfdbfe7b091c82) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add `unregisterPush` API - [#4048](https://github.com/bluesky-social/atproto/pull/4048) [`3b356c509`](https://github.com/bluesky-social/atproto/commit/3b356c5096a269f1be6c4e69bdee7f5d14eb5d7e) Thanks [@foysalit](https://github.com/foysalit)! - Add externalId to ozone events for deduping events per subject and event type ## 0.15.25 ### Patch Changes - [#4028](https://github.com/bluesky-social/atproto/pull/4028) [`88c136427`](https://github.com/bluesky-social/atproto/commit/88c136427451a20d21812a1aa88a70cf21904138) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Age assurance compliance ## 0.15.24 ### Patch Changes - [#4034](https://github.com/bluesky-social/atproto/pull/4034) [`34d7a0846`](https://github.com/bluesky-social/atproto/commit/34d7a0846bb14bb36a8cc2747fb7ce73005e59d1) Thanks [@foysalit](https://github.com/foysalit)! - Add age assurance event types to ozone lexicons - Updated dependencies [[`8ef976d38`](https://github.com/bluesky-social/atproto/commit/8ef976d3852df4bfa376e515e131cc0810a42f20)]: - @atproto/lexicon@0.4.12 - @atproto/xrpc@0.7.1 ## 0.15.23 ### Patch Changes - [#3991](https://github.com/bluesky-social/atproto/pull/3991) [`0c0381a2b`](https://github.com/bluesky-social/atproto/commit/0c0381a2bb9b9dc14ca6c1c8c4a6b966f0d516e8) Thanks [@foysalit](https://github.com/foysalit)! - Add modTool parameter to ozone events ## 0.15.22 ### Patch Changes - [#3945](https://github.com/bluesky-social/atproto/pull/3945) [`02c358d0c`](https://github.com/bluesky-social/atproto/commit/02c358d0ca280922c20da5be1e23b4aa9e90a30b) Thanks [@foysalit](https://github.com/foysalit)! - Add safelink module in ozone ## 0.15.21 ### Patch Changes - [#4010](https://github.com/bluesky-social/atproto/pull/4010) [`d344723a1`](https://github.com/bluesky-social/atproto/commit/d344723a1018b2436b5453526397936bd587a2e2) Thanks [@mozzius](https://github.com/mozzius)! - Loosen constraints for saved feed preferences ## 0.15.20 ### Patch Changes - [#4005](https://github.com/bluesky-social/atproto/pull/4005) [`bb65f7a6e`](https://github.com/bluesky-social/atproto/commit/bb65f7a6e22ceedb57c74a18cf0539c1dd04c0a7) Thanks [@mozzius](https://github.com/mozzius)! - add `subscribed-post` notification reason ## 0.15.19 ### Patch Changes - [#3997](https://github.com/bluesky-social/atproto/pull/3997) [`376778a92`](https://github.com/bluesky-social/atproto/commit/376778a92f08fb6709c4cde736bfaca7393a72e1) Thanks [@mozzius](https://github.com/mozzius)! - Add put method for AppBskyNotificationDeclarationRecord ## 0.15.18 ### Patch Changes - [#3995](https://github.com/bluesky-social/atproto/pull/3995) [`e3e31b2b9`](https://github.com/bluesky-social/atproto/commit/e3e31b2b9bf8c4de6b2d7fa992c3b3795686ea72) Thanks [@mozzius](https://github.com/mozzius)! - Add put method to record utility classes ## 0.15.17 ### Patch Changes - [#3990](https://github.com/bluesky-social/atproto/pull/3990) [`6cd120206`](https://github.com/bluesky-social/atproto/commit/6cd12020657bfb5f87e97cd16e4abb379b64f60b) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add activity subscription lexicons ## 0.15.16 ### Patch Changes - [#3966](https://github.com/bluesky-social/atproto/pull/3966) [`97ef11657`](https://github.com/bluesky-social/atproto/commit/97ef116571909c95713017bcd7b621c8afbc90ef) Thanks [@mozzius](https://github.com/mozzius)! - Rename notification preference lexicon "filter" key to "include" ## 0.15.15 ### Patch Changes - [#2934](https://github.com/bluesky-social/atproto/pull/2934) [`7f1316748`](https://github.com/bluesky-social/atproto/commit/7f1316748dedb512ae739ad51b95644baa39fe80) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Fix bug where fuzzy matching mute words was over-zealous e.g. `Andor` matching `and/or`. - [#2934](https://github.com/bluesky-social/atproto/pull/2934) [`7f1316748`](https://github.com/bluesky-social/atproto/commit/7f1316748dedb512ae739ad51b95644baa39fe80) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Updates mute word matching to include a `matches: MuteWordMatch[]` property on the `muted-word` `cause` type returned as part of a `ModerationDecision`. ## 0.15.14 ### Patch Changes - [#3901](https://github.com/bluesky-social/atproto/pull/3901) [`a48671e73`](https://github.com/bluesky-social/atproto/commit/a48671e730681f692a88053e8f137bd9e2aed5f1) Thanks [@mozzius](https://github.com/mozzius)! - Add notification preferences V2 lexicons ## 0.15.13 ### Patch Changes - [#3929](https://github.com/bluesky-social/atproto/pull/3929) [`c6eb8a12e`](https://github.com/bluesky-social/atproto/commit/c6eb8a12e291c88fea79da447f9da8608d02300d) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Rename `getPostThreadHiddenV2` to `getPostThreadOtherV2` to better reflect the intent of the API. ## 0.15.12 ### Patch Changes - [#3912](https://github.com/bluesky-social/atproto/pull/3912) [`a5cd018bd`](https://github.com/bluesky-social/atproto/commit/a5cd018bd5f237221902ab1b6956b46233c92187) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Unify `getPostThreadV2` and `getPostThreadHiddenV2` responses under `app.bsky.unspecced.defs` namespace and a single interface via `threadItemPost`. ## 0.15.11 ### Patch Changes - [#3910](https://github.com/bluesky-social/atproto/pull/3910) [`a978681fd`](https://github.com/bluesky-social/atproto/commit/a978681fde1c138a5298bae77e5dc36ce155f955) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Updates to app.bsky.unspecced.getPostThreadHiddenV2 done in f6d5a467e71fb54996754cce7747b1e98a34442b (https://github.com/bluesky-social/atproto/pull/3909) ## 0.15.10 ### Patch Changes - [#3825](https://github.com/bluesky-social/atproto/pull/3825) [`1dae6c59a`](https://github.com/bluesky-social/atproto/commit/1dae6c59abe0e5aa4a7b7d0cc1dfee88f458d4b9) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add app.bsky.unspecced.getPostThreadV2 - [#3825](https://github.com/bluesky-social/atproto/pull/3825) [`1dae6c59a`](https://github.com/bluesky-social/atproto/commit/1dae6c59abe0e5aa4a7b7d0cc1dfee88f458d4b9) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add app.bsky.unspecced.getPostThreadHiddenV2 ## 0.15.9 ### Patch Changes - [#3882](https://github.com/bluesky-social/atproto/pull/3882) [`79a75bb1e`](https://github.com/bluesky-social/atproto/commit/79a75bb1ed8fc14cefa246621fe1faeebf3fc159) Thanks [@mozzius](https://github.com/mozzius)! - add a "via" field to reposts and likes allowing a reference a repost, and then give a notification when a repost is liked or reposted. ## 0.15.8 ### Patch Changes - [#3869](https://github.com/bluesky-social/atproto/pull/3869) [`80f402f36`](https://github.com/bluesky-social/atproto/commit/80f402f3663af08fd048300738d04c67aa2b9cb8) Thanks [@haileyok](https://github.com/haileyok)! - add `reqId` to feed interactions ## 0.15.7 ### Patch Changes - [#3860](https://github.com/bluesky-social/atproto/pull/3860) [`86b315388`](https://github.com/bluesky-social/atproto/commit/86b3153884099ceeb0cfdb9d2bfdd447c39fb35a) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add liveNow to app.bsky.unspecced.getConfig ## 0.15.6 ### Patch Changes - [#3824](https://github.com/bluesky-social/atproto/pull/3824) [`3a65b68f7`](https://github.com/bluesky-social/atproto/commit/3a65b68f7dc63c8bfbea0ae615f8ae984272f2e4) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add app.bsky.actor.status lexicon - Updated dependencies [[`cc485d296`](https://github.com/bluesky-social/atproto/commit/cc485d29638488928b5efec3d4b0627040589812), [`f36ab48d9`](https://github.com/bluesky-social/atproto/commit/f36ab48d910fc4a3afcd22138ba014c814beb93b), [`f36ab48d9`](https://github.com/bluesky-social/atproto/commit/f36ab48d910fc4a3afcd22138ba014c814beb93b), [`f36ab48d9`](https://github.com/bluesky-social/atproto/commit/f36ab48d910fc4a3afcd22138ba014c814beb93b), [`cc485d296`](https://github.com/bluesky-social/atproto/commit/cc485d29638488928b5efec3d4b0627040589812)]: - @atproto/common-web@0.4.2 - @atproto/xrpc@0.7.0 - @atproto/lexicon@0.4.11 ## 0.15.5 ### Patch Changes - [#3765](https://github.com/bluesky-social/atproto/pull/3765) [`45354c84f`](https://github.com/bluesky-social/atproto/commit/45354c84f898d79f58c14b5c0da3661beb7353f9) Thanks [@foysalit](https://github.com/foysalit)! - Add verification lexicons to ozone ## 0.15.4 ### Patch Changes - [#3768](https://github.com/bluesky-social/atproto/pull/3768) [`7af77f3ed`](https://github.com/bluesky-social/atproto/commit/7af77f3edfe52f77729f61de4188e8375f03b4ef) Thanks [@devinivy](https://github.com/devinivy)! - Support tools.ozone.hosting.getAccountHistory ## 0.15.3 ### Patch Changes - [#3773](https://github.com/bluesky-social/atproto/pull/3773) [`0087dc1c0`](https://github.com/bluesky-social/atproto/commit/0087dc1c0bafad1d0a0a1a16683d250dea031bf9) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add verification notifications ## 0.15.2 ### Patch Changes - [#3770](https://github.com/bluesky-social/atproto/pull/3770) [`553c988f1`](https://github.com/bluesky-social/atproto/commit/553c988f1d226b3d2fbe94c117b088f5c82db794) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `verificationPrefs` and `hideBadges` setting to user prefs. ## 0.15.1 ### Patch Changes - [#3761](https://github.com/bluesky-social/atproto/pull/3761) [`688268b6a`](https://github.com/bluesky-social/atproto/commit/688268b6a5ee30f0922ee152ffbd26583d164ae4) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add verification state to profile view lexicons - [#3766](https://github.com/bluesky-social/atproto/pull/3766) [`8d99915ce`](https://github.com/bluesky-social/atproto/commit/8d99915ce02c73b9b37bf121ccd2703fa14a906a) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Update chat verification lexicon ## 0.15.0 ### Minor Changes - [#3715](https://github.com/bluesky-social/atproto/pull/3715) [`23462184d`](https://github.com/bluesky-social/atproto/commit/23462184dc941ba2fc3b4d054985a53715585020) Thanks [@knotbin](https://github.com/knotbin)! - run codegen for changes in lex-cli ## 0.14.22 ### Patch Changes - [#3714](https://github.com/bluesky-social/atproto/pull/3714) [`fc61662d7`](https://github.com/bluesky-social/atproto/commit/fc61662d7b88597f78383e37ee54264a8bb4b670) Thanks [@bnewbold](https://github.com/bnewbold)! - new lexicons: listHosts and getHostStatus endpoints under com.atproto.sync - [#3741](https://github.com/bluesky-social/atproto/pull/3741) [`ca07871c4`](https://github.com/bluesky-social/atproto/commit/ca07871c487abc99fe7b7f8671aa8d98eb5dc4bb) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Update reaction limit on chat lexicon ## 0.14.21 ### Patch Changes - [#3724](https://github.com/bluesky-social/atproto/pull/3724) [`8b7bf7e8f`](https://github.com/bluesky-social/atproto/commit/8b7bf7e8f0e5447c68633a87a2a3cff99f9e7e1c) Thanks [@haileyok](https://github.com/haileyok)! - Return `ProfileView` from `getSuggestedUsers` unspecced endpoint ## 0.14.20 ### Patch Changes - [#3713](https://github.com/bluesky-social/atproto/pull/3713) [`0e681d303`](https://github.com/bluesky-social/atproto/commit/0e681d3036fd0b35c6d2198638392051b2ce4c81) Thanks [@haileyok](https://github.com/haileyok)! - add `getSuggestedUsers` and `getSuggestedUsersSkeleton` ## 0.14.19 ### Patch Changes - [#3680](https://github.com/bluesky-social/atproto/pull/3680) [`efb302db1`](https://github.com/bluesky-social/atproto/commit/efb302db1a615b68795c725a22489dbd0400e011) Thanks [@haileyok](https://github.com/haileyok)! - Add unspecced `getSuggestedFeeds` and associated types - Updated dependencies [[`4db923ca1`](https://github.com/bluesky-social/atproto/commit/4db923ca1c4fadd31d41c851933659e5186ee144)]: - @atproto/common-web@0.4.1 - @atproto/lexicon@0.4.10 - @atproto/xrpc@0.6.12 ## 0.14.18 ### Patch Changes - [#3706](https://github.com/bluesky-social/atproto/pull/3706) [`04b6230cd`](https://github.com/bluesky-social/atproto/commit/04b6230cd2fbfe4a06cb00ab8ccb8e6c87c6c546) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Return `StarterPackView` instead of `StarterPackViewBasic` from `getSuggestedStarterPacks` ## 0.14.17 ### Patch Changes - [#2519](https://github.com/bluesky-social/atproto/pull/2519) [`bdbd3c3e3`](https://github.com/bluesky-social/atproto/commit/bdbd3c3e3f8fe8476a3fecac73810554846c938f) Thanks [@dholms](https://github.com/dholms)! - Add com.atproto.admin.updateAccountSigningKey - [#3673](https://github.com/bluesky-social/atproto/pull/3673) [`2b7efb6cb`](https://github.com/bluesky-social/atproto/commit/2b7efb6cb1c93a108570efdafe9d9ec3f1018dfa) Thanks [@haileyok](https://github.com/haileyok)! - Add `getTrends`, `getTrendsSkeleton`, and associated types - [#3705](https://github.com/bluesky-social/atproto/pull/3705) [`b0a0f1484`](https://github.com/bluesky-social/atproto/commit/b0a0f1484378adeb5e2aa20b9b6ff2c2eca0f740) Thanks [@dholms](https://github.com/dholms)! - Fix codegent for com.atproto.admin.updateAccountSigningKey - [#3677](https://github.com/bluesky-social/atproto/pull/3677) [`0eea698be`](https://github.com/bluesky-social/atproto/commit/0eea698bef76520ae4cc0e1f2efbb588a0459556) Thanks [@haileyok](https://github.com/haileyok)! - Add `getSuggestedStarterPacks`, `getSuggestedStarterPacksSkeleton`, and associated types ## 0.14.16 ### Patch Changes - [#3695](https://github.com/bluesky-social/atproto/pull/3695) [`652894308`](https://github.com/bluesky-social/atproto/commit/65289430806976ec13177ed9c9f0e883e8f9330c) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Fix last reaction lexicon ## 0.14.15 ### Patch Changes - [#3692](https://github.com/bluesky-social/atproto/pull/3692) [`b4ab5011b`](https://github.com/bluesky-social/atproto/commit/b4ab5011bcc64f9f05122a8773806af8e0c13146) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Support more ways to instantiate an `Agent` ## 0.14.14 ### Patch Changes - [#3685](https://github.com/bluesky-social/atproto/pull/3685) [`9a05892f6`](https://github.com/bluesky-social/atproto/commit/9a05892f6fd405bf6bb96c9c8d2a9a89d5e94bc5) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Update chat reaction lexicon ## 0.14.13 ### Patch Changes - [#3651](https://github.com/bluesky-social/atproto/pull/3651) [`076c2f987`](https://github.com/bluesky-social/atproto/commit/076c2f9872387217806624306e3af08878d1adcd) Thanks [@foysalit](https://github.com/foysalit)! - Add getSubjects endpoint to ozone for fetching detailed view of multiple subjects ## 0.14.12 ### Patch Changes - [#3674](https://github.com/bluesky-social/atproto/pull/3674) [`44f5c3639`](https://github.com/bluesky-social/atproto/commit/44f5c3639fcaf73865d21ec4b0c64baa641006c0) Thanks [@mozzius](https://github.com/mozzius)! - run codegen for changes in chat lexicon ## 0.14.11 ### Patch Changes - [#3670](https://github.com/bluesky-social/atproto/pull/3670) [`d87ffc7bf`](https://github.com/bluesky-social/atproto/commit/d87ffc7bfe3c1e792dc84a320544eb2e053d61ce) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add DM reactions lexicons ## 0.14.10 ### Patch Changes - Updated dependencies [[`670b6b5de`](https://github.com/bluesky-social/atproto/commit/670b6b5de2bf91e6944761c98eb1126fb6a681ee)]: - @atproto/syntax@0.4.0 - @atproto/lexicon@0.4.9 - @atproto/xrpc@0.6.11 ## 0.14.9 ### Patch Changes - [#3587](https://github.com/bluesky-social/atproto/pull/3587) [`18fbfa000`](https://github.com/bluesky-social/atproto/commit/18fbfa00057dda9ef4eba77d8b4e87994893c952) Thanks [@foysalit](https://github.com/foysalit)! - Add searchable handle and displayName to ozone team members ## 0.14.8 ### Patch Changes - [#3585](https://github.com/bluesky-social/atproto/pull/3585) [`38320191e`](https://github.com/bluesky-social/atproto/commit/38320191e559f8b928c6e951a9b4a6207240bfc1) Thanks [@dholms](https://github.com/dholms)! - Wrap sync v1.1 semantics. Add #sync event to subscribeRepos and deprecate #handle and #tombstone events - [#3602](https://github.com/bluesky-social/atproto/pull/3602) [`6bcbb6d8c`](https://github.com/bluesky-social/atproto/commit/6bcbb6d8cd3696280935ff7892d8e191fd21fa49) Thanks [@devinivy](https://github.com/devinivy)! - Permit 100mb video embeds. - [#2264](https://github.com/bluesky-social/atproto/pull/2264) [`dc6e4ecb0`](https://github.com/bluesky-social/atproto/commit/dc6e4ecb0e09bbf4bc7a79c6ac43fb6da4166200) Thanks [@bnewbold](https://github.com/bnewbold)! - new com.atproto.identity endpoints: resolveDid, resolveIdentity, refreshIdentity - Updated dependencies [[`850e39843`](https://github.com/bluesky-social/atproto/commit/850e39843cb0ec9ea716675f7568c0c601f45e29)]: - @atproto/syntax@0.3.4 - @atproto/lexicon@0.4.8 - @atproto/xrpc@0.6.10 ## 0.14.7 ### Patch Changes - [#3521](https://github.com/bluesky-social/atproto/pull/3521) [`99e2809ca`](https://github.com/bluesky-social/atproto/commit/99e2809ca2ebf70acaa10254f140a8dd0fad4305) Thanks [@bnewbold](https://github.com/bnewbold)! - Add `reasonTypes`, `subjectTypes`, and `subjectCollections` properties to labeler service records. - [#2506](https://github.com/bluesky-social/atproto/pull/2506) [`27b0a7be1`](https://github.com/bluesky-social/atproto/commit/27b0a7be1ed1b6e098114791d84ec9dc844db552) Thanks [@bnewbold](https://github.com/bnewbold)! - remove some deprecated fields from com.atproto Lexicons - [#3579](https://github.com/bluesky-social/atproto/pull/3579) [`11d8d21be`](https://github.com/bluesky-social/atproto/commit/11d8d21beac4b79ac44b930197761f9d08dbb492) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Mirror new labeler service record properties on `labelerViewDetailed`. ## 0.14.6 ### Patch Changes - [#3576](https://github.com/bluesky-social/atproto/pull/3576) [`44f81f2eb`](https://github.com/bluesky-social/atproto/commit/44f81f2eb9229e21aec4472b3a05e855396dbec5) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add chat.bsky.convo.updateAllRead lex ## 0.14.5 ### Patch Changes - [#3449](https://github.com/bluesky-social/atproto/pull/3449) [`7e3678c08`](https://github.com/bluesky-social/atproto/commit/7e3678c089d2faa1a884a52a4fb80b8116c9854f) Thanks [@dholms](https://github.com/dholms)! - Updated subscribeRepo to include prev CIDs for operations and covering proofs for all ops. - [#3572](https://github.com/bluesky-social/atproto/pull/3572) [`9b643fbec`](https://github.com/bluesky-social/atproto/commit/9b643fbecac30de5cfdb80d0671bfa55e9f4512a) Thanks [@foysalit](https://github.com/foysalit)! - Make comment property optional on ozone comment event - [#3391](https://github.com/bluesky-social/atproto/pull/3391) [`6e382f67a`](https://github.com/bluesky-social/atproto/commit/6e382f67aa73532efadfea80ff96a27b526cb178) Thanks [@bnewbold](https://github.com/bnewbold)! - update sync lexicons for induction firehose ## 0.14.4 ### Patch Changes - [#3561](https://github.com/bluesky-social/atproto/pull/3561) [`b9cb049d9`](https://github.com/bluesky-social/atproto/commit/b9cb049d940cc706681142ef498238f74e2f539c) Thanks [@foysalit](https://github.com/foysalit)! - Add Divert event to the list of allowed ozone events ## 0.14.3 ### Patch Changes - [#3564](https://github.com/bluesky-social/atproto/pull/3564) [`22af31a89`](https://github.com/bluesky-social/atproto/commit/22af31a898476c5e317aea263af366bddda120d6) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Update chat lexicons - [#2378](https://github.com/bluesky-social/atproto/pull/2378) [`01874c4be`](https://github.com/bluesky-social/atproto/commit/01874c4be73a41ffb8fe28378f674949aa2c938f) Thanks [@bnewbold](https://github.com/bnewbold)! - set 'tid' and 'record-key' formats on com.atproto.sync and com.atproto.repo lexicons ## 0.14.2 ### Patch Changes - [#3524](https://github.com/bluesky-social/atproto/pull/3524) [`010f10c6f`](https://github.com/bluesky-social/atproto/commit/010f10c6f212f699ad42c0349a58bbcf2172e3cc) Thanks [@bnewbold](https://github.com/bnewbold)! - add com.atproto.sync.listReposByCollection Lexicon - [#3546](https://github.com/bluesky-social/atproto/pull/3546) [`a9887f687`](https://github.com/bluesky-social/atproto/commit/a9887f68778c49932d92cfea98aadcfa4d5b62e9) Thanks [@foysalit](https://github.com/foysalit)! - Add reporter stats endpoint on ozone service ## 0.14.1 ### Patch Changes - [#3535](https://github.com/bluesky-social/atproto/pull/3535) [`ba5bb6e66`](https://github.com/bluesky-social/atproto/commit/ba5bb6e667fb58bbefd332844957de575e102ca3) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fix bug preventing "logout()" calls from working. ## 0.14.0 ### Minor Changes - [#2999](https://github.com/bluesky-social/atproto/pull/2999) [`c53d943c8`](https://github.com/bluesky-social/atproto/commit/c53d943c8be5b8886254e020970a68c0f745b14c) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Update Lexicon derived code to better reflect data typings. In particular, Lexicon derived interfaces will now explicitly include the `$type` property that can be present in the data. - [#2999](https://github.com/bluesky-social/atproto/pull/2999) [`c53d943c8`](https://github.com/bluesky-social/atproto/commit/c53d943c8be5b8886254e020970a68c0f745b14c) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Helper functions (e.g. `NS.isRecord`) no longer casts the output value. Use `asPredicate(NS.validateRecord)` to create a predicate function that will ensure that an unknown value is indeed an `NS.Record`. The `isX` helper function's purpose is to discriminate between `$type`d values from unions. ### Patch Changes - [#2999](https://github.com/bluesky-social/atproto/pull/2999) [`c53d943c8`](https://github.com/bluesky-social/atproto/commit/c53d943c8be5b8886254e020970a68c0f745b14c) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fixes a bug that would clear interests prefs when updating hidden posts - Updated dependencies [[`c53d943c8`](https://github.com/bluesky-social/atproto/commit/c53d943c8be5b8886254e020970a68c0f745b14c), [`c53d943c8`](https://github.com/bluesky-social/atproto/commit/c53d943c8be5b8886254e020970a68c0f745b14c), [`c53d943c8`](https://github.com/bluesky-social/atproto/commit/c53d943c8be5b8886254e020970a68c0f745b14c)]: - @atproto/syntax@0.3.3 - @atproto/lexicon@0.4.7 - @atproto/xrpc@0.6.9 ## 0.13.35 ### Patch Changes - [#3495](https://github.com/bluesky-social/atproto/pull/3495) [`709a85b0b`](https://github.com/bluesky-social/atproto/commit/709a85b0b633b5483b7161db64b429c746239153) Thanks [@foysalit](https://github.com/foysalit)! - Add a priority score to ozone subjects ## 0.13.34 ### Patch Changes - [#3496](https://github.com/bluesky-social/atproto/pull/3496) [`dc8a7842e`](https://github.com/bluesky-social/atproto/commit/dc8a7842e67f5f3709e88310d2a60d384453b486) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add followerRule threadgate - [#3501](https://github.com/bluesky-social/atproto/pull/3501) [`636951e47`](https://github.com/bluesky-social/atproto/commit/636951e4728cd52c2e5355eb93b47d7e869b67e9) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Include `followerRule` as valid setting in `postInteractionSettings` pref ## 0.13.33 ### Patch Changes - [#3220](https://github.com/bluesky-social/atproto/pull/3220) [`61dc0d60e`](https://github.com/bluesky-social/atproto/commit/61dc0d60e19b88c6427a54c6d95a391b5f4da7bd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Apply new linting rules regarding import order - [#3494](https://github.com/bluesky-social/atproto/pull/3494) [`87ed907a6`](https://github.com/bluesky-social/atproto/commit/87ed907a6b96b408c02c9af819cec8380a453254) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `setPostInteractionSettings` for configuring default interaction settings for creation of posts - Updated dependencies [[`61dc0d60e`](https://github.com/bluesky-social/atproto/commit/61dc0d60e19b88c6427a54c6d95a391b5f4da7bd), [`8a30e0ed9`](https://github.com/bluesky-social/atproto/commit/8a30e0ed9239cb2037d54fb98e70e8b0cfbc3e39)]: - @atproto/common-web@0.4.0 - @atproto/lexicon@0.4.6 - @atproto/syntax@0.3.2 - @atproto/xrpc@0.6.8 ## 0.13.32 ### Patch Changes - [#3352](https://github.com/bluesky-social/atproto/pull/3352) [`7f52e6735`](https://github.com/bluesky-social/atproto/commit/7f52e67354906c3bf9830d7a2924ab58d6160905) Thanks [@foysalit](https://github.com/foysalit)! - Auto resolve appeals when taking down - Updated dependencies [[`fb64d50ee`](https://github.com/bluesky-social/atproto/commit/fb64d50ee220316b9f1183e5c3259629489734c9)]: - @atproto/xrpc@0.6.7 ## 0.13.31 ### Patch Changes - [#3441](https://github.com/bluesky-social/atproto/pull/3441) [`8c6c7813a`](https://github.com/bluesky-social/atproto/commit/8c6c7813a9c2110c8fe21acdca8f09554a1983ce) Thanks [@mozzius](https://github.com/mozzius)! - Allow passing `allowTakendown` to createSession ## 0.13.30 ### Patch Changes - [#3429](https://github.com/bluesky-social/atproto/pull/3429) [`e6e6aea38`](https://github.com/bluesky-social/atproto/commit/e6e6aea3814e3d0bb42a537f80d77947e85fa73f) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - add feedViewPost.threadContext defs - [#3390](https://github.com/bluesky-social/atproto/pull/3390) [`c0a75d310`](https://github.com/bluesky-social/atproto/commit/c0a75d310aa92c067799a97d1acc5bd0543114c5) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - posts_with_video filter in getAuthorFeed ## 0.13.29 ### Patch Changes - [#3416](https://github.com/bluesky-social/atproto/pull/3416) [`50603b4f2`](https://github.com/bluesky-social/atproto/commit/50603b4f2ef08bd618730107ec164a57f27dcca6) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Update `tools.ozone.moderation.queryStatuses` lexicon ## 0.13.28 ### Patch Changes - [#3389](https://github.com/bluesky-social/atproto/pull/3389) [`cbf17066f`](https://github.com/bluesky-social/atproto/commit/cbf17066f314fbc7f2e943127ee4a9f589f8bec2) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - add feedgen content mode lexicon spec ## 0.13.27 ### Patch Changes - [#3364](https://github.com/bluesky-social/atproto/pull/3364) [`e277158f7`](https://github.com/bluesky-social/atproto/commit/e277158f70a831b04fde3ec84b3c1eaa6ce82e9d) Thanks [@iwsmith](https://github.com/iwsmith)! - add recId to getSuggestions ## 0.13.26 ### Patch Changes - Updated dependencies [[`72eba67af`](https://github.com/bluesky-social/atproto/commit/72eba67af1af8320b5400bcb9319d5c3c8407d99), [`72eba67af`](https://github.com/bluesky-social/atproto/commit/72eba67af1af8320b5400bcb9319d5c3c8407d99)]: - @atproto/common-web@0.3.2 - @atproto/lexicon@0.4.5 - @atproto/xrpc@0.6.6 ## 0.13.25 ### Patch Changes - [#3271](https://github.com/bluesky-social/atproto/pull/3271) [`53621f8e1`](https://github.com/bluesky-social/atproto/commit/53621f8e100a3aa3c1caff10a08d3f4ea919875a) Thanks [@foysalit](https://github.com/foysalit)! - Allow setting policy names with takedown actions and when querying events ## 0.13.24 ### Patch Changes - [#3294](https://github.com/bluesky-social/atproto/pull/3294) [`d90d999de`](https://github.com/bluesky-social/atproto/commit/d90d999defda01a9b04dbce129e254990062c283) Thanks [@foysalit](https://github.com/foysalit)! - Limit tags filter to 25 max and remove 25 char limit for tag item ## 0.13.23 ### Patch Changes - [#3251](https://github.com/bluesky-social/atproto/pull/3251) [`6d308b857`](https://github.com/bluesky-social/atproto/commit/6d308b857ba2a514ee3c75ebdef7225e298ed7d7) Thanks [@foysalit](https://github.com/foysalit)! - Allow createSession to request takendown account scope - [#3280](https://github.com/bluesky-social/atproto/pull/3280) [`9ea2cce9a`](https://github.com/bluesky-social/atproto/commit/9ea2cce9a4c0a08994a8cb5abc81dc4bc2221d0c) Thanks [@foysalit](https://github.com/foysalit)! - Apply ozone queue splitting at the database query level ## 0.13.22 ### Patch Changes - [#3270](https://github.com/bluesky-social/atproto/pull/3270) [`f22383cee`](https://github.com/bluesky-social/atproto/commit/f22383cee8feb8b9f761c801ab6e07ad8dc019ed) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add support for label def aliases, deprecation notices. This provides support for the deprecated `gore` label until a full cleanup effort can be completed. ## 0.13.21 ### Patch Changes - [#3250](https://github.com/bluesky-social/atproto/pull/3250) [`dced566de`](https://github.com/bluesky-social/atproto/commit/dced566de5079ef4208801db476a7e7416f5e5aa) Thanks [@haileyok](https://github.com/haileyok)! - add trending topics ## 0.13.20 ### Patch Changes - [#3222](https://github.com/bluesky-social/atproto/pull/3222) [`207728d2b`](https://github.com/bluesky-social/atproto/commit/207728d2b3b819af297ecb90e6373eb7721cbe34) Thanks [@gaearon](https://github.com/gaearon)! - Add optional reasons param to listNotifications - Updated dependencies [[`9fd65ba0f`](https://github.com/bluesky-social/atproto/commit/9fd65ba0fa4caca59fd0e6156145e4c2618e3a95)]: - @atproto/lexicon@0.4.4 - @atproto/xrpc@0.6.5 ## 0.13.19 ### Patch Changes - [#3171](https://github.com/bluesky-social/atproto/pull/3171) [`ed2236220`](https://github.com/bluesky-social/atproto/commit/ed2236220900ab9a6132c525289cfdd959733a42) Thanks [@foysalit](https://github.com/foysalit)! - Allow moderators to optionally acknowledge all open subjects of an account when acknowledging account level reports ## 0.13.18 ### Patch Changes - [#3082](https://github.com/bluesky-social/atproto/pull/3082) [`a3ce23c4c`](https://github.com/bluesky-social/atproto/commit/a3ce23c4ccf4f40998b9d1f5731e5c905390aedc) Thanks [@gaearon](https://github.com/gaearon)! - Add hotness as a thread sorting option ## 0.13.17 ### Patch Changes - [#2978](https://github.com/bluesky-social/atproto/pull/2978) [`a4b528e5f`](https://github.com/bluesky-social/atproto/commit/a4b528e5f51c8bfca56b293b0059b88d138ec421) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add searchStarterPacks and searchStarterPacksSkeleton - [#3056](https://github.com/bluesky-social/atproto/pull/3056) [`2e7aa211d`](https://github.com/bluesky-social/atproto/commit/2e7aa211d2cbc629899c7f87f1713b13b932750b) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add com.atproto.temp.addReservedHandle lexicon ## 0.13.16 ### Patch Changes - [#2988](https://github.com/bluesky-social/atproto/pull/2988) [`48d08a469`](https://github.com/bluesky-social/atproto/commit/48d08a469f75837e3b7e879d286d12780440b8b8) Thanks [@foysalit](https://github.com/foysalit)! - Make durationInHours optional for mute reporter event - [#2911](https://github.com/bluesky-social/atproto/pull/2911) [`bac9be2d3`](https://github.com/bluesky-social/atproto/commit/bac9be2d3ec904d1f984a871f43cf89aca17289d) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Export the generated lexicons `schemas` definitions - [#2953](https://github.com/bluesky-social/atproto/pull/2953) [`561431fe4`](https://github.com/bluesky-social/atproto/commit/561431fe4897e81767dc768e9a31020d09bf86ff) Thanks [@rafaelbsky](https://github.com/rafaelbsky)! - Add convoView.opened to lexicon definition - Updated dependencies [[`bac9be2d3`](https://github.com/bluesky-social/atproto/commit/bac9be2d3ec904d1f984a871f43cf89aca17289d), [`bac9be2d3`](https://github.com/bluesky-social/atproto/commit/bac9be2d3ec904d1f984a871f43cf89aca17289d)]: - @atproto/syntax@0.3.1 - @atproto/lexicon@0.4.3 - @atproto/xrpc@0.6.4 ## 0.13.15 ### Patch Changes - [#2661](https://github.com/bluesky-social/atproto/pull/2661) [`d6f33b474`](https://github.com/bluesky-social/atproto/commit/d6f33b4742e0b94722a993efc7d18833d9416bb6) Thanks [@foysalit](https://github.com/foysalit)! - Add mod events and status filter for account and record hosting status - [#2957](https://github.com/bluesky-social/atproto/pull/2957) [`b6eeb81c6`](https://github.com/bluesky-social/atproto/commit/b6eeb81c6d454b5ae91b05a21fc1820274c1b429) Thanks [@gaearon](https://github.com/gaearon)! - Detect facets in parallel - [#2917](https://github.com/bluesky-social/atproto/pull/2917) [`839202a3d`](https://github.com/bluesky-social/atproto/commit/839202a3d2b01de25de900cec7540019545798c6) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Allow instantiating an API Agent with a string or URL - [#2933](https://github.com/bluesky-social/atproto/pull/2933) [`e680d55ca`](https://github.com/bluesky-social/atproto/commit/e680d55ca2d7f6b213e2a8693eba6be39163ba41) Thanks [@mozzius](https://github.com/mozzius)! - Fix handling of invalid facets in RichText - [#2905](https://github.com/bluesky-social/atproto/pull/2905) [`c4b5e5395`](https://github.com/bluesky-social/atproto/commit/c4b5e53957463c37dd16fdd1b897d4ab02ab8e84) Thanks [@foysalit](https://github.com/foysalit)! - Add user specific and instance-wide settings api for ozone ## 0.13.14 ### Patch Changes - [#2918](https://github.com/bluesky-social/atproto/pull/2918) [`209238769`](https://github.com/bluesky-social/atproto/commit/209238769c0bf38bf04f7fa9621eeb176b5c0ed8) Thanks [@devinivy](https://github.com/devinivy)! - add app.bsky.unspecced.getConfig endpoint - [#2931](https://github.com/bluesky-social/atproto/pull/2931) [`73f40e63a`](https://github.com/bluesky-social/atproto/commit/73f40e63abe3283efc0a27eef781c00b497caad1) Thanks [@dholms](https://github.com/dholms)! - Add threatSignatures to ozone repo views ## 0.13.13 ### Patch Changes - [#2914](https://github.com/bluesky-social/atproto/pull/2914) [`19e36afb2`](https://github.com/bluesky-social/atproto/commit/19e36afb2c13dbc7b1033eb3cab5e7fc6f496fdc) Thanks [@foysalit](https://github.com/foysalit)! - Add collections and subjectType filters to ozone's queryEvents and queryStatuses endpoints ## 0.13.12 ### Patch Changes - [#2636](https://github.com/bluesky-social/atproto/pull/2636) [`22d039a22`](https://github.com/bluesky-social/atproto/commit/22d039a229e3ef08a793e1c98b473b1b8e18ac5e) Thanks [@foysalit](https://github.com/foysalit)! - Sets api to manage lists of strings on ozone, mostly aimed for automod configuration ## 0.13.11 ### Patch Changes - [#2857](https://github.com/bluesky-social/atproto/pull/2857) [`a0531ce42`](https://github.com/bluesky-social/atproto/commit/a0531ce429f5139cb0e2cc19aa9b338599947e44) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds support for muting words within link cards attached to `RecordWithMedia` embeds. ## 0.13.10 ### Patch Changes - [#2855](https://github.com/bluesky-social/atproto/pull/2855) [`df14df522`](https://github.com/bluesky-social/atproto/commit/df14df522bb7986e56ee1f6a0f5d862e1ea6f4d5) Thanks [@dholms](https://github.com/dholms)! - Add tools.ozone.signature lexicons ## 0.13.9 ### Patch Changes - [#2836](https://github.com/bluesky-social/atproto/pull/2836) [`a2bad977a`](https://github.com/bluesky-social/atproto/commit/a2bad977a8d941b4075ea3ffee3d6f7a0c0f467c) Thanks [@foysalit](https://github.com/foysalit)! - Add getRepos and getRecords endpoints for bulk fetching ## 0.13.8 ### Patch Changes - [#2771](https://github.com/bluesky-social/atproto/pull/2771) [`2676206e4`](https://github.com/bluesky-social/atproto/commit/2676206e422233fefbf2d9d182e8d462f0957c93) Thanks [@mozzius](https://github.com/mozzius)! - Add pinned posts to profile record and getAuthorFeed - Updated dependencies [[`a07b21151`](https://github.com/bluesky-social/atproto/commit/a07b21151f1850340c4b7797ebb11521b1a6cdf3), [`a07b21151`](https://github.com/bluesky-social/atproto/commit/a07b21151f1850340c4b7797ebb11521b1a6cdf3), [`a07b21151`](https://github.com/bluesky-social/atproto/commit/a07b21151f1850340c4b7797ebb11521b1a6cdf3), [`eb20ff64a`](https://github.com/bluesky-social/atproto/commit/eb20ff64a2d8e3061c652e1e247bf9b0fe3c41a6), [`87a1f2426`](https://github.com/bluesky-social/atproto/commit/87a1f24262e0e644b6cf31cc7a0446d9127ffa94)]: - @atproto/xrpc@0.6.3 - @atproto/common-web@0.3.1 - @atproto/lexicon@0.4.2 ## 0.13.7 ### Patch Changes - [#2807](https://github.com/bluesky-social/atproto/pull/2807) [`e6bd5aecc`](https://github.com/bluesky-social/atproto/commit/e6bd5aecce7954d60e5fb263297e697ab7aab98e) Thanks [@foysalit](https://github.com/foysalit)! - Introduce a acknowledgeAccountSubjects flag on takedown event to ack all subjects from the author that need review - [#2810](https://github.com/bluesky-social/atproto/pull/2810) [`33aa0c722`](https://github.com/bluesky-social/atproto/commit/33aa0c722226a18215af0ae1833c7c552fc7aaa7) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add NUX API - Updated dependencies [[`98711a147`](https://github.com/bluesky-social/atproto/commit/98711a147a8674337f605c6368f39fc10c2fae93)]: - @atproto/xrpc@0.6.2 ## 0.13.6 ### Patch Changes - [#2780](https://github.com/bluesky-social/atproto/pull/2780) [`e4d41d66f`](https://github.com/bluesky-social/atproto/commit/e4d41d66fa4757a696363f39903562458967b63d) Thanks [@foysalit](https://github.com/foysalit)! - Add language property to communication templates ## 0.13.5 ### Patch Changes - [#2751](https://github.com/bluesky-social/atproto/pull/2751) [`80ada8f47`](https://github.com/bluesky-social/atproto/commit/80ada8f47628f55f3074cd16a52857e98d117e14) Thanks [@devinivy](https://github.com/devinivy)! - Lexicons and support for video embeds within bsky posts. ## 0.13.4 ### Patch Changes - [#2714](https://github.com/bluesky-social/atproto/pull/2714) [`d9ffa3c46`](https://github.com/bluesky-social/atproto/commit/d9ffa3c460924010d7002b616cb7a0c66111cc6c) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Drop use of `AtpBaseClient` class - [#2714](https://github.com/bluesky-social/atproto/pull/2714) [`d9ffa3c46`](https://github.com/bluesky-social/atproto/commit/d9ffa3c460924010d7002b616cb7a0c66111cc6c) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Expose the `CredentialSession` class that can be used to instantiate both `Agent` and `XrpcClient`, while internally managing credential based (username/password) sessions. - [`bbca17bc5`](https://github.com/bluesky-social/atproto/commit/bbca17bc5388e0b2af26fb107347c8ab507ee42f) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Deprecate Agent.accountDid in favor of Agent.assertDid - [#2737](https://github.com/bluesky-social/atproto/pull/2737) [`a8e1f9000`](https://github.com/bluesky-social/atproto/commit/a8e1f9000d9617c4df9d9f0e74ae0e0b73fcfd66) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `threadgate: ThreadgateView` to response from `getPostThread` - [#2714](https://github.com/bluesky-social/atproto/pull/2714) [`d9ffa3c46`](https://github.com/bluesky-social/atproto/commit/d9ffa3c460924010d7002b616cb7a0c66111cc6c) Thanks [@matthieusieben](https://github.com/matthieusieben)! - `Agent` is no longer an abstract class. Instead it can be instantiated using object implementing a new `SessionManager` interface. If your project extends `Agent` and overrides the constructor or any method implementations, consider that you may want to call them from `super`. - Updated dependencies [[`d9ffa3c46`](https://github.com/bluesky-social/atproto/commit/d9ffa3c460924010d7002b616cb7a0c66111cc6c), [`d9ffa3c46`](https://github.com/bluesky-social/atproto/commit/d9ffa3c460924010d7002b616cb7a0c66111cc6c), [`d9ffa3c46`](https://github.com/bluesky-social/atproto/commit/d9ffa3c460924010d7002b616cb7a0c66111cc6c)]: - @atproto/xrpc@0.6.1 ## 0.13.3 ### Patch Changes - [#2735](https://github.com/bluesky-social/atproto/pull/2735) [`4ab248354`](https://github.com/bluesky-social/atproto/commit/4ab2483547d5dabfba88ed4419a4f374bbd7cae7) Thanks [@haileyok](https://github.com/haileyok)! - add `quoteCount` to embed view ## 0.13.2 ### Patch Changes - [#2658](https://github.com/bluesky-social/atproto/pull/2658) [`2a0c088cc`](https://github.com/bluesky-social/atproto/commit/2a0c088cc5d502ca70da9612a261186aa2f2e1fb) Thanks [@haileyok](https://github.com/haileyok)! - Adds `app.bsky.feed.getQuotes` lexicon and handlers - [#2675](https://github.com/bluesky-social/atproto/pull/2675) [`aba664fbd`](https://github.com/bluesky-social/atproto/commit/aba664fbdfbaddba321e96db2478e0bc8fc72d27) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds `postgate` records to power quote gating and detached quote posts, plus `hiddenReplies` to the `threadgate` record. ## 0.13.1 ### Patch Changes - [#2708](https://github.com/bluesky-social/atproto/pull/2708) [`22af354a5`](https://github.com/bluesky-social/atproto/commit/22af354a5db595d7cbc0e65f02601de3565337e1) Thanks [@devinivy](https://github.com/devinivy)! - Export AtpAgentOptions type to better support extending AtpAgent. ## 0.13.0 ### Minor Changes - [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! #### Motivation The motivation for these changes is the need to make the `@atproto/api` package compatible with OAuth session management. We don't have OAuth client support "launched" and documented quite yet, so you can keep using the current app password authentication system. When we do "launch" OAuth support and begin encouraging its usage in the near future (see the [OAuth Roadmap](https://github.com/bluesky-social/atproto/discussions/2656)), these changes will make it easier to migrate. In addition, the redesigned session management system fixes a bug that could cause the session data to become invalid when Agent clones are created (e.g. using `agent.withProxy()`). #### New Features We've restructured the `XrpcClient` HTTP fetch handler to be specified during the instantiation of the XRPC client, through the constructor, instead of using a default implementation (which was statically defined). With this refactor, the XRPC client is now more modular and reusable. Session management, retries, cryptographic signing, and other request-specific logic can be implemented in the fetch handler itself rather than by the calling code. A new abstract class named `Agent`, has been added to `@atproto/api`. This class will be the base class for all Bluesky agents classes in the `@atproto` ecosystem. It is meant to be extended by implementations that provide session management and fetch handling. As you adapt your code to these changes, make sure to use the `Agent` type wherever you expect to receive an agent, and use the `AtpAgent` type (class) only to instantiate your client. The reason for this is to be forward compatible with the OAuth agent implementation that will also extend `Agent`, and not `AtpAgent`. ```ts import { Agent, AtpAgent } from '@atproto/api' async function setupAgent( service: string, username: string, password: string, ): Promise { const agent = new AtpAgent({ service, persistSession: (evt, session) => { // handle session update }, }) await agent.login(username, password) return agent } ``` ```ts import { Agent } from '@atproto/api' async function doStuffWithAgent(agent: Agent, arg: string) { return agent.resolveHandle(arg) } ``` ```ts import { Agent, AtpAgent } from '@atproto/api' class MyClass { agent: Agent constructor() { this.agent = new AtpAgent() } } ``` #### Breaking changes Most of the changes introduced in this version are backward-compatible. However, there are a couple of breaking changes you should be aware of: - Customizing `fetch`: The ability to customize the `fetch: FetchHandler` property of `@atproto/xrpc`'s `Client` and `@atproto/api`'s `AtpAgent` classes has been removed. Previously, the `fetch` property could be set to a function that would be used as the fetch handler for that instance, and was initialized to a default fetch handler. That property is still accessible in a read-only fashion through the `fetchHandler` property and can only be set during the instance creation. Attempting to set/get the `fetch` property will now result in an error. - The `fetch()` method, as well as WhatWG compliant `Request` and `Headers` constructors, must be globally available in your environment. Use a polyfill if necessary. - The `AtpBaseClient` has been removed. The `AtpServiceClient` has been renamed `AtpBaseClient`. Any code using either of these classes will need to be updated. - Instead of _wrapping_ an `XrpcClient` in its `xrpc` property, the `AtpBaseClient` (formerly `AtpServiceClient`) class - created through `lex-cli` - now _extends_ the `XrpcClient` class. This means that a client instance now passes the `instanceof XrpcClient` check. The `xrpc` property now returns the instance itself and has been deprecated. - `setSessionPersistHandler` is no longer available on the `AtpAgent` or `BskyAgent` classes. The session handler can only be set though the `persistSession` options of the `AtpAgent` constructor. - The new class hierarchy is as follows: - `BskyAgent` extends `AtpAgent`: but add no functionality (hence its deprecation). - `AtpAgent` extends `Agent`: adds password based session management. - `Agent` extends `AtpBaseClient`: this abstract class that adds syntactic sugar methods `app.bsky` lexicons. It also adds abstract session management methods and adds atproto specific utilities (`labelers` & `proxy` headers, cloning capability) - `AtpBaseClient` extends `XrpcClient`: automatically code that adds fully typed lexicon defined namespaces (`instance.app.bsky.feed.getPosts()`) to the `XrpcClient`. - `XrpcClient` is the base class. #### Non-breaking changes - The `com.*` and `app.*` namespaces have been made directly available to every `Agent` instances. #### Deprecations - The default export of the `@atproto/xrpc` package has been deprecated. Use named exports instead. - The `Client` and `ServiceClient` classes are now deprecated. They are replaced by a single `XrpcClient` class. - The default export of the `@atproto/api` package has been deprecated. Use named exports instead. - The `BskyAgent` has been deprecated. Use the `AtpAgent` class instead. - The `xrpc` property of the `AtpClient` instances has been deprecated. The instance itself should be used as the XRPC client. - The `api` property of the `AtpAgent` and `BskyAgent` instances has been deprecated. Use the instance itself instead. #### Migration ##### The `@atproto/api` package If you were relying on the `AtpBaseClient` solely to perform validation, use this:
Before
After
```ts import { AtpBaseClient, ComAtprotoSyncSubscribeRepos } from '@atproto/api' const baseClient = new AtpBaseClient() baseClient.xrpc.lex.assertValidXrpcMessage('io.example.doStuff', { // ... }) ``` ```ts import { lexicons } from '@atproto/api' lexicons.assertValidXrpcMessage('io.example.doStuff', { // ... }) ```
If you are extending the `BskyAgent` to perform custom `session` manipulation, define your own `Agent` subclass instead:
Before
After
```ts import { BskyAgent } from '@atproto/api' class MyAgent extends BskyAgent { private accessToken?: string async createOrRefreshSession(identifier: string, password: string) { // custom logic here this.accessToken = 'my-access-jwt' } async doStuff() { return this.call('io.example.doStuff', { headers: { Authorization: this.accessToken && `Bearer ${this.accessToken}`, }, }) } } ``` ```ts import { Agent } from '@atproto/api' class MyAgent extends Agent { private accessToken?: string public did?: string constructor(private readonly service: string | URL) { super({ service, headers: { Authorization: () => this.accessToken ? `Bearer ${this.accessToken}` : null, }, }) } clone(): MyAgent { const agent = new MyAgent(this.service) agent.accessToken = this.accessToken agent.did = this.did return this.copyInto(agent) } async createOrRefreshSession(identifier: string, password: string) { // custom logic here this.did = 'did:example:123' this.accessToken = 'my-access-jwt' } } ```
If you are monkey patching the `xrpc` service client to perform client-side rate limiting, you can now do this in the `FetchHandler` function:
Before
After
```ts import { BskyAgent } from '@atproto/api' import { RateLimitThreshold } from 'rate-limit-threshold' const agent = new BskyAgent() const limiter = new RateLimitThreshold(3000, 300_000) const origCall = agent.api.xrpc.call agent.api.xrpc.call = async function (...args) { await limiter.wait() return origCall.call(this, ...args) } ``` ```ts import { AtpAgent } from '@atproto/api' import { RateLimitThreshold } from 'rate-limit-threshold' class LimitedAtpAgent extends AtpAgent { constructor(options: AtpAgentOptions) { const fetch: typeof globalThis.fetch = options.fetch ?? globalThis.fetch const limiter = new RateLimitThreshold(3000, 300_000) super({ ...options, fetch: async (...args) => { await limiter.wait() return fetch(...args) }, }) } } ```
If you configure a static `fetch` handler on the `BskyAgent` class - for example to modify the headers of every request - you can now do this by providing your own `fetch` function:
Before
After
```ts import { BskyAgent, defaultFetchHandler } from '@atproto/api' BskyAgent.configure({ fetch: async (httpUri, httpMethod, httpHeaders, httpReqBody) => { const ua = httpHeaders['User-Agent'] httpHeaders['User-Agent'] = ua ? `${ua} ${userAgent}` : userAgent return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody) }, }) ``` ```ts import { AtpAgent } from '@atproto/api' class MyAtpAgent extends AtpAgent { constructor(options: AtpAgentOptions) { const fetch = options.fetch ?? globalThis.fetch super({ ...options, fetch: async (url, init) => { const headers = new Headers(init.headers) const ua = headersList.get('User-Agent') headersList.set('User-Agent', ua ? `${ua} ${userAgent}` : userAgent) return fetch(url, { ...init, headers }) }, }) } } ```
##### The `@atproto/xrpc` package The `Client` and `ServiceClient` classes are now **deprecated**. If you need a lexicon based client, you should update the code to use the `XrpcClient` class instead. The deprecated `ServiceClient` class now extends the new `XrpcClient` class. Because of this, the `fetch` `FetchHandler` can no longer be configured on the `Client` instances (including the default export of the package). If you are not relying on the `fetch` `FetchHandler`, the new changes should have no impact on your code. Beware that the deprecated classes will eventually be removed in a future version. Since its use has completely changed, the `FetchHandler` type has also completely changed. The new `FetchHandler` type is now a function that receives a `url` pathname and a `RequestInit` object and returns a `Promise`. This function is responsible for making the actual request to the server. ```ts export type FetchHandler = ( this: void, /** * The URL (pathname + query parameters) to make the request to, without the * origin. The origin (protocol, hostname, and port) must be added by this * {@link FetchHandler}, typically based on authentication or other factors. */ url: string, init: RequestInit, ) => Promise ``` A noticeable change that has been introduced is that the `uri` field of the `ServiceClient` class has _not_ been ported to the new `XrpcClient` class. It is now the responsibility of the `FetchHandler` to determine the full URL to make the request to. The same goes for the `headers`, which should now be set through the `FetchHandler` function. If you _do_ rely on the legacy `Client.fetch` property to perform custom logic upon request, you will need to migrate your code to use the new `XrpcClient` class. The `XrpcClient` class has a similar API to the old `ServiceClient` class, but with a few differences: - The `Client` + `ServiceClient` duality was removed in favor of a single `XrpcClient` class. This means that: - There no longer exists a centralized lexicon registry. If you need a global lexicon registry, you can maintain one yourself using a `new Lexicons` (from `@atproto/lexicon`). - The `FetchHandler` is no longer a statically defined property of the `Client` class. Instead, it is passed as an argument to the `XrpcClient` constructor. - The `XrpcClient` constructor now requires a `FetchHandler` function as the first argument, and an optional `Lexicon` instance as the second argument. - The `setHeader` and `unsetHeader` methods were not ported to the new `XrpcClient` class. If you need to set or unset headers, you should do so in the `FetchHandler` function provided in the constructor arg.
Before
After
```ts import client, { defaultFetchHandler } from '@atproto/xrpc' client.fetch = function ( httpUri: string, httpMethod: string, httpHeaders: Headers, httpReqBody: unknown, ) { // Custom logic here return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody) } client.addLexicon({ lexicon: 1, id: 'io.example.doStuff', defs: {}, }) const instance = client.service('http://my-service.com') instance.setHeader('my-header', 'my-value') await instance.call('io.example.doStuff') ``` ```ts import { XrpcClient } from '@atproto/xrpc' const instance = new XrpcClient( async (url, init) => { const headers = new Headers(init.headers) headers.set('my-header', 'my-value') // Custom logic here const fullUrl = new URL(url, 'http://my-service.com') return fetch(fullUrl, { ...init, headers }) }, [ { lexicon: 1, id: 'io.example.doStuff', defs: {}, }, ], ) await instance.call('io.example.doStuff') ```
If your fetch handler does not require any "custom logic", and all you need is an `XrpcClient` that makes its HTTP requests towards a static service URL, the previous example can be simplified to: ```ts import { XrpcClient } from '@atproto/xrpc' const instance = new XrpcClient('http://my-service.com', [ { lexicon: 1, id: 'io.example.doStuff', defs: {}, }, ]) ``` If you need to add static headers to all requests, you can instead instantiate the `XrpcClient` as follows: ```ts import { XrpcClient } from '@atproto/xrpc' const instance = new XrpcClient( { service: 'http://my-service.com', headers: { 'my-header': 'my-value', }, }, [ { lexicon: 1, id: 'io.example.doStuff', defs: {}, }, ], ) ``` If you need the headers or service url to be dynamic, you can define them using functions: ```ts import { XrpcClient } from '@atproto/xrpc' const instance = new XrpcClient( { service: () => 'http://my-service.com', headers: { 'my-header': () => 'my-value', 'my-ignored-header': () => null, // ignored }, }, [ { lexicon: 1, id: 'io.example.doStuff', defs: {}, }, ], ) ``` - [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add the ability to use `fetch()` compatible `BodyInit` body when making XRPC calls. ### Patch Changes - Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]: - @atproto/lexicon@0.4.1 - @atproto/xrpc@0.6.0 ## 0.12.29 ### Patch Changes - [#2668](https://github.com/bluesky-social/atproto/pull/2668) [`dc471da26`](https://github.com/bluesky-social/atproto/commit/dc471da267955d0962a8affaf983df60d962d97c) Thanks [@dholms](https://github.com/dholms)! - Add lxm and exp parameters to com.atproto.server.getServiceAuth ## 0.12.28 ### Patch Changes - [#2676](https://github.com/bluesky-social/atproto/pull/2676) [`951a3df15`](https://github.com/bluesky-social/atproto/commit/951a3df15aa9c1f5b0a2b66cfb0e2eaf6198fe41) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Remove `app.bsky.feed.detach` record, to be replaced by `app.bsky.feed.postgate` record in a future release. ## 0.12.27 ### Patch Changes - [#2664](https://github.com/bluesky-social/atproto/pull/2664) [`ff803fd2b`](https://github.com/bluesky-social/atproto/commit/ff803fd2bfad92eec5f88ee9b347c174731ef4ec) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds `app.bsky.feed.detach` record lexicons. ## 0.12.26 ### Patch Changes - [#2276](https://github.com/bluesky-social/atproto/pull/2276) [`77c5306d2`](https://github.com/bluesky-social/atproto/commit/77c5306d2a40d7edd20def73163b8f93f3a30ee7) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Updates muted words lexicons to include new attributes `id`, `actorTarget`, and `expiresAt`. Adds and updates methods in API SDK for better management of muted words. ## 0.12.25 ### Patch Changes - [#2570](https://github.com/bluesky-social/atproto/pull/2570) [`12dcdb668`](https://github.com/bluesky-social/atproto/commit/12dcdb668c8ec0f8a89689c326ab3e9dbc6d2f3c) Thanks [@sugyan](https://github.com/sugyan)! - Fix `hasMutedWord` for facets with multiple features - [#2648](https://github.com/bluesky-social/atproto/pull/2648) [`76c91f832`](https://github.com/bluesky-social/atproto/commit/76c91f8325363c95e25349e8e236aa2f70e63d5b) Thanks [@dholms](https://github.com/dholms)! - Support for priority notifications ## 0.12.24 ### Patch Changes - [#2613](https://github.com/bluesky-social/atproto/pull/2613) [`ed5810179`](https://github.com/bluesky-social/atproto/commit/ed5810179006f254f2035fe1f0e3c4798080cfe0) Thanks [@haileyok](https://github.com/haileyok)! - Support for starter packs in record embed views. - [#2554](https://github.com/bluesky-social/atproto/pull/2554) [`0529bec99`](https://github.com/bluesky-social/atproto/commit/0529bec99183439829a3553f45ac7203763144c3) Thanks [@sugyan](https://github.com/sugyan)! - Add missing `getPreferences` union return types ## 0.12.23 ### Patch Changes - [#2492](https://github.com/bluesky-social/atproto/pull/2492) [`bc861a2c2`](https://github.com/bluesky-social/atproto/commit/bc861a2c25b4151fb7e070dc20d5e1e07da21863) Thanks [@pfrazee](https://github.com/pfrazee)! - Added bsky app state preference and improved protections against race conditions in preferences sdk ## 0.12.22 ### Patch Changes - [#2553](https://github.com/bluesky-social/atproto/pull/2553) [`af7d3912a`](https://github.com/bluesky-social/atproto/commit/af7d3912a3b304a752ed72947eaa8cf28b35ec02) Thanks [@devinivy](https://github.com/devinivy)! - Support for starter packs (app.bsky.graph.starterpack) ## 0.12.21 ### Patch Changes - [#2460](https://github.com/bluesky-social/atproto/pull/2460) [`3ad051996`](https://github.com/bluesky-social/atproto/commit/3ad0519961e2437aa4870bf1358e6c275dcdee24) Thanks [@foysalit](https://github.com/foysalit)! - Add DB backed team member management for ozone ## 0.12.20 ### Patch Changes - [#2582](https://github.com/bluesky-social/atproto/pull/2582) [`ea0f10b5d`](https://github.com/bluesky-social/atproto/commit/ea0f10b5d0d334eb587032c54d5ace9ea811cf26) Thanks [@pfrazee](https://github.com/pfrazee)! - Remove client-side enforcement of labeler limits ## 0.12.19 ### Patch Changes - [#2558](https://github.com/bluesky-social/atproto/pull/2558) [`7c1973841`](https://github.com/bluesky-social/atproto/commit/7c1973841dab416ae19435d37853aeea1f579d39) Thanks [@dholms](https://github.com/dholms)! - Add thread mute routes and viewer state ## 0.12.18 ### Patch Changes - [#2557](https://github.com/bluesky-social/atproto/pull/2557) [`58abcbd8b`](https://github.com/bluesky-social/atproto/commit/58abcbd8b6e42a1f66bda6acc3ee6a2c0894e546) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds "social proof": `knowFollowers` to `ViewerState` for `ProfileViewDetailed` views and `app.bsky.graph.getKnownFollowers` method for listing known followers of a given user. ## 0.12.17 ### Patch Changes - [#2426](https://github.com/bluesky-social/atproto/pull/2426) [`2b21b5be2`](https://github.com/bluesky-social/atproto/commit/2b21b5be293d32c5eb5ae971c39703bc7d2224fd) Thanks [@foysalit](https://github.com/foysalit)! - Add com.atproto.admin.searchAccounts lexicon to allow searching for accounts using email address ## 0.12.16 ### Patch Changes - [#2539](https://github.com/bluesky-social/atproto/pull/2539) [`9495af23b`](https://github.com/bluesky-social/atproto/commit/9495af23bdb328cfc71182ac80e6eb61863d7a46) Thanks [@dholms](https://github.com/dholms)! - Allow updating deactivation state through admin.updateSubjectStatus ## 0.12.15 ### Patch Changes - [#2531](https://github.com/bluesky-social/atproto/pull/2531) [`255d5ea1f`](https://github.com/bluesky-social/atproto/commit/255d5ea1f06726547cdbe59c83bd18f2d4746912) Thanks [@dholms](https://github.com/dholms)! - Account deactivation. Current hosting status returned on session routes. ## 0.12.14 ### Patch Changes - [#2533](https://github.com/bluesky-social/atproto/pull/2533) [`c4af6a409`](https://github.com/bluesky-social/atproto/commit/c4af6a409ea2171c3cf1d0e7c8ed496794a3f049) Thanks [@devinivy](https://github.com/devinivy)! - Support for post embeds in chat lexicons ## 0.12.13 ### Patch Changes - [#2517](https://github.com/bluesky-social/atproto/pull/2517) [`1d4ab5d04`](https://github.com/bluesky-social/atproto/commit/1d4ab5d046aac4539658ee6d7e61882c54d5beb9) Thanks [@dholms](https://github.com/dholms)! - Add privileged flag to app password routes ## 0.12.12 ### Patch Changes - [#2442](https://github.com/bluesky-social/atproto/pull/2442) [`1f560f021`](https://github.com/bluesky-social/atproto/commit/1f560f021c07eb9e8d76577e67fd2d7ac39cdee4) Thanks [@foysalit](https://github.com/foysalit)! - Add com.atproto.label.queryLabels endpoint on appview and allow viewing external labels through ozone ## 0.12.11 ### Patch Changes - [#2499](https://github.com/bluesky-social/atproto/pull/2499) [`06d2328ee`](https://github.com/bluesky-social/atproto/commit/06d2328eeb8d706018dbdf7cc7b9862dd65b96cb) Thanks [@devinivy](https://github.com/devinivy)! - Misc tweaks and fixes to chat lexicons ## 0.12.10 ### Patch Changes - [#2485](https://github.com/bluesky-social/atproto/pull/2485) [`d32f7215f`](https://github.com/bluesky-social/atproto/commit/d32f7215f69bc87f50890d9cfdb09840c2fbaa41) Thanks [@devinivy](https://github.com/devinivy)! - Add lexicons for chat.bsky namespace ## 0.12.9 ### Patch Changes - [#2467](https://github.com/bluesky-social/atproto/pull/2467) [`f83b4c8ca`](https://github.com/bluesky-social/atproto/commit/f83b4c8cad01cebc1b67caa6c7ebe45f07b2f318) Thanks [@haileyok](https://github.com/haileyok)! - Modify label-handling on user's own content to still apply blurring ## 0.12.8 ### Patch Changes - [`58f719cc1`](https://github.com/bluesky-social/atproto/commit/58f719cc1c8d0ebd5ad7cf11221372b671cd7857) Thanks [@devinivy](https://github.com/devinivy)! - Add grandparent author to feed item reply ref ## 0.12.7 ### Patch Changes - [#2390](https://github.com/bluesky-social/atproto/pull/2390) [`58551bbe0`](https://github.com/bluesky-social/atproto/commit/58551bbe0595462c44fc3b6ab5b83e520f141933) Thanks [@foysalit](https://github.com/foysalit)! - Allow muting reports from accounts via `#modEventMuteReporter` event ## 0.12.6 ### Patch Changes - [#2427](https://github.com/bluesky-social/atproto/pull/2427) [`b9b7c5821`](https://github.com/bluesky-social/atproto/commit/b9b7c582199d57d2fe0af8af5c8c411ed34f5b9d) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Introduces V2 of saved feeds preferences. V2 and v1 prefs are incompatible. v1 methods and preference objects are retained for backwards compatability, but are considered deprecated. Developers should immediately migrate to v2 interfaces. ## 0.12.5 ### Patch Changes - [#2419](https://github.com/bluesky-social/atproto/pull/2419) [`3424a1770`](https://github.com/bluesky-social/atproto/commit/3424a17703891f5678ec76ef97e696afb3288b22) Thanks [@pfrazee](https://github.com/pfrazee)! - Add authFactorToken to session objects ## 0.12.4 ### Patch Changes - [#2416](https://github.com/bluesky-social/atproto/pull/2416) [`93a4a4df9`](https://github.com/bluesky-social/atproto/commit/93a4a4df9ce38f89a5d05e300d247b85fb007e05) Thanks [@devinivy](https://github.com/devinivy)! - Support for email auth factor lexicons ## 0.12.3 ### Patch Changes - [#2383](https://github.com/bluesky-social/atproto/pull/2383) [`0edef0ec0`](https://github.com/bluesky-social/atproto/commit/0edef0ec01403fd6097a4d2875b68313f2f1261f) Thanks [@dholms](https://github.com/dholms)! - Added feed generator interaction lexicons - [#2409](https://github.com/bluesky-social/atproto/pull/2409) [`c6d758b8b`](https://github.com/bluesky-social/atproto/commit/c6d758b8b63f4ef50b2ab9afc62164e92a53e7f0) Thanks [@devinivy](https://github.com/devinivy)! - Support for upcoming post search params ## 0.12.2 ### Patch Changes - [#2344](https://github.com/bluesky-social/atproto/pull/2344) [`abc6f82da`](https://github.com/bluesky-social/atproto/commit/abc6f82da38abef2b1bbe8d9e41a0534a5418c9e) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Support muting words that contain apostrophes and other punctuation ## 0.12.1 ### Patch Changes - [#2342](https://github.com/bluesky-social/atproto/pull/2342) [`eb7668c07`](https://github.com/bluesky-social/atproto/commit/eb7668c07d44f4b42ea2cc28143c64f4ba3312f5) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds the `associated` property to `profile` and `profile-basic` views, bringing them in line with `profile-detailed` views. ## 0.12.0 ### Minor Changes - [#2169](https://github.com/bluesky-social/atproto/pull/2169) [`f689bd51a`](https://github.com/bluesky-social/atproto/commit/f689bd51a2f4e02d4eca40eb2568a1fcb95494e9) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Build system rework, stop bundling dependencies. ### Patch Changes - [#2338](https://github.com/bluesky-social/atproto/pull/2338) [`36f2e966c`](https://github.com/bluesky-social/atproto/commit/36f2e966cba6cc90ba4320520da5c7381cfb8086) Thanks [@pfrazee](https://github.com/pfrazee)! - Fix: correctly detected blocked quote-posts when moderating posts - Updated dependencies [[`f689bd51a`](https://github.com/bluesky-social/atproto/commit/f689bd51a2f4e02d4eca40eb2568a1fcb95494e9)]: - @atproto/common-web@0.3.0 - @atproto/lexicon@0.4.0 - @atproto/syntax@0.3.0 - @atproto/xrpc@0.5.0 ## 0.11.2 ### Patch Changes - [#2328](https://github.com/bluesky-social/atproto/pull/2328) [`7dd9941b7`](https://github.com/bluesky-social/atproto/commit/7dd9941b73dbbd82601740e021cc87d765af60ca) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Remove unecessary escapes from regex, which was causing a minification error when bundled in React Native. ## 0.11.1 ### Patch Changes - [#2312](https://github.com/bluesky-social/atproto/pull/2312) [`219480764`](https://github.com/bluesky-social/atproto/commit/2194807644cbdb0021e867437693300c1b0e55f5) Thanks [@pfrazee](https://github.com/pfrazee)! - Fixed an issue that would cause agent clones to drop the PDS URI config. ## 0.11.0 ### Minor Changes - [#2302](https://github.com/bluesky-social/atproto/pull/2302) [`4eaadc0ac`](https://github.com/bluesky-social/atproto/commit/4eaadc0acb6b73b9745dd7a2b929d02e58083ab0) Thanks [@dholms](https://github.com/dholms)! - - Breaking changes - Redesigned the `moderate*` APIs which now output a `ModerationUI` object. - `agent.getPreferences()` output object `BskyPreferences` has been modified. - Moved Ozone routes from `com.atproto.admin` to `tools.ozone` namespace. - Additions - Added support for labeler configuration in `Agent.configure()` and `agent.configureLabelerHeader()`. - Added `agent.addLabeler()` and `agent.removeLabeler()` preference methods. - Muted words and hidden posts are now handled in the `moderate*` APIs. - Added `agent.getLabelers()` and `agent.getLabelDefinitions()`. - Added `agent.configureProxyHeader()` and `withProxy()` methods to support remote service proxying behaviors. ### Patch Changes - Updated dependencies [[`4eaadc0ac`](https://github.com/bluesky-social/atproto/commit/4eaadc0acb6b73b9745dd7a2b929d02e58083ab0)]: - @atproto/common-web@0.2.4 - @atproto/lexicon@0.3.3 - @atproto/syntax@0.2.1 - @atproto/xrpc@0.4.3 ## 0.10.5 ### Patch Changes - [#2279](https://github.com/bluesky-social/atproto/pull/2279) [`192223f12`](https://github.com/bluesky-social/atproto/commit/192223f127c0b226287df1ecfcd953636db08655) Thanks [@gaearon](https://github.com/gaearon)! - Change Following feed prefs to only show replies from people you follow by default ## 0.10.4 ### Patch Changes - [#2260](https://github.com/bluesky-social/atproto/pull/2260) [`6ec885992`](https://github.com/bluesky-social/atproto/commit/6ec8859929a16f9725319cc398b716acf913b01f) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Export regex from rich text detection - [#2260](https://github.com/bluesky-social/atproto/pull/2260) [`6ec885992`](https://github.com/bluesky-social/atproto/commit/6ec8859929a16f9725319cc398b716acf913b01f) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Disallow rare unicode whitespace characters from tags - [#2260](https://github.com/bluesky-social/atproto/pull/2260) [`6ec885992`](https://github.com/bluesky-social/atproto/commit/6ec8859929a16f9725319cc398b716acf913b01f) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Allow tags to lead with numbers ## 0.10.3 ### Patch Changes - [#2247](https://github.com/bluesky-social/atproto/pull/2247) [`2a0ceb818`](https://github.com/bluesky-social/atproto/commit/2a0ceb8180faa17de8061d4fa6c361b57a2005ed) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Fix double sanitization bug when editing muted words. - [#2247](https://github.com/bluesky-social/atproto/pull/2247) [`2a0ceb818`](https://github.com/bluesky-social/atproto/commit/2a0ceb8180faa17de8061d4fa6c361b57a2005ed) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - More sanitization of muted words, including newlines and leading/trailing whitespace - [#2247](https://github.com/bluesky-social/atproto/pull/2247) [`2a0ceb818`](https://github.com/bluesky-social/atproto/commit/2a0ceb8180faa17de8061d4fa6c361b57a2005ed) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `sanitizeMutedWordValue` util - [#2247](https://github.com/bluesky-social/atproto/pull/2247) [`2a0ceb818`](https://github.com/bluesky-social/atproto/commit/2a0ceb8180faa17de8061d4fa6c361b57a2005ed) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Handle hash emoji in mute words ## 0.10.2 ### Patch Changes - [#2245](https://github.com/bluesky-social/atproto/pull/2245) [`61b3d2525`](https://github.com/bluesky-social/atproto/commit/61b3d25253353db2da1336004f94e7dc5adb0410) Thanks [@mary-ext](https://github.com/mary-ext)! - Prevent hashtag emoji from being parsed as a tag - [#2218](https://github.com/bluesky-social/atproto/pull/2218) [`43531905c`](https://github.com/bluesky-social/atproto/commit/43531905ce1aec6d36d9be5943782811ecca6e6d) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Fix mute word upsert logic by ensuring we're comparing sanitized word values - [#2245](https://github.com/bluesky-social/atproto/pull/2245) [`61b3d2525`](https://github.com/bluesky-social/atproto/commit/61b3d25253353db2da1336004f94e7dc5adb0410) Thanks [@mary-ext](https://github.com/mary-ext)! - Properly calculate length of tag - Updated dependencies [[`0c815b964`](https://github.com/bluesky-social/atproto/commit/0c815b964c030aa0f277c40bf9786f130dc320f4)]: - @atproto/syntax@0.2.0 - @atproto/lexicon@0.3.2 - @atproto/xrpc@0.4.2 ## 0.10.1 ### Patch Changes - [#2215](https://github.com/bluesky-social/atproto/pull/2215) [`514aab92d`](https://github.com/bluesky-social/atproto/commit/514aab92d26acd43859285f46318e386846522b1) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add missing `getPreferences` union return types ## 0.10.0 ### Minor Changes - [#2170](https://github.com/bluesky-social/atproto/pull/2170) [`4c511b3d9`](https://github.com/bluesky-social/atproto/commit/4c511b3d9de41ffeae3fc11db941e7df04f4468a) Thanks [@dholms](https://github.com/dholms)! - Add lexicons and methods for account migration ### Patch Changes - [#2195](https://github.com/bluesky-social/atproto/pull/2195) [`b60719480`](https://github.com/bluesky-social/atproto/commit/b60719480f5f00bffd074a40e8ddc03aa93d137d) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add muted words/tags and hidden posts prefs and methods" ## 0.9.8 ### Patch Changes - [#2192](https://github.com/bluesky-social/atproto/pull/2192) [`f79cc6339`](https://github.com/bluesky-social/atproto/commit/f79cc63390ae9dbd47a4ff5d694eec25b78b788e) Thanks [@foysalit](https://github.com/foysalit)! - Tag event on moderation subjects and allow filtering events and subjects by tags ## 0.9.7 ### Patch Changes - [#2188](https://github.com/bluesky-social/atproto/pull/2188) [`8c94979f7`](https://github.com/bluesky-social/atproto/commit/8c94979f73fc5057449e24e66ef2e09b0e17e55b) Thanks [@dholms](https://github.com/dholms)! - Added timelineIndex to savedFeedsPref ## 0.9.6 ### Patch Changes - [#2124](https://github.com/bluesky-social/atproto/pull/2124) [`e4ec7af03`](https://github.com/bluesky-social/atproto/commit/e4ec7af03608949fc3b00a845f547a77599b5ad0) Thanks [@foysalit](https://github.com/foysalit)! - Allow filtering for comment, label, report type and date range on queryModerationEvents endpoint. ## 0.9.5 ### Patch Changes - [#2090](https://github.com/bluesky-social/atproto/pull/2090) [`8994d363`](https://github.com/bluesky-social/atproto/commit/8994d3633adad1c02569d6d44ae896e18195e8e2) Thanks [@dholms](https://github.com/dholms)! - add checkSignupQueue method and expose refreshSession on agent ## 0.9.4 ### Patch Changes - [#2086](https://github.com/bluesky-social/atproto/pull/2086) [`4171c04a`](https://github.com/bluesky-social/atproto/commit/4171c04ad81c5734a4558bc41fa1c4f3a1aba18c) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `setInterestsPref` method to BskyAgent, and `interests` prop to `getPreferences` response. ## 0.9.3 ### Patch Changes - [#2081](https://github.com/bluesky-social/atproto/pull/2081) [`5368245a`](https://github.com/bluesky-social/atproto/commit/5368245a6ef7095c86ad166fb04ff9bef27c3c3e) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add unspecced route for new onboarding `app.bsky.unspecced.getTaggedSuggestions` ## 0.9.2 ### Patch Changes - [#2045](https://github.com/bluesky-social/atproto/pull/2045) [`15f38560`](https://github.com/bluesky-social/atproto/commit/15f38560b9e2dc3af8cf860826e7477234fe6a2d) Thanks [@foysalit](https://github.com/foysalit)! - support new lexicons for admin communication templates ## 0.9.1 ### Patch Changes - [#2062](https://github.com/bluesky-social/atproto/pull/2062) [`c6fc73ae`](https://github.com/bluesky-social/atproto/commit/c6fc73aee6c245d12f876abd11889b8dbd0ce2ed) Thanks [@dholms](https://github.com/dholms)! - Directly pass create account params in api agent ## 0.9.0 ### Minor Changes - [#2039](https://github.com/bluesky-social/atproto/pull/2039) [`bf8d718c`](https://github.com/bluesky-social/atproto/commit/bf8d718cf918ac8d8a2cb1f57fde80535284642d) Thanks [@dholms](https://github.com/dholms)! - Namespace lexicon codegen ### Patch Changes - [#2056](https://github.com/bluesky-social/atproto/pull/2056) [`e43396af`](https://github.com/bluesky-social/atproto/commit/e43396af0973748dd2d034e88d35cf7ae8b4df2c) Thanks [@dholms](https://github.com/dholms)! - Added phone verification methods/schemas to agent. - [#1988](https://github.com/bluesky-social/atproto/pull/1988) [`51fcba7a`](https://github.com/bluesky-social/atproto/commit/51fcba7a7945c604fc50e9545850a12ef0ee6da6) Thanks [@bnewbold](https://github.com/bnewbold)! - remove deprecated app.bsky.unspecced.getPopular endpoint ## 0.8.0 ### Minor Changes - [#2010](https://github.com/bluesky-social/atproto/pull/2010) [`14067733`](https://github.com/bluesky-social/atproto/commit/140677335f76b99129c1f593d9e11d64624386c6) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Improve `resumeSession` event emission. It will no longer double emit when some requests fail, and the `create-failed` event has been replaced by `expired` where appropriate, and with a new event `network-error` where appropriate or an unknown error occurs. ## 0.7.4 ### Patch Changes - [#1966](https://github.com/bluesky-social/atproto/pull/1966) [`8f3f43cb`](https://github.com/bluesky-social/atproto/commit/8f3f43cb40f79ff7c52f81290daec55cfb000093) Thanks [@pfrazee](https://github.com/pfrazee)! - Fix to the application of the no-unauthenticated label ## 0.7.3 ### Patch Changes - [#1962](https://github.com/bluesky-social/atproto/pull/1962) [`7dec9df3`](https://github.com/bluesky-social/atproto/commit/7dec9df3b583ee8c06c0c6a7e32c259820dc84a5) Thanks [@pfrazee](https://github.com/pfrazee)! - Add seenAt time to listNotifications output ## 0.7.2 ### Patch Changes - [#1776](https://github.com/bluesky-social/atproto/pull/1776) [`ffe39aae`](https://github.com/bluesky-social/atproto/commit/ffe39aae8394394f73bbfaa9047a8b5818aa053a) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add `posts_and_author_threads` filter to `getAuthorFeed` ## 0.7.1 ### Patch Changes - [#1944](https://github.com/bluesky-social/atproto/pull/1944) [`60deea17`](https://github.com/bluesky-social/atproto/commit/60deea17622f7c574c18432a55ced4e1cdc1b3a1) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Strip trailing colon from URLs in rich-text facet detection. ## 0.7.0 ### Minor Changes - [#1937](https://github.com/bluesky-social/atproto/pull/1937) [`45352f9b`](https://github.com/bluesky-social/atproto/commit/45352f9b6d02aa405be94e9102424d983912ca5d) Thanks [@pfrazee](https://github.com/pfrazee)! - Add the !no-unauthenticated label to the moderation SDK ## 0.6.24 ### Patch Changes - [#1912](https://github.com/bluesky-social/atproto/pull/1912) [`378fc613`](https://github.com/bluesky-social/atproto/commit/378fc6132f621ca517897c9467ed5bba134b3776) Thanks [@devinivy](https://github.com/devinivy)! - Contains breaking lexicon changes: removing legacy com.atproto admin endpoints, making uri field required on app.bsky list views. - Updated dependencies [[`3c0ef382`](https://github.com/bluesky-social/atproto/commit/3c0ef382c12a413cc971ae47ffb341236c545f60)]: - @atproto/syntax@0.1.5 - @atproto/lexicon@0.3.1 - @atproto/xrpc@0.4.1 ## 0.6.23 ### Patch Changes - [#1806](https://github.com/bluesky-social/atproto/pull/1806) [`772736a0`](https://github.com/bluesky-social/atproto/commit/772736a01081f39504e1b19a1b3687783bb78f07) Thanks [@devinivy](https://github.com/devinivy)! - respect pds endpoint during session resumption ## 0.6.22 ### Patch Changes - [#1788](https://github.com/bluesky-social/atproto/pull/1788) [`84e2d4d2`](https://github.com/bluesky-social/atproto/commit/84e2d4d2b6694f344d80c18672c78b650189d423) Thanks [@bnewbold](https://github.com/bnewbold)! - update license to "MIT or Apache2" - Updated dependencies [[`ce49743d`](https://github.com/bluesky-social/atproto/commit/ce49743d7f8800d33116b88001d7b512553c2c89), [`84e2d4d2`](https://github.com/bluesky-social/atproto/commit/84e2d4d2b6694f344d80c18672c78b650189d423)]: - @atproto/lexicon@0.3.0 - @atproto/xrpc@0.4.0 - @atproto/common-web@0.2.3 - @atproto/syntax@0.1.4 ## 0.6.21 ### Patch Changes - [#1779](https://github.com/bluesky-social/atproto/pull/1779) [`9c98a5ba`](https://github.com/bluesky-social/atproto/commit/9c98a5baaf503b02238a6afe4f6e2b79c5181693) Thanks [@pfrazee](https://github.com/pfrazee)! - modlist helpers added to bsky-agent, add blockingByList to viewer state lexicon - [`35d108ce`](https://github.com/bluesky-social/atproto/commit/35d108ce94866ce1b3d147cd0620a0ba1c4ebcd7) Thanks [@devinivy](https://github.com/devinivy)! - Allow pds to serve did doc with credentials, API client to respect PDS listed in the did doc. - Updated dependencies [[`35d108ce`](https://github.com/bluesky-social/atproto/commit/35d108ce94866ce1b3d147cd0620a0ba1c4ebcd7)]: - @atproto/common-web@0.2.2 - @atproto/lexicon@0.2.3 - @atproto/syntax@0.1.3 - @atproto/xrpc@0.3.3 ## 0.6.20 ### Patch Changes - [#1568](https://github.com/bluesky-social/atproto/pull/1568) [`41ee177f`](https://github.com/bluesky-social/atproto/commit/41ee177f5a440490280d17acd8a89bcddaffb23b) Thanks [@dholms](https://github.com/dholms)! - Added email verification and update flows - Updated dependencies [[`41ee177f`](https://github.com/bluesky-social/atproto/commit/41ee177f5a440490280d17acd8a89bcddaffb23b)]: - @atproto/common-web@0.2.1 - @atproto/lexicon@0.2.2 - @atproto/syntax@0.1.2 - @atproto/xrpc@0.3.2 ## 0.6.19 ### Patch Changes - [#1674](https://github.com/bluesky-social/atproto/pull/1674) [`35b616cd`](https://github.com/bluesky-social/atproto/commit/35b616cd82232879937afc88d3f77d20c6395276) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Strip leading `#` from from detected tag facets ## 0.6.18 ### Patch Changes - [#1651](https://github.com/bluesky-social/atproto/pull/1651) [`2ce8a11b`](https://github.com/bluesky-social/atproto/commit/2ce8a11b8daf5d39027488c5dde8c47b0eb937bf) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds support for hashtags in the `RichText.detectFacets` method. ## 0.6.17 ### Patch Changes - [#1637](https://github.com/bluesky-social/atproto/pull/1637) [`d96f7d9b`](https://github.com/bluesky-social/atproto/commit/d96f7d9b84c6fbab9711059c8584a77d892dcedd) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Introduce general support for tags on posts ## 0.6.16 ### Patch Changes - [#1653](https://github.com/bluesky-social/atproto/pull/1653) [`56e2cf89`](https://github.com/bluesky-social/atproto/commit/56e2cf8999f6d7522529a9be8652c47545f82242) Thanks [@pfrazee](https://github.com/pfrazee)! - Improve the types of the thread and feed preferences APIs ## 0.6.15 ### Patch Changes - [#1639](https://github.com/bluesky-social/atproto/pull/1639) [`2cc329f2`](https://github.com/bluesky-social/atproto/commit/2cc329f26547217dd94b6bb11ee590d707cbd14f) Thanks [@pfrazee](https://github.com/pfrazee)! - Added new preferences for feed and thread view behaviors. ## 0.6.14 ### Patch Changes - Updated dependencies [[`b1dc3555`](https://github.com/bluesky-social/atproto/commit/b1dc355504f9f2e047093dc56682b8034518cf80)]: - @atproto/syntax@0.1.1 - @atproto/lexicon@0.2.1 - @atproto/xrpc@0.3.1 ## 0.6.13 ### Patch Changes - [#1553](https://github.com/bluesky-social/atproto/pull/1553) [`3877210e`](https://github.com/bluesky-social/atproto/commit/3877210e7fb3c76dfb1a11eb9ba3f18426301d9f) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Adds a new method `app.bsky.graph.getSuggestedFollowsByActor`. This method returns suggested follows for a given actor based on their likes and follows. ================================================ FILE: packages/api/OAUTH.md ================================================ # OAuth Client Quickstart This document describes how to implement OAuth based authentication in a browser-based Single Page App (SPA), to communicate with [atproto](https://atproto.com) API services. ## Prerequisites - You need a web server - or at the very least a static file server - to host your SPA. > [!TIP] > > During development, you can use a local server to host your client metadata. > You will need to use a tunneling service like [ngrok](https://ngrok.com/) to > make your local server accessible from the internet. > [!TIP] > > You can use a service like [GitHub Pages](https://pages.github.com/) to host > your client metadata and SPA for free. - You must be able to build and deploy a SPA to your server. ## Step 1: Create your client metadata Based on your hosting server endpoint, you will first need to choose a `client_id`. That `client_id` will be used to identify your client to Authorization Servers. A `client_id` must be a URL pointing to a JSON file which contains your client metadata. The client metadata **must** contain a `client_id` that is the URL used to access the metadata. Here is an example client metadata. ```json { "client_id": "https://example.com/client-metadata.json", "client_name": "Example atproto Browser App", "client_uri": "https://example.com", "logo_uri": "https://example.com/logo.png", "tos_uri": "https://example.com/tos", "policy_uri": "https://example.com/policy", "redirect_uris": ["https://example.com/callback"], "scope": "atproto", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "none", "application_type": "web", "dpop_bound_access_tokens": true } ``` - `redirect_uris`: An array of URLs that will be used as the redirect URIs for the OAuth flow. This should typically contain a single URL that points to a page on your SPA that will handle the OAuth response. This URL must be HTTPS. - `client_id`: The URL where the client metadata is hosted. This field must be the exact same as the URL used to access the metadata. - `client_name`: The name of your client. Will be displayed to the user during the authentication process. - `client_uri`: The URL of your client. Whether or not this value is actually displayed / used is up to the Authorization Server. - `logo_uri`: The URL of your client's logo. Should be displayed to the user during the authentication process. Whether your logo is actually displayed during the authentication process or not is up to the Authorization Server. - `tos_uri`: The URL of your client's terms of service. Will be displayed to the user during the authentication process. - `policy_uri`: The URL of your client's privacy policy. Will be displayed to the user during the authentication process. - If you don't want or need the user to stay authenticated for long periods (better for security), you can remove `refresh_token` from the `grant_types`. > [!NOTE] > > To mitigate phishing attacks, the Authentication Server will typically _not_ > display the `client_uri` or `logo_uri` to the user. If you don't see your logo > or client name during the authentication process, don't worry. This is normal. > The `client_name` _is_ generally displayed for all clients. Upload this JSON file so that it is accessible at the URL you chose for your `client_id`. ## Step 2: Setup your SPA Start by setting up your SPA. You can use any framework you like, or none at all. In this example, we will use TypeScript and Parcel, with plain JavaScript. ```bash npm init -y npm install --save-dev @atproto/oauth-client-browser npm install --save-dev @atproto/api npm install --save-dev parcel npm install --save-dev parcel-reporter-static-files-copy mkdir -p src mkdir -p static ``` Create a `.parcelrc` file with the following (exact) content: ```json { "extends": ["@parcel/config-default"], "reporters": ["...", "parcel-reporter-static-files-copy"] } ``` Create an `src/index.html` file with the following content: ```html My First OAuth App Loading... ``` And an `src/app.ts` file, with the following content: ```typescript console.log('Hello from atproto OAuth example app!') ``` Start the app in development mode: ```bash npx parcel src/index.html ``` In another terminal, open a tunnel to your local server: ```bash ngrok http 1234 ``` Create a `static/client-metadata.json` file with the client metadata you created in [Step 1](#step-1-create-your-client-metadata). Use the hostname provided by ngrok as the `client_id`: ```json { "client_id": "https://.ngrok.app/client-metadata.json", "client_name": "My First atproto OAuth App", "client_uri": "https://.ngrok.app", "redirect_uris": ["https://.ngrok.app/"], "grant_types": ["authorization_code"], "response_types": ["code"], "token_endpoint_auth_method": "none", "application_type": "web", "dpop_bound_access_tokens": true } ``` ## Step 3: Implement the OAuth flow Replace the content of the `src/app.ts` file, with the following content: ```typescript import { Agent } from '@atproto/api' import { BrowserOAuthClient } from '@atproto/oauth-client-browser' async function main() { const oauthClient = await BrowserOAuthClient.load({ clientId: '', handleResolver: 'https://bsky.social/', }) // TO BE CONTINUED } document.addEventListener('DOMContentLoaded', main) ``` > [!CAUTION] > > Using Bluesky-hosted services for handle resolution (eg, the `bsky.social` > endpoint) will leak both user IP addresses and handle identifier to Bluesky, > a third party. While Bluesky has a declared privacy policy, both developers > and users of applications need to be informed of and aware of the privacy > implications of this arrangement. Application developers are encouraged to > improve user privacy by operating their own handle resolution service when > possible. If you are a PDS self-hoster, you can use your PDS's URL for > `handleResolver`. The `oauthClient` is now configured to communicate with the user's Authorization Service. You can now initialize it in order to detect if the user is already authenticated. Replace the `// TO BE CONTINUED` comment with the following code: ```typescript const result = await oauthClient.init() if (result) { if ('state' in result) { console.log('The user was just redirected back from the authorization page') } console.log(`The user is currently signed in as ${result.session.did}`) } const session = result?.session // TO BE CONTINUED ``` At this point you can detect if the user is already authenticated or not (by checking if `session` is `undefined`). Let's initiate an authentication flow if the user is not authenticated. Replace the `// TO BE CONTINUED` comment with the following code: ```typescript if (!session) { const handle = prompt('Enter your atproto handle to authenticate') if (!handle) throw new Error('Authentication process canceled by the user') const url = await oauthClient.authorize(handle) // Redirect the user to the authorization page window.open(url, '_self', 'noopener') // Protect against browser's back-forward cache await new Promise((resolve, reject) => { setTimeout( reject, 10_000, new Error('User navigated back from the authorization page'), ) }) } // TO BE CONTINUED ``` At this point in the script, the user **will** be authenticated. Authenticated API calls can be made using the `session`. The `session` can be used to instantiate the `Agent` class from `@atproto/api`. Let's make a simple call to the API to retrieve the user's profile. Replace the `// TO BE CONTINUED` comment with the following code: ```typescript if (session) { const agent = new Agent(session) const fetchProfile = async () => { const profile = await agent.getProfile({ actor: agent.did }) return profile.data } // Update the user interface document.body.textContent = `Authenticated as ${agent.did}` const profileBtn = document.createElement('button') document.body.appendChild(profileBtn) profileBtn.textContent = 'Fetch Profile' profileBtn.onclick = async () => { const profile = await fetchProfile() outputPre.textContent = JSON.stringify(profile, null, 2) } const logoutBtn = document.createElement('button') document.body.appendChild(logoutBtn) logoutBtn.textContent = 'Logout' logoutBtn.onclick = async () => { await session.signOut() window.location.reload() } const outputPre = document.createElement('pre') document.body.appendChild(outputPre) } ``` [API]: ./README.md ================================================ FILE: packages/api/README.md ================================================ # ATP API This API is a client for ATProtocol servers. It communicates using HTTP. It includes: - ✔️ APIs for ATProto and Bluesky. - ✔️ Validation and complete typescript types. - ✔️ Session management. - ✔️ A RichText library. ## Getting started First install the package: ```sh yarn add @atproto/api ``` Then in your application: ```typescript import { Agent, CredentialSession } from '@atproto/api' const session = new CredentialSession(new URL('https://bsky.social')) await session.login(account) const agent = new Agent(session) ``` ## Usage ### Session management You'll need an authenticated session for most API calls. There are two ways to manage sessions: 1. [App password based session management](#app-password-based-session-management) 2. [OAuth based session management](#oauth-based-session-management) #### App password based session management Username / password based authentication can be performed using the `Agent` class. > [!CAUTION] > > This method is deprecated in favor of OAuth based session management. It is > recommended to use OAuth based session management (through the > `@atproto/oauth-client-*` packages). ```typescript import { Agent, CredentialSession, type AtpAgentLoginOpts } from '@atproto/api' // Configure connection to the server with authentification const account: AtpAgentLoginOpts = { identifier: 'your.bsky.social', password: 'xxxx-xxxx-xxxx-xxxx', } async function authenticate(account: AtpAgentLoginOpts): Promise { const session = new CredentialSession(new URL('https://example.com')) await session.login(account) const agent = new Agent(session) return agent } ;(async () => { console.log('Authenticating...') const agent = await authenticate(account) console.log(`Authenticated as from: ${agent.sessionManager.did}`) })() ``` #### OAuth based session management Depending on the environment used by your application, different OAuth clients are available: - [@atproto/oauth-client-browser](https://www.npmjs.com/package/@atproto/oauth-client-browser): for the browser. - [@atproto/oauth-client-node](https://www.npmjs.com/package/@atproto/oauth-client-node): for Node.js. - [@atproto/oauth-client](https://www.npmjs.com/package/@atproto/oauth-client): Lower level; compatible with most JS engines. Every `@atproto/oauth-client-*` implementation has a different way to obtain an `OAuthSession` instance that can be used to instantiate an `Agent` (from `@atproto/api`). Here is an example restoring a previously saved session: ```typescript import { Agent } from '@atproto/api' import { OAuthClient } from '@atproto/oauth-client' const oauthClient = new OAuthClient({ // ... }) const oauthSession = await oauthClient.restore('did:plc:123') // Instantiate the api Agent using an OAuthSession const agent = new Agent(oauthSession) ``` ### API calls The agent includes methods for many common operations, including: ```typescript // The DID of the user currently authenticated (or undefined) agent.did agent.accountDid // Throws if the user is not authenticated // Feeds and content await agent.getTimeline(params, opts) await agent.getAuthorFeed(params, opts) await agent.getPostThread(params, opts) await agent.getPost(params) await agent.getPosts(params, opts) await agent.getLikes(params, opts) await agent.getRepostedBy(params, opts) await agent.post(record) await agent.deletePost(postUri) await agent.like(uri, cid) await agent.deleteLike(likeUri) await agent.repost(uri, cid) await agent.deleteRepost(repostUri) await agent.uploadBlob(data, opts) // Social graph await agent.getFollows(params, opts) await agent.getFollowers(params, opts) await agent.follow(did) await agent.deleteFollow(followUri) // Actors await agent.getProfile(params, opts) await agent.upsertProfile(updateFn) await agent.getProfiles(params, opts) await agent.getSuggestions(params, opts) await agent.searchActors(params, opts) await agent.searchActorsTypeahead(params, opts) await agent.mute(did) await agent.unmute(did) await agent.muteModList(listUri) await agent.unmuteModList(listUri) await agent.blockModList(listUri) await agent.unblockModList(listUri) // Notifications await agent.listNotifications(params, opts) await agent.countUnreadNotifications(params, opts) await agent.updateSeenNotifications() // Identity await agent.resolveHandle(params, opts) await agent.updateHandle(params, opts) // Legacy: Session management should be performed through the SessionManager // rather than the Agent instance. if (agent instanceof AtpAgent) { // AtpAgent instances support using different sessions during their lifetime await agent.createAccount({ ... }) // session a await agent.login({ ... }) // session b await agent.resumeSession(savedSession) // session c } ``` ### Validation and types The package includes a complete types system which includes validation and type-guards. For example, to validate a post record: ```typescript import { AppBskyFeedPost } from '@atproto/api' const post = {...} if (AppBskyFeedPost.isRecord(post)) { // typescript now recognizes `post` as a AppBskyFeedPost.Record // however -- we still need to validate it const res = AppBskyFeedPost.validateRecord(post) if (res.success) { // a valid record } else { // something is wrong console.log(res.error) } } ``` ### Rich text Some 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. ℹ️ 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. ```typescript import { RichText } from '@atproto/api' // creating richtext const rt = new RichText({ text: 'Hello @alice.com, check out this link: https://example.com', }) await rt.detectFacets(agent) // automatically detects mentions and links const postRecord = { $type: 'app.bsky.feed.post', text: rt.text, facets: rt.facets, createdAt: new Date().toISOString(), } // rendering as markdown let markdown = '' for (const segment of rt.segments()) { if (segment.isLink()) { markdown += `[${segment.text}](${segment.link?.uri})` } else if (segment.isMention()) { markdown += `[${segment.text}](https://my-bsky-app.com/user/${segment.mention?.did})` } else { markdown += segment.text } } // calculating string lengths const rt2 = new RichText({ text: 'Hello' }) console.log(rt2.length) // => 5 console.log(rt2.graphemeLength) // => 5 const rt3 = new RichText({ text: '👨‍👩‍👧‍👧' }) console.log(rt3.length) // => 25 console.log(rt3.graphemeLength) // => 1 ``` ### Moderation Applying 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: - Moderator labeling - User muting (including mutelists) - User blocking - Mutewords - Hidden posts For more information, see the [Moderation Documentation](./docs/moderation.md). ```typescript import { moderatePost } from '@atproto/api' // First get the user's moderation prefs and their label definitions // = const prefs = await agent.getPreferences() const labelDefs = await agent.getLabelDefinitions(prefs) // We call the appropriate moderation function for the content // = const postMod = moderatePost(postView, { userDid: agent.session.did, moderationPrefs: prefs.moderationPrefs, labelDefs, }) // We then use the output to decide how to affect rendering // = // in feeds if (postMod.ui('contentList').filter) { // don't include in feeds } if (postMod.ui('contentList').blur) { // render the whole object behind a cover (use postMod.ui('contentList').blurs to explain) if (postMod.ui('contentList').noOverride) { // do not allow the cover the be removed } } if (postMod.ui('contentList').alert || postMod.ui('contentList').inform) { // render warnings on the post // find the warnings in postMod.ui('contentList').alerts and postMod.ui('contentList').informs } // viewed directly if (postMod.ui('contentView').filter) { // don't include in feeds } if (postMod.ui('contentView').blur) { // render the whole object behind a cover (use postMod.ui('contentView').blurs to explain) if (postMod.ui('contentView').noOverride) { // do not allow the cover the be removed } } if (postMod.ui('contentView').alert || postMod.ui('contentView').inform) { // render warnings on the post // find the warnings in postMod.ui('contentView').alerts and postMod.ui('contentView').informs } // post embeds in all contexts if (postMod.ui('contentMedia').blur) { // render the whole object behind a cover (use postMod.ui('contentMedia').blurs to explain) if (postMod.ui('contentMedia').noOverride) { // do not allow the cover the be removed } } ``` ## Advanced ### Advanced API calls The methods above are convenience wrappers. It covers most but not all available methods. The AT Protocol identifies methods and records with reverse-DNS names. You can use them on the agent as well: ```typescript const res1 = await agent.com.atproto.repo.createRecord({ did: alice.did, collection: 'app.bsky.feed.post', record: { $type: 'app.bsky.feed.post', text: 'Hello, world!', createdAt: new Date().toISOString(), }, }) const res2 = await agent.com.atproto.repo.listRecords({ repo: alice.did, collection: 'app.bsky.feed.post', }) const res3 = await agent.app.bsky.feed.post.create( { repo: alice.did }, { text: 'Hello, world!', createdAt: new Date().toISOString(), }, ) const res4 = await agent.app.bsky.feed.post.list({ repo: alice.did }) ``` ### Non-browser configuration If your environment doesn't have a built-in `fetch` implementation, you'll need to provide one. This will typically be done through a polyfill. ### Bring your own fetch If you want to provide your own `fetch` implementation, you can do so by instantiating the sessionManager with a custom fetch implementation: ```typescript import { AtpAgent } from '@atproto/api' const myFetch = (input: RequestInfo | URL, init?: RequestInit) => { console.log('requesting', input) const response = await globalThis.fetch(input, init) console.log('got response', response) return response } const agent = new AtpAgent({ service: 'https://example.com', fetch: myFetch, }) ``` ## License This project is dual-licensed under MIT and Apache 2.0 terms: - MIT license ([LICENSE-MIT.txt](https://github.com/bluesky-social/atproto/blob/main/LICENSE-MIT.txt) or http://opensource.org/licenses/MIT) - 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) Downstream 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. ================================================ FILE: packages/api/definitions/labels.json ================================================ [ { "identifier": "!hide", "configurable": false, "defaultSetting": "hide", "flags": ["no-override", "no-self"], "severity": "alert", "blurs": "content", "behaviors": { "account": { "profileList": "blur", "profileView": "blur", "avatar": "blur", "banner": "blur", "displayName": "blur", "contentList": "blur", "contentView": "blur" }, "profile": { "avatar": "blur", "banner": "blur", "displayName": "blur" }, "content": { "contentList": "blur", "contentView": "blur" } } }, { "identifier": "!warn", "configurable": false, "defaultSetting": "warn", "flags": ["no-self"], "severity": "none", "blurs": "content", "behaviors": { "account": { "profileList": "blur", "profileView": "blur", "avatar": "blur", "banner": "blur", "contentList": "blur", "contentView": "blur" }, "profile": { "avatar": "blur", "banner": "blur", "displayName": "blur" }, "content": { "contentList": "blur", "contentView": "blur" } } }, { "identifier": "!no-unauthenticated", "configurable": false, "defaultSetting": "hide", "flags": ["no-override", "unauthed"], "severity": "none", "blurs": "content", "behaviors": { "account": { "profileList": "blur", "profileView": "blur", "avatar": "blur", "banner": "blur", "displayName": "blur", "contentList": "blur", "contentView": "blur" }, "profile": { "avatar": "blur", "banner": "blur", "displayName": "blur" }, "content": { "contentList": "blur", "contentView": "blur" } } }, { "identifier": "porn", "configurable": true, "defaultSetting": "hide", "flags": ["adult"], "severity": "none", "blurs": "media", "behaviors": { "account": { "avatar": "blur", "banner": "blur" }, "profile": { "avatar": "blur", "banner": "blur" }, "content": { "contentMedia": "blur" } } }, { "identifier": "sexual", "configurable": true, "defaultSetting": "warn", "flags": ["adult"], "severity": "none", "blurs": "media", "behaviors": { "account": { "avatar": "blur", "banner": "blur" }, "profile": { "avatar": "blur", "banner": "blur" }, "content": { "contentMedia": "blur" } } }, { "identifier": "nudity", "configurable": true, "defaultSetting": "ignore", "flags": [], "severity": "none", "blurs": "media", "behaviors": { "account": { "avatar": "blur", "banner": "blur" }, "profile": { "avatar": "blur", "banner": "blur" }, "content": { "contentMedia": "blur" } } }, { "identifier": "graphic-media", "alias": ["gore"], "flags": ["adult"], "configurable": true, "defaultSetting": "warn", "severity": "none", "blurs": "media", "behaviors": { "account": { "avatar": "blur", "banner": "blur" }, "profile": { "avatar": "blur", "banner": "blur" }, "content": { "contentMedia": "blur" } } } ] ================================================ FILE: packages/api/docs/moderation.md ================================================ # Moderation API Applying 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: - Moderator labeling - User muting (including mutelists) - User blocking - Mutewords - Hidden posts ## Configuration Every moderation function takes a set of options which look like this: ```typescript { // the logged-in user's DID userDid: 'did:plc:1234...', moderationPrefs: { // is adult content allowed? adultContentEnabled: true, // the global label settings (used on self-labels) labels: { porn: 'hide', sexual: 'warn', nudity: 'ignore', // ... }, // the subscribed labelers and their label settings labelers: [ { did: 'did:plc:1234...', labels: { porn: 'hide', sexual: 'warn', nudity: 'ignore', // ... } } ], mutedWords: [/* ... */], hiddenPosts: [/* ... */] }, // custom label definitions labelDefs: { // labelerDid => defs[] 'did:plc:1234...': [ /* ... */ ] } } ``` This should match the following interfaces: ```typescript export interface ModerationPrefsLabeler { did: string labels: Record } export interface ModerationPrefs { adultContentEnabled: boolean labels: Record labelers: ModerationPrefsLabeler[] mutedWords: AppBskyActorDefs.MutedWord[] hiddenPosts: string[] } export interface ModerationOpts { userDid: string | undefined prefs: ModerationPrefs /** * Map of labeler did -> custom definitions */ labelDefs?: Record } ``` You can quickly grab the `ModerationPrefs` using the `agent.getPreferences()` method: ```typescript const prefs = await agent.getPreferences() moderatePost(post, { userDid: /*...*/, prefs: prefs.moderationPrefs, labelDefs: /*...*/ }) ``` To gather the label definitions (`labelDefs`) see the _Labelers_ section below. ## Labelers Labelers are services that provide moderation labels. Your application will typically have 1+ top-level labelers set with the ability to do "takedowns" on content. This is controlled via this static function, though the default is to use Bluesky's moderation: ```typescript BskyAgent.configure({ appLabelers: ['did:web:my-labeler.com'], }) ``` Users may also add their own labelers. The active labelers are controlled via an HTTP header which is automatically set by the agent when `getPreferences` is called, or when the labeler preferences are changed. Labelers publish a `app.bsky.labeler.service` record that looks like this: ```js { $type: 'app.bsky.labeler.service', policies: { // the list of label values the labeler will publish labelValues: [ 'rude', ], // any custom definitions the labeler will be using labelValueDefinitions: [ { identifier: 'rude', blurs: 'content', severity: 'alert', defaultSetting: 'warn', adultOnly: false, locales: [ { lang: 'en', name: 'Rude', description: 'Not keeping things civil.', }, ], }, ], }, createdAt: '2024-03-12T17:17:17.215Z' } ``` The label value definition are custom labels which only apply to that labeler. Your client needs to sync those definitions in order to correctly interpret them. To do that, call `app.bsky.labeler.getService()` (or the `getServices` batch variant) periodically to fetch their definitions. We recommend caching the response (at time our writing the official client uses a TTL of 6 hours). Here is how to do this: ```typescript import { AtpAgent } from '@atproto/api' const agent = new AtpAgent({ service: 'https://example.com' }) // assume `agent` is a signed in session const prefs = await agent.getPreferences() const labelDefs = await agent.getLabelDefinitions(prefs) moderatePost(post, { userDid: agent.session.did, prefs: prefs.moderationPrefs, labelDefs, }) ``` ## The `moderate*()` APIs The SDK exports methods to moderate the different kinds of content on the network. ```typescript import { moderateProfile, moderatePost, moderateNotification, moderateFeedGen, moderateUserList, moderateLabeler, } from '@atproto/api' ``` Each of these follows the same API signature: ```typescript const res = moderatePost(post, moderationOptions) ``` The response object provides an API for figuring out what your UI should do in different contexts. ```typescript res.ui(context) /* => ModerationUI { filter: boolean // should the content be removed from the interface? blur: boolean // should the content be put behind a cover? alert: boolean // should an alert be put on the content? (negative) inform: boolean // should an informational notice be put on the content? (neutral) noOverride: boolean // if blur=true, should the UI disable opening the cover? // the reasons for each of the flags: filters: ModerationCause[] blurs: ModerationCause[] alerts: ModerationCause[] informs: ModerationCause[] } */ ``` There are multiple UI contexts available: - `profileList` A profile being listed, eg in search or a follower list - `profileView` A profile being viewed directly - `avatar` The user's avatar in any context - `banner` The user's banner in any context - `displayName` The user's display name in any context - `contentList` Content being listed, eg posts in a feed, posts as replies, a user list list, a feed generator list, etc - `contentView` Content being viewed direct, eg an opened post, the user list page, the feedgen page, etc - `contentMedia ` Media inside the content, eg a picture embedded in a post Here's how a post in a feed would use these tools to make a decision: ```typescript const mod = moderatePost(post, moderationOptions) if (mod.ui('contentList').filter) { // dont show the post } if (mod.ui('contentList').blur) { // cover the post with the explanation from mod.ui('contentList').blurs[0] if (mod.ui('contentList').noOverride) { // dont allow the cover to be removed } } if (mod.ui('contentMedia').blur) { // cover the post's embedded images with the explanation from mod.ui('contentMedia').blurs[0] if (mod.ui('contentMedia').noOverride) { // dont allow the cover to be removed } } if (mod.ui('avatar').blur) { // cover the avatar with the explanation from mod.ui('avatar').blurs[0] if (mod.ui('avatar').noOverride) { // dont allow the cover to be removed } } for (const alert of mod.ui('contentList').alerts) { // render this alert } for (const inform of mod.ui('contentList').informs) { // render this inform } ``` ## Sending moderation reports Any Labeler is capable of receiving moderation reports. As a result, you need to specify which labeler should receive the report. You do this with the `Atproto-Proxy` header: ```typescript agent .withProxy('atproto_labeler', 'did:web:my-labeler.com') .createModerationReport({ reasonType: 'com.atproto.moderation.defs#reasonViolation', reason: 'They were being such a jerk to me!', subject: { did: 'did:web:bob.com' }, }) ``` ================================================ FILE: packages/api/jest.config.js ================================================ /** @type {import('jest').Config} */ module.exports = { displayName: 'API', transform: { '^.+\\.ts$': '@swc/jest' }, testTimeout: 60000, setupFiles: ['/../../jest.setup.ts'], setupFilesAfterEnv: ['/jest.setup.ts'], moduleNameMapper: { '^(\\.\\.?\\/.+)\\.js$': ['$1.ts', '$1.js'] }, } ================================================ FILE: packages/api/jest.d.ts ================================================ declare namespace jest { // eslint-disable-next-line interface Matchers { toBeModerationResult( expected: ModerationTestSuiteResultFlag[] | undefined, context?: string, stringifiedResult?: string, ignoreCause?: boolean, ): R } interface Expect { toBeModerationResult( expected: ModerationTestSuiteResultFlag[] | undefined, context?: string, stringifiedResult?: string, ignoreCause?: boolean, ): void } } ================================================ FILE: packages/api/jest.setup.ts ================================================ import { ModerationUI } from './src' import { ModerationTestSuiteResultFlag } from './tests/util/moderation-behavior' expect.extend({ toBeModerationResult( actual: ModerationUI, expected: ModerationTestSuiteResultFlag[] | undefined, context = '', stringifiedResult: string | undefined = undefined, _ignoreCause = false, ) { const fail = (msg: string) => ({ pass: false, message: () => `${msg}.${ stringifiedResult ? ` Full result: ${stringifiedResult}` : '' }`, }) // let cause = actual.causes?.type as string // if (actual.cause?.type === 'label') { // cause = `label:${actual.cause.labelDef.id}` // } else if (actual.cause?.type === 'muted') { // if (actual.cause.source.type === 'list') { // cause = 'muted-by-list' // } // } else if (actual.cause?.type === 'blocking') { // if (actual.cause.source.type === 'list') { // cause = 'blocking-by-list' // } // } if (!expected) { // if (!ignoreCause && actual.cause) { // return fail(`${context} expected to be a no-op, got ${cause}`) // } if (actual.inform) { return fail(`${context} expected to be a no-op, got inform=true`) } if (actual.alert) { return fail(`${context} expected to be a no-op, got alert=true`) } if (actual.blur) { return fail(`${context} expected to be a no-op, got blur=true`) } if (actual.filter) { return fail(`${context} expected to be a no-op, got filter=true`) } if (actual.noOverride) { return fail(`${context} expected to be a no-op, got noOverride=true`) } } else { // if (!ignoreCause && cause !== expected.cause) { // return fail(`${context} expected to be ${expected.cause}, got ${cause}`) // } const expectedInform = expected.includes('inform') if (!!actual.inform !== expectedInform) { return fail( `${context} expected to be inform=${expectedInform}, got ${ actual.inform || false }`, ) } const expectedAlert = expected.includes('alert') if (!!actual.alert !== expectedAlert) { return fail( `${context} expected to be alert=${expectedAlert}, got ${ actual.alert || false }`, ) } const expectedBlur = expected.includes('blur') if (!!actual.blur !== expectedBlur) { return fail( `${context} expected to be blur=${expectedBlur}, got ${ actual.blur || false }`, ) } const expectedFilter = expected.includes('filter') if (!!actual.filter !== expectedFilter) { return fail( `${context} expected to be filter=${expectedFilter}, got ${ actual.filter || false }`, ) } const expectedNoOverride = expected.includes('noOverride') if (!!actual.noOverride !== expectedNoOverride) { return fail( `${context} expected to be noOverride=${expectedNoOverride}, got ${ actual.noOverride || false }`, ) } } return { pass: true, message: () => '' } }, }) ================================================ FILE: packages/api/package.json ================================================ { "name": "@atproto/api", "version": "0.19.4", "license": "MIT", "description": "Client library for atproto and Bluesky", "keywords": [ "atproto", "bluesky", "api" ], "homepage": "https://atproto.com", "repository": { "type": "git", "url": "https://github.com/bluesky-social/atproto", "directory": "packages/api" }, "main": "dist/index.js", "types": "dist/index.d.ts", "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/*/* ../../lexicons/com/germnetwork/*", "build": "tsc --build tsconfig.build.json", "test": "jest" }, "dependencies": { "@atproto/common-web": "workspace:^", "@atproto/lexicon": "workspace:^", "@atproto/syntax": "workspace:^", "@atproto/xrpc": "workspace:^", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", "zod": "^3.23.8" }, "devDependencies": { "@atproto/lex-cli": "workspace:^", "@jest/globals": "^28.1.3", "jest": "^28.1.2", "prettier": "^3.2.5", "typescript": "^5.6.3" } } ================================================ FILE: packages/api/scripts/code/labels.mjs ================================================ import * as url from 'url' import { readFileSync, writeFileSync } from 'fs' import { join } from 'path' import * as prettier from 'prettier' const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) const labelsDef = JSON.parse( readFileSync( join(__dirname, '..', '..', 'definitions', 'labels.json'), 'utf8', ), ) writeFileSync( join(__dirname, '..', '..', 'src', 'moderation', 'const', 'labels.ts'), await gen(), 'utf8', ) async function gen() { const knownValues = new Set() const flattenedLabelDefs = [] for (const { alias: aliases, ...label } of labelsDef) { knownValues.add(label.identifier) flattenedLabelDefs.push([label.identifier, { ...label, locales: [] }]) if (aliases) { for (const alias of aliases) { knownValues.add(alias) flattenedLabelDefs.push([ alias, { ...label, identifier: alias, locales: [], comment: `@deprecated alias for \`${label.identifier}\``, }, ]) } } } let labelDefsStr = `{` for (const [key, { comment, ...value }] of flattenedLabelDefs) { const commentStr = comment ? `\n/** ${comment} */\n` : '' labelDefsStr += `${commentStr}'${key}': ${JSON.stringify(value, null, 2)},` } labelDefsStr += `}` return prettier.format( `/** this doc is generated by ./scripts/code/labels.mjs **/ import {InterpretedLabelValueDefinition, LabelPreference} from '../types' export type KnownLabelValue = ${Array.from(knownValues) .map((value) => `"${value}"`) .join(' | ')} export const DEFAULT_LABEL_SETTINGS: Record = ${JSON.stringify( Object.fromEntries( labelsDef .filter((label) => label.configurable) .map((label) => [label.identifier, label.defaultSetting]), ), )} export const LABELS: Record = ${labelDefsStr} `, { semi: false, parser: 'typescript', singleQuote: true }, ) } export {} ================================================ FILE: packages/api/scripts/generate-code.mjs ================================================ import './code/labels.mjs' export {} ================================================ FILE: packages/api/src/age-assurance.test.ts ================================================ import { describe, expect, it } from '@jest/globals' import { ageAssuranceRuleIDs, computeAgeAssuranceRegionAccess, getAgeAssuranceRegionConfig, } from './age-assurance' import { AppBskyAgeassuranceDefs } from './client' describe('age-assurance', () => { describe('getAgeAssuranceRegionConfig', () => { const config: AppBskyAgeassuranceDefs.Config = { regions: [ { countryCode: 'US', regionCode: 'CA', minAccessAge: 13, rules: [], }, { countryCode: 'US', minAccessAge: 13, rules: [], }, ], } it('should find region by country code only', () => { const result = getAgeAssuranceRegionConfig(config, { countryCode: 'US', }) expect(result).toEqual({ countryCode: 'US', minAccessAge: 13, rules: [], }) }) it('should find region by country code and region code', () => { const result = getAgeAssuranceRegionConfig(config, { countryCode: 'US', regionCode: 'CA', }) expect(result).toEqual({ countryCode: 'US', regionCode: 'CA', minAccessAge: 13, rules: [], }) }) it('should return undefined when no matching region found', () => { const result = getAgeAssuranceRegionConfig(config, { countryCode: 'GB', }) expect(result).toBeUndefined() }) }) describe('computeAgeAssuranceRegionAccess', () => { const region: AppBskyAgeassuranceDefs.ConfigRegion = { countryCode: 'US', minAccessAge: 13, rules: [ { $type: ageAssuranceRuleIDs.IfAccountNewerThan, date: '2025-12-10T00:00:00Z', access: 'none', }, { $type: ageAssuranceRuleIDs.IfAssuredOverAge, age: 18, access: 'full', }, { $type: ageAssuranceRuleIDs.IfAssuredOverAge, age: 16, access: 'safe', }, { $type: ageAssuranceRuleIDs.IfDeclaredOverAge, age: 16, access: 'safe', }, { $type: ageAssuranceRuleIDs.Default, access: 'none', }, ], } it('should apply default if no data provided', () => { const result = computeAgeAssuranceRegionAccess(region, {}) expect(result).toEqual({ access: 'none', reason: ageAssuranceRuleIDs.Default, }) }) describe('IfAccountNewerThan', () => { it('should block accounts created after threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { accountCreatedAt: new Date(2025, 11, 15).toISOString(), declaredAge: 18, }) expect(result).toEqual({ access: 'none', reason: ageAssuranceRuleIDs.IfAccountNewerThan, }) }) it('should allow accounts created before threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { accountCreatedAt: new Date(2025, 10, 1).toISOString(), declaredAge: 18, }) expect(result).toEqual({ access: 'safe', reason: ageAssuranceRuleIDs.IfDeclaredOverAge, }) }) it('should allow accounts created exactly at threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { accountCreatedAt: new Date(2025, 11, 1).toISOString(), declaredAge: 18, }) expect(result).toEqual({ access: 'safe', reason: ageAssuranceRuleIDs.IfDeclaredOverAge, }) }) it('should not apply rule when accountCreatedAt is not provided', () => { const result = computeAgeAssuranceRegionAccess(region, { declaredAge: 15, }) expect(result).toEqual({ access: 'none', reason: ageAssuranceRuleIDs.Default, }) }) it('should not apply rule when assuredAge is present', () => { const result = computeAgeAssuranceRegionAccess(region, { accountCreatedAt: new Date(2025, 11, 15).toISOString(), assuredAge: 20, }) expect(result).toEqual({ access: 'full', reason: ageAssuranceRuleIDs.IfAssuredOverAge, }) }) }) describe('IfDeclaredOverAge rule', () => { it('should allow users at or above age threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { declaredAge: 18, }) expect(result).toEqual({ access: 'safe', reason: ageAssuranceRuleIDs.IfDeclaredOverAge, }) }) it('should allow users above age threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { declaredAge: 25, }) expect(result).toEqual({ access: 'safe', reason: ageAssuranceRuleIDs.IfDeclaredOverAge, }) }) it('should not allow users below age threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { declaredAge: 17, }) expect(result).toEqual({ access: 'safe', reason: ageAssuranceRuleIDs.IfDeclaredOverAge, }) }) }) describe('IfAssuredOverAge rule', () => { it('should allow users at or above assured age threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { assuredAge: 18, }) expect(result).toEqual({ access: 'full', reason: ageAssuranceRuleIDs.IfAssuredOverAge, }) }) it('should not allow users below assured age threshold', () => { const result = computeAgeAssuranceRegionAccess(region, { assuredAge: 17, }) expect(result).toEqual({ access: 'safe', reason: ageAssuranceRuleIDs.IfAssuredOverAge, }) }) }) }) }) ================================================ FILE: packages/api/src/age-assurance.ts ================================================ import { AppBskyAgeassuranceDefs } from './client' import { ids } from './client/lexicons' export type AgeAssuranceRuleID = Exclude< | AppBskyAgeassuranceDefs.ConfigRegionRuleDefault['$type'] | AppBskyAgeassuranceDefs.ConfigRegionRuleIfDeclaredOverAge['$type'] | AppBskyAgeassuranceDefs.ConfigRegionRuleIfDeclaredUnderAge['$type'] | AppBskyAgeassuranceDefs.ConfigRegionRuleIfAssuredOverAge['$type'] | AppBskyAgeassuranceDefs.ConfigRegionRuleIfAssuredUnderAge['$type'] | AppBskyAgeassuranceDefs.ConfigRegionRuleIfAccountNewerThan['$type'] | AppBskyAgeassuranceDefs.ConfigRegionRuleIfAccountOlderThan['$type'], undefined > export const ageAssuranceRuleIDs: Record = { Default: `${ids.AppBskyAgeassuranceDefs}#configRegionRuleDefault`, IfDeclaredOverAge: `${ids.AppBskyAgeassuranceDefs}#configRegionRuleIfDeclaredOverAge`, IfDeclaredUnderAge: `${ids.AppBskyAgeassuranceDefs}#configRegionRuleIfDeclaredUnderAge`, IfAssuredOverAge: `${ids.AppBskyAgeassuranceDefs}#configRegionRuleIfAssuredOverAge`, IfAssuredUnderAge: `${ids.AppBskyAgeassuranceDefs}#configRegionRuleIfAssuredUnderAge`, IfAccountNewerThan: `${ids.AppBskyAgeassuranceDefs}#configRegionRuleIfAccountNewerThan`, IfAccountOlderThan: `${ids.AppBskyAgeassuranceDefs}#configRegionRuleIfAccountOlderThan`, } /** * Returns the first matched region configuration based on the provided geolocation. */ export function getAgeAssuranceRegionConfig( config: AppBskyAgeassuranceDefs.Config, geolocation: { countryCode: string regionCode?: string }, ): AppBskyAgeassuranceDefs.ConfigRegion | undefined { const { regions } = config return regions.find(({ countryCode, regionCode }) => { if (countryCode === geolocation.countryCode) { return !regionCode || regionCode === geolocation.regionCode } }) } export function computeAgeAssuranceRegionAccess( region: AppBskyAgeassuranceDefs.ConfigRegion, data: | { /** * The account creation date in ISO 8601 format. Only checked if we * don't have an assured age, such as on the client. */ accountCreatedAt?: string /** * The user's declared age */ declaredAge?: number /** * The user's minimum age as assured by a trusted third party. */ assuredAge?: number } | undefined, ): | { access: AppBskyAgeassuranceDefs.Access reason: AgeAssuranceRuleID } | undefined { // first match wins for (const rule of region.rules) { if (AppBskyAgeassuranceDefs.isConfigRegionRuleIfAccountNewerThan(rule)) { if (data?.accountCreatedAt && !data?.assuredAge) { const accountCreatedAt = new Date(data.accountCreatedAt) const threshold = new Date(rule.date) if (accountCreatedAt >= threshold) { return { access: rule.access, reason: rule.$type, } } } } else if ( AppBskyAgeassuranceDefs.isConfigRegionRuleIfAccountOlderThan(rule) ) { if (data?.accountCreatedAt && !data?.assuredAge) { const accountCreatedAt = new Date(data.accountCreatedAt) const threshold = new Date(rule.date) if (accountCreatedAt < threshold) { return { access: rule.access, reason: rule.$type, } } } } else if ( AppBskyAgeassuranceDefs.isConfigRegionRuleIfDeclaredOverAge(rule) ) { if (data?.declaredAge !== undefined && data.declaredAge >= rule.age) { return { access: rule.access, reason: rule.$type, } } } else if ( AppBskyAgeassuranceDefs.isConfigRegionRuleIfDeclaredUnderAge(rule) ) { if (data?.declaredAge !== undefined && data.declaredAge < rule.age) { return { access: rule.access, reason: rule.$type, } } } else if ( AppBskyAgeassuranceDefs.isConfigRegionRuleIfAssuredOverAge(rule) ) { if (data?.assuredAge && data.assuredAge >= rule.age) { return { access: rule.access, reason: rule.$type, } } } else if ( AppBskyAgeassuranceDefs.isConfigRegionRuleIfAssuredUnderAge(rule) ) { if (data?.assuredAge && data.assuredAge < rule.age) { return { access: rule.access, reason: rule.$type, } } } else if (AppBskyAgeassuranceDefs.isConfigRegionRuleDefault(rule)) { return { access: rule.access, reason: rule.$type, } } } } ================================================ FILE: packages/api/src/agent.ts ================================================ import AwaitLock from 'await-lock' import { TID, retry } from '@atproto/common-web' import { AtUri, ensureValidDid } from '@atproto/syntax' import { FetchHandler, FetchHandlerOptions, XrpcClient, buildFetchHandler, } from '@atproto/xrpc' import { AppBskyActorDefs, AppBskyActorProfile, AppBskyFeedPost, AppBskyLabelerDefs, AppNS, ChatNS, ComAtprotoRepoPutRecord, ComNS, ToolsNS, } from './client/index' import { schemas } from './client/lexicons' import { MutedWord, Nux } from './client/types/app/bsky/actor/defs' import { $Typed, Un$Typed } from './client/util' import { BSKY_LABELER_DID } from './const' import { interpretLabelValueDefinitions } from './moderation' import { DEFAULT_LABEL_SETTINGS } from './moderation/const/labels' import { InterpretedLabelValueDefinition, LabelPreference, ModerationPrefs, } from './moderation/types' import * as predicate from './predicate' import { SessionManager } from './session-manager' import { AtpAgentGlobalOpts, AtprotoProxy, AtprotoServiceType, BskyFeedViewPreference, BskyInterestsPreference, BskyPreferences, BskyThreadViewPreference, asAtprotoProxy, asDid, isDid, } from './types' import { getSavedFeedType, sanitizeMutedWordValue, savedFeedsToUriArrays, validateNux, validateSavedFeed, } from './util' const FEED_VIEW_PREF_DEFAULTS = { hideReplies: false, hideRepliesByUnfollowed: true, hideRepliesByLikeCount: 0, hideReposts: false, hideQuotePosts: false, } const THREAD_VIEW_PREF_DEFAULTS = { sort: 'hotness', } export type { FetchHandler } /** * An {@link Agent} is an {@link AtpBaseClient} with the following * additional features: * - AT Protocol labelers configuration utilities * - AT Protocol proxy configuration utilities * - Cloning utilities * - `app.bsky` syntactic sugar * - `com.atproto` syntactic sugar */ export class Agent extends XrpcClient { //#region Static configuration /** * The labelers to be used across all requests with the takedown capability */ static appLabelers: readonly string[] = [BSKY_LABELER_DID] /** * Configures the Agent (or its sub classes) globally. */ static configure(opts: AtpAgentGlobalOpts) { if (opts.appLabelers) { this.appLabelers = opts.appLabelers.map(asDid) // Validate & copy } } //#endregion com = new ComNS(this) app = new AppNS(this) chat = new ChatNS(this) tools = new ToolsNS(this) /** @deprecated use `this` instead */ get xrpc(): XrpcClient { return this } readonly sessionManager: SessionManager constructor(options: SessionManager | FetchHandler | FetchHandlerOptions) { const sessionManager: SessionManager = typeof options === 'object' && 'fetchHandler' in options ? options : { did: undefined, fetchHandler: buildFetchHandler(options), } super((url, init) => { const headers = new Headers(init?.headers) if (this.proxy && !headers.has('atproto-proxy')) { headers.set('atproto-proxy', this.proxy) } // Merge the labelers header of this particular request with the app & // instance labelers. headers.set( 'atproto-accept-labelers', [ ...this.appLabelers.map((l) => `${l};redact`), ...this.labelers, headers.get('atproto-accept-labelers')?.trim(), ] .filter(Boolean) .join(', '), ) return this.sessionManager.fetchHandler(url, { ...init, headers }) }, schemas) this.sessionManager = sessionManager } //#region Cloning utilities clone(): Agent { return this.copyInto(new Agent(this.sessionManager)) } copyInto(inst: T): T { inst.configureLabelers(this.labelers) inst.configureProxy(this.proxy ?? null) inst.clearHeaders() for (const [key, value] of this.headers) inst.setHeader(key, value) return inst } withProxy(serviceType: AtprotoServiceType, did: string) { const inst = this.clone() inst.configureProxy(`${asDid(did)}#${serviceType}`) return inst as ReturnType } //#endregion //#region ATPROTO labelers configuration utilities /** * The labelers statically configured on the class of the current instance. */ get appLabelers() { return (this.constructor as typeof Agent).appLabelers } labelers: readonly string[] = [] configureLabelers(labelerDids: readonly string[]) { this.labelers = labelerDids.map(asDid) // Validate & copy } /** @deprecated use {@link configureLabelers} instead */ configureLabelersHeader(labelerDids: readonly string[]) { // Filtering non-did values for backwards compatibility this.configureLabelers(labelerDids.filter(isDid)) } //#endregion //#region ATPROTO proxy configuration utilities proxy?: AtprotoProxy configureProxy(value: AtprotoProxy | null) { if (value === null) this.proxy = undefined else this.proxy = asAtprotoProxy(value) } /** @deprecated use {@link configureProxy} instead */ configureProxyHeader(serviceType: AtprotoServiceType, did: string) { // Ignoring non-did values for backwards compatibility if (isDid(did)) this.configureProxy(`${did}#${serviceType}`) } //#endregion //#region Session management /** * Get the authenticated user's DID, if any. */ get did() { return this.sessionManager.did } /** @deprecated Use {@link Agent.assertDid} instead */ get accountDid() { return this.assertDid } /** * Get the authenticated user's DID, or throw an error if not authenticated. */ get assertDid(): string { this.assertAuthenticated() return this.did } /** * Assert that the user is authenticated. */ public assertAuthenticated(): asserts this is { did: string } { if (!this.did) throw new Error('Not logged in') } //#endregion /** @deprecated use "this" instead */ get api() { return this } //#region "com.atproto" lexicon short hand methods /** * Upload a binary blob to the server */ uploadBlob: typeof this.com.atproto.repo.uploadBlob = (data, opts) => this.com.atproto.repo.uploadBlob(data, opts) /** * Resolve a handle to a DID */ resolveHandle: typeof this.com.atproto.identity.resolveHandle = ( params, opts, ) => this.com.atproto.identity.resolveHandle(params, opts) /** * Change the user's handle */ updateHandle: typeof this.com.atproto.identity.updateHandle = (data, opts) => this.com.atproto.identity.updateHandle(data, opts) /** * Create a moderation report */ createModerationReport: typeof this.com.atproto.moderation.createReport = ( data, opts, ) => this.com.atproto.moderation.createReport(data, opts) //#endregion //#region "app.bsky" lexicon short hand methods getTimeline: typeof this.app.bsky.feed.getTimeline = (params, opts) => this.app.bsky.feed.getTimeline(params, opts) getAuthorFeed: typeof this.app.bsky.feed.getAuthorFeed = (params, opts) => this.app.bsky.feed.getAuthorFeed(params, opts) getActorLikes: typeof this.app.bsky.feed.getActorLikes = (params, opts) => this.app.bsky.feed.getActorLikes(params, opts) getPostThread: typeof this.app.bsky.feed.getPostThread = (params, opts) => this.app.bsky.feed.getPostThread(params, opts) getPost: typeof this.app.bsky.feed.post.get = (params) => this.app.bsky.feed.post.get(params) getPosts: typeof this.app.bsky.feed.getPosts = (params, opts) => this.app.bsky.feed.getPosts(params, opts) getLikes: typeof this.app.bsky.feed.getLikes = (params, opts) => this.app.bsky.feed.getLikes(params, opts) getRepostedBy: typeof this.app.bsky.feed.getRepostedBy = (params, opts) => this.app.bsky.feed.getRepostedBy(params, opts) getFollows: typeof this.app.bsky.graph.getFollows = (params, opts) => this.app.bsky.graph.getFollows(params, opts) getFollowers: typeof this.app.bsky.graph.getFollowers = (params, opts) => this.app.bsky.graph.getFollowers(params, opts) getProfile: typeof this.app.bsky.actor.getProfile = (params, opts) => this.app.bsky.actor.getProfile(params, opts) getProfiles: typeof this.app.bsky.actor.getProfiles = (params, opts) => this.app.bsky.actor.getProfiles(params, opts) getSuggestions: typeof this.app.bsky.actor.getSuggestions = (params, opts) => this.app.bsky.actor.getSuggestions(params, opts) searchActors: typeof this.app.bsky.actor.searchActors = (params, opts) => this.app.bsky.actor.searchActors(params, opts) searchActorsTypeahead: typeof this.app.bsky.actor.searchActorsTypeahead = ( params, opts, ) => this.app.bsky.actor.searchActorsTypeahead(params, opts) listNotifications: typeof this.app.bsky.notification.listNotifications = ( params, opts, ) => this.app.bsky.notification.listNotifications(params, opts) countUnreadNotifications: typeof this.app.bsky.notification.getUnreadCount = ( params, opts, ) => this.app.bsky.notification.getUnreadCount(params, opts) getLabelers: typeof this.app.bsky.labeler.getServices = (params, opts) => this.app.bsky.labeler.getServices(params, opts) async getLabelDefinitions( prefs: BskyPreferences | ModerationPrefs | string[], ): Promise> { // collect the labeler dids const dids: string[] = [...this.appLabelers] if (isBskyPrefs(prefs)) { dids.push(...prefs.moderationPrefs.labelers.map((l) => l.did)) } else if (isModPrefs(prefs)) { dids.push(...prefs.labelers.map((l) => l.did)) } else { dids.push(...prefs) } // fetch their definitions const labelers = await this.getLabelers({ dids, detailed: true, }) // assemble a map of labeler dids to the interpreted label value definitions const labelDefs = {} if (labelers.data) { for (const labeler of labelers.data .views as AppBskyLabelerDefs.LabelerViewDetailed[]) { labelDefs[labeler.creator.did] = interpretLabelValueDefinitions(labeler) } } return labelDefs } async post( record: Partial & Omit, ) { record.createdAt ||= new Date().toISOString() return this.app.bsky.feed.post.create( { repo: this.accountDid }, record as AppBskyFeedPost.Record, ) } async deletePost(postUri: string) { this.assertAuthenticated() const postUrip = new AtUri(postUri) return this.app.bsky.feed.post.delete({ repo: postUrip.hostname, rkey: postUrip.rkey, }) } async like(uri: string, cid: string, via?: { uri: string; cid: string }) { return this.app.bsky.feed.like.create( { repo: this.accountDid }, { subject: { uri, cid }, createdAt: new Date().toISOString(), via, }, ) } async deleteLike(likeUri: string) { this.assertAuthenticated() const likeUrip = new AtUri(likeUri) return this.app.bsky.feed.like.delete({ repo: likeUrip.hostname, rkey: likeUrip.rkey, }) } async repost(uri: string, cid: string, via?: { uri: string; cid: string }) { return this.app.bsky.feed.repost.create( { repo: this.accountDid }, { subject: { uri, cid }, createdAt: new Date().toISOString(), via, }, ) } async deleteRepost(repostUri: string) { this.assertAuthenticated() const repostUrip = new AtUri(repostUri) return this.app.bsky.feed.repost.delete({ repo: repostUrip.hostname, rkey: repostUrip.rkey, }) } async follow(subjectDid: string, via?: { uri: string; cid: string }) { return this.app.bsky.graph.follow.create( { repo: this.accountDid }, { subject: subjectDid, createdAt: new Date().toISOString(), via, }, ) } async deleteFollow(followUri: string) { this.assertAuthenticated() const followUrip = new AtUri(followUri) return this.app.bsky.graph.follow.delete({ repo: followUrip.hostname, rkey: followUrip.rkey, }) } /** * @note: Using this method will reset the whole profile record if it * previously contained invalid values (wrt to the profile lexicon). */ async upsertProfile( updateFn: ( existing: AppBskyActorProfile.Record | undefined, ) => | Un$Typed | Promise>, ): Promise { const upsert = async () => { const repo = this.assertDid const collection = 'app.bsky.actor.profile' const existing = await this.com.atproto.repo .getRecord({ repo, collection, rkey: 'self' }) .catch((_) => undefined) const existingRecord: AppBskyActorProfile.Record | undefined = existing && predicate.isValidProfile(existing.data.value) ? existing.data.value : undefined // run the update const updated = await updateFn(existingRecord) // validate the value returned by the update function const validation = AppBskyActorProfile.validateRecord({ $type: collection, ...updated, }) if (!validation.success) { throw validation.error } await this.com.atproto.repo.putRecord({ repo, collection, rkey: 'self', record: validation.value, swapRecord: existing?.data.cid || null, }) } return retry(upsert, { maxRetries: 5, retryable: (e) => e instanceof ComAtprotoRepoPutRecord.InvalidSwapError, }) } async mute(actor: string) { return this.app.bsky.graph.muteActor({ actor }) } async unmute(actor: string) { return this.app.bsky.graph.unmuteActor({ actor }) } async muteModList(uri: string) { return this.app.bsky.graph.muteActorList({ list: uri }) } async unmuteModList(uri: string) { return this.app.bsky.graph.unmuteActorList({ list: uri }) } async blockModList(uri: string) { return this.app.bsky.graph.listblock.create( { repo: this.accountDid }, { subject: uri, createdAt: new Date().toISOString(), }, ) } async unblockModList(uri: string) { const repo = this.accountDid const listInfo = await this.app.bsky.graph.getList({ list: uri, limit: 1, }) const blocked = listInfo.data.list.viewer?.blocked if (blocked) { const { rkey } = new AtUri(blocked) return this.app.bsky.graph.listblock.delete({ repo, rkey, }) } } async updateSeenNotifications(seenAt = new Date().toISOString()) { return this.app.bsky.notification.updateSeen({ seenAt }) } async getPreferences(): Promise { const prefs: BskyPreferences = { feeds: { saved: undefined, pinned: undefined, }, // @ts-ignore populating below savedFeeds: undefined, feedViewPrefs: { home: { ...FEED_VIEW_PREF_DEFAULTS, }, }, threadViewPrefs: { ...THREAD_VIEW_PREF_DEFAULTS }, moderationPrefs: { adultContentEnabled: false, labels: { ...DEFAULT_LABEL_SETTINGS }, labelers: this.appLabelers.map((did) => ({ did, labels: {}, })), mutedWords: [], hiddenPosts: [], }, birthDate: undefined, interests: { tags: [], }, bskyAppState: { queuedNudges: [], activeProgressGuide: undefined, nuxs: [], }, postInteractionSettings: { threadgateAllowRules: undefined, postgateEmbeddingRules: undefined, }, verificationPrefs: { hideBadges: false, }, liveEventPreferences: { hiddenFeedIds: [], hideAllFeeds: false, }, } const res = await this.app.bsky.actor.getPreferences({}) const labelPrefs: AppBskyActorDefs.ContentLabelPref[] = [] for (const pref of res.data.preferences) { if (predicate.isValidAdultContentPref(pref)) { // adult content preferences prefs.moderationPrefs.adultContentEnabled = pref.enabled } else if (predicate.isValidContentLabelPref(pref)) { // content label preference const adjustedPref = adjustLegacyContentLabelPref(pref) labelPrefs.push(adjustedPref) } else if (predicate.isValidLabelersPref(pref)) { // labelers preferences prefs.moderationPrefs.labelers = this.appLabelers .map((did: string) => ({ did, labels: {} })) .concat( pref.labelers.map((labeler) => ({ ...labeler, labels: {}, })), ) } else if (predicate.isValidSavedFeedsPrefV2(pref)) { prefs.savedFeeds = pref.items } else if (predicate.isValidSavedFeedsPref(pref)) { // saved and pinned feeds prefs.feeds.saved = pref.saved prefs.feeds.pinned = pref.pinned } else if (predicate.isValidPersonalDetailsPref(pref)) { // birth date (irl) if (pref.birthDate) { prefs.birthDate = new Date(pref.birthDate) } } else if (predicate.isValidDeclaredAgePref(pref)) { const { $type: _, ...declaredAgePref } = pref prefs.declaredAge = declaredAgePref } else if (predicate.isValidFeedViewPref(pref)) { // feed view preferences const { $type: _, feed, ...v } = pref prefs.feedViewPrefs[feed] = { ...FEED_VIEW_PREF_DEFAULTS, ...v } } else if (predicate.isValidThreadViewPref(pref)) { // thread view preferences const { $type: _, ...v } = pref prefs.threadViewPrefs = { ...prefs.threadViewPrefs, ...v } } else if (predicate.isValidInterestsPref(pref)) { const { $type: _, ...v } = pref prefs.interests = { ...prefs.interests, ...v } } else if (predicate.isValidMutedWordsPref(pref)) { prefs.moderationPrefs.mutedWords = pref.items if (prefs.moderationPrefs.mutedWords.length) { prefs.moderationPrefs.mutedWords = prefs.moderationPrefs.mutedWords.map((word) => { word.actorTarget = word.actorTarget || 'all' return word }) } } else if (predicate.isValidHiddenPostsPref(pref)) { prefs.moderationPrefs.hiddenPosts = pref.items } else if (predicate.isValidBskyAppStatePref(pref)) { prefs.bskyAppState.queuedNudges = pref.queuedNudges || [] prefs.bskyAppState.activeProgressGuide = pref.activeProgressGuide prefs.bskyAppState.nuxs = pref.nuxs || [] } else if (predicate.isValidPostInteractionSettingsPref(pref)) { prefs.postInteractionSettings.threadgateAllowRules = pref.threadgateAllowRules prefs.postInteractionSettings.postgateEmbeddingRules = pref.postgateEmbeddingRules } else if (predicate.isValidVerificationPrefs(pref)) { prefs.verificationPrefs = { hideBadges: pref.hideBadges, } } else if (predicate.isValidLiveEventPreferences(pref)) { prefs.liveEventPreferences = { hiddenFeedIds: pref.hiddenFeedIds || [], hideAllFeeds: pref.hideAllFeeds ?? false, } } } /* * If `prefs.savedFeeds` is undefined, no `savedFeedsPrefV2` exists, which * means we want to try to migrate if needed. * * If v1 prefs exist, they will be migrated to v2. * * If no v1 prefs exist, the user is either new, or could be old and has * never edited their feeds. */ if (prefs.savedFeeds == null) { const { saved, pinned } = prefs.feeds if (saved && pinned) { const uniqueMigratedSavedFeeds: Map< string, AppBskyActorDefs.SavedFeed > = new Map() // insert Following feed first uniqueMigratedSavedFeeds.set('timeline', { id: TID.nextStr(), type: 'timeline', value: 'following', pinned: true, }) // use pinned as source of truth for feed order for (const uri of pinned) { const type = getSavedFeedType(uri) // only want supported types if (type === 'unknown') continue uniqueMigratedSavedFeeds.set(uri, { id: TID.nextStr(), type, value: uri, pinned: true, }) } for (const uri of saved) { if (!uniqueMigratedSavedFeeds.has(uri)) { const type = getSavedFeedType(uri) // only want supported types if (type === 'unknown') continue uniqueMigratedSavedFeeds.set(uri, { id: TID.nextStr(), type, value: uri, pinned: false, }) } } prefs.savedFeeds = Array.from(uniqueMigratedSavedFeeds.values()) } else { prefs.savedFeeds = [ { id: TID.nextStr(), type: 'timeline', value: 'following', pinned: true, }, ] } // save to user preferences so this migration doesn't re-occur await this.overwriteSavedFeeds(prefs.savedFeeds) } // apply the label prefs for (const pref of labelPrefs) { if (pref.labelerDid) { const labeler = prefs.moderationPrefs.labelers.find( (labeler) => labeler.did === pref.labelerDid, ) if (!labeler) continue labeler.labels[pref.label] = pref.visibility as LabelPreference } else { prefs.moderationPrefs.labels[pref.label] = pref.visibility as LabelPreference } } prefs.moderationPrefs.labels = remapLegacyLabels( prefs.moderationPrefs.labels, ) // automatically configure the client this.configureLabelers(prefsArrayToLabelerDids(res.data.preferences)) return prefs } async overwriteSavedFeeds(savedFeeds: AppBskyActorDefs.SavedFeed[]) { savedFeeds.forEach(validateSavedFeed) const uniqueSavedFeeds = new Map() savedFeeds.forEach((feed) => { // remove and re-insert to preserve order if (uniqueSavedFeeds.has(feed.id)) { uniqueSavedFeeds.delete(feed.id) } uniqueSavedFeeds.set(feed.id, feed) }) return this.updateSavedFeedsV2Preferences(() => Array.from(uniqueSavedFeeds.values()), ) } async updateSavedFeeds(savedFeedsToUpdate: AppBskyActorDefs.SavedFeed[]) { savedFeedsToUpdate.map(validateSavedFeed) return this.updateSavedFeedsV2Preferences((savedFeeds) => { return savedFeeds.map((savedFeed) => { const updatedVersion = savedFeedsToUpdate.find( (updated) => savedFeed.id === updated.id, ) if (updatedVersion) { return { ...savedFeed, // only update pinned pinned: updatedVersion.pinned, } } return savedFeed }) }) } async addSavedFeeds( savedFeeds: Pick[], ) { const toSave: AppBskyActorDefs.SavedFeed[] = savedFeeds.map((f) => ({ ...f, id: TID.nextStr(), })) toSave.forEach(validateSavedFeed) return this.updateSavedFeedsV2Preferences((savedFeeds) => [ ...savedFeeds, ...toSave, ]) } async removeSavedFeeds(ids: string[]) { return this.updateSavedFeedsV2Preferences((savedFeeds) => [ ...savedFeeds.filter((feed) => !ids.find((id) => feed.id === id)), ]) } /** * @deprecated use `overwriteSavedFeeds` */ async setSavedFeeds(saved: string[], pinned: string[]) { return this.updateFeedPreferences(() => ({ saved, pinned, })) } /** * @deprecated use `addSavedFeeds` */ async addSavedFeed(v: string) { return this.updateFeedPreferences((saved: string[], pinned: string[]) => ({ saved: [...saved.filter((uri) => uri !== v), v], pinned, })) } /** * @deprecated use `removeSavedFeeds` */ async removeSavedFeed(v: string) { return this.updateFeedPreferences((saved: string[], pinned: string[]) => ({ saved: saved.filter((uri) => uri !== v), pinned: pinned.filter((uri) => uri !== v), })) } /** * @deprecated use `addSavedFeeds` or `updateSavedFeeds` */ async addPinnedFeed(v: string) { return this.updateFeedPreferences((saved: string[], pinned: string[]) => ({ saved: [...saved.filter((uri) => uri !== v), v], pinned: [...pinned.filter((uri) => uri !== v), v], })) } /** * @deprecated use `updateSavedFeeds` or `removeSavedFeeds` */ async removePinnedFeed(v: string) { return this.updateFeedPreferences((saved: string[], pinned: string[]) => ({ saved, pinned: pinned.filter((uri) => uri !== v), })) } async setAdultContentEnabled(v: boolean) { await this.updatePreferences((prefs) => { const adultContentPref = prefs.findLast( predicate.isValidAdultContentPref, ) || { $type: 'app.bsky.actor.defs#adultContentPref', enabled: v, } adultContentPref.enabled = v return prefs .filter((pref) => !AppBskyActorDefs.isAdultContentPref(pref)) .concat(adultContentPref) }) } async setContentLabelPref( key: string, value: LabelPreference, labelerDid?: string, ) { if (labelerDid) { ensureValidDid(labelerDid) } await this.updatePreferences((prefs) => { const labelPref = prefs .filter(predicate.isValidContentLabelPref) .findLast( (pref) => pref.label === key && pref.labelerDid === labelerDid, ) || { $type: 'app.bsky.actor.defs#contentLabelPref', label: key, labelerDid, visibility: value, } labelPref.visibility = value let legacyLabelPref: $Typed | undefined if (AppBskyActorDefs.isContentLabelPref(labelPref)) { // is global if (!labelPref.labelerDid) { const legacyLabelValue = { 'graphic-media': 'gore', porn: 'nsfw', sexual: 'suggestive', // Protect against using toString, hasOwnProperty, etc. as a label: __proto__: null, }[labelPref.label] // if it's a legacy label, double-write the legacy label if (legacyLabelValue) { legacyLabelPref = prefs .filter(predicate.isValidContentLabelPref) .findLast( (pref) => pref.label === legacyLabelValue && pref.labelerDid === undefined, ) || { $type: 'app.bsky.actor.defs#contentLabelPref', label: legacyLabelValue, labelerDid: undefined, visibility: value, } legacyLabelPref!.visibility = value } } } return prefs .filter( (pref) => !AppBskyActorDefs.isContentLabelPref(pref) || !(pref.label === key && pref.labelerDid === labelerDid), ) .concat(labelPref) .filter((pref) => { if (!legacyLabelPref) return true return ( !AppBskyActorDefs.isContentLabelPref(pref) || !( pref.label === legacyLabelPref.label && pref.labelerDid === undefined ) ) }) .concat(legacyLabelPref ? [legacyLabelPref] : []) }) } async addLabeler(did: string) { const prefs = await this.updatePreferences((prefs) => { const labelersPref = prefs.findLast(predicate.isValidLabelersPref) || { $type: 'app.bsky.actor.defs#labelersPref', labelers: [], } if (!labelersPref.labelers.some((labeler) => labeler.did === did)) { labelersPref.labelers.push({ did }) } return prefs .filter((pref) => !AppBskyActorDefs.isLabelersPref(pref)) .concat(labelersPref) }) // automatically configure the client this.configureLabelers(prefsArrayToLabelerDids(prefs)) } async removeLabeler(did: string) { const prefs = await this.updatePreferences((prefs) => { const labelersPref = prefs.findLast(predicate.isValidLabelersPref) || { $type: 'app.bsky.actor.defs#labelersPref', labelers: [], } labelersPref.labelers = labelersPref.labelers.filter((l) => l.did !== did) return prefs .filter((pref) => !AppBskyActorDefs.isLabelersPref(pref)) .concat(labelersPref) }) // automatically configure the client this.configureLabelers(prefsArrayToLabelerDids(prefs)) } async setPersonalDetails({ birthDate, }: { birthDate: string | Date | undefined }) { await this.updatePreferences((prefs) => { const personalDetailsPref = prefs.findLast( predicate.isValidPersonalDetailsPref, ) || { $type: 'app.bsky.actor.defs#personalDetailsPref', } personalDetailsPref.birthDate = birthDate instanceof Date ? birthDate.toISOString() : birthDate return prefs .filter((pref) => !AppBskyActorDefs.isPersonalDetailsPref(pref)) .concat(personalDetailsPref) }) } async setFeedViewPrefs(feed: string, pref: Partial) { await this.updatePreferences((prefs) => { const existing = prefs .filter(predicate.isValidFeedViewPref) .findLast((pref) => pref.feed === feed) return prefs .filter((p) => !AppBskyActorDefs.isFeedViewPref(p) || p.feed !== feed) .concat({ ...existing, ...pref, $type: 'app.bsky.actor.defs#feedViewPref', feed, }) }) } async setThreadViewPrefs(pref: Partial) { await this.updatePreferences((prefs) => { const existing = prefs.findLast(predicate.isValidThreadViewPref) return prefs .filter((p) => !AppBskyActorDefs.isThreadViewPref(p)) .concat({ ...existing, ...pref, $type: 'app.bsky.actor.defs#threadViewPref', }) }) } async setInterestsPref(pref: Partial) { await this.updatePreferences((prefs) => { const existing = prefs.findLast(predicate.isValidInterestsPref) return prefs .filter((p) => !AppBskyActorDefs.isInterestsPref(p)) .concat({ ...existing, ...pref, $type: 'app.bsky.actor.defs#interestsPref', }) }) } /** * Add a muted word to user preferences. */ async addMutedWord( mutedWord: Pick< MutedWord, 'value' | 'targets' | 'actorTarget' | 'expiresAt' >, ) { const sanitizedValue = sanitizeMutedWordValue(mutedWord.value) if (!sanitizedValue) return await this.updatePreferences((prefs) => { let mutedWordsPref = prefs.findLast(predicate.isValidMutedWordsPref) const newMutedWord: AppBskyActorDefs.MutedWord = { id: TID.nextStr(), value: sanitizedValue, targets: mutedWord.targets || [], actorTarget: mutedWord.actorTarget || 'all', expiresAt: mutedWord.expiresAt || undefined, } if (mutedWordsPref) { mutedWordsPref.items.push(newMutedWord) /** * Migrate any old muted words that don't have an id */ mutedWordsPref.items = migrateLegacyMutedWordsItems( mutedWordsPref.items, ) } else { // if the pref doesn't exist, create it mutedWordsPref = { $type: 'app.bsky.actor.defs#mutedWordsPref', items: [newMutedWord], } } return prefs .filter((p) => !AppBskyActorDefs.isMutedWordsPref(p)) .concat(mutedWordsPref) }) } /** * Convenience method to add muted words to user preferences */ async addMutedWords(newMutedWords: AppBskyActorDefs.MutedWord[]) { await Promise.all(newMutedWords.map((word) => this.addMutedWord(word))) } /** * @deprecated use `addMutedWords` or `addMutedWord` instead */ async upsertMutedWords( mutedWords: Pick< MutedWord, 'value' | 'targets' | 'actorTarget' | 'expiresAt' >[], ) { await this.addMutedWords(mutedWords) } /** * Update a muted word in user preferences. */ async updateMutedWord(mutedWord: AppBskyActorDefs.MutedWord) { await this.updatePreferences((prefs) => { const mutedWordsPref = prefs.findLast(predicate.isValidMutedWordsPref) if (mutedWordsPref) { mutedWordsPref.items = mutedWordsPref.items.map((existingItem) => { const match = matchMutedWord(existingItem, mutedWord) if (match) { const updated = { ...existingItem, ...mutedWord, } return { id: existingItem.id || TID.nextStr(), value: sanitizeMutedWordValue(updated.value) || existingItem.value, targets: updated.targets || [], actorTarget: updated.actorTarget || 'all', expiresAt: updated.expiresAt || undefined, } } else { return existingItem } }) /** * Migrate any old muted words that don't have an id */ mutedWordsPref.items = migrateLegacyMutedWordsItems( mutedWordsPref.items, ) return prefs .filter((p) => !AppBskyActorDefs.isMutedWordsPref(p)) .concat(mutedWordsPref) } return prefs }) } /** * Remove a muted word from user preferences. */ async removeMutedWord(mutedWord: AppBskyActorDefs.MutedWord) { await this.updatePreferences((prefs) => { const mutedWordsPref = prefs.findLast(predicate.isValidMutedWordsPref) if (mutedWordsPref) { for (let i = 0; i < mutedWordsPref.items.length; i++) { const match = matchMutedWord(mutedWordsPref.items[i], mutedWord) if (match) { mutedWordsPref.items.splice(i, 1) break } } /** * Migrate any old muted words that don't have an id */ mutedWordsPref.items = migrateLegacyMutedWordsItems( mutedWordsPref.items, ) return prefs .filter((p) => !AppBskyActorDefs.isMutedWordsPref(p)) .concat(mutedWordsPref) } return prefs }) } /** * Convenience method to remove muted words from user preferences */ async removeMutedWords(mutedWords: AppBskyActorDefs.MutedWord[]) { await Promise.all(mutedWords.map((word) => this.removeMutedWord(word))) } async hidePost(postUri: string) { await this.updateHiddenPost(postUri, 'hide') } async unhidePost(postUri: string) { await this.updateHiddenPost(postUri, 'unhide') } async bskyAppQueueNudges(nudges: string | string[]) { await this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidBskyAppStatePref) || { $type: 'app.bsky.actor.defs#bskyAppStatePref', } pref.queuedNudges = (pref.queuedNudges || []).concat(nudges) return prefs .filter((p) => !AppBskyActorDefs.isBskyAppStatePref(p)) .concat(pref) }) } async bskyAppDismissNudges(nudges: string | string[]) { await this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidBskyAppStatePref) || { $type: 'app.bsky.actor.defs#bskyAppStatePref', } nudges = Array.isArray(nudges) ? nudges : [nudges] pref.queuedNudges = (pref.queuedNudges || []).filter( (nudge) => !nudges.includes(nudge), ) return prefs .filter((p) => !AppBskyActorDefs.isBskyAppStatePref(p)) .concat(pref) }) } async bskyAppSetActiveProgressGuide( guide: AppBskyActorDefs.BskyAppProgressGuide | undefined, ) { if (guide) { const result = AppBskyActorDefs.validateBskyAppProgressGuide(guide) if (!result.success) throw result.error } await this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidBskyAppStatePref) || { $type: 'app.bsky.actor.defs#bskyAppStatePref', } pref.activeProgressGuide = guide return prefs .filter((p) => !AppBskyActorDefs.isBskyAppStatePref(p)) .concat(pref) }) } /** * Insert or update a NUX in user prefs */ async bskyAppUpsertNux(nux: Nux) { validateNux(nux) await this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidBskyAppStatePref) || { $type: 'app.bsky.actor.defs#bskyAppStatePref', } pref.nuxs = pref.nuxs || [] const existing = pref.nuxs?.find((n) => { return n.id === nux.id }) let next: AppBskyActorDefs.Nux if (existing) { next = { id: existing.id, completed: nux.completed, data: nux.data, expiresAt: nux.expiresAt, } } else { next = nux } // remove duplicates and append pref.nuxs = pref.nuxs.filter((n) => n.id !== nux.id).concat(next) return prefs .filter((p) => !AppBskyActorDefs.isBskyAppStatePref(p)) .concat(pref) }) } /** * Removes NUXs from user preferences. */ async bskyAppRemoveNuxs(ids: string[]) { await this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidBskyAppStatePref) || { $type: 'app.bsky.actor.defs#bskyAppStatePref', } pref.nuxs = (pref.nuxs || []).filter((nux) => !ids.includes(nux.id)) return prefs .filter((p) => !AppBskyActorDefs.isBskyAppStatePref(p)) .concat(pref) }) } async setPostInteractionSettings( settings: AppBskyActorDefs.PostInteractionSettingsPref, ) { const result = AppBskyActorDefs.validatePostInteractionSettingsPref(settings) // Fool-proofing (should not be needed because of type safety) if (!result.success) throw result.error await this.updatePreferences((prefs) => { const pref = prefs.findLast( predicate.isValidPostInteractionSettingsPref, ) || { $type: 'app.bsky.actor.defs#postInteractionSettingsPref', } /** * Matches handling of `threadgate.allow` where `undefined` means "everyone" */ pref.threadgateAllowRules = settings.threadgateAllowRules pref.postgateEmbeddingRules = settings.postgateEmbeddingRules return prefs .filter((p) => !AppBskyActorDefs.isPostInteractionSettingsPref(p)) .concat(pref) }) } async setVerificationPrefs(settings: AppBskyActorDefs.VerificationPrefs) { const result = AppBskyActorDefs.validateVerificationPrefs(settings) // Fool-proofing (should not be needed because of type safety) if (!result.success) throw result.error await this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidVerificationPrefs) || { $type: 'app.bsky.actor.defs#verificationPrefs', hideBadges: false, } pref.hideBadges = settings.hideBadges return prefs .filter((p) => !AppBskyActorDefs.isVerificationPrefs(p)) .concat(pref) }) } async updateLiveEventPreferences( action: | { type: 'hideFeed'; id: string } | { type: 'unhideFeed'; id: string } | { type: 'toggleHideAllFeeds' }, ) { return this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidLiveEventPreferences) || { $type: 'app.bsky.actor.defs#liveEventPreferences', hiddenFeedIds: [], hideAllFeeds: false, } const hiddenFeedIds = new Set(pref.hiddenFeedIds || []) switch (action.type) { case 'hideFeed': hiddenFeedIds.add(action.id) break case 'unhideFeed': hiddenFeedIds.delete(action.id) break case 'toggleHideAllFeeds': pref.hideAllFeeds = !pref.hideAllFeeds break } pref.hiddenFeedIds = [...hiddenFeedIds] return prefs .filter((p) => !AppBskyActorDefs.isLiveEventPreferences(p)) .concat(pref) }) } //- Private methods #prefsLock = new AwaitLock() /** * This function updates the preferences of a user and allows for a callback function to be executed * before the update. * @param cb - cb is a callback function that takes in a single parameter of type * AppBskyActorDefs.Preferences and returns either a boolean or void. This callback function is used to * update the preferences of the user. The function is called with the current preferences as an * argument and if the callback returns false, the preferences are not updated. */ private async updatePreferences( cb: ( prefs: AppBskyActorDefs.Preferences, ) => AppBskyActorDefs.Preferences | false, ) { try { await this.#prefsLock.acquireAsync() const res = await this.app.bsky.actor.getPreferences({}) const newPrefs = cb(res.data.preferences) if (newPrefs === false) { return res.data.preferences } await this.app.bsky.actor.putPreferences({ preferences: newPrefs, }) return newPrefs } finally { this.#prefsLock.release() } } private async updateHiddenPost(postUri: string, action: 'hide' | 'unhide') { await this.updatePreferences((prefs) => { const pref = prefs.findLast(predicate.isValidHiddenPostsPref) || { $type: 'app.bsky.actor.defs#hiddenPostsPref', items: [], } const hiddenItems = new Set(pref.items) if (action === 'hide') hiddenItems.add(postUri) else hiddenItems.delete(postUri) pref.items = [...hiddenItems] return prefs .filter((p) => !AppBskyActorDefs.isHiddenPostsPref(p)) .concat(pref) }) } /** * A helper specifically for updating feed preferences */ private async updateFeedPreferences( cb: ( saved: string[], pinned: string[], ) => { saved: string[]; pinned: string[] }, ): Promise<{ saved: string[]; pinned: string[] }> { let res await this.updatePreferences((prefs) => { const feedsPref = prefs.findLast(predicate.isValidSavedFeedsPref) || { $type: 'app.bsky.actor.defs#savedFeedsPref', saved: [], pinned: [], } res = cb(feedsPref.saved, feedsPref.pinned) feedsPref.saved = res.saved feedsPref.pinned = res.pinned return prefs .filter((pref) => !AppBskyActorDefs.isSavedFeedsPref(pref)) .concat(feedsPref) }) return res } private async updateSavedFeedsV2Preferences( cb: ( savedFeedsPref: AppBskyActorDefs.SavedFeed[], ) => AppBskyActorDefs.SavedFeed[], ): Promise { let maybeMutatedSavedFeeds: AppBskyActorDefs.SavedFeed[] = [] await this.updatePreferences((prefs) => { const existingV2Pref = prefs.findLast( predicate.isValidSavedFeedsPrefV2, ) || { $type: 'app.bsky.actor.defs#savedFeedsPrefV2', items: [], } const newSavedFeeds = cb(existingV2Pref.items) // enforce ordering: pinned first, then saved existingV2Pref.items = [...newSavedFeeds].sort((a, b) => // @NOTE: preserve order of items with the same pinned status a.pinned === b.pinned ? 0 : a.pinned ? -1 : 1, ) // Store the return value maybeMutatedSavedFeeds = newSavedFeeds let updatedPrefs = prefs .filter((pref) => !AppBskyActorDefs.isSavedFeedsPrefV2(pref)) .concat(existingV2Pref) /* * If there's a v2 pref present, it means this account was migrated from v1 * to v2. During the transition period, we double write v2 prefs back to * v1, but NOT the other way around. */ let existingV1Pref = prefs.findLast(predicate.isValidSavedFeedsPref) if (existingV1Pref) { const { saved, pinned } = existingV1Pref const v2Compat = savedFeedsToUriArrays( // v1 only supports feeds and lists existingV2Pref.items.filter((i) => ['feed', 'list'].includes(i.type)), ) existingV1Pref = { ...existingV1Pref, saved: Array.from(new Set([...saved, ...v2Compat.saved])), pinned: Array.from(new Set([...pinned, ...v2Compat.pinned])), } updatedPrefs = updatedPrefs .filter((pref) => !AppBskyActorDefs.isSavedFeedsPref(pref)) .concat(existingV1Pref) } return updatedPrefs }) return maybeMutatedSavedFeeds } //#endregion } /** * Helper to transform the legacy content preferences. */ function adjustLegacyContentLabelPref( pref: AppBskyActorDefs.ContentLabelPref, ): AppBskyActorDefs.ContentLabelPref { let visibility = pref.visibility // adjust legacy values if (visibility === 'show') { visibility = 'ignore' } return { ...pref, visibility } } /** * Re-maps legacy labels to new labels on READ. Does not save these changes to * the user's preferences. */ function remapLegacyLabels( labels: BskyPreferences['moderationPrefs']['labels'], ) { const _labels = { ...labels } const legacyToNewMap: Record = { gore: 'graphic-media', nsfw: 'porn', suggestive: 'sexual', } for (const labelName in _labels) { const newLabelName = legacyToNewMap[labelName]! if (newLabelName) { _labels[newLabelName] = _labels[labelName] } } return _labels } /** * A helper to get the currently enabled labelers from the full preferences array */ function prefsArrayToLabelerDids( prefs: AppBskyActorDefs.Preferences, ): string[] { const labelersPref = prefs.findLast(predicate.isValidLabelersPref) let dids: string[] = [] if (labelersPref) { dids = (labelersPref as AppBskyActorDefs.LabelersPref).labelers.map( (labeler) => labeler.did, ) } return dids } function isBskyPrefs(v: any): v is BskyPreferences { return ( v && typeof v === 'object' && 'moderationPrefs' in v && isModPrefs(v.moderationPrefs) ) } function isModPrefs(v: any): v is ModerationPrefs { return v && typeof v === 'object' && 'labelers' in v } function migrateLegacyMutedWordsItems(items: AppBskyActorDefs.MutedWord[]) { return items.map((item) => ({ ...item, id: item.id || TID.nextStr(), })) } function matchMutedWord( existingWord: AppBskyActorDefs.MutedWord, newWord: AppBskyActorDefs.MutedWord, ): boolean { // id is undefined in legacy implementation const existingId = existingWord.id // prefer matching based on id const matchById = existingId && existingId === newWord.id // handle legacy case where id is not set const legacyMatchByValue = !existingId && existingWord.value === newWord.value return matchById || legacyMatchByValue } ================================================ FILE: packages/api/src/atp-agent.ts ================================================ import { getPdsEndpoint, isValidDidDoc } from '@atproto/common-web' import { ErrorResponseBody, Gettable, ResponseType, XRPCError, XrpcClient, errorResponseBody, } from '@atproto/xrpc' import { Agent } from './agent' import { ComAtprotoServerCreateAccount, ComAtprotoServerCreateSession, ComAtprotoServerGetSession, ComAtprotoServerNS, ComAtprotoServerRefreshSession, } from './client' import { schemas } from './client/lexicons' import { SessionManager } from './session-manager' import { AtpAgentLoginOpts, AtpPersistSessionHandler, AtpSessionData, } from './types' const ReadableStream = globalThis.ReadableStream as | typeof globalThis.ReadableStream | undefined export type AtpAgentOptions = { service: string | URL persistSession?: AtpPersistSessionHandler fetch?: typeof globalThis.fetch headers?: Iterable<[string, Gettable]> } /** * A wrapper around the {@link Agent} class that uses credential based session * management. This class also exposes most of the session management methods * directly. * * This class will be deprecated in the near future. Use {@link Agent} directly * with a {@link CredentialSession} instead: * * ```ts * const session = new CredentialSession({ * service: new URL('https://example.com'), * }) * * const agent = new Agent(session) * ``` */ export class AtpAgent extends Agent { readonly sessionManager: CredentialSession constructor(options: AtpAgentOptions | CredentialSession) { const sessionManager = options instanceof CredentialSession ? options : new CredentialSession( new URL(options.service), options.fetch, options.persistSession, ) super(sessionManager) // This assignment is already being done in the super constructor, but we // need to do it here to make TypeScript happy. this.sessionManager = sessionManager if (!(options instanceof CredentialSession) && options.headers) { for (const [key, value] of options.headers) { this.setHeader(key, value) } } } clone(): AtpAgent { return this.copyInto(new AtpAgent(this.sessionManager)) } get session() { return this.sessionManager.session } get hasSession() { return this.sessionManager.hasSession } get did() { return this.sessionManager.did } get serviceUrl() { return this.sessionManager.serviceUrl } get pdsUrl() { return this.sessionManager.pdsUrl } get dispatchUrl() { return this.sessionManager.dispatchUrl } /** @deprecated use {@link serviceUrl} instead */ get service() { return this.serviceUrl } get persistSession() { throw new Error( 'Cannot set persistSession directly. "persistSession" is defined through the constructor and will be invoked automatically when session data changes.', ) } set persistSession(v: unknown) { throw new Error( 'Cannot set persistSession directly. "persistSession" must be defined in the constructor and can no longer be changed.', ) } /** @deprecated use {@link AtpAgent.serviceUrl} instead */ getServiceUrl() { return this.serviceUrl } async resumeSession( session: AtpSessionData, ): Promise { return this.sessionManager.resumeSession(session) } async createAccount( data: ComAtprotoServerCreateAccount.InputSchema, opts?: ComAtprotoServerCreateAccount.CallOptions, ): Promise { return this.sessionManager.createAccount(data, opts) } async login( opts: AtpAgentLoginOpts, ): Promise { return this.sessionManager.login(opts) } async logout(): Promise { return this.sessionManager.logout() } } /** * Credentials (username / password) based session manager. Instances of this * class will typically be used as the session manager for an {@link AtpAgent}. * They can also be used with an {@link XrpcClient}, if you want to use you * own Lexicons. */ export class CredentialSession implements SessionManager { public pdsUrl?: URL // The PDS URL, driven by the did doc public session?: AtpSessionData public refreshSessionPromise?: Promise /** * Private {@link ComAtprotoServerNS} used to perform session management API * calls on the service endpoint. Calls performed by this agent will not be * authenticated using the user's session to allow proper manual configuration * of the headers when performing session management operations. */ protected server = new ComAtprotoServerNS( // Note that the use of the codegen "schemas" (to instantiate `this.api`), // as well as the use of `ComAtprotoServerNS` will cause this class to // reference (way) more code than it actually needs. It is not possible, // with the current state of the codegen, to generate a client that only // includes the methods that are actually used by this class. This is a // known limitation that should be addressed in a future version of the // codegen. new XrpcClient((url, init) => { return (0, this.fetch)(new URL(url, this.serviceUrl), init) }, schemas), ) constructor( public readonly serviceUrl: URL, public fetch = globalThis.fetch, protected readonly persistSession?: AtpPersistSessionHandler, ) {} get did() { return this.session?.did } get dispatchUrl() { return this.pdsUrl || this.serviceUrl } get hasSession() { return !!this.session } /** * Sets a WhatWG "fetch()" function to be used for making HTTP requests. */ setFetch(fetch = globalThis.fetch) { this.fetch = fetch } async fetchHandler(url: string, init?: RequestInit): Promise { // wait for any active session-refreshes to finish await this.refreshSessionPromise const initialUri = new URL(url, this.dispatchUrl) const initialReq = new Request(initialUri, init) const initialToken = this.session?.accessJwt if (!initialToken || initialReq.headers.has('authorization')) { return (0, this.fetch)(initialReq) } initialReq.headers.set('authorization', `Bearer ${initialToken}`) const initialRes = await (0, this.fetch)(initialReq) if (!this.session?.refreshJwt) { return initialRes } const isExpiredToken = initialRes.status === 401 || (await isErrorResponse(initialRes, [400], ['ExpiredToken'])) if (!isExpiredToken) { return initialRes } try { await this.refreshSession() } catch { return initialRes } if (init?.signal?.aborted) { return initialRes } // The stream was already consumed. We cannot retry the request. A solution // would be to tee() the input stream but that would bufferize the entire // stream in memory which can lead to memory starvation. Instead, we will // return the original response and let the calling code handle retries. if (ReadableStream && init?.body instanceof ReadableStream) { return initialRes } // Return initial "ExpiredToken" response if the session was not refreshed. const updatedToken = this.session?.accessJwt if (!updatedToken || updatedToken === initialToken) { return initialRes } // Make sure the initial request is cancelled to avoid leaking resources // (NodeJS 👀): https://undici.nodejs.org/#/?id=garbage-collection await initialRes.body?.cancel() // We need to re-compute the URI in case the PDS endpoint has changed const updatedUri = new URL(url, this.dispatchUrl) const updatedReq = new Request(updatedUri, init) updatedReq.headers.set('authorization', `Bearer ${updatedToken}`) return await (0, this.fetch)(updatedReq) } /** * Create a new account and hydrate its session in this agent. */ async createAccount( data: ComAtprotoServerCreateAccount.InputSchema, opts?: ComAtprotoServerCreateAccount.CallOptions, ): Promise { // Clear any existing session this.session = undefined this.refreshSessionPromise = undefined try { const res = await this.server.createAccount(data, opts) this.session = { accessJwt: res.data.accessJwt, refreshJwt: res.data.refreshJwt, handle: res.data.handle, did: res.data.did, email: data.email, emailConfirmed: false, emailAuthFactor: false, active: true, } this.persistSession?.('create', this.session) this._updateApiEndpoint(res.data.didDoc) return res } catch (e) { this.session = undefined this.persistSession?.('create-failed', undefined) throw e } } /** * Start a new session with this agent. */ async login( opts: AtpAgentLoginOpts, ): Promise { // Clear any existing session this.session = undefined this.refreshSessionPromise = undefined try { const res = await this.server.createSession({ identifier: opts.identifier, password: opts.password, authFactorToken: opts.authFactorToken, allowTakendown: opts.allowTakendown, }) if (this.session) { throw new Error('Concurrent login detected') } this.session = { accessJwt: res.data.accessJwt, refreshJwt: res.data.refreshJwt, handle: res.data.handle, did: res.data.did, email: res.data.email, emailConfirmed: res.data.emailConfirmed, emailAuthFactor: res.data.emailAuthFactor, active: res.data.active ?? true, status: res.data.status, } this._updateApiEndpoint(res.data.didDoc) this.persistSession?.('create', this.session) return res } catch (e) { this.session = undefined this.persistSession?.('create-failed', undefined) throw e } } async logout(): Promise { if (this.session) { try { await this.server.deleteSession(undefined, { headers: { authorization: `Bearer ${this.session.refreshJwt}`, }, }) } catch { // Ignore errors } finally { this.session = undefined this.persistSession?.('expired', undefined) } } } /** * Resume a pre-existing session with this agent. * * @note that a rejected promise from this method indicates a failure to * refresh the session after resuming it but does not indicate a failure to * set the session itself. In case of rejection, check the presence of * {@link CredentialSession.session} after calling this method to ensure the * session was set. */ async resumeSession( session: AtpSessionData, ): Promise { // Protect against multiple calls to resumeSession that would trigger a // refresh for the same session simultaneously. // Ideally, this check would be based on a session identifier, but since // we don't have one, we will just check the refresh token. if (session.refreshJwt !== this.session?.refreshJwt) { // Set the current session, and discard any pending refresh operation.. this.session = session this.refreshSessionPromise = undefined } // Ensure that the session is still valid by forcing a refresh. This will // also ensure that persistSession handler is called. const result = await this.refreshSession() // Fool-proofing: another concurrent operation may have replaced the session // while we were waiting for the refresh to complete. if (session.did !== this.session?.did) { throw new Error('DID mismatch on resumeSession') } return result } /** * Internal helper to refresh sessions * - Wraps the actual implementation in a promise-guard to ensure only * one refresh is attempted at a time. */ async refreshSession(): Promise { if (!this.session) { throw new Error('Unexpected state: no session to refresh') } // Do not refresh if we already have a refresh in progress if (this.refreshSessionPromise) return this.refreshSessionPromise const promise = this._refreshSessionInner().finally(() => { if (this.refreshSessionPromise === promise) { this.refreshSessionPromise = undefined } }) this.refreshSessionPromise = promise return promise } /** * Internal helper to refresh sessions (actual behavior) */ private async _refreshSessionInner(): Promise { const { session } = this // Should never happen if (!session) throw new Error('No session to refresh') try { const res = await this.server.refreshSession(undefined, { headers: { authorization: `Bearer ${session.refreshJwt}` }, }) const { data } = res // Something is very wrong if the DID changes during a refresh if (data.did !== session.did) { throw new XRPCError( ResponseType.InvalidRequest, 'Invalid session', 'InvalidDID', ) } // Historically, refreshSession did not return all the fields from // getSession. In particular, email, emailConfirmed and emailAuthFactor // were missing. Similarly, some servers might not return the didDoc in // refreshSession. We fetch them via getSession if missing, allowing to // ensure that we are always talking with the right PDS. if (data.emailConfirmed == null || data.didDoc == null) { try { const res = await this.server.getSession(undefined, { headers: { authorization: `Bearer ${data.accessJwt}` }, }) // Fool proofing (should always match) if (res.data.did === data.did) { Object.assign(data, res.data) } } catch { // Noop, we'll keep the current values we have } } // protect against concurrent session updates if (this.session !== session) { return Promise.reject(new Error('Concurrent session update detected')) } // succeeded, update the session this.session = { did: data.did, accessJwt: data.accessJwt, refreshJwt: data.refreshJwt, handle: data.handle ?? session.handle, email: data.email ?? session.email, emailConfirmed: data.emailConfirmed ?? session.emailConfirmed, emailAuthFactor: data.emailAuthFactor ?? session.emailAuthFactor, active: data.active ?? session.active ?? true, status: data.status, } this._updateApiEndpoint(res.data.didDoc) this.persistSession?.('update', this.session) return res } catch (err) { // protect against concurrent session updates if (this.session === session) { if ( err instanceof XRPCError && (err.status === 401 || err.error === 'InvalidDID' || ['ExpiredToken', 'InvalidToken'].includes(err.error)) ) { // failed due to a bad refresh token this.session = undefined this.persistSession?.('expired', undefined) } else { // Assume the problem is transient and the session can be reused later. this.session = session this.persistSession?.('network-error', session) } } throw err } } /** * Helper to update the pds endpoint dynamically. * * The session methods (create, resume, refresh) may respond with the user's * did document which contains the user's canonical PDS endpoint. That endpoint * may differ from the endpoint used to contact the server. We capture that * PDS endpoint and update the client to use that given endpoint for future * requests. (This helps ensure smooth migrations between PDSes, especially * when the PDSes are operated by a single org.) */ private _updateApiEndpoint(didDoc: unknown) { const endpoint = isValidDidDoc(didDoc) ? getPdsEndpoint(didDoc) : undefined if (endpoint) { this.pdsUrl = new URL(endpoint) } else { // If the did doc is invalid (or missing), we clear the pdsUrl (should // never happen). This is fine if the auth server and PDS are the same // service, or if the auth server will proxy requests to the right PDS // (which is the case for Bluesky's "entryway"). this.pdsUrl = undefined } } } function isErrorObject(v: unknown): v is ErrorResponseBody { return errorResponseBody.safeParse(v).success } async function isErrorResponse( response: Response, status: number[], errorNames: string[], ): Promise { if (!status.includes(response.status)) return false // Some engines (react-native 👀) don't expose a response.body property... // if (!response.body) return false try { const json = await peekJson(response, 10 * 1024) return isErrorObject(json) && (errorNames as any[]).includes(json.error) } catch (err) { return false } } async function peekJson( response: Response, maxSize = Infinity, ): Promise { if (extractType(response) !== 'application/json') throw new Error('Not JSON') if (extractLength(response) > maxSize) throw new Error('Response too large') return response.clone().json() } function extractLength({ headers }: Response) { return headers.get('Content-Length') ? Number(headers.get('Content-Length')) : NaN } function extractType({ headers }: Response) { return headers.get('Content-Type')?.split(';')[0]?.trim() } ================================================ FILE: packages/api/src/bsky-agent.ts ================================================ import { AtpAgent } from './atp-agent' /** @deprecated use {@link AtpAgent} instead */ export class BskyAgent extends AtpAgent { clone(): this { if (this.constructor === BskyAgent) { const agent = new BskyAgent(this.sessionManager) return this.copyInto(agent as this) } // sub-classes should override this method throw new TypeError('Cannot clone a subclass of BskyAgent') } } ================================================ FILE: packages/api/src/client/index.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { XrpcClient, type FetchHandler, type FetchHandlerOptions, } from '@atproto/xrpc' import { schemas } from './lexicons.js' import { CID } from 'multiformats/cid' import { type OmitKey, type Un$Typed } from './util.js' import * as AppBskyActorDefs from './types/app/bsky/actor/defs.js' import * as AppBskyActorGetPreferences from './types/app/bsky/actor/getPreferences.js' import * as AppBskyActorGetProfile from './types/app/bsky/actor/getProfile.js' import * as AppBskyActorGetProfiles from './types/app/bsky/actor/getProfiles.js' import * as AppBskyActorGetSuggestions from './types/app/bsky/actor/getSuggestions.js' import * as AppBskyActorProfile from './types/app/bsky/actor/profile.js' import * as AppBskyActorPutPreferences from './types/app/bsky/actor/putPreferences.js' import * as AppBskyActorSearchActors from './types/app/bsky/actor/searchActors.js' import * as AppBskyActorSearchActorsTypeahead from './types/app/bsky/actor/searchActorsTypeahead.js' import * as AppBskyActorStatus from './types/app/bsky/actor/status.js' import * as AppBskyAgeassuranceBegin from './types/app/bsky/ageassurance/begin.js' import * as AppBskyAgeassuranceDefs from './types/app/bsky/ageassurance/defs.js' import * as AppBskyAgeassuranceGetConfig from './types/app/bsky/ageassurance/getConfig.js' import * as AppBskyAgeassuranceGetState from './types/app/bsky/ageassurance/getState.js' import * as AppBskyBookmarkCreateBookmark from './types/app/bsky/bookmark/createBookmark.js' import * as AppBskyBookmarkDefs from './types/app/bsky/bookmark/defs.js' import * as AppBskyBookmarkDeleteBookmark from './types/app/bsky/bookmark/deleteBookmark.js' import * as AppBskyBookmarkGetBookmarks from './types/app/bsky/bookmark/getBookmarks.js' import * as AppBskyContactDefs from './types/app/bsky/contact/defs.js' import * as AppBskyContactDismissMatch from './types/app/bsky/contact/dismissMatch.js' import * as AppBskyContactGetMatches from './types/app/bsky/contact/getMatches.js' import * as AppBskyContactGetSyncStatus from './types/app/bsky/contact/getSyncStatus.js' import * as AppBskyContactImportContacts from './types/app/bsky/contact/importContacts.js' import * as AppBskyContactRemoveData from './types/app/bsky/contact/removeData.js' import * as AppBskyContactSendNotification from './types/app/bsky/contact/sendNotification.js' import * as AppBskyContactStartPhoneVerification from './types/app/bsky/contact/startPhoneVerification.js' import * as AppBskyContactVerifyPhone from './types/app/bsky/contact/verifyPhone.js' import * as AppBskyDraftCreateDraft from './types/app/bsky/draft/createDraft.js' import * as AppBskyDraftDefs from './types/app/bsky/draft/defs.js' import * as AppBskyDraftDeleteDraft from './types/app/bsky/draft/deleteDraft.js' import * as AppBskyDraftGetDrafts from './types/app/bsky/draft/getDrafts.js' import * as AppBskyDraftUpdateDraft from './types/app/bsky/draft/updateDraft.js' import * as AppBskyEmbedDefs from './types/app/bsky/embed/defs.js' import * as AppBskyEmbedExternal from './types/app/bsky/embed/external.js' import * as AppBskyEmbedImages from './types/app/bsky/embed/images.js' import * as AppBskyEmbedRecord from './types/app/bsky/embed/record.js' import * as AppBskyEmbedRecordWithMedia from './types/app/bsky/embed/recordWithMedia.js' import * as AppBskyEmbedVideo from './types/app/bsky/embed/video.js' import * as AppBskyFeedDefs from './types/app/bsky/feed/defs.js' import * as AppBskyFeedDescribeFeedGenerator from './types/app/bsky/feed/describeFeedGenerator.js' import * as AppBskyFeedGenerator from './types/app/bsky/feed/generator.js' import * as AppBskyFeedGetActorFeeds from './types/app/bsky/feed/getActorFeeds.js' import * as AppBskyFeedGetActorLikes from './types/app/bsky/feed/getActorLikes.js' import * as AppBskyFeedGetAuthorFeed from './types/app/bsky/feed/getAuthorFeed.js' import * as AppBskyFeedGetFeed from './types/app/bsky/feed/getFeed.js' import * as AppBskyFeedGetFeedGenerator from './types/app/bsky/feed/getFeedGenerator.js' import * as AppBskyFeedGetFeedGenerators from './types/app/bsky/feed/getFeedGenerators.js' import * as AppBskyFeedGetFeedSkeleton from './types/app/bsky/feed/getFeedSkeleton.js' import * as AppBskyFeedGetLikes from './types/app/bsky/feed/getLikes.js' import * as AppBskyFeedGetListFeed from './types/app/bsky/feed/getListFeed.js' import * as AppBskyFeedGetPostThread from './types/app/bsky/feed/getPostThread.js' import * as AppBskyFeedGetPosts from './types/app/bsky/feed/getPosts.js' import * as AppBskyFeedGetQuotes from './types/app/bsky/feed/getQuotes.js' import * as AppBskyFeedGetRepostedBy from './types/app/bsky/feed/getRepostedBy.js' import * as AppBskyFeedGetSuggestedFeeds from './types/app/bsky/feed/getSuggestedFeeds.js' import * as AppBskyFeedGetTimeline from './types/app/bsky/feed/getTimeline.js' import * as AppBskyFeedLike from './types/app/bsky/feed/like.js' import * as AppBskyFeedPost from './types/app/bsky/feed/post.js' import * as AppBskyFeedPostgate from './types/app/bsky/feed/postgate.js' import * as AppBskyFeedRepost from './types/app/bsky/feed/repost.js' import * as AppBskyFeedSearchPosts from './types/app/bsky/feed/searchPosts.js' import * as AppBskyFeedSendInteractions from './types/app/bsky/feed/sendInteractions.js' import * as AppBskyFeedThreadgate from './types/app/bsky/feed/threadgate.js' import * as AppBskyGraphBlock from './types/app/bsky/graph/block.js' import * as AppBskyGraphDefs from './types/app/bsky/graph/defs.js' import * as AppBskyGraphFollow from './types/app/bsky/graph/follow.js' import * as AppBskyGraphGetActorStarterPacks from './types/app/bsky/graph/getActorStarterPacks.js' import * as AppBskyGraphGetBlocks from './types/app/bsky/graph/getBlocks.js' import * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers.js' import * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows.js' import * as AppBskyGraphGetKnownFollowers from './types/app/bsky/graph/getKnownFollowers.js' import * as AppBskyGraphGetList from './types/app/bsky/graph/getList.js' import * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks.js' import * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes.js' import * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists.js' import * as AppBskyGraphGetListsWithMembership from './types/app/bsky/graph/getListsWithMembership.js' import * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes.js' import * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships.js' import * as AppBskyGraphGetStarterPack from './types/app/bsky/graph/getStarterPack.js' import * as AppBskyGraphGetStarterPacks from './types/app/bsky/graph/getStarterPacks.js' import * as AppBskyGraphGetStarterPacksWithMembership from './types/app/bsky/graph/getStarterPacksWithMembership.js' import * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor.js' import * as AppBskyGraphList from './types/app/bsky/graph/list.js' import * as AppBskyGraphListblock from './types/app/bsky/graph/listblock.js' import * as AppBskyGraphListitem from './types/app/bsky/graph/listitem.js' import * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor.js' import * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList.js' import * as AppBskyGraphMuteThread from './types/app/bsky/graph/muteThread.js' import * as AppBskyGraphSearchStarterPacks from './types/app/bsky/graph/searchStarterPacks.js' import * as AppBskyGraphStarterpack from './types/app/bsky/graph/starterpack.js' import * as AppBskyGraphUnmuteActor from './types/app/bsky/graph/unmuteActor.js' import * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js' import * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js' import * as AppBskyGraphVerification from './types/app/bsky/graph/verification.js' import * as AppBskyLabelerDefs from './types/app/bsky/labeler/defs.js' import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js' import * as AppBskyLabelerService from './types/app/bsky/labeler/service.js' import * as AppBskyNotificationDeclaration from './types/app/bsky/notification/declaration.js' import * as AppBskyNotificationDefs from './types/app/bsky/notification/defs.js' import * as AppBskyNotificationGetPreferences from './types/app/bsky/notification/getPreferences.js' import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js' import * as AppBskyNotificationListActivitySubscriptions from './types/app/bsky/notification/listActivitySubscriptions.js' import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js' import * as AppBskyNotificationPutActivitySubscription from './types/app/bsky/notification/putActivitySubscription.js' import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js' import * as AppBskyNotificationPutPreferencesV2 from './types/app/bsky/notification/putPreferencesV2.js' import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js' import * as AppBskyNotificationUnregisterPush from './types/app/bsky/notification/unregisterPush.js' import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js' import * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet.js' import * as AppBskyUnspeccedDefs from './types/app/bsky/unspecced/defs.js' import * as AppBskyUnspeccedGetAgeAssuranceState from './types/app/bsky/unspecced/getAgeAssuranceState.js' import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js' import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacks from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js' import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js' import * as AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton from './types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.js' import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators.js' import * as AppBskyUnspeccedGetPostThreadOtherV2 from './types/app/bsky/unspecced/getPostThreadOtherV2.js' import * as AppBskyUnspeccedGetPostThreadV2 from './types/app/bsky/unspecced/getPostThreadV2.js' import * as AppBskyUnspeccedGetSuggestedFeeds from './types/app/bsky/unspecced/getSuggestedFeeds.js' import * as AppBskyUnspeccedGetSuggestedFeedsSkeleton from './types/app/bsky/unspecced/getSuggestedFeedsSkeleton.js' import * as AppBskyUnspeccedGetSuggestedOnboardingUsers from './types/app/bsky/unspecced/getSuggestedOnboardingUsers.js' import * as AppBskyUnspeccedGetSuggestedStarterPacks from './types/app/bsky/unspecced/getSuggestedStarterPacks.js' import * as AppBskyUnspeccedGetSuggestedStarterPacksSkeleton from './types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.js' import * as AppBskyUnspeccedGetSuggestedUsers from './types/app/bsky/unspecced/getSuggestedUsers.js' import * as AppBskyUnspeccedGetSuggestedUsersSkeleton from './types/app/bsky/unspecced/getSuggestedUsersSkeleton.js' import * as AppBskyUnspeccedGetSuggestionsSkeleton from './types/app/bsky/unspecced/getSuggestionsSkeleton.js' import * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions.js' import * as AppBskyUnspeccedGetTrendingTopics from './types/app/bsky/unspecced/getTrendingTopics.js' import * as AppBskyUnspeccedGetTrends from './types/app/bsky/unspecced/getTrends.js' import * as AppBskyUnspeccedGetTrendsSkeleton from './types/app/bsky/unspecced/getTrendsSkeleton.js' import * as AppBskyUnspeccedInitAgeAssurance from './types/app/bsky/unspecced/initAgeAssurance.js' import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton.js' import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton.js' import * as AppBskyUnspeccedSearchStarterPacksSkeleton from './types/app/bsky/unspecced/searchStarterPacksSkeleton.js' import * as AppBskyVideoDefs from './types/app/bsky/video/defs.js' import * as AppBskyVideoGetJobStatus from './types/app/bsky/video/getJobStatus.js' import * as AppBskyVideoGetUploadLimits from './types/app/bsky/video/getUploadLimits.js' import * as AppBskyVideoUploadVideo from './types/app/bsky/video/uploadVideo.js' import * as ChatBskyActorDeclaration from './types/chat/bsky/actor/declaration.js' import * as ChatBskyActorDefs from './types/chat/bsky/actor/defs.js' import * as ChatBskyActorDeleteAccount from './types/chat/bsky/actor/deleteAccount.js' import * as ChatBskyActorExportAccountData from './types/chat/bsky/actor/exportAccountData.js' import * as ChatBskyConvoAcceptConvo from './types/chat/bsky/convo/acceptConvo.js' import * as ChatBskyConvoAddReaction from './types/chat/bsky/convo/addReaction.js' import * as ChatBskyConvoDefs from './types/chat/bsky/convo/defs.js' import * as ChatBskyConvoDeleteMessageForSelf from './types/chat/bsky/convo/deleteMessageForSelf.js' import * as ChatBskyConvoGetConvo from './types/chat/bsky/convo/getConvo.js' import * as ChatBskyConvoGetConvoAvailability from './types/chat/bsky/convo/getConvoAvailability.js' import * as ChatBskyConvoGetConvoForMembers from './types/chat/bsky/convo/getConvoForMembers.js' import * as ChatBskyConvoGetLog from './types/chat/bsky/convo/getLog.js' import * as ChatBskyConvoGetMessages from './types/chat/bsky/convo/getMessages.js' import * as ChatBskyConvoLeaveConvo from './types/chat/bsky/convo/leaveConvo.js' import * as ChatBskyConvoListConvos from './types/chat/bsky/convo/listConvos.js' import * as ChatBskyConvoMuteConvo from './types/chat/bsky/convo/muteConvo.js' import * as ChatBskyConvoRemoveReaction from './types/chat/bsky/convo/removeReaction.js' import * as ChatBskyConvoSendMessage from './types/chat/bsky/convo/sendMessage.js' import * as ChatBskyConvoSendMessageBatch from './types/chat/bsky/convo/sendMessageBatch.js' import * as ChatBskyConvoUnmuteConvo from './types/chat/bsky/convo/unmuteConvo.js' import * as ChatBskyConvoUpdateAllRead from './types/chat/bsky/convo/updateAllRead.js' import * as ChatBskyConvoUpdateRead from './types/chat/bsky/convo/updateRead.js' import * as ChatBskyModerationGetActorMetadata from './types/chat/bsky/moderation/getActorMetadata.js' import * as ChatBskyModerationGetMessageContext from './types/chat/bsky/moderation/getMessageContext.js' import * as ChatBskyModerationUpdateActorAccess from './types/chat/bsky/moderation/updateActorAccess.js' import * as ComAtprotoAdminDefs from './types/com/atproto/admin/defs.js' import * as ComAtprotoAdminDeleteAccount from './types/com/atproto/admin/deleteAccount.js' import * as ComAtprotoAdminDisableAccountInvites from './types/com/atproto/admin/disableAccountInvites.js' import * as ComAtprotoAdminDisableInviteCodes from './types/com/atproto/admin/disableInviteCodes.js' import * as ComAtprotoAdminEnableAccountInvites from './types/com/atproto/admin/enableAccountInvites.js' import * as ComAtprotoAdminGetAccountInfo from './types/com/atproto/admin/getAccountInfo.js' import * as ComAtprotoAdminGetAccountInfos from './types/com/atproto/admin/getAccountInfos.js' import * as ComAtprotoAdminGetInviteCodes from './types/com/atproto/admin/getInviteCodes.js' import * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus.js' import * as ComAtprotoAdminSearchAccounts from './types/com/atproto/admin/searchAccounts.js' import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail.js' import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail.js' import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle.js' import * as ComAtprotoAdminUpdateAccountPassword from './types/com/atproto/admin/updateAccountPassword.js' import * as ComAtprotoAdminUpdateAccountSigningKey from './types/com/atproto/admin/updateAccountSigningKey.js' import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus.js' import * as ComAtprotoIdentityDefs from './types/com/atproto/identity/defs.js' import * as ComAtprotoIdentityGetRecommendedDidCredentials from './types/com/atproto/identity/getRecommendedDidCredentials.js' import * as ComAtprotoIdentityRefreshIdentity from './types/com/atproto/identity/refreshIdentity.js' import * as ComAtprotoIdentityRequestPlcOperationSignature from './types/com/atproto/identity/requestPlcOperationSignature.js' import * as ComAtprotoIdentityResolveDid from './types/com/atproto/identity/resolveDid.js' import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle.js' import * as ComAtprotoIdentityResolveIdentity from './types/com/atproto/identity/resolveIdentity.js' import * as ComAtprotoIdentitySignPlcOperation from './types/com/atproto/identity/signPlcOperation.js' import * as ComAtprotoIdentitySubmitPlcOperation from './types/com/atproto/identity/submitPlcOperation.js' import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle.js' import * as ComAtprotoLabelDefs from './types/com/atproto/label/defs.js' import * as ComAtprotoLabelQueryLabels from './types/com/atproto/label/queryLabels.js' import * as ComAtprotoLabelSubscribeLabels from './types/com/atproto/label/subscribeLabels.js' import * as ComAtprotoLexiconResolveLexicon from './types/com/atproto/lexicon/resolveLexicon.js' import * as ComAtprotoLexiconSchema from './types/com/atproto/lexicon/schema.js' import * as ComAtprotoModerationCreateReport from './types/com/atproto/moderation/createReport.js' import * as ComAtprotoModerationDefs from './types/com/atproto/moderation/defs.js' import * as ComAtprotoRepoApplyWrites from './types/com/atproto/repo/applyWrites.js' import * as ComAtprotoRepoCreateRecord from './types/com/atproto/repo/createRecord.js' import * as ComAtprotoRepoDefs from './types/com/atproto/repo/defs.js' import * as ComAtprotoRepoDeleteRecord from './types/com/atproto/repo/deleteRecord.js' import * as ComAtprotoRepoDescribeRepo from './types/com/atproto/repo/describeRepo.js' import * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord.js' import * as ComAtprotoRepoImportRepo from './types/com/atproto/repo/importRepo.js' import * as ComAtprotoRepoListMissingBlobs from './types/com/atproto/repo/listMissingBlobs.js' import * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords.js' import * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord.js' import * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef.js' import * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob.js' import * as ComAtprotoServerActivateAccount from './types/com/atproto/server/activateAccount.js' import * as ComAtprotoServerCheckAccountStatus from './types/com/atproto/server/checkAccountStatus.js' import * as ComAtprotoServerConfirmEmail from './types/com/atproto/server/confirmEmail.js' import * as ComAtprotoServerCreateAccount from './types/com/atproto/server/createAccount.js' import * as ComAtprotoServerCreateAppPassword from './types/com/atproto/server/createAppPassword.js' import * as ComAtprotoServerCreateInviteCode from './types/com/atproto/server/createInviteCode.js' import * as ComAtprotoServerCreateInviteCodes from './types/com/atproto/server/createInviteCodes.js' import * as ComAtprotoServerCreateSession from './types/com/atproto/server/createSession.js' import * as ComAtprotoServerDeactivateAccount from './types/com/atproto/server/deactivateAccount.js' import * as ComAtprotoServerDefs from './types/com/atproto/server/defs.js' import * as ComAtprotoServerDeleteAccount from './types/com/atproto/server/deleteAccount.js' import * as ComAtprotoServerDeleteSession from './types/com/atproto/server/deleteSession.js' import * as ComAtprotoServerDescribeServer from './types/com/atproto/server/describeServer.js' import * as ComAtprotoServerGetAccountInviteCodes from './types/com/atproto/server/getAccountInviteCodes.js' import * as ComAtprotoServerGetServiceAuth from './types/com/atproto/server/getServiceAuth.js' import * as ComAtprotoServerGetSession from './types/com/atproto/server/getSession.js' import * as ComAtprotoServerListAppPasswords from './types/com/atproto/server/listAppPasswords.js' import * as ComAtprotoServerRefreshSession from './types/com/atproto/server/refreshSession.js' import * as ComAtprotoServerRequestAccountDelete from './types/com/atproto/server/requestAccountDelete.js' import * as ComAtprotoServerRequestEmailConfirmation from './types/com/atproto/server/requestEmailConfirmation.js' import * as ComAtprotoServerRequestEmailUpdate from './types/com/atproto/server/requestEmailUpdate.js' import * as ComAtprotoServerRequestPasswordReset from './types/com/atproto/server/requestPasswordReset.js' import * as ComAtprotoServerReserveSigningKey from './types/com/atproto/server/reserveSigningKey.js' import * as ComAtprotoServerResetPassword from './types/com/atproto/server/resetPassword.js' import * as ComAtprotoServerRevokeAppPassword from './types/com/atproto/server/revokeAppPassword.js' import * as ComAtprotoServerUpdateEmail from './types/com/atproto/server/updateEmail.js' import * as ComAtprotoSyncDefs from './types/com/atproto/sync/defs.js' import * as ComAtprotoSyncGetBlob from './types/com/atproto/sync/getBlob.js' import * as ComAtprotoSyncGetBlocks from './types/com/atproto/sync/getBlocks.js' import * as ComAtprotoSyncGetCheckout from './types/com/atproto/sync/getCheckout.js' import * as ComAtprotoSyncGetHead from './types/com/atproto/sync/getHead.js' import * as ComAtprotoSyncGetHostStatus from './types/com/atproto/sync/getHostStatus.js' import * as ComAtprotoSyncGetLatestCommit from './types/com/atproto/sync/getLatestCommit.js' import * as ComAtprotoSyncGetRecord from './types/com/atproto/sync/getRecord.js' import * as ComAtprotoSyncGetRepo from './types/com/atproto/sync/getRepo.js' import * as ComAtprotoSyncGetRepoStatus from './types/com/atproto/sync/getRepoStatus.js' import * as ComAtprotoSyncListBlobs from './types/com/atproto/sync/listBlobs.js' import * as ComAtprotoSyncListHosts from './types/com/atproto/sync/listHosts.js' import * as ComAtprotoSyncListRepos from './types/com/atproto/sync/listRepos.js' import * as ComAtprotoSyncListReposByCollection from './types/com/atproto/sync/listReposByCollection.js' import * as ComAtprotoSyncNotifyOfUpdate from './types/com/atproto/sync/notifyOfUpdate.js' import * as ComAtprotoSyncRequestCrawl from './types/com/atproto/sync/requestCrawl.js' import * as ComAtprotoSyncSubscribeRepos from './types/com/atproto/sync/subscribeRepos.js' import * as ComAtprotoTempAddReservedHandle from './types/com/atproto/temp/addReservedHandle.js' import * as ComAtprotoTempCheckHandleAvailability from './types/com/atproto/temp/checkHandleAvailability.js' import * as ComAtprotoTempCheckSignupQueue from './types/com/atproto/temp/checkSignupQueue.js' import * as ComAtprotoTempDereferenceScope from './types/com/atproto/temp/dereferenceScope.js' import * as ComAtprotoTempFetchLabels from './types/com/atproto/temp/fetchLabels.js' import * as ComAtprotoTempRequestPhoneVerification from './types/com/atproto/temp/requestPhoneVerification.js' import * as ComAtprotoTempRevokeAccountCredentials from './types/com/atproto/temp/revokeAccountCredentials.js' import * as ComGermnetworkDeclaration from './types/com/germnetwork/declaration.js' import * as ToolsOzoneCommunicationCreateTemplate from './types/tools/ozone/communication/createTemplate.js' import * as ToolsOzoneCommunicationDefs from './types/tools/ozone/communication/defs.js' import * as ToolsOzoneCommunicationDeleteTemplate from './types/tools/ozone/communication/deleteTemplate.js' import * as ToolsOzoneCommunicationListTemplates from './types/tools/ozone/communication/listTemplates.js' import * as ToolsOzoneCommunicationUpdateTemplate from './types/tools/ozone/communication/updateTemplate.js' import * as ToolsOzoneHostingGetAccountHistory from './types/tools/ozone/hosting/getAccountHistory.js' import * as ToolsOzoneModerationCancelScheduledActions from './types/tools/ozone/moderation/cancelScheduledActions.js' import * as ToolsOzoneModerationDefs from './types/tools/ozone/moderation/defs.js' import * as ToolsOzoneModerationEmitEvent from './types/tools/ozone/moderation/emitEvent.js' import * as ToolsOzoneModerationGetAccountTimeline from './types/tools/ozone/moderation/getAccountTimeline.js' import * as ToolsOzoneModerationGetEvent from './types/tools/ozone/moderation/getEvent.js' import * as ToolsOzoneModerationGetRecord from './types/tools/ozone/moderation/getRecord.js' import * as ToolsOzoneModerationGetRecords from './types/tools/ozone/moderation/getRecords.js' import * as ToolsOzoneModerationGetRepo from './types/tools/ozone/moderation/getRepo.js' import * as ToolsOzoneModerationGetReporterStats from './types/tools/ozone/moderation/getReporterStats.js' import * as ToolsOzoneModerationGetRepos from './types/tools/ozone/moderation/getRepos.js' import * as ToolsOzoneModerationGetSubjects from './types/tools/ozone/moderation/getSubjects.js' import * as ToolsOzoneModerationListScheduledActions from './types/tools/ozone/moderation/listScheduledActions.js' import * as ToolsOzoneModerationQueryEvents from './types/tools/ozone/moderation/queryEvents.js' import * as ToolsOzoneModerationQueryStatuses from './types/tools/ozone/moderation/queryStatuses.js' import * as ToolsOzoneModerationScheduleAction from './types/tools/ozone/moderation/scheduleAction.js' import * as ToolsOzoneModerationSearchRepos from './types/tools/ozone/moderation/searchRepos.js' import * as ToolsOzoneReportDefs from './types/tools/ozone/report/defs.js' import * as ToolsOzoneSafelinkAddRule from './types/tools/ozone/safelink/addRule.js' import * as ToolsOzoneSafelinkDefs from './types/tools/ozone/safelink/defs.js' import * as ToolsOzoneSafelinkQueryEvents from './types/tools/ozone/safelink/queryEvents.js' import * as ToolsOzoneSafelinkQueryRules from './types/tools/ozone/safelink/queryRules.js' import * as ToolsOzoneSafelinkRemoveRule from './types/tools/ozone/safelink/removeRule.js' import * as ToolsOzoneSafelinkUpdateRule from './types/tools/ozone/safelink/updateRule.js' import * as ToolsOzoneServerGetConfig from './types/tools/ozone/server/getConfig.js' import * as ToolsOzoneSetAddValues from './types/tools/ozone/set/addValues.js' import * as ToolsOzoneSetDefs from './types/tools/ozone/set/defs.js' import * as ToolsOzoneSetDeleteSet from './types/tools/ozone/set/deleteSet.js' import * as ToolsOzoneSetDeleteValues from './types/tools/ozone/set/deleteValues.js' import * as ToolsOzoneSetGetValues from './types/tools/ozone/set/getValues.js' import * as ToolsOzoneSetQuerySets from './types/tools/ozone/set/querySets.js' import * as ToolsOzoneSetUpsertSet from './types/tools/ozone/set/upsertSet.js' import * as ToolsOzoneSettingDefs from './types/tools/ozone/setting/defs.js' import * as ToolsOzoneSettingListOptions from './types/tools/ozone/setting/listOptions.js' import * as ToolsOzoneSettingRemoveOptions from './types/tools/ozone/setting/removeOptions.js' import * as ToolsOzoneSettingUpsertOption from './types/tools/ozone/setting/upsertOption.js' import * as ToolsOzoneSignatureDefs from './types/tools/ozone/signature/defs.js' import * as ToolsOzoneSignatureFindCorrelation from './types/tools/ozone/signature/findCorrelation.js' import * as ToolsOzoneSignatureFindRelatedAccounts from './types/tools/ozone/signature/findRelatedAccounts.js' import * as ToolsOzoneSignatureSearchAccounts from './types/tools/ozone/signature/searchAccounts.js' import * as ToolsOzoneTeamAddMember from './types/tools/ozone/team/addMember.js' import * as ToolsOzoneTeamDefs from './types/tools/ozone/team/defs.js' import * as ToolsOzoneTeamDeleteMember from './types/tools/ozone/team/deleteMember.js' import * as ToolsOzoneTeamListMembers from './types/tools/ozone/team/listMembers.js' import * as ToolsOzoneTeamUpdateMember from './types/tools/ozone/team/updateMember.js' import * as ToolsOzoneVerificationDefs from './types/tools/ozone/verification/defs.js' import * as ToolsOzoneVerificationGrantVerifications from './types/tools/ozone/verification/grantVerifications.js' import * as ToolsOzoneVerificationListVerifications from './types/tools/ozone/verification/listVerifications.js' import * as ToolsOzoneVerificationRevokeVerifications from './types/tools/ozone/verification/revokeVerifications.js' export * as AppBskyActorDefs from './types/app/bsky/actor/defs.js' export * as AppBskyActorGetPreferences from './types/app/bsky/actor/getPreferences.js' export * as AppBskyActorGetProfile from './types/app/bsky/actor/getProfile.js' export * as AppBskyActorGetProfiles from './types/app/bsky/actor/getProfiles.js' export * as AppBskyActorGetSuggestions from './types/app/bsky/actor/getSuggestions.js' export * as AppBskyActorProfile from './types/app/bsky/actor/profile.js' export * as AppBskyActorPutPreferences from './types/app/bsky/actor/putPreferences.js' export * as AppBskyActorSearchActors from './types/app/bsky/actor/searchActors.js' export * as AppBskyActorSearchActorsTypeahead from './types/app/bsky/actor/searchActorsTypeahead.js' export * as AppBskyActorStatus from './types/app/bsky/actor/status.js' export * as AppBskyAgeassuranceBegin from './types/app/bsky/ageassurance/begin.js' export * as AppBskyAgeassuranceDefs from './types/app/bsky/ageassurance/defs.js' export * as AppBskyAgeassuranceGetConfig from './types/app/bsky/ageassurance/getConfig.js' export * as AppBskyAgeassuranceGetState from './types/app/bsky/ageassurance/getState.js' export * as AppBskyBookmarkCreateBookmark from './types/app/bsky/bookmark/createBookmark.js' export * as AppBskyBookmarkDefs from './types/app/bsky/bookmark/defs.js' export * as AppBskyBookmarkDeleteBookmark from './types/app/bsky/bookmark/deleteBookmark.js' export * as AppBskyBookmarkGetBookmarks from './types/app/bsky/bookmark/getBookmarks.js' export * as AppBskyContactDefs from './types/app/bsky/contact/defs.js' export * as AppBskyContactDismissMatch from './types/app/bsky/contact/dismissMatch.js' export * as AppBskyContactGetMatches from './types/app/bsky/contact/getMatches.js' export * as AppBskyContactGetSyncStatus from './types/app/bsky/contact/getSyncStatus.js' export * as AppBskyContactImportContacts from './types/app/bsky/contact/importContacts.js' export * as AppBskyContactRemoveData from './types/app/bsky/contact/removeData.js' export * as AppBskyContactSendNotification from './types/app/bsky/contact/sendNotification.js' export * as AppBskyContactStartPhoneVerification from './types/app/bsky/contact/startPhoneVerification.js' export * as AppBskyContactVerifyPhone from './types/app/bsky/contact/verifyPhone.js' export * as AppBskyDraftCreateDraft from './types/app/bsky/draft/createDraft.js' export * as AppBskyDraftDefs from './types/app/bsky/draft/defs.js' export * as AppBskyDraftDeleteDraft from './types/app/bsky/draft/deleteDraft.js' export * as AppBskyDraftGetDrafts from './types/app/bsky/draft/getDrafts.js' export * as AppBskyDraftUpdateDraft from './types/app/bsky/draft/updateDraft.js' export * as AppBskyEmbedDefs from './types/app/bsky/embed/defs.js' export * as AppBskyEmbedExternal from './types/app/bsky/embed/external.js' export * as AppBskyEmbedImages from './types/app/bsky/embed/images.js' export * as AppBskyEmbedRecord from './types/app/bsky/embed/record.js' export * as AppBskyEmbedRecordWithMedia from './types/app/bsky/embed/recordWithMedia.js' export * as AppBskyEmbedVideo from './types/app/bsky/embed/video.js' export * as AppBskyFeedDefs from './types/app/bsky/feed/defs.js' export * as AppBskyFeedDescribeFeedGenerator from './types/app/bsky/feed/describeFeedGenerator.js' export * as AppBskyFeedGenerator from './types/app/bsky/feed/generator.js' export * as AppBskyFeedGetActorFeeds from './types/app/bsky/feed/getActorFeeds.js' export * as AppBskyFeedGetActorLikes from './types/app/bsky/feed/getActorLikes.js' export * as AppBskyFeedGetAuthorFeed from './types/app/bsky/feed/getAuthorFeed.js' export * as AppBskyFeedGetFeed from './types/app/bsky/feed/getFeed.js' export * as AppBskyFeedGetFeedGenerator from './types/app/bsky/feed/getFeedGenerator.js' export * as AppBskyFeedGetFeedGenerators from './types/app/bsky/feed/getFeedGenerators.js' export * as AppBskyFeedGetFeedSkeleton from './types/app/bsky/feed/getFeedSkeleton.js' export * as AppBskyFeedGetLikes from './types/app/bsky/feed/getLikes.js' export * as AppBskyFeedGetListFeed from './types/app/bsky/feed/getListFeed.js' export * as AppBskyFeedGetPostThread from './types/app/bsky/feed/getPostThread.js' export * as AppBskyFeedGetPosts from './types/app/bsky/feed/getPosts.js' export * as AppBskyFeedGetQuotes from './types/app/bsky/feed/getQuotes.js' export * as AppBskyFeedGetRepostedBy from './types/app/bsky/feed/getRepostedBy.js' export * as AppBskyFeedGetSuggestedFeeds from './types/app/bsky/feed/getSuggestedFeeds.js' export * as AppBskyFeedGetTimeline from './types/app/bsky/feed/getTimeline.js' export * as AppBskyFeedLike from './types/app/bsky/feed/like.js' export * as AppBskyFeedPost from './types/app/bsky/feed/post.js' export * as AppBskyFeedPostgate from './types/app/bsky/feed/postgate.js' export * as AppBskyFeedRepost from './types/app/bsky/feed/repost.js' export * as AppBskyFeedSearchPosts from './types/app/bsky/feed/searchPosts.js' export * as AppBskyFeedSendInteractions from './types/app/bsky/feed/sendInteractions.js' export * as AppBskyFeedThreadgate from './types/app/bsky/feed/threadgate.js' export * as AppBskyGraphBlock from './types/app/bsky/graph/block.js' export * as AppBskyGraphDefs from './types/app/bsky/graph/defs.js' export * as AppBskyGraphFollow from './types/app/bsky/graph/follow.js' export * as AppBskyGraphGetActorStarterPacks from './types/app/bsky/graph/getActorStarterPacks.js' export * as AppBskyGraphGetBlocks from './types/app/bsky/graph/getBlocks.js' export * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers.js' export * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows.js' export * as AppBskyGraphGetKnownFollowers from './types/app/bsky/graph/getKnownFollowers.js' export * as AppBskyGraphGetList from './types/app/bsky/graph/getList.js' export * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks.js' export * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes.js' export * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists.js' export * as AppBskyGraphGetListsWithMembership from './types/app/bsky/graph/getListsWithMembership.js' export * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes.js' export * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships.js' export * as AppBskyGraphGetStarterPack from './types/app/bsky/graph/getStarterPack.js' export * as AppBskyGraphGetStarterPacks from './types/app/bsky/graph/getStarterPacks.js' export * as AppBskyGraphGetStarterPacksWithMembership from './types/app/bsky/graph/getStarterPacksWithMembership.js' export * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor.js' export * as AppBskyGraphList from './types/app/bsky/graph/list.js' export * as AppBskyGraphListblock from './types/app/bsky/graph/listblock.js' export * as AppBskyGraphListitem from './types/app/bsky/graph/listitem.js' export * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor.js' export * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList.js' export * as AppBskyGraphMuteThread from './types/app/bsky/graph/muteThread.js' export * as AppBskyGraphSearchStarterPacks from './types/app/bsky/graph/searchStarterPacks.js' export * as AppBskyGraphStarterpack from './types/app/bsky/graph/starterpack.js' export * as AppBskyGraphUnmuteActor from './types/app/bsky/graph/unmuteActor.js' export * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js' export * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js' export * as AppBskyGraphVerification from './types/app/bsky/graph/verification.js' export * as AppBskyLabelerDefs from './types/app/bsky/labeler/defs.js' export * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js' export * as AppBskyLabelerService from './types/app/bsky/labeler/service.js' export * as AppBskyNotificationDeclaration from './types/app/bsky/notification/declaration.js' export * as AppBskyNotificationDefs from './types/app/bsky/notification/defs.js' export * as AppBskyNotificationGetPreferences from './types/app/bsky/notification/getPreferences.js' export * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js' export * as AppBskyNotificationListActivitySubscriptions from './types/app/bsky/notification/listActivitySubscriptions.js' export * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js' export * as AppBskyNotificationPutActivitySubscription from './types/app/bsky/notification/putActivitySubscription.js' export * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js' export * as AppBskyNotificationPutPreferencesV2 from './types/app/bsky/notification/putPreferencesV2.js' export * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js' export * as AppBskyNotificationUnregisterPush from './types/app/bsky/notification/unregisterPush.js' export * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js' export * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet.js' export * as AppBskyUnspeccedDefs from './types/app/bsky/unspecced/defs.js' export * as AppBskyUnspeccedGetAgeAssuranceState from './types/app/bsky/unspecced/getAgeAssuranceState.js' export * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js' export * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacks from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js' export * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js' export * as AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton from './types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.js' export * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators.js' export * as AppBskyUnspeccedGetPostThreadOtherV2 from './types/app/bsky/unspecced/getPostThreadOtherV2.js' export * as AppBskyUnspeccedGetPostThreadV2 from './types/app/bsky/unspecced/getPostThreadV2.js' export * as AppBskyUnspeccedGetSuggestedFeeds from './types/app/bsky/unspecced/getSuggestedFeeds.js' export * as AppBskyUnspeccedGetSuggestedFeedsSkeleton from './types/app/bsky/unspecced/getSuggestedFeedsSkeleton.js' export * as AppBskyUnspeccedGetSuggestedOnboardingUsers from './types/app/bsky/unspecced/getSuggestedOnboardingUsers.js' export * as AppBskyUnspeccedGetSuggestedStarterPacks from './types/app/bsky/unspecced/getSuggestedStarterPacks.js' export * as AppBskyUnspeccedGetSuggestedStarterPacksSkeleton from './types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.js' export * as AppBskyUnspeccedGetSuggestedUsers from './types/app/bsky/unspecced/getSuggestedUsers.js' export * as AppBskyUnspeccedGetSuggestedUsersSkeleton from './types/app/bsky/unspecced/getSuggestedUsersSkeleton.js' export * as AppBskyUnspeccedGetSuggestionsSkeleton from './types/app/bsky/unspecced/getSuggestionsSkeleton.js' export * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions.js' export * as AppBskyUnspeccedGetTrendingTopics from './types/app/bsky/unspecced/getTrendingTopics.js' export * as AppBskyUnspeccedGetTrends from './types/app/bsky/unspecced/getTrends.js' export * as AppBskyUnspeccedGetTrendsSkeleton from './types/app/bsky/unspecced/getTrendsSkeleton.js' export * as AppBskyUnspeccedInitAgeAssurance from './types/app/bsky/unspecced/initAgeAssurance.js' export * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton.js' export * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton.js' export * as AppBskyUnspeccedSearchStarterPacksSkeleton from './types/app/bsky/unspecced/searchStarterPacksSkeleton.js' export * as AppBskyVideoDefs from './types/app/bsky/video/defs.js' export * as AppBskyVideoGetJobStatus from './types/app/bsky/video/getJobStatus.js' export * as AppBskyVideoGetUploadLimits from './types/app/bsky/video/getUploadLimits.js' export * as AppBskyVideoUploadVideo from './types/app/bsky/video/uploadVideo.js' export * as ChatBskyActorDeclaration from './types/chat/bsky/actor/declaration.js' export * as ChatBskyActorDefs from './types/chat/bsky/actor/defs.js' export * as ChatBskyActorDeleteAccount from './types/chat/bsky/actor/deleteAccount.js' export * as ChatBskyActorExportAccountData from './types/chat/bsky/actor/exportAccountData.js' export * as ChatBskyConvoAcceptConvo from './types/chat/bsky/convo/acceptConvo.js' export * as ChatBskyConvoAddReaction from './types/chat/bsky/convo/addReaction.js' export * as ChatBskyConvoDefs from './types/chat/bsky/convo/defs.js' export * as ChatBskyConvoDeleteMessageForSelf from './types/chat/bsky/convo/deleteMessageForSelf.js' export * as ChatBskyConvoGetConvo from './types/chat/bsky/convo/getConvo.js' export * as ChatBskyConvoGetConvoAvailability from './types/chat/bsky/convo/getConvoAvailability.js' export * as ChatBskyConvoGetConvoForMembers from './types/chat/bsky/convo/getConvoForMembers.js' export * as ChatBskyConvoGetLog from './types/chat/bsky/convo/getLog.js' export * as ChatBskyConvoGetMessages from './types/chat/bsky/convo/getMessages.js' export * as ChatBskyConvoLeaveConvo from './types/chat/bsky/convo/leaveConvo.js' export * as ChatBskyConvoListConvos from './types/chat/bsky/convo/listConvos.js' export * as ChatBskyConvoMuteConvo from './types/chat/bsky/convo/muteConvo.js' export * as ChatBskyConvoRemoveReaction from './types/chat/bsky/convo/removeReaction.js' export * as ChatBskyConvoSendMessage from './types/chat/bsky/convo/sendMessage.js' export * as ChatBskyConvoSendMessageBatch from './types/chat/bsky/convo/sendMessageBatch.js' export * as ChatBskyConvoUnmuteConvo from './types/chat/bsky/convo/unmuteConvo.js' export * as ChatBskyConvoUpdateAllRead from './types/chat/bsky/convo/updateAllRead.js' export * as ChatBskyConvoUpdateRead from './types/chat/bsky/convo/updateRead.js' export * as ChatBskyModerationGetActorMetadata from './types/chat/bsky/moderation/getActorMetadata.js' export * as ChatBskyModerationGetMessageContext from './types/chat/bsky/moderation/getMessageContext.js' export * as ChatBskyModerationUpdateActorAccess from './types/chat/bsky/moderation/updateActorAccess.js' export * as ComAtprotoAdminDefs from './types/com/atproto/admin/defs.js' export * as ComAtprotoAdminDeleteAccount from './types/com/atproto/admin/deleteAccount.js' export * as ComAtprotoAdminDisableAccountInvites from './types/com/atproto/admin/disableAccountInvites.js' export * as ComAtprotoAdminDisableInviteCodes from './types/com/atproto/admin/disableInviteCodes.js' export * as ComAtprotoAdminEnableAccountInvites from './types/com/atproto/admin/enableAccountInvites.js' export * as ComAtprotoAdminGetAccountInfo from './types/com/atproto/admin/getAccountInfo.js' export * as ComAtprotoAdminGetAccountInfos from './types/com/atproto/admin/getAccountInfos.js' export * as ComAtprotoAdminGetInviteCodes from './types/com/atproto/admin/getInviteCodes.js' export * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus.js' export * as ComAtprotoAdminSearchAccounts from './types/com/atproto/admin/searchAccounts.js' export * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail.js' export * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail.js' export * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle.js' export * as ComAtprotoAdminUpdateAccountPassword from './types/com/atproto/admin/updateAccountPassword.js' export * as ComAtprotoAdminUpdateAccountSigningKey from './types/com/atproto/admin/updateAccountSigningKey.js' export * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus.js' export * as ComAtprotoIdentityDefs from './types/com/atproto/identity/defs.js' export * as ComAtprotoIdentityGetRecommendedDidCredentials from './types/com/atproto/identity/getRecommendedDidCredentials.js' export * as ComAtprotoIdentityRefreshIdentity from './types/com/atproto/identity/refreshIdentity.js' export * as ComAtprotoIdentityRequestPlcOperationSignature from './types/com/atproto/identity/requestPlcOperationSignature.js' export * as ComAtprotoIdentityResolveDid from './types/com/atproto/identity/resolveDid.js' export * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle.js' export * as ComAtprotoIdentityResolveIdentity from './types/com/atproto/identity/resolveIdentity.js' export * as ComAtprotoIdentitySignPlcOperation from './types/com/atproto/identity/signPlcOperation.js' export * as ComAtprotoIdentitySubmitPlcOperation from './types/com/atproto/identity/submitPlcOperation.js' export * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle.js' export * as ComAtprotoLabelDefs from './types/com/atproto/label/defs.js' export * as ComAtprotoLabelQueryLabels from './types/com/atproto/label/queryLabels.js' export * as ComAtprotoLabelSubscribeLabels from './types/com/atproto/label/subscribeLabels.js' export * as ComAtprotoLexiconResolveLexicon from './types/com/atproto/lexicon/resolveLexicon.js' export * as ComAtprotoLexiconSchema from './types/com/atproto/lexicon/schema.js' export * as ComAtprotoModerationCreateReport from './types/com/atproto/moderation/createReport.js' export * as ComAtprotoModerationDefs from './types/com/atproto/moderation/defs.js' export * as ComAtprotoRepoApplyWrites from './types/com/atproto/repo/applyWrites.js' export * as ComAtprotoRepoCreateRecord from './types/com/atproto/repo/createRecord.js' export * as ComAtprotoRepoDefs from './types/com/atproto/repo/defs.js' export * as ComAtprotoRepoDeleteRecord from './types/com/atproto/repo/deleteRecord.js' export * as ComAtprotoRepoDescribeRepo from './types/com/atproto/repo/describeRepo.js' export * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord.js' export * as ComAtprotoRepoImportRepo from './types/com/atproto/repo/importRepo.js' export * as ComAtprotoRepoListMissingBlobs from './types/com/atproto/repo/listMissingBlobs.js' export * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords.js' export * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord.js' export * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef.js' export * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob.js' export * as ComAtprotoServerActivateAccount from './types/com/atproto/server/activateAccount.js' export * as ComAtprotoServerCheckAccountStatus from './types/com/atproto/server/checkAccountStatus.js' export * as ComAtprotoServerConfirmEmail from './types/com/atproto/server/confirmEmail.js' export * as ComAtprotoServerCreateAccount from './types/com/atproto/server/createAccount.js' export * as ComAtprotoServerCreateAppPassword from './types/com/atproto/server/createAppPassword.js' export * as ComAtprotoServerCreateInviteCode from './types/com/atproto/server/createInviteCode.js' export * as ComAtprotoServerCreateInviteCodes from './types/com/atproto/server/createInviteCodes.js' export * as ComAtprotoServerCreateSession from './types/com/atproto/server/createSession.js' export * as ComAtprotoServerDeactivateAccount from './types/com/atproto/server/deactivateAccount.js' export * as ComAtprotoServerDefs from './types/com/atproto/server/defs.js' export * as ComAtprotoServerDeleteAccount from './types/com/atproto/server/deleteAccount.js' export * as ComAtprotoServerDeleteSession from './types/com/atproto/server/deleteSession.js' export * as ComAtprotoServerDescribeServer from './types/com/atproto/server/describeServer.js' export * as ComAtprotoServerGetAccountInviteCodes from './types/com/atproto/server/getAccountInviteCodes.js' export * as ComAtprotoServerGetServiceAuth from './types/com/atproto/server/getServiceAuth.js' export * as ComAtprotoServerGetSession from './types/com/atproto/server/getSession.js' export * as ComAtprotoServerListAppPasswords from './types/com/atproto/server/listAppPasswords.js' export * as ComAtprotoServerRefreshSession from './types/com/atproto/server/refreshSession.js' export * as ComAtprotoServerRequestAccountDelete from './types/com/atproto/server/requestAccountDelete.js' export * as ComAtprotoServerRequestEmailConfirmation from './types/com/atproto/server/requestEmailConfirmation.js' export * as ComAtprotoServerRequestEmailUpdate from './types/com/atproto/server/requestEmailUpdate.js' export * as ComAtprotoServerRequestPasswordReset from './types/com/atproto/server/requestPasswordReset.js' export * as ComAtprotoServerReserveSigningKey from './types/com/atproto/server/reserveSigningKey.js' export * as ComAtprotoServerResetPassword from './types/com/atproto/server/resetPassword.js' export * as ComAtprotoServerRevokeAppPassword from './types/com/atproto/server/revokeAppPassword.js' export * as ComAtprotoServerUpdateEmail from './types/com/atproto/server/updateEmail.js' export * as ComAtprotoSyncDefs from './types/com/atproto/sync/defs.js' export * as ComAtprotoSyncGetBlob from './types/com/atproto/sync/getBlob.js' export * as ComAtprotoSyncGetBlocks from './types/com/atproto/sync/getBlocks.js' export * as ComAtprotoSyncGetCheckout from './types/com/atproto/sync/getCheckout.js' export * as ComAtprotoSyncGetHead from './types/com/atproto/sync/getHead.js' export * as ComAtprotoSyncGetHostStatus from './types/com/atproto/sync/getHostStatus.js' export * as ComAtprotoSyncGetLatestCommit from './types/com/atproto/sync/getLatestCommit.js' export * as ComAtprotoSyncGetRecord from './types/com/atproto/sync/getRecord.js' export * as ComAtprotoSyncGetRepo from './types/com/atproto/sync/getRepo.js' export * as ComAtprotoSyncGetRepoStatus from './types/com/atproto/sync/getRepoStatus.js' export * as ComAtprotoSyncListBlobs from './types/com/atproto/sync/listBlobs.js' export * as ComAtprotoSyncListHosts from './types/com/atproto/sync/listHosts.js' export * as ComAtprotoSyncListRepos from './types/com/atproto/sync/listRepos.js' export * as ComAtprotoSyncListReposByCollection from './types/com/atproto/sync/listReposByCollection.js' export * as ComAtprotoSyncNotifyOfUpdate from './types/com/atproto/sync/notifyOfUpdate.js' export * as ComAtprotoSyncRequestCrawl from './types/com/atproto/sync/requestCrawl.js' export * as ComAtprotoSyncSubscribeRepos from './types/com/atproto/sync/subscribeRepos.js' export * as ComAtprotoTempAddReservedHandle from './types/com/atproto/temp/addReservedHandle.js' export * as ComAtprotoTempCheckHandleAvailability from './types/com/atproto/temp/checkHandleAvailability.js' export * as ComAtprotoTempCheckSignupQueue from './types/com/atproto/temp/checkSignupQueue.js' export * as ComAtprotoTempDereferenceScope from './types/com/atproto/temp/dereferenceScope.js' export * as ComAtprotoTempFetchLabels from './types/com/atproto/temp/fetchLabels.js' export * as ComAtprotoTempRequestPhoneVerification from './types/com/atproto/temp/requestPhoneVerification.js' export * as ComAtprotoTempRevokeAccountCredentials from './types/com/atproto/temp/revokeAccountCredentials.js' export * as ComGermnetworkDeclaration from './types/com/germnetwork/declaration.js' export * as ToolsOzoneCommunicationCreateTemplate from './types/tools/ozone/communication/createTemplate.js' export * as ToolsOzoneCommunicationDefs from './types/tools/ozone/communication/defs.js' export * as ToolsOzoneCommunicationDeleteTemplate from './types/tools/ozone/communication/deleteTemplate.js' export * as ToolsOzoneCommunicationListTemplates from './types/tools/ozone/communication/listTemplates.js' export * as ToolsOzoneCommunicationUpdateTemplate from './types/tools/ozone/communication/updateTemplate.js' export * as ToolsOzoneHostingGetAccountHistory from './types/tools/ozone/hosting/getAccountHistory.js' export * as ToolsOzoneModerationCancelScheduledActions from './types/tools/ozone/moderation/cancelScheduledActions.js' export * as ToolsOzoneModerationDefs from './types/tools/ozone/moderation/defs.js' export * as ToolsOzoneModerationEmitEvent from './types/tools/ozone/moderation/emitEvent.js' export * as ToolsOzoneModerationGetAccountTimeline from './types/tools/ozone/moderation/getAccountTimeline.js' export * as ToolsOzoneModerationGetEvent from './types/tools/ozone/moderation/getEvent.js' export * as ToolsOzoneModerationGetRecord from './types/tools/ozone/moderation/getRecord.js' export * as ToolsOzoneModerationGetRecords from './types/tools/ozone/moderation/getRecords.js' export * as ToolsOzoneModerationGetRepo from './types/tools/ozone/moderation/getRepo.js' export * as ToolsOzoneModerationGetReporterStats from './types/tools/ozone/moderation/getReporterStats.js' export * as ToolsOzoneModerationGetRepos from './types/tools/ozone/moderation/getRepos.js' export * as ToolsOzoneModerationGetSubjects from './types/tools/ozone/moderation/getSubjects.js' export * as ToolsOzoneModerationListScheduledActions from './types/tools/ozone/moderation/listScheduledActions.js' export * as ToolsOzoneModerationQueryEvents from './types/tools/ozone/moderation/queryEvents.js' export * as ToolsOzoneModerationQueryStatuses from './types/tools/ozone/moderation/queryStatuses.js' export * as ToolsOzoneModerationScheduleAction from './types/tools/ozone/moderation/scheduleAction.js' export * as ToolsOzoneModerationSearchRepos from './types/tools/ozone/moderation/searchRepos.js' export * as ToolsOzoneReportDefs from './types/tools/ozone/report/defs.js' export * as ToolsOzoneSafelinkAddRule from './types/tools/ozone/safelink/addRule.js' export * as ToolsOzoneSafelinkDefs from './types/tools/ozone/safelink/defs.js' export * as ToolsOzoneSafelinkQueryEvents from './types/tools/ozone/safelink/queryEvents.js' export * as ToolsOzoneSafelinkQueryRules from './types/tools/ozone/safelink/queryRules.js' export * as ToolsOzoneSafelinkRemoveRule from './types/tools/ozone/safelink/removeRule.js' export * as ToolsOzoneSafelinkUpdateRule from './types/tools/ozone/safelink/updateRule.js' export * as ToolsOzoneServerGetConfig from './types/tools/ozone/server/getConfig.js' export * as ToolsOzoneSetAddValues from './types/tools/ozone/set/addValues.js' export * as ToolsOzoneSetDefs from './types/tools/ozone/set/defs.js' export * as ToolsOzoneSetDeleteSet from './types/tools/ozone/set/deleteSet.js' export * as ToolsOzoneSetDeleteValues from './types/tools/ozone/set/deleteValues.js' export * as ToolsOzoneSetGetValues from './types/tools/ozone/set/getValues.js' export * as ToolsOzoneSetQuerySets from './types/tools/ozone/set/querySets.js' export * as ToolsOzoneSetUpsertSet from './types/tools/ozone/set/upsertSet.js' export * as ToolsOzoneSettingDefs from './types/tools/ozone/setting/defs.js' export * as ToolsOzoneSettingListOptions from './types/tools/ozone/setting/listOptions.js' export * as ToolsOzoneSettingRemoveOptions from './types/tools/ozone/setting/removeOptions.js' export * as ToolsOzoneSettingUpsertOption from './types/tools/ozone/setting/upsertOption.js' export * as ToolsOzoneSignatureDefs from './types/tools/ozone/signature/defs.js' export * as ToolsOzoneSignatureFindCorrelation from './types/tools/ozone/signature/findCorrelation.js' export * as ToolsOzoneSignatureFindRelatedAccounts from './types/tools/ozone/signature/findRelatedAccounts.js' export * as ToolsOzoneSignatureSearchAccounts from './types/tools/ozone/signature/searchAccounts.js' export * as ToolsOzoneTeamAddMember from './types/tools/ozone/team/addMember.js' export * as ToolsOzoneTeamDefs from './types/tools/ozone/team/defs.js' export * as ToolsOzoneTeamDeleteMember from './types/tools/ozone/team/deleteMember.js' export * as ToolsOzoneTeamListMembers from './types/tools/ozone/team/listMembers.js' export * as ToolsOzoneTeamUpdateMember from './types/tools/ozone/team/updateMember.js' export * as ToolsOzoneVerificationDefs from './types/tools/ozone/verification/defs.js' export * as ToolsOzoneVerificationGrantVerifications from './types/tools/ozone/verification/grantVerifications.js' export * as ToolsOzoneVerificationListVerifications from './types/tools/ozone/verification/listVerifications.js' export * as ToolsOzoneVerificationRevokeVerifications from './types/tools/ozone/verification/revokeVerifications.js' export const APP_BSKY_ACTOR = { StatusLive: 'app.bsky.actor.status#live', } export const APP_BSKY_FEED = { DefsRequestLess: 'app.bsky.feed.defs#requestLess', DefsRequestMore: 'app.bsky.feed.defs#requestMore', DefsClickthroughItem: 'app.bsky.feed.defs#clickthroughItem', DefsClickthroughAuthor: 'app.bsky.feed.defs#clickthroughAuthor', DefsClickthroughReposter: 'app.bsky.feed.defs#clickthroughReposter', DefsClickthroughEmbed: 'app.bsky.feed.defs#clickthroughEmbed', DefsContentModeUnspecified: 'app.bsky.feed.defs#contentModeUnspecified', DefsContentModeVideo: 'app.bsky.feed.defs#contentModeVideo', DefsInteractionSeen: 'app.bsky.feed.defs#interactionSeen', DefsInteractionLike: 'app.bsky.feed.defs#interactionLike', DefsInteractionRepost: 'app.bsky.feed.defs#interactionRepost', DefsInteractionReply: 'app.bsky.feed.defs#interactionReply', DefsInteractionQuote: 'app.bsky.feed.defs#interactionQuote', DefsInteractionShare: 'app.bsky.feed.defs#interactionShare', } export const APP_BSKY_GRAPH = { DefsModlist: 'app.bsky.graph.defs#modlist', DefsCuratelist: 'app.bsky.graph.defs#curatelist', DefsReferencelist: 'app.bsky.graph.defs#referencelist', } export const COM_ATPROTO_MODERATION = { DefsReasonSpam: 'com.atproto.moderation.defs#reasonSpam', DefsReasonViolation: 'com.atproto.moderation.defs#reasonViolation', DefsReasonMisleading: 'com.atproto.moderation.defs#reasonMisleading', DefsReasonSexual: 'com.atproto.moderation.defs#reasonSexual', DefsReasonRude: 'com.atproto.moderation.defs#reasonRude', DefsReasonOther: 'com.atproto.moderation.defs#reasonOther', DefsReasonAppeal: 'com.atproto.moderation.defs#reasonAppeal', } export const TOOLS_OZONE_MODERATION = { DefsReviewOpen: 'tools.ozone.moderation.defs#reviewOpen', DefsReviewEscalated: 'tools.ozone.moderation.defs#reviewEscalated', DefsReviewClosed: 'tools.ozone.moderation.defs#reviewClosed', DefsReviewNone: 'tools.ozone.moderation.defs#reviewNone', DefsTimelineEventPlcCreate: 'tools.ozone.moderation.defs#timelineEventPlcCreate', DefsTimelineEventPlcOperation: 'tools.ozone.moderation.defs#timelineEventPlcOperation', DefsTimelineEventPlcTombstone: 'tools.ozone.moderation.defs#timelineEventPlcTombstone', } export const TOOLS_OZONE_REPORT = { DefsReasonAppeal: 'tools.ozone.report.defs#reasonAppeal', DefsReasonOther: 'tools.ozone.report.defs#reasonOther', DefsReasonViolenceAnimal: 'tools.ozone.report.defs#reasonViolenceAnimal', DefsReasonViolenceThreats: 'tools.ozone.report.defs#reasonViolenceThreats', DefsReasonViolenceGraphicContent: 'tools.ozone.report.defs#reasonViolenceGraphicContent', DefsReasonViolenceGlorification: 'tools.ozone.report.defs#reasonViolenceGlorification', DefsReasonViolenceExtremistContent: 'tools.ozone.report.defs#reasonViolenceExtremistContent', DefsReasonViolenceTrafficking: 'tools.ozone.report.defs#reasonViolenceTrafficking', DefsReasonViolenceOther: 'tools.ozone.report.defs#reasonViolenceOther', DefsReasonSexualAbuseContent: 'tools.ozone.report.defs#reasonSexualAbuseContent', DefsReasonSexualNCII: 'tools.ozone.report.defs#reasonSexualNCII', DefsReasonSexualDeepfake: 'tools.ozone.report.defs#reasonSexualDeepfake', DefsReasonSexualAnimal: 'tools.ozone.report.defs#reasonSexualAnimal', DefsReasonSexualUnlabeled: 'tools.ozone.report.defs#reasonSexualUnlabeled', DefsReasonSexualOther: 'tools.ozone.report.defs#reasonSexualOther', DefsReasonChildSafetyCSAM: 'tools.ozone.report.defs#reasonChildSafetyCSAM', DefsReasonChildSafetyGroom: 'tools.ozone.report.defs#reasonChildSafetyGroom', DefsReasonChildSafetyPrivacy: 'tools.ozone.report.defs#reasonChildSafetyPrivacy', DefsReasonChildSafetyHarassment: 'tools.ozone.report.defs#reasonChildSafetyHarassment', DefsReasonChildSafetyOther: 'tools.ozone.report.defs#reasonChildSafetyOther', DefsReasonHarassmentTroll: 'tools.ozone.report.defs#reasonHarassmentTroll', DefsReasonHarassmentTargeted: 'tools.ozone.report.defs#reasonHarassmentTargeted', DefsReasonHarassmentHateSpeech: 'tools.ozone.report.defs#reasonHarassmentHateSpeech', DefsReasonHarassmentDoxxing: 'tools.ozone.report.defs#reasonHarassmentDoxxing', DefsReasonHarassmentOther: 'tools.ozone.report.defs#reasonHarassmentOther', DefsReasonMisleadingBot: 'tools.ozone.report.defs#reasonMisleadingBot', DefsReasonMisleadingImpersonation: 'tools.ozone.report.defs#reasonMisleadingImpersonation', DefsReasonMisleadingSpam: 'tools.ozone.report.defs#reasonMisleadingSpam', DefsReasonMisleadingScam: 'tools.ozone.report.defs#reasonMisleadingScam', DefsReasonMisleadingElections: 'tools.ozone.report.defs#reasonMisleadingElections', DefsReasonMisleadingOther: 'tools.ozone.report.defs#reasonMisleadingOther', DefsReasonRuleSiteSecurity: 'tools.ozone.report.defs#reasonRuleSiteSecurity', DefsReasonRuleProhibitedSales: 'tools.ozone.report.defs#reasonRuleProhibitedSales', DefsReasonRuleBanEvasion: 'tools.ozone.report.defs#reasonRuleBanEvasion', DefsReasonRuleOther: 'tools.ozone.report.defs#reasonRuleOther', DefsReasonSelfHarmContent: 'tools.ozone.report.defs#reasonSelfHarmContent', DefsReasonSelfHarmED: 'tools.ozone.report.defs#reasonSelfHarmED', DefsReasonSelfHarmStunts: 'tools.ozone.report.defs#reasonSelfHarmStunts', DefsReasonSelfHarmSubstances: 'tools.ozone.report.defs#reasonSelfHarmSubstances', DefsReasonSelfHarmOther: 'tools.ozone.report.defs#reasonSelfHarmOther', } export const TOOLS_OZONE_TEAM = { DefsRoleAdmin: 'tools.ozone.team.defs#roleAdmin', DefsRoleModerator: 'tools.ozone.team.defs#roleModerator', DefsRoleTriage: 'tools.ozone.team.defs#roleTriage', DefsRoleVerifier: 'tools.ozone.team.defs#roleVerifier', } export class AtpBaseClient extends XrpcClient { app: AppNS chat: ChatNS com: ComNS tools: ToolsNS constructor(options: FetchHandler | FetchHandlerOptions) { super(options, schemas) this.app = new AppNS(this) this.chat = new ChatNS(this) this.com = new ComNS(this) this.tools = new ToolsNS(this) } /** @deprecated use `this` instead */ get xrpc(): XrpcClient { return this } } export class AppNS { _client: XrpcClient bsky: AppBskyNS constructor(client: XrpcClient) { this._client = client this.bsky = new AppBskyNS(client) } } export class AppBskyNS { _client: XrpcClient actor: AppBskyActorNS ageassurance: AppBskyAgeassuranceNS bookmark: AppBskyBookmarkNS contact: AppBskyContactNS draft: AppBskyDraftNS embed: AppBskyEmbedNS feed: AppBskyFeedNS graph: AppBskyGraphNS labeler: AppBskyLabelerNS notification: AppBskyNotificationNS richtext: AppBskyRichtextNS unspecced: AppBskyUnspeccedNS video: AppBskyVideoNS constructor(client: XrpcClient) { this._client = client this.actor = new AppBskyActorNS(client) this.ageassurance = new AppBskyAgeassuranceNS(client) this.bookmark = new AppBskyBookmarkNS(client) this.contact = new AppBskyContactNS(client) this.draft = new AppBskyDraftNS(client) this.embed = new AppBskyEmbedNS(client) this.feed = new AppBskyFeedNS(client) this.graph = new AppBskyGraphNS(client) this.labeler = new AppBskyLabelerNS(client) this.notification = new AppBskyNotificationNS(client) this.richtext = new AppBskyRichtextNS(client) this.unspecced = new AppBskyUnspeccedNS(client) this.video = new AppBskyVideoNS(client) } } export class AppBskyActorNS { _client: XrpcClient profile: AppBskyActorProfileRecord status: AppBskyActorStatusRecord constructor(client: XrpcClient) { this._client = client this.profile = new AppBskyActorProfileRecord(client) this.status = new AppBskyActorStatusRecord(client) } getPreferences( params?: AppBskyActorGetPreferences.QueryParams, opts?: AppBskyActorGetPreferences.CallOptions, ): Promise { return this._client.call( 'app.bsky.actor.getPreferences', params, undefined, opts, ) } getProfile( params?: AppBskyActorGetProfile.QueryParams, opts?: AppBskyActorGetProfile.CallOptions, ): Promise { return this._client.call( 'app.bsky.actor.getProfile', params, undefined, opts, ) } getProfiles( params?: AppBskyActorGetProfiles.QueryParams, opts?: AppBskyActorGetProfiles.CallOptions, ): Promise { return this._client.call( 'app.bsky.actor.getProfiles', params, undefined, opts, ) } getSuggestions( params?: AppBskyActorGetSuggestions.QueryParams, opts?: AppBskyActorGetSuggestions.CallOptions, ): Promise { return this._client.call( 'app.bsky.actor.getSuggestions', params, undefined, opts, ) } putPreferences( data?: AppBskyActorPutPreferences.InputSchema, opts?: AppBskyActorPutPreferences.CallOptions, ): Promise { return this._client.call( 'app.bsky.actor.putPreferences', opts?.qp, data, opts, ) } searchActors( params?: AppBskyActorSearchActors.QueryParams, opts?: AppBskyActorSearchActors.CallOptions, ): Promise { return this._client.call( 'app.bsky.actor.searchActors', params, undefined, opts, ) } searchActorsTypeahead( params?: AppBskyActorSearchActorsTypeahead.QueryParams, opts?: AppBskyActorSearchActorsTypeahead.CallOptions, ): Promise { return this._client.call( 'app.bsky.actor.searchActorsTypeahead', params, undefined, opts, ) } } export class AppBskyActorProfileRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyActorProfile.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.actor.profile', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyActorProfile.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.actor.profile', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.actor.profile' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, rkey: 'self', ...params, record: { ...record, $type: collection }, }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.actor.profile' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.actor.profile', ...params }, { headers }, ) } } export class AppBskyActorStatusRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyActorStatus.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.actor.status', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyActorStatus.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.actor.status', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.actor.status' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, rkey: 'self', ...params, record: { ...record, $type: collection }, }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.actor.status' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.actor.status', ...params }, { headers }, ) } } export class AppBskyAgeassuranceNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } begin( data?: AppBskyAgeassuranceBegin.InputSchema, opts?: AppBskyAgeassuranceBegin.CallOptions, ): Promise { return this._client .call('app.bsky.ageassurance.begin', opts?.qp, data, opts) .catch((e) => { throw AppBskyAgeassuranceBegin.toKnownErr(e) }) } getConfig( params?: AppBskyAgeassuranceGetConfig.QueryParams, opts?: AppBskyAgeassuranceGetConfig.CallOptions, ): Promise { return this._client.call( 'app.bsky.ageassurance.getConfig', params, undefined, opts, ) } getState( params?: AppBskyAgeassuranceGetState.QueryParams, opts?: AppBskyAgeassuranceGetState.CallOptions, ): Promise { return this._client.call( 'app.bsky.ageassurance.getState', params, undefined, opts, ) } } export class AppBskyBookmarkNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } createBookmark( data?: AppBskyBookmarkCreateBookmark.InputSchema, opts?: AppBskyBookmarkCreateBookmark.CallOptions, ): Promise { return this._client .call('app.bsky.bookmark.createBookmark', opts?.qp, data, opts) .catch((e) => { throw AppBskyBookmarkCreateBookmark.toKnownErr(e) }) } deleteBookmark( data?: AppBskyBookmarkDeleteBookmark.InputSchema, opts?: AppBskyBookmarkDeleteBookmark.CallOptions, ): Promise { return this._client .call('app.bsky.bookmark.deleteBookmark', opts?.qp, data, opts) .catch((e) => { throw AppBskyBookmarkDeleteBookmark.toKnownErr(e) }) } getBookmarks( params?: AppBskyBookmarkGetBookmarks.QueryParams, opts?: AppBskyBookmarkGetBookmarks.CallOptions, ): Promise { return this._client.call( 'app.bsky.bookmark.getBookmarks', params, undefined, opts, ) } } export class AppBskyContactNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } dismissMatch( data?: AppBskyContactDismissMatch.InputSchema, opts?: AppBskyContactDismissMatch.CallOptions, ): Promise { return this._client .call('app.bsky.contact.dismissMatch', opts?.qp, data, opts) .catch((e) => { throw AppBskyContactDismissMatch.toKnownErr(e) }) } getMatches( params?: AppBskyContactGetMatches.QueryParams, opts?: AppBskyContactGetMatches.CallOptions, ): Promise { return this._client .call('app.bsky.contact.getMatches', params, undefined, opts) .catch((e) => { throw AppBskyContactGetMatches.toKnownErr(e) }) } getSyncStatus( params?: AppBskyContactGetSyncStatus.QueryParams, opts?: AppBskyContactGetSyncStatus.CallOptions, ): Promise { return this._client .call('app.bsky.contact.getSyncStatus', params, undefined, opts) .catch((e) => { throw AppBskyContactGetSyncStatus.toKnownErr(e) }) } importContacts( data?: AppBskyContactImportContacts.InputSchema, opts?: AppBskyContactImportContacts.CallOptions, ): Promise { return this._client .call('app.bsky.contact.importContacts', opts?.qp, data, opts) .catch((e) => { throw AppBskyContactImportContacts.toKnownErr(e) }) } removeData( data?: AppBskyContactRemoveData.InputSchema, opts?: AppBskyContactRemoveData.CallOptions, ): Promise { return this._client .call('app.bsky.contact.removeData', opts?.qp, data, opts) .catch((e) => { throw AppBskyContactRemoveData.toKnownErr(e) }) } sendNotification( data?: AppBskyContactSendNotification.InputSchema, opts?: AppBskyContactSendNotification.CallOptions, ): Promise { return this._client.call( 'app.bsky.contact.sendNotification', opts?.qp, data, opts, ) } startPhoneVerification( data?: AppBskyContactStartPhoneVerification.InputSchema, opts?: AppBskyContactStartPhoneVerification.CallOptions, ): Promise { return this._client .call('app.bsky.contact.startPhoneVerification', opts?.qp, data, opts) .catch((e) => { throw AppBskyContactStartPhoneVerification.toKnownErr(e) }) } verifyPhone( data?: AppBskyContactVerifyPhone.InputSchema, opts?: AppBskyContactVerifyPhone.CallOptions, ): Promise { return this._client .call('app.bsky.contact.verifyPhone', opts?.qp, data, opts) .catch((e) => { throw AppBskyContactVerifyPhone.toKnownErr(e) }) } } export class AppBskyDraftNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } createDraft( data?: AppBskyDraftCreateDraft.InputSchema, opts?: AppBskyDraftCreateDraft.CallOptions, ): Promise { return this._client .call('app.bsky.draft.createDraft', opts?.qp, data, opts) .catch((e) => { throw AppBskyDraftCreateDraft.toKnownErr(e) }) } deleteDraft( data?: AppBskyDraftDeleteDraft.InputSchema, opts?: AppBskyDraftDeleteDraft.CallOptions, ): Promise { return this._client.call('app.bsky.draft.deleteDraft', opts?.qp, data, opts) } getDrafts( params?: AppBskyDraftGetDrafts.QueryParams, opts?: AppBskyDraftGetDrafts.CallOptions, ): Promise { return this._client.call( 'app.bsky.draft.getDrafts', params, undefined, opts, ) } updateDraft( data?: AppBskyDraftUpdateDraft.InputSchema, opts?: AppBskyDraftUpdateDraft.CallOptions, ): Promise { return this._client.call('app.bsky.draft.updateDraft', opts?.qp, data, opts) } } export class AppBskyEmbedNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } } export class AppBskyFeedNS { _client: XrpcClient generator: AppBskyFeedGeneratorRecord like: AppBskyFeedLikeRecord post: AppBskyFeedPostRecord postgate: AppBskyFeedPostgateRecord repost: AppBskyFeedRepostRecord threadgate: AppBskyFeedThreadgateRecord constructor(client: XrpcClient) { this._client = client this.generator = new AppBskyFeedGeneratorRecord(client) this.like = new AppBskyFeedLikeRecord(client) this.post = new AppBskyFeedPostRecord(client) this.postgate = new AppBskyFeedPostgateRecord(client) this.repost = new AppBskyFeedRepostRecord(client) this.threadgate = new AppBskyFeedThreadgateRecord(client) } describeFeedGenerator( params?: AppBskyFeedDescribeFeedGenerator.QueryParams, opts?: AppBskyFeedDescribeFeedGenerator.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.describeFeedGenerator', params, undefined, opts, ) } getActorFeeds( params?: AppBskyFeedGetActorFeeds.QueryParams, opts?: AppBskyFeedGetActorFeeds.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.getActorFeeds', params, undefined, opts, ) } getActorLikes( params?: AppBskyFeedGetActorLikes.QueryParams, opts?: AppBskyFeedGetActorLikes.CallOptions, ): Promise { return this._client .call('app.bsky.feed.getActorLikes', params, undefined, opts) .catch((e) => { throw AppBskyFeedGetActorLikes.toKnownErr(e) }) } getAuthorFeed( params?: AppBskyFeedGetAuthorFeed.QueryParams, opts?: AppBskyFeedGetAuthorFeed.CallOptions, ): Promise { return this._client .call('app.bsky.feed.getAuthorFeed', params, undefined, opts) .catch((e) => { throw AppBskyFeedGetAuthorFeed.toKnownErr(e) }) } getFeed( params?: AppBskyFeedGetFeed.QueryParams, opts?: AppBskyFeedGetFeed.CallOptions, ): Promise { return this._client .call('app.bsky.feed.getFeed', params, undefined, opts) .catch((e) => { throw AppBskyFeedGetFeed.toKnownErr(e) }) } getFeedGenerator( params?: AppBskyFeedGetFeedGenerator.QueryParams, opts?: AppBskyFeedGetFeedGenerator.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.getFeedGenerator', params, undefined, opts, ) } getFeedGenerators( params?: AppBskyFeedGetFeedGenerators.QueryParams, opts?: AppBskyFeedGetFeedGenerators.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.getFeedGenerators', params, undefined, opts, ) } getFeedSkeleton( params?: AppBskyFeedGetFeedSkeleton.QueryParams, opts?: AppBskyFeedGetFeedSkeleton.CallOptions, ): Promise { return this._client .call('app.bsky.feed.getFeedSkeleton', params, undefined, opts) .catch((e) => { throw AppBskyFeedGetFeedSkeleton.toKnownErr(e) }) } getLikes( params?: AppBskyFeedGetLikes.QueryParams, opts?: AppBskyFeedGetLikes.CallOptions, ): Promise { return this._client.call('app.bsky.feed.getLikes', params, undefined, opts) } getListFeed( params?: AppBskyFeedGetListFeed.QueryParams, opts?: AppBskyFeedGetListFeed.CallOptions, ): Promise { return this._client .call('app.bsky.feed.getListFeed', params, undefined, opts) .catch((e) => { throw AppBskyFeedGetListFeed.toKnownErr(e) }) } getPostThread( params?: AppBskyFeedGetPostThread.QueryParams, opts?: AppBskyFeedGetPostThread.CallOptions, ): Promise { return this._client .call('app.bsky.feed.getPostThread', params, undefined, opts) .catch((e) => { throw AppBskyFeedGetPostThread.toKnownErr(e) }) } getPosts( params?: AppBskyFeedGetPosts.QueryParams, opts?: AppBskyFeedGetPosts.CallOptions, ): Promise { return this._client.call('app.bsky.feed.getPosts', params, undefined, opts) } getQuotes( params?: AppBskyFeedGetQuotes.QueryParams, opts?: AppBskyFeedGetQuotes.CallOptions, ): Promise { return this._client.call('app.bsky.feed.getQuotes', params, undefined, opts) } getRepostedBy( params?: AppBskyFeedGetRepostedBy.QueryParams, opts?: AppBskyFeedGetRepostedBy.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.getRepostedBy', params, undefined, opts, ) } getSuggestedFeeds( params?: AppBskyFeedGetSuggestedFeeds.QueryParams, opts?: AppBskyFeedGetSuggestedFeeds.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.getSuggestedFeeds', params, undefined, opts, ) } getTimeline( params?: AppBskyFeedGetTimeline.QueryParams, opts?: AppBskyFeedGetTimeline.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.getTimeline', params, undefined, opts, ) } searchPosts( params?: AppBskyFeedSearchPosts.QueryParams, opts?: AppBskyFeedSearchPosts.CallOptions, ): Promise { return this._client .call('app.bsky.feed.searchPosts', params, undefined, opts) .catch((e) => { throw AppBskyFeedSearchPosts.toKnownErr(e) }) } sendInteractions( data?: AppBskyFeedSendInteractions.InputSchema, opts?: AppBskyFeedSendInteractions.CallOptions, ): Promise { return this._client.call( 'app.bsky.feed.sendInteractions', opts?.qp, data, opts, ) } } export class AppBskyFeedGeneratorRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyFeedGenerator.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.feed.generator', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyFeedGenerator.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.feed.generator', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.generator' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.generator' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.feed.generator', ...params }, { headers }, ) } } export class AppBskyFeedLikeRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyFeedLike.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.feed.like', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyFeedLike.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.feed.like', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.like' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.like' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.feed.like', ...params }, { headers }, ) } } export class AppBskyFeedPostRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyFeedPost.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.feed.post', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyFeedPost.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.feed.post', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.post' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.post' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.feed.post', ...params }, { headers }, ) } } export class AppBskyFeedPostgateRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyFeedPostgate.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.feed.postgate', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyFeedPostgate.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.feed.postgate', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.postgate' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.postgate' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.feed.postgate', ...params }, { headers }, ) } } export class AppBskyFeedRepostRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyFeedRepost.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.feed.repost', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyFeedRepost.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.feed.repost', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.repost' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.repost' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.feed.repost', ...params }, { headers }, ) } } export class AppBskyFeedThreadgateRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyFeedThreadgate.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.feed.threadgate', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: AppBskyFeedThreadgate.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.feed.threadgate', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.threadgate' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.feed.threadgate' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.feed.threadgate', ...params }, { headers }, ) } } export class AppBskyGraphNS { _client: XrpcClient block: AppBskyGraphBlockRecord follow: AppBskyGraphFollowRecord list: AppBskyGraphListRecord listblock: AppBskyGraphListblockRecord listitem: AppBskyGraphListitemRecord starterpack: AppBskyGraphStarterpackRecord verification: AppBskyGraphVerificationRecord constructor(client: XrpcClient) { this._client = client this.block = new AppBskyGraphBlockRecord(client) this.follow = new AppBskyGraphFollowRecord(client) this.list = new AppBskyGraphListRecord(client) this.listblock = new AppBskyGraphListblockRecord(client) this.listitem = new AppBskyGraphListitemRecord(client) this.starterpack = new AppBskyGraphStarterpackRecord(client) this.verification = new AppBskyGraphVerificationRecord(client) } getActorStarterPacks( params?: AppBskyGraphGetActorStarterPacks.QueryParams, opts?: AppBskyGraphGetActorStarterPacks.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getActorStarterPacks', params, undefined, opts, ) } getBlocks( params?: AppBskyGraphGetBlocks.QueryParams, opts?: AppBskyGraphGetBlocks.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getBlocks', params, undefined, opts, ) } getFollowers( params?: AppBskyGraphGetFollowers.QueryParams, opts?: AppBskyGraphGetFollowers.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getFollowers', params, undefined, opts, ) } getFollows( params?: AppBskyGraphGetFollows.QueryParams, opts?: AppBskyGraphGetFollows.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getFollows', params, undefined, opts, ) } getKnownFollowers( params?: AppBskyGraphGetKnownFollowers.QueryParams, opts?: AppBskyGraphGetKnownFollowers.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getKnownFollowers', params, undefined, opts, ) } getList( params?: AppBskyGraphGetList.QueryParams, opts?: AppBskyGraphGetList.CallOptions, ): Promise { return this._client.call('app.bsky.graph.getList', params, undefined, opts) } getListBlocks( params?: AppBskyGraphGetListBlocks.QueryParams, opts?: AppBskyGraphGetListBlocks.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getListBlocks', params, undefined, opts, ) } getListMutes( params?: AppBskyGraphGetListMutes.QueryParams, opts?: AppBskyGraphGetListMutes.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getListMutes', params, undefined, opts, ) } getLists( params?: AppBskyGraphGetLists.QueryParams, opts?: AppBskyGraphGetLists.CallOptions, ): Promise { return this._client.call('app.bsky.graph.getLists', params, undefined, opts) } getListsWithMembership( params?: AppBskyGraphGetListsWithMembership.QueryParams, opts?: AppBskyGraphGetListsWithMembership.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getListsWithMembership', params, undefined, opts, ) } getMutes( params?: AppBskyGraphGetMutes.QueryParams, opts?: AppBskyGraphGetMutes.CallOptions, ): Promise { return this._client.call('app.bsky.graph.getMutes', params, undefined, opts) } getRelationships( params?: AppBskyGraphGetRelationships.QueryParams, opts?: AppBskyGraphGetRelationships.CallOptions, ): Promise { return this._client .call('app.bsky.graph.getRelationships', params, undefined, opts) .catch((e) => { throw AppBskyGraphGetRelationships.toKnownErr(e) }) } getStarterPack( params?: AppBskyGraphGetStarterPack.QueryParams, opts?: AppBskyGraphGetStarterPack.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getStarterPack', params, undefined, opts, ) } getStarterPacks( params?: AppBskyGraphGetStarterPacks.QueryParams, opts?: AppBskyGraphGetStarterPacks.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getStarterPacks', params, undefined, opts, ) } getStarterPacksWithMembership( params?: AppBskyGraphGetStarterPacksWithMembership.QueryParams, opts?: AppBskyGraphGetStarterPacksWithMembership.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getStarterPacksWithMembership', params, undefined, opts, ) } getSuggestedFollowsByActor( params?: AppBskyGraphGetSuggestedFollowsByActor.QueryParams, opts?: AppBskyGraphGetSuggestedFollowsByActor.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.getSuggestedFollowsByActor', params, undefined, opts, ) } muteActor( data?: AppBskyGraphMuteActor.InputSchema, opts?: AppBskyGraphMuteActor.CallOptions, ): Promise { return this._client.call('app.bsky.graph.muteActor', opts?.qp, data, opts) } muteActorList( data?: AppBskyGraphMuteActorList.InputSchema, opts?: AppBskyGraphMuteActorList.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.muteActorList', opts?.qp, data, opts, ) } muteThread( data?: AppBskyGraphMuteThread.InputSchema, opts?: AppBskyGraphMuteThread.CallOptions, ): Promise { return this._client.call('app.bsky.graph.muteThread', opts?.qp, data, opts) } searchStarterPacks( params?: AppBskyGraphSearchStarterPacks.QueryParams, opts?: AppBskyGraphSearchStarterPacks.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.searchStarterPacks', params, undefined, opts, ) } unmuteActor( data?: AppBskyGraphUnmuteActor.InputSchema, opts?: AppBskyGraphUnmuteActor.CallOptions, ): Promise { return this._client.call('app.bsky.graph.unmuteActor', opts?.qp, data, opts) } unmuteActorList( data?: AppBskyGraphUnmuteActorList.InputSchema, opts?: AppBskyGraphUnmuteActorList.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.unmuteActorList', opts?.qp, data, opts, ) } unmuteThread( data?: AppBskyGraphUnmuteThread.InputSchema, opts?: AppBskyGraphUnmuteThread.CallOptions, ): Promise { return this._client.call( 'app.bsky.graph.unmuteThread', opts?.qp, data, opts, ) } } export class AppBskyGraphBlockRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyGraphBlock.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.graph.block', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyGraphBlock.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.graph.block', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.block' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.block' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.graph.block', ...params }, { headers }, ) } } export class AppBskyGraphFollowRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyGraphFollow.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.graph.follow', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyGraphFollow.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.graph.follow', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.follow' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.follow' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.graph.follow', ...params }, { headers }, ) } } export class AppBskyGraphListRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyGraphList.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.graph.list', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyGraphList.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.graph.list', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.list' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.list' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.graph.list', ...params }, { headers }, ) } } export class AppBskyGraphListblockRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyGraphListblock.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.graph.listblock', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: AppBskyGraphListblock.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.graph.listblock', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.listblock' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.listblock' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.graph.listblock', ...params }, { headers }, ) } } export class AppBskyGraphListitemRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyGraphListitem.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.graph.listitem', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string; cid: string; value: AppBskyGraphListitem.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.graph.listitem', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.listitem' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.listitem' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.graph.listitem', ...params }, { headers }, ) } } export class AppBskyGraphStarterpackRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyGraphStarterpack.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.graph.starterpack', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: AppBskyGraphStarterpack.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.graph.starterpack', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.starterpack' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.starterpack' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.graph.starterpack', ...params }, { headers }, ) } } export class AppBskyGraphVerificationRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyGraphVerification.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.graph.verification', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: AppBskyGraphVerification.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.graph.verification', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.verification' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.graph.verification' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.graph.verification', ...params }, { headers }, ) } } export class AppBskyLabelerNS { _client: XrpcClient service: AppBskyLabelerServiceRecord constructor(client: XrpcClient) { this._client = client this.service = new AppBskyLabelerServiceRecord(client) } getServices( params?: AppBskyLabelerGetServices.QueryParams, opts?: AppBskyLabelerGetServices.CallOptions, ): Promise { return this._client.call( 'app.bsky.labeler.getServices', params, undefined, opts, ) } } export class AppBskyLabelerServiceRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyLabelerService.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.labeler.service', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: AppBskyLabelerService.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.labeler.service', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.labeler.service' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, rkey: 'self', ...params, record: { ...record, $type: collection }, }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.labeler.service' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.labeler.service', ...params }, { headers }, ) } } export class AppBskyNotificationNS { _client: XrpcClient declaration: AppBskyNotificationDeclarationRecord constructor(client: XrpcClient) { this._client = client this.declaration = new AppBskyNotificationDeclarationRecord(client) } getPreferences( params?: AppBskyNotificationGetPreferences.QueryParams, opts?: AppBskyNotificationGetPreferences.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.getPreferences', params, undefined, opts, ) } getUnreadCount( params?: AppBskyNotificationGetUnreadCount.QueryParams, opts?: AppBskyNotificationGetUnreadCount.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.getUnreadCount', params, undefined, opts, ) } listActivitySubscriptions( params?: AppBskyNotificationListActivitySubscriptions.QueryParams, opts?: AppBskyNotificationListActivitySubscriptions.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.listActivitySubscriptions', params, undefined, opts, ) } listNotifications( params?: AppBskyNotificationListNotifications.QueryParams, opts?: AppBskyNotificationListNotifications.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.listNotifications', params, undefined, opts, ) } putActivitySubscription( data?: AppBskyNotificationPutActivitySubscription.InputSchema, opts?: AppBskyNotificationPutActivitySubscription.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.putActivitySubscription', opts?.qp, data, opts, ) } putPreferences( data?: AppBskyNotificationPutPreferences.InputSchema, opts?: AppBskyNotificationPutPreferences.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.putPreferences', opts?.qp, data, opts, ) } putPreferencesV2( data?: AppBskyNotificationPutPreferencesV2.InputSchema, opts?: AppBskyNotificationPutPreferencesV2.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.putPreferencesV2', opts?.qp, data, opts, ) } registerPush( data?: AppBskyNotificationRegisterPush.InputSchema, opts?: AppBskyNotificationRegisterPush.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.registerPush', opts?.qp, data, opts, ) } unregisterPush( data?: AppBskyNotificationUnregisterPush.InputSchema, opts?: AppBskyNotificationUnregisterPush.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.unregisterPush', opts?.qp, data, opts, ) } updateSeen( data?: AppBskyNotificationUpdateSeen.InputSchema, opts?: AppBskyNotificationUpdateSeen.CallOptions, ): Promise { return this._client.call( 'app.bsky.notification.updateSeen', opts?.qp, data, opts, ) } } export class AppBskyNotificationDeclarationRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: AppBskyNotificationDeclaration.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'app.bsky.notification.declaration', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: AppBskyNotificationDeclaration.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'app.bsky.notification.declaration', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.notification.declaration' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, rkey: 'self', ...params, record: { ...record, $type: collection }, }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'app.bsky.notification.declaration' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'app.bsky.notification.declaration', ...params }, { headers }, ) } } export class AppBskyRichtextNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } } export class AppBskyUnspeccedNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } getAgeAssuranceState( params?: AppBskyUnspeccedGetAgeAssuranceState.QueryParams, opts?: AppBskyUnspeccedGetAgeAssuranceState.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getAgeAssuranceState', params, undefined, opts, ) } getConfig( params?: AppBskyUnspeccedGetConfig.QueryParams, opts?: AppBskyUnspeccedGetConfig.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getConfig', params, undefined, opts, ) } getOnboardingSuggestedStarterPacks( params?: AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.QueryParams, opts?: AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks', params, undefined, opts, ) } getOnboardingSuggestedStarterPacksSkeleton( params?: AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.QueryParams, opts?: AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton', params, undefined, opts, ) } getOnboardingSuggestedUsersSkeleton( params?: AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton.QueryParams, opts?: AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton', params, undefined, opts, ) } getPopularFeedGenerators( params?: AppBskyUnspeccedGetPopularFeedGenerators.QueryParams, opts?: AppBskyUnspeccedGetPopularFeedGenerators.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getPopularFeedGenerators', params, undefined, opts, ) } getPostThreadOtherV2( params?: AppBskyUnspeccedGetPostThreadOtherV2.QueryParams, opts?: AppBskyUnspeccedGetPostThreadOtherV2.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getPostThreadOtherV2', params, undefined, opts, ) } getPostThreadV2( params?: AppBskyUnspeccedGetPostThreadV2.QueryParams, opts?: AppBskyUnspeccedGetPostThreadV2.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getPostThreadV2', params, undefined, opts, ) } getSuggestedFeeds( params?: AppBskyUnspeccedGetSuggestedFeeds.QueryParams, opts?: AppBskyUnspeccedGetSuggestedFeeds.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestedFeeds', params, undefined, opts, ) } getSuggestedFeedsSkeleton( params?: AppBskyUnspeccedGetSuggestedFeedsSkeleton.QueryParams, opts?: AppBskyUnspeccedGetSuggestedFeedsSkeleton.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestedFeedsSkeleton', params, undefined, opts, ) } getSuggestedOnboardingUsers( params?: AppBskyUnspeccedGetSuggestedOnboardingUsers.QueryParams, opts?: AppBskyUnspeccedGetSuggestedOnboardingUsers.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestedOnboardingUsers', params, undefined, opts, ) } getSuggestedStarterPacks( params?: AppBskyUnspeccedGetSuggestedStarterPacks.QueryParams, opts?: AppBskyUnspeccedGetSuggestedStarterPacks.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestedStarterPacks', params, undefined, opts, ) } getSuggestedStarterPacksSkeleton( params?: AppBskyUnspeccedGetSuggestedStarterPacksSkeleton.QueryParams, opts?: AppBskyUnspeccedGetSuggestedStarterPacksSkeleton.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton', params, undefined, opts, ) } getSuggestedUsers( params?: AppBskyUnspeccedGetSuggestedUsers.QueryParams, opts?: AppBskyUnspeccedGetSuggestedUsers.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestedUsers', params, undefined, opts, ) } getSuggestedUsersSkeleton( params?: AppBskyUnspeccedGetSuggestedUsersSkeleton.QueryParams, opts?: AppBskyUnspeccedGetSuggestedUsersSkeleton.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestedUsersSkeleton', params, undefined, opts, ) } getSuggestionsSkeleton( params?: AppBskyUnspeccedGetSuggestionsSkeleton.QueryParams, opts?: AppBskyUnspeccedGetSuggestionsSkeleton.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getSuggestionsSkeleton', params, undefined, opts, ) } getTaggedSuggestions( params?: AppBskyUnspeccedGetTaggedSuggestions.QueryParams, opts?: AppBskyUnspeccedGetTaggedSuggestions.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getTaggedSuggestions', params, undefined, opts, ) } getTrendingTopics( params?: AppBskyUnspeccedGetTrendingTopics.QueryParams, opts?: AppBskyUnspeccedGetTrendingTopics.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getTrendingTopics', params, undefined, opts, ) } getTrends( params?: AppBskyUnspeccedGetTrends.QueryParams, opts?: AppBskyUnspeccedGetTrends.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getTrends', params, undefined, opts, ) } getTrendsSkeleton( params?: AppBskyUnspeccedGetTrendsSkeleton.QueryParams, opts?: AppBskyUnspeccedGetTrendsSkeleton.CallOptions, ): Promise { return this._client.call( 'app.bsky.unspecced.getTrendsSkeleton', params, undefined, opts, ) } initAgeAssurance( data?: AppBskyUnspeccedInitAgeAssurance.InputSchema, opts?: AppBskyUnspeccedInitAgeAssurance.CallOptions, ): Promise { return this._client .call('app.bsky.unspecced.initAgeAssurance', opts?.qp, data, opts) .catch((e) => { throw AppBskyUnspeccedInitAgeAssurance.toKnownErr(e) }) } searchActorsSkeleton( params?: AppBskyUnspeccedSearchActorsSkeleton.QueryParams, opts?: AppBskyUnspeccedSearchActorsSkeleton.CallOptions, ): Promise { return this._client .call('app.bsky.unspecced.searchActorsSkeleton', params, undefined, opts) .catch((e) => { throw AppBskyUnspeccedSearchActorsSkeleton.toKnownErr(e) }) } searchPostsSkeleton( params?: AppBskyUnspeccedSearchPostsSkeleton.QueryParams, opts?: AppBskyUnspeccedSearchPostsSkeleton.CallOptions, ): Promise { return this._client .call('app.bsky.unspecced.searchPostsSkeleton', params, undefined, opts) .catch((e) => { throw AppBskyUnspeccedSearchPostsSkeleton.toKnownErr(e) }) } searchStarterPacksSkeleton( params?: AppBskyUnspeccedSearchStarterPacksSkeleton.QueryParams, opts?: AppBskyUnspeccedSearchStarterPacksSkeleton.CallOptions, ): Promise { return this._client .call( 'app.bsky.unspecced.searchStarterPacksSkeleton', params, undefined, opts, ) .catch((e) => { throw AppBskyUnspeccedSearchStarterPacksSkeleton.toKnownErr(e) }) } } export class AppBskyVideoNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } getJobStatus( params?: AppBskyVideoGetJobStatus.QueryParams, opts?: AppBskyVideoGetJobStatus.CallOptions, ): Promise { return this._client.call( 'app.bsky.video.getJobStatus', params, undefined, opts, ) } getUploadLimits( params?: AppBskyVideoGetUploadLimits.QueryParams, opts?: AppBskyVideoGetUploadLimits.CallOptions, ): Promise { return this._client.call( 'app.bsky.video.getUploadLimits', params, undefined, opts, ) } uploadVideo( data?: AppBskyVideoUploadVideo.InputSchema, opts?: AppBskyVideoUploadVideo.CallOptions, ): Promise { return this._client.call('app.bsky.video.uploadVideo', opts?.qp, data, opts) } } export class ChatNS { _client: XrpcClient bsky: ChatBskyNS constructor(client: XrpcClient) { this._client = client this.bsky = new ChatBskyNS(client) } } export class ChatBskyNS { _client: XrpcClient actor: ChatBskyActorNS convo: ChatBskyConvoNS moderation: ChatBskyModerationNS constructor(client: XrpcClient) { this._client = client this.actor = new ChatBskyActorNS(client) this.convo = new ChatBskyConvoNS(client) this.moderation = new ChatBskyModerationNS(client) } } export class ChatBskyActorNS { _client: XrpcClient declaration: ChatBskyActorDeclarationRecord constructor(client: XrpcClient) { this._client = client this.declaration = new ChatBskyActorDeclarationRecord(client) } deleteAccount( data?: ChatBskyActorDeleteAccount.InputSchema, opts?: ChatBskyActorDeleteAccount.CallOptions, ): Promise { return this._client.call( 'chat.bsky.actor.deleteAccount', opts?.qp, data, opts, ) } exportAccountData( params?: ChatBskyActorExportAccountData.QueryParams, opts?: ChatBskyActorExportAccountData.CallOptions, ): Promise { return this._client.call( 'chat.bsky.actor.exportAccountData', params, undefined, opts, ) } } export class ChatBskyActorDeclarationRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: ChatBskyActorDeclaration.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'chat.bsky.actor.declaration', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: ChatBskyActorDeclaration.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'chat.bsky.actor.declaration', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'chat.bsky.actor.declaration' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, rkey: 'self', ...params, record: { ...record, $type: collection }, }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'chat.bsky.actor.declaration' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'chat.bsky.actor.declaration', ...params }, { headers }, ) } } export class ChatBskyConvoNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } acceptConvo( data?: ChatBskyConvoAcceptConvo.InputSchema, opts?: ChatBskyConvoAcceptConvo.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.acceptConvo', opts?.qp, data, opts, ) } addReaction( data?: ChatBskyConvoAddReaction.InputSchema, opts?: ChatBskyConvoAddReaction.CallOptions, ): Promise { return this._client .call('chat.bsky.convo.addReaction', opts?.qp, data, opts) .catch((e) => { throw ChatBskyConvoAddReaction.toKnownErr(e) }) } deleteMessageForSelf( data?: ChatBskyConvoDeleteMessageForSelf.InputSchema, opts?: ChatBskyConvoDeleteMessageForSelf.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.deleteMessageForSelf', opts?.qp, data, opts, ) } getConvo( params?: ChatBskyConvoGetConvo.QueryParams, opts?: ChatBskyConvoGetConvo.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.getConvo', params, undefined, opts, ) } getConvoAvailability( params?: ChatBskyConvoGetConvoAvailability.QueryParams, opts?: ChatBskyConvoGetConvoAvailability.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.getConvoAvailability', params, undefined, opts, ) } getConvoForMembers( params?: ChatBskyConvoGetConvoForMembers.QueryParams, opts?: ChatBskyConvoGetConvoForMembers.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.getConvoForMembers', params, undefined, opts, ) } getLog( params?: ChatBskyConvoGetLog.QueryParams, opts?: ChatBskyConvoGetLog.CallOptions, ): Promise { return this._client.call('chat.bsky.convo.getLog', params, undefined, opts) } getMessages( params?: ChatBskyConvoGetMessages.QueryParams, opts?: ChatBskyConvoGetMessages.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.getMessages', params, undefined, opts, ) } leaveConvo( data?: ChatBskyConvoLeaveConvo.InputSchema, opts?: ChatBskyConvoLeaveConvo.CallOptions, ): Promise { return this._client.call('chat.bsky.convo.leaveConvo', opts?.qp, data, opts) } listConvos( params?: ChatBskyConvoListConvos.QueryParams, opts?: ChatBskyConvoListConvos.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.listConvos', params, undefined, opts, ) } muteConvo( data?: ChatBskyConvoMuteConvo.InputSchema, opts?: ChatBskyConvoMuteConvo.CallOptions, ): Promise { return this._client.call('chat.bsky.convo.muteConvo', opts?.qp, data, opts) } removeReaction( data?: ChatBskyConvoRemoveReaction.InputSchema, opts?: ChatBskyConvoRemoveReaction.CallOptions, ): Promise { return this._client .call('chat.bsky.convo.removeReaction', opts?.qp, data, opts) .catch((e) => { throw ChatBskyConvoRemoveReaction.toKnownErr(e) }) } sendMessage( data?: ChatBskyConvoSendMessage.InputSchema, opts?: ChatBskyConvoSendMessage.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.sendMessage', opts?.qp, data, opts, ) } sendMessageBatch( data?: ChatBskyConvoSendMessageBatch.InputSchema, opts?: ChatBskyConvoSendMessageBatch.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.sendMessageBatch', opts?.qp, data, opts, ) } unmuteConvo( data?: ChatBskyConvoUnmuteConvo.InputSchema, opts?: ChatBskyConvoUnmuteConvo.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.unmuteConvo', opts?.qp, data, opts, ) } updateAllRead( data?: ChatBskyConvoUpdateAllRead.InputSchema, opts?: ChatBskyConvoUpdateAllRead.CallOptions, ): Promise { return this._client.call( 'chat.bsky.convo.updateAllRead', opts?.qp, data, opts, ) } updateRead( data?: ChatBskyConvoUpdateRead.InputSchema, opts?: ChatBskyConvoUpdateRead.CallOptions, ): Promise { return this._client.call('chat.bsky.convo.updateRead', opts?.qp, data, opts) } } export class ChatBskyModerationNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } getActorMetadata( params?: ChatBskyModerationGetActorMetadata.QueryParams, opts?: ChatBskyModerationGetActorMetadata.CallOptions, ): Promise { return this._client.call( 'chat.bsky.moderation.getActorMetadata', params, undefined, opts, ) } getMessageContext( params?: ChatBskyModerationGetMessageContext.QueryParams, opts?: ChatBskyModerationGetMessageContext.CallOptions, ): Promise { return this._client.call( 'chat.bsky.moderation.getMessageContext', params, undefined, opts, ) } updateActorAccess( data?: ChatBskyModerationUpdateActorAccess.InputSchema, opts?: ChatBskyModerationUpdateActorAccess.CallOptions, ): Promise { return this._client.call( 'chat.bsky.moderation.updateActorAccess', opts?.qp, data, opts, ) } } export class ComNS { _client: XrpcClient atproto: ComAtprotoNS germnetwork: ComGermnetworkNS constructor(client: XrpcClient) { this._client = client this.atproto = new ComAtprotoNS(client) this.germnetwork = new ComGermnetworkNS(client) } } export class ComAtprotoNS { _client: XrpcClient admin: ComAtprotoAdminNS identity: ComAtprotoIdentityNS label: ComAtprotoLabelNS lexicon: ComAtprotoLexiconNS moderation: ComAtprotoModerationNS repo: ComAtprotoRepoNS server: ComAtprotoServerNS sync: ComAtprotoSyncNS temp: ComAtprotoTempNS constructor(client: XrpcClient) { this._client = client this.admin = new ComAtprotoAdminNS(client) this.identity = new ComAtprotoIdentityNS(client) this.label = new ComAtprotoLabelNS(client) this.lexicon = new ComAtprotoLexiconNS(client) this.moderation = new ComAtprotoModerationNS(client) this.repo = new ComAtprotoRepoNS(client) this.server = new ComAtprotoServerNS(client) this.sync = new ComAtprotoSyncNS(client) this.temp = new ComAtprotoTempNS(client) } } export class ComAtprotoAdminNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } deleteAccount( data?: ComAtprotoAdminDeleteAccount.InputSchema, opts?: ComAtprotoAdminDeleteAccount.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.deleteAccount', opts?.qp, data, opts, ) } disableAccountInvites( data?: ComAtprotoAdminDisableAccountInvites.InputSchema, opts?: ComAtprotoAdminDisableAccountInvites.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.disableAccountInvites', opts?.qp, data, opts, ) } disableInviteCodes( data?: ComAtprotoAdminDisableInviteCodes.InputSchema, opts?: ComAtprotoAdminDisableInviteCodes.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.disableInviteCodes', opts?.qp, data, opts, ) } enableAccountInvites( data?: ComAtprotoAdminEnableAccountInvites.InputSchema, opts?: ComAtprotoAdminEnableAccountInvites.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.enableAccountInvites', opts?.qp, data, opts, ) } getAccountInfo( params?: ComAtprotoAdminGetAccountInfo.QueryParams, opts?: ComAtprotoAdminGetAccountInfo.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.getAccountInfo', params, undefined, opts, ) } getAccountInfos( params?: ComAtprotoAdminGetAccountInfos.QueryParams, opts?: ComAtprotoAdminGetAccountInfos.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.getAccountInfos', params, undefined, opts, ) } getInviteCodes( params?: ComAtprotoAdminGetInviteCodes.QueryParams, opts?: ComAtprotoAdminGetInviteCodes.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.getInviteCodes', params, undefined, opts, ) } getSubjectStatus( params?: ComAtprotoAdminGetSubjectStatus.QueryParams, opts?: ComAtprotoAdminGetSubjectStatus.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.getSubjectStatus', params, undefined, opts, ) } searchAccounts( params?: ComAtprotoAdminSearchAccounts.QueryParams, opts?: ComAtprotoAdminSearchAccounts.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.searchAccounts', params, undefined, opts, ) } sendEmail( data?: ComAtprotoAdminSendEmail.InputSchema, opts?: ComAtprotoAdminSendEmail.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.sendEmail', opts?.qp, data, opts, ) } updateAccountEmail( data?: ComAtprotoAdminUpdateAccountEmail.InputSchema, opts?: ComAtprotoAdminUpdateAccountEmail.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.updateAccountEmail', opts?.qp, data, opts, ) } updateAccountHandle( data?: ComAtprotoAdminUpdateAccountHandle.InputSchema, opts?: ComAtprotoAdminUpdateAccountHandle.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.updateAccountHandle', opts?.qp, data, opts, ) } updateAccountPassword( data?: ComAtprotoAdminUpdateAccountPassword.InputSchema, opts?: ComAtprotoAdminUpdateAccountPassword.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.updateAccountPassword', opts?.qp, data, opts, ) } updateAccountSigningKey( data?: ComAtprotoAdminUpdateAccountSigningKey.InputSchema, opts?: ComAtprotoAdminUpdateAccountSigningKey.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.updateAccountSigningKey', opts?.qp, data, opts, ) } updateSubjectStatus( data?: ComAtprotoAdminUpdateSubjectStatus.InputSchema, opts?: ComAtprotoAdminUpdateSubjectStatus.CallOptions, ): Promise { return this._client.call( 'com.atproto.admin.updateSubjectStatus', opts?.qp, data, opts, ) } } export class ComAtprotoIdentityNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } getRecommendedDidCredentials( params?: ComAtprotoIdentityGetRecommendedDidCredentials.QueryParams, opts?: ComAtprotoIdentityGetRecommendedDidCredentials.CallOptions, ): Promise { return this._client.call( 'com.atproto.identity.getRecommendedDidCredentials', params, undefined, opts, ) } refreshIdentity( data?: ComAtprotoIdentityRefreshIdentity.InputSchema, opts?: ComAtprotoIdentityRefreshIdentity.CallOptions, ): Promise { return this._client .call('com.atproto.identity.refreshIdentity', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoIdentityRefreshIdentity.toKnownErr(e) }) } requestPlcOperationSignature( data?: ComAtprotoIdentityRequestPlcOperationSignature.InputSchema, opts?: ComAtprotoIdentityRequestPlcOperationSignature.CallOptions, ): Promise { return this._client.call( 'com.atproto.identity.requestPlcOperationSignature', opts?.qp, data, opts, ) } resolveDid( params?: ComAtprotoIdentityResolveDid.QueryParams, opts?: ComAtprotoIdentityResolveDid.CallOptions, ): Promise { return this._client .call('com.atproto.identity.resolveDid', params, undefined, opts) .catch((e) => { throw ComAtprotoIdentityResolveDid.toKnownErr(e) }) } resolveHandle( params?: ComAtprotoIdentityResolveHandle.QueryParams, opts?: ComAtprotoIdentityResolveHandle.CallOptions, ): Promise { return this._client .call('com.atproto.identity.resolveHandle', params, undefined, opts) .catch((e) => { throw ComAtprotoIdentityResolveHandle.toKnownErr(e) }) } resolveIdentity( params?: ComAtprotoIdentityResolveIdentity.QueryParams, opts?: ComAtprotoIdentityResolveIdentity.CallOptions, ): Promise { return this._client .call('com.atproto.identity.resolveIdentity', params, undefined, opts) .catch((e) => { throw ComAtprotoIdentityResolveIdentity.toKnownErr(e) }) } signPlcOperation( data?: ComAtprotoIdentitySignPlcOperation.InputSchema, opts?: ComAtprotoIdentitySignPlcOperation.CallOptions, ): Promise { return this._client.call( 'com.atproto.identity.signPlcOperation', opts?.qp, data, opts, ) } submitPlcOperation( data?: ComAtprotoIdentitySubmitPlcOperation.InputSchema, opts?: ComAtprotoIdentitySubmitPlcOperation.CallOptions, ): Promise { return this._client.call( 'com.atproto.identity.submitPlcOperation', opts?.qp, data, opts, ) } updateHandle( data?: ComAtprotoIdentityUpdateHandle.InputSchema, opts?: ComAtprotoIdentityUpdateHandle.CallOptions, ): Promise { return this._client.call( 'com.atproto.identity.updateHandle', opts?.qp, data, opts, ) } } export class ComAtprotoLabelNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } queryLabels( params?: ComAtprotoLabelQueryLabels.QueryParams, opts?: ComAtprotoLabelQueryLabels.CallOptions, ): Promise { return this._client.call( 'com.atproto.label.queryLabels', params, undefined, opts, ) } } export class ComAtprotoLexiconNS { _client: XrpcClient schema: ComAtprotoLexiconSchemaRecord constructor(client: XrpcClient) { this._client = client this.schema = new ComAtprotoLexiconSchemaRecord(client) } resolveLexicon( params?: ComAtprotoLexiconResolveLexicon.QueryParams, opts?: ComAtprotoLexiconResolveLexicon.CallOptions, ): Promise { return this._client .call('com.atproto.lexicon.resolveLexicon', params, undefined, opts) .catch((e) => { throw ComAtprotoLexiconResolveLexicon.toKnownErr(e) }) } } export class ComAtprotoLexiconSchemaRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: ComAtprotoLexiconSchema.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'com.atproto.lexicon.schema', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: ComAtprotoLexiconSchema.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'com.atproto.lexicon.schema', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'com.atproto.lexicon.schema' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'com.atproto.lexicon.schema' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'com.atproto.lexicon.schema', ...params }, { headers }, ) } } export class ComAtprotoModerationNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } createReport( data?: ComAtprotoModerationCreateReport.InputSchema, opts?: ComAtprotoModerationCreateReport.CallOptions, ): Promise { return this._client.call( 'com.atproto.moderation.createReport', opts?.qp, data, opts, ) } } export class ComAtprotoRepoNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } applyWrites( data?: ComAtprotoRepoApplyWrites.InputSchema, opts?: ComAtprotoRepoApplyWrites.CallOptions, ): Promise { return this._client .call('com.atproto.repo.applyWrites', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoRepoApplyWrites.toKnownErr(e) }) } createRecord( data?: ComAtprotoRepoCreateRecord.InputSchema, opts?: ComAtprotoRepoCreateRecord.CallOptions, ): Promise { return this._client .call('com.atproto.repo.createRecord', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoRepoCreateRecord.toKnownErr(e) }) } deleteRecord( data?: ComAtprotoRepoDeleteRecord.InputSchema, opts?: ComAtprotoRepoDeleteRecord.CallOptions, ): Promise { return this._client .call('com.atproto.repo.deleteRecord', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoRepoDeleteRecord.toKnownErr(e) }) } describeRepo( params?: ComAtprotoRepoDescribeRepo.QueryParams, opts?: ComAtprotoRepoDescribeRepo.CallOptions, ): Promise { return this._client.call( 'com.atproto.repo.describeRepo', params, undefined, opts, ) } getRecord( params?: ComAtprotoRepoGetRecord.QueryParams, opts?: ComAtprotoRepoGetRecord.CallOptions, ): Promise { return this._client .call('com.atproto.repo.getRecord', params, undefined, opts) .catch((e) => { throw ComAtprotoRepoGetRecord.toKnownErr(e) }) } importRepo( data?: ComAtprotoRepoImportRepo.InputSchema, opts?: ComAtprotoRepoImportRepo.CallOptions, ): Promise { return this._client.call( 'com.atproto.repo.importRepo', opts?.qp, data, opts, ) } listMissingBlobs( params?: ComAtprotoRepoListMissingBlobs.QueryParams, opts?: ComAtprotoRepoListMissingBlobs.CallOptions, ): Promise { return this._client.call( 'com.atproto.repo.listMissingBlobs', params, undefined, opts, ) } listRecords( params?: ComAtprotoRepoListRecords.QueryParams, opts?: ComAtprotoRepoListRecords.CallOptions, ): Promise { return this._client.call( 'com.atproto.repo.listRecords', params, undefined, opts, ) } putRecord( data?: ComAtprotoRepoPutRecord.InputSchema, opts?: ComAtprotoRepoPutRecord.CallOptions, ): Promise { return this._client .call('com.atproto.repo.putRecord', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoRepoPutRecord.toKnownErr(e) }) } uploadBlob( data?: ComAtprotoRepoUploadBlob.InputSchema, opts?: ComAtprotoRepoUploadBlob.CallOptions, ): Promise { return this._client.call( 'com.atproto.repo.uploadBlob', opts?.qp, data, opts, ) } } export class ComAtprotoServerNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } activateAccount( data?: ComAtprotoServerActivateAccount.InputSchema, opts?: ComAtprotoServerActivateAccount.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.activateAccount', opts?.qp, data, opts, ) } checkAccountStatus( params?: ComAtprotoServerCheckAccountStatus.QueryParams, opts?: ComAtprotoServerCheckAccountStatus.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.checkAccountStatus', params, undefined, opts, ) } confirmEmail( data?: ComAtprotoServerConfirmEmail.InputSchema, opts?: ComAtprotoServerConfirmEmail.CallOptions, ): Promise { return this._client .call('com.atproto.server.confirmEmail', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerConfirmEmail.toKnownErr(e) }) } createAccount( data?: ComAtprotoServerCreateAccount.InputSchema, opts?: ComAtprotoServerCreateAccount.CallOptions, ): Promise { return this._client .call('com.atproto.server.createAccount', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerCreateAccount.toKnownErr(e) }) } createAppPassword( data?: ComAtprotoServerCreateAppPassword.InputSchema, opts?: ComAtprotoServerCreateAppPassword.CallOptions, ): Promise { return this._client .call('com.atproto.server.createAppPassword', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerCreateAppPassword.toKnownErr(e) }) } createInviteCode( data?: ComAtprotoServerCreateInviteCode.InputSchema, opts?: ComAtprotoServerCreateInviteCode.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.createInviteCode', opts?.qp, data, opts, ) } createInviteCodes( data?: ComAtprotoServerCreateInviteCodes.InputSchema, opts?: ComAtprotoServerCreateInviteCodes.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.createInviteCodes', opts?.qp, data, opts, ) } createSession( data?: ComAtprotoServerCreateSession.InputSchema, opts?: ComAtprotoServerCreateSession.CallOptions, ): Promise { return this._client .call('com.atproto.server.createSession', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerCreateSession.toKnownErr(e) }) } deactivateAccount( data?: ComAtprotoServerDeactivateAccount.InputSchema, opts?: ComAtprotoServerDeactivateAccount.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.deactivateAccount', opts?.qp, data, opts, ) } deleteAccount( data?: ComAtprotoServerDeleteAccount.InputSchema, opts?: ComAtprotoServerDeleteAccount.CallOptions, ): Promise { return this._client .call('com.atproto.server.deleteAccount', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerDeleteAccount.toKnownErr(e) }) } deleteSession( data?: ComAtprotoServerDeleteSession.InputSchema, opts?: ComAtprotoServerDeleteSession.CallOptions, ): Promise { return this._client .call('com.atproto.server.deleteSession', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerDeleteSession.toKnownErr(e) }) } describeServer( params?: ComAtprotoServerDescribeServer.QueryParams, opts?: ComAtprotoServerDescribeServer.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.describeServer', params, undefined, opts, ) } getAccountInviteCodes( params?: ComAtprotoServerGetAccountInviteCodes.QueryParams, opts?: ComAtprotoServerGetAccountInviteCodes.CallOptions, ): Promise { return this._client .call('com.atproto.server.getAccountInviteCodes', params, undefined, opts) .catch((e) => { throw ComAtprotoServerGetAccountInviteCodes.toKnownErr(e) }) } getServiceAuth( params?: ComAtprotoServerGetServiceAuth.QueryParams, opts?: ComAtprotoServerGetServiceAuth.CallOptions, ): Promise { return this._client .call('com.atproto.server.getServiceAuth', params, undefined, opts) .catch((e) => { throw ComAtprotoServerGetServiceAuth.toKnownErr(e) }) } getSession( params?: ComAtprotoServerGetSession.QueryParams, opts?: ComAtprotoServerGetSession.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.getSession', params, undefined, opts, ) } listAppPasswords( params?: ComAtprotoServerListAppPasswords.QueryParams, opts?: ComAtprotoServerListAppPasswords.CallOptions, ): Promise { return this._client .call('com.atproto.server.listAppPasswords', params, undefined, opts) .catch((e) => { throw ComAtprotoServerListAppPasswords.toKnownErr(e) }) } refreshSession( data?: ComAtprotoServerRefreshSession.InputSchema, opts?: ComAtprotoServerRefreshSession.CallOptions, ): Promise { return this._client .call('com.atproto.server.refreshSession', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerRefreshSession.toKnownErr(e) }) } requestAccountDelete( data?: ComAtprotoServerRequestAccountDelete.InputSchema, opts?: ComAtprotoServerRequestAccountDelete.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.requestAccountDelete', opts?.qp, data, opts, ) } requestEmailConfirmation( data?: ComAtprotoServerRequestEmailConfirmation.InputSchema, opts?: ComAtprotoServerRequestEmailConfirmation.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.requestEmailConfirmation', opts?.qp, data, opts, ) } requestEmailUpdate( data?: ComAtprotoServerRequestEmailUpdate.InputSchema, opts?: ComAtprotoServerRequestEmailUpdate.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.requestEmailUpdate', opts?.qp, data, opts, ) } requestPasswordReset( data?: ComAtprotoServerRequestPasswordReset.InputSchema, opts?: ComAtprotoServerRequestPasswordReset.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.requestPasswordReset', opts?.qp, data, opts, ) } reserveSigningKey( data?: ComAtprotoServerReserveSigningKey.InputSchema, opts?: ComAtprotoServerReserveSigningKey.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.reserveSigningKey', opts?.qp, data, opts, ) } resetPassword( data?: ComAtprotoServerResetPassword.InputSchema, opts?: ComAtprotoServerResetPassword.CallOptions, ): Promise { return this._client .call('com.atproto.server.resetPassword', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerResetPassword.toKnownErr(e) }) } revokeAppPassword( data?: ComAtprotoServerRevokeAppPassword.InputSchema, opts?: ComAtprotoServerRevokeAppPassword.CallOptions, ): Promise { return this._client.call( 'com.atproto.server.revokeAppPassword', opts?.qp, data, opts, ) } updateEmail( data?: ComAtprotoServerUpdateEmail.InputSchema, opts?: ComAtprotoServerUpdateEmail.CallOptions, ): Promise { return this._client .call('com.atproto.server.updateEmail', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoServerUpdateEmail.toKnownErr(e) }) } } export class ComAtprotoSyncNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } getBlob( params?: ComAtprotoSyncGetBlob.QueryParams, opts?: ComAtprotoSyncGetBlob.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getBlob', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetBlob.toKnownErr(e) }) } getBlocks( params?: ComAtprotoSyncGetBlocks.QueryParams, opts?: ComAtprotoSyncGetBlocks.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getBlocks', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetBlocks.toKnownErr(e) }) } getCheckout( params?: ComAtprotoSyncGetCheckout.QueryParams, opts?: ComAtprotoSyncGetCheckout.CallOptions, ): Promise { return this._client.call( 'com.atproto.sync.getCheckout', params, undefined, opts, ) } getHead( params?: ComAtprotoSyncGetHead.QueryParams, opts?: ComAtprotoSyncGetHead.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getHead', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetHead.toKnownErr(e) }) } getHostStatus( params?: ComAtprotoSyncGetHostStatus.QueryParams, opts?: ComAtprotoSyncGetHostStatus.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getHostStatus', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetHostStatus.toKnownErr(e) }) } getLatestCommit( params?: ComAtprotoSyncGetLatestCommit.QueryParams, opts?: ComAtprotoSyncGetLatestCommit.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getLatestCommit', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetLatestCommit.toKnownErr(e) }) } getRecord( params?: ComAtprotoSyncGetRecord.QueryParams, opts?: ComAtprotoSyncGetRecord.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getRecord', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetRecord.toKnownErr(e) }) } getRepo( params?: ComAtprotoSyncGetRepo.QueryParams, opts?: ComAtprotoSyncGetRepo.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getRepo', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetRepo.toKnownErr(e) }) } getRepoStatus( params?: ComAtprotoSyncGetRepoStatus.QueryParams, opts?: ComAtprotoSyncGetRepoStatus.CallOptions, ): Promise { return this._client .call('com.atproto.sync.getRepoStatus', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncGetRepoStatus.toKnownErr(e) }) } listBlobs( params?: ComAtprotoSyncListBlobs.QueryParams, opts?: ComAtprotoSyncListBlobs.CallOptions, ): Promise { return this._client .call('com.atproto.sync.listBlobs', params, undefined, opts) .catch((e) => { throw ComAtprotoSyncListBlobs.toKnownErr(e) }) } listHosts( params?: ComAtprotoSyncListHosts.QueryParams, opts?: ComAtprotoSyncListHosts.CallOptions, ): Promise { return this._client.call( 'com.atproto.sync.listHosts', params, undefined, opts, ) } listRepos( params?: ComAtprotoSyncListRepos.QueryParams, opts?: ComAtprotoSyncListRepos.CallOptions, ): Promise { return this._client.call( 'com.atproto.sync.listRepos', params, undefined, opts, ) } listReposByCollection( params?: ComAtprotoSyncListReposByCollection.QueryParams, opts?: ComAtprotoSyncListReposByCollection.CallOptions, ): Promise { return this._client.call( 'com.atproto.sync.listReposByCollection', params, undefined, opts, ) } notifyOfUpdate( data?: ComAtprotoSyncNotifyOfUpdate.InputSchema, opts?: ComAtprotoSyncNotifyOfUpdate.CallOptions, ): Promise { return this._client.call( 'com.atproto.sync.notifyOfUpdate', opts?.qp, data, opts, ) } requestCrawl( data?: ComAtprotoSyncRequestCrawl.InputSchema, opts?: ComAtprotoSyncRequestCrawl.CallOptions, ): Promise { return this._client .call('com.atproto.sync.requestCrawl', opts?.qp, data, opts) .catch((e) => { throw ComAtprotoSyncRequestCrawl.toKnownErr(e) }) } } export class ComAtprotoTempNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } addReservedHandle( data?: ComAtprotoTempAddReservedHandle.InputSchema, opts?: ComAtprotoTempAddReservedHandle.CallOptions, ): Promise { return this._client.call( 'com.atproto.temp.addReservedHandle', opts?.qp, data, opts, ) } checkHandleAvailability( params?: ComAtprotoTempCheckHandleAvailability.QueryParams, opts?: ComAtprotoTempCheckHandleAvailability.CallOptions, ): Promise { return this._client .call('com.atproto.temp.checkHandleAvailability', params, undefined, opts) .catch((e) => { throw ComAtprotoTempCheckHandleAvailability.toKnownErr(e) }) } checkSignupQueue( params?: ComAtprotoTempCheckSignupQueue.QueryParams, opts?: ComAtprotoTempCheckSignupQueue.CallOptions, ): Promise { return this._client.call( 'com.atproto.temp.checkSignupQueue', params, undefined, opts, ) } dereferenceScope( params?: ComAtprotoTempDereferenceScope.QueryParams, opts?: ComAtprotoTempDereferenceScope.CallOptions, ): Promise { return this._client .call('com.atproto.temp.dereferenceScope', params, undefined, opts) .catch((e) => { throw ComAtprotoTempDereferenceScope.toKnownErr(e) }) } fetchLabels( params?: ComAtprotoTempFetchLabels.QueryParams, opts?: ComAtprotoTempFetchLabels.CallOptions, ): Promise { return this._client.call( 'com.atproto.temp.fetchLabels', params, undefined, opts, ) } requestPhoneVerification( data?: ComAtprotoTempRequestPhoneVerification.InputSchema, opts?: ComAtprotoTempRequestPhoneVerification.CallOptions, ): Promise { return this._client.call( 'com.atproto.temp.requestPhoneVerification', opts?.qp, data, opts, ) } revokeAccountCredentials( data?: ComAtprotoTempRevokeAccountCredentials.InputSchema, opts?: ComAtprotoTempRevokeAccountCredentials.CallOptions, ): Promise { return this._client.call( 'com.atproto.temp.revokeAccountCredentials', opts?.qp, data, opts, ) } } export class ComGermnetworkNS { _client: XrpcClient declaration: ComGermnetworkDeclarationRecord constructor(client: XrpcClient) { this._client = client this.declaration = new ComGermnetworkDeclarationRecord(client) } } export class ComGermnetworkDeclarationRecord { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } async list( params: OmitKey, ): Promise<{ cursor?: string records: { uri: string; value: ComGermnetworkDeclaration.Record }[] }> { const res = await this._client.call('com.atproto.repo.listRecords', { collection: 'com.germnetwork.declaration', ...params, }) return res.data } async get( params: OmitKey, ): Promise<{ uri: string cid: string value: ComGermnetworkDeclaration.Record }> { const res = await this._client.call('com.atproto.repo.getRecord', { collection: 'com.germnetwork.declaration', ...params, }) return res.data } async create( params: OmitKey< ComAtprotoRepoCreateRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'com.germnetwork.declaration' const res = await this._client.call( 'com.atproto.repo.createRecord', undefined, { collection, rkey: 'self', ...params, record: { ...record, $type: collection }, }, { encoding: 'application/json', headers }, ) return res.data } async put( params: OmitKey< ComAtprotoRepoPutRecord.InputSchema, 'collection' | 'record' >, record: Un$Typed, headers?: Record, ): Promise<{ uri: string; cid: string }> { const collection = 'com.germnetwork.declaration' const res = await this._client.call( 'com.atproto.repo.putRecord', undefined, { collection, ...params, record: { ...record, $type: collection } }, { encoding: 'application/json', headers }, ) return res.data } async delete( params: OmitKey, headers?: Record, ): Promise { await this._client.call( 'com.atproto.repo.deleteRecord', undefined, { collection: 'com.germnetwork.declaration', ...params }, { headers }, ) } } export class ToolsNS { _client: XrpcClient ozone: ToolsOzoneNS constructor(client: XrpcClient) { this._client = client this.ozone = new ToolsOzoneNS(client) } } export class ToolsOzoneNS { _client: XrpcClient communication: ToolsOzoneCommunicationNS hosting: ToolsOzoneHostingNS moderation: ToolsOzoneModerationNS safelink: ToolsOzoneSafelinkNS server: ToolsOzoneServerNS set: ToolsOzoneSetNS setting: ToolsOzoneSettingNS signature: ToolsOzoneSignatureNS team: ToolsOzoneTeamNS verification: ToolsOzoneVerificationNS constructor(client: XrpcClient) { this._client = client this.communication = new ToolsOzoneCommunicationNS(client) this.hosting = new ToolsOzoneHostingNS(client) this.moderation = new ToolsOzoneModerationNS(client) this.safelink = new ToolsOzoneSafelinkNS(client) this.server = new ToolsOzoneServerNS(client) this.set = new ToolsOzoneSetNS(client) this.setting = new ToolsOzoneSettingNS(client) this.signature = new ToolsOzoneSignatureNS(client) this.team = new ToolsOzoneTeamNS(client) this.verification = new ToolsOzoneVerificationNS(client) } } export class ToolsOzoneCommunicationNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } createTemplate( data?: ToolsOzoneCommunicationCreateTemplate.InputSchema, opts?: ToolsOzoneCommunicationCreateTemplate.CallOptions, ): Promise { return this._client .call('tools.ozone.communication.createTemplate', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneCommunicationCreateTemplate.toKnownErr(e) }) } deleteTemplate( data?: ToolsOzoneCommunicationDeleteTemplate.InputSchema, opts?: ToolsOzoneCommunicationDeleteTemplate.CallOptions, ): Promise { return this._client.call( 'tools.ozone.communication.deleteTemplate', opts?.qp, data, opts, ) } listTemplates( params?: ToolsOzoneCommunicationListTemplates.QueryParams, opts?: ToolsOzoneCommunicationListTemplates.CallOptions, ): Promise { return this._client.call( 'tools.ozone.communication.listTemplates', params, undefined, opts, ) } updateTemplate( data?: ToolsOzoneCommunicationUpdateTemplate.InputSchema, opts?: ToolsOzoneCommunicationUpdateTemplate.CallOptions, ): Promise { return this._client .call('tools.ozone.communication.updateTemplate', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneCommunicationUpdateTemplate.toKnownErr(e) }) } } export class ToolsOzoneHostingNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } getAccountHistory( params?: ToolsOzoneHostingGetAccountHistory.QueryParams, opts?: ToolsOzoneHostingGetAccountHistory.CallOptions, ): Promise { return this._client.call( 'tools.ozone.hosting.getAccountHistory', params, undefined, opts, ) } } export class ToolsOzoneModerationNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } cancelScheduledActions( data?: ToolsOzoneModerationCancelScheduledActions.InputSchema, opts?: ToolsOzoneModerationCancelScheduledActions.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.cancelScheduledActions', opts?.qp, data, opts, ) } emitEvent( data?: ToolsOzoneModerationEmitEvent.InputSchema, opts?: ToolsOzoneModerationEmitEvent.CallOptions, ): Promise { return this._client .call('tools.ozone.moderation.emitEvent', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneModerationEmitEvent.toKnownErr(e) }) } getAccountTimeline( params?: ToolsOzoneModerationGetAccountTimeline.QueryParams, opts?: ToolsOzoneModerationGetAccountTimeline.CallOptions, ): Promise { return this._client .call( 'tools.ozone.moderation.getAccountTimeline', params, undefined, opts, ) .catch((e) => { throw ToolsOzoneModerationGetAccountTimeline.toKnownErr(e) }) } getEvent( params?: ToolsOzoneModerationGetEvent.QueryParams, opts?: ToolsOzoneModerationGetEvent.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.getEvent', params, undefined, opts, ) } getRecord( params?: ToolsOzoneModerationGetRecord.QueryParams, opts?: ToolsOzoneModerationGetRecord.CallOptions, ): Promise { return this._client .call('tools.ozone.moderation.getRecord', params, undefined, opts) .catch((e) => { throw ToolsOzoneModerationGetRecord.toKnownErr(e) }) } getRecords( params?: ToolsOzoneModerationGetRecords.QueryParams, opts?: ToolsOzoneModerationGetRecords.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.getRecords', params, undefined, opts, ) } getRepo( params?: ToolsOzoneModerationGetRepo.QueryParams, opts?: ToolsOzoneModerationGetRepo.CallOptions, ): Promise { return this._client .call('tools.ozone.moderation.getRepo', params, undefined, opts) .catch((e) => { throw ToolsOzoneModerationGetRepo.toKnownErr(e) }) } getReporterStats( params?: ToolsOzoneModerationGetReporterStats.QueryParams, opts?: ToolsOzoneModerationGetReporterStats.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.getReporterStats', params, undefined, opts, ) } getRepos( params?: ToolsOzoneModerationGetRepos.QueryParams, opts?: ToolsOzoneModerationGetRepos.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.getRepos', params, undefined, opts, ) } getSubjects( params?: ToolsOzoneModerationGetSubjects.QueryParams, opts?: ToolsOzoneModerationGetSubjects.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.getSubjects', params, undefined, opts, ) } listScheduledActions( data?: ToolsOzoneModerationListScheduledActions.InputSchema, opts?: ToolsOzoneModerationListScheduledActions.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.listScheduledActions', opts?.qp, data, opts, ) } queryEvents( params?: ToolsOzoneModerationQueryEvents.QueryParams, opts?: ToolsOzoneModerationQueryEvents.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.queryEvents', params, undefined, opts, ) } queryStatuses( params?: ToolsOzoneModerationQueryStatuses.QueryParams, opts?: ToolsOzoneModerationQueryStatuses.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.queryStatuses', params, undefined, opts, ) } scheduleAction( data?: ToolsOzoneModerationScheduleAction.InputSchema, opts?: ToolsOzoneModerationScheduleAction.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.scheduleAction', opts?.qp, data, opts, ) } searchRepos( params?: ToolsOzoneModerationSearchRepos.QueryParams, opts?: ToolsOzoneModerationSearchRepos.CallOptions, ): Promise { return this._client.call( 'tools.ozone.moderation.searchRepos', params, undefined, opts, ) } } export class ToolsOzoneSafelinkNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } addRule( data?: ToolsOzoneSafelinkAddRule.InputSchema, opts?: ToolsOzoneSafelinkAddRule.CallOptions, ): Promise { return this._client .call('tools.ozone.safelink.addRule', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneSafelinkAddRule.toKnownErr(e) }) } queryEvents( data?: ToolsOzoneSafelinkQueryEvents.InputSchema, opts?: ToolsOzoneSafelinkQueryEvents.CallOptions, ): Promise { return this._client.call( 'tools.ozone.safelink.queryEvents', opts?.qp, data, opts, ) } queryRules( data?: ToolsOzoneSafelinkQueryRules.InputSchema, opts?: ToolsOzoneSafelinkQueryRules.CallOptions, ): Promise { return this._client.call( 'tools.ozone.safelink.queryRules', opts?.qp, data, opts, ) } removeRule( data?: ToolsOzoneSafelinkRemoveRule.InputSchema, opts?: ToolsOzoneSafelinkRemoveRule.CallOptions, ): Promise { return this._client .call('tools.ozone.safelink.removeRule', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneSafelinkRemoveRule.toKnownErr(e) }) } updateRule( data?: ToolsOzoneSafelinkUpdateRule.InputSchema, opts?: ToolsOzoneSafelinkUpdateRule.CallOptions, ): Promise { return this._client .call('tools.ozone.safelink.updateRule', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneSafelinkUpdateRule.toKnownErr(e) }) } } export class ToolsOzoneServerNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } getConfig( params?: ToolsOzoneServerGetConfig.QueryParams, opts?: ToolsOzoneServerGetConfig.CallOptions, ): Promise { return this._client.call( 'tools.ozone.server.getConfig', params, undefined, opts, ) } } export class ToolsOzoneSetNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } addValues( data?: ToolsOzoneSetAddValues.InputSchema, opts?: ToolsOzoneSetAddValues.CallOptions, ): Promise { return this._client.call('tools.ozone.set.addValues', opts?.qp, data, opts) } deleteSet( data?: ToolsOzoneSetDeleteSet.InputSchema, opts?: ToolsOzoneSetDeleteSet.CallOptions, ): Promise { return this._client .call('tools.ozone.set.deleteSet', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneSetDeleteSet.toKnownErr(e) }) } deleteValues( data?: ToolsOzoneSetDeleteValues.InputSchema, opts?: ToolsOzoneSetDeleteValues.CallOptions, ): Promise { return this._client .call('tools.ozone.set.deleteValues', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneSetDeleteValues.toKnownErr(e) }) } getValues( params?: ToolsOzoneSetGetValues.QueryParams, opts?: ToolsOzoneSetGetValues.CallOptions, ): Promise { return this._client .call('tools.ozone.set.getValues', params, undefined, opts) .catch((e) => { throw ToolsOzoneSetGetValues.toKnownErr(e) }) } querySets( params?: ToolsOzoneSetQuerySets.QueryParams, opts?: ToolsOzoneSetQuerySets.CallOptions, ): Promise { return this._client.call( 'tools.ozone.set.querySets', params, undefined, opts, ) } upsertSet( data?: ToolsOzoneSetUpsertSet.InputSchema, opts?: ToolsOzoneSetUpsertSet.CallOptions, ): Promise { return this._client.call('tools.ozone.set.upsertSet', opts?.qp, data, opts) } } export class ToolsOzoneSettingNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } listOptions( params?: ToolsOzoneSettingListOptions.QueryParams, opts?: ToolsOzoneSettingListOptions.CallOptions, ): Promise { return this._client.call( 'tools.ozone.setting.listOptions', params, undefined, opts, ) } removeOptions( data?: ToolsOzoneSettingRemoveOptions.InputSchema, opts?: ToolsOzoneSettingRemoveOptions.CallOptions, ): Promise { return this._client.call( 'tools.ozone.setting.removeOptions', opts?.qp, data, opts, ) } upsertOption( data?: ToolsOzoneSettingUpsertOption.InputSchema, opts?: ToolsOzoneSettingUpsertOption.CallOptions, ): Promise { return this._client.call( 'tools.ozone.setting.upsertOption', opts?.qp, data, opts, ) } } export class ToolsOzoneSignatureNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } findCorrelation( params?: ToolsOzoneSignatureFindCorrelation.QueryParams, opts?: ToolsOzoneSignatureFindCorrelation.CallOptions, ): Promise { return this._client.call( 'tools.ozone.signature.findCorrelation', params, undefined, opts, ) } findRelatedAccounts( params?: ToolsOzoneSignatureFindRelatedAccounts.QueryParams, opts?: ToolsOzoneSignatureFindRelatedAccounts.CallOptions, ): Promise { return this._client.call( 'tools.ozone.signature.findRelatedAccounts', params, undefined, opts, ) } searchAccounts( params?: ToolsOzoneSignatureSearchAccounts.QueryParams, opts?: ToolsOzoneSignatureSearchAccounts.CallOptions, ): Promise { return this._client.call( 'tools.ozone.signature.searchAccounts', params, undefined, opts, ) } } export class ToolsOzoneTeamNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } addMember( data?: ToolsOzoneTeamAddMember.InputSchema, opts?: ToolsOzoneTeamAddMember.CallOptions, ): Promise { return this._client .call('tools.ozone.team.addMember', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneTeamAddMember.toKnownErr(e) }) } deleteMember( data?: ToolsOzoneTeamDeleteMember.InputSchema, opts?: ToolsOzoneTeamDeleteMember.CallOptions, ): Promise { return this._client .call('tools.ozone.team.deleteMember', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneTeamDeleteMember.toKnownErr(e) }) } listMembers( params?: ToolsOzoneTeamListMembers.QueryParams, opts?: ToolsOzoneTeamListMembers.CallOptions, ): Promise { return this._client.call( 'tools.ozone.team.listMembers', params, undefined, opts, ) } updateMember( data?: ToolsOzoneTeamUpdateMember.InputSchema, opts?: ToolsOzoneTeamUpdateMember.CallOptions, ): Promise { return this._client .call('tools.ozone.team.updateMember', opts?.qp, data, opts) .catch((e) => { throw ToolsOzoneTeamUpdateMember.toKnownErr(e) }) } } export class ToolsOzoneVerificationNS { _client: XrpcClient constructor(client: XrpcClient) { this._client = client } grantVerifications( data?: ToolsOzoneVerificationGrantVerifications.InputSchema, opts?: ToolsOzoneVerificationGrantVerifications.CallOptions, ): Promise { return this._client.call( 'tools.ozone.verification.grantVerifications', opts?.qp, data, opts, ) } listVerifications( params?: ToolsOzoneVerificationListVerifications.QueryParams, opts?: ToolsOzoneVerificationListVerifications.CallOptions, ): Promise { return this._client.call( 'tools.ozone.verification.listVerifications', params, undefined, opts, ) } revokeVerifications( data?: ToolsOzoneVerificationRevokeVerifications.InputSchema, opts?: ToolsOzoneVerificationRevokeVerifications.CallOptions, ): Promise { return this._client.call( 'tools.ozone.verification.revokeVerifications', opts?.qp, data, opts, ) } } ================================================ FILE: packages/api/src/client/lexicons.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type LexiconDoc, Lexicons, ValidationError, type ValidationResult, } from '@atproto/lexicon' import { type $Typed, is$typed, maybe$typed } from './util.js' export const schemaDict = { AppBskyActorDefs: { lexicon: 1, id: 'app.bsky.actor.defs', defs: { profileViewBasic: { type: 'object', required: ['did', 'handle'], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, displayName: { type: 'string', maxGraphemes: 64, maxLength: 640, }, pronouns: { type: 'string', }, avatar: { type: 'string', format: 'uri', }, associated: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileAssociated', }, viewer: { type: 'ref', ref: 'lex:app.bsky.actor.defs#viewerState', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, createdAt: { type: 'string', format: 'datetime', }, verification: { type: 'ref', ref: 'lex:app.bsky.actor.defs#verificationState', }, status: { type: 'ref', ref: 'lex:app.bsky.actor.defs#statusView', }, debug: { type: 'unknown', description: 'Debug information for internal development', }, }, }, profileView: { type: 'object', required: ['did', 'handle'], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, displayName: { type: 'string', maxGraphemes: 64, maxLength: 640, }, pronouns: { type: 'string', }, description: { type: 'string', maxGraphemes: 256, maxLength: 2560, }, avatar: { type: 'string', format: 'uri', }, associated: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileAssociated', }, indexedAt: { type: 'string', format: 'datetime', }, createdAt: { type: 'string', format: 'datetime', }, viewer: { type: 'ref', ref: 'lex:app.bsky.actor.defs#viewerState', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, verification: { type: 'ref', ref: 'lex:app.bsky.actor.defs#verificationState', }, status: { type: 'ref', ref: 'lex:app.bsky.actor.defs#statusView', }, debug: { type: 'unknown', description: 'Debug information for internal development', }, }, }, profileViewDetailed: { type: 'object', required: ['did', 'handle'], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, displayName: { type: 'string', maxGraphemes: 64, maxLength: 640, }, description: { type: 'string', maxGraphemes: 256, maxLength: 2560, }, pronouns: { type: 'string', }, website: { type: 'string', format: 'uri', }, avatar: { type: 'string', format: 'uri', }, banner: { type: 'string', format: 'uri', }, followersCount: { type: 'integer', }, followsCount: { type: 'integer', }, postsCount: { type: 'integer', }, associated: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileAssociated', }, joinedViaStarterPack: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackViewBasic', }, indexedAt: { type: 'string', format: 'datetime', }, createdAt: { type: 'string', format: 'datetime', }, viewer: { type: 'ref', ref: 'lex:app.bsky.actor.defs#viewerState', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, pinnedPost: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, verification: { type: 'ref', ref: 'lex:app.bsky.actor.defs#verificationState', }, status: { type: 'ref', ref: 'lex:app.bsky.actor.defs#statusView', }, debug: { type: 'unknown', description: 'Debug information for internal development', }, }, }, profileAssociated: { type: 'object', properties: { lists: { type: 'integer', }, feedgens: { type: 'integer', }, starterPacks: { type: 'integer', }, labeler: { type: 'boolean', }, chat: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileAssociatedChat', }, activitySubscription: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileAssociatedActivitySubscription', }, germ: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileAssociatedGerm', }, }, }, profileAssociatedChat: { type: 'object', required: ['allowIncoming'], properties: { allowIncoming: { type: 'string', knownValues: ['all', 'none', 'following'], }, }, }, profileAssociatedGerm: { type: 'object', required: ['showButtonTo', 'messageMeUrl'], properties: { messageMeUrl: { type: 'string', format: 'uri', }, showButtonTo: { type: 'string', knownValues: ['usersIFollow', 'everyone'], }, }, }, profileAssociatedActivitySubscription: { type: 'object', required: ['allowSubscriptions'], properties: { allowSubscriptions: { type: 'string', knownValues: ['followers', 'mutuals', 'none'], }, }, }, viewerState: { type: 'object', description: "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.", properties: { muted: { type: 'boolean', }, mutedByList: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listViewBasic', }, blockedBy: { type: 'boolean', }, blocking: { type: 'string', format: 'at-uri', }, blockingByList: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listViewBasic', }, following: { type: 'string', format: 'at-uri', }, followedBy: { type: 'string', format: 'at-uri', }, knownFollowers: { description: 'This property is present only in selected cases, as an optimization.', type: 'ref', ref: 'lex:app.bsky.actor.defs#knownFollowers', }, activitySubscription: { description: 'This property is present only in selected cases, as an optimization.', type: 'ref', ref: 'lex:app.bsky.notification.defs#activitySubscription', }, }, }, knownFollowers: { type: 'object', description: "The subject's followers whom you also follow", required: ['count', 'followers'], properties: { count: { type: 'integer', }, followers: { type: 'array', minLength: 0, maxLength: 5, items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, }, }, }, verificationState: { type: 'object', description: 'Represents the verification information about the user this object is attached to.', required: ['verifications', 'verifiedStatus', 'trustedVerifierStatus'], properties: { verifications: { type: 'array', description: 'All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included.', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#verificationView', }, }, verifiedStatus: { type: 'string', description: "The user's status as a verified account.", knownValues: ['valid', 'invalid', 'none'], }, trustedVerifierStatus: { type: 'string', description: "The user's status as a trusted verifier.", knownValues: ['valid', 'invalid', 'none'], }, }, }, verificationView: { type: 'object', description: 'An individual verification for an associated subject.', required: ['issuer', 'uri', 'isValid', 'createdAt'], properties: { issuer: { type: 'string', description: 'The user who issued this verification.', format: 'did', }, uri: { type: 'string', description: 'The AT-URI of the verification record.', format: 'at-uri', }, isValid: { type: 'boolean', description: 'True if the verification passes validation, otherwise false.', }, createdAt: { type: 'string', description: 'Timestamp when the verification was created.', format: 'datetime', }, }, }, preferences: { type: 'array', items: { type: 'union', refs: [ 'lex:app.bsky.actor.defs#adultContentPref', 'lex:app.bsky.actor.defs#contentLabelPref', 'lex:app.bsky.actor.defs#savedFeedsPref', 'lex:app.bsky.actor.defs#savedFeedsPrefV2', 'lex:app.bsky.actor.defs#personalDetailsPref', 'lex:app.bsky.actor.defs#declaredAgePref', 'lex:app.bsky.actor.defs#feedViewPref', 'lex:app.bsky.actor.defs#threadViewPref', 'lex:app.bsky.actor.defs#interestsPref', 'lex:app.bsky.actor.defs#mutedWordsPref', 'lex:app.bsky.actor.defs#hiddenPostsPref', 'lex:app.bsky.actor.defs#bskyAppStatePref', 'lex:app.bsky.actor.defs#labelersPref', 'lex:app.bsky.actor.defs#postInteractionSettingsPref', 'lex:app.bsky.actor.defs#verificationPrefs', 'lex:app.bsky.actor.defs#liveEventPreferences', ], }, }, adultContentPref: { type: 'object', required: ['enabled'], properties: { enabled: { type: 'boolean', default: false, }, }, }, contentLabelPref: { type: 'object', required: ['label', 'visibility'], properties: { labelerDid: { type: 'string', description: 'Which labeler does this preference apply to? If undefined, applies globally.', format: 'did', }, label: { type: 'string', }, visibility: { type: 'string', knownValues: ['ignore', 'show', 'warn', 'hide'], }, }, }, savedFeed: { type: 'object', required: ['id', 'type', 'value', 'pinned'], properties: { id: { type: 'string', }, type: { type: 'string', knownValues: ['feed', 'list', 'timeline'], }, value: { type: 'string', }, pinned: { type: 'boolean', }, }, }, savedFeedsPrefV2: { type: 'object', required: ['items'], properties: { items: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#savedFeed', }, }, }, }, savedFeedsPref: { type: 'object', required: ['pinned', 'saved'], properties: { pinned: { type: 'array', items: { type: 'string', format: 'at-uri', }, }, saved: { type: 'array', items: { type: 'string', format: 'at-uri', }, }, timelineIndex: { type: 'integer', }, }, }, personalDetailsPref: { type: 'object', properties: { birthDate: { type: 'string', format: 'datetime', description: 'The birth date of account owner.', }, }, }, declaredAgePref: { type: 'object', description: "Read-only preference containing value(s) inferred from the user's declared birthdate. Absence of this preference object in the response indicates that the user has not made a declaration.", properties: { isOverAge13: { type: 'boolean', description: 'Indicates if the user has declared that they are over 13 years of age.', }, isOverAge16: { type: 'boolean', description: 'Indicates if the user has declared that they are over 16 years of age.', }, isOverAge18: { type: 'boolean', description: 'Indicates if the user has declared that they are over 18 years of age.', }, }, }, feedViewPref: { type: 'object', required: ['feed'], properties: { feed: { type: 'string', description: 'The URI of the feed, or an identifier which describes the feed.', }, hideReplies: { type: 'boolean', description: 'Hide replies in the feed.', }, hideRepliesByUnfollowed: { type: 'boolean', description: 'Hide replies in the feed if they are not by followed users.', default: true, }, hideRepliesByLikeCount: { type: 'integer', description: 'Hide replies in the feed if they do not have this number of likes.', }, hideReposts: { type: 'boolean', description: 'Hide reposts in the feed.', }, hideQuotePosts: { type: 'boolean', description: 'Hide quote posts in the feed.', }, }, }, threadViewPref: { type: 'object', properties: { sort: { type: 'string', description: 'Sorting mode for threads.', knownValues: [ 'oldest', 'newest', 'most-likes', 'random', 'hotness', ], }, }, }, interestsPref: { type: 'object', required: ['tags'], properties: { tags: { type: 'array', maxLength: 100, items: { type: 'string', maxLength: 640, maxGraphemes: 64, }, description: "A list of tags which describe the account owner's interests gathered during onboarding.", }, }, }, mutedWordTarget: { type: 'string', knownValues: ['content', 'tag'], maxLength: 640, maxGraphemes: 64, }, mutedWord: { type: 'object', description: 'A word that the account owner has muted.', required: ['value', 'targets'], properties: { id: { type: 'string', }, value: { type: 'string', description: 'The muted word itself.', maxLength: 10000, maxGraphemes: 1000, }, targets: { type: 'array', description: 'The intended targets of the muted word.', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#mutedWordTarget', }, }, actorTarget: { type: 'string', description: 'Groups of users to apply the muted word to. If undefined, applies to all users.', knownValues: ['all', 'exclude-following'], default: 'all', }, expiresAt: { type: 'string', format: 'datetime', description: 'The date and time at which the muted word will expire and no longer be applied.', }, }, }, mutedWordsPref: { type: 'object', required: ['items'], properties: { items: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#mutedWord', }, description: 'A list of words the account owner has muted.', }, }, }, hiddenPostsPref: { type: 'object', required: ['items'], properties: { items: { type: 'array', items: { type: 'string', format: 'at-uri', }, description: 'A list of URIs of posts the account owner has hidden.', }, }, }, labelersPref: { type: 'object', required: ['labelers'], properties: { labelers: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#labelerPrefItem', }, }, }, }, labelerPrefItem: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, bskyAppStatePref: { description: "A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this.", type: 'object', properties: { activeProgressGuide: { type: 'ref', ref: 'lex:app.bsky.actor.defs#bskyAppProgressGuide', }, queuedNudges: { description: 'An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user.', type: 'array', maxLength: 1000, items: { type: 'string', maxLength: 100, }, }, nuxs: { description: 'Storage for NUXs the user has encountered.', type: 'array', maxLength: 100, items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#nux', }, }, }, }, bskyAppProgressGuide: { description: 'If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress.', type: 'object', required: ['guide'], properties: { guide: { type: 'string', maxLength: 100, }, }, }, nux: { type: 'object', description: 'A new user experiences (NUX) storage object', required: ['id', 'completed'], properties: { id: { type: 'string', maxLength: 100, }, completed: { type: 'boolean', default: false, }, data: { description: 'Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters.', type: 'string', maxLength: 3000, maxGraphemes: 300, }, expiresAt: { type: 'string', format: 'datetime', description: 'The date and time at which the NUX will expire and should be considered completed.', }, }, }, verificationPrefs: { type: 'object', description: 'Preferences for how verified accounts appear in the app.', required: [], properties: { hideBadges: { description: 'Hide the blue check badges for verified accounts and trusted verifiers.', type: 'boolean', default: false, }, }, }, liveEventPreferences: { type: 'object', description: 'Preferences for live events.', properties: { hiddenFeedIds: { description: 'A list of feed IDs that the user has hidden from live events.', type: 'array', items: { type: 'string', }, }, hideAllFeeds: { description: 'Whether to hide all feeds from live events.', type: 'boolean', default: false, }, }, }, postInteractionSettingsPref: { type: 'object', description: 'Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.', required: [], properties: { threadgateAllowRules: { description: 'Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.', type: 'array', maxLength: 5, items: { type: 'union', refs: [ 'lex:app.bsky.feed.threadgate#mentionRule', 'lex:app.bsky.feed.threadgate#followerRule', 'lex:app.bsky.feed.threadgate#followingRule', 'lex:app.bsky.feed.threadgate#listRule', ], }, }, postgateEmbeddingRules: { description: 'Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.', type: 'array', maxLength: 5, items: { type: 'union', refs: ['lex:app.bsky.feed.postgate#disableRule'], }, }, }, }, statusView: { type: 'object', required: ['status', 'record'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, status: { type: 'string', description: 'The status for the account.', knownValues: ['app.bsky.actor.status#live'], }, record: { type: 'unknown', }, embed: { type: 'union', description: 'An optional embed associated with the status.', refs: ['lex:app.bsky.embed.external#view'], }, expiresAt: { type: 'string', description: 'The date when this status will expire. The application might choose to no longer return the status after expiration.', format: 'datetime', }, isActive: { type: 'boolean', description: 'True if the status is not expired, false if it is expired. Only present if expiration was set.', }, isDisabled: { type: 'boolean', description: "True if the user's go-live access has been disabled by a moderator, false otherwise.", }, }, }, }, }, AppBskyActorGetPreferences: { lexicon: 1, id: 'app.bsky.actor.getPreferences', defs: { main: { type: 'query', description: 'Get private preferences attached to the current account. Expected use is synchronization between multiple devices, and import/export during account migration. Requires auth.', parameters: { type: 'params', properties: {}, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['preferences'], properties: { preferences: { type: 'ref', ref: 'lex:app.bsky.actor.defs#preferences', }, }, }, }, }, }, }, AppBskyActorGetProfile: { lexicon: 1, id: 'app.bsky.actor.getProfile', defs: { main: { type: 'query', description: 'Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', description: 'Handle or DID of account to fetch profile of.', }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewDetailed', }, }, }, }, }, AppBskyActorGetProfiles: { lexicon: 1, id: 'app.bsky.actor.getProfiles', defs: { main: { type: 'query', description: 'Get detailed profile views of multiple actors.', parameters: { type: 'params', required: ['actors'], properties: { actors: { type: 'array', items: { type: 'string', format: 'at-identifier', }, maxLength: 25, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['profiles'], properties: { profiles: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewDetailed', }, }, }, }, }, }, }, }, AppBskyActorGetSuggestions: { lexicon: 1, id: 'app.bsky.actor.getSuggestions', defs: { main: { type: 'query', description: 'Get a list of suggested actors. Expected use is discovery of accounts to follow during new account onboarding.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actors'], properties: { cursor: { type: 'string', }, actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, recId: { type: 'integer', description: 'DEPRECATED: use recIdStr instead.', }, recIdStr: { type: 'string', description: 'Snowflake for this recommendation, use when submitting recommendation events.', }, }, }, }, }, }, }, AppBskyActorProfile: { lexicon: 1, id: 'app.bsky.actor.profile', defs: { main: { type: 'record', description: 'A declaration of a Bluesky account profile.', key: 'literal:self', record: { type: 'object', properties: { displayName: { type: 'string', maxGraphemes: 64, maxLength: 640, }, description: { type: 'string', description: 'Free-form profile description text.', maxGraphemes: 256, maxLength: 2560, }, pronouns: { type: 'string', description: 'Free-form pronouns text.', maxGraphemes: 20, maxLength: 200, }, website: { type: 'string', format: 'uri', }, avatar: { type: 'blob', description: "Small image to be displayed next to posts from account. AKA, 'profile picture'", accept: ['image/png', 'image/jpeg'], maxSize: 1000000, }, banner: { type: 'blob', description: 'Larger horizontal image to display behind profile view.', accept: ['image/png', 'image/jpeg'], maxSize: 1000000, }, labels: { type: 'union', description: 'Self-label values, specific to the Bluesky application, on the overall account.', refs: ['lex:com.atproto.label.defs#selfLabels'], }, joinedViaStarterPack: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, pinnedPost: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, }, }, AppBskyActorPutPreferences: { lexicon: 1, id: 'app.bsky.actor.putPreferences', defs: { main: { type: 'procedure', description: 'Set the private preferences attached to the account.', input: { encoding: 'application/json', schema: { type: 'object', required: ['preferences'], properties: { preferences: { type: 'ref', ref: 'lex:app.bsky.actor.defs#preferences', }, }, }, }, }, }, }, AppBskyActorSearchActors: { lexicon: 1, id: 'app.bsky.actor.searchActors', defs: { main: { type: 'query', description: 'Find actors (profiles) matching search criteria. Does not require auth.', parameters: { type: 'params', properties: { term: { type: 'string', description: "DEPRECATED: use 'q' instead.", }, q: { type: 'string', description: 'Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 25, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actors'], properties: { cursor: { type: 'string', }, actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyActorSearchActorsTypeahead: { lexicon: 1, id: 'app.bsky.actor.searchActorsTypeahead', defs: { main: { type: 'query', description: 'Find actor suggestions for a prefix search term. Expected use is for auto-completion during text field entry. Does not require auth.', parameters: { type: 'params', properties: { term: { type: 'string', description: "DEPRECATED: use 'q' instead.", }, q: { type: 'string', description: 'Search query prefix; not a full query string.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actors'], properties: { actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, }, }, }, }, }, }, }, AppBskyActorStatus: { lexicon: 1, id: 'app.bsky.actor.status', defs: { main: { type: 'record', description: 'A declaration of a Bluesky account status.', key: 'literal:self', record: { type: 'object', required: ['status', 'createdAt'], properties: { status: { type: 'string', description: 'The status for the account.', knownValues: ['app.bsky.actor.status#live'], }, embed: { type: 'union', description: 'An optional embed associated with the status.', refs: ['lex:app.bsky.embed.external'], }, durationMinutes: { type: 'integer', description: 'The duration of the status in minutes. Applications can choose to impose minimum and maximum limits.', minimum: 1, }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, live: { type: 'token', description: 'Advertises an account as currently offering live content.', }, }, }, AppBskyAgeassuranceBegin: { lexicon: 1, id: 'app.bsky.ageassurance.begin', defs: { main: { type: 'procedure', description: 'Initiate Age Assurance for an account.', input: { encoding: 'application/json', schema: { type: 'object', required: ['email', 'language', 'countryCode'], properties: { email: { type: 'string', description: "The user's email address to receive Age Assurance instructions.", }, language: { type: 'string', description: "The user's preferred language for communication during the Age Assurance process.", }, countryCode: { type: 'string', description: "An ISO 3166-1 alpha-2 code of the user's location.", }, regionCode: { type: 'string', description: "An optional ISO 3166-2 code of the user's region or state within the country.", }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#state', }, }, errors: [ { name: 'InvalidEmail', }, { name: 'DidTooLong', }, { name: 'InvalidInitiation', }, { name: 'RegionNotSupported', }, ], }, }, }, AppBskyAgeassuranceDefs: { lexicon: 1, id: 'app.bsky.ageassurance.defs', defs: { access: { description: "The access level granted based on Age Assurance data we've processed.", type: 'string', knownValues: ['unknown', 'none', 'safe', 'full'], }, status: { type: 'string', description: 'The status of the Age Assurance process.', knownValues: ['unknown', 'pending', 'assured', 'blocked'], }, state: { type: 'object', description: "The user's computed Age Assurance state.", required: ['status', 'access'], properties: { lastInitiatedAt: { type: 'string', format: 'datetime', description: 'The timestamp when this state was last updated.', }, status: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#status', }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, stateMetadata: { type: 'object', description: 'Additional metadata needed to compute Age Assurance state client-side.', required: [], properties: { accountCreatedAt: { type: 'string', format: 'datetime', description: 'The account creation timestamp.', }, }, }, config: { type: 'object', description: '', required: ['regions'], properties: { regions: { type: 'array', description: 'The per-region Age Assurance configuration.', items: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#configRegion', }, }, }, }, configRegion: { type: 'object', description: 'The Age Assurance configuration for a specific region.', required: ['countryCode', 'minAccessAge', 'rules'], properties: { countryCode: { type: 'string', description: 'The ISO 3166-1 alpha-2 country code this configuration applies to.', }, regionCode: { type: 'string', description: 'The ISO 3166-2 region code this configuration applies to. If omitted, the configuration applies to the entire country.', }, minAccessAge: { type: 'integer', description: 'The minimum age (as a whole integer) required to use Bluesky in this region.', }, rules: { type: 'array', description: 'The ordered list of Age Assurance rules that apply to this region. Rules should be applied in order, and the first matching rule determines the access level granted. The rules array should always include a default rule as the last item.', items: { type: 'union', refs: [ 'lex:app.bsky.ageassurance.defs#configRegionRuleDefault', 'lex:app.bsky.ageassurance.defs#configRegionRuleIfDeclaredOverAge', 'lex:app.bsky.ageassurance.defs#configRegionRuleIfDeclaredUnderAge', 'lex:app.bsky.ageassurance.defs#configRegionRuleIfAssuredOverAge', 'lex:app.bsky.ageassurance.defs#configRegionRuleIfAssuredUnderAge', 'lex:app.bsky.ageassurance.defs#configRegionRuleIfAccountNewerThan', 'lex:app.bsky.ageassurance.defs#configRegionRuleIfAccountOlderThan', ], }, }, }, }, configRegionRuleDefault: { type: 'object', description: 'Age Assurance rule that applies by default.', required: ['access'], properties: { access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, configRegionRuleIfDeclaredOverAge: { type: 'object', description: 'Age Assurance rule that applies if the user has declared themselves equal-to or over a certain age.', required: ['age', 'access'], properties: { age: { type: 'integer', description: 'The age threshold as a whole integer.', }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, configRegionRuleIfDeclaredUnderAge: { type: 'object', description: 'Age Assurance rule that applies if the user has declared themselves under a certain age.', required: ['age', 'access'], properties: { age: { type: 'integer', description: 'The age threshold as a whole integer.', }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, configRegionRuleIfAssuredOverAge: { type: 'object', description: 'Age Assurance rule that applies if the user has been assured to be equal-to or over a certain age.', required: ['age', 'access'], properties: { age: { type: 'integer', description: 'The age threshold as a whole integer.', }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, configRegionRuleIfAssuredUnderAge: { type: 'object', description: 'Age Assurance rule that applies if the user has been assured to be under a certain age.', required: ['age', 'access'], properties: { age: { type: 'integer', description: 'The age threshold as a whole integer.', }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, configRegionRuleIfAccountNewerThan: { type: 'object', description: 'Age Assurance rule that applies if the account is equal-to or newer than a certain date.', required: ['date', 'access'], properties: { date: { type: 'string', format: 'datetime', description: 'The date threshold as a datetime string.', }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, configRegionRuleIfAccountOlderThan: { type: 'object', description: 'Age Assurance rule that applies if the account is older than a certain date.', required: ['date', 'access'], properties: { date: { type: 'string', format: 'datetime', description: 'The date threshold as a datetime string.', }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, }, }, event: { type: 'object', description: 'Object used to store Age Assurance data in stash.', required: ['createdAt', 'status', 'access', 'attemptId', 'countryCode'], properties: { createdAt: { type: 'string', format: 'datetime', description: 'The date and time of this write operation.', }, attemptId: { type: 'string', description: 'The unique identifier for this instance of the Age Assurance flow, in UUID format.', }, status: { type: 'string', description: 'The status of the Age Assurance process.', knownValues: ['unknown', 'pending', 'assured', 'blocked'], }, access: { description: "The access level granted based on Age Assurance data we've processed.", type: 'string', knownValues: ['unknown', 'none', 'safe', 'full'], }, countryCode: { type: 'string', description: 'The ISO 3166-1 alpha-2 country code provided when beginning the Age Assurance flow.', }, regionCode: { type: 'string', description: 'The ISO 3166-2 region code provided when beginning the Age Assurance flow.', }, email: { type: 'string', description: 'The email used for Age Assurance.', }, initIp: { type: 'string', description: 'The IP address used when initiating the Age Assurance flow.', }, initUa: { type: 'string', description: 'The user agent used when initiating the Age Assurance flow.', }, completeIp: { type: 'string', description: 'The IP address used when completing the Age Assurance flow.', }, completeUa: { type: 'string', description: 'The user agent used when completing the Age Assurance flow.', }, }, }, }, }, AppBskyAgeassuranceGetConfig: { lexicon: 1, id: 'app.bsky.ageassurance.getConfig', defs: { main: { type: 'query', description: 'Returns Age Assurance configuration for use on the client.', output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#config', }, }, }, }, }, AppBskyAgeassuranceGetState: { lexicon: 1, id: 'app.bsky.ageassurance.getState', defs: { main: { type: 'query', description: 'Returns server-computed Age Assurance state, if available, and any additional metadata needed to compute Age Assurance state client-side.', parameters: { type: 'params', required: ['countryCode'], properties: { countryCode: { type: 'string', }, regionCode: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['state', 'metadata'], properties: { state: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#state', }, metadata: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#stateMetadata', }, }, }, }, }, }, }, AppBskyBookmarkCreateBookmark: { lexicon: 1, id: 'app.bsky.bookmark.createBookmark', defs: { main: { type: 'procedure', description: 'Creates a private bookmark for the specified record. Currently, only `app.bsky.feed.post` records are supported. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['uri', 'cid'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, }, }, }, errors: [ { name: 'UnsupportedCollection', description: 'The URI to be bookmarked is for an unsupported collection.', }, ], }, }, }, AppBskyBookmarkDefs: { lexicon: 1, id: 'app.bsky.bookmark.defs', defs: { bookmark: { description: 'Object used to store bookmark data in stash.', type: 'object', required: ['subject'], properties: { subject: { description: 'A strong ref to the record to be bookmarked. Currently, only `app.bsky.feed.post` records are supported.', type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, }, }, bookmarkView: { type: 'object', required: ['subject', 'item'], properties: { subject: { description: 'A strong ref to the bookmarked record.', type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, createdAt: { type: 'string', format: 'datetime', }, item: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#blockedPost', 'lex:app.bsky.feed.defs#notFoundPost', 'lex:app.bsky.feed.defs#postView', ], }, }, }, }, }, AppBskyBookmarkDeleteBookmark: { lexicon: 1, id: 'app.bsky.bookmark.deleteBookmark', defs: { main: { type: 'procedure', description: 'Deletes a private bookmark for the specified record. Currently, only `app.bsky.feed.post` records are supported. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', }, }, }, }, errors: [ { name: 'UnsupportedCollection', description: 'The URI to be bookmarked is for an unsupported collection.', }, ], }, }, }, AppBskyBookmarkGetBookmarks: { lexicon: 1, id: 'app.bsky.bookmark.getBookmarks', defs: { main: { type: 'query', description: 'Gets views of records bookmarked by the authenticated user. Requires authentication.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['bookmarks'], properties: { cursor: { type: 'string', }, bookmarks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.bookmark.defs#bookmarkView', }, }, }, }, }, }, }, }, AppBskyContactDefs: { lexicon: 1, id: 'app.bsky.contact.defs', defs: { matchAndContactIndex: { description: 'Associates a profile with the positional index of the contact import input in the call to `app.bsky.contact.importContacts`, so clients can know which phone caused a particular match.', type: 'object', required: ['match', 'contactIndex'], properties: { match: { description: 'Profile of the matched user.', type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, contactIndex: { description: 'The index of this match in the import contact input.', type: 'integer', minimum: 0, maximum: 999, }, }, }, syncStatus: { type: 'object', required: ['syncedAt', 'matchesCount'], properties: { syncedAt: { description: 'Last date when contacts where imported.', type: 'string', format: 'datetime', }, matchesCount: { description: 'Number of existing contact matches resulting of the user imports and of their imported contacts having imported the user. Matches stop being counted when the user either follows the matched contact or dismisses the match.', type: 'integer', minimum: 0, }, }, }, notification: { description: 'A stash object to be sent via bsync representing a notification to be created.', type: 'object', required: ['from', 'to'], properties: { from: { description: 'The DID of who this notification comes from.', type: 'string', format: 'did', }, to: { description: 'The DID of who this notification should go to.', type: 'string', format: 'did', }, }, }, }, }, AppBskyContactDismissMatch: { lexicon: 1, id: 'app.bsky.contact.dismissMatch', defs: { main: { type: 'procedure', description: "Removes a match that was found via contact import. It shouldn't appear again if the same contact is re-imported. Requires authentication.", input: { encoding: 'application/json', schema: { type: 'object', required: ['subject'], properties: { subject: { description: "The subject's DID to dismiss the match with.", type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, errors: [ { name: 'InvalidDid', }, { name: 'InternalError', }, ], }, }, }, AppBskyContactGetMatches: { lexicon: 1, id: 'app.bsky.contact.getMatches', defs: { main: { type: 'query', description: 'Returns the matched contacts (contacts that were mutually imported). Excludes dismissed matches. Requires authentication.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['matches'], properties: { cursor: { type: 'string', }, matches: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, errors: [ { name: 'InvalidDid', }, { name: 'InvalidLimit', }, { name: 'InvalidCursor', }, { name: 'InternalError', }, ], }, }, }, AppBskyContactGetSyncStatus: { lexicon: 1, id: 'app.bsky.contact.getSyncStatus', defs: { main: { type: 'query', description: "Gets the user's current contact import status. Requires authentication.", parameters: { type: 'params', properties: {}, }, output: { encoding: 'application/json', schema: { type: 'object', properties: { syncStatus: { description: "If present, indicates the user has imported their contacts. If not present, indicates the user never used the feature or called `app.bsky.contact.removeData` and didn't import again since.", type: 'ref', ref: 'lex:app.bsky.contact.defs#syncStatus', }, }, }, }, errors: [ { name: 'InvalidDid', }, { name: 'InternalError', }, ], }, }, }, AppBskyContactImportContacts: { lexicon: 1, id: 'app.bsky.contact.importContacts', defs: { main: { type: 'procedure', description: 'Import contacts for securely matching with other users. This follows the protocol explained in https://docs.bsky.app/blog/contact-import-rfc. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['token', 'contacts'], properties: { token: { description: 'JWT to authenticate the call. Use the JWT received as a response to the call to `app.bsky.contact.verifyPhone`.', type: 'string', }, contacts: { description: "List of phone numbers in global E.164 format (e.g., '+12125550123'). Phone numbers that cannot be normalized into a valid phone number will be discarded. Should not repeat the 'phone' input used in `app.bsky.contact.verifyPhone`.", type: 'array', items: { type: 'string', }, minLength: 1, maxLength: 1000, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['matchesAndContactIndexes'], properties: { matchesAndContactIndexes: { description: 'The users that matched during import and their indexes on the input contacts, so the client can correlate with its local list.', type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.contact.defs#matchAndContactIndex', }, }, }, }, }, errors: [ { name: 'InvalidDid', }, { name: 'InvalidContacts', }, { name: 'TooManyContacts', }, { name: 'InvalidToken', }, { name: 'InternalError', }, ], }, }, }, AppBskyContactRemoveData: { lexicon: 1, id: 'app.bsky.contact.removeData', defs: { main: { type: 'procedure', description: 'Removes all stored hashes used for contact matching, existing matches, and sync status. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, errors: [ { name: 'InvalidDid', }, { name: 'InternalError', }, ], }, }, }, AppBskyContactSendNotification: { lexicon: 1, id: 'app.bsky.contact.sendNotification', defs: { main: { type: 'procedure', description: 'System endpoint to send notifications related to contact imports. Requires role authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['from', 'to'], properties: { from: { description: 'The DID of who this notification comes from.', type: 'string', format: 'did', }, to: { description: 'The DID of who this notification should go to.', type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, }, }, }, AppBskyContactStartPhoneVerification: { lexicon: 1, id: 'app.bsky.contact.startPhoneVerification', defs: { main: { type: 'procedure', description: 'Starts a phone verification flow. The phone passed will receive a code via SMS that should be passed to `app.bsky.contact.verifyPhone`. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['phone'], properties: { phone: { description: 'The phone number to receive the code via SMS.', type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, errors: [ { name: 'RateLimitExceeded', }, { name: 'InvalidDid', }, { name: 'InvalidPhone', }, { name: 'InternalError', }, ], }, }, }, AppBskyContactVerifyPhone: { lexicon: 1, id: 'app.bsky.contact.verifyPhone', defs: { main: { type: 'procedure', description: 'Verifies control over a phone number with a code received via SMS and starts a contact import session. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['phone', 'code'], properties: { phone: { description: 'The phone number to verify. Should be the same as the one passed to `app.bsky.contact.startPhoneVerification`.', type: 'string', }, code: { description: 'The code received via SMS as a result of the call to `app.bsky.contact.startPhoneVerification`.', type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['token'], properties: { token: { description: 'JWT to be used in a call to `app.bsky.contact.importContacts`. It is only valid for a single call.', type: 'string', }, }, }, }, errors: [ { name: 'RateLimitExceeded', }, { name: 'InvalidDid', }, { name: 'InvalidPhone', }, { name: 'InvalidCode', }, { name: 'InternalError', }, ], }, }, }, AppBskyDraftCreateDraft: { lexicon: 1, id: 'app.bsky.draft.createDraft', defs: { main: { type: 'procedure', description: 'Inserts a draft using private storage (stash). An upper limit of drafts might be enforced. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['draft'], properties: { draft: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draft', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['id'], properties: { id: { type: 'string', description: 'The ID of the created draft.', }, }, }, }, errors: [ { name: 'DraftLimitReached', description: 'Trying to insert a new draft when the limit was already reached.', }, ], }, }, }, AppBskyDraftDefs: { lexicon: 1, id: 'app.bsky.draft.defs', defs: { draftWithId: { description: 'A draft with an identifier, used to store drafts in private storage (stash).', type: 'object', required: ['id', 'draft'], properties: { id: { description: 'A TID to be used as a draft identifier.', type: 'string', format: 'tid', }, draft: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draft', }, }, }, draft: { description: 'A draft containing an array of draft posts.', type: 'object', required: ['posts'], properties: { deviceId: { type: 'string', description: 'UUIDv4 identifier of the device that created this draft.', maxLength: 100, }, deviceName: { type: 'string', description: 'The device and/or platform on which the draft was created.', maxLength: 100, }, posts: { description: 'Array of draft posts that compose this draft.', type: 'array', minLength: 1, maxLength: 100, items: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftPost', }, }, langs: { type: 'array', description: 'Indicates human language of posts primary text content.', maxLength: 3, items: { type: 'string', format: 'language', }, }, postgateEmbeddingRules: { description: 'Embedding rules for the postgates to be created when this draft is published.', type: 'array', maxLength: 5, items: { type: 'union', refs: ['lex:app.bsky.feed.postgate#disableRule'], }, }, threadgateAllow: { description: 'Allow-rules for the threadgate to be created when this draft is published.', type: 'array', maxLength: 5, items: { type: 'union', refs: [ 'lex:app.bsky.feed.threadgate#mentionRule', 'lex:app.bsky.feed.threadgate#followerRule', 'lex:app.bsky.feed.threadgate#followingRule', 'lex:app.bsky.feed.threadgate#listRule', ], }, }, }, }, draftPost: { description: 'One of the posts that compose a draft.', type: 'object', required: ['text'], properties: { text: { type: 'string', maxLength: 10000, maxGraphemes: 1000, description: 'The primary post content. It has a higher limit than post contents to allow storing a larger text that can later be refined into smaller posts.', }, labels: { type: 'union', description: 'Self-label values for this post. Effectively content warnings.', refs: ['lex:com.atproto.label.defs#selfLabels'], }, embedImages: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftEmbedImage', }, maxLength: 4, }, embedVideos: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftEmbedVideo', }, maxLength: 1, }, embedExternals: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftEmbedExternal', }, maxLength: 1, }, embedRecords: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftEmbedRecord', }, maxLength: 1, }, }, }, draftView: { description: 'View to present drafts data to users.', type: 'object', required: ['id', 'draft', 'createdAt', 'updatedAt'], properties: { id: { description: 'A TID to be used as a draft identifier.', type: 'string', format: 'tid', }, draft: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draft', }, createdAt: { description: 'The time the draft was created.', type: 'string', format: 'datetime', }, updatedAt: { description: 'The time the draft was last updated.', type: 'string', format: 'datetime', }, }, }, draftEmbedLocalRef: { type: 'object', required: ['path'], properties: { path: { type: 'string', description: 'Local, on-device ref to file to be embedded. Embeds are currently device-bound for drafts.', minLength: 1, maxLength: 1024, }, }, }, draftEmbedCaption: { type: 'object', required: ['lang', 'content'], properties: { lang: { type: 'string', format: 'language', }, content: { type: 'string', maxLength: 10000, }, }, }, draftEmbedImage: { type: 'object', required: ['localRef'], properties: { localRef: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftEmbedLocalRef', }, alt: { type: 'string', maxGraphemes: 2000, }, }, }, draftEmbedVideo: { type: 'object', required: ['localRef'], properties: { localRef: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftEmbedLocalRef', }, alt: { type: 'string', maxGraphemes: 2000, }, captions: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftEmbedCaption', }, maxLength: 20, }, }, }, draftEmbedExternal: { type: 'object', required: ['uri'], properties: { uri: { type: 'string', format: 'uri', }, }, }, draftEmbedRecord: { type: 'object', required: ['record'], properties: { record: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, }, }, }, }, AppBskyDraftDeleteDraft: { lexicon: 1, id: 'app.bsky.draft.deleteDraft', defs: { main: { type: 'procedure', description: 'Deletes a draft by ID. Requires authentication.', input: { encoding: 'application/json', schema: { type: 'object', required: ['id'], properties: { id: { type: 'string', format: 'tid', }, }, }, }, }, }, }, AppBskyDraftGetDrafts: { lexicon: 1, id: 'app.bsky.draft.getDrafts', defs: { main: { type: 'query', description: 'Gets views of user drafts. Requires authentication.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['drafts'], properties: { cursor: { type: 'string', }, drafts: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftView', }, }, }, }, }, }, }, }, AppBskyDraftUpdateDraft: { lexicon: 1, id: 'app.bsky.draft.updateDraft', defs: { main: { type: 'procedure', description: "Updates a draft using private storage (stash). If the draft ID points to a non-existing ID, the update will be silently ignored. This is done because updates don't enforce draft limit, so it accepts all writes, but will ignore invalid ones. Requires authentication.", input: { encoding: 'application/json', schema: { type: 'object', required: ['draft'], properties: { draft: { type: 'ref', ref: 'lex:app.bsky.draft.defs#draftWithId', }, }, }, }, }, }, }, AppBskyEmbedDefs: { lexicon: 1, id: 'app.bsky.embed.defs', defs: { aspectRatio: { type: 'object', description: 'width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.', required: ['width', 'height'], properties: { width: { type: 'integer', minimum: 1, }, height: { type: 'integer', minimum: 1, }, }, }, }, }, AppBskyEmbedExternal: { lexicon: 1, id: 'app.bsky.embed.external', defs: { main: { type: 'object', description: "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).", required: ['external'], properties: { external: { type: 'ref', ref: 'lex:app.bsky.embed.external#external', }, }, }, external: { type: 'object', required: ['uri', 'title', 'description'], properties: { uri: { type: 'string', format: 'uri', }, title: { type: 'string', }, description: { type: 'string', }, thumb: { type: 'blob', accept: ['image/*'], maxSize: 1000000, }, }, }, view: { type: 'object', required: ['external'], properties: { external: { type: 'ref', ref: 'lex:app.bsky.embed.external#viewExternal', }, }, }, viewExternal: { type: 'object', required: ['uri', 'title', 'description'], properties: { uri: { type: 'string', format: 'uri', }, title: { type: 'string', }, description: { type: 'string', }, thumb: { type: 'string', format: 'uri', }, }, }, }, }, AppBskyEmbedImages: { lexicon: 1, id: 'app.bsky.embed.images', description: 'A set of images embedded in a Bluesky record (eg, a post).', defs: { main: { type: 'object', required: ['images'], properties: { images: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.embed.images#image', }, maxLength: 4, }, }, }, image: { type: 'object', required: ['image', 'alt'], properties: { image: { type: 'blob', accept: ['image/*'], maxSize: 1000000, }, alt: { type: 'string', description: 'Alt text description of the image, for accessibility.', }, aspectRatio: { type: 'ref', ref: 'lex:app.bsky.embed.defs#aspectRatio', }, }, }, view: { type: 'object', required: ['images'], properties: { images: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.embed.images#viewImage', }, maxLength: 4, }, }, }, viewImage: { type: 'object', required: ['thumb', 'fullsize', 'alt'], properties: { thumb: { type: 'string', format: 'uri', description: 'Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View.', }, fullsize: { type: 'string', format: 'uri', description: 'Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View.', }, alt: { type: 'string', description: 'Alt text description of the image, for accessibility.', }, aspectRatio: { type: 'ref', ref: 'lex:app.bsky.embed.defs#aspectRatio', }, }, }, }, }, AppBskyEmbedRecord: { lexicon: 1, id: 'app.bsky.embed.record', description: 'A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.', defs: { main: { type: 'object', required: ['record'], properties: { record: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, }, }, view: { type: 'object', required: ['record'], properties: { record: { type: 'union', refs: [ 'lex:app.bsky.embed.record#viewRecord', 'lex:app.bsky.embed.record#viewNotFound', 'lex:app.bsky.embed.record#viewBlocked', 'lex:app.bsky.embed.record#viewDetached', 'lex:app.bsky.feed.defs#generatorView', 'lex:app.bsky.graph.defs#listView', 'lex:app.bsky.labeler.defs#labelerView', 'lex:app.bsky.graph.defs#starterPackViewBasic', ], }, }, }, viewRecord: { type: 'object', required: ['uri', 'cid', 'author', 'value', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, author: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, value: { type: 'unknown', description: 'The record data itself.', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, replyCount: { type: 'integer', }, repostCount: { type: 'integer', }, likeCount: { type: 'integer', }, quoteCount: { type: 'integer', }, embeds: { type: 'array', items: { type: 'union', refs: [ 'lex:app.bsky.embed.images#view', 'lex:app.bsky.embed.video#view', 'lex:app.bsky.embed.external#view', 'lex:app.bsky.embed.record#view', 'lex:app.bsky.embed.recordWithMedia#view', ], }, }, indexedAt: { type: 'string', format: 'datetime', }, }, }, viewNotFound: { type: 'object', required: ['uri', 'notFound'], properties: { uri: { type: 'string', format: 'at-uri', }, notFound: { type: 'boolean', const: true, }, }, }, viewBlocked: { type: 'object', required: ['uri', 'blocked', 'author'], properties: { uri: { type: 'string', format: 'at-uri', }, blocked: { type: 'boolean', const: true, }, author: { type: 'ref', ref: 'lex:app.bsky.feed.defs#blockedAuthor', }, }, }, viewDetached: { type: 'object', required: ['uri', 'detached'], properties: { uri: { type: 'string', format: 'at-uri', }, detached: { type: 'boolean', const: true, }, }, }, }, }, AppBskyEmbedRecordWithMedia: { lexicon: 1, id: 'app.bsky.embed.recordWithMedia', description: 'A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.', defs: { main: { type: 'object', required: ['record', 'media'], properties: { record: { type: 'ref', ref: 'lex:app.bsky.embed.record', }, media: { type: 'union', refs: [ 'lex:app.bsky.embed.images', 'lex:app.bsky.embed.video', 'lex:app.bsky.embed.external', ], }, }, }, view: { type: 'object', required: ['record', 'media'], properties: { record: { type: 'ref', ref: 'lex:app.bsky.embed.record#view', }, media: { type: 'union', refs: [ 'lex:app.bsky.embed.images#view', 'lex:app.bsky.embed.video#view', 'lex:app.bsky.embed.external#view', ], }, }, }, }, }, AppBskyEmbedVideo: { lexicon: 1, id: 'app.bsky.embed.video', description: 'A video embedded in a Bluesky record (eg, a post).', defs: { main: { type: 'object', required: ['video'], properties: { video: { type: 'blob', description: 'The mp4 video file. May be up to 100mb, formerly limited to 50mb.', accept: ['video/mp4'], maxSize: 100000000, }, captions: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.embed.video#caption', }, maxLength: 20, }, alt: { type: 'string', description: 'Alt text description of the video, for accessibility.', maxGraphemes: 1000, maxLength: 10000, }, aspectRatio: { type: 'ref', ref: 'lex:app.bsky.embed.defs#aspectRatio', }, presentation: { type: 'string', description: 'A hint to the client about how to present the video.', knownValues: ['default', 'gif'], }, }, }, caption: { type: 'object', required: ['lang', 'file'], properties: { lang: { type: 'string', format: 'language', }, file: { type: 'blob', accept: ['text/vtt'], maxSize: 20000, }, }, }, view: { type: 'object', required: ['cid', 'playlist'], properties: { cid: { type: 'string', format: 'cid', }, playlist: { type: 'string', format: 'uri', }, thumbnail: { type: 'string', format: 'uri', }, alt: { type: 'string', maxGraphemes: 1000, maxLength: 10000, }, aspectRatio: { type: 'ref', ref: 'lex:app.bsky.embed.defs#aspectRatio', }, presentation: { type: 'string', description: 'A hint to the client about how to present the video.', knownValues: ['default', 'gif'], }, }, }, }, }, AppBskyFeedDefs: { lexicon: 1, id: 'app.bsky.feed.defs', defs: { postView: { type: 'object', required: ['uri', 'cid', 'author', 'record', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, author: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, record: { type: 'unknown', }, embed: { type: 'union', refs: [ 'lex:app.bsky.embed.images#view', 'lex:app.bsky.embed.video#view', 'lex:app.bsky.embed.external#view', 'lex:app.bsky.embed.record#view', 'lex:app.bsky.embed.recordWithMedia#view', ], }, bookmarkCount: { type: 'integer', }, replyCount: { type: 'integer', }, repostCount: { type: 'integer', }, likeCount: { type: 'integer', }, quoteCount: { type: 'integer', }, indexedAt: { type: 'string', format: 'datetime', }, viewer: { type: 'ref', ref: 'lex:app.bsky.feed.defs#viewerState', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, threadgate: { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, debug: { type: 'unknown', description: 'Debug information for internal development', }, }, }, viewerState: { type: 'object', description: "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.", properties: { repost: { type: 'string', format: 'at-uri', }, like: { type: 'string', format: 'at-uri', }, bookmarked: { type: 'boolean', }, threadMuted: { type: 'boolean', }, replyDisabled: { type: 'boolean', }, embeddingDisabled: { type: 'boolean', }, pinned: { type: 'boolean', }, }, }, threadContext: { type: 'object', description: 'Metadata about this post within the context of the thread it is in.', properties: { rootAuthorLike: { type: 'string', format: 'at-uri', }, }, }, feedViewPost: { type: 'object', required: ['post'], properties: { post: { type: 'ref', ref: 'lex:app.bsky.feed.defs#postView', }, reply: { type: 'ref', ref: 'lex:app.bsky.feed.defs#replyRef', }, reason: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#reasonRepost', 'lex:app.bsky.feed.defs#reasonPin', ], }, feedContext: { type: 'string', description: 'Context provided by feed generator that may be passed back alongside interactions.', maxLength: 2000, }, reqId: { type: 'string', description: 'Unique identifier per request that may be passed back alongside interactions.', maxLength: 100, }, }, }, replyRef: { type: 'object', required: ['root', 'parent'], properties: { root: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#postView', 'lex:app.bsky.feed.defs#notFoundPost', 'lex:app.bsky.feed.defs#blockedPost', ], }, parent: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#postView', 'lex:app.bsky.feed.defs#notFoundPost', 'lex:app.bsky.feed.defs#blockedPost', ], }, grandparentAuthor: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', description: 'When parent is a reply to another post, this is the author of that post.', }, }, }, reasonRepost: { type: 'object', required: ['by', 'indexedAt'], properties: { by: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, indexedAt: { type: 'string', format: 'datetime', }, }, }, reasonPin: { type: 'object', properties: {}, }, threadViewPost: { type: 'object', required: ['post'], properties: { post: { type: 'ref', ref: 'lex:app.bsky.feed.defs#postView', }, parent: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#threadViewPost', 'lex:app.bsky.feed.defs#notFoundPost', 'lex:app.bsky.feed.defs#blockedPost', ], }, replies: { type: 'array', items: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#threadViewPost', 'lex:app.bsky.feed.defs#notFoundPost', 'lex:app.bsky.feed.defs#blockedPost', ], }, }, threadContext: { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadContext', }, }, }, notFoundPost: { type: 'object', required: ['uri', 'notFound'], properties: { uri: { type: 'string', format: 'at-uri', }, notFound: { type: 'boolean', const: true, }, }, }, blockedPost: { type: 'object', required: ['uri', 'blocked', 'author'], properties: { uri: { type: 'string', format: 'at-uri', }, blocked: { type: 'boolean', const: true, }, author: { type: 'ref', ref: 'lex:app.bsky.feed.defs#blockedAuthor', }, }, }, blockedAuthor: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, viewer: { type: 'ref', ref: 'lex:app.bsky.actor.defs#viewerState', }, }, }, generatorView: { type: 'object', required: ['uri', 'cid', 'did', 'creator', 'displayName', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, did: { type: 'string', format: 'did', }, creator: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, displayName: { type: 'string', }, description: { type: 'string', maxGraphemes: 300, maxLength: 3000, }, descriptionFacets: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, avatar: { type: 'string', format: 'uri', }, likeCount: { type: 'integer', minimum: 0, }, acceptsInteractions: { type: 'boolean', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, viewer: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorViewerState', }, contentMode: { type: 'string', knownValues: [ 'app.bsky.feed.defs#contentModeUnspecified', 'app.bsky.feed.defs#contentModeVideo', ], }, indexedAt: { type: 'string', format: 'datetime', }, }, }, generatorViewerState: { type: 'object', properties: { like: { type: 'string', format: 'at-uri', }, }, }, skeletonFeedPost: { type: 'object', required: ['post'], properties: { post: { type: 'string', format: 'at-uri', }, reason: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#skeletonReasonRepost', 'lex:app.bsky.feed.defs#skeletonReasonPin', ], }, feedContext: { type: 'string', description: 'Context that will be passed through to client and may be passed to feed generator back alongside interactions.', maxLength: 2000, }, }, }, skeletonReasonRepost: { type: 'object', required: ['repost'], properties: { repost: { type: 'string', format: 'at-uri', }, }, }, skeletonReasonPin: { type: 'object', properties: {}, }, threadgateView: { type: 'object', properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, record: { type: 'unknown', }, lists: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listViewBasic', }, }, }, }, interaction: { type: 'object', properties: { item: { type: 'string', format: 'at-uri', }, event: { type: 'string', knownValues: [ 'app.bsky.feed.defs#requestLess', 'app.bsky.feed.defs#requestMore', 'app.bsky.feed.defs#clickthroughItem', 'app.bsky.feed.defs#clickthroughAuthor', 'app.bsky.feed.defs#clickthroughReposter', 'app.bsky.feed.defs#clickthroughEmbed', 'app.bsky.feed.defs#interactionSeen', 'app.bsky.feed.defs#interactionLike', 'app.bsky.feed.defs#interactionRepost', 'app.bsky.feed.defs#interactionReply', 'app.bsky.feed.defs#interactionQuote', 'app.bsky.feed.defs#interactionShare', ], }, feedContext: { type: 'string', description: 'Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton.', maxLength: 2000, }, reqId: { type: 'string', description: 'Unique identifier per request that may be passed back alongside interactions.', maxLength: 100, }, }, }, requestLess: { type: 'token', description: 'Request that less content like the given feed item be shown in the feed', }, requestMore: { type: 'token', description: 'Request that more content like the given feed item be shown in the feed', }, clickthroughItem: { type: 'token', description: 'User clicked through to the feed item', }, clickthroughAuthor: { type: 'token', description: 'User clicked through to the author of the feed item', }, clickthroughReposter: { type: 'token', description: 'User clicked through to the reposter of the feed item', }, clickthroughEmbed: { type: 'token', description: 'User clicked through to the embedded content of the feed item', }, contentModeUnspecified: { type: 'token', description: 'Declares the feed generator returns any types of posts.', }, contentModeVideo: { type: 'token', description: 'Declares the feed generator returns posts containing app.bsky.embed.video embeds.', }, interactionSeen: { type: 'token', description: 'Feed item was seen by user', }, interactionLike: { type: 'token', description: 'User liked the feed item', }, interactionRepost: { type: 'token', description: 'User reposted the feed item', }, interactionReply: { type: 'token', description: 'User replied to the feed item', }, interactionQuote: { type: 'token', description: 'User quoted the feed item', }, interactionShare: { type: 'token', description: 'User shared the feed item', }, }, }, AppBskyFeedDescribeFeedGenerator: { lexicon: 1, id: 'app.bsky.feed.describeFeedGenerator', defs: { main: { type: 'query', description: 'Get information about a feed generator, including policies and offered feed URIs. Does not require auth; implemented by Feed Generator services (not App View).', output: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'feeds'], properties: { did: { type: 'string', format: 'did', }, feeds: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.describeFeedGenerator#feed', }, }, links: { type: 'ref', ref: 'lex:app.bsky.feed.describeFeedGenerator#links', }, }, }, }, }, feed: { type: 'object', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', }, }, }, links: { type: 'object', properties: { privacyPolicy: { type: 'string', }, termsOfService: { type: 'string', }, }, }, }, }, AppBskyFeedGenerator: { lexicon: 1, id: 'app.bsky.feed.generator', defs: { main: { type: 'record', description: 'Record declaring of the existence of a feed generator, and containing metadata about it. The record can exist in any repository.', key: 'any', record: { type: 'object', required: ['did', 'displayName', 'createdAt'], properties: { did: { type: 'string', format: 'did', }, displayName: { type: 'string', maxGraphemes: 24, maxLength: 240, }, description: { type: 'string', maxGraphemes: 300, maxLength: 3000, }, descriptionFacets: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, avatar: { type: 'blob', accept: ['image/png', 'image/jpeg'], maxSize: 1000000, }, acceptsInteractions: { type: 'boolean', description: 'Declaration that a feed accepts feedback interactions from a client through app.bsky.feed.sendInteractions', }, labels: { type: 'union', description: 'Self-label values', refs: ['lex:com.atproto.label.defs#selfLabels'], }, contentMode: { type: 'string', knownValues: [ 'app.bsky.feed.defs#contentModeUnspecified', 'app.bsky.feed.defs#contentModeVideo', ], }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, }, }, AppBskyFeedGetActorFeeds: { lexicon: 1, id: 'app.bsky.feed.getActorFeeds', defs: { main: { type: 'query', description: "Get a list of feeds (feed generator records) created by the actor (in the actor's repo).", parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feeds'], properties: { cursor: { type: 'string', }, feeds: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorView', }, }, }, }, }, }, }, }, AppBskyFeedGetActorLikes: { lexicon: 1, id: 'app.bsky.feed.getActorLikes', defs: { main: { type: 'query', description: 'Get a list of posts liked by an actor. Requires auth, actor must be the requesting account.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feed'], properties: { cursor: { type: 'string', }, feed: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#feedViewPost', }, }, }, }, }, errors: [ { name: 'BlockedActor', }, { name: 'BlockedByActor', }, ], }, }, }, AppBskyFeedGetAuthorFeed: { lexicon: 1, id: 'app.bsky.feed.getAuthorFeed', defs: { main: { type: 'query', description: "Get a view of an actor's 'author feed' (post and reposts by the author). Does not require auth.", parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, filter: { type: 'string', description: 'Combinations of post/repost types to include in response.', knownValues: [ 'posts_with_replies', 'posts_no_replies', 'posts_with_media', 'posts_and_author_threads', 'posts_with_video', ], default: 'posts_with_replies', }, includePins: { type: 'boolean', default: false, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feed'], properties: { cursor: { type: 'string', }, feed: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#feedViewPost', }, }, }, }, }, errors: [ { name: 'BlockedActor', }, { name: 'BlockedByActor', }, ], }, }, }, AppBskyFeedGetFeed: { lexicon: 1, id: 'app.bsky.feed.getFeed', defs: { main: { type: 'query', description: "Get a hydrated feed from an actor's selected feed generator. Implemented by App View.", parameters: { type: 'params', required: ['feed'], properties: { feed: { type: 'string', format: 'at-uri', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feed'], properties: { cursor: { type: 'string', }, feed: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#feedViewPost', }, }, }, }, }, errors: [ { name: 'UnknownFeed', }, ], }, }, }, AppBskyFeedGetFeedGenerator: { lexicon: 1, id: 'app.bsky.feed.getFeedGenerator', defs: { main: { type: 'query', description: 'Get information about a feed generator. Implemented by AppView.', parameters: { type: 'params', required: ['feed'], properties: { feed: { type: 'string', format: 'at-uri', description: 'AT-URI of the feed generator record.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['view', 'isOnline', 'isValid'], properties: { view: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorView', }, isOnline: { type: 'boolean', description: 'Indicates whether the feed generator service has been online recently, or else seems to be inactive.', }, isValid: { type: 'boolean', description: 'Indicates whether the feed generator service is compatible with the record declaration.', }, }, }, }, }, }, }, AppBskyFeedGetFeedGenerators: { lexicon: 1, id: 'app.bsky.feed.getFeedGenerators', defs: { main: { type: 'query', description: 'Get information about a list of feed generators.', parameters: { type: 'params', required: ['feeds'], properties: { feeds: { type: 'array', items: { type: 'string', format: 'at-uri', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feeds'], properties: { feeds: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorView', }, }, }, }, }, }, }, }, AppBskyFeedGetFeedSkeleton: { lexicon: 1, id: 'app.bsky.feed.getFeedSkeleton', defs: { main: { type: 'query', description: 'Get a skeleton of a feed provided by a feed generator. Auth is optional, depending on provider requirements, and provides the DID of the requester. Implemented by Feed Generator Service.', parameters: { type: 'params', required: ['feed'], properties: { feed: { type: 'string', format: 'at-uri', description: 'Reference to feed generator record describing the specific feed being requested.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feed'], properties: { cursor: { type: 'string', }, feed: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#skeletonFeedPost', }, }, reqId: { type: 'string', description: 'Unique identifier per request that may be passed back alongside interactions.', maxLength: 100, }, }, }, }, errors: [ { name: 'UnknownFeed', }, ], }, }, }, AppBskyFeedGetLikes: { lexicon: 1, id: 'app.bsky.feed.getLikes', defs: { main: { type: 'query', description: 'Get like records which reference a subject (by AT-URI and CID).', parameters: { type: 'params', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', description: 'AT-URI of the subject (eg, a post record).', }, cid: { type: 'string', format: 'cid', description: 'CID of the subject record (aka, specific version of record), to filter likes.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['uri', 'likes'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, cursor: { type: 'string', }, likes: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.getLikes#like', }, }, }, }, }, }, like: { type: 'object', required: ['indexedAt', 'createdAt', 'actor'], properties: { indexedAt: { type: 'string', format: 'datetime', }, createdAt: { type: 'string', format: 'datetime', }, actor: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, AppBskyFeedGetListFeed: { lexicon: 1, id: 'app.bsky.feed.getListFeed', defs: { main: { type: 'query', description: 'Get a feed of recent posts from a list (posts and reposts from any actors on the list). Does not require auth.', parameters: { type: 'params', required: ['list'], properties: { list: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to the list record.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feed'], properties: { cursor: { type: 'string', }, feed: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#feedViewPost', }, }, }, }, }, errors: [ { name: 'UnknownList', }, ], }, }, }, AppBskyFeedGetPostThread: { lexicon: 1, id: 'app.bsky.feed.getPostThread', defs: { main: { type: 'query', description: 'Get posts in a thread. Does not require auth, but additional metadata and filtering will be applied for authed requests.', parameters: { type: 'params', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to post record.', }, depth: { type: 'integer', description: 'How many levels of reply depth should be included in response.', default: 6, minimum: 0, maximum: 1000, }, parentHeight: { type: 'integer', description: 'How many levels of parent (and grandparent, etc) post to include.', default: 80, minimum: 0, maximum: 1000, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['thread'], properties: { thread: { type: 'union', refs: [ 'lex:app.bsky.feed.defs#threadViewPost', 'lex:app.bsky.feed.defs#notFoundPost', 'lex:app.bsky.feed.defs#blockedPost', ], }, threadgate: { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, }, }, }, errors: [ { name: 'NotFound', }, ], }, }, }, AppBskyFeedGetPosts: { lexicon: 1, id: 'app.bsky.feed.getPosts', defs: { main: { type: 'query', description: "Gets post views for a specified list of posts (by AT-URI). This is sometimes referred to as 'hydrating' a 'feed skeleton'.", parameters: { type: 'params', required: ['uris'], properties: { uris: { type: 'array', description: 'List of post AT-URIs to return hydrated views for.', items: { type: 'string', format: 'at-uri', }, maxLength: 25, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['posts'], properties: { posts: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#postView', }, }, }, }, }, }, }, }, AppBskyFeedGetQuotes: { lexicon: 1, id: 'app.bsky.feed.getQuotes', defs: { main: { type: 'query', description: 'Get a list of quotes for a given post.', parameters: { type: 'params', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) of post record', }, cid: { type: 'string', format: 'cid', description: 'If supplied, filters to quotes of specific version (by CID) of the post record.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['uri', 'posts'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, cursor: { type: 'string', }, posts: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#postView', }, }, }, }, }, }, }, }, AppBskyFeedGetRepostedBy: { lexicon: 1, id: 'app.bsky.feed.getRepostedBy', defs: { main: { type: 'query', description: 'Get a list of reposts for a given post.', parameters: { type: 'params', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) of post record', }, cid: { type: 'string', format: 'cid', description: 'If supplied, filters to reposts of specific version (by CID) of the post record.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['uri', 'repostedBy'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, cursor: { type: 'string', }, repostedBy: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyFeedGetSuggestedFeeds: { lexicon: 1, id: 'app.bsky.feed.getSuggestedFeeds', defs: { main: { type: 'query', description: 'Get a list of suggested feeds (feed generators) for the requesting account.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feeds'], properties: { cursor: { type: 'string', }, feeds: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorView', }, }, }, }, }, }, }, }, AppBskyFeedGetTimeline: { lexicon: 1, id: 'app.bsky.feed.getTimeline', defs: { main: { type: 'query', description: "Get a view of the requesting account's home timeline. This is expected to be some form of reverse-chronological feed.", parameters: { type: 'params', properties: { algorithm: { type: 'string', description: "Variant 'algorithm' for timeline. Implementation-specific. NOTE: most feed flexibility has been moved to feed generator mechanism.", }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feed'], properties: { cursor: { type: 'string', }, feed: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#feedViewPost', }, }, }, }, }, }, }, }, AppBskyFeedLike: { lexicon: 1, id: 'app.bsky.feed.like', defs: { main: { type: 'record', description: "Record declaring a 'like' of a piece of subject content.", key: 'tid', record: { type: 'object', required: ['subject', 'createdAt'], properties: { subject: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, createdAt: { type: 'string', format: 'datetime', }, via: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, }, }, }, }, }, AppBskyFeedPost: { lexicon: 1, id: 'app.bsky.feed.post', defs: { main: { type: 'record', description: 'Record containing a Bluesky post.', key: 'tid', record: { type: 'object', required: ['text', 'createdAt'], properties: { text: { type: 'string', maxLength: 3000, maxGraphemes: 300, description: 'The primary post content. May be an empty string, if there are embeds.', }, entities: { type: 'array', description: 'DEPRECATED: replaced by app.bsky.richtext.facet.', items: { type: 'ref', ref: 'lex:app.bsky.feed.post#entity', }, }, facets: { type: 'array', description: 'Annotations of text (mentions, URLs, hashtags, etc)', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, reply: { type: 'ref', ref: 'lex:app.bsky.feed.post#replyRef', }, embed: { type: 'union', refs: [ 'lex:app.bsky.embed.images', 'lex:app.bsky.embed.video', 'lex:app.bsky.embed.external', 'lex:app.bsky.embed.record', 'lex:app.bsky.embed.recordWithMedia', ], }, langs: { type: 'array', description: 'Indicates human language of post primary text content.', maxLength: 3, items: { type: 'string', format: 'language', }, }, labels: { type: 'union', description: 'Self-label values for this post. Effectively content warnings.', refs: ['lex:com.atproto.label.defs#selfLabels'], }, tags: { type: 'array', description: 'Additional hashtags, in addition to any included in post text and facets.', maxLength: 8, items: { type: 'string', maxLength: 640, maxGraphemes: 64, }, }, createdAt: { type: 'string', format: 'datetime', description: 'Client-declared timestamp when this post was originally created.', }, }, }, }, replyRef: { type: 'object', required: ['root', 'parent'], properties: { root: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, parent: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, }, }, entity: { type: 'object', description: 'Deprecated: use facets instead.', required: ['index', 'type', 'value'], properties: { index: { type: 'ref', ref: 'lex:app.bsky.feed.post#textSlice', }, type: { type: 'string', description: "Expected values are 'mention' and 'link'.", }, value: { type: 'string', }, }, }, textSlice: { type: 'object', description: 'Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.', required: ['start', 'end'], properties: { start: { type: 'integer', minimum: 0, }, end: { type: 'integer', minimum: 0, }, }, }, }, }, AppBskyFeedPostgate: { lexicon: 1, id: 'app.bsky.feed.postgate', defs: { main: { type: 'record', key: 'tid', description: 'Record defining interaction rules for a post. The record key (rkey) of the postgate record must match the record key of the post, and that record must be in the same repository.', record: { type: 'object', required: ['post', 'createdAt'], properties: { createdAt: { type: 'string', format: 'datetime', }, post: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to the post record.', }, detachedEmbeddingUris: { type: 'array', maxLength: 50, items: { type: 'string', format: 'at-uri', }, description: 'List of AT-URIs embedding this post that the author has detached from.', }, embeddingRules: { description: 'List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.', type: 'array', maxLength: 5, items: { type: 'union', refs: ['lex:app.bsky.feed.postgate#disableRule'], }, }, }, }, }, disableRule: { type: 'object', description: 'Disables embedding of this post.', properties: {}, }, }, }, AppBskyFeedRepost: { lexicon: 1, id: 'app.bsky.feed.repost', defs: { main: { description: "Record representing a 'repost' of an existing Bluesky post.", type: 'record', key: 'tid', record: { type: 'object', required: ['subject', 'createdAt'], properties: { subject: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, createdAt: { type: 'string', format: 'datetime', }, via: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, }, }, }, }, }, AppBskyFeedSearchPosts: { lexicon: 1, id: 'app.bsky.feed.searchPosts', defs: { main: { type: 'query', description: 'Find posts matching search criteria, returning views of those posts. Note that this API endpoint may require authentication (eg, not public) for some service providers and implementations.', parameters: { type: 'params', required: ['q'], properties: { q: { type: 'string', description: 'Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.', }, sort: { type: 'string', knownValues: ['top', 'latest'], default: 'latest', description: 'Specifies the ranking order of results.', }, since: { type: 'string', description: "Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD).", }, until: { type: 'string', description: "Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD).", }, mentions: { type: 'string', format: 'at-identifier', description: 'Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions.', }, author: { type: 'string', format: 'at-identifier', description: 'Filter to posts by the given account. Handles are resolved to DID before query-time.', }, lang: { type: 'string', format: 'language', description: 'Filter to posts in the given language. Expected to be based on post language field, though server may override language detection.', }, domain: { type: 'string', description: 'Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization.', }, url: { type: 'string', format: 'uri', description: 'Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching.', }, tag: { type: 'array', items: { type: 'string', maxLength: 640, maxGraphemes: 64, }, description: "Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching.", }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 25, }, cursor: { type: 'string', description: 'Optional pagination mechanism; may not necessarily allow scrolling through entire result set.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['posts'], properties: { cursor: { type: 'string', }, hitsTotal: { type: 'integer', description: 'Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.', }, posts: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#postView', }, }, }, }, }, errors: [ { name: 'BadQueryString', }, ], }, }, }, AppBskyFeedSendInteractions: { lexicon: 1, id: 'app.bsky.feed.sendInteractions', defs: { main: { type: 'procedure', description: 'Send information about interactions with feed items back to the feed generator that served them.', input: { encoding: 'application/json', schema: { type: 'object', required: ['interactions'], properties: { feed: { type: 'string', format: 'at-uri', }, interactions: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#interaction', }, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, }, }, }, AppBskyFeedThreadgate: { lexicon: 1, id: 'app.bsky.feed.threadgate', defs: { main: { type: 'record', key: 'tid', description: "Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository.", record: { type: 'object', required: ['post', 'createdAt'], properties: { post: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to the post record.', }, allow: { description: 'List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.', type: 'array', maxLength: 5, items: { type: 'union', refs: [ 'lex:app.bsky.feed.threadgate#mentionRule', 'lex:app.bsky.feed.threadgate#followerRule', 'lex:app.bsky.feed.threadgate#followingRule', 'lex:app.bsky.feed.threadgate#listRule', ], }, }, createdAt: { type: 'string', format: 'datetime', }, hiddenReplies: { type: 'array', maxLength: 300, items: { type: 'string', format: 'at-uri', }, description: 'List of hidden reply URIs.', }, }, }, }, mentionRule: { type: 'object', description: 'Allow replies from actors mentioned in your post.', properties: {}, }, followerRule: { type: 'object', description: 'Allow replies from actors who follow you.', properties: {}, }, followingRule: { type: 'object', description: 'Allow replies from actors you follow.', properties: {}, }, listRule: { type: 'object', description: 'Allow replies from actors on a list.', required: ['list'], properties: { list: { type: 'string', format: 'at-uri', }, }, }, }, }, AppBskyGraphBlock: { lexicon: 1, id: 'app.bsky.graph.block', defs: { main: { type: 'record', description: "Record declaring a 'block' relationship against another account. NOTE: blocks are public in Bluesky; see blog posts for details.", key: 'tid', record: { type: 'object', required: ['subject', 'createdAt'], properties: { subject: { type: 'string', format: 'did', description: 'DID of the account to be blocked.', }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, }, }, AppBskyGraphDefs: { lexicon: 1, id: 'app.bsky.graph.defs', defs: { listViewBasic: { type: 'object', required: ['uri', 'cid', 'name', 'purpose'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, name: { type: 'string', maxLength: 64, minLength: 1, }, purpose: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listPurpose', }, avatar: { type: 'string', format: 'uri', }, listItemCount: { type: 'integer', minimum: 0, }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, viewer: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listViewerState', }, indexedAt: { type: 'string', format: 'datetime', }, }, }, listView: { type: 'object', required: ['uri', 'cid', 'creator', 'name', 'purpose', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, creator: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, name: { type: 'string', maxLength: 64, minLength: 1, }, purpose: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listPurpose', }, description: { type: 'string', maxGraphemes: 300, maxLength: 3000, }, descriptionFacets: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, avatar: { type: 'string', format: 'uri', }, listItemCount: { type: 'integer', minimum: 0, }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, viewer: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listViewerState', }, indexedAt: { type: 'string', format: 'datetime', }, }, }, listItemView: { type: 'object', required: ['uri', 'subject'], properties: { uri: { type: 'string', format: 'at-uri', }, subject: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, starterPackView: { type: 'object', required: ['uri', 'cid', 'record', 'creator', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, record: { type: 'unknown', }, creator: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, list: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listViewBasic', }, listItemsSample: { type: 'array', maxLength: 12, items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listItemView', }, }, feeds: { type: 'array', maxLength: 3, items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorView', }, }, joinedWeekCount: { type: 'integer', minimum: 0, }, joinedAllTimeCount: { type: 'integer', minimum: 0, }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, indexedAt: { type: 'string', format: 'datetime', }, }, }, starterPackViewBasic: { type: 'object', required: ['uri', 'cid', 'record', 'creator', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, record: { type: 'unknown', }, creator: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, listItemCount: { type: 'integer', minimum: 0, }, joinedWeekCount: { type: 'integer', minimum: 0, }, joinedAllTimeCount: { type: 'integer', minimum: 0, }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, indexedAt: { type: 'string', format: 'datetime', }, }, }, listPurpose: { type: 'string', knownValues: [ 'app.bsky.graph.defs#modlist', 'app.bsky.graph.defs#curatelist', 'app.bsky.graph.defs#referencelist', ], }, modlist: { type: 'token', description: 'A list of actors to apply an aggregate moderation action (mute/block) on.', }, curatelist: { type: 'token', description: 'A list of actors used for curation purposes such as list feeds or interaction gating.', }, referencelist: { type: 'token', description: 'A list of actors used for only for reference purposes such as within a starter pack.', }, listViewerState: { type: 'object', properties: { muted: { type: 'boolean', }, blocked: { type: 'string', format: 'at-uri', }, }, }, notFoundActor: { type: 'object', description: 'indicates that a handle or DID could not be resolved', required: ['actor', 'notFound'], properties: { actor: { type: 'string', format: 'at-identifier', }, notFound: { type: 'boolean', const: true, }, }, }, relationship: { type: 'object', description: 'lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)', required: ['did'], properties: { did: { type: 'string', format: 'did', }, following: { type: 'string', format: 'at-uri', description: 'if the actor follows this DID, this is the AT-URI of the follow record', }, followedBy: { type: 'string', format: 'at-uri', description: 'if the actor is followed by this DID, contains the AT-URI of the follow record', }, blocking: { type: 'string', format: 'at-uri', description: 'if the actor blocks this DID, this is the AT-URI of the block record', }, blockedBy: { type: 'string', format: 'at-uri', description: 'if the actor is blocked by this DID, contains the AT-URI of the block record', }, blockingByList: { type: 'string', format: 'at-uri', description: 'if the actor blocks this DID via a block list, this is the AT-URI of the listblock record', }, blockedByList: { type: 'string', format: 'at-uri', description: 'if the actor is blocked by this DID via a block list, contains the AT-URI of the listblock record', }, }, }, }, }, AppBskyGraphFollow: { lexicon: 1, id: 'app.bsky.graph.follow', defs: { main: { type: 'record', description: "Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView.", key: 'tid', record: { type: 'object', required: ['subject', 'createdAt'], properties: { subject: { type: 'string', format: 'did', }, createdAt: { type: 'string', format: 'datetime', }, via: { type: 'ref', ref: 'lex:com.atproto.repo.strongRef', }, }, }, }, }, }, AppBskyGraphGetActorStarterPacks: { lexicon: 1, id: 'app.bsky.graph.getActorStarterPacks', defs: { main: { type: 'query', description: 'Get a list of starter packs created by the actor.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { cursor: { type: 'string', }, starterPacks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackViewBasic', }, }, }, }, }, }, }, }, AppBskyGraphGetBlocks: { lexicon: 1, id: 'app.bsky.graph.getBlocks', defs: { main: { type: 'query', description: 'Enumerates which accounts the requesting account is currently blocking. Requires auth.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['blocks'], properties: { cursor: { type: 'string', }, blocks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyGraphGetFollowers: { lexicon: 1, id: 'app.bsky.graph.getFollowers', defs: { main: { type: 'query', description: 'Enumerates accounts which follow a specified account (actor).', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subject', 'followers'], properties: { subject: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, cursor: { type: 'string', }, followers: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyGraphGetFollows: { lexicon: 1, id: 'app.bsky.graph.getFollows', defs: { main: { type: 'query', description: 'Enumerates accounts which a specified account (actor) follows.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subject', 'follows'], properties: { subject: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, cursor: { type: 'string', }, follows: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyGraphGetKnownFollowers: { lexicon: 1, id: 'app.bsky.graph.getKnownFollowers', defs: { main: { type: 'query', description: 'Enumerates accounts which follow a specified account (actor) and are followed by the viewer.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subject', 'followers'], properties: { subject: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, cursor: { type: 'string', }, followers: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyGraphGetList: { lexicon: 1, id: 'app.bsky.graph.getList', defs: { main: { type: 'query', description: "Gets a 'view' (with additional context) of a specified list.", parameters: { type: 'params', required: ['list'], properties: { list: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) of the list record to hydrate.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['list', 'items'], properties: { cursor: { type: 'string', }, list: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listView', }, items: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listItemView', }, }, }, }, }, }, }, }, AppBskyGraphGetListBlocks: { lexicon: 1, id: 'app.bsky.graph.getListBlocks', defs: { main: { type: 'query', description: 'Get mod lists that the requesting account (actor) is blocking. Requires auth.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['lists'], properties: { cursor: { type: 'string', }, lists: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listView', }, }, }, }, }, }, }, }, AppBskyGraphGetListMutes: { lexicon: 1, id: 'app.bsky.graph.getListMutes', defs: { main: { type: 'query', description: 'Enumerates mod lists that the requesting account (actor) currently has muted. Requires auth.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['lists'], properties: { cursor: { type: 'string', }, lists: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listView', }, }, }, }, }, }, }, }, AppBskyGraphGetLists: { lexicon: 1, id: 'app.bsky.graph.getLists', defs: { main: { type: 'query', description: 'Enumerates the lists created by a specified account (actor).', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', description: 'The account (actor) to enumerate lists from.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, purposes: { type: 'array', description: 'Optional filter by list purpose. If not specified, all supported types are returned.', items: { type: 'string', knownValues: ['modlist', 'curatelist'], }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['lists'], properties: { cursor: { type: 'string', }, lists: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listView', }, }, }, }, }, }, }, }, AppBskyGraphGetListsWithMembership: { lexicon: 1, id: 'app.bsky.graph.getListsWithMembership', defs: { main: { type: 'query', description: 'Enumerates the lists created by the session user, and includes membership information about `actor` in those lists. Only supports curation and moderation lists (no reference lists, used in starter packs). Requires auth.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', description: 'The account (actor) to check for membership.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, purposes: { type: 'array', description: 'Optional filter by list purpose. If not specified, all supported types are returned.', items: { type: 'string', knownValues: ['modlist', 'curatelist'], }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['listsWithMembership'], properties: { cursor: { type: 'string', }, listsWithMembership: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.getListsWithMembership#listWithMembership', }, }, }, }, }, }, listWithMembership: { description: 'A list and an optional list item indicating membership of a target user to that list.', type: 'object', required: ['list'], properties: { list: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listView', }, listItem: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listItemView', }, }, }, }, }, AppBskyGraphGetMutes: { lexicon: 1, id: 'app.bsky.graph.getMutes', defs: { main: { type: 'query', description: 'Enumerates accounts that the requesting account (actor) currently has muted. Requires auth.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['mutes'], properties: { cursor: { type: 'string', }, mutes: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyGraphGetRelationships: { lexicon: 1, id: 'app.bsky.graph.getRelationships', defs: { main: { type: 'query', description: 'Enumerates public relationships between one account, and a list of other accounts. Does not require auth.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', description: 'Primary account requesting relationships for.', }, others: { type: 'array', description: "List of 'other' accounts to be related back to the primary.", maxLength: 30, items: { type: 'string', format: 'at-identifier', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['relationships'], properties: { actor: { type: 'string', format: 'did', }, relationships: { type: 'array', items: { type: 'union', refs: [ 'lex:app.bsky.graph.defs#relationship', 'lex:app.bsky.graph.defs#notFoundActor', ], }, }, }, }, }, errors: [ { name: 'ActorNotFound', description: 'the primary actor at-identifier could not be resolved', }, ], }, }, }, AppBskyGraphGetStarterPack: { lexicon: 1, id: 'app.bsky.graph.getStarterPack', defs: { main: { type: 'query', description: 'Gets a view of a starter pack.', parameters: { type: 'params', required: ['starterPack'], properties: { starterPack: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) of the starter pack record.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPack'], properties: { starterPack: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackView', }, }, }, }, }, }, }, AppBskyGraphGetStarterPacks: { lexicon: 1, id: 'app.bsky.graph.getStarterPacks', defs: { main: { type: 'query', description: 'Get views for a list of starter packs.', parameters: { type: 'params', required: ['uris'], properties: { uris: { type: 'array', items: { type: 'string', format: 'at-uri', }, maxLength: 25, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { starterPacks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackViewBasic', }, }, }, }, }, }, }, }, AppBskyGraphGetStarterPacksWithMembership: { lexicon: 1, id: 'app.bsky.graph.getStarterPacksWithMembership', defs: { main: { type: 'query', description: 'Enumerates the starter packs created by the session user, and includes membership information about `actor` in those starter packs. Requires auth.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', description: 'The account (actor) to check for membership.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacksWithMembership'], properties: { cursor: { type: 'string', }, starterPacksWithMembership: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.getStarterPacksWithMembership#starterPackWithMembership', }, }, }, }, }, }, starterPackWithMembership: { description: 'A starter pack and an optional list item indicating membership of a target user to that starter pack.', type: 'object', required: ['starterPack'], properties: { starterPack: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackView', }, listItem: { type: 'ref', ref: 'lex:app.bsky.graph.defs#listItemView', }, }, }, }, }, AppBskyGraphGetSuggestedFollowsByActor: { lexicon: 1, id: 'app.bsky.graph.getSuggestedFollowsByActor', defs: { main: { type: 'query', description: 'Enumerates follows similar to a given account (actor). Expected use is to recommend additional accounts immediately after following one account.', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['suggestions'], properties: { suggestions: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, recIdStr: { type: 'string', description: 'Snowflake for this recommendation, use when submitting recommendation events.', }, isFallback: { type: 'boolean', description: 'DEPRECATED, unused. Previously: if true, response has fallen-back to generic results, and is not scoped using relativeToDid', default: false, }, recId: { type: 'integer', description: 'DEPRECATED: use recIdStr instead.', }, }, }, }, }, }, }, AppBskyGraphList: { lexicon: 1, id: 'app.bsky.graph.list', defs: { main: { type: 'record', description: 'Record representing a list of accounts (actors). Scope includes both moderation-oriented lists and curration-oriented lists.', key: 'tid', record: { type: 'object', required: ['name', 'purpose', 'createdAt'], properties: { purpose: { type: 'ref', description: 'Defines the purpose of the list (aka, moderation-oriented or curration-oriented)', ref: 'lex:app.bsky.graph.defs#listPurpose', }, name: { type: 'string', maxLength: 64, minLength: 1, description: 'Display name for list; can not be empty.', }, description: { type: 'string', maxGraphemes: 300, maxLength: 3000, }, descriptionFacets: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, avatar: { type: 'blob', accept: ['image/png', 'image/jpeg'], maxSize: 1000000, }, labels: { type: 'union', refs: ['lex:com.atproto.label.defs#selfLabels'], }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, }, }, AppBskyGraphListblock: { lexicon: 1, id: 'app.bsky.graph.listblock', defs: { main: { type: 'record', description: 'Record representing a block relationship against an entire an entire list of accounts (actors).', key: 'tid', record: { type: 'object', required: ['subject', 'createdAt'], properties: { subject: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to the mod list record.', }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, }, }, AppBskyGraphListitem: { lexicon: 1, id: 'app.bsky.graph.listitem', defs: { main: { type: 'record', description: "Record representing an account's inclusion on a specific list. The AppView will ignore duplicate listitem records.", key: 'tid', record: { type: 'object', required: ['subject', 'list', 'createdAt'], properties: { subject: { type: 'string', format: 'did', description: 'The account which is included on the list.', }, list: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to the list record (app.bsky.graph.list).', }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, }, }, AppBskyGraphMuteActor: { lexicon: 1, id: 'app.bsky.graph.muteActor', defs: { main: { type: 'procedure', description: 'Creates a mute relationship for the specified account. Mutes are private in Bluesky. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, }, }, }, }, }, }, AppBskyGraphMuteActorList: { lexicon: 1, id: 'app.bsky.graph.muteActorList', defs: { main: { type: 'procedure', description: 'Creates a mute relationship for the specified list of accounts. Mutes are private in Bluesky. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['list'], properties: { list: { type: 'string', format: 'at-uri', }, }, }, }, }, }, }, AppBskyGraphMuteThread: { lexicon: 1, id: 'app.bsky.graph.muteThread', defs: { main: { type: 'procedure', description: 'Mutes a thread preventing notifications from the thread and any of its children. Mutes are private in Bluesky. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['root'], properties: { root: { type: 'string', format: 'at-uri', }, }, }, }, }, }, }, AppBskyGraphSearchStarterPacks: { lexicon: 1, id: 'app.bsky.graph.searchStarterPacks', defs: { main: { type: 'query', description: 'Find starter packs matching search criteria. Does not require auth.', parameters: { type: 'params', required: ['q'], properties: { q: { type: 'string', description: 'Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 25, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { cursor: { type: 'string', }, starterPacks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackViewBasic', }, }, }, }, }, }, }, }, AppBskyGraphStarterpack: { lexicon: 1, id: 'app.bsky.graph.starterpack', defs: { main: { type: 'record', description: 'Record defining a starter pack of actors and feeds for new users.', key: 'tid', record: { type: 'object', required: ['name', 'list', 'createdAt'], properties: { name: { type: 'string', maxGraphemes: 50, maxLength: 500, minLength: 1, description: 'Display name for starter pack; can not be empty.', }, description: { type: 'string', maxGraphemes: 300, maxLength: 3000, }, descriptionFacets: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, list: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to the list record.', }, feeds: { type: 'array', maxLength: 3, items: { type: 'ref', ref: 'lex:app.bsky.graph.starterpack#feedItem', }, }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, feedItem: { type: 'object', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', }, }, }, }, }, AppBskyGraphUnmuteActor: { lexicon: 1, id: 'app.bsky.graph.unmuteActor', defs: { main: { type: 'procedure', description: 'Unmutes the specified account. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['actor'], properties: { actor: { type: 'string', format: 'at-identifier', }, }, }, }, }, }, }, AppBskyGraphUnmuteActorList: { lexicon: 1, id: 'app.bsky.graph.unmuteActorList', defs: { main: { type: 'procedure', description: 'Unmutes the specified list of accounts. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['list'], properties: { list: { type: 'string', format: 'at-uri', }, }, }, }, }, }, }, AppBskyGraphUnmuteThread: { lexicon: 1, id: 'app.bsky.graph.unmuteThread', defs: { main: { type: 'procedure', description: 'Unmutes the specified thread. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['root'], properties: { root: { type: 'string', format: 'at-uri', }, }, }, }, }, }, }, AppBskyGraphVerification: { lexicon: 1, id: 'app.bsky.graph.verification', defs: { main: { type: 'record', description: 'Record declaring a verification relationship between two accounts. Verifications are only considered valid by an app if issued by an account the app considers trusted.', key: 'tid', record: { type: 'object', required: ['subject', 'handle', 'displayName', 'createdAt'], properties: { subject: { description: 'DID of the subject the verification applies to.', type: 'string', format: 'did', }, handle: { description: 'Handle of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current handle matches the one at the time of verifying.', type: 'string', format: 'handle', }, displayName: { description: 'Display name of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current displayName matches the one at the time of verifying.', type: 'string', }, createdAt: { description: 'Date of when the verification was created.', type: 'string', format: 'datetime', }, }, }, }, }, }, AppBskyLabelerDefs: { lexicon: 1, id: 'app.bsky.labeler.defs', defs: { labelerView: { type: 'object', required: ['uri', 'cid', 'creator', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, creator: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, likeCount: { type: 'integer', minimum: 0, }, viewer: { type: 'ref', ref: 'lex:app.bsky.labeler.defs#labelerViewerState', }, indexedAt: { type: 'string', format: 'datetime', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, }, }, labelerViewDetailed: { type: 'object', required: ['uri', 'cid', 'creator', 'policies', 'indexedAt'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, creator: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, policies: { type: 'ref', ref: 'lex:app.bsky.labeler.defs#labelerPolicies', }, likeCount: { type: 'integer', minimum: 0, }, viewer: { type: 'ref', ref: 'lex:app.bsky.labeler.defs#labelerViewerState', }, indexedAt: { type: 'string', format: 'datetime', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, reasonTypes: { description: "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.moderation.defs#reasonType', }, }, subjectTypes: { description: 'The set of subject types (account, record, etc) this service accepts reports on.', type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.moderation.defs#subjectType', }, }, subjectCollections: { type: 'array', description: 'Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.', items: { type: 'string', format: 'nsid', }, }, }, }, labelerViewerState: { type: 'object', properties: { like: { type: 'string', format: 'at-uri', }, }, }, labelerPolicies: { type: 'object', required: ['labelValues'], properties: { labelValues: { type: 'array', description: 'The label values which this labeler publishes. May include global or custom labels.', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#labelValue', }, }, labelValueDefinitions: { type: 'array', description: 'Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler.', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#labelValueDefinition', }, }, }, }, }, }, AppBskyLabelerGetServices: { lexicon: 1, id: 'app.bsky.labeler.getServices', defs: { main: { type: 'query', description: 'Get information about a list of labeler services.', parameters: { type: 'params', required: ['dids'], properties: { dids: { type: 'array', items: { type: 'string', format: 'did', }, }, detailed: { type: 'boolean', default: false, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['views'], properties: { views: { type: 'array', items: { type: 'union', refs: [ 'lex:app.bsky.labeler.defs#labelerView', 'lex:app.bsky.labeler.defs#labelerViewDetailed', ], }, }, }, }, }, }, }, }, AppBskyLabelerService: { lexicon: 1, id: 'app.bsky.labeler.service', defs: { main: { type: 'record', description: 'A declaration of the existence of labeler service.', key: 'literal:self', record: { type: 'object', required: ['policies', 'createdAt'], properties: { policies: { type: 'ref', ref: 'lex:app.bsky.labeler.defs#labelerPolicies', }, labels: { type: 'union', refs: ['lex:com.atproto.label.defs#selfLabels'], }, createdAt: { type: 'string', format: 'datetime', }, reasonTypes: { description: "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.moderation.defs#reasonType', }, }, subjectTypes: { description: 'The set of subject types (account, record, etc) this service accepts reports on.', type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.moderation.defs#subjectType', }, }, subjectCollections: { type: 'array', description: 'Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.', items: { type: 'string', format: 'nsid', }, }, }, }, }, }, }, AppBskyNotificationDeclaration: { lexicon: 1, id: 'app.bsky.notification.declaration', defs: { main: { type: 'record', description: "A declaration of the user's choices related to notifications that can be produced by them.", key: 'literal:self', record: { type: 'object', required: ['allowSubscriptions'], properties: { allowSubscriptions: { type: 'string', description: "A declaration of the user's preference for allowing activity subscriptions from other users. Absence of a record implies 'followers'.", knownValues: ['followers', 'mutuals', 'none'], }, }, }, }, }, }, AppBskyNotificationDefs: { lexicon: 1, id: 'app.bsky.notification.defs', defs: { recordDeleted: { type: 'object', properties: {}, }, chatPreference: { type: 'object', required: ['include', 'push'], properties: { include: { type: 'string', knownValues: ['all', 'accepted'], }, push: { type: 'boolean', }, }, }, filterablePreference: { type: 'object', required: ['include', 'list', 'push'], properties: { include: { type: 'string', knownValues: ['all', 'follows'], }, list: { type: 'boolean', }, push: { type: 'boolean', }, }, }, preference: { type: 'object', required: ['list', 'push'], properties: { list: { type: 'boolean', }, push: { type: 'boolean', }, }, }, preferences: { type: 'object', required: [ 'chat', 'follow', 'like', 'likeViaRepost', 'mention', 'quote', 'reply', 'repost', 'repostViaRepost', 'starterpackJoined', 'subscribedPost', 'unverified', 'verified', ], properties: { chat: { type: 'ref', ref: 'lex:app.bsky.notification.defs#chatPreference', }, follow: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, like: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, likeViaRepost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, mention: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, quote: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, reply: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, repost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, repostViaRepost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, starterpackJoined: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, subscribedPost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, unverified: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, verified: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, }, }, activitySubscription: { type: 'object', required: ['post', 'reply'], properties: { post: { type: 'boolean', }, reply: { type: 'boolean', }, }, }, subjectActivitySubscription: { description: 'Object used to store activity subscription data in stash.', type: 'object', required: ['subject', 'activitySubscription'], properties: { subject: { type: 'string', format: 'did', }, activitySubscription: { type: 'ref', ref: 'lex:app.bsky.notification.defs#activitySubscription', }, }, }, }, }, AppBskyNotificationGetPreferences: { lexicon: 1, id: 'app.bsky.notification.getPreferences', defs: { main: { type: 'query', description: 'Get notification-related preferences for an account. Requires auth.', parameters: { type: 'params', properties: {}, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['preferences'], properties: { preferences: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preferences', }, }, }, }, }, }, }, AppBskyNotificationGetUnreadCount: { lexicon: 1, id: 'app.bsky.notification.getUnreadCount', defs: { main: { type: 'query', description: 'Count the number of unread notifications for the requesting account. Requires auth.', parameters: { type: 'params', properties: { priority: { type: 'boolean', }, seenAt: { type: 'string', format: 'datetime', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['count'], properties: { count: { type: 'integer', }, }, }, }, }, }, }, AppBskyNotificationListActivitySubscriptions: { lexicon: 1, id: 'app.bsky.notification.listActivitySubscriptions', defs: { main: { type: 'query', description: 'Enumerate all accounts to which the requesting account is subscribed to receive notifications for. Requires auth.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subscriptions'], properties: { cursor: { type: 'string', }, subscriptions: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, }, }, }, }, }, }, AppBskyNotificationListNotifications: { lexicon: 1, id: 'app.bsky.notification.listNotifications', defs: { main: { type: 'query', description: 'Enumerate notifications for the requesting account. Requires auth.', parameters: { type: 'params', properties: { reasons: { description: 'Notification reasons to include in response.', type: 'array', items: { type: 'string', description: 'A reason that matches the reason property of #notification.', }, }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, priority: { type: 'boolean', }, cursor: { type: 'string', }, seenAt: { type: 'string', format: 'datetime', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['notifications'], properties: { cursor: { type: 'string', }, notifications: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.notification.listNotifications#notification', }, }, priority: { type: 'boolean', }, seenAt: { type: 'string', format: 'datetime', }, }, }, }, }, notification: { type: 'object', required: [ 'uri', 'cid', 'author', 'reason', 'record', 'isRead', 'indexedAt', ], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, author: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, reason: { type: 'string', description: 'The reason why this notification was delivered - e.g. your post was liked, or you received a new follower.', knownValues: [ 'like', 'repost', 'follow', 'mention', 'reply', 'quote', 'starterpack-joined', 'verified', 'unverified', 'like-via-repost', 'repost-via-repost', 'subscribed-post', 'contact-match', ], }, reasonSubject: { type: 'string', format: 'at-uri', }, record: { type: 'unknown', }, isRead: { type: 'boolean', }, indexedAt: { type: 'string', format: 'datetime', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, }, }, }, }, AppBskyNotificationPutActivitySubscription: { lexicon: 1, id: 'app.bsky.notification.putActivitySubscription', defs: { main: { type: 'procedure', description: 'Puts an activity subscription entry. The key should be omitted for creation and provided for updates. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['subject', 'activitySubscription'], properties: { subject: { type: 'string', format: 'did', }, activitySubscription: { type: 'ref', ref: 'lex:app.bsky.notification.defs#activitySubscription', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subject'], properties: { subject: { type: 'string', format: 'did', }, activitySubscription: { type: 'ref', ref: 'lex:app.bsky.notification.defs#activitySubscription', }, }, }, }, }, }, }, AppBskyNotificationPutPreferences: { lexicon: 1, id: 'app.bsky.notification.putPreferences', defs: { main: { type: 'procedure', description: 'Set notification-related preferences for an account. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['priority'], properties: { priority: { type: 'boolean', }, }, }, }, }, }, }, AppBskyNotificationPutPreferencesV2: { lexicon: 1, id: 'app.bsky.notification.putPreferencesV2', defs: { main: { type: 'procedure', description: 'Set notification-related preferences for an account. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', properties: { chat: { type: 'ref', ref: 'lex:app.bsky.notification.defs#chatPreference', }, follow: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, like: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, likeViaRepost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, mention: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, quote: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, reply: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, repost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, repostViaRepost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#filterablePreference', }, starterpackJoined: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, subscribedPost: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, unverified: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, verified: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preference', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['preferences'], properties: { preferences: { type: 'ref', ref: 'lex:app.bsky.notification.defs#preferences', }, }, }, }, }, }, }, AppBskyNotificationRegisterPush: { lexicon: 1, id: 'app.bsky.notification.registerPush', defs: { main: { type: 'procedure', description: 'Register to receive push notifications, via a specified service, for the requesting account. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['serviceDid', 'token', 'platform', 'appId'], properties: { serviceDid: { type: 'string', format: 'did', }, token: { type: 'string', }, platform: { type: 'string', knownValues: ['ios', 'android', 'web'], }, appId: { type: 'string', }, ageRestricted: { type: 'boolean', description: 'Set to true when the actor is age restricted', }, }, }, }, }, }, }, AppBskyNotificationUnregisterPush: { lexicon: 1, id: 'app.bsky.notification.unregisterPush', defs: { main: { type: 'procedure', description: 'The inverse of registerPush - inform a specified service that push notifications should no longer be sent to the given token for the requesting account. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['serviceDid', 'token', 'platform', 'appId'], properties: { serviceDid: { type: 'string', format: 'did', }, token: { type: 'string', }, platform: { type: 'string', knownValues: ['ios', 'android', 'web'], }, appId: { type: 'string', }, }, }, }, }, }, }, AppBskyNotificationUpdateSeen: { lexicon: 1, id: 'app.bsky.notification.updateSeen', defs: { main: { type: 'procedure', description: 'Notify server that the requesting account has seen notifications. Requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['seenAt'], properties: { seenAt: { type: 'string', format: 'datetime', }, }, }, }, }, }, }, AppBskyRichtextFacet: { lexicon: 1, id: 'app.bsky.richtext.facet', defs: { main: { type: 'object', description: 'Annotation of a sub-string within rich text.', required: ['index', 'features'], properties: { index: { type: 'ref', ref: 'lex:app.bsky.richtext.facet#byteSlice', }, features: { type: 'array', items: { type: 'union', refs: [ 'lex:app.bsky.richtext.facet#mention', 'lex:app.bsky.richtext.facet#link', 'lex:app.bsky.richtext.facet#tag', ], }, }, }, }, mention: { type: 'object', description: "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.", required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, link: { type: 'object', description: 'Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.', required: ['uri'], properties: { uri: { type: 'string', format: 'uri', }, }, }, tag: { type: 'object', description: "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').", required: ['tag'], properties: { tag: { type: 'string', maxLength: 640, maxGraphemes: 64, }, }, }, byteSlice: { type: 'object', description: 'Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.', required: ['byteStart', 'byteEnd'], properties: { byteStart: { type: 'integer', minimum: 0, }, byteEnd: { type: 'integer', minimum: 0, }, }, }, }, }, AppBskyUnspeccedDefs: { lexicon: 1, id: 'app.bsky.unspecced.defs', defs: { skeletonSearchPost: { type: 'object', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', }, }, }, skeletonSearchActor: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, skeletonSearchStarterPack: { type: 'object', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', }, }, }, trendingTopic: { type: 'object', required: ['topic', 'link'], properties: { topic: { type: 'string', }, displayName: { type: 'string', }, description: { type: 'string', }, link: { type: 'string', }, }, }, skeletonTrend: { type: 'object', required: [ 'topic', 'displayName', 'link', 'startedAt', 'postCount', 'dids', ], properties: { topic: { type: 'string', }, displayName: { type: 'string', }, link: { type: 'string', }, startedAt: { type: 'string', format: 'datetime', }, postCount: { type: 'integer', }, status: { type: 'string', knownValues: ['hot'], }, category: { type: 'string', }, dids: { type: 'array', items: { type: 'string', format: 'did', }, }, }, }, trendView: { type: 'object', required: [ 'topic', 'displayName', 'link', 'startedAt', 'postCount', 'actors', ], properties: { topic: { type: 'string', }, displayName: { type: 'string', }, link: { type: 'string', }, startedAt: { type: 'string', format: 'datetime', }, postCount: { type: 'integer', }, status: { type: 'string', knownValues: ['hot'], }, category: { type: 'string', }, actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewBasic', }, }, }, }, threadItemPost: { type: 'object', required: [ 'post', 'moreParents', 'moreReplies', 'opThread', 'hiddenByThreadgate', 'mutedByViewer', ], properties: { post: { type: 'ref', ref: 'lex:app.bsky.feed.defs#postView', }, moreParents: { type: 'boolean', description: 'This post has more parents that were not present in the response. This is just a boolean, without the number of parents.', }, moreReplies: { type: 'integer', description: 'This post has more replies that were not present in the response. This is a numeric value, which is best-effort and might not be accurate.', }, opThread: { type: 'boolean', description: 'This post is part of a contiguous thread by the OP from the thread root. Many different OP threads can happen in the same thread.', }, hiddenByThreadgate: { type: 'boolean', description: 'The threadgate created by the author indicates this post as a reply to be hidden for everyone consuming the thread.', }, mutedByViewer: { type: 'boolean', description: 'This is by an account muted by the viewer requesting it.', }, }, }, threadItemNoUnauthenticated: { type: 'object', properties: {}, }, threadItemNotFound: { type: 'object', properties: {}, }, threadItemBlocked: { type: 'object', required: ['author'], properties: { author: { type: 'ref', ref: 'lex:app.bsky.feed.defs#blockedAuthor', }, }, }, ageAssuranceState: { type: 'object', description: 'The computed state of the age assurance process, returned to the user in question on certain authenticated requests.', required: ['status'], properties: { lastInitiatedAt: { type: 'string', format: 'datetime', description: 'The timestamp when this state was last updated.', }, status: { type: 'string', description: 'The status of the age assurance process.', knownValues: ['unknown', 'pending', 'assured', 'blocked'], }, }, }, ageAssuranceEvent: { type: 'object', description: 'Object used to store age assurance data in stash.', required: ['createdAt', 'status', 'attemptId'], properties: { createdAt: { type: 'string', format: 'datetime', description: 'The date and time of this write operation.', }, status: { type: 'string', description: 'The status of the age assurance process.', knownValues: ['unknown', 'pending', 'assured'], }, attemptId: { type: 'string', description: 'The unique identifier for this instance of the age assurance flow, in UUID format.', }, email: { type: 'string', description: 'The email used for AA.', }, initIp: { type: 'string', description: 'The IP address used when initiating the AA flow.', }, initUa: { type: 'string', description: 'The user agent used when initiating the AA flow.', }, completeIp: { type: 'string', description: 'The IP address used when completing the AA flow.', }, completeUa: { type: 'string', description: 'The user agent used when completing the AA flow.', }, }, }, }, }, AppBskyUnspeccedGetAgeAssuranceState: { lexicon: 1, id: 'app.bsky.unspecced.getAgeAssuranceState', defs: { main: { type: 'query', description: 'Returns the current state of the age assurance process for an account. This is used to check if the user has completed age assurance or if further action is required.', output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#ageAssuranceState', }, }, }, }, }, AppBskyUnspeccedGetConfig: { lexicon: 1, id: 'app.bsky.unspecced.getConfig', defs: { main: { type: 'query', description: 'Get miscellaneous runtime configuration.', output: { encoding: 'application/json', schema: { type: 'object', required: [], properties: { checkEmailConfirmed: { type: 'boolean', }, liveNow: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.getConfig#liveNowConfig', }, }, }, }, }, }, liveNowConfig: { type: 'object', required: ['did', 'domains'], properties: { did: { type: 'string', format: 'did', }, domains: { type: 'array', items: { type: 'string', }, }, }, }, }, }, AppBskyUnspeccedGetOnboardingSuggestedStarterPacks: { lexicon: 1, id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks', defs: { main: { type: 'query', description: 'Get a list of suggested starterpacks for onboarding', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { starterPacks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackView', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton', defs: { main: { type: 'query', description: 'Get a skeleton of suggested starterpacks for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getOnboardingSuggestedStarterPacks', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries).', }, limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { starterPacks: { type: 'array', items: { type: 'string', format: 'at-uri', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton', defs: { main: { type: 'query', description: 'Get a skeleton of suggested users for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedOnboardingUsers', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries).', }, category: { type: 'string', description: 'Category of users to get suggestions for.', }, limit: { type: 'integer', minimum: 1, maximum: 50, default: 25, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['dids'], properties: { dids: { type: 'array', items: { type: 'string', format: 'did', }, }, recId: { type: 'string', description: 'DEPRECATED: use recIdStr instead.', }, recIdStr: { type: 'string', description: 'Snowflake for this recommendation, use when submitting recommendation events.', }, }, }, }, }, }, }, AppBskyUnspeccedGetPopularFeedGenerators: { lexicon: 1, id: 'app.bsky.unspecced.getPopularFeedGenerators', defs: { main: { type: 'query', description: 'An unspecced view of globally popular feed generators.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, query: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feeds'], properties: { cursor: { type: 'string', }, feeds: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorView', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetPostThreadOtherV2: { lexicon: 1, id: 'app.bsky.unspecced.getPostThreadOtherV2', defs: { main: { type: 'query', description: "(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get additional posts under a thread e.g. replies hidden by threadgate. Based on an anchor post at any depth of the tree, returns top-level replies below that anchor. It does not include ancestors nor the anchor itself. This should be called after exhausting `app.bsky.unspecced.getPostThreadV2`. Does not require auth, but additional metadata and filtering will be applied for authed requests.", parameters: { type: 'params', required: ['anchor'], properties: { anchor: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to post record. This is the anchor post.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['thread'], properties: { thread: { type: 'array', description: 'A flat list of other thread items. The depth of each item is indicated by the depth property inside the item.', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.getPostThreadOtherV2#threadItem', }, }, }, }, }, }, threadItem: { type: 'object', required: ['uri', 'depth', 'value'], properties: { uri: { type: 'string', format: 'at-uri', }, depth: { type: 'integer', description: 'The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths.', }, value: { type: 'union', refs: ['lex:app.bsky.unspecced.defs#threadItemPost'], }, }, }, }, }, AppBskyUnspeccedGetPostThreadV2: { lexicon: 1, id: 'app.bsky.unspecced.getPostThreadV2', defs: { main: { type: 'query', description: "(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get posts in a thread. It is based in an anchor post at any depth of the tree, and returns posts above it (recursively resolving the parent, without further branching to their replies) and below it (recursive replies, with branching to their replies). Does not require auth, but additional metadata and filtering will be applied for authed requests.", parameters: { type: 'params', required: ['anchor'], properties: { anchor: { type: 'string', format: 'at-uri', description: 'Reference (AT-URI) to post record. This is the anchor post, and the thread will be built around it. It can be any post in the tree, not necessarily a root post.', }, above: { type: 'boolean', description: 'Whether to include parents above the anchor.', default: true, }, below: { type: 'integer', description: 'How many levels of replies to include below the anchor.', default: 6, minimum: 0, maximum: 20, }, branchingFactor: { type: 'integer', description: 'Maximum of replies to include at each level of the thread, except for the direct replies to the anchor, which are (NOTE: currently, during unspecced phase) all returned (NOTE: later they might be paginated).', default: 10, minimum: 0, maximum: 100, }, sort: { type: 'string', description: 'Sorting for the thread replies.', knownValues: ['newest', 'oldest', 'top'], default: 'oldest', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['thread', 'hasOtherReplies'], properties: { thread: { type: 'array', description: 'A flat list of thread items. The depth of each item is indicated by the depth property inside the item.', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.getPostThreadV2#threadItem', }, }, threadgate: { type: 'ref', ref: 'lex:app.bsky.feed.defs#threadgateView', }, hasOtherReplies: { type: 'boolean', description: 'Whether this thread has additional replies. If true, a call can be made to the `getPostThreadOtherV2` endpoint to retrieve them.', }, }, }, }, }, threadItem: { type: 'object', required: ['uri', 'depth', 'value'], properties: { uri: { type: 'string', format: 'at-uri', }, depth: { type: 'integer', description: 'The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths.', }, value: { type: 'union', refs: [ 'lex:app.bsky.unspecced.defs#threadItemPost', 'lex:app.bsky.unspecced.defs#threadItemNoUnauthenticated', 'lex:app.bsky.unspecced.defs#threadItemNotFound', 'lex:app.bsky.unspecced.defs#threadItemBlocked', ], }, }, }, }, }, AppBskyUnspeccedGetSuggestedFeeds: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestedFeeds', defs: { main: { type: 'query', description: 'Get a list of suggested feeds', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feeds'], properties: { feeds: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.feed.defs#generatorView', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetSuggestedFeedsSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestedFeedsSkeleton', defs: { main: { type: 'query', description: 'Get a skeleton of suggested feeds. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedFeeds', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries).', }, limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['feeds'], properties: { feeds: { type: 'array', items: { type: 'string', format: 'at-uri', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetSuggestedOnboardingUsers: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestedOnboardingUsers', defs: { main: { type: 'query', description: 'Get a list of suggested users for onboarding', parameters: { type: 'params', properties: { category: { type: 'string', description: 'Category of users to get suggestions for.', }, limit: { type: 'integer', minimum: 1, maximum: 50, default: 25, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actors'], properties: { actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, recId: { type: 'string', description: 'DEPRECATED: use recIdStr instead.', }, recIdStr: { type: 'string', description: 'Snowflake for this recommendation, use when submitting recommendation events.', }, }, }, }, }, }, }, AppBskyUnspeccedGetSuggestedStarterPacks: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestedStarterPacks', defs: { main: { type: 'query', description: 'Get a list of suggested starterpacks', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { starterPacks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.graph.defs#starterPackView', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetSuggestedStarterPacksSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton', defs: { main: { type: 'query', description: 'Get a skeleton of suggested starterpacks. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedStarterpacks', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries).', }, limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { starterPacks: { type: 'array', items: { type: 'string', format: 'at-uri', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetSuggestedUsers: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestedUsers', defs: { main: { type: 'query', description: 'Get a list of suggested users', parameters: { type: 'params', properties: { category: { type: 'string', description: 'Category of users to get suggestions for.', }, limit: { type: 'integer', minimum: 1, maximum: 50, default: 25, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actors'], properties: { actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileView', }, }, recId: { type: 'string', description: 'DEPRECATED: use recIdStr instead.', }, recIdStr: { type: 'string', description: 'Snowflake for this recommendation, use when submitting recommendation events.', }, }, }, }, }, }, }, AppBskyUnspeccedGetSuggestedUsersSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestedUsersSkeleton', defs: { main: { type: 'query', description: 'Get a skeleton of suggested users. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedUsers', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries).', }, category: { type: 'string', description: 'Category of users to get suggestions for.', }, limit: { type: 'integer', minimum: 1, maximum: 50, default: 25, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['dids'], properties: { dids: { type: 'array', items: { type: 'string', format: 'did', }, }, recId: { type: 'string', description: 'DEPRECATED: use recIdStr instead.', }, recIdStr: { type: 'string', description: 'Snowflake for this recommendation, use when submitting recommendation events.', }, }, }, }, }, }, }, AppBskyUnspeccedGetSuggestionsSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getSuggestionsSkeleton', defs: { main: { type: 'query', description: 'Get a skeleton of suggested actors. Intended to be called and then hydrated through app.bsky.actor.getSuggestions', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, relativeToDid: { type: 'string', format: 'did', description: 'DID of the account to get suggestions relative to. If not provided, suggestions will be based on the viewer.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actors'], properties: { cursor: { type: 'string', }, actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#skeletonSearchActor', }, }, relativeToDid: { type: 'string', format: 'did', description: 'DID of the account these suggestions are relative to. If this is returned undefined, suggestions are based on the viewer.', }, recId: { type: 'integer', description: 'DEPRECATED: use recIdStr instead.', }, recIdStr: { type: 'string', description: 'Snowflake for this recommendation, use when submitting recommendation events.', }, }, }, }, }, }, }, AppBskyUnspeccedGetTaggedSuggestions: { lexicon: 1, id: 'app.bsky.unspecced.getTaggedSuggestions', defs: { main: { type: 'query', description: 'Get a list of suggestions (feeds and users) tagged with categories', parameters: { type: 'params', properties: {}, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['suggestions'], properties: { suggestions: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.getTaggedSuggestions#suggestion', }, }, }, }, }, }, suggestion: { type: 'object', required: ['tag', 'subjectType', 'subject'], properties: { tag: { type: 'string', }, subjectType: { type: 'string', knownValues: ['actor', 'feed'], }, subject: { type: 'string', format: 'uri', }, }, }, }, }, AppBskyUnspeccedGetTrendingTopics: { lexicon: 1, id: 'app.bsky.unspecced.getTrendingTopics', defs: { main: { type: 'query', description: 'Get a list of trending topics', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.', }, limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['topics', 'suggested'], properties: { topics: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#trendingTopic', }, }, suggested: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#trendingTopic', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetTrends: { lexicon: 1, id: 'app.bsky.unspecced.getTrends', defs: { main: { type: 'query', description: 'Get the current trends on the network', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['trends'], properties: { trends: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#trendView', }, }, }, }, }, }, }, }, AppBskyUnspeccedGetTrendsSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.getTrendsSkeleton', defs: { main: { type: 'query', description: 'Get the skeleton of trends on the network. Intended to be called and then hydrated through app.bsky.unspecced.getTrends', parameters: { type: 'params', properties: { viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries).', }, limit: { type: 'integer', minimum: 1, maximum: 25, default: 10, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['trends'], properties: { trends: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#skeletonTrend', }, }, }, }, }, }, }, }, AppBskyUnspeccedInitAgeAssurance: { lexicon: 1, id: 'app.bsky.unspecced.initAgeAssurance', defs: { main: { type: 'procedure', description: "Initiate age assurance for an account. This is a one-time action that will start the process of verifying the user's age.", input: { encoding: 'application/json', schema: { type: 'object', required: ['email', 'language', 'countryCode'], properties: { email: { type: 'string', description: "The user's email address to receive assurance instructions.", }, language: { type: 'string', description: "The user's preferred language for communication during the assurance process.", }, countryCode: { type: 'string', description: "An ISO 3166-1 alpha-2 code of the user's location.", }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#ageAssuranceState', }, }, errors: [ { name: 'InvalidEmail', }, { name: 'DidTooLong', }, { name: 'InvalidInitiation', }, ], }, }, }, AppBskyUnspeccedSearchActorsSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.searchActorsSkeleton', defs: { main: { type: 'query', description: 'Backend Actors (profile) search, returns only skeleton.', parameters: { type: 'params', required: ['q'], properties: { q: { type: 'string', description: 'Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. For typeahead search, only simple term match is supported, not full syntax.', }, viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.', }, typeahead: { type: 'boolean', description: "If true, acts as fast/simple 'typeahead' query.", }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 25, }, cursor: { type: 'string', description: 'Optional pagination mechanism; may not necessarily allow scrolling through entire result set.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actors'], properties: { cursor: { type: 'string', }, hitsTotal: { type: 'integer', description: 'Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.', }, actors: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#skeletonSearchActor', }, }, }, }, }, errors: [ { name: 'BadQueryString', }, ], }, }, }, AppBskyUnspeccedSearchPostsSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.searchPostsSkeleton', defs: { main: { type: 'query', description: 'Backend Posts search, returns only skeleton', parameters: { type: 'params', required: ['q'], properties: { q: { type: 'string', description: 'Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.', }, sort: { type: 'string', knownValues: ['top', 'latest'], default: 'latest', description: 'Specifies the ranking order of results.', }, since: { type: 'string', description: "Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD).", }, until: { type: 'string', description: "Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD).", }, mentions: { type: 'string', format: 'at-identifier', description: 'Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions.', }, author: { type: 'string', format: 'at-identifier', description: 'Filter to posts by the given account. Handles are resolved to DID before query-time.', }, lang: { type: 'string', format: 'language', description: 'Filter to posts in the given language. Expected to be based on post language field, though server may override language detection.', }, domain: { type: 'string', description: 'Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization.', }, url: { type: 'string', format: 'uri', description: 'Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching.', }, tag: { type: 'array', items: { type: 'string', maxLength: 640, maxGraphemes: 64, }, description: "Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching.", }, viewer: { type: 'string', format: 'did', description: "DID of the account making the request (not included for public/unauthenticated queries). Used for 'from:me' queries.", }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 25, }, cursor: { type: 'string', description: 'Optional pagination mechanism; may not necessarily allow scrolling through entire result set.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['posts'], properties: { cursor: { type: 'string', }, hitsTotal: { type: 'integer', description: 'Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.', }, posts: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#skeletonSearchPost', }, }, }, }, }, errors: [ { name: 'BadQueryString', }, ], }, }, }, AppBskyUnspeccedSearchStarterPacksSkeleton: { lexicon: 1, id: 'app.bsky.unspecced.searchStarterPacksSkeleton', defs: { main: { type: 'query', description: 'Backend Starter Pack search, returns only skeleton.', parameters: { type: 'params', required: ['q'], properties: { q: { type: 'string', description: 'Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.', }, viewer: { type: 'string', format: 'did', description: 'DID of the account making the request (not included for public/unauthenticated queries).', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 25, }, cursor: { type: 'string', description: 'Optional pagination mechanism; may not necessarily allow scrolling through entire result set.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['starterPacks'], properties: { cursor: { type: 'string', }, hitsTotal: { type: 'integer', description: 'Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.', }, starterPacks: { type: 'array', items: { type: 'ref', ref: 'lex:app.bsky.unspecced.defs#skeletonSearchStarterPack', }, }, }, }, }, errors: [ { name: 'BadQueryString', }, ], }, }, }, AppBskyVideoDefs: { lexicon: 1, id: 'app.bsky.video.defs', defs: { jobStatus: { type: 'object', required: ['jobId', 'did', 'state'], properties: { jobId: { type: 'string', }, did: { type: 'string', format: 'did', }, state: { type: 'string', description: 'The state of the video processing job. All values not listed as a known value indicate that the job is in process.', knownValues: ['JOB_STATE_COMPLETED', 'JOB_STATE_FAILED'], }, progress: { type: 'integer', minimum: 0, maximum: 100, description: 'Progress within the current processing state.', }, blob: { type: 'blob', }, error: { type: 'string', }, message: { type: 'string', }, }, }, }, }, AppBskyVideoGetJobStatus: { lexicon: 1, id: 'app.bsky.video.getJobStatus', defs: { main: { type: 'query', description: 'Get status details for a video processing job.', parameters: { type: 'params', required: ['jobId'], properties: { jobId: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['jobStatus'], properties: { jobStatus: { type: 'ref', ref: 'lex:app.bsky.video.defs#jobStatus', }, }, }, }, }, }, }, AppBskyVideoGetUploadLimits: { lexicon: 1, id: 'app.bsky.video.getUploadLimits', defs: { main: { type: 'query', description: 'Get video upload limits for the authenticated user.', output: { encoding: 'application/json', schema: { type: 'object', required: ['canUpload'], properties: { canUpload: { type: 'boolean', }, remainingDailyVideos: { type: 'integer', }, remainingDailyBytes: { type: 'integer', }, message: { type: 'string', }, error: { type: 'string', }, }, }, }, }, }, }, AppBskyVideoUploadVideo: { lexicon: 1, id: 'app.bsky.video.uploadVideo', defs: { main: { type: 'procedure', description: 'Upload a video to be processed then stored on the PDS.', input: { encoding: 'video/mp4', }, output: { encoding: 'application/json', schema: { type: 'object', required: ['jobStatus'], properties: { jobStatus: { type: 'ref', ref: 'lex:app.bsky.video.defs#jobStatus', }, }, }, }, }, }, }, ChatBskyActorDeclaration: { lexicon: 1, id: 'chat.bsky.actor.declaration', defs: { main: { type: 'record', description: 'A declaration of a Bluesky chat account.', key: 'literal:self', record: { type: 'object', required: ['allowIncoming'], properties: { allowIncoming: { type: 'string', knownValues: ['all', 'none', 'following'], }, }, }, }, }, }, ChatBskyActorDefs: { lexicon: 1, id: 'chat.bsky.actor.defs', defs: { profileViewBasic: { type: 'object', required: ['did', 'handle'], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, displayName: { type: 'string', maxGraphemes: 64, maxLength: 640, }, avatar: { type: 'string', format: 'uri', }, associated: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileAssociated', }, viewer: { type: 'ref', ref: 'lex:app.bsky.actor.defs#viewerState', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, chatDisabled: { type: 'boolean', description: 'Set to true when the actor cannot actively participate in conversations', }, verification: { type: 'ref', ref: 'lex:app.bsky.actor.defs#verificationState', }, }, }, }, }, ChatBskyActorDeleteAccount: { lexicon: 1, id: 'chat.bsky.actor.deleteAccount', defs: { main: { type: 'procedure', output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, }, }, }, ChatBskyActorExportAccountData: { lexicon: 1, id: 'chat.bsky.actor.exportAccountData', defs: { main: { type: 'query', output: { encoding: 'application/jsonl', }, }, }, }, ChatBskyConvoAcceptConvo: { lexicon: 1, id: 'chat.bsky.convo.acceptConvo', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId'], properties: { convoId: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: { rev: { description: 'Rev when the convo was accepted. If not present, the convo was already accepted.', type: 'string', }, }, }, }, }, }, }, ChatBskyConvoAddReaction: { lexicon: 1, id: 'chat.bsky.convo.addReaction', defs: { main: { type: 'procedure', description: 'Adds an emoji reaction to a message. Requires authentication. It is idempotent, so multiple calls from the same user with the same emoji result in a single reaction.', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId', 'messageId', 'value'], properties: { convoId: { type: 'string', }, messageId: { type: 'string', }, value: { type: 'string', minLength: 1, maxLength: 64, minGraphemes: 1, maxGraphemes: 1, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['message'], properties: { message: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageView', }, }, }, }, errors: [ { name: 'ReactionMessageDeleted', description: 'Indicates that the message has been deleted and reactions can no longer be added/removed.', }, { name: 'ReactionLimitReached', description: "Indicates that the message has the maximum number of reactions allowed for a single user, and the requested reaction wasn't yet present. If it was already present, the request will not fail since it is idempotent.", }, { name: 'ReactionInvalidValue', description: 'Indicates the value for the reaction is not acceptable. In general, this means it is not an emoji.', }, ], }, }, }, ChatBskyConvoDefs: { lexicon: 1, id: 'chat.bsky.convo.defs', defs: { messageRef: { type: 'object', required: ['did', 'messageId', 'convoId'], properties: { did: { type: 'string', format: 'did', }, convoId: { type: 'string', }, messageId: { type: 'string', }, }, }, messageInput: { type: 'object', required: ['text'], properties: { text: { type: 'string', maxLength: 10000, maxGraphemes: 1000, }, facets: { type: 'array', description: 'Annotations of text (mentions, URLs, hashtags, etc)', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, embed: { type: 'union', refs: ['lex:app.bsky.embed.record'], }, }, }, messageView: { type: 'object', required: ['id', 'rev', 'text', 'sender', 'sentAt'], properties: { id: { type: 'string', }, rev: { type: 'string', }, text: { type: 'string', maxLength: 10000, maxGraphemes: 1000, }, facets: { type: 'array', description: 'Annotations of text (mentions, URLs, hashtags, etc)', items: { type: 'ref', ref: 'lex:app.bsky.richtext.facet', }, }, embed: { type: 'union', refs: ['lex:app.bsky.embed.record#view'], }, reactions: { type: 'array', description: 'Reactions to this message, in ascending order of creation time.', items: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#reactionView', }, }, sender: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageViewSender', }, sentAt: { type: 'string', format: 'datetime', }, }, }, deletedMessageView: { type: 'object', required: ['id', 'rev', 'sender', 'sentAt'], properties: { id: { type: 'string', }, rev: { type: 'string', }, sender: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageViewSender', }, sentAt: { type: 'string', format: 'datetime', }, }, }, messageViewSender: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, reactionView: { type: 'object', required: ['value', 'sender', 'createdAt'], properties: { value: { type: 'string', }, sender: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#reactionViewSender', }, createdAt: { type: 'string', format: 'datetime', }, }, }, reactionViewSender: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, messageAndReactionView: { type: 'object', required: ['message', 'reaction'], properties: { message: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageView', }, reaction: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#reactionView', }, }, }, convoView: { type: 'object', required: ['id', 'rev', 'members', 'muted', 'unreadCount'], properties: { id: { type: 'string', }, rev: { type: 'string', }, members: { type: 'array', items: { type: 'ref', ref: 'lex:chat.bsky.actor.defs#profileViewBasic', }, }, lastMessage: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, lastReaction: { type: 'union', refs: ['lex:chat.bsky.convo.defs#messageAndReactionView'], }, muted: { type: 'boolean', }, status: { type: 'string', knownValues: ['request', 'accepted'], }, unreadCount: { type: 'integer', }, }, }, logBeginConvo: { type: 'object', required: ['rev', 'convoId'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, }, }, logAcceptConvo: { type: 'object', required: ['rev', 'convoId'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, }, }, logLeaveConvo: { type: 'object', required: ['rev', 'convoId'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, }, }, logMuteConvo: { type: 'object', required: ['rev', 'convoId'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, }, }, logUnmuteConvo: { type: 'object', required: ['rev', 'convoId'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, }, }, logCreateMessage: { type: 'object', required: ['rev', 'convoId', 'message'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, message: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, }, }, logDeleteMessage: { type: 'object', required: ['rev', 'convoId', 'message'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, message: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, }, }, logReadMessage: { type: 'object', required: ['rev', 'convoId', 'message'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, message: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, }, }, logAddReaction: { type: 'object', required: ['rev', 'convoId', 'message', 'reaction'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, message: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, reaction: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#reactionView', }, }, }, logRemoveReaction: { type: 'object', required: ['rev', 'convoId', 'message', 'reaction'], properties: { rev: { type: 'string', }, convoId: { type: 'string', }, message: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, reaction: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#reactionView', }, }, }, }, }, ChatBskyConvoDeleteMessageForSelf: { lexicon: 1, id: 'chat.bsky.convo.deleteMessageForSelf', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId', 'messageId'], properties: { convoId: { type: 'string', }, messageId: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#deletedMessageView', }, }, }, }, }, ChatBskyConvoGetConvo: { lexicon: 1, id: 'chat.bsky.convo.getConvo', defs: { main: { type: 'query', parameters: { type: 'params', required: ['convoId'], properties: { convoId: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['convo'], properties: { convo: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#convoView', }, }, }, }, }, }, }, ChatBskyConvoGetConvoAvailability: { lexicon: 1, id: 'chat.bsky.convo.getConvoAvailability', defs: { main: { type: 'query', description: 'Get whether the requester and the other members can chat. If an existing convo is found for these members, it is returned.', parameters: { type: 'params', required: ['members'], properties: { members: { type: 'array', minLength: 1, maxLength: 10, items: { type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['canChat'], properties: { canChat: { type: 'boolean', }, convo: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#convoView', }, }, }, }, }, }, }, ChatBskyConvoGetConvoForMembers: { lexicon: 1, id: 'chat.bsky.convo.getConvoForMembers', defs: { main: { type: 'query', parameters: { type: 'params', required: ['members'], properties: { members: { type: 'array', minLength: 1, maxLength: 10, items: { type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['convo'], properties: { convo: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#convoView', }, }, }, }, }, }, }, ChatBskyConvoGetLog: { lexicon: 1, id: 'chat.bsky.convo.getLog', defs: { main: { type: 'query', parameters: { type: 'params', required: [], properties: { cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['logs'], properties: { cursor: { type: 'string', }, logs: { type: 'array', items: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#logBeginConvo', 'lex:chat.bsky.convo.defs#logAcceptConvo', 'lex:chat.bsky.convo.defs#logLeaveConvo', 'lex:chat.bsky.convo.defs#logMuteConvo', 'lex:chat.bsky.convo.defs#logUnmuteConvo', 'lex:chat.bsky.convo.defs#logCreateMessage', 'lex:chat.bsky.convo.defs#logDeleteMessage', 'lex:chat.bsky.convo.defs#logReadMessage', 'lex:chat.bsky.convo.defs#logAddReaction', 'lex:chat.bsky.convo.defs#logRemoveReaction', ], }, }, }, }, }, }, }, }, ChatBskyConvoGetMessages: { lexicon: 1, id: 'chat.bsky.convo.getMessages', defs: { main: { type: 'query', parameters: { type: 'params', required: ['convoId'], properties: { convoId: { type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['messages'], properties: { cursor: { type: 'string', }, messages: { type: 'array', items: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, }, }, }, }, }, }, }, ChatBskyConvoLeaveConvo: { lexicon: 1, id: 'chat.bsky.convo.leaveConvo', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId'], properties: { convoId: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['convoId', 'rev'], properties: { convoId: { type: 'string', }, rev: { type: 'string', }, }, }, }, }, }, }, ChatBskyConvoListConvos: { lexicon: 1, id: 'chat.bsky.convo.listConvos', defs: { main: { type: 'query', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, readState: { type: 'string', knownValues: ['unread'], }, status: { type: 'string', knownValues: ['request', 'accepted'], }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['convos'], properties: { cursor: { type: 'string', }, convos: { type: 'array', items: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#convoView', }, }, }, }, }, }, }, }, ChatBskyConvoMuteConvo: { lexicon: 1, id: 'chat.bsky.convo.muteConvo', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId'], properties: { convoId: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['convo'], properties: { convo: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#convoView', }, }, }, }, }, }, }, ChatBskyConvoRemoveReaction: { lexicon: 1, id: 'chat.bsky.convo.removeReaction', defs: { main: { type: 'procedure', description: "Removes an emoji reaction from a message. Requires authentication. It is idempotent, so multiple calls from the same user with the same emoji result in that reaction not being present, even if it already wasn't.", input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId', 'messageId', 'value'], properties: { convoId: { type: 'string', }, messageId: { type: 'string', }, value: { type: 'string', minLength: 1, maxLength: 64, minGraphemes: 1, maxGraphemes: 1, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['message'], properties: { message: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageView', }, }, }, }, errors: [ { name: 'ReactionMessageDeleted', description: 'Indicates that the message has been deleted and reactions can no longer be added/removed.', }, { name: 'ReactionInvalidValue', description: 'Indicates the value for the reaction is not acceptable. In general, this means it is not an emoji.', }, ], }, }, }, ChatBskyConvoSendMessage: { lexicon: 1, id: 'chat.bsky.convo.sendMessage', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId', 'message'], properties: { convoId: { type: 'string', }, message: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageInput', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageView', }, }, }, }, }, ChatBskyConvoSendMessageBatch: { lexicon: 1, id: 'chat.bsky.convo.sendMessageBatch', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['items'], properties: { items: { type: 'array', maxLength: 100, items: { type: 'ref', ref: 'lex:chat.bsky.convo.sendMessageBatch#batchItem', }, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['items'], properties: { items: { type: 'array', items: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageView', }, }, }, }, }, }, batchItem: { type: 'object', required: ['convoId', 'message'], properties: { convoId: { type: 'string', }, message: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#messageInput', }, }, }, }, }, ChatBskyConvoUnmuteConvo: { lexicon: 1, id: 'chat.bsky.convo.unmuteConvo', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId'], properties: { convoId: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['convo'], properties: { convo: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#convoView', }, }, }, }, }, }, }, ChatBskyConvoUpdateAllRead: { lexicon: 1, id: 'chat.bsky.convo.updateAllRead', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', properties: { status: { type: 'string', knownValues: ['request', 'accepted'], }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['updatedCount'], properties: { updatedCount: { description: 'The count of updated convos.', type: 'integer', }, }, }, }, }, }, }, ChatBskyConvoUpdateRead: { lexicon: 1, id: 'chat.bsky.convo.updateRead', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['convoId'], properties: { convoId: { type: 'string', }, messageId: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['convo'], properties: { convo: { type: 'ref', ref: 'lex:chat.bsky.convo.defs#convoView', }, }, }, }, }, }, }, ChatBskyModerationGetActorMetadata: { lexicon: 1, id: 'chat.bsky.moderation.getActorMetadata', defs: { main: { type: 'query', parameters: { type: 'params', required: ['actor'], properties: { actor: { type: 'string', format: 'did', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['day', 'month', 'all'], properties: { day: { type: 'ref', ref: 'lex:chat.bsky.moderation.getActorMetadata#metadata', }, month: { type: 'ref', ref: 'lex:chat.bsky.moderation.getActorMetadata#metadata', }, all: { type: 'ref', ref: 'lex:chat.bsky.moderation.getActorMetadata#metadata', }, }, }, }, }, metadata: { type: 'object', required: [ 'messagesSent', 'messagesReceived', 'convos', 'convosStarted', ], properties: { messagesSent: { type: 'integer', }, messagesReceived: { type: 'integer', }, convos: { type: 'integer', }, convosStarted: { type: 'integer', }, }, }, }, }, ChatBskyModerationGetMessageContext: { lexicon: 1, id: 'chat.bsky.moderation.getMessageContext', defs: { main: { type: 'query', parameters: { type: 'params', required: ['messageId'], properties: { convoId: { type: 'string', description: 'Conversation that the message is from. NOTE: this field will eventually be required.', }, messageId: { type: 'string', }, before: { type: 'integer', default: 5, }, after: { type: 'integer', default: 5, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['messages'], properties: { messages: { type: 'array', items: { type: 'union', refs: [ 'lex:chat.bsky.convo.defs#messageView', 'lex:chat.bsky.convo.defs#deletedMessageView', ], }, }, }, }, }, }, }, }, ChatBskyModerationUpdateActorAccess: { lexicon: 1, id: 'chat.bsky.moderation.updateActorAccess', defs: { main: { type: 'procedure', input: { encoding: 'application/json', schema: { type: 'object', required: ['actor', 'allowAccess'], properties: { actor: { type: 'string', format: 'did', }, allowAccess: { type: 'boolean', }, ref: { type: 'string', }, }, }, }, }, }, }, ComAtprotoAdminDefs: { lexicon: 1, id: 'com.atproto.admin.defs', defs: { statusAttr: { type: 'object', required: ['applied'], properties: { applied: { type: 'boolean', }, ref: { type: 'string', }, }, }, accountView: { type: 'object', required: ['did', 'handle', 'indexedAt'], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, email: { type: 'string', }, relatedRecords: { type: 'array', items: { type: 'unknown', }, }, indexedAt: { type: 'string', format: 'datetime', }, invitedBy: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCode', }, invites: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCode', }, }, invitesDisabled: { type: 'boolean', }, emailConfirmedAt: { type: 'string', format: 'datetime', }, inviteNote: { type: 'string', }, deactivatedAt: { type: 'string', format: 'datetime', }, threatSignatures: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.admin.defs#threatSignature', }, }, }, }, repoRef: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, repoBlobRef: { type: 'object', required: ['did', 'cid'], properties: { did: { type: 'string', format: 'did', }, cid: { type: 'string', format: 'cid', }, recordUri: { type: 'string', format: 'at-uri', }, }, }, threatSignature: { type: 'object', required: ['property', 'value'], properties: { property: { type: 'string', }, value: { type: 'string', }, }, }, }, }, ComAtprotoAdminDeleteAccount: { lexicon: 1, id: 'com.atproto.admin.deleteAccount', defs: { main: { type: 'procedure', description: 'Delete a user account as an administrator.', input: { encoding: 'application/json', schema: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, }, }, }, }, ComAtprotoAdminDisableAccountInvites: { lexicon: 1, id: 'com.atproto.admin.disableAccountInvites', defs: { main: { type: 'procedure', description: 'Disable an account from receiving new invite codes, but does not invalidate existing codes.', input: { encoding: 'application/json', schema: { type: 'object', required: ['account'], properties: { account: { type: 'string', format: 'did', }, note: { type: 'string', description: 'Optional reason for disabled invites.', }, }, }, }, }, }, }, ComAtprotoAdminDisableInviteCodes: { lexicon: 1, id: 'com.atproto.admin.disableInviteCodes', defs: { main: { type: 'procedure', description: 'Disable some set of codes and/or all codes associated with a set of users.', input: { encoding: 'application/json', schema: { type: 'object', properties: { codes: { type: 'array', items: { type: 'string', }, }, accounts: { type: 'array', items: { type: 'string', }, }, }, }, }, }, }, }, ComAtprotoAdminEnableAccountInvites: { lexicon: 1, id: 'com.atproto.admin.enableAccountInvites', defs: { main: { type: 'procedure', description: "Re-enable an account's ability to receive invite codes.", input: { encoding: 'application/json', schema: { type: 'object', required: ['account'], properties: { account: { type: 'string', format: 'did', }, note: { type: 'string', description: 'Optional reason for enabled invites.', }, }, }, }, }, }, }, ComAtprotoAdminGetAccountInfo: { lexicon: 1, id: 'com.atproto.admin.getAccountInfo', defs: { main: { type: 'query', description: 'Get details about an account.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:com.atproto.admin.defs#accountView', }, }, }, }, }, ComAtprotoAdminGetAccountInfos: { lexicon: 1, id: 'com.atproto.admin.getAccountInfos', defs: { main: { type: 'query', description: 'Get details about some accounts.', parameters: { type: 'params', required: ['dids'], properties: { dids: { type: 'array', items: { type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['infos'], properties: { infos: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.admin.defs#accountView', }, }, }, }, }, }, }, }, ComAtprotoAdminGetInviteCodes: { lexicon: 1, id: 'com.atproto.admin.getInviteCodes', defs: { main: { type: 'query', description: 'Get an admin view of invite codes.', parameters: { type: 'params', properties: { sort: { type: 'string', knownValues: ['recent', 'usage'], default: 'recent', }, limit: { type: 'integer', minimum: 1, maximum: 500, default: 100, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['codes'], properties: { cursor: { type: 'string', }, codes: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCode', }, }, }, }, }, }, }, }, ComAtprotoAdminGetSubjectStatus: { lexicon: 1, id: 'com.atproto.admin.getSubjectStatus', defs: { main: { type: 'query', description: 'Get the service-specific admin status of a subject (account, record, or blob).', parameters: { type: 'params', properties: { did: { type: 'string', format: 'did', }, uri: { type: 'string', format: 'at-uri', }, blob: { type: 'string', format: 'cid', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subject'], properties: { subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', 'lex:com.atproto.admin.defs#repoBlobRef', ], }, takedown: { type: 'ref', ref: 'lex:com.atproto.admin.defs#statusAttr', }, deactivated: { type: 'ref', ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, }, }, }, }, ComAtprotoAdminSearchAccounts: { lexicon: 1, id: 'com.atproto.admin.searchAccounts', defs: { main: { type: 'query', description: 'Get list of accounts that matches your search query.', parameters: { type: 'params', properties: { email: { type: 'string', }, cursor: { type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['accounts'], properties: { cursor: { type: 'string', }, accounts: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.admin.defs#accountView', }, }, }, }, }, }, }, }, ComAtprotoAdminSendEmail: { lexicon: 1, id: 'com.atproto.admin.sendEmail', defs: { main: { type: 'procedure', description: "Send email to a user's account email address.", input: { encoding: 'application/json', schema: { type: 'object', required: ['recipientDid', 'content', 'senderDid'], properties: { recipientDid: { type: 'string', format: 'did', }, content: { type: 'string', }, subject: { type: 'string', }, senderDid: { type: 'string', format: 'did', }, comment: { type: 'string', description: "Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers", }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['sent'], properties: { sent: { type: 'boolean', }, }, }, }, }, }, }, ComAtprotoAdminUpdateAccountEmail: { lexicon: 1, id: 'com.atproto.admin.updateAccountEmail', defs: { main: { type: 'procedure', description: "Administrative action to update an account's email.", input: { encoding: 'application/json', schema: { type: 'object', required: ['account', 'email'], properties: { account: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo.', }, email: { type: 'string', }, }, }, }, }, }, }, ComAtprotoAdminUpdateAccountHandle: { lexicon: 1, id: 'com.atproto.admin.updateAccountHandle', defs: { main: { type: 'procedure', description: "Administrative action to update an account's handle.", input: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'handle'], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, }, }, }, }, }, }, ComAtprotoAdminUpdateAccountPassword: { lexicon: 1, id: 'com.atproto.admin.updateAccountPassword', defs: { main: { type: 'procedure', description: 'Update the password for a user account as an administrator.', input: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'password'], properties: { did: { type: 'string', format: 'did', }, password: { type: 'string', }, }, }, }, }, }, }, ComAtprotoAdminUpdateAccountSigningKey: { lexicon: 1, id: 'com.atproto.admin.updateAccountSigningKey', defs: { main: { type: 'procedure', description: "Administrative action to update an account's signing key in their Did document.", input: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'signingKey'], properties: { did: { type: 'string', format: 'did', }, signingKey: { type: 'string', format: 'did', description: 'Did-key formatted public key', }, }, }, }, }, }, }, ComAtprotoAdminUpdateSubjectStatus: { lexicon: 1, id: 'com.atproto.admin.updateSubjectStatus', defs: { main: { type: 'procedure', description: 'Update the service-specific admin status of a subject (account, record, or blob).', input: { encoding: 'application/json', schema: { type: 'object', required: ['subject'], properties: { subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', 'lex:com.atproto.admin.defs#repoBlobRef', ], }, takedown: { type: 'ref', ref: 'lex:com.atproto.admin.defs#statusAttr', }, deactivated: { type: 'ref', ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subject'], properties: { subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', 'lex:com.atproto.admin.defs#repoBlobRef', ], }, takedown: { type: 'ref', ref: 'lex:com.atproto.admin.defs#statusAttr', }, }, }, }, }, }, }, ComAtprotoIdentityDefs: { lexicon: 1, id: 'com.atproto.identity.defs', defs: { identityInfo: { type: 'object', required: ['did', 'handle', 'didDoc'], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', description: "The validated handle of the account; or 'handle.invalid' if the handle did not bi-directionally match the DID document.", }, didDoc: { type: 'unknown', description: 'The complete DID document for the identity.', }, }, }, }, }, ComAtprotoIdentityGetRecommendedDidCredentials: { lexicon: 1, id: 'com.atproto.identity.getRecommendedDidCredentials', defs: { main: { type: 'query', description: 'Describe the credentials that should be included in the DID doc of an account that is migrating to this service.', output: { encoding: 'application/json', schema: { type: 'object', properties: { rotationKeys: { description: 'Recommended rotation keys for PLC dids. Should be undefined (or ignored) for did:webs.', type: 'array', items: { type: 'string', }, }, alsoKnownAs: { type: 'array', items: { type: 'string', }, }, verificationMethods: { type: 'unknown', }, services: { type: 'unknown', }, }, }, }, }, }, }, ComAtprotoIdentityRefreshIdentity: { lexicon: 1, id: 'com.atproto.identity.refreshIdentity', defs: { main: { type: 'procedure', description: 'Request that the server re-resolve an identity (DID and handle). The server may ignore this request, or require authentication, depending on the role, implementation, and policy of the server.', input: { encoding: 'application/json', schema: { type: 'object', required: ['identifier'], properties: { identifier: { type: 'string', format: 'at-identifier', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:com.atproto.identity.defs#identityInfo', }, }, errors: [ { name: 'HandleNotFound', description: 'The resolution process confirmed that the handle does not resolve to any DID.', }, { name: 'DidNotFound', description: 'The DID resolution process confirmed that there is no current DID.', }, { name: 'DidDeactivated', description: 'The DID previously existed, but has been deactivated.', }, ], }, }, }, ComAtprotoIdentityRequestPlcOperationSignature: { lexicon: 1, id: 'com.atproto.identity.requestPlcOperationSignature', defs: { main: { type: 'procedure', description: 'Request an email with a code to in order to request a signed PLC operation. Requires Auth.', }, }, }, ComAtprotoIdentityResolveDid: { lexicon: 1, id: 'com.atproto.identity.resolveDid', defs: { main: { type: 'query', description: 'Resolves DID to DID document. Does not bi-directionally verify handle.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', description: 'DID to resolve.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['didDoc'], properties: { didDoc: { type: 'unknown', description: 'The complete DID document for the identity.', }, }, }, }, errors: [ { name: 'DidNotFound', description: 'The DID resolution process confirmed that there is no current DID.', }, { name: 'DidDeactivated', description: 'The DID previously existed, but has been deactivated.', }, ], }, }, }, ComAtprotoIdentityResolveHandle: { lexicon: 1, id: 'com.atproto.identity.resolveHandle', defs: { main: { type: 'query', description: 'Resolves an atproto handle (hostname) to a DID. Does not necessarily bi-directionally verify against the the DID document.', parameters: { type: 'params', required: ['handle'], properties: { handle: { type: 'string', format: 'handle', description: 'The handle to resolve.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, }, errors: [ { name: 'HandleNotFound', description: 'The resolution process confirmed that the handle does not resolve to any DID.', }, ], }, }, }, ComAtprotoIdentityResolveIdentity: { lexicon: 1, id: 'com.atproto.identity.resolveIdentity', defs: { main: { type: 'query', description: 'Resolves an identity (DID or Handle) to a full identity (DID document and verified handle).', parameters: { type: 'params', required: ['identifier'], properties: { identifier: { type: 'string', format: 'at-identifier', description: 'Handle or DID to resolve.', }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:com.atproto.identity.defs#identityInfo', }, }, errors: [ { name: 'HandleNotFound', description: 'The resolution process confirmed that the handle does not resolve to any DID.', }, { name: 'DidNotFound', description: 'The DID resolution process confirmed that there is no current DID.', }, { name: 'DidDeactivated', description: 'The DID previously existed, but has been deactivated.', }, ], }, }, }, ComAtprotoIdentitySignPlcOperation: { lexicon: 1, id: 'com.atproto.identity.signPlcOperation', defs: { main: { type: 'procedure', description: "Signs a PLC operation to update some value(s) in the requesting DID's document.", input: { encoding: 'application/json', schema: { type: 'object', properties: { token: { description: 'A token received through com.atproto.identity.requestPlcOperationSignature', type: 'string', }, rotationKeys: { type: 'array', items: { type: 'string', }, }, alsoKnownAs: { type: 'array', items: { type: 'string', }, }, verificationMethods: { type: 'unknown', }, services: { type: 'unknown', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['operation'], properties: { operation: { type: 'unknown', description: 'A signed DID PLC operation.', }, }, }, }, }, }, }, ComAtprotoIdentitySubmitPlcOperation: { lexicon: 1, id: 'com.atproto.identity.submitPlcOperation', defs: { main: { type: 'procedure', description: "Validates a PLC operation to ensure that it doesn't violate a service's constraints or get the identity into a bad state, then submits it to the PLC registry", input: { encoding: 'application/json', schema: { type: 'object', required: ['operation'], properties: { operation: { type: 'unknown', }, }, }, }, }, }, }, ComAtprotoIdentityUpdateHandle: { lexicon: 1, id: 'com.atproto.identity.updateHandle', defs: { main: { type: 'procedure', description: "Updates the current account's handle. Verifies handle validity, and updates did:plc document if necessary. Implemented by PDS, and requires auth.", input: { encoding: 'application/json', schema: { type: 'object', required: ['handle'], properties: { handle: { type: 'string', format: 'handle', description: 'The new handle.', }, }, }, }, }, }, }, ComAtprotoLabelDefs: { lexicon: 1, id: 'com.atproto.label.defs', defs: { label: { type: 'object', description: 'Metadata tag on an atproto resource (eg, repo or record).', required: ['src', 'uri', 'val', 'cts'], properties: { ver: { type: 'integer', description: 'The AT Protocol version of the label object.', }, src: { type: 'string', format: 'did', description: 'DID of the actor who created this label.', }, uri: { type: 'string', format: 'uri', description: 'AT URI of the record, repository (account), or other resource that this label applies to.', }, cid: { type: 'string', format: 'cid', description: "Optionally, CID specifying the specific version of 'uri' resource this label applies to.", }, val: { type: 'string', maxLength: 128, description: 'The short string name of the value or type of this label.', }, neg: { type: 'boolean', description: 'If true, this is a negation label, overwriting a previous label.', }, cts: { type: 'string', format: 'datetime', description: 'Timestamp when this label was created.', }, exp: { type: 'string', format: 'datetime', description: 'Timestamp at which this label expires (no longer applies).', }, sig: { type: 'bytes', description: 'Signature of dag-cbor encoded label.', }, }, }, selfLabels: { type: 'object', description: 'Metadata tags on an atproto record, published by the author within the record.', required: ['values'], properties: { values: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#selfLabel', }, maxLength: 10, }, }, }, selfLabel: { type: 'object', description: 'Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.', required: ['val'], properties: { val: { type: 'string', maxLength: 128, description: 'The short string name of the value or type of this label.', }, }, }, labelValueDefinition: { type: 'object', description: 'Declares a label value and its expected interpretations and behaviors.', required: ['identifier', 'severity', 'blurs', 'locales'], properties: { identifier: { type: 'string', description: "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", maxLength: 100, maxGraphemes: 100, }, severity: { type: 'string', description: "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", knownValues: ['inform', 'alert', 'none'], }, blurs: { type: 'string', description: "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", knownValues: ['content', 'media', 'none'], }, defaultSetting: { type: 'string', description: 'The default setting for this label.', knownValues: ['ignore', 'warn', 'hide'], default: 'warn', }, adultOnly: { type: 'boolean', description: 'Does the user need to have adult content enabled in order to configure this label?', }, locales: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#labelValueDefinitionStrings', }, }, }, }, labelValueDefinitionStrings: { type: 'object', description: 'Strings which describe the label in the UI, localized into a specific language.', required: ['lang', 'name', 'description'], properties: { lang: { type: 'string', description: 'The code of the language these strings are written in.', format: 'language', }, name: { type: 'string', description: 'A short human-readable name for the label.', maxGraphemes: 64, maxLength: 640, }, description: { type: 'string', description: 'A longer description of what the label means and why it might be applied.', maxGraphemes: 10000, maxLength: 100000, }, }, }, labelValue: { type: 'string', knownValues: [ '!hide', '!no-promote', '!warn', '!no-unauthenticated', 'dmca-violation', 'doxxing', 'porn', 'sexual', 'nudity', 'nsfl', 'gore', ], }, }, }, ComAtprotoLabelQueryLabels: { lexicon: 1, id: 'com.atproto.label.queryLabels', defs: { main: { type: 'query', description: 'Find labels relevant to the provided AT-URI patterns. Public endpoint for moderation services, though may return different or additional results with auth.', parameters: { type: 'params', required: ['uriPatterns'], properties: { uriPatterns: { type: 'array', items: { type: 'string', }, description: "List of AT URI patterns to match (boolean 'OR'). Each may be a prefix (ending with '*'; will match inclusive of the string leading to '*'), or a full URI.", }, sources: { type: 'array', items: { type: 'string', format: 'did', }, description: 'Optional list of label sources (DIDs) to filter on.', }, limit: { type: 'integer', minimum: 1, maximum: 250, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['labels'], properties: { cursor: { type: 'string', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, }, }, }, }, }, }, ComAtprotoLabelSubscribeLabels: { lexicon: 1, id: 'com.atproto.label.subscribeLabels', defs: { main: { type: 'subscription', description: 'Subscribe to stream of labels (and negations). Public endpoint implemented by mod services. Uses same sequencing scheme as repo event stream.', parameters: { type: 'params', properties: { cursor: { type: 'integer', description: 'The last known event seq number to backfill from.', }, }, }, message: { schema: { type: 'union', refs: [ 'lex:com.atproto.label.subscribeLabels#labels', 'lex:com.atproto.label.subscribeLabels#info', ], }, }, errors: [ { name: 'FutureCursor', }, ], }, labels: { type: 'object', required: ['seq', 'labels'], properties: { seq: { type: 'integer', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, }, }, info: { type: 'object', required: ['name'], properties: { name: { type: 'string', knownValues: ['OutdatedCursor'], }, message: { type: 'string', }, }, }, }, }, ComAtprotoLexiconResolveLexicon: { lexicon: 1, id: 'com.atproto.lexicon.resolveLexicon', defs: { main: { type: 'query', description: 'Resolves an atproto lexicon (NSID) to a schema.', parameters: { type: 'params', properties: { nsid: { format: 'nsid', type: 'string', description: 'The lexicon NSID to resolve.', }, }, required: ['nsid'], }, output: { encoding: 'application/json', schema: { type: 'object', properties: { cid: { type: 'string', format: 'cid', description: 'The CID of the lexicon schema record.', }, schema: { type: 'ref', ref: 'lex:com.atproto.lexicon.schema#main', description: 'The resolved lexicon schema record.', }, uri: { type: 'string', format: 'at-uri', description: 'The AT-URI of the lexicon schema record.', }, }, required: ['uri', 'cid', 'schema'], }, }, errors: [ { description: 'No lexicon was resolved for the NSID.', name: 'LexiconNotFound', }, ], }, }, }, ComAtprotoLexiconSchema: { lexicon: 1, id: 'com.atproto.lexicon.schema', defs: { main: { type: 'record', description: "Representation of Lexicon schemas themselves, when published as atproto records. Note that the schema language is not defined in Lexicon; this meta schema currently only includes a single version field ('lexicon'). See the atproto specifications for description of the other expected top-level fields ('id', 'defs', etc).", key: 'nsid', record: { type: 'object', required: ['lexicon'], properties: { lexicon: { type: 'integer', description: "Indicates the 'version' of the Lexicon language. Must be '1' for the current atproto/Lexicon schema system.", }, }, }, }, }, }, ComAtprotoModerationCreateReport: { lexicon: 1, id: 'com.atproto.moderation.createReport', defs: { main: { type: 'procedure', description: 'Submit a moderation report regarding an atproto account or record. Implemented by moderation services (with PDS proxying), and requires auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['reasonType', 'subject'], properties: { reasonType: { type: 'ref', description: 'Indicates the broad category of violation the report is for.', ref: 'lex:com.atproto.moderation.defs#reasonType', }, reason: { type: 'string', maxGraphemes: 2000, maxLength: 20000, description: 'Additional context about the content and violation.', }, subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', ], }, modTool: { type: 'ref', ref: 'lex:com.atproto.moderation.createReport#modTool', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: [ 'id', 'reasonType', 'subject', 'reportedBy', 'createdAt', ], properties: { id: { type: 'integer', }, reasonType: { type: 'ref', ref: 'lex:com.atproto.moderation.defs#reasonType', }, reason: { type: 'string', maxGraphemes: 2000, maxLength: 20000, }, subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', ], }, reportedBy: { type: 'string', format: 'did', }, createdAt: { type: 'string', format: 'datetime', }, }, }, }, }, modTool: { type: 'object', description: 'Moderation tool information for tracing the source of the action', required: ['name'], properties: { name: { type: 'string', description: "Name/identifier of the source (e.g., 'bsky-app/android', 'bsky-web/chrome')", }, meta: { type: 'unknown', description: 'Additional arbitrary metadata about the source', }, }, }, }, }, ComAtprotoModerationDefs: { lexicon: 1, id: 'com.atproto.moderation.defs', defs: { reasonType: { type: 'string', knownValues: [ 'com.atproto.moderation.defs#reasonSpam', 'com.atproto.moderation.defs#reasonViolation', 'com.atproto.moderation.defs#reasonMisleading', 'com.atproto.moderation.defs#reasonSexual', 'com.atproto.moderation.defs#reasonRude', 'com.atproto.moderation.defs#reasonOther', 'com.atproto.moderation.defs#reasonAppeal', 'tools.ozone.report.defs#reasonAppeal', 'tools.ozone.report.defs#reasonOther', 'tools.ozone.report.defs#reasonViolenceAnimal', 'tools.ozone.report.defs#reasonViolenceThreats', 'tools.ozone.report.defs#reasonViolenceGraphicContent', 'tools.ozone.report.defs#reasonViolenceGlorification', 'tools.ozone.report.defs#reasonViolenceExtremistContent', 'tools.ozone.report.defs#reasonViolenceTrafficking', 'tools.ozone.report.defs#reasonViolenceOther', 'tools.ozone.report.defs#reasonSexualAbuseContent', 'tools.ozone.report.defs#reasonSexualNCII', 'tools.ozone.report.defs#reasonSexualDeepfake', 'tools.ozone.report.defs#reasonSexualAnimal', 'tools.ozone.report.defs#reasonSexualUnlabeled', 'tools.ozone.report.defs#reasonSexualOther', 'tools.ozone.report.defs#reasonChildSafetyCSAM', 'tools.ozone.report.defs#reasonChildSafetyGroom', 'tools.ozone.report.defs#reasonChildSafetyPrivacy', 'tools.ozone.report.defs#reasonChildSafetyHarassment', 'tools.ozone.report.defs#reasonChildSafetyOther', 'tools.ozone.report.defs#reasonHarassmentTroll', 'tools.ozone.report.defs#reasonHarassmentTargeted', 'tools.ozone.report.defs#reasonHarassmentHateSpeech', 'tools.ozone.report.defs#reasonHarassmentDoxxing', 'tools.ozone.report.defs#reasonHarassmentOther', 'tools.ozone.report.defs#reasonMisleadingBot', 'tools.ozone.report.defs#reasonMisleadingImpersonation', 'tools.ozone.report.defs#reasonMisleadingSpam', 'tools.ozone.report.defs#reasonMisleadingScam', 'tools.ozone.report.defs#reasonMisleadingElections', 'tools.ozone.report.defs#reasonMisleadingOther', 'tools.ozone.report.defs#reasonRuleSiteSecurity', 'tools.ozone.report.defs#reasonRuleProhibitedSales', 'tools.ozone.report.defs#reasonRuleBanEvasion', 'tools.ozone.report.defs#reasonRuleOther', 'tools.ozone.report.defs#reasonSelfHarmContent', 'tools.ozone.report.defs#reasonSelfHarmED', 'tools.ozone.report.defs#reasonSelfHarmStunts', 'tools.ozone.report.defs#reasonSelfHarmSubstances', 'tools.ozone.report.defs#reasonSelfHarmOther', ], }, reasonSpam: { type: 'token', description: 'Spam: frequent unwanted promotion, replies, mentions. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingSpam`.', }, reasonViolation: { type: 'token', description: 'Direct violation of server rules, laws, terms of service. Prefer new lexicon definition `tools.ozone.report.defs#reasonRuleOther`.', }, reasonMisleading: { type: 'token', description: 'Misleading identity, affiliation, or content. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingOther`.', }, reasonSexual: { type: 'token', description: 'Unwanted or mislabeled sexual content. Prefer new lexicon definition `tools.ozone.report.defs#reasonSexualUnlabeled`.', }, reasonRude: { type: 'token', description: 'Rude, harassing, explicit, or otherwise unwelcoming behavior. Prefer new lexicon definition `tools.ozone.report.defs#reasonHarassmentOther`.', }, reasonOther: { type: 'token', description: 'Reports not falling under another report category. Prefer new lexicon definition `tools.ozone.report.defs#reasonOther`.', }, reasonAppeal: { type: 'token', description: 'Appeal a previously taken moderation action', }, subjectType: { type: 'string', description: 'Tag describing a type of subject that might be reported.', knownValues: ['account', 'record', 'chat'], }, }, }, ComAtprotoRepoApplyWrites: { lexicon: 1, id: 'com.atproto.repo.applyWrites', defs: { main: { type: 'procedure', description: 'Apply a batch transaction of repository creates, updates, and deletes. Requires auth, implemented by PDS.', input: { encoding: 'application/json', schema: { type: 'object', required: ['repo', 'writes'], properties: { repo: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo (aka, current account).', }, validate: { type: 'boolean', description: "Can be set to 'false' to skip Lexicon schema validation of record data across all operations, 'true' to require it, or leave unset to validate only for known Lexicons.", }, writes: { type: 'array', items: { type: 'union', refs: [ 'lex:com.atproto.repo.applyWrites#create', 'lex:com.atproto.repo.applyWrites#update', 'lex:com.atproto.repo.applyWrites#delete', ], closed: true, }, }, swapCommit: { type: 'string', description: 'If provided, the entire operation will fail if the current repo commit CID does not match this value. Used to prevent conflicting repo mutations.', format: 'cid', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: [], properties: { commit: { type: 'ref', ref: 'lex:com.atproto.repo.defs#commitMeta', }, results: { type: 'array', items: { type: 'union', refs: [ 'lex:com.atproto.repo.applyWrites#createResult', 'lex:com.atproto.repo.applyWrites#updateResult', 'lex:com.atproto.repo.applyWrites#deleteResult', ], closed: true, }, }, }, }, }, errors: [ { name: 'InvalidSwap', description: "Indicates that the 'swapCommit' parameter did not match current commit.", }, ], }, create: { type: 'object', description: 'Operation which creates a new record.', required: ['collection', 'value'], properties: { collection: { type: 'string', format: 'nsid', }, rkey: { type: 'string', maxLength: 512, format: 'record-key', description: 'NOTE: maxLength is redundant with record-key format. Keeping it temporarily to ensure backwards compatibility.', }, value: { type: 'unknown', }, }, }, update: { type: 'object', description: 'Operation which updates an existing record.', required: ['collection', 'rkey', 'value'], properties: { collection: { type: 'string', format: 'nsid', }, rkey: { type: 'string', format: 'record-key', }, value: { type: 'unknown', }, }, }, delete: { type: 'object', description: 'Operation which deletes an existing record.', required: ['collection', 'rkey'], properties: { collection: { type: 'string', format: 'nsid', }, rkey: { type: 'string', format: 'record-key', }, }, }, createResult: { type: 'object', required: ['uri', 'cid'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, validationStatus: { type: 'string', knownValues: ['valid', 'unknown'], }, }, }, updateResult: { type: 'object', required: ['uri', 'cid'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, validationStatus: { type: 'string', knownValues: ['valid', 'unknown'], }, }, }, deleteResult: { type: 'object', required: [], properties: {}, }, }, }, ComAtprotoRepoCreateRecord: { lexicon: 1, id: 'com.atproto.repo.createRecord', defs: { main: { type: 'procedure', description: 'Create a single new repository record. Requires auth, implemented by PDS.', input: { encoding: 'application/json', schema: { type: 'object', required: ['repo', 'collection', 'record'], properties: { repo: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo (aka, current account).', }, collection: { type: 'string', format: 'nsid', description: 'The NSID of the record collection.', }, rkey: { type: 'string', format: 'record-key', description: 'The Record Key.', maxLength: 512, }, validate: { type: 'boolean', description: "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons.", }, record: { type: 'unknown', description: 'The record itself. Must contain a $type field.', }, swapCommit: { type: 'string', format: 'cid', description: 'Compare and swap with the previous commit by CID.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['uri', 'cid'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, commit: { type: 'ref', ref: 'lex:com.atproto.repo.defs#commitMeta', }, validationStatus: { type: 'string', knownValues: ['valid', 'unknown'], }, }, }, }, errors: [ { name: 'InvalidSwap', description: "Indicates that 'swapCommit' didn't match current repo commit.", }, ], }, }, }, ComAtprotoRepoDefs: { lexicon: 1, id: 'com.atproto.repo.defs', defs: { commitMeta: { type: 'object', required: ['cid', 'rev'], properties: { cid: { type: 'string', format: 'cid', }, rev: { type: 'string', format: 'tid', }, }, }, }, }, ComAtprotoRepoDeleteRecord: { lexicon: 1, id: 'com.atproto.repo.deleteRecord', defs: { main: { type: 'procedure', description: "Delete a repository record, or ensure it doesn't exist. Requires auth, implemented by PDS.", input: { encoding: 'application/json', schema: { type: 'object', required: ['repo', 'collection', 'rkey'], properties: { repo: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo (aka, current account).', }, collection: { type: 'string', format: 'nsid', description: 'The NSID of the record collection.', }, rkey: { type: 'string', format: 'record-key', description: 'The Record Key.', }, swapRecord: { type: 'string', format: 'cid', description: 'Compare and swap with the previous record by CID.', }, swapCommit: { type: 'string', format: 'cid', description: 'Compare and swap with the previous commit by CID.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: { commit: { type: 'ref', ref: 'lex:com.atproto.repo.defs#commitMeta', }, }, }, }, errors: [ { name: 'InvalidSwap', }, ], }, }, }, ComAtprotoRepoDescribeRepo: { lexicon: 1, id: 'com.atproto.repo.describeRepo', defs: { main: { type: 'query', description: 'Get information about an account and repository, including the list of collections. Does not require auth.', parameters: { type: 'params', required: ['repo'], properties: { repo: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: [ 'handle', 'did', 'didDoc', 'collections', 'handleIsCorrect', ], properties: { handle: { type: 'string', format: 'handle', }, did: { type: 'string', format: 'did', }, didDoc: { type: 'unknown', description: 'The complete DID document for this account.', }, collections: { type: 'array', description: 'List of all the collections (NSIDs) for which this repo contains at least one record.', items: { type: 'string', format: 'nsid', }, }, handleIsCorrect: { type: 'boolean', description: 'Indicates if handle is currently valid (resolves bi-directionally)', }, }, }, }, }, }, }, ComAtprotoRepoGetRecord: { lexicon: 1, id: 'com.atproto.repo.getRecord', defs: { main: { type: 'query', description: 'Get a single record from a repository. Does not require auth.', parameters: { type: 'params', required: ['repo', 'collection', 'rkey'], properties: { repo: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo.', }, collection: { type: 'string', format: 'nsid', description: 'The NSID of the record collection.', }, rkey: { type: 'string', description: 'The Record Key.', format: 'record-key', }, cid: { type: 'string', format: 'cid', description: 'The CID of the version of the record. If not specified, then return the most recent version.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['uri', 'value'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, value: { type: 'unknown', }, }, }, }, errors: [ { name: 'RecordNotFound', }, ], }, }, }, ComAtprotoRepoImportRepo: { lexicon: 1, id: 'com.atproto.repo.importRepo', defs: { main: { type: 'procedure', description: 'Import a repo in the form of a CAR file. Requires Content-Length HTTP header to be set.', input: { encoding: 'application/vnd.ipld.car', }, }, }, }, ComAtprotoRepoListMissingBlobs: { lexicon: 1, id: 'com.atproto.repo.listMissingBlobs', defs: { main: { type: 'query', description: 'Returns a list of missing blobs for the requesting account. Intended to be used in the account migration flow.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 1000, default: 500, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['blobs'], properties: { cursor: { type: 'string', }, blobs: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.repo.listMissingBlobs#recordBlob', }, }, }, }, }, }, recordBlob: { type: 'object', required: ['cid', 'recordUri'], properties: { cid: { type: 'string', format: 'cid', }, recordUri: { type: 'string', format: 'at-uri', }, }, }, }, }, ComAtprotoRepoListRecords: { lexicon: 1, id: 'com.atproto.repo.listRecords', defs: { main: { type: 'query', description: 'List a range of records in a repository, matching a specific collection. Does not require auth.', parameters: { type: 'params', required: ['repo', 'collection'], properties: { repo: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo.', }, collection: { type: 'string', format: 'nsid', description: 'The NSID of the record type.', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, description: 'The number of records to return.', }, cursor: { type: 'string', }, reverse: { type: 'boolean', description: 'Flag to reverse the order of the returned records.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['records'], properties: { cursor: { type: 'string', }, records: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.repo.listRecords#record', }, }, }, }, }, }, record: { type: 'object', required: ['uri', 'cid', 'value'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, value: { type: 'unknown', }, }, }, }, }, ComAtprotoRepoPutRecord: { lexicon: 1, id: 'com.atproto.repo.putRecord', defs: { main: { type: 'procedure', description: 'Write a repository record, creating or updating it as needed. Requires auth, implemented by PDS.', input: { encoding: 'application/json', schema: { type: 'object', required: ['repo', 'collection', 'rkey', 'record'], nullable: ['swapRecord'], properties: { repo: { type: 'string', format: 'at-identifier', description: 'The handle or DID of the repo (aka, current account).', }, collection: { type: 'string', format: 'nsid', description: 'The NSID of the record collection.', }, rkey: { type: 'string', format: 'record-key', description: 'The Record Key.', maxLength: 512, }, validate: { type: 'boolean', description: "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons.", }, record: { type: 'unknown', description: 'The record to write.', }, swapRecord: { type: 'string', format: 'cid', description: 'Compare and swap with the previous record by CID. WARNING: nullable and optional field; may cause problems with golang implementation', }, swapCommit: { type: 'string', format: 'cid', description: 'Compare and swap with the previous commit by CID.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['uri', 'cid'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, commit: { type: 'ref', ref: 'lex:com.atproto.repo.defs#commitMeta', }, validationStatus: { type: 'string', knownValues: ['valid', 'unknown'], }, }, }, }, errors: [ { name: 'InvalidSwap', }, ], }, }, }, ComAtprotoRepoStrongRef: { lexicon: 1, id: 'com.atproto.repo.strongRef', description: 'A URI with a content-hash fingerprint.', defs: { main: { type: 'object', required: ['uri', 'cid'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, }, }, }, }, ComAtprotoRepoUploadBlob: { lexicon: 1, id: 'com.atproto.repo.uploadBlob', defs: { main: { type: 'procedure', description: 'Upload a new blob, to be referenced from a repository record. The blob will be deleted if it is not referenced within a time window (eg, minutes). Blob restrictions (mimetype, size, etc) are enforced when the reference is created. Requires auth, implemented by PDS.', input: { encoding: '*/*', }, output: { encoding: 'application/json', schema: { type: 'object', required: ['blob'], properties: { blob: { type: 'blob', }, }, }, }, }, }, }, ComAtprotoServerActivateAccount: { lexicon: 1, id: 'com.atproto.server.activateAccount', defs: { main: { type: 'procedure', description: "Activates a currently deactivated account. Used to finalize account migration after the account's repo is imported and identity is setup.", }, }, }, ComAtprotoServerCheckAccountStatus: { lexicon: 1, id: 'com.atproto.server.checkAccountStatus', defs: { main: { type: 'query', description: 'Returns the status of an account, especially as pertaining to import or recovery. Can be called many times over the course of an account migration. Requires auth and can only be called pertaining to oneself.', output: { encoding: 'application/json', schema: { type: 'object', required: [ 'activated', 'validDid', 'repoCommit', 'repoRev', 'repoBlocks', 'indexedRecords', 'privateStateValues', 'expectedBlobs', 'importedBlobs', ], properties: { activated: { type: 'boolean', }, validDid: { type: 'boolean', }, repoCommit: { type: 'string', format: 'cid', }, repoRev: { type: 'string', }, repoBlocks: { type: 'integer', }, indexedRecords: { type: 'integer', }, privateStateValues: { type: 'integer', }, expectedBlobs: { type: 'integer', }, importedBlobs: { type: 'integer', }, }, }, }, }, }, }, ComAtprotoServerConfirmEmail: { lexicon: 1, id: 'com.atproto.server.confirmEmail', defs: { main: { type: 'procedure', description: 'Confirm an email using a token from com.atproto.server.requestEmailConfirmation.', input: { encoding: 'application/json', schema: { type: 'object', required: ['email', 'token'], properties: { email: { type: 'string', }, token: { type: 'string', }, }, }, }, errors: [ { name: 'AccountNotFound', }, { name: 'ExpiredToken', }, { name: 'InvalidToken', }, { name: 'InvalidEmail', }, ], }, }, }, ComAtprotoServerCreateAccount: { lexicon: 1, id: 'com.atproto.server.createAccount', defs: { main: { type: 'procedure', description: 'Create an account. Implemented by PDS.', input: { encoding: 'application/json', schema: { type: 'object', required: ['handle'], properties: { email: { type: 'string', }, handle: { type: 'string', format: 'handle', description: 'Requested handle for the account.', }, did: { type: 'string', format: 'did', description: 'Pre-existing atproto DID, being imported to a new account.', }, inviteCode: { type: 'string', }, verificationCode: { type: 'string', }, verificationPhone: { type: 'string', }, password: { type: 'string', description: 'Initial account password. May need to meet instance-specific password strength requirements.', }, recoveryKey: { type: 'string', description: 'DID PLC rotation key (aka, recovery key) to be included in PLC creation operation.', }, plcOp: { type: 'unknown', description: 'A signed DID PLC operation to be submitted as part of importing an existing account to this instance. NOTE: this optional field may be updated when full account migration is implemented.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', description: 'Account login session returned on successful account creation.', required: ['accessJwt', 'refreshJwt', 'handle', 'did'], properties: { accessJwt: { type: 'string', }, refreshJwt: { type: 'string', }, handle: { type: 'string', format: 'handle', }, did: { type: 'string', format: 'did', description: 'The DID of the new account.', }, didDoc: { type: 'unknown', description: 'Complete DID document.', }, }, }, }, errors: [ { name: 'InvalidHandle', }, { name: 'InvalidPassword', }, { name: 'InvalidInviteCode', }, { name: 'HandleNotAvailable', }, { name: 'UnsupportedDomain', }, { name: 'UnresolvableDid', }, { name: 'IncompatibleDidDoc', }, ], }, }, }, ComAtprotoServerCreateAppPassword: { lexicon: 1, id: 'com.atproto.server.createAppPassword', defs: { main: { type: 'procedure', description: 'Create an App Password.', input: { encoding: 'application/json', schema: { type: 'object', required: ['name'], properties: { name: { type: 'string', description: 'A short name for the App Password, to help distinguish them.', }, privileged: { type: 'boolean', description: "If an app password has 'privileged' access to possibly sensitive account state. Meant for use with trusted clients.", }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:com.atproto.server.createAppPassword#appPassword', }, }, errors: [ { name: 'AccountTakedown', }, ], }, appPassword: { type: 'object', required: ['name', 'password', 'createdAt'], properties: { name: { type: 'string', }, password: { type: 'string', }, createdAt: { type: 'string', format: 'datetime', }, privileged: { type: 'boolean', }, }, }, }, }, ComAtprotoServerCreateInviteCode: { lexicon: 1, id: 'com.atproto.server.createInviteCode', defs: { main: { type: 'procedure', description: 'Create an invite code.', input: { encoding: 'application/json', schema: { type: 'object', required: ['useCount'], properties: { useCount: { type: 'integer', }, forAccount: { type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['code'], properties: { code: { type: 'string', }, }, }, }, }, }, }, ComAtprotoServerCreateInviteCodes: { lexicon: 1, id: 'com.atproto.server.createInviteCodes', defs: { main: { type: 'procedure', description: 'Create invite codes.', input: { encoding: 'application/json', schema: { type: 'object', required: ['codeCount', 'useCount'], properties: { codeCount: { type: 'integer', default: 1, }, useCount: { type: 'integer', }, forAccounts: { type: 'array', items: { type: 'string', format: 'did', }, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['codes'], properties: { codes: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.server.createInviteCodes#accountCodes', }, }, }, }, }, }, accountCodes: { type: 'object', required: ['account', 'codes'], properties: { account: { type: 'string', }, codes: { type: 'array', items: { type: 'string', }, }, }, }, }, }, ComAtprotoServerCreateSession: { lexicon: 1, id: 'com.atproto.server.createSession', defs: { main: { type: 'procedure', description: 'Create an authentication session.', input: { encoding: 'application/json', schema: { type: 'object', required: ['identifier', 'password'], properties: { identifier: { type: 'string', description: 'Handle or other identifier supported by the server for the authenticating user.', }, password: { type: 'string', }, authFactorToken: { type: 'string', }, allowTakendown: { type: 'boolean', description: 'When true, instead of throwing error for takendown accounts, a valid response with a narrow scoped token will be returned', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['accessJwt', 'refreshJwt', 'handle', 'did'], properties: { accessJwt: { type: 'string', }, refreshJwt: { type: 'string', }, handle: { type: 'string', format: 'handle', }, did: { type: 'string', format: 'did', }, didDoc: { type: 'unknown', }, email: { type: 'string', }, emailConfirmed: { type: 'boolean', }, emailAuthFactor: { type: 'boolean', }, active: { type: 'boolean', }, status: { type: 'string', description: 'If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.', knownValues: ['takendown', 'suspended', 'deactivated'], }, }, }, }, errors: [ { name: 'AccountTakedown', }, { name: 'AuthFactorTokenRequired', }, ], }, }, }, ComAtprotoServerDeactivateAccount: { lexicon: 1, id: 'com.atproto.server.deactivateAccount', defs: { main: { type: 'procedure', description: 'Deactivates a currently active account. Stops serving of repo, and future writes to repo until reactivated. Used to finalize account migration with the old host after the account has been activated on the new host.', input: { encoding: 'application/json', schema: { type: 'object', properties: { deleteAfter: { type: 'string', format: 'datetime', description: 'A recommendation to server as to how long they should hold onto the deactivated account before deleting.', }, }, }, }, }, }, }, ComAtprotoServerDefs: { lexicon: 1, id: 'com.atproto.server.defs', defs: { inviteCode: { type: 'object', required: [ 'code', 'available', 'disabled', 'forAccount', 'createdBy', 'createdAt', 'uses', ], properties: { code: { type: 'string', }, available: { type: 'integer', }, disabled: { type: 'boolean', }, forAccount: { type: 'string', }, createdBy: { type: 'string', }, createdAt: { type: 'string', format: 'datetime', }, uses: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCodeUse', }, }, }, }, inviteCodeUse: { type: 'object', required: ['usedBy', 'usedAt'], properties: { usedBy: { type: 'string', format: 'did', }, usedAt: { type: 'string', format: 'datetime', }, }, }, }, }, ComAtprotoServerDeleteAccount: { lexicon: 1, id: 'com.atproto.server.deleteAccount', defs: { main: { type: 'procedure', description: "Delete an actor's account with a token and password. Can only be called after requesting a deletion token. Requires auth.", input: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'password', 'token'], properties: { did: { type: 'string', format: 'did', }, password: { type: 'string', }, token: { type: 'string', }, }, }, }, errors: [ { name: 'ExpiredToken', }, { name: 'InvalidToken', }, ], }, }, }, ComAtprotoServerDeleteSession: { lexicon: 1, id: 'com.atproto.server.deleteSession', defs: { main: { type: 'procedure', description: "Delete the current session. Requires auth using the 'refreshJwt' (not the 'accessJwt').", errors: [ { name: 'InvalidToken', }, { name: 'ExpiredToken', }, ], }, }, }, ComAtprotoServerDescribeServer: { lexicon: 1, id: 'com.atproto.server.describeServer', defs: { main: { type: 'query', description: "Describes the server's account creation requirements and capabilities. Implemented by PDS.", output: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'availableUserDomains'], properties: { inviteCodeRequired: { type: 'boolean', description: 'If true, an invite code must be supplied to create an account on this instance.', }, phoneVerificationRequired: { type: 'boolean', description: 'If true, a phone verification token must be supplied to create an account on this instance.', }, availableUserDomains: { type: 'array', description: 'List of domain suffixes that can be used in account handles.', items: { type: 'string', }, }, links: { type: 'ref', description: 'URLs of service policy documents.', ref: 'lex:com.atproto.server.describeServer#links', }, contact: { type: 'ref', description: 'Contact information', ref: 'lex:com.atproto.server.describeServer#contact', }, did: { type: 'string', format: 'did', }, }, }, }, }, links: { type: 'object', properties: { privacyPolicy: { type: 'string', format: 'uri', }, termsOfService: { type: 'string', format: 'uri', }, }, }, contact: { type: 'object', properties: { email: { type: 'string', }, }, }, }, }, ComAtprotoServerGetAccountInviteCodes: { lexicon: 1, id: 'com.atproto.server.getAccountInviteCodes', defs: { main: { type: 'query', description: 'Get all invite codes for the current account. Requires auth.', parameters: { type: 'params', properties: { includeUsed: { type: 'boolean', default: true, }, createAvailable: { type: 'boolean', default: true, description: "Controls whether any new 'earned' but not 'created' invites should be created.", }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['codes'], properties: { codes: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCode', }, }, }, }, }, errors: [ { name: 'DuplicateCreate', }, ], }, }, }, ComAtprotoServerGetServiceAuth: { lexicon: 1, id: 'com.atproto.server.getServiceAuth', defs: { main: { type: 'query', description: 'Get a signed token on behalf of the requesting DID for the requested service.', parameters: { type: 'params', required: ['aud'], properties: { aud: { type: 'string', format: 'did', description: 'The DID of the service that the token will be used to authenticate with', }, exp: { type: 'integer', description: 'The time in Unix Epoch seconds that the JWT expires. Defaults to 60 seconds in the future. The service may enforce certain time bounds on tokens depending on the requested scope.', }, lxm: { type: 'string', format: 'nsid', description: 'Lexicon (XRPC) method to bind the requested token to', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['token'], properties: { token: { type: 'string', }, }, }, }, errors: [ { name: 'BadExpiration', description: 'Indicates that the requested expiration date is not a valid. May be in the past or may be reliant on the requested scopes.', }, ], }, }, }, ComAtprotoServerGetSession: { lexicon: 1, id: 'com.atproto.server.getSession', defs: { main: { type: 'query', description: 'Get information about the current auth session. Requires auth.', output: { encoding: 'application/json', schema: { type: 'object', required: ['handle', 'did'], properties: { handle: { type: 'string', format: 'handle', }, did: { type: 'string', format: 'did', }, didDoc: { type: 'unknown', }, email: { type: 'string', }, emailConfirmed: { type: 'boolean', }, emailAuthFactor: { type: 'boolean', }, active: { type: 'boolean', }, status: { type: 'string', description: 'If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.', knownValues: ['takendown', 'suspended', 'deactivated'], }, }, }, }, }, }, }, ComAtprotoServerListAppPasswords: { lexicon: 1, id: 'com.atproto.server.listAppPasswords', defs: { main: { type: 'query', description: 'List all App Passwords.', output: { encoding: 'application/json', schema: { type: 'object', required: ['passwords'], properties: { passwords: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.server.listAppPasswords#appPassword', }, }, }, }, }, errors: [ { name: 'AccountTakedown', }, ], }, appPassword: { type: 'object', required: ['name', 'createdAt'], properties: { name: { type: 'string', }, createdAt: { type: 'string', format: 'datetime', }, privileged: { type: 'boolean', }, }, }, }, }, ComAtprotoServerRefreshSession: { lexicon: 1, id: 'com.atproto.server.refreshSession', defs: { main: { type: 'procedure', description: "Refresh an authentication session. Requires auth using the 'refreshJwt' (not the 'accessJwt').", output: { encoding: 'application/json', schema: { type: 'object', required: ['accessJwt', 'refreshJwt', 'handle', 'did'], properties: { accessJwt: { type: 'string', }, refreshJwt: { type: 'string', }, handle: { type: 'string', format: 'handle', }, did: { type: 'string', format: 'did', }, didDoc: { type: 'unknown', }, email: { type: 'string', }, emailConfirmed: { type: 'boolean', }, emailAuthFactor: { type: 'boolean', }, active: { type: 'boolean', }, status: { type: 'string', description: "Hosting status of the account. If not specified, then assume 'active'.", knownValues: ['takendown', 'suspended', 'deactivated'], }, }, }, }, errors: [ { name: 'AccountTakedown', }, { name: 'InvalidToken', }, { name: 'ExpiredToken', }, ], }, }, }, ComAtprotoServerRequestAccountDelete: { lexicon: 1, id: 'com.atproto.server.requestAccountDelete', defs: { main: { type: 'procedure', description: 'Initiate a user account deletion via email.', }, }, }, ComAtprotoServerRequestEmailConfirmation: { lexicon: 1, id: 'com.atproto.server.requestEmailConfirmation', defs: { main: { type: 'procedure', description: 'Request an email with a code to confirm ownership of email.', }, }, }, ComAtprotoServerRequestEmailUpdate: { lexicon: 1, id: 'com.atproto.server.requestEmailUpdate', defs: { main: { type: 'procedure', description: 'Request a token in order to update email.', output: { encoding: 'application/json', schema: { type: 'object', required: ['tokenRequired'], properties: { tokenRequired: { type: 'boolean', }, }, }, }, }, }, }, ComAtprotoServerRequestPasswordReset: { lexicon: 1, id: 'com.atproto.server.requestPasswordReset', defs: { main: { type: 'procedure', description: 'Initiate a user account password reset via email.', input: { encoding: 'application/json', schema: { type: 'object', required: ['email'], properties: { email: { type: 'string', }, }, }, }, }, }, }, ComAtprotoServerReserveSigningKey: { lexicon: 1, id: 'com.atproto.server.reserveSigningKey', defs: { main: { type: 'procedure', description: 'Reserve a repo signing key, for use with account creation. Necessary so that a DID PLC update operation can be constructed during an account migraiton. Public and does not require auth; implemented by PDS. NOTE: this endpoint may change when full account migration is implemented.', input: { encoding: 'application/json', schema: { type: 'object', properties: { did: { type: 'string', format: 'did', description: 'The DID to reserve a key for.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['signingKey'], properties: { signingKey: { type: 'string', description: 'The public key for the reserved signing key, in did:key serialization.', }, }, }, }, }, }, }, ComAtprotoServerResetPassword: { lexicon: 1, id: 'com.atproto.server.resetPassword', defs: { main: { type: 'procedure', description: 'Reset a user account password using a token.', input: { encoding: 'application/json', schema: { type: 'object', required: ['token', 'password'], properties: { token: { type: 'string', }, password: { type: 'string', }, }, }, }, errors: [ { name: 'ExpiredToken', }, { name: 'InvalidToken', }, ], }, }, }, ComAtprotoServerRevokeAppPassword: { lexicon: 1, id: 'com.atproto.server.revokeAppPassword', defs: { main: { type: 'procedure', description: 'Revoke an App Password by name.', input: { encoding: 'application/json', schema: { type: 'object', required: ['name'], properties: { name: { type: 'string', }, }, }, }, }, }, }, ComAtprotoServerUpdateEmail: { lexicon: 1, id: 'com.atproto.server.updateEmail', defs: { main: { type: 'procedure', description: "Update an account's email.", input: { encoding: 'application/json', schema: { type: 'object', required: ['email'], properties: { email: { type: 'string', }, emailAuthFactor: { type: 'boolean', }, token: { type: 'string', description: "Requires a token from com.atproto.sever.requestEmailUpdate if the account's email has been confirmed.", }, }, }, }, errors: [ { name: 'ExpiredToken', }, { name: 'InvalidToken', }, { name: 'TokenRequired', }, ], }, }, }, ComAtprotoSyncDefs: { lexicon: 1, id: 'com.atproto.sync.defs', defs: { hostStatus: { type: 'string', knownValues: ['active', 'idle', 'offline', 'throttled', 'banned'], }, }, }, ComAtprotoSyncGetBlob: { lexicon: 1, id: 'com.atproto.sync.getBlob', defs: { main: { type: 'query', description: 'Get a blob associated with a given account. Returns the full blob as originally uploaded. Does not require auth; implemented by PDS.', parameters: { type: 'params', required: ['did', 'cid'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the account.', }, cid: { type: 'string', format: 'cid', description: 'The CID of the blob to fetch', }, }, }, output: { encoding: '*/*', }, errors: [ { name: 'BlobNotFound', }, { name: 'RepoNotFound', }, { name: 'RepoTakendown', }, { name: 'RepoSuspended', }, { name: 'RepoDeactivated', }, ], }, }, }, ComAtprotoSyncGetBlocks: { lexicon: 1, id: 'com.atproto.sync.getBlocks', defs: { main: { type: 'query', description: 'Get data blocks from a given repo, by CID. For example, intermediate MST nodes, or records. Does not require auth; implemented by PDS.', parameters: { type: 'params', required: ['did', 'cids'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, cids: { type: 'array', items: { type: 'string', format: 'cid', }, }, }, }, output: { encoding: 'application/vnd.ipld.car', }, errors: [ { name: 'BlockNotFound', }, { name: 'RepoNotFound', }, { name: 'RepoTakendown', }, { name: 'RepoSuspended', }, { name: 'RepoDeactivated', }, ], }, }, }, ComAtprotoSyncGetCheckout: { lexicon: 1, id: 'com.atproto.sync.getCheckout', defs: { main: { type: 'query', description: 'DEPRECATED - please use com.atproto.sync.getRepo instead', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, }, }, output: { encoding: 'application/vnd.ipld.car', }, }, }, }, ComAtprotoSyncGetHead: { lexicon: 1, id: 'com.atproto.sync.getHead', defs: { main: { type: 'query', description: 'DEPRECATED - please use com.atproto.sync.getLatestCommit instead', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['root'], properties: { root: { type: 'string', format: 'cid', }, }, }, }, errors: [ { name: 'HeadNotFound', }, ], }, }, }, ComAtprotoSyncGetHostStatus: { lexicon: 1, id: 'com.atproto.sync.getHostStatus', defs: { main: { type: 'query', description: 'Returns information about a specified upstream host, as consumed by the server. Implemented by relays.', parameters: { type: 'params', required: ['hostname'], properties: { hostname: { type: 'string', description: 'Hostname of the host (eg, PDS or relay) being queried.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['hostname'], properties: { hostname: { type: 'string', }, seq: { type: 'integer', description: 'Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor).', }, accountCount: { type: 'integer', description: 'Number of accounts on the server which are associated with the upstream host. Note that the upstream may actually have more accounts.', }, status: { type: 'ref', ref: 'lex:com.atproto.sync.defs#hostStatus', }, }, }, }, errors: [ { name: 'HostNotFound', }, ], }, }, }, ComAtprotoSyncGetLatestCommit: { lexicon: 1, id: 'com.atproto.sync.getLatestCommit', defs: { main: { type: 'query', description: 'Get the current commit CID & revision of the specified repo. Does not require auth.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['cid', 'rev'], properties: { cid: { type: 'string', format: 'cid', }, rev: { type: 'string', format: 'tid', }, }, }, }, errors: [ { name: 'RepoNotFound', }, { name: 'RepoTakendown', }, { name: 'RepoSuspended', }, { name: 'RepoDeactivated', }, ], }, }, }, ComAtprotoSyncGetRecord: { lexicon: 1, id: 'com.atproto.sync.getRecord', defs: { main: { type: 'query', description: 'Get data blocks needed to prove the existence or non-existence of record in the current version of repo. Does not require auth.', parameters: { type: 'params', required: ['did', 'collection', 'rkey'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, collection: { type: 'string', format: 'nsid', }, rkey: { type: 'string', description: 'Record Key', format: 'record-key', }, }, }, output: { encoding: 'application/vnd.ipld.car', }, errors: [ { name: 'RecordNotFound', }, { name: 'RepoNotFound', }, { name: 'RepoTakendown', }, { name: 'RepoSuspended', }, { name: 'RepoDeactivated', }, ], }, }, }, ComAtprotoSyncGetRepo: { lexicon: 1, id: 'com.atproto.sync.getRepo', defs: { main: { type: 'query', description: "Download a repository export as CAR file. Optionally only a 'diff' since a previous revision. Does not require auth; implemented by PDS.", parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, since: { type: 'string', format: 'tid', description: "The revision ('rev') of the repo to create a diff from.", }, }, }, output: { encoding: 'application/vnd.ipld.car', }, errors: [ { name: 'RepoNotFound', }, { name: 'RepoTakendown', }, { name: 'RepoSuspended', }, { name: 'RepoDeactivated', }, ], }, }, }, ComAtprotoSyncGetRepoStatus: { lexicon: 1, id: 'com.atproto.sync.getRepoStatus', defs: { main: { type: 'query', description: 'Get the hosting status for a repository, on this server. Expected to be implemented by PDS and Relay.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'active'], properties: { did: { type: 'string', format: 'did', }, active: { type: 'boolean', }, status: { type: 'string', description: 'If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.', knownValues: [ 'takendown', 'suspended', 'deleted', 'deactivated', 'desynchronized', 'throttled', ], }, rev: { type: 'string', format: 'tid', description: 'Optional field, the current rev of the repo, if active=true', }, }, }, }, errors: [ { name: 'RepoNotFound', }, ], }, }, }, ComAtprotoSyncListBlobs: { lexicon: 1, id: 'com.atproto.sync.listBlobs', defs: { main: { type: 'query', description: 'List blob CIDs for an account, since some repo revision. Does not require auth; implemented by PDS.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', description: 'The DID of the repo.', }, since: { type: 'string', format: 'tid', description: 'Optional revision of the repo to list blobs since.', }, limit: { type: 'integer', minimum: 1, maximum: 1000, default: 500, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['cids'], properties: { cursor: { type: 'string', }, cids: { type: 'array', items: { type: 'string', format: 'cid', }, }, }, }, }, errors: [ { name: 'RepoNotFound', }, { name: 'RepoTakendown', }, { name: 'RepoSuspended', }, { name: 'RepoDeactivated', }, ], }, }, }, ComAtprotoSyncListHosts: { lexicon: 1, id: 'com.atproto.sync.listHosts', defs: { main: { type: 'query', description: 'Enumerates upstream hosts (eg, PDS or relay instances) that this service consumes from. Implemented by relays.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 1000, default: 200, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['hosts'], properties: { cursor: { type: 'string', }, hosts: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.sync.listHosts#host', }, description: 'Sort order is not formally specified. Recommended order is by time host was first seen by the server, with oldest first.', }, }, }, }, }, host: { type: 'object', required: ['hostname'], properties: { hostname: { type: 'string', description: 'hostname of server; not a URL (no scheme)', }, seq: { type: 'integer', description: 'Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor).', }, accountCount: { type: 'integer', }, status: { type: 'ref', ref: 'lex:com.atproto.sync.defs#hostStatus', }, }, }, }, }, ComAtprotoSyncListRepos: { lexicon: 1, id: 'com.atproto.sync.listRepos', defs: { main: { type: 'query', description: 'Enumerates all the DID, rev, and commit CID for all repos hosted by this service. Does not require auth; implemented by PDS and Relay.', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 1000, default: 500, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['repos'], properties: { cursor: { type: 'string', }, repos: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.sync.listRepos#repo', }, }, }, }, }, }, repo: { type: 'object', required: ['did', 'head', 'rev'], properties: { did: { type: 'string', format: 'did', }, head: { type: 'string', format: 'cid', description: 'Current repo commit CID', }, rev: { type: 'string', format: 'tid', }, active: { type: 'boolean', }, status: { type: 'string', description: 'If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.', knownValues: [ 'takendown', 'suspended', 'deleted', 'deactivated', 'desynchronized', 'throttled', ], }, }, }, }, }, ComAtprotoSyncListReposByCollection: { lexicon: 1, id: 'com.atproto.sync.listReposByCollection', defs: { main: { type: 'query', description: 'Enumerates all the DIDs which have records with the given collection NSID.', parameters: { type: 'params', required: ['collection'], properties: { collection: { type: 'string', format: 'nsid', }, limit: { type: 'integer', description: 'Maximum size of response set. Recommend setting a large maximum (1000+) when enumerating large DID lists.', minimum: 1, maximum: 2000, default: 500, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['repos'], properties: { cursor: { type: 'string', }, repos: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.sync.listReposByCollection#repo', }, }, }, }, }, }, repo: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, }, }, ComAtprotoSyncNotifyOfUpdate: { lexicon: 1, id: 'com.atproto.sync.notifyOfUpdate', defs: { main: { type: 'procedure', description: 'Notify a crawling service of a recent update, and that crawling should resume. Intended use is after a gap between repo stream events caused the crawling service to disconnect. Does not require auth; implemented by Relay. DEPRECATED: just use com.atproto.sync.requestCrawl', input: { encoding: 'application/json', schema: { type: 'object', required: ['hostname'], properties: { hostname: { type: 'string', description: 'Hostname of the current service (usually a PDS) that is notifying of update.', }, }, }, }, }, }, }, ComAtprotoSyncRequestCrawl: { lexicon: 1, id: 'com.atproto.sync.requestCrawl', defs: { main: { type: 'procedure', description: 'Request a service to persistently crawl hosted repos. Expected use is new PDS instances declaring their existence to Relays. Does not require auth.', input: { encoding: 'application/json', schema: { type: 'object', required: ['hostname'], properties: { hostname: { type: 'string', description: 'Hostname of the current service (eg, PDS) that is requesting to be crawled.', }, }, }, }, errors: [ { name: 'HostBanned', }, ], }, }, }, ComAtprotoSyncSubscribeRepos: { lexicon: 1, id: 'com.atproto.sync.subscribeRepos', defs: { main: { type: 'subscription', description: 'Repository event stream, aka Firehose endpoint. Outputs repo commits with diff data, and identity update events, for all repositories on the current server. See the atproto specifications for details around stream sequencing, repo versioning, CAR diff format, and more. Public and does not require auth; implemented by PDS and Relay.', parameters: { type: 'params', properties: { cursor: { type: 'integer', description: 'The last known event seq number to backfill from.', }, }, }, message: { schema: { type: 'union', refs: [ 'lex:com.atproto.sync.subscribeRepos#commit', 'lex:com.atproto.sync.subscribeRepos#sync', 'lex:com.atproto.sync.subscribeRepos#identity', 'lex:com.atproto.sync.subscribeRepos#account', 'lex:com.atproto.sync.subscribeRepos#info', ], }, }, errors: [ { name: 'FutureCursor', }, { name: 'ConsumerTooSlow', description: 'If the consumer of the stream can not keep up with events, and a backlog gets too large, the server will drop the connection.', }, ], }, commit: { type: 'object', description: 'Represents an update of repository state. Note that empty commits are allowed, which include no repo data changes, but an update to rev and signature.', required: [ 'seq', 'rebase', 'tooBig', 'repo', 'commit', 'rev', 'since', 'blocks', 'ops', 'blobs', 'time', ], nullable: ['since'], properties: { seq: { type: 'integer', description: 'The stream sequence number of this message.', }, rebase: { type: 'boolean', description: 'DEPRECATED -- unused', }, tooBig: { type: 'boolean', description: 'DEPRECATED -- replaced by #sync event and data limits. Indicates that this commit contained too many ops, or data size was too large. Consumers will need to make a separate request to get missing data.', }, repo: { type: 'string', format: 'did', description: "The repo this event comes from. Note that all other message types name this field 'did'.", }, commit: { type: 'cid-link', description: 'Repo commit object CID.', }, rev: { type: 'string', format: 'tid', description: 'The rev of the emitted commit. Note that this information is also in the commit object included in blocks, unless this is a tooBig event.', }, since: { type: 'string', format: 'tid', description: 'The rev of the last emitted commit from this repo (if any).', }, blocks: { type: 'bytes', description: "CAR file containing relevant blocks, as a diff since the previous repo state. The commit must be included as a block, and the commit block CID must be the first entry in the CAR header 'roots' list.", maxLength: 2000000, }, ops: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.sync.subscribeRepos#repoOp', description: 'List of repo mutation operations in this commit (eg, records created, updated, or deleted).', }, maxLength: 200, }, blobs: { type: 'array', items: { type: 'cid-link', description: 'DEPRECATED -- will soon always be empty. List of new blobs (by CID) referenced by records in this commit.', }, }, prevData: { type: 'cid-link', description: "The root CID of the MST tree for the previous commit from this repo (indicated by the 'since' revision field in this message). Corresponds to the 'data' field in the repo commit object. NOTE: this field is effectively required for the 'inductive' version of firehose.", }, time: { type: 'string', format: 'datetime', description: 'Timestamp of when this message was originally broadcast.', }, }, }, sync: { type: 'object', description: 'Updates the repo to a new state, without necessarily including that state on the firehose. Used to recover from broken commit streams, data loss incidents, or in situations where upstream host does not know recent state of the repository.', required: ['seq', 'did', 'blocks', 'rev', 'time'], properties: { seq: { type: 'integer', description: 'The stream sequence number of this message.', }, did: { type: 'string', format: 'did', description: 'The account this repo event corresponds to. Must match that in the commit object.', }, blocks: { type: 'bytes', description: "CAR file containing the commit, as a block. The CAR header must include the commit block CID as the first 'root'.", maxLength: 10000, }, rev: { type: 'string', description: 'The rev of the commit. This value must match that in the commit object.', }, time: { type: 'string', format: 'datetime', description: 'Timestamp of when this message was originally broadcast.', }, }, }, identity: { type: 'object', description: "Represents a change to an account's identity. Could be an updated handle, signing key, or pds hosting endpoint. Serves as a prod to all downstream services to refresh their identity cache.", required: ['seq', 'did', 'time'], properties: { seq: { type: 'integer', }, did: { type: 'string', format: 'did', }, time: { type: 'string', format: 'datetime', }, handle: { type: 'string', format: 'handle', description: "The current handle for the account, or 'handle.invalid' if validation fails. This field is optional, might have been validated or passed-through from an upstream source. Semantics and behaviors for PDS vs Relay may evolve in the future; see atproto specs for more details.", }, }, }, account: { type: 'object', description: "Represents a change to an account's status on a host (eg, PDS or Relay). The semantics of this event are that the status is at the host which emitted the event, not necessarily that at the currently active PDS. Eg, a Relay takedown would emit a takedown with active=false, even if the PDS is still active.", required: ['seq', 'did', 'time', 'active'], properties: { seq: { type: 'integer', }, did: { type: 'string', format: 'did', }, time: { type: 'string', format: 'datetime', }, active: { type: 'boolean', description: 'Indicates that the account has a repository which can be fetched from the host that emitted this event.', }, status: { type: 'string', description: 'If active=false, this optional field indicates a reason for why the account is not active.', knownValues: [ 'takendown', 'suspended', 'deleted', 'deactivated', 'desynchronized', 'throttled', ], }, }, }, info: { type: 'object', required: ['name'], properties: { name: { type: 'string', knownValues: ['OutdatedCursor'], }, message: { type: 'string', }, }, }, repoOp: { type: 'object', description: 'A repo operation, ie a mutation of a single record.', required: ['action', 'path', 'cid'], nullable: ['cid'], properties: { action: { type: 'string', knownValues: ['create', 'update', 'delete'], }, path: { type: 'string', }, cid: { type: 'cid-link', description: 'For creates and updates, the new record CID. For deletions, null.', }, prev: { type: 'cid-link', description: 'For updates and deletes, the previous record CID (required for inductive firehose). For creations, field should not be defined.', }, }, }, }, }, ComAtprotoTempAddReservedHandle: { lexicon: 1, id: 'com.atproto.temp.addReservedHandle', defs: { main: { type: 'procedure', description: 'Add a handle to the set of reserved handles.', input: { encoding: 'application/json', schema: { type: 'object', required: ['handle'], properties: { handle: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, }, }, }, ComAtprotoTempCheckHandleAvailability: { lexicon: 1, id: 'com.atproto.temp.checkHandleAvailability', defs: { main: { type: 'query', description: 'Checks whether the provided handle is available. If the handle is not available, available suggestions will be returned. Optional inputs will be used to generate suggestions.', parameters: { type: 'params', required: ['handle'], properties: { handle: { type: 'string', format: 'handle', description: 'Tentative handle. Will be checked for availability or used to build handle suggestions.', }, email: { type: 'string', description: 'User-provided email. Might be used to build handle suggestions.', }, birthDate: { type: 'string', format: 'datetime', description: 'User-provided birth date. Might be used to build handle suggestions.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['handle', 'result'], properties: { handle: { type: 'string', format: 'handle', description: 'Echo of the input handle.', }, result: { type: 'union', refs: [ 'lex:com.atproto.temp.checkHandleAvailability#resultAvailable', 'lex:com.atproto.temp.checkHandleAvailability#resultUnavailable', ], }, }, }, }, errors: [ { name: 'InvalidEmail', description: 'An invalid email was provided.', }, ], }, resultAvailable: { type: 'object', description: 'Indicates the provided handle is available.', properties: {}, }, resultUnavailable: { type: 'object', description: 'Indicates the provided handle is unavailable and gives suggestions of available handles.', required: ['suggestions'], properties: { suggestions: { type: 'array', description: 'List of suggested handles based on the provided inputs.', items: { type: 'ref', ref: 'lex:com.atproto.temp.checkHandleAvailability#suggestion', }, }, }, }, suggestion: { type: 'object', required: ['handle', 'method'], properties: { handle: { type: 'string', format: 'handle', }, method: { type: 'string', description: 'Method used to build this suggestion. Should be considered opaque to clients. Can be used for metrics.', }, }, }, }, }, ComAtprotoTempCheckSignupQueue: { lexicon: 1, id: 'com.atproto.temp.checkSignupQueue', defs: { main: { type: 'query', description: 'Check accounts location in signup queue.', output: { encoding: 'application/json', schema: { type: 'object', required: ['activated'], properties: { activated: { type: 'boolean', }, placeInQueue: { type: 'integer', }, estimatedTimeMs: { type: 'integer', }, }, }, }, }, }, }, ComAtprotoTempDereferenceScope: { lexicon: 1, id: 'com.atproto.temp.dereferenceScope', defs: { main: { type: 'query', description: 'Allows finding the oauth permission scope from a reference', parameters: { type: 'params', required: ['scope'], properties: { scope: { type: 'string', description: "The scope reference (starts with 'ref:')", }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['scope'], properties: { scope: { type: 'string', description: 'The full oauth permission scope', }, }, }, }, errors: [ { name: 'InvalidScopeReference', description: 'An invalid scope reference was provided.', }, ], }, }, }, ComAtprotoTempFetchLabels: { lexicon: 1, id: 'com.atproto.temp.fetchLabels', defs: { main: { type: 'query', description: 'DEPRECATED: use queryLabels or subscribeLabels instead -- Fetch all labels from a labeler created after a certain date.', parameters: { type: 'params', properties: { since: { type: 'integer', }, limit: { type: 'integer', minimum: 1, maximum: 250, default: 50, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['labels'], properties: { labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, }, }, }, }, }, }, ComAtprotoTempRequestPhoneVerification: { lexicon: 1, id: 'com.atproto.temp.requestPhoneVerification', defs: { main: { type: 'procedure', description: 'Request a verification code to be sent to the supplied phone number', input: { encoding: 'application/json', schema: { type: 'object', required: ['phoneNumber'], properties: { phoneNumber: { type: 'string', }, }, }, }, }, }, }, ComAtprotoTempRevokeAccountCredentials: { lexicon: 1, id: 'com.atproto.temp.revokeAccountCredentials', defs: { main: { type: 'procedure', description: 'Revoke sessions, password, and app passwords associated with account. May be resolved by a password reset.', input: { encoding: 'application/json', schema: { type: 'object', required: ['account'], properties: { account: { type: 'string', format: 'at-identifier', }, }, }, }, }, }, }, ComGermnetworkDeclaration: { lexicon: 1, id: 'com.germnetwork.declaration', defs: { main: { type: 'record', description: 'A declaration of a Germ Network account', key: 'literal:self', record: { type: 'object', required: ['version', 'currentKey'], properties: { version: { type: 'string', description: 'Semver version number, without pre-release or build information, for the format of opaque content', minLength: 5, maxLength: 14, }, currentKey: { type: 'bytes', description: 'Opaque value, an ed25519 public key prefixed with a byte enum', }, messageMe: { type: 'ref', description: 'Controls who can message this account', ref: 'lex:com.germnetwork.declaration#messageMe', }, keyPackage: { type: 'bytes', description: 'Opaque value, contains MLS KeyPackage(s), and other signature data, and is signed by the currentKey', }, continuityProofs: { type: 'array', description: 'Array of opaque values to allow for key rolling', items: { type: 'bytes', }, maxLength: 1000, }, }, }, }, messageMe: { type: 'object', required: ['showButtonTo', 'messageMeUrl'], properties: { messageMeUrl: { type: 'string', description: 'A URL to present to an account that does not have its own com.germnetwork.declaration record, must have an empty fragment component, where the app should fill in the fragment component with the DIDs of the two accounts who wish to message each other', format: 'uri', minLength: 1, maxLength: 2047, }, showButtonTo: { type: 'string', knownValues: ['none', 'usersIFollow', 'everyone'], description: "The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer.", minLength: 1, maxLength: 100, }, }, }, }, }, ToolsOzoneCommunicationCreateTemplate: { lexicon: 1, id: 'tools.ozone.communication.createTemplate', defs: { main: { type: 'procedure', description: 'Administrative action to create a new, re-usable communication (email for now) template.', input: { encoding: 'application/json', schema: { type: 'object', required: ['subject', 'contentMarkdown', 'name'], properties: { name: { type: 'string', description: 'Name of the template.', }, contentMarkdown: { type: 'string', description: 'Content of the template, markdown supported, can contain variable placeholders.', }, subject: { type: 'string', description: 'Subject of the message, used in emails.', }, lang: { type: 'string', format: 'language', description: 'Message language.', }, createdBy: { type: 'string', format: 'did', description: 'DID of the user who is creating the template.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.communication.defs#templateView', }, }, errors: [ { name: 'DuplicateTemplateName', }, ], }, }, }, ToolsOzoneCommunicationDefs: { lexicon: 1, id: 'tools.ozone.communication.defs', defs: { templateView: { type: 'object', required: [ 'id', 'name', 'contentMarkdown', 'disabled', 'lastUpdatedBy', 'createdAt', 'updatedAt', ], properties: { id: { type: 'string', }, name: { type: 'string', description: 'Name of the template.', }, subject: { type: 'string', description: 'Content of the template, can contain markdown and variable placeholders.', }, contentMarkdown: { type: 'string', description: 'Subject of the message, used in emails.', }, disabled: { type: 'boolean', }, lang: { type: 'string', format: 'language', description: 'Message language.', }, lastUpdatedBy: { type: 'string', format: 'did', description: 'DID of the user who last updated the template.', }, createdAt: { type: 'string', format: 'datetime', }, updatedAt: { type: 'string', format: 'datetime', }, }, }, }, }, ToolsOzoneCommunicationDeleteTemplate: { lexicon: 1, id: 'tools.ozone.communication.deleteTemplate', defs: { main: { type: 'procedure', description: 'Delete a communication template.', input: { encoding: 'application/json', schema: { type: 'object', required: ['id'], properties: { id: { type: 'string', }, }, }, }, }, }, }, ToolsOzoneCommunicationListTemplates: { lexicon: 1, id: 'tools.ozone.communication.listTemplates', defs: { main: { type: 'query', description: 'Get list of all communication templates.', output: { encoding: 'application/json', schema: { type: 'object', required: ['communicationTemplates'], properties: { communicationTemplates: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.communication.defs#templateView', }, }, }, }, }, }, }, }, ToolsOzoneCommunicationUpdateTemplate: { lexicon: 1, id: 'tools.ozone.communication.updateTemplate', defs: { main: { type: 'procedure', description: 'Administrative action to update an existing communication template. Allows passing partial fields to patch specific fields only.', input: { encoding: 'application/json', schema: { type: 'object', required: ['id'], properties: { id: { type: 'string', description: 'ID of the template to be updated.', }, name: { type: 'string', description: 'Name of the template.', }, lang: { type: 'string', format: 'language', description: 'Message language.', }, contentMarkdown: { type: 'string', description: 'Content of the template, markdown supported, can contain variable placeholders.', }, subject: { type: 'string', description: 'Subject of the message, used in emails.', }, updatedBy: { type: 'string', format: 'did', description: 'DID of the user who is updating the template.', }, disabled: { type: 'boolean', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.communication.defs#templateView', }, }, errors: [ { name: 'DuplicateTemplateName', }, ], }, }, }, ToolsOzoneHostingGetAccountHistory: { lexicon: 1, id: 'tools.ozone.hosting.getAccountHistory', defs: { main: { type: 'query', description: 'Get account history, e.g. log of updated email addresses or other identity information.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', }, events: { type: 'array', items: { type: 'string', knownValues: [ 'accountCreated', 'emailUpdated', 'emailConfirmed', 'passwordUpdated', 'handleUpdated', ], }, }, cursor: { type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['events'], properties: { cursor: { type: 'string', }, events: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.hosting.getAccountHistory#event', }, }, }, }, }, }, event: { type: 'object', required: ['details', 'createdBy', 'createdAt'], properties: { details: { type: 'union', refs: [ 'lex:tools.ozone.hosting.getAccountHistory#accountCreated', 'lex:tools.ozone.hosting.getAccountHistory#emailUpdated', 'lex:tools.ozone.hosting.getAccountHistory#emailConfirmed', 'lex:tools.ozone.hosting.getAccountHistory#passwordUpdated', 'lex:tools.ozone.hosting.getAccountHistory#handleUpdated', ], }, createdBy: { type: 'string', }, createdAt: { type: 'string', format: 'datetime', }, }, }, accountCreated: { type: 'object', required: [], properties: { email: { type: 'string', }, handle: { type: 'string', format: 'handle', }, }, }, emailUpdated: { type: 'object', required: ['email'], properties: { email: { type: 'string', }, }, }, emailConfirmed: { type: 'object', required: ['email'], properties: { email: { type: 'string', }, }, }, passwordUpdated: { type: 'object', required: [], properties: {}, }, handleUpdated: { type: 'object', required: ['handle'], properties: { handle: { type: 'string', format: 'handle', }, }, }, }, }, ToolsOzoneModerationCancelScheduledActions: { lexicon: 1, id: 'tools.ozone.moderation.cancelScheduledActions', defs: { main: { type: 'procedure', description: 'Cancel all pending scheduled moderation actions for specified subjects', input: { encoding: 'application/json', schema: { type: 'object', required: ['subjects'], properties: { subjects: { type: 'array', maxLength: 100, items: { type: 'string', format: 'did', }, description: 'Array of DID subjects to cancel scheduled actions for', }, comment: { type: 'string', description: 'Optional comment describing the reason for cancellation', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.moderation.cancelScheduledActions#cancellationResults', }, }, }, cancellationResults: { type: 'object', required: ['succeeded', 'failed'], properties: { succeeded: { type: 'array', items: { type: 'string', format: 'did', }, description: 'DIDs for which all pending scheduled actions were successfully cancelled', }, failed: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.cancelScheduledActions#failedCancellation', }, description: 'DIDs for which cancellation failed with error details', }, }, }, failedCancellation: { type: 'object', required: ['did', 'error'], properties: { did: { type: 'string', format: 'did', }, error: { type: 'string', }, errorCode: { type: 'string', }, }, }, }, }, ToolsOzoneModerationDefs: { lexicon: 1, id: 'tools.ozone.moderation.defs', defs: { modEventView: { type: 'object', required: [ 'id', 'event', 'subject', 'subjectBlobCids', 'createdBy', 'createdAt', ], properties: { id: { type: 'integer', }, event: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#modEventTakedown', 'lex:tools.ozone.moderation.defs#modEventReverseTakedown', 'lex:tools.ozone.moderation.defs#modEventComment', 'lex:tools.ozone.moderation.defs#modEventReport', 'lex:tools.ozone.moderation.defs#modEventLabel', 'lex:tools.ozone.moderation.defs#modEventAcknowledge', 'lex:tools.ozone.moderation.defs#modEventEscalate', 'lex:tools.ozone.moderation.defs#modEventMute', 'lex:tools.ozone.moderation.defs#modEventUnmute', 'lex:tools.ozone.moderation.defs#modEventMuteReporter', 'lex:tools.ozone.moderation.defs#modEventUnmuteReporter', 'lex:tools.ozone.moderation.defs#modEventEmail', 'lex:tools.ozone.moderation.defs#modEventResolveAppeal', 'lex:tools.ozone.moderation.defs#modEventDivert', 'lex:tools.ozone.moderation.defs#modEventTag', 'lex:tools.ozone.moderation.defs#accountEvent', 'lex:tools.ozone.moderation.defs#identityEvent', 'lex:tools.ozone.moderation.defs#recordEvent', 'lex:tools.ozone.moderation.defs#modEventPriorityScore', 'lex:tools.ozone.moderation.defs#ageAssuranceEvent', 'lex:tools.ozone.moderation.defs#ageAssuranceOverrideEvent', 'lex:tools.ozone.moderation.defs#ageAssurancePurgeEvent', 'lex:tools.ozone.moderation.defs#revokeAccountCredentialsEvent', 'lex:tools.ozone.moderation.defs#scheduleTakedownEvent', 'lex:tools.ozone.moderation.defs#cancelScheduledTakedownEvent', ], }, subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', 'lex:chat.bsky.convo.defs#messageRef', ], }, subjectBlobCids: { type: 'array', items: { type: 'string', }, }, createdBy: { type: 'string', format: 'did', }, createdAt: { type: 'string', format: 'datetime', }, creatorHandle: { type: 'string', }, subjectHandle: { type: 'string', }, modTool: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#modTool', }, }, }, modEventViewDetail: { type: 'object', required: [ 'id', 'event', 'subject', 'subjectBlobs', 'createdBy', 'createdAt', ], properties: { id: { type: 'integer', }, event: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#modEventTakedown', 'lex:tools.ozone.moderation.defs#modEventReverseTakedown', 'lex:tools.ozone.moderation.defs#modEventComment', 'lex:tools.ozone.moderation.defs#modEventReport', 'lex:tools.ozone.moderation.defs#modEventLabel', 'lex:tools.ozone.moderation.defs#modEventAcknowledge', 'lex:tools.ozone.moderation.defs#modEventEscalate', 'lex:tools.ozone.moderation.defs#modEventMute', 'lex:tools.ozone.moderation.defs#modEventUnmute', 'lex:tools.ozone.moderation.defs#modEventMuteReporter', 'lex:tools.ozone.moderation.defs#modEventUnmuteReporter', 'lex:tools.ozone.moderation.defs#modEventEmail', 'lex:tools.ozone.moderation.defs#modEventResolveAppeal', 'lex:tools.ozone.moderation.defs#modEventDivert', 'lex:tools.ozone.moderation.defs#modEventTag', 'lex:tools.ozone.moderation.defs#accountEvent', 'lex:tools.ozone.moderation.defs#identityEvent', 'lex:tools.ozone.moderation.defs#recordEvent', 'lex:tools.ozone.moderation.defs#modEventPriorityScore', 'lex:tools.ozone.moderation.defs#ageAssuranceEvent', 'lex:tools.ozone.moderation.defs#ageAssuranceOverrideEvent', 'lex:tools.ozone.moderation.defs#ageAssurancePurgeEvent', 'lex:tools.ozone.moderation.defs#revokeAccountCredentialsEvent', 'lex:tools.ozone.moderation.defs#scheduleTakedownEvent', 'lex:tools.ozone.moderation.defs#cancelScheduledTakedownEvent', ], }, subject: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#repoView', 'lex:tools.ozone.moderation.defs#repoViewNotFound', 'lex:tools.ozone.moderation.defs#recordView', 'lex:tools.ozone.moderation.defs#recordViewNotFound', ], }, subjectBlobs: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#blobView', }, }, createdBy: { type: 'string', format: 'did', }, createdAt: { type: 'string', format: 'datetime', }, modTool: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#modTool', }, }, }, subjectStatusView: { type: 'object', required: ['id', 'subject', 'createdAt', 'updatedAt', 'reviewState'], properties: { id: { type: 'integer', }, subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', 'lex:chat.bsky.convo.defs#messageRef', ], }, hosting: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#accountHosting', 'lex:tools.ozone.moderation.defs#recordHosting', ], }, subjectBlobCids: { type: 'array', items: { type: 'string', format: 'cid', }, }, subjectRepoHandle: { type: 'string', }, updatedAt: { type: 'string', format: 'datetime', description: 'Timestamp referencing when the last update was made to the moderation status of the subject', }, createdAt: { type: 'string', format: 'datetime', description: 'Timestamp referencing the first moderation status impacting event was emitted on the subject', }, reviewState: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#subjectReviewState', }, comment: { type: 'string', description: 'Sticky comment on the subject.', }, priorityScore: { type: 'integer', description: 'Numeric value representing the level of priority. Higher score means higher priority.', minimum: 0, maximum: 100, }, muteUntil: { type: 'string', format: 'datetime', }, muteReportingUntil: { type: 'string', format: 'datetime', }, lastReviewedBy: { type: 'string', format: 'did', }, lastReviewedAt: { type: 'string', format: 'datetime', }, lastReportedAt: { type: 'string', format: 'datetime', }, lastAppealedAt: { type: 'string', format: 'datetime', description: 'Timestamp referencing when the author of the subject appealed a moderation action', }, takendown: { type: 'boolean', }, appealed: { type: 'boolean', description: 'True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators.', }, suspendUntil: { type: 'string', format: 'datetime', }, tags: { type: 'array', items: { type: 'string', }, }, accountStats: { description: 'Statistics related to the account subject', type: 'ref', ref: 'lex:tools.ozone.moderation.defs#accountStats', }, recordsStats: { description: "Statistics related to the record subjects authored by the subject's account", type: 'ref', ref: 'lex:tools.ozone.moderation.defs#recordsStats', }, accountStrike: { description: 'Strike information for the account (account-level only)', type: 'ref', ref: 'lex:tools.ozone.moderation.defs#accountStrike', }, ageAssuranceState: { type: 'string', description: 'Current age assurance state of the subject.', knownValues: ['pending', 'assured', 'unknown', 'reset', 'blocked'], }, ageAssuranceUpdatedBy: { type: 'string', description: 'Whether or not the last successful update to age assurance was made by the user or admin.', knownValues: ['admin', 'user'], }, }, }, subjectView: { description: "Detailed view of a subject. For record subjects, the author's repo and profile will be returned.", type: 'object', required: ['type', 'subject'], properties: { type: { type: 'ref', ref: 'lex:com.atproto.moderation.defs#subjectType', }, subject: { type: 'string', }, status: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#subjectStatusView', }, repo: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#repoViewDetail', }, profile: { type: 'union', refs: [], }, record: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#recordViewDetail', }, }, }, accountStats: { description: 'Statistics about a particular account subject', type: 'object', properties: { reportCount: { description: 'Total number of reports on the account', type: 'integer', }, appealCount: { description: 'Total number of appeals against a moderation action on the account', type: 'integer', }, suspendCount: { description: 'Number of times the account was suspended', type: 'integer', }, escalateCount: { description: 'Number of times the account was escalated', type: 'integer', }, takedownCount: { description: 'Number of times the account was taken down', type: 'integer', }, }, }, recordsStats: { description: 'Statistics about a set of record subject items', type: 'object', properties: { totalReports: { description: 'Cumulative sum of the number of reports on the items in the set', type: 'integer', }, reportedCount: { description: 'Number of items that were reported at least once', type: 'integer', }, escalatedCount: { description: 'Number of items that were escalated at least once', type: 'integer', }, appealedCount: { description: 'Number of items that were appealed at least once', type: 'integer', }, subjectCount: { description: 'Total number of item in the set', type: 'integer', }, pendingCount: { description: 'Number of item currently in "reviewOpen" or "reviewEscalated" state', type: 'integer', }, processedCount: { description: 'Number of item currently in "reviewNone" or "reviewClosed" state', type: 'integer', }, takendownCount: { description: 'Number of item currently taken down', type: 'integer', }, }, }, accountStrike: { description: 'Strike information for an account', type: 'object', properties: { activeStrikeCount: { description: 'Current number of active strikes (excluding expired strikes)', type: 'integer', }, totalStrikeCount: { description: 'Total number of strikes ever received (including expired strikes)', type: 'integer', }, firstStrikeAt: { description: 'Timestamp of the first strike received', type: 'string', format: 'datetime', }, lastStrikeAt: { description: 'Timestamp of the most recent strike received', type: 'string', format: 'datetime', }, }, }, subjectReviewState: { type: 'string', knownValues: [ 'tools.ozone.moderation.defs#reviewOpen', 'tools.ozone.moderation.defs#reviewEscalated', 'tools.ozone.moderation.defs#reviewClosed', 'tools.ozone.moderation.defs#reviewNone', ], }, reviewOpen: { type: 'token', description: 'Moderator review status of a subject: Open. Indicates that the subject needs to be reviewed by a moderator', }, reviewEscalated: { type: 'token', description: 'Moderator review status of a subject: Escalated. Indicates that the subject was escalated for review by a moderator', }, reviewClosed: { type: 'token', description: 'Moderator review status of a subject: Closed. Indicates that the subject was already reviewed and resolved by a moderator', }, reviewNone: { type: 'token', description: 'Moderator review status of a subject: Unnecessary. Indicates that the subject does not need a review at the moment but there is probably some moderation related metadata available for it', }, modEventTakedown: { type: 'object', description: 'Take down a subject permanently or temporarily', properties: { comment: { type: 'string', }, durationInHours: { type: 'integer', description: 'Indicates how long the takedown should be in effect before automatically expiring.', }, acknowledgeAccountSubjects: { type: 'boolean', description: 'If true, all other reports on content authored by this account will be resolved (acknowledged).', }, policies: { type: 'array', maxLength: 5, items: { type: 'string', }, description: 'Names/Keywords of the policies that drove the decision.', }, severityLevel: { type: 'string', description: "Severity level of the violation (e.g., 'sev-0', 'sev-1', 'sev-2', etc.).", }, targetServices: { type: 'array', items: { type: 'string', knownValues: ['appview', 'pds'], }, description: 'List of services where the takedown should be applied. If empty or not provided, takedown is applied on all configured services.', }, strikeCount: { type: 'integer', description: 'Number of strikes to assign to the user for this violation.', }, strikeExpiresAt: { type: 'string', format: 'datetime', description: 'When the strike should expire. If not provided, the strike never expires.', }, }, }, modEventReverseTakedown: { type: 'object', description: 'Revert take down action on a subject', properties: { comment: { type: 'string', description: 'Describe reasoning behind the reversal.', }, policies: { type: 'array', maxLength: 5, items: { type: 'string', }, description: 'Names/Keywords of the policy infraction for which takedown is being reversed.', }, severityLevel: { type: 'string', description: "Severity level of the violation. Usually set from the last policy infraction's severity.", }, strikeCount: { type: 'integer', description: "Number of strikes to subtract from the user's strike count. Usually set from the last policy infraction's severity.", }, }, }, modEventResolveAppeal: { type: 'object', description: 'Resolve appeal on a subject', properties: { comment: { type: 'string', description: 'Describe resolution.', }, }, }, modEventComment: { type: 'object', description: 'Add a comment to a subject. An empty comment will clear any previously set sticky comment.', properties: { comment: { type: 'string', }, sticky: { type: 'boolean', description: 'Make the comment persistent on the subject', }, }, }, modEventReport: { type: 'object', description: 'Report a subject', required: ['reportType'], properties: { comment: { type: 'string', }, isReporterMuted: { type: 'boolean', description: "Set to true if the reporter was muted from reporting at the time of the event. These reports won't impact the reviewState of the subject.", }, reportType: { type: 'ref', ref: 'lex:com.atproto.moderation.defs#reasonType', }, }, }, modEventLabel: { type: 'object', description: 'Apply/Negate labels on a subject', required: ['createLabelVals', 'negateLabelVals'], properties: { comment: { type: 'string', }, createLabelVals: { type: 'array', items: { type: 'string', }, }, negateLabelVals: { type: 'array', items: { type: 'string', }, }, durationInHours: { type: 'integer', description: 'Indicates how long the label will remain on the subject. Only applies on labels that are being added.', }, }, }, modEventPriorityScore: { type: 'object', description: 'Set priority score of the subject. Higher score means higher priority.', required: ['score'], properties: { comment: { type: 'string', }, score: { type: 'integer', minimum: 0, maximum: 100, }, }, }, ageAssuranceEvent: { type: 'object', description: 'Age assurance info coming directly from users. Only works on DID subjects.', required: ['createdAt', 'status', 'attemptId'], properties: { createdAt: { type: 'string', format: 'datetime', description: 'The date and time of this write operation.', }, attemptId: { type: 'string', description: 'The unique identifier for this instance of the age assurance flow, in UUID format.', }, status: { type: 'string', description: 'The status of the Age Assurance process.', knownValues: ['unknown', 'pending', 'assured'], }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, countryCode: { type: 'string', description: 'The ISO 3166-1 alpha-2 country code provided when beginning the Age Assurance flow.', }, regionCode: { type: 'string', description: 'The ISO 3166-2 region code provided when beginning the Age Assurance flow.', }, initIp: { type: 'string', description: 'The IP address used when initiating the AA flow.', }, initUa: { type: 'string', description: 'The user agent used when initiating the AA flow.', }, completeIp: { type: 'string', description: 'The IP address used when completing the AA flow.', }, completeUa: { type: 'string', description: 'The user agent used when completing the AA flow.', }, }, }, ageAssuranceOverrideEvent: { type: 'object', description: 'Age assurance status override by moderators. Only works on DID subjects.', required: ['comment', 'status'], properties: { status: { type: 'string', description: 'The status to be set for the user decided by a moderator, overriding whatever value the user had previously. Use reset to default to original state.', knownValues: ['assured', 'reset', 'blocked'], }, access: { type: 'ref', ref: 'lex:app.bsky.ageassurance.defs#access', }, comment: { type: 'string', minLength: 1, description: 'Comment describing the reason for the override.', }, }, }, ageAssurancePurgeEvent: { type: 'object', description: 'Purges all age assurance events for the subject. Only works on DID subjects. Moderator-only.', required: ['comment'], properties: { comment: { type: 'string', minLength: 1, description: 'Comment describing the reason for the purge.', }, }, }, revokeAccountCredentialsEvent: { type: 'object', description: 'Account credentials revocation by moderators. Only works on DID subjects.', required: ['comment'], properties: { comment: { minLength: 1, type: 'string', description: 'Comment describing the reason for the revocation.', }, }, }, modEventAcknowledge: { type: 'object', properties: { comment: { type: 'string', }, acknowledgeAccountSubjects: { type: 'boolean', description: 'If true, all other reports on content authored by this account will be resolved (acknowledged).', }, }, }, modEventEscalate: { type: 'object', properties: { comment: { type: 'string', }, }, }, modEventMute: { type: 'object', description: 'Mute incoming reports on a subject', required: ['durationInHours'], properties: { comment: { type: 'string', }, durationInHours: { type: 'integer', description: 'Indicates how long the subject should remain muted.', }, }, }, modEventUnmute: { type: 'object', description: 'Unmute action on a subject', properties: { comment: { type: 'string', description: 'Describe reasoning behind the reversal.', }, }, }, modEventMuteReporter: { type: 'object', description: 'Mute incoming reports from an account', properties: { comment: { type: 'string', }, durationInHours: { type: 'integer', description: 'Indicates how long the account should remain muted. Falsy value here means a permanent mute.', }, }, }, modEventUnmuteReporter: { type: 'object', description: 'Unmute incoming reports from an account', properties: { comment: { type: 'string', description: 'Describe reasoning behind the reversal.', }, }, }, modEventEmail: { type: 'object', description: 'Keep a log of outgoing email to a user', required: ['subjectLine'], properties: { subjectLine: { type: 'string', description: 'The subject line of the email sent to the user.', }, content: { type: 'string', description: 'The content of the email sent to the user.', }, comment: { type: 'string', description: 'Additional comment about the outgoing comm.', }, policies: { type: 'array', maxLength: 5, items: { type: 'string', }, description: 'Names/Keywords of the policies that necessitated the email.', }, severityLevel: { type: 'string', description: "Severity level of the violation. Normally 'sev-1' that adds strike on repeat offense", }, strikeCount: { type: 'integer', description: 'Number of strikes to assign to the user for this violation. Normally 0 as an indicator of a warning and only added as a strike on a repeat offense.', }, strikeExpiresAt: { type: 'string', format: 'datetime', description: 'When the strike should expire. If not provided, the strike never expires.', }, isDelivered: { type: 'boolean', description: "Indicates whether the email was successfully delivered to the user's inbox.", }, }, }, modEventDivert: { type: 'object', description: "Divert a record's blobs to a 3rd party service for further scanning/tagging", properties: { comment: { type: 'string', }, }, }, modEventTag: { type: 'object', description: 'Add/Remove a tag on a subject', required: ['add', 'remove'], properties: { add: { type: 'array', items: { type: 'string', }, description: "Tags to be added to the subject. If already exists, won't be duplicated.", }, remove: { type: 'array', items: { type: 'string', }, description: "Tags to be removed to the subject. Ignores a tag If it doesn't exist, won't be duplicated.", }, comment: { type: 'string', description: 'Additional comment about added/removed tags.', }, }, }, accountEvent: { type: 'object', description: 'Logs account status related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.', required: ['timestamp', 'active'], properties: { comment: { type: 'string', }, active: { type: 'boolean', description: 'Indicates that the account has a repository which can be fetched from the host that emitted this event.', }, status: { type: 'string', knownValues: [ 'unknown', 'deactivated', 'deleted', 'takendown', 'suspended', 'tombstoned', ], }, timestamp: { type: 'string', format: 'datetime', }, }, }, identityEvent: { type: 'object', description: 'Logs identity related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.', required: ['timestamp'], properties: { comment: { type: 'string', }, handle: { type: 'string', format: 'handle', }, pdsHost: { type: 'string', format: 'uri', }, tombstone: { type: 'boolean', }, timestamp: { type: 'string', format: 'datetime', }, }, }, recordEvent: { type: 'object', description: 'Logs lifecycle event on a record subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.', required: ['timestamp', 'op'], properties: { comment: { type: 'string', }, op: { type: 'string', knownValues: ['create', 'update', 'delete'], }, cid: { type: 'string', format: 'cid', }, timestamp: { type: 'string', format: 'datetime', }, }, }, scheduleTakedownEvent: { type: 'object', description: 'Logs a scheduled takedown action for an account.', properties: { comment: { type: 'string', }, executeAt: { type: 'string', format: 'datetime', }, executeAfter: { type: 'string', format: 'datetime', }, executeUntil: { type: 'string', format: 'datetime', }, }, }, cancelScheduledTakedownEvent: { type: 'object', description: 'Logs cancellation of a scheduled takedown action for an account.', properties: { comment: { type: 'string', }, }, }, repoView: { type: 'object', required: [ 'did', 'handle', 'relatedRecords', 'indexedAt', 'moderation', ], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, email: { type: 'string', }, relatedRecords: { type: 'array', items: { type: 'unknown', }, }, indexedAt: { type: 'string', format: 'datetime', }, moderation: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#moderation', }, invitedBy: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCode', }, invitesDisabled: { type: 'boolean', }, inviteNote: { type: 'string', }, deactivatedAt: { type: 'string', format: 'datetime', }, threatSignatures: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.admin.defs#threatSignature', }, }, }, }, repoViewDetail: { type: 'object', required: [ 'did', 'handle', 'relatedRecords', 'indexedAt', 'moderation', ], properties: { did: { type: 'string', format: 'did', }, handle: { type: 'string', format: 'handle', }, email: { type: 'string', }, relatedRecords: { type: 'array', items: { type: 'unknown', }, }, indexedAt: { type: 'string', format: 'datetime', }, moderation: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#moderationDetail', }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, invitedBy: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCode', }, invites: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.server.defs#inviteCode', }, }, invitesDisabled: { type: 'boolean', }, inviteNote: { type: 'string', }, emailConfirmedAt: { type: 'string', format: 'datetime', }, deactivatedAt: { type: 'string', format: 'datetime', }, threatSignatures: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.admin.defs#threatSignature', }, }, }, }, repoViewNotFound: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, recordView: { type: 'object', required: [ 'uri', 'cid', 'value', 'blobCids', 'indexedAt', 'moderation', 'repo', ], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, value: { type: 'unknown', }, blobCids: { type: 'array', items: { type: 'string', format: 'cid', }, }, indexedAt: { type: 'string', format: 'datetime', }, moderation: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#moderation', }, repo: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#repoView', }, }, }, recordViewDetail: { type: 'object', required: [ 'uri', 'cid', 'value', 'blobs', 'indexedAt', 'moderation', 'repo', ], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, value: { type: 'unknown', }, blobs: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#blobView', }, }, labels: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.label.defs#label', }, }, indexedAt: { type: 'string', format: 'datetime', }, moderation: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#moderationDetail', }, repo: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#repoView', }, }, }, recordViewNotFound: { type: 'object', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', }, }, }, moderation: { type: 'object', properties: { subjectStatus: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#subjectStatusView', }, }, }, moderationDetail: { type: 'object', properties: { subjectStatus: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#subjectStatusView', }, }, }, blobView: { type: 'object', required: ['cid', 'mimeType', 'size', 'createdAt'], properties: { cid: { type: 'string', format: 'cid', }, mimeType: { type: 'string', }, size: { type: 'integer', }, createdAt: { type: 'string', format: 'datetime', }, details: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#imageDetails', 'lex:tools.ozone.moderation.defs#videoDetails', ], }, moderation: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#moderation', }, }, }, imageDetails: { type: 'object', required: ['width', 'height'], properties: { width: { type: 'integer', }, height: { type: 'integer', }, }, }, videoDetails: { type: 'object', required: ['width', 'height', 'length'], properties: { width: { type: 'integer', }, height: { type: 'integer', }, length: { type: 'integer', }, }, }, accountHosting: { type: 'object', required: ['status'], properties: { status: { type: 'string', knownValues: [ 'takendown', 'suspended', 'deleted', 'deactivated', 'unknown', ], }, updatedAt: { type: 'string', format: 'datetime', }, createdAt: { type: 'string', format: 'datetime', }, deletedAt: { type: 'string', format: 'datetime', }, deactivatedAt: { type: 'string', format: 'datetime', }, reactivatedAt: { type: 'string', format: 'datetime', }, }, }, recordHosting: { type: 'object', required: ['status'], properties: { status: { type: 'string', knownValues: ['deleted', 'unknown'], }, updatedAt: { type: 'string', format: 'datetime', }, createdAt: { type: 'string', format: 'datetime', }, deletedAt: { type: 'string', format: 'datetime', }, }, }, reporterStats: { type: 'object', required: [ 'did', 'accountReportCount', 'recordReportCount', 'reportedAccountCount', 'reportedRecordCount', 'takendownAccountCount', 'takendownRecordCount', 'labeledAccountCount', 'labeledRecordCount', ], properties: { did: { type: 'string', format: 'did', }, accountReportCount: { type: 'integer', description: 'The total number of reports made by the user on accounts.', }, recordReportCount: { type: 'integer', description: 'The total number of reports made by the user on records.', }, reportedAccountCount: { type: 'integer', description: 'The total number of accounts reported by the user.', }, reportedRecordCount: { type: 'integer', description: 'The total number of records reported by the user.', }, takendownAccountCount: { type: 'integer', description: "The total number of accounts taken down as a result of the user's reports.", }, takendownRecordCount: { type: 'integer', description: "The total number of records taken down as a result of the user's reports.", }, labeledAccountCount: { type: 'integer', description: "The total number of accounts labeled as a result of the user's reports.", }, labeledRecordCount: { type: 'integer', description: "The total number of records labeled as a result of the user's reports.", }, }, }, modTool: { type: 'object', description: 'Moderation tool information for tracing the source of the action', required: ['name'], properties: { name: { type: 'string', description: "Name/identifier of the source (e.g., 'automod', 'ozone/workspace')", }, meta: { type: 'unknown', description: 'Additional arbitrary metadata about the source', }, }, }, timelineEventPlcCreate: { type: 'token', description: 'Moderation event timeline event for a PLC create operation', }, timelineEventPlcOperation: { type: 'token', description: 'Moderation event timeline event for generic PLC operation', }, timelineEventPlcTombstone: { type: 'token', description: 'Moderation event timeline event for a PLC tombstone operation', }, scheduledActionView: { type: 'object', description: 'View of a scheduled moderation action', required: ['id', 'action', 'did', 'createdBy', 'createdAt', 'status'], properties: { id: { type: 'integer', description: 'Auto-incrementing row ID', }, action: { type: 'string', knownValues: ['takedown'], description: 'Type of action to be executed', }, eventData: { type: 'unknown', description: 'Serialized event object that will be propagated to the event when performed', }, did: { type: 'string', format: 'did', description: 'Subject DID for the action', }, executeAt: { type: 'string', format: 'datetime', description: 'Exact time to execute the action', }, executeAfter: { type: 'string', format: 'datetime', description: 'Earliest time to execute the action (for randomized scheduling)', }, executeUntil: { type: 'string', format: 'datetime', description: 'Latest time to execute the action (for randomized scheduling)', }, randomizeExecution: { type: 'boolean', description: 'Whether execution time should be randomized within the specified range', }, createdBy: { type: 'string', format: 'did', description: 'DID of the user who created this scheduled action', }, createdAt: { type: 'string', format: 'datetime', description: 'When the scheduled action was created', }, updatedAt: { type: 'string', format: 'datetime', description: 'When the scheduled action was last updated', }, status: { type: 'string', knownValues: ['pending', 'executed', 'cancelled', 'failed'], description: 'Current status of the scheduled action', }, lastExecutedAt: { type: 'string', format: 'datetime', description: 'When the action was last attempted to be executed', }, lastFailureReason: { type: 'string', description: 'Reason for the last execution failure', }, executionEventId: { type: 'integer', description: 'ID of the moderation event created when action was successfully executed', }, }, }, }, }, ToolsOzoneModerationEmitEvent: { lexicon: 1, id: 'tools.ozone.moderation.emitEvent', defs: { main: { type: 'procedure', description: 'Take a moderation action on an actor.', input: { encoding: 'application/json', schema: { type: 'object', required: ['event', 'subject', 'createdBy'], properties: { event: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#modEventTakedown', 'lex:tools.ozone.moderation.defs#modEventAcknowledge', 'lex:tools.ozone.moderation.defs#modEventEscalate', 'lex:tools.ozone.moderation.defs#modEventComment', 'lex:tools.ozone.moderation.defs#modEventLabel', 'lex:tools.ozone.moderation.defs#modEventReport', 'lex:tools.ozone.moderation.defs#modEventMute', 'lex:tools.ozone.moderation.defs#modEventUnmute', 'lex:tools.ozone.moderation.defs#modEventMuteReporter', 'lex:tools.ozone.moderation.defs#modEventUnmuteReporter', 'lex:tools.ozone.moderation.defs#modEventReverseTakedown', 'lex:tools.ozone.moderation.defs#modEventResolveAppeal', 'lex:tools.ozone.moderation.defs#modEventEmail', 'lex:tools.ozone.moderation.defs#modEventDivert', 'lex:tools.ozone.moderation.defs#modEventTag', 'lex:tools.ozone.moderation.defs#accountEvent', 'lex:tools.ozone.moderation.defs#identityEvent', 'lex:tools.ozone.moderation.defs#recordEvent', 'lex:tools.ozone.moderation.defs#modEventPriorityScore', 'lex:tools.ozone.moderation.defs#ageAssuranceEvent', 'lex:tools.ozone.moderation.defs#ageAssuranceOverrideEvent', 'lex:tools.ozone.moderation.defs#ageAssurancePurgeEvent', 'lex:tools.ozone.moderation.defs#revokeAccountCredentialsEvent', 'lex:tools.ozone.moderation.defs#scheduleTakedownEvent', 'lex:tools.ozone.moderation.defs#cancelScheduledTakedownEvent', ], }, subject: { type: 'union', refs: [ 'lex:com.atproto.admin.defs#repoRef', 'lex:com.atproto.repo.strongRef', ], }, subjectBlobCids: { type: 'array', items: { type: 'string', format: 'cid', }, }, createdBy: { type: 'string', format: 'did', }, modTool: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#modTool', }, externalId: { type: 'string', description: 'An optional external ID for the event, used to deduplicate events from external systems. Fails when an event of same type with the same external ID exists for the same subject.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#modEventView', }, }, errors: [ { name: 'SubjectHasAction', }, { name: 'DuplicateExternalId', description: 'An event with the same external ID already exists for the subject.', }, ], }, }, }, ToolsOzoneModerationGetAccountTimeline: { lexicon: 1, id: 'tools.ozone.moderation.getAccountTimeline', defs: { main: { type: 'query', description: 'Get timeline of all available events of an account. This includes moderation events, account history and did history.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['timeline'], properties: { timeline: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.getAccountTimeline#timelineItem', }, }, }, }, }, errors: [ { name: 'RepoNotFound', }, ], }, timelineItem: { type: 'object', required: ['day', 'summary'], properties: { day: { type: 'string', }, summary: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.getAccountTimeline#timelineItemSummary', }, }, }, }, timelineItemSummary: { type: 'object', required: ['eventSubjectType', 'eventType', 'count'], properties: { eventSubjectType: { type: 'string', knownValues: ['account', 'record', 'chat'], }, eventType: { type: 'string', knownValues: [ 'tools.ozone.moderation.defs#modEventTakedown', 'tools.ozone.moderation.defs#modEventReverseTakedown', 'tools.ozone.moderation.defs#modEventComment', 'tools.ozone.moderation.defs#modEventReport', 'tools.ozone.moderation.defs#modEventLabel', 'tools.ozone.moderation.defs#modEventAcknowledge', 'tools.ozone.moderation.defs#modEventEscalate', 'tools.ozone.moderation.defs#modEventMute', 'tools.ozone.moderation.defs#modEventUnmute', 'tools.ozone.moderation.defs#modEventMuteReporter', 'tools.ozone.moderation.defs#modEventUnmuteReporter', 'tools.ozone.moderation.defs#modEventEmail', 'tools.ozone.moderation.defs#modEventResolveAppeal', 'tools.ozone.moderation.defs#modEventDivert', 'tools.ozone.moderation.defs#modEventTag', 'tools.ozone.moderation.defs#accountEvent', 'tools.ozone.moderation.defs#identityEvent', 'tools.ozone.moderation.defs#recordEvent', 'tools.ozone.moderation.defs#modEventPriorityScore', 'tools.ozone.moderation.defs#revokeAccountCredentialsEvent', 'tools.ozone.moderation.defs#ageAssuranceEvent', 'tools.ozone.moderation.defs#ageAssuranceOverrideEvent', 'tools.ozone.moderation.defs#timelineEventPlcCreate', 'tools.ozone.moderation.defs#timelineEventPlcOperation', 'tools.ozone.moderation.defs#timelineEventPlcTombstone', 'tools.ozone.hosting.getAccountHistory#accountCreated', 'tools.ozone.hosting.getAccountHistory#emailConfirmed', 'tools.ozone.hosting.getAccountHistory#passwordUpdated', 'tools.ozone.hosting.getAccountHistory#handleUpdated', 'tools.ozone.moderation.defs#scheduleTakedownEvent', 'tools.ozone.moderation.defs#cancelScheduledTakedownEvent', ], }, count: { type: 'integer', }, }, }, }, }, ToolsOzoneModerationGetEvent: { lexicon: 1, id: 'tools.ozone.moderation.getEvent', defs: { main: { type: 'query', description: 'Get details about a moderation event.', parameters: { type: 'params', required: ['id'], properties: { id: { type: 'integer', }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#modEventViewDetail', }, }, }, }, }, ToolsOzoneModerationGetRecord: { lexicon: 1, id: 'tools.ozone.moderation.getRecord', defs: { main: { type: 'query', description: 'Get details about a record.', parameters: { type: 'params', required: ['uri'], properties: { uri: { type: 'string', format: 'at-uri', }, cid: { type: 'string', format: 'cid', }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#recordViewDetail', }, }, errors: [ { name: 'RecordNotFound', }, ], }, }, }, ToolsOzoneModerationGetRecords: { lexicon: 1, id: 'tools.ozone.moderation.getRecords', defs: { main: { type: 'query', description: 'Get details about some records.', parameters: { type: 'params', required: ['uris'], properties: { uris: { type: 'array', maxLength: 100, items: { type: 'string', format: 'at-uri', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['records'], properties: { records: { type: 'array', items: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#recordViewDetail', 'lex:tools.ozone.moderation.defs#recordViewNotFound', ], }, }, }, }, }, }, }, }, ToolsOzoneModerationGetRepo: { lexicon: 1, id: 'tools.ozone.moderation.getRepo', defs: { main: { type: 'query', description: 'Get details about a repository.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#repoViewDetail', }, }, errors: [ { name: 'RepoNotFound', }, ], }, }, }, ToolsOzoneModerationGetReporterStats: { lexicon: 1, id: 'tools.ozone.moderation.getReporterStats', defs: { main: { type: 'query', description: 'Get reporter stats for a list of users.', parameters: { type: 'params', required: ['dids'], properties: { dids: { type: 'array', maxLength: 100, items: { type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['stats'], properties: { stats: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#reporterStats', }, }, }, }, }, }, }, }, ToolsOzoneModerationGetRepos: { lexicon: 1, id: 'tools.ozone.moderation.getRepos', defs: { main: { type: 'query', description: 'Get details about some repositories.', parameters: { type: 'params', required: ['dids'], properties: { dids: { type: 'array', maxLength: 100, items: { type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['repos'], properties: { repos: { type: 'array', items: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#repoViewDetail', 'lex:tools.ozone.moderation.defs#repoViewNotFound', ], }, }, }, }, }, }, }, }, ToolsOzoneModerationGetSubjects: { lexicon: 1, id: 'tools.ozone.moderation.getSubjects', defs: { main: { type: 'query', description: 'Get details about subjects.', parameters: { type: 'params', required: ['subjects'], properties: { subjects: { type: 'array', maxLength: 100, minLength: 1, items: { type: 'string', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subjects'], properties: { subjects: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#subjectView', }, }, }, }, }, }, }, }, ToolsOzoneModerationListScheduledActions: { lexicon: 1, id: 'tools.ozone.moderation.listScheduledActions', defs: { main: { type: 'procedure', description: 'List scheduled moderation actions with optional filtering', input: { encoding: 'application/json', schema: { type: 'object', required: ['statuses'], properties: { startsAfter: { type: 'string', format: 'datetime', description: 'Filter actions scheduled to execute after this time', }, endsBefore: { type: 'string', format: 'datetime', description: 'Filter actions scheduled to execute before this time', }, subjects: { type: 'array', maxLength: 100, items: { type: 'string', format: 'did', }, description: 'Filter actions for specific DID subjects', }, statuses: { type: 'array', minLength: 1, items: { type: 'string', knownValues: ['pending', 'executed', 'cancelled', 'failed'], }, description: 'Filter actions by status', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, description: 'Maximum number of results to return', }, cursor: { type: 'string', description: 'Cursor for pagination', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['actions'], properties: { actions: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#scheduledActionView', }, }, cursor: { type: 'string', description: 'Cursor for next page of results', }, }, }, }, }, }, }, ToolsOzoneModerationQueryEvents: { lexicon: 1, id: 'tools.ozone.moderation.queryEvents', defs: { main: { type: 'query', description: 'List moderation events related to a subject.', parameters: { type: 'params', properties: { types: { type: 'array', items: { type: 'string', }, description: 'The types of events (fully qualified string in the format of tools.ozone.moderation.defs#modEvent) to filter by. If not specified, all events are returned.', }, createdBy: { type: 'string', format: 'did', }, sortDirection: { type: 'string', default: 'desc', enum: ['asc', 'desc'], description: 'Sort direction for the events. Defaults to descending order of created at timestamp.', }, createdAfter: { type: 'string', format: 'datetime', description: 'Retrieve events created after a given timestamp', }, createdBefore: { type: 'string', format: 'datetime', description: 'Retrieve events created before a given timestamp', }, subject: { type: 'string', format: 'uri', }, collections: { type: 'array', maxLength: 20, description: "If specified, only events where the subject belongs to the given collections will be returned. When subjectType is set to 'account', this will be ignored.", items: { type: 'string', format: 'nsid', }, }, subjectType: { type: 'string', description: "If specified, only events where the subject is of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored.", knownValues: ['account', 'record'], }, includeAllUserRecords: { type: 'boolean', default: false, description: "If true, events on all record types (posts, lists, profile etc.) or records from given 'collections' param, owned by the did are returned.", }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, hasComment: { type: 'boolean', description: 'If true, only events with comments are returned', }, comment: { type: 'string', description: 'If specified, only events with comments containing the keyword are returned. Apply || separator to use multiple keywords and match using OR condition.', }, addedLabels: { type: 'array', items: { type: 'string', }, description: 'If specified, only events where all of these labels were added are returned', }, removedLabels: { type: 'array', items: { type: 'string', }, description: 'If specified, only events where all of these labels were removed are returned', }, addedTags: { type: 'array', items: { type: 'string', }, description: 'If specified, only events where all of these tags were added are returned', }, removedTags: { type: 'array', items: { type: 'string', }, description: 'If specified, only events where all of these tags were removed are returned', }, reportTypes: { type: 'array', items: { type: 'string', }, }, policies: { type: 'array', items: { type: 'string', description: 'If specified, only events where the action policies match any of the given policies are returned', }, }, modTool: { type: 'array', items: { type: 'string', }, description: 'If specified, only events where the modTool name matches any of the given values are returned', }, batchId: { type: 'string', description: 'If specified, only events where the batchId matches the given value are returned', }, ageAssuranceState: { type: 'string', description: 'If specified, only events where the age assurance state matches the given value are returned', knownValues: [ 'pending', 'assured', 'unknown', 'reset', 'blocked', ], }, withStrike: { type: 'boolean', description: 'If specified, only events where strikeCount value is set are returned.', }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['events'], properties: { cursor: { type: 'string', }, events: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#modEventView', }, }, }, }, }, }, }, }, ToolsOzoneModerationQueryStatuses: { lexicon: 1, id: 'tools.ozone.moderation.queryStatuses', defs: { main: { type: 'query', description: 'View moderation statuses of subjects (record or repo).', parameters: { type: 'params', properties: { queueCount: { type: 'integer', description: 'Number of queues being used by moderators. Subjects will be split among all queues.', }, queueIndex: { type: 'integer', description: 'Index of the queue to fetch subjects from. Works only when queueCount value is specified.', }, queueSeed: { type: 'string', description: 'A seeder to shuffle/balance the queue items.', }, includeAllUserRecords: { type: 'boolean', description: "All subjects, or subjects from given 'collections' param, belonging to the account specified in the 'subject' param will be returned.", }, subject: { type: 'string', format: 'uri', description: 'The subject to get the status for.', }, comment: { type: 'string', description: 'Search subjects by keyword from comments', }, reportedAfter: { type: 'string', format: 'datetime', description: 'Search subjects reported after a given timestamp', }, reportedBefore: { type: 'string', format: 'datetime', description: 'Search subjects reported before a given timestamp', }, reviewedAfter: { type: 'string', format: 'datetime', description: 'Search subjects reviewed after a given timestamp', }, hostingDeletedAfter: { type: 'string', format: 'datetime', description: 'Search subjects where the associated record/account was deleted after a given timestamp', }, hostingDeletedBefore: { type: 'string', format: 'datetime', description: 'Search subjects where the associated record/account was deleted before a given timestamp', }, hostingUpdatedAfter: { type: 'string', format: 'datetime', description: 'Search subjects where the associated record/account was updated after a given timestamp', }, hostingUpdatedBefore: { type: 'string', format: 'datetime', description: 'Search subjects where the associated record/account was updated before a given timestamp', }, hostingStatuses: { type: 'array', items: { type: 'string', }, description: 'Search subjects by the status of the associated record/account', }, reviewedBefore: { type: 'string', format: 'datetime', description: 'Search subjects reviewed before a given timestamp', }, includeMuted: { type: 'boolean', description: "By default, we don't include muted subjects in the results. Set this to true to include them.", }, onlyMuted: { type: 'boolean', description: 'When set to true, only muted subjects and reporters will be returned.', }, reviewState: { type: 'string', description: 'Specify when fetching subjects in a certain state', knownValues: [ 'tools.ozone.moderation.defs#reviewOpen', 'tools.ozone.moderation.defs#reviewClosed', 'tools.ozone.moderation.defs#reviewEscalated', 'tools.ozone.moderation.defs#reviewNone', ], }, ignoreSubjects: { type: 'array', items: { type: 'string', format: 'uri', }, }, lastReviewedBy: { type: 'string', format: 'did', description: 'Get all subject statuses that were reviewed by a specific moderator', }, sortField: { type: 'string', default: 'lastReportedAt', enum: [ 'lastReviewedAt', 'lastReportedAt', 'reportedRecordsCount', 'takendownRecordsCount', 'priorityScore', ], }, sortDirection: { type: 'string', default: 'desc', enum: ['asc', 'desc'], }, takendown: { type: 'boolean', description: 'Get subjects that were taken down', }, appealed: { type: 'boolean', description: 'Get subjects in unresolved appealed status', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, tags: { type: 'array', maxLength: 25, items: { type: 'string', description: 'Items in this array are applied with OR filters. To apply AND filter, put all tags in the same string and separate using && characters', }, }, excludeTags: { type: 'array', items: { type: 'string', }, }, cursor: { type: 'string', }, collections: { type: 'array', maxLength: 20, description: "If specified, subjects belonging to the given collections will be returned. When subjectType is set to 'account', this will be ignored.", items: { type: 'string', format: 'nsid', }, }, subjectType: { type: 'string', description: "If specified, subjects of the given type (account or record) will be returned. When this is set to 'account' the 'collections' parameter will be ignored. When includeAllUserRecords or subject is set, this will be ignored.", knownValues: ['account', 'record'], }, minAccountSuspendCount: { type: 'integer', description: 'If specified, only subjects that belong to an account that has at least this many suspensions will be returned.', }, minReportedRecordsCount: { type: 'integer', description: 'If specified, only subjects that belong to an account that has at least this many reported records will be returned.', }, minTakendownRecordsCount: { type: 'integer', description: 'If specified, only subjects that belong to an account that has at least this many taken down records will be returned.', }, minPriorityScore: { minimum: 0, maximum: 100, type: 'integer', description: 'If specified, only subjects that have priority score value above the given value will be returned.', }, minStrikeCount: { type: 'integer', minimum: 1, description: 'If specified, only subjects that belong to an account that has at least this many active strikes will be returned.', }, ageAssuranceState: { type: 'string', description: 'If specified, only subjects with the given age assurance state will be returned.', knownValues: [ 'pending', 'assured', 'unknown', 'reset', 'blocked', ], }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['subjectStatuses'], properties: { cursor: { type: 'string', }, subjectStatuses: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#subjectStatusView', }, }, }, }, }, }, }, }, ToolsOzoneModerationScheduleAction: { lexicon: 1, id: 'tools.ozone.moderation.scheduleAction', defs: { main: { type: 'procedure', description: 'Schedule a moderation action to be executed at a future time', input: { encoding: 'application/json', schema: { type: 'object', required: ['action', 'subjects', 'createdBy', 'scheduling'], properties: { action: { type: 'union', refs: ['lex:tools.ozone.moderation.scheduleAction#takedown'], }, subjects: { type: 'array', maxLength: 100, items: { type: 'string', format: 'did', }, description: 'Array of DID subjects to schedule the action for', }, createdBy: { type: 'string', format: 'did', }, scheduling: { type: 'ref', ref: 'lex:tools.ozone.moderation.scheduleAction#schedulingConfig', }, modTool: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#modTool', description: 'This will be propagated to the moderation event when it is applied', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.moderation.scheduleAction#scheduledActionResults', }, }, }, takedown: { type: 'object', description: 'Schedule a takedown action', properties: { comment: { type: 'string', }, durationInHours: { type: 'integer', description: 'Indicates how long the takedown should be in effect before automatically expiring.', }, acknowledgeAccountSubjects: { type: 'boolean', description: 'If true, all other reports on content authored by this account will be resolved (acknowledged).', }, policies: { type: 'array', maxLength: 5, items: { type: 'string', }, description: 'Names/Keywords of the policies that drove the decision.', }, severityLevel: { type: 'string', description: "Severity level of the violation (e.g., 'sev-0', 'sev-1', 'sev-2', etc.).", }, strikeCount: { type: 'integer', description: 'Number of strikes to assign to the user when takedown is applied.', }, strikeExpiresAt: { type: 'string', format: 'datetime', description: 'When the strike should expire. If not provided, the strike never expires.', }, emailContent: { type: 'string', description: 'Email content to be sent to the user upon takedown.', }, emailSubject: { type: 'string', description: 'Subject of the email to be sent to the user upon takedown.', }, }, }, schedulingConfig: { type: 'object', description: 'Configuration for when the action should be executed', properties: { executeAt: { type: 'string', format: 'datetime', description: 'Exact time to execute the action', }, executeAfter: { type: 'string', format: 'datetime', description: 'Earliest time to execute the action (for randomized scheduling)', }, executeUntil: { type: 'string', format: 'datetime', description: 'Latest time to execute the action (for randomized scheduling)', }, }, }, scheduledActionResults: { type: 'object', required: ['succeeded', 'failed'], properties: { succeeded: { type: 'array', items: { type: 'string', format: 'did', }, }, failed: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.scheduleAction#failedScheduling', }, }, }, }, failedScheduling: { type: 'object', required: ['subject', 'error'], properties: { subject: { type: 'string', format: 'did', }, error: { type: 'string', }, errorCode: { type: 'string', }, }, }, }, }, ToolsOzoneModerationSearchRepos: { lexicon: 1, id: 'tools.ozone.moderation.searchRepos', defs: { main: { type: 'query', description: 'Find repositories based on a search term.', parameters: { type: 'params', properties: { term: { type: 'string', description: "DEPRECATED: use 'q' instead", }, q: { type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['repos'], properties: { cursor: { type: 'string', }, repos: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.moderation.defs#repoView', }, }, }, }, }, }, }, }, ToolsOzoneReportDefs: { lexicon: 1, id: 'tools.ozone.report.defs', defs: { reasonType: { type: 'string', knownValues: [ 'tools.ozone.report.defs#reasonAppeal', 'tools.ozone.report.defs#reasonOther', 'tools.ozone.report.defs#reasonViolenceAnimal', 'tools.ozone.report.defs#reasonViolenceThreats', 'tools.ozone.report.defs#reasonViolenceGraphicContent', 'tools.ozone.report.defs#reasonViolenceGlorification', 'tools.ozone.report.defs#reasonViolenceExtremistContent', 'tools.ozone.report.defs#reasonViolenceTrafficking', 'tools.ozone.report.defs#reasonViolenceOther', 'tools.ozone.report.defs#reasonSexualAbuseContent', 'tools.ozone.report.defs#reasonSexualNCII', 'tools.ozone.report.defs#reasonSexualDeepfake', 'tools.ozone.report.defs#reasonSexualAnimal', 'tools.ozone.report.defs#reasonSexualUnlabeled', 'tools.ozone.report.defs#reasonSexualOther', 'tools.ozone.report.defs#reasonChildSafetyCSAM', 'tools.ozone.report.defs#reasonChildSafetyGroom', 'tools.ozone.report.defs#reasonChildSafetyPrivacy', 'tools.ozone.report.defs#reasonChildSafetyHarassment', 'tools.ozone.report.defs#reasonChildSafetyOther', 'tools.ozone.report.defs#reasonHarassmentTroll', 'tools.ozone.report.defs#reasonHarassmentTargeted', 'tools.ozone.report.defs#reasonHarassmentHateSpeech', 'tools.ozone.report.defs#reasonHarassmentDoxxing', 'tools.ozone.report.defs#reasonHarassmentOther', 'tools.ozone.report.defs#reasonMisleadingBot', 'tools.ozone.report.defs#reasonMisleadingImpersonation', 'tools.ozone.report.defs#reasonMisleadingSpam', 'tools.ozone.report.defs#reasonMisleadingScam', 'tools.ozone.report.defs#reasonMisleadingElections', 'tools.ozone.report.defs#reasonMisleadingOther', 'tools.ozone.report.defs#reasonRuleSiteSecurity', 'tools.ozone.report.defs#reasonRuleProhibitedSales', 'tools.ozone.report.defs#reasonRuleBanEvasion', 'tools.ozone.report.defs#reasonRuleOther', 'tools.ozone.report.defs#reasonSelfHarmContent', 'tools.ozone.report.defs#reasonSelfHarmED', 'tools.ozone.report.defs#reasonSelfHarmStunts', 'tools.ozone.report.defs#reasonSelfHarmSubstances', 'tools.ozone.report.defs#reasonSelfHarmOther', ], }, reasonAppeal: { type: 'token', description: 'Appeal a previously taken moderation action', }, reasonOther: { type: 'token', description: 'An issue not included in these options', }, reasonViolenceAnimal: { type: 'token', description: 'Animal welfare violations', }, reasonViolenceThreats: { type: 'token', description: 'Threats or incitement', }, reasonViolenceGraphicContent: { type: 'token', description: 'Graphic violent content', }, reasonViolenceGlorification: { type: 'token', description: 'Glorification of violence', }, reasonViolenceExtremistContent: { type: 'token', description: "Extremist content. These reports will be sent only be sent to the application's Moderation Authority.", }, reasonViolenceTrafficking: { type: 'token', description: 'Human trafficking', }, reasonViolenceOther: { type: 'token', description: 'Other violent content', }, reasonSexualAbuseContent: { type: 'token', description: 'Adult sexual abuse content', }, reasonSexualNCII: { type: 'token', description: 'Non-consensual intimate imagery', }, reasonSexualDeepfake: { type: 'token', description: 'Deepfake adult content', }, reasonSexualAnimal: { type: 'token', description: 'Animal sexual abuse', }, reasonSexualUnlabeled: { type: 'token', description: 'Unlabelled adult content', }, reasonSexualOther: { type: 'token', description: 'Other sexual violence content', }, reasonChildSafetyCSAM: { type: 'token', description: "Child sexual abuse material (CSAM). These reports will be sent only be sent to the application's Moderation Authority.", }, reasonChildSafetyGroom: { type: 'token', description: "Grooming or predatory behavior. These reports will be sent only be sent to the application's Moderation Authority.", }, reasonChildSafetyPrivacy: { type: 'token', description: 'Privacy violation involving a minor', }, reasonChildSafetyHarassment: { type: 'token', description: 'Harassment or bullying of minors', }, reasonChildSafetyOther: { type: 'token', description: "Other child safety. These reports will be sent only be sent to the application's Moderation Authority.", }, reasonHarassmentTroll: { type: 'token', description: 'Trolling', }, reasonHarassmentTargeted: { type: 'token', description: 'Targeted harassment', }, reasonHarassmentHateSpeech: { type: 'token', description: 'Hate speech', }, reasonHarassmentDoxxing: { type: 'token', description: 'Doxxing', }, reasonHarassmentOther: { type: 'token', description: 'Other harassing or hateful content', }, reasonMisleadingBot: { type: 'token', description: 'Fake account or bot', }, reasonMisleadingImpersonation: { type: 'token', description: 'Impersonation', }, reasonMisleadingSpam: { type: 'token', description: 'Spam', }, reasonMisleadingScam: { type: 'token', description: 'Scam', }, reasonMisleadingElections: { type: 'token', description: 'False information about elections', }, reasonMisleadingOther: { type: 'token', description: 'Other misleading content', }, reasonRuleSiteSecurity: { type: 'token', description: 'Hacking or system attacks', }, reasonRuleProhibitedSales: { type: 'token', description: 'Promoting or selling prohibited items or services', }, reasonRuleBanEvasion: { type: 'token', description: 'Banned user returning', }, reasonRuleOther: { type: 'token', description: 'Other', }, reasonSelfHarmContent: { type: 'token', description: 'Content promoting or depicting self-harm', }, reasonSelfHarmED: { type: 'token', description: 'Eating disorders', }, reasonSelfHarmStunts: { type: 'token', description: 'Dangerous challenges or activities', }, reasonSelfHarmSubstances: { type: 'token', description: 'Dangerous substances or drug abuse', }, reasonSelfHarmOther: { type: 'token', description: 'Other dangerous content', }, }, }, ToolsOzoneSafelinkAddRule: { lexicon: 1, id: 'tools.ozone.safelink.addRule', defs: { main: { type: 'procedure', description: 'Add a new URL safety rule', input: { encoding: 'application/json', schema: { type: 'object', required: ['url', 'pattern', 'action', 'reason'], properties: { url: { type: 'string', description: 'The URL or domain to apply the rule to', }, pattern: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#patternType', }, action: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#actionType', }, reason: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#reasonType', }, comment: { type: 'string', description: 'Optional comment about the decision', }, createdBy: { type: 'string', format: 'did', description: 'Author DID. Only respected when using admin auth', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#event', }, }, errors: [ { name: 'InvalidUrl', description: 'The provided URL is invalid', }, { name: 'RuleAlreadyExists', description: 'A rule for this URL/domain already exists', }, ], }, }, }, ToolsOzoneSafelinkDefs: { lexicon: 1, id: 'tools.ozone.safelink.defs', defs: { event: { type: 'object', description: 'An event for URL safety decisions', required: [ 'id', 'eventType', 'url', 'pattern', 'action', 'reason', 'createdBy', 'createdAt', ], properties: { id: { type: 'integer', description: 'Auto-incrementing row ID', }, eventType: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#eventType', }, url: { type: 'string', description: 'The URL that this rule applies to', }, pattern: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#patternType', }, action: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#actionType', }, reason: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#reasonType', }, createdBy: { type: 'string', format: 'did', description: 'DID of the user who created this rule', }, createdAt: { type: 'string', format: 'datetime', }, comment: { type: 'string', description: 'Optional comment about the decision', }, }, }, eventType: { type: 'string', knownValues: ['addRule', 'updateRule', 'removeRule'], }, patternType: { type: 'string', knownValues: ['domain', 'url'], }, actionType: { type: 'string', knownValues: ['block', 'warn', 'whitelist'], }, reasonType: { type: 'string', knownValues: ['csam', 'spam', 'phishing', 'none'], }, urlRule: { type: 'object', description: 'Input for creating a URL safety rule', required: [ 'url', 'pattern', 'action', 'reason', 'createdBy', 'createdAt', 'updatedAt', ], properties: { url: { type: 'string', description: 'The URL or domain to apply the rule to', }, pattern: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#patternType', }, action: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#actionType', }, reason: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#reasonType', }, comment: { type: 'string', description: 'Optional comment about the decision', }, createdBy: { type: 'string', format: 'did', description: 'DID of the user added the rule.', }, createdAt: { type: 'string', format: 'datetime', description: 'Timestamp when the rule was created', }, updatedAt: { type: 'string', format: 'datetime', description: 'Timestamp when the rule was last updated', }, }, }, }, }, ToolsOzoneSafelinkQueryEvents: { lexicon: 1, id: 'tools.ozone.safelink.queryEvents', defs: { main: { type: 'procedure', description: 'Query URL safety audit events', input: { encoding: 'application/json', schema: { type: 'object', properties: { cursor: { type: 'string', description: 'Cursor for pagination', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, description: 'Maximum number of results to return', }, urls: { type: 'array', items: { type: 'string', }, description: 'Filter by specific URLs or domains', }, patternType: { type: 'string', description: 'Filter by pattern type', }, sortDirection: { type: 'string', knownValues: ['asc', 'desc'], default: 'desc', description: 'Sort direction', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['events'], properties: { cursor: { type: 'string', description: 'Next cursor for pagination. Only present if there are more results.', }, events: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#event', }, }, }, }, }, }, }, }, ToolsOzoneSafelinkQueryRules: { lexicon: 1, id: 'tools.ozone.safelink.queryRules', defs: { main: { type: 'procedure', description: 'Query URL safety rules', input: { encoding: 'application/json', schema: { type: 'object', properties: { cursor: { type: 'string', description: 'Cursor for pagination', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, description: 'Maximum number of results to return', }, urls: { type: 'array', items: { type: 'string', }, description: 'Filter by specific URLs or domains', }, patternType: { type: 'string', description: 'Filter by pattern type', }, actions: { type: 'array', items: { type: 'string', }, description: 'Filter by action types', }, reason: { type: 'string', description: 'Filter by reason type', }, createdBy: { type: 'string', format: 'did', description: 'Filter by rule creator', }, sortDirection: { type: 'string', knownValues: ['asc', 'desc'], default: 'desc', description: 'Sort direction', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['rules'], properties: { cursor: { type: 'string', description: 'Next cursor for pagination. Only present if there are more results.', }, rules: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#urlRule', }, }, }, }, }, }, }, }, ToolsOzoneSafelinkRemoveRule: { lexicon: 1, id: 'tools.ozone.safelink.removeRule', defs: { main: { type: 'procedure', description: 'Remove an existing URL safety rule', input: { encoding: 'application/json', schema: { type: 'object', required: ['url', 'pattern'], properties: { url: { type: 'string', description: 'The URL or domain to remove the rule for', }, pattern: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#patternType', }, comment: { type: 'string', description: 'Optional comment about why the rule is being removed', }, createdBy: { type: 'string', format: 'did', description: 'Optional DID of the user. Only respected when using admin auth.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#event', }, }, errors: [ { name: 'RuleNotFound', description: 'No active rule found for this URL/domain', }, ], }, }, }, ToolsOzoneSafelinkUpdateRule: { lexicon: 1, id: 'tools.ozone.safelink.updateRule', defs: { main: { type: 'procedure', description: 'Update an existing URL safety rule', input: { encoding: 'application/json', schema: { type: 'object', required: ['url', 'pattern', 'action', 'reason'], properties: { url: { type: 'string', description: 'The URL or domain to update the rule for', }, pattern: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#patternType', }, action: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#actionType', }, reason: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#reasonType', }, comment: { type: 'string', description: 'Optional comment about the update', }, createdBy: { type: 'string', format: 'did', description: 'Optional DID to credit as the creator. Only respected for admin_token authentication.', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.safelink.defs#event', }, }, errors: [ { name: 'RuleNotFound', description: 'No active rule found for this URL/domain', }, ], }, }, }, ToolsOzoneServerGetConfig: { lexicon: 1, id: 'tools.ozone.server.getConfig', defs: { main: { type: 'query', description: "Get details about ozone's server configuration.", output: { encoding: 'application/json', schema: { type: 'object', properties: { appview: { type: 'ref', ref: 'lex:tools.ozone.server.getConfig#serviceConfig', }, pds: { type: 'ref', ref: 'lex:tools.ozone.server.getConfig#serviceConfig', }, blobDivert: { type: 'ref', ref: 'lex:tools.ozone.server.getConfig#serviceConfig', }, chat: { type: 'ref', ref: 'lex:tools.ozone.server.getConfig#serviceConfig', }, viewer: { type: 'ref', ref: 'lex:tools.ozone.server.getConfig#viewerConfig', }, verifierDid: { type: 'string', format: 'did', description: 'The did of the verifier used for verification.', }, }, }, }, }, serviceConfig: { type: 'object', properties: { url: { type: 'string', format: 'uri', }, }, }, viewerConfig: { type: 'object', properties: { role: { type: 'string', knownValues: [ 'tools.ozone.team.defs#roleAdmin', 'tools.ozone.team.defs#roleModerator', 'tools.ozone.team.defs#roleTriage', 'tools.ozone.team.defs#roleVerifier', ], }, }, }, }, }, ToolsOzoneSetAddValues: { lexicon: 1, id: 'tools.ozone.set.addValues', defs: { main: { type: 'procedure', description: 'Add values to a specific set. Attempting to add values to a set that does not exist will result in an error.', input: { encoding: 'application/json', schema: { type: 'object', required: ['name', 'values'], properties: { name: { type: 'string', description: 'Name of the set to add values to', }, values: { type: 'array', minLength: 1, maxLength: 1000, items: { type: 'string', }, description: 'Array of string values to add to the set', }, }, }, }, }, }, }, ToolsOzoneSetDefs: { lexicon: 1, id: 'tools.ozone.set.defs', defs: { set: { type: 'object', required: ['name'], properties: { name: { type: 'string', minLength: 3, maxLength: 128, }, description: { type: 'string', maxGraphemes: 1024, maxLength: 10240, }, }, }, setView: { type: 'object', required: ['name', 'setSize', 'createdAt', 'updatedAt'], properties: { name: { type: 'string', minLength: 3, maxLength: 128, }, description: { type: 'string', maxGraphemes: 1024, maxLength: 10240, }, setSize: { type: 'integer', }, createdAt: { type: 'string', format: 'datetime', }, updatedAt: { type: 'string', format: 'datetime', }, }, }, }, }, ToolsOzoneSetDeleteSet: { lexicon: 1, id: 'tools.ozone.set.deleteSet', defs: { main: { type: 'procedure', description: 'Delete an entire set. Attempting to delete a set that does not exist will result in an error.', input: { encoding: 'application/json', schema: { type: 'object', required: ['name'], properties: { name: { type: 'string', description: 'Name of the set to delete', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, errors: [ { name: 'SetNotFound', description: 'set with the given name does not exist', }, ], }, }, }, ToolsOzoneSetDeleteValues: { lexicon: 1, id: 'tools.ozone.set.deleteValues', defs: { main: { type: 'procedure', description: 'Delete values from a specific set. Attempting to delete values that are not in the set will not result in an error', input: { encoding: 'application/json', schema: { type: 'object', required: ['name', 'values'], properties: { name: { type: 'string', description: 'Name of the set to delete values from', }, values: { type: 'array', minLength: 1, items: { type: 'string', }, description: 'Array of string values to delete from the set', }, }, }, }, errors: [ { name: 'SetNotFound', description: 'set with the given name does not exist', }, ], }, }, }, ToolsOzoneSetGetValues: { lexicon: 1, id: 'tools.ozone.set.getValues', defs: { main: { type: 'query', description: 'Get a specific set and its values', parameters: { type: 'params', required: ['name'], properties: { name: { type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: 1000, default: 100, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['set', 'values'], properties: { set: { type: 'ref', ref: 'lex:tools.ozone.set.defs#setView', }, values: { type: 'array', items: { type: 'string', }, }, cursor: { type: 'string', }, }, }, }, errors: [ { name: 'SetNotFound', description: 'set with the given name does not exist', }, ], }, }, }, ToolsOzoneSetQuerySets: { lexicon: 1, id: 'tools.ozone.set.querySets', defs: { main: { type: 'query', description: 'Query available sets', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, namePrefix: { type: 'string', }, sortBy: { type: 'string', enum: ['name', 'createdAt', 'updatedAt'], default: 'name', }, sortDirection: { type: 'string', default: 'asc', enum: ['asc', 'desc'], description: 'Defaults to ascending order of name field.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['sets'], properties: { sets: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.set.defs#setView', }, }, cursor: { type: 'string', }, }, }, }, }, }, }, ToolsOzoneSetUpsertSet: { lexicon: 1, id: 'tools.ozone.set.upsertSet', defs: { main: { type: 'procedure', description: 'Create or update set metadata', input: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.set.defs#set', }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.set.defs#setView', }, }, }, }, }, ToolsOzoneSettingDefs: { lexicon: 1, id: 'tools.ozone.setting.defs', defs: { option: { type: 'object', required: [ 'key', 'value', 'did', 'scope', 'createdBy', 'lastUpdatedBy', ], properties: { key: { type: 'string', format: 'nsid', }, did: { type: 'string', format: 'did', }, value: { type: 'unknown', }, description: { type: 'string', maxGraphemes: 1024, maxLength: 10240, }, createdAt: { type: 'string', format: 'datetime', }, updatedAt: { type: 'string', format: 'datetime', }, managerRole: { type: 'string', knownValues: [ 'tools.ozone.team.defs#roleModerator', 'tools.ozone.team.defs#roleTriage', 'tools.ozone.team.defs#roleAdmin', 'tools.ozone.team.defs#roleVerifier', ], }, scope: { type: 'string', knownValues: ['instance', 'personal'], }, createdBy: { type: 'string', format: 'did', }, lastUpdatedBy: { type: 'string', format: 'did', }, }, }, }, }, ToolsOzoneSettingListOptions: { lexicon: 1, id: 'tools.ozone.setting.listOptions', defs: { main: { type: 'query', description: 'List settings with optional filtering', parameters: { type: 'params', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, scope: { type: 'string', knownValues: ['instance', 'personal'], default: 'instance', }, prefix: { type: 'string', description: 'Filter keys by prefix', }, keys: { type: 'array', maxLength: 100, items: { type: 'string', format: 'nsid', }, description: 'Filter for only the specified keys. Ignored if prefix is provided', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['options'], properties: { cursor: { type: 'string', }, options: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.setting.defs#option', }, }, }, }, }, }, }, }, ToolsOzoneSettingRemoveOptions: { lexicon: 1, id: 'tools.ozone.setting.removeOptions', defs: { main: { type: 'procedure', description: 'Delete settings by key', input: { encoding: 'application/json', schema: { type: 'object', required: ['keys', 'scope'], properties: { keys: { type: 'array', minLength: 1, maxLength: 200, items: { type: 'string', format: 'nsid', }, }, scope: { type: 'string', knownValues: ['instance', 'personal'], }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', properties: {}, }, }, }, }, }, ToolsOzoneSettingUpsertOption: { lexicon: 1, id: 'tools.ozone.setting.upsertOption', defs: { main: { type: 'procedure', description: 'Create or update setting option', input: { encoding: 'application/json', schema: { type: 'object', required: ['key', 'scope', 'value'], properties: { key: { type: 'string', format: 'nsid', }, scope: { type: 'string', knownValues: ['instance', 'personal'], }, value: { type: 'unknown', }, description: { type: 'string', maxLength: 2000, }, managerRole: { type: 'string', knownValues: [ 'tools.ozone.team.defs#roleModerator', 'tools.ozone.team.defs#roleTriage', 'tools.ozone.team.defs#roleVerifier', 'tools.ozone.team.defs#roleAdmin', ], }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['option'], properties: { option: { type: 'ref', ref: 'lex:tools.ozone.setting.defs#option', }, }, }, }, }, }, }, ToolsOzoneSignatureDefs: { lexicon: 1, id: 'tools.ozone.signature.defs', defs: { sigDetail: { type: 'object', required: ['property', 'value'], properties: { property: { type: 'string', }, value: { type: 'string', }, }, }, }, }, ToolsOzoneSignatureFindCorrelation: { lexicon: 1, id: 'tools.ozone.signature.findCorrelation', defs: { main: { type: 'query', description: 'Find all correlated threat signatures between 2 or more accounts.', parameters: { type: 'params', required: ['dids'], properties: { dids: { type: 'array', items: { type: 'string', format: 'did', }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['details'], properties: { details: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.signature.defs#sigDetail', }, }, }, }, }, }, }, }, ToolsOzoneSignatureFindRelatedAccounts: { lexicon: 1, id: 'tools.ozone.signature.findRelatedAccounts', defs: { main: { type: 'query', description: 'Get accounts that share some matching threat signatures with the root account.', parameters: { type: 'params', required: ['did'], properties: { did: { type: 'string', format: 'did', }, cursor: { type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['accounts'], properties: { cursor: { type: 'string', }, accounts: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.signature.findRelatedAccounts#relatedAccount', }, }, }, }, }, }, relatedAccount: { type: 'object', required: ['account'], properties: { account: { type: 'ref', ref: 'lex:com.atproto.admin.defs#accountView', }, similarities: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.signature.defs#sigDetail', }, }, }, }, }, }, ToolsOzoneSignatureSearchAccounts: { lexicon: 1, id: 'tools.ozone.signature.searchAccounts', defs: { main: { type: 'query', description: 'Search for accounts that match one or more threat signature values.', parameters: { type: 'params', required: ['values'], properties: { values: { type: 'array', items: { type: 'string', }, }, cursor: { type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['accounts'], properties: { cursor: { type: 'string', }, accounts: { type: 'array', items: { type: 'ref', ref: 'lex:com.atproto.admin.defs#accountView', }, }, }, }, }, }, }, }, ToolsOzoneTeamAddMember: { lexicon: 1, id: 'tools.ozone.team.addMember', defs: { main: { type: 'procedure', description: 'Add a member to the ozone team. Requires admin role.', input: { encoding: 'application/json', schema: { type: 'object', required: ['did', 'role'], properties: { did: { type: 'string', format: 'did', }, role: { type: 'string', knownValues: [ 'tools.ozone.team.defs#roleAdmin', 'tools.ozone.team.defs#roleModerator', 'tools.ozone.team.defs#roleVerifier', 'tools.ozone.team.defs#roleTriage', ], }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.team.defs#member', }, }, errors: [ { name: 'MemberAlreadyExists', description: 'Member already exists in the team.', }, ], }, }, }, ToolsOzoneTeamDefs: { lexicon: 1, id: 'tools.ozone.team.defs', defs: { member: { type: 'object', required: ['did', 'role'], properties: { did: { type: 'string', format: 'did', }, disabled: { type: 'boolean', }, profile: { type: 'ref', ref: 'lex:app.bsky.actor.defs#profileViewDetailed', }, createdAt: { type: 'string', format: 'datetime', }, updatedAt: { type: 'string', format: 'datetime', }, lastUpdatedBy: { type: 'string', }, role: { type: 'string', knownValues: [ 'tools.ozone.team.defs#roleAdmin', 'tools.ozone.team.defs#roleModerator', 'tools.ozone.team.defs#roleTriage', 'tools.ozone.team.defs#roleVerifier', ], }, }, }, roleAdmin: { type: 'token', description: 'Admin role. Highest level of access, can perform all actions.', }, roleModerator: { type: 'token', description: 'Moderator role. Can perform most actions.', }, roleTriage: { type: 'token', description: 'Triage role. Mostly intended for monitoring and escalating issues.', }, roleVerifier: { type: 'token', description: 'Verifier role. Only allowed to issue verifications.', }, }, }, ToolsOzoneTeamDeleteMember: { lexicon: 1, id: 'tools.ozone.team.deleteMember', defs: { main: { type: 'procedure', description: 'Delete a member from ozone team. Requires admin role.', input: { encoding: 'application/json', schema: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, }, }, }, errors: [ { name: 'MemberNotFound', description: 'The member being deleted does not exist', }, { name: 'CannotDeleteSelf', description: 'You can not delete yourself from the team', }, ], }, }, }, ToolsOzoneTeamListMembers: { lexicon: 1, id: 'tools.ozone.team.listMembers', defs: { main: { type: 'query', description: 'List all members with access to the ozone service.', parameters: { type: 'params', properties: { q: { type: 'string', }, disabled: { type: 'boolean', }, roles: { type: 'array', items: { type: 'string', }, }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 50, }, cursor: { type: 'string', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['members'], properties: { cursor: { type: 'string', }, members: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.team.defs#member', }, }, }, }, }, }, }, }, ToolsOzoneTeamUpdateMember: { lexicon: 1, id: 'tools.ozone.team.updateMember', defs: { main: { type: 'procedure', description: 'Update a member in the ozone service. Requires admin role.', input: { encoding: 'application/json', schema: { type: 'object', required: ['did'], properties: { did: { type: 'string', format: 'did', }, disabled: { type: 'boolean', }, role: { type: 'string', knownValues: [ 'tools.ozone.team.defs#roleAdmin', 'tools.ozone.team.defs#roleModerator', 'tools.ozone.team.defs#roleVerifier', 'tools.ozone.team.defs#roleTriage', ], }, }, }, }, output: { encoding: 'application/json', schema: { type: 'ref', ref: 'lex:tools.ozone.team.defs#member', }, }, errors: [ { name: 'MemberNotFound', description: 'The member being updated does not exist in the team', }, ], }, }, }, ToolsOzoneVerificationDefs: { lexicon: 1, id: 'tools.ozone.verification.defs', defs: { verificationView: { type: 'object', description: 'Verification data for the associated subject.', required: [ 'issuer', 'uri', 'subject', 'handle', 'displayName', 'createdAt', ], properties: { issuer: { type: 'string', description: 'The user who issued this verification.', format: 'did', }, uri: { type: 'string', description: 'The AT-URI of the verification record.', format: 'at-uri', }, subject: { type: 'string', format: 'did', description: 'The subject of the verification.', }, handle: { type: 'string', description: 'Handle of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current handle matches the one at the time of verifying.', format: 'handle', }, displayName: { type: 'string', description: 'Display name of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current displayName matches the one at the time of verifying.', }, createdAt: { type: 'string', description: 'Timestamp when the verification was created.', format: 'datetime', }, revokeReason: { type: 'string', description: 'Describes the reason for revocation, also indicating that the verification is no longer valid.', }, revokedAt: { type: 'string', description: 'Timestamp when the verification was revoked.', format: 'datetime', }, revokedBy: { type: 'string', description: 'The user who revoked this verification.', format: 'did', }, subjectProfile: { type: 'union', refs: [], }, issuerProfile: { type: 'union', refs: [], }, subjectRepo: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#repoViewDetail', 'lex:tools.ozone.moderation.defs#repoViewNotFound', ], }, issuerRepo: { type: 'union', refs: [ 'lex:tools.ozone.moderation.defs#repoViewDetail', 'lex:tools.ozone.moderation.defs#repoViewNotFound', ], }, }, }, }, }, ToolsOzoneVerificationGrantVerifications: { lexicon: 1, id: 'tools.ozone.verification.grantVerifications', defs: { main: { type: 'procedure', description: 'Grant verifications to multiple subjects. Allows batch processing of up to 100 verifications at once.', input: { encoding: 'application/json', schema: { type: 'object', required: ['verifications'], properties: { verifications: { type: 'array', description: 'Array of verification requests to process', maxLength: 100, items: { type: 'ref', ref: 'lex:tools.ozone.verification.grantVerifications#verificationInput', }, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['verifications', 'failedVerifications'], properties: { verifications: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.verification.defs#verificationView', }, }, failedVerifications: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.verification.grantVerifications#grantError', }, }, }, }, }, }, verificationInput: { type: 'object', required: ['subject', 'handle', 'displayName'], properties: { subject: { type: 'string', description: 'The did of the subject being verified', format: 'did', }, handle: { type: 'string', description: 'Handle of the subject the verification applies to at the moment of verifying.', format: 'handle', }, displayName: { type: 'string', description: 'Display name of the subject the verification applies to at the moment of verifying.', }, createdAt: { type: 'string', format: 'datetime', description: 'Timestamp for verification record. Defaults to current time when not specified.', }, }, }, grantError: { type: 'object', description: 'Error object for failed verifications.', required: ['error', 'subject'], properties: { error: { type: 'string', description: 'Error message describing the reason for failure.', }, subject: { type: 'string', description: 'The did of the subject being verified', format: 'did', }, }, }, }, }, ToolsOzoneVerificationListVerifications: { lexicon: 1, id: 'tools.ozone.verification.listVerifications', defs: { main: { type: 'query', description: 'List verifications', parameters: { type: 'params', properties: { cursor: { type: 'string', description: 'Pagination cursor', }, limit: { type: 'integer', description: 'Maximum number of results to return', minimum: 1, maximum: 100, default: 50, }, createdAfter: { type: 'string', format: 'datetime', description: 'Filter to verifications created after this timestamp', }, createdBefore: { type: 'string', format: 'datetime', description: 'Filter to verifications created before this timestamp', }, issuers: { type: 'array', maxLength: 100, description: 'Filter to verifications from specific issuers', items: { type: 'string', format: 'did', }, }, subjects: { type: 'array', description: 'Filter to specific verified DIDs', maxLength: 100, items: { type: 'string', format: 'did', }, }, sortDirection: { type: 'string', description: 'Sort direction for creation date', enum: ['asc', 'desc'], default: 'desc', }, isRevoked: { type: 'boolean', description: 'Filter to verifications that are revoked or not. By default, includes both.', }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['verifications'], properties: { cursor: { type: 'string', }, verifications: { type: 'array', items: { type: 'ref', ref: 'lex:tools.ozone.verification.defs#verificationView', }, }, }, }, }, }, }, }, ToolsOzoneVerificationRevokeVerifications: { lexicon: 1, id: 'tools.ozone.verification.revokeVerifications', defs: { main: { type: 'procedure', description: 'Revoke previously granted verifications in batches of up to 100.', input: { encoding: 'application/json', schema: { type: 'object', required: ['uris'], properties: { uris: { type: 'array', description: 'Array of verification record uris to revoke', maxLength: 100, items: { type: 'string', description: 'The AT-URI of the verification record to revoke.', format: 'at-uri', }, }, revokeReason: { type: 'string', description: 'Reason for revoking the verification. This is optional and can be omitted if not needed.', maxLength: 1000, }, }, }, }, output: { encoding: 'application/json', schema: { type: 'object', required: ['revokedVerifications', 'failedRevocations'], properties: { revokedVerifications: { type: 'array', description: 'List of verification uris successfully revoked', items: { type: 'string', format: 'at-uri', }, }, failedRevocations: { type: 'array', description: "List of verification uris that couldn't be revoked, including failure reasons", items: { type: 'ref', ref: 'lex:tools.ozone.verification.revokeVerifications#revokeError', }, }, }, }, }, }, revokeError: { type: 'object', description: 'Error object for failed revocations', required: ['uri', 'error'], properties: { uri: { type: 'string', description: 'The AT-URI of the verification record that failed to revoke.', format: 'at-uri', }, error: { type: 'string', description: 'Description of the error that occurred during revocation.', }, }, }, }, }, } as const satisfies Record export const schemas = Object.values(schemaDict) satisfies LexiconDoc[] export const lexicons: Lexicons = new Lexicons(schemas) export function validate( v: unknown, id: string, hash: string, requiredType: true, ): ValidationResult export function validate( v: unknown, id: string, hash: string, requiredType?: false, ): ValidationResult export function validate( v: unknown, id: string, hash: string, requiredType?: boolean, ): ValidationResult { return (requiredType ? is$typed : maybe$typed)(v, id, hash) ? lexicons.validate(`${id}#${hash}`, v) : { success: false, error: new ValidationError( `Must be an object with "${hash === 'main' ? id : `${id}#${hash}`}" $type property`, ), } } export const ids = { AppBskyActorDefs: 'app.bsky.actor.defs', AppBskyActorGetPreferences: 'app.bsky.actor.getPreferences', AppBskyActorGetProfile: 'app.bsky.actor.getProfile', AppBskyActorGetProfiles: 'app.bsky.actor.getProfiles', AppBskyActorGetSuggestions: 'app.bsky.actor.getSuggestions', AppBskyActorProfile: 'app.bsky.actor.profile', AppBskyActorPutPreferences: 'app.bsky.actor.putPreferences', AppBskyActorSearchActors: 'app.bsky.actor.searchActors', AppBskyActorSearchActorsTypeahead: 'app.bsky.actor.searchActorsTypeahead', AppBskyActorStatus: 'app.bsky.actor.status', AppBskyAgeassuranceBegin: 'app.bsky.ageassurance.begin', AppBskyAgeassuranceDefs: 'app.bsky.ageassurance.defs', AppBskyAgeassuranceGetConfig: 'app.bsky.ageassurance.getConfig', AppBskyAgeassuranceGetState: 'app.bsky.ageassurance.getState', AppBskyBookmarkCreateBookmark: 'app.bsky.bookmark.createBookmark', AppBskyBookmarkDefs: 'app.bsky.bookmark.defs', AppBskyBookmarkDeleteBookmark: 'app.bsky.bookmark.deleteBookmark', AppBskyBookmarkGetBookmarks: 'app.bsky.bookmark.getBookmarks', AppBskyContactDefs: 'app.bsky.contact.defs', AppBskyContactDismissMatch: 'app.bsky.contact.dismissMatch', AppBskyContactGetMatches: 'app.bsky.contact.getMatches', AppBskyContactGetSyncStatus: 'app.bsky.contact.getSyncStatus', AppBskyContactImportContacts: 'app.bsky.contact.importContacts', AppBskyContactRemoveData: 'app.bsky.contact.removeData', AppBskyContactSendNotification: 'app.bsky.contact.sendNotification', AppBskyContactStartPhoneVerification: 'app.bsky.contact.startPhoneVerification', AppBskyContactVerifyPhone: 'app.bsky.contact.verifyPhone', AppBskyDraftCreateDraft: 'app.bsky.draft.createDraft', AppBskyDraftDefs: 'app.bsky.draft.defs', AppBskyDraftDeleteDraft: 'app.bsky.draft.deleteDraft', AppBskyDraftGetDrafts: 'app.bsky.draft.getDrafts', AppBskyDraftUpdateDraft: 'app.bsky.draft.updateDraft', AppBskyEmbedDefs: 'app.bsky.embed.defs', AppBskyEmbedExternal: 'app.bsky.embed.external', AppBskyEmbedImages: 'app.bsky.embed.images', AppBskyEmbedRecord: 'app.bsky.embed.record', AppBskyEmbedRecordWithMedia: 'app.bsky.embed.recordWithMedia', AppBskyEmbedVideo: 'app.bsky.embed.video', AppBskyFeedDefs: 'app.bsky.feed.defs', AppBskyFeedDescribeFeedGenerator: 'app.bsky.feed.describeFeedGenerator', AppBskyFeedGenerator: 'app.bsky.feed.generator', AppBskyFeedGetActorFeeds: 'app.bsky.feed.getActorFeeds', AppBskyFeedGetActorLikes: 'app.bsky.feed.getActorLikes', AppBskyFeedGetAuthorFeed: 'app.bsky.feed.getAuthorFeed', AppBskyFeedGetFeed: 'app.bsky.feed.getFeed', AppBskyFeedGetFeedGenerator: 'app.bsky.feed.getFeedGenerator', AppBskyFeedGetFeedGenerators: 'app.bsky.feed.getFeedGenerators', AppBskyFeedGetFeedSkeleton: 'app.bsky.feed.getFeedSkeleton', AppBskyFeedGetLikes: 'app.bsky.feed.getLikes', AppBskyFeedGetListFeed: 'app.bsky.feed.getListFeed', AppBskyFeedGetPostThread: 'app.bsky.feed.getPostThread', AppBskyFeedGetPosts: 'app.bsky.feed.getPosts', AppBskyFeedGetQuotes: 'app.bsky.feed.getQuotes', AppBskyFeedGetRepostedBy: 'app.bsky.feed.getRepostedBy', AppBskyFeedGetSuggestedFeeds: 'app.bsky.feed.getSuggestedFeeds', AppBskyFeedGetTimeline: 'app.bsky.feed.getTimeline', AppBskyFeedLike: 'app.bsky.feed.like', AppBskyFeedPost: 'app.bsky.feed.post', AppBskyFeedPostgate: 'app.bsky.feed.postgate', AppBskyFeedRepost: 'app.bsky.feed.repost', AppBskyFeedSearchPosts: 'app.bsky.feed.searchPosts', AppBskyFeedSendInteractions: 'app.bsky.feed.sendInteractions', AppBskyFeedThreadgate: 'app.bsky.feed.threadgate', AppBskyGraphBlock: 'app.bsky.graph.block', AppBskyGraphDefs: 'app.bsky.graph.defs', AppBskyGraphFollow: 'app.bsky.graph.follow', AppBskyGraphGetActorStarterPacks: 'app.bsky.graph.getActorStarterPacks', AppBskyGraphGetBlocks: 'app.bsky.graph.getBlocks', AppBskyGraphGetFollowers: 'app.bsky.graph.getFollowers', AppBskyGraphGetFollows: 'app.bsky.graph.getFollows', AppBskyGraphGetKnownFollowers: 'app.bsky.graph.getKnownFollowers', AppBskyGraphGetList: 'app.bsky.graph.getList', AppBskyGraphGetListBlocks: 'app.bsky.graph.getListBlocks', AppBskyGraphGetListMutes: 'app.bsky.graph.getListMutes', AppBskyGraphGetLists: 'app.bsky.graph.getLists', AppBskyGraphGetListsWithMembership: 'app.bsky.graph.getListsWithMembership', AppBskyGraphGetMutes: 'app.bsky.graph.getMutes', AppBskyGraphGetRelationships: 'app.bsky.graph.getRelationships', AppBskyGraphGetStarterPack: 'app.bsky.graph.getStarterPack', AppBskyGraphGetStarterPacks: 'app.bsky.graph.getStarterPacks', AppBskyGraphGetStarterPacksWithMembership: 'app.bsky.graph.getStarterPacksWithMembership', AppBskyGraphGetSuggestedFollowsByActor: 'app.bsky.graph.getSuggestedFollowsByActor', AppBskyGraphList: 'app.bsky.graph.list', AppBskyGraphListblock: 'app.bsky.graph.listblock', AppBskyGraphListitem: 'app.bsky.graph.listitem', AppBskyGraphMuteActor: 'app.bsky.graph.muteActor', AppBskyGraphMuteActorList: 'app.bsky.graph.muteActorList', AppBskyGraphMuteThread: 'app.bsky.graph.muteThread', AppBskyGraphSearchStarterPacks: 'app.bsky.graph.searchStarterPacks', AppBskyGraphStarterpack: 'app.bsky.graph.starterpack', AppBskyGraphUnmuteActor: 'app.bsky.graph.unmuteActor', AppBskyGraphUnmuteActorList: 'app.bsky.graph.unmuteActorList', AppBskyGraphUnmuteThread: 'app.bsky.graph.unmuteThread', AppBskyGraphVerification: 'app.bsky.graph.verification', AppBskyLabelerDefs: 'app.bsky.labeler.defs', AppBskyLabelerGetServices: 'app.bsky.labeler.getServices', AppBskyLabelerService: 'app.bsky.labeler.service', AppBskyNotificationDeclaration: 'app.bsky.notification.declaration', AppBskyNotificationDefs: 'app.bsky.notification.defs', AppBskyNotificationGetPreferences: 'app.bsky.notification.getPreferences', AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount', AppBskyNotificationListActivitySubscriptions: 'app.bsky.notification.listActivitySubscriptions', AppBskyNotificationListNotifications: 'app.bsky.notification.listNotifications', AppBskyNotificationPutActivitySubscription: 'app.bsky.notification.putActivitySubscription', AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences', AppBskyNotificationPutPreferencesV2: 'app.bsky.notification.putPreferencesV2', AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush', AppBskyNotificationUnregisterPush: 'app.bsky.notification.unregisterPush', AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen', AppBskyRichtextFacet: 'app.bsky.richtext.facet', AppBskyUnspeccedDefs: 'app.bsky.unspecced.defs', AppBskyUnspeccedGetAgeAssuranceState: 'app.bsky.unspecced.getAgeAssuranceState', AppBskyUnspeccedGetConfig: 'app.bsky.unspecced.getConfig', AppBskyUnspeccedGetOnboardingSuggestedStarterPacks: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks', AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton', AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton: 'app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton', AppBskyUnspeccedGetPopularFeedGenerators: 'app.bsky.unspecced.getPopularFeedGenerators', AppBskyUnspeccedGetPostThreadOtherV2: 'app.bsky.unspecced.getPostThreadOtherV2', AppBskyUnspeccedGetPostThreadV2: 'app.bsky.unspecced.getPostThreadV2', AppBskyUnspeccedGetSuggestedFeeds: 'app.bsky.unspecced.getSuggestedFeeds', AppBskyUnspeccedGetSuggestedFeedsSkeleton: 'app.bsky.unspecced.getSuggestedFeedsSkeleton', AppBskyUnspeccedGetSuggestedOnboardingUsers: 'app.bsky.unspecced.getSuggestedOnboardingUsers', AppBskyUnspeccedGetSuggestedStarterPacks: 'app.bsky.unspecced.getSuggestedStarterPacks', AppBskyUnspeccedGetSuggestedStarterPacksSkeleton: 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton', AppBskyUnspeccedGetSuggestedUsers: 'app.bsky.unspecced.getSuggestedUsers', AppBskyUnspeccedGetSuggestedUsersSkeleton: 'app.bsky.unspecced.getSuggestedUsersSkeleton', AppBskyUnspeccedGetSuggestionsSkeleton: 'app.bsky.unspecced.getSuggestionsSkeleton', AppBskyUnspeccedGetTaggedSuggestions: 'app.bsky.unspecced.getTaggedSuggestions', AppBskyUnspeccedGetTrendingTopics: 'app.bsky.unspecced.getTrendingTopics', AppBskyUnspeccedGetTrends: 'app.bsky.unspecced.getTrends', AppBskyUnspeccedGetTrendsSkeleton: 'app.bsky.unspecced.getTrendsSkeleton', AppBskyUnspeccedInitAgeAssurance: 'app.bsky.unspecced.initAgeAssurance', AppBskyUnspeccedSearchActorsSkeleton: 'app.bsky.unspecced.searchActorsSkeleton', AppBskyUnspeccedSearchPostsSkeleton: 'app.bsky.unspecced.searchPostsSkeleton', AppBskyUnspeccedSearchStarterPacksSkeleton: 'app.bsky.unspecced.searchStarterPacksSkeleton', AppBskyVideoDefs: 'app.bsky.video.defs', AppBskyVideoGetJobStatus: 'app.bsky.video.getJobStatus', AppBskyVideoGetUploadLimits: 'app.bsky.video.getUploadLimits', AppBskyVideoUploadVideo: 'app.bsky.video.uploadVideo', ChatBskyActorDeclaration: 'chat.bsky.actor.declaration', ChatBskyActorDefs: 'chat.bsky.actor.defs', ChatBskyActorDeleteAccount: 'chat.bsky.actor.deleteAccount', ChatBskyActorExportAccountData: 'chat.bsky.actor.exportAccountData', ChatBskyConvoAcceptConvo: 'chat.bsky.convo.acceptConvo', ChatBskyConvoAddReaction: 'chat.bsky.convo.addReaction', ChatBskyConvoDefs: 'chat.bsky.convo.defs', ChatBskyConvoDeleteMessageForSelf: 'chat.bsky.convo.deleteMessageForSelf', ChatBskyConvoGetConvo: 'chat.bsky.convo.getConvo', ChatBskyConvoGetConvoAvailability: 'chat.bsky.convo.getConvoAvailability', ChatBskyConvoGetConvoForMembers: 'chat.bsky.convo.getConvoForMembers', ChatBskyConvoGetLog: 'chat.bsky.convo.getLog', ChatBskyConvoGetMessages: 'chat.bsky.convo.getMessages', ChatBskyConvoLeaveConvo: 'chat.bsky.convo.leaveConvo', ChatBskyConvoListConvos: 'chat.bsky.convo.listConvos', ChatBskyConvoMuteConvo: 'chat.bsky.convo.muteConvo', ChatBskyConvoRemoveReaction: 'chat.bsky.convo.removeReaction', ChatBskyConvoSendMessage: 'chat.bsky.convo.sendMessage', ChatBskyConvoSendMessageBatch: 'chat.bsky.convo.sendMessageBatch', ChatBskyConvoUnmuteConvo: 'chat.bsky.convo.unmuteConvo', ChatBskyConvoUpdateAllRead: 'chat.bsky.convo.updateAllRead', ChatBskyConvoUpdateRead: 'chat.bsky.convo.updateRead', ChatBskyModerationGetActorMetadata: 'chat.bsky.moderation.getActorMetadata', ChatBskyModerationGetMessageContext: 'chat.bsky.moderation.getMessageContext', ChatBskyModerationUpdateActorAccess: 'chat.bsky.moderation.updateActorAccess', ComAtprotoAdminDefs: 'com.atproto.admin.defs', ComAtprotoAdminDeleteAccount: 'com.atproto.admin.deleteAccount', ComAtprotoAdminDisableAccountInvites: 'com.atproto.admin.disableAccountInvites', ComAtprotoAdminDisableInviteCodes: 'com.atproto.admin.disableInviteCodes', ComAtprotoAdminEnableAccountInvites: 'com.atproto.admin.enableAccountInvites', ComAtprotoAdminGetAccountInfo: 'com.atproto.admin.getAccountInfo', ComAtprotoAdminGetAccountInfos: 'com.atproto.admin.getAccountInfos', ComAtprotoAdminGetInviteCodes: 'com.atproto.admin.getInviteCodes', ComAtprotoAdminGetSubjectStatus: 'com.atproto.admin.getSubjectStatus', ComAtprotoAdminSearchAccounts: 'com.atproto.admin.searchAccounts', ComAtprotoAdminSendEmail: 'com.atproto.admin.sendEmail', ComAtprotoAdminUpdateAccountEmail: 'com.atproto.admin.updateAccountEmail', ComAtprotoAdminUpdateAccountHandle: 'com.atproto.admin.updateAccountHandle', ComAtprotoAdminUpdateAccountPassword: 'com.atproto.admin.updateAccountPassword', ComAtprotoAdminUpdateAccountSigningKey: 'com.atproto.admin.updateAccountSigningKey', ComAtprotoAdminUpdateSubjectStatus: 'com.atproto.admin.updateSubjectStatus', ComAtprotoIdentityDefs: 'com.atproto.identity.defs', ComAtprotoIdentityGetRecommendedDidCredentials: 'com.atproto.identity.getRecommendedDidCredentials', ComAtprotoIdentityRefreshIdentity: 'com.atproto.identity.refreshIdentity', ComAtprotoIdentityRequestPlcOperationSignature: 'com.atproto.identity.requestPlcOperationSignature', ComAtprotoIdentityResolveDid: 'com.atproto.identity.resolveDid', ComAtprotoIdentityResolveHandle: 'com.atproto.identity.resolveHandle', ComAtprotoIdentityResolveIdentity: 'com.atproto.identity.resolveIdentity', ComAtprotoIdentitySignPlcOperation: 'com.atproto.identity.signPlcOperation', ComAtprotoIdentitySubmitPlcOperation: 'com.atproto.identity.submitPlcOperation', ComAtprotoIdentityUpdateHandle: 'com.atproto.identity.updateHandle', ComAtprotoLabelDefs: 'com.atproto.label.defs', ComAtprotoLabelQueryLabels: 'com.atproto.label.queryLabels', ComAtprotoLabelSubscribeLabels: 'com.atproto.label.subscribeLabels', ComAtprotoLexiconResolveLexicon: 'com.atproto.lexicon.resolveLexicon', ComAtprotoLexiconSchema: 'com.atproto.lexicon.schema', ComAtprotoModerationCreateReport: 'com.atproto.moderation.createReport', ComAtprotoModerationDefs: 'com.atproto.moderation.defs', ComAtprotoRepoApplyWrites: 'com.atproto.repo.applyWrites', ComAtprotoRepoCreateRecord: 'com.atproto.repo.createRecord', ComAtprotoRepoDefs: 'com.atproto.repo.defs', ComAtprotoRepoDeleteRecord: 'com.atproto.repo.deleteRecord', ComAtprotoRepoDescribeRepo: 'com.atproto.repo.describeRepo', ComAtprotoRepoGetRecord: 'com.atproto.repo.getRecord', ComAtprotoRepoImportRepo: 'com.atproto.repo.importRepo', ComAtprotoRepoListMissingBlobs: 'com.atproto.repo.listMissingBlobs', ComAtprotoRepoListRecords: 'com.atproto.repo.listRecords', ComAtprotoRepoPutRecord: 'com.atproto.repo.putRecord', ComAtprotoRepoStrongRef: 'com.atproto.repo.strongRef', ComAtprotoRepoUploadBlob: 'com.atproto.repo.uploadBlob', ComAtprotoServerActivateAccount: 'com.atproto.server.activateAccount', ComAtprotoServerCheckAccountStatus: 'com.atproto.server.checkAccountStatus', ComAtprotoServerConfirmEmail: 'com.atproto.server.confirmEmail', ComAtprotoServerCreateAccount: 'com.atproto.server.createAccount', ComAtprotoServerCreateAppPassword: 'com.atproto.server.createAppPassword', ComAtprotoServerCreateInviteCode: 'com.atproto.server.createInviteCode', ComAtprotoServerCreateInviteCodes: 'com.atproto.server.createInviteCodes', ComAtprotoServerCreateSession: 'com.atproto.server.createSession', ComAtprotoServerDeactivateAccount: 'com.atproto.server.deactivateAccount', ComAtprotoServerDefs: 'com.atproto.server.defs', ComAtprotoServerDeleteAccount: 'com.atproto.server.deleteAccount', ComAtprotoServerDeleteSession: 'com.atproto.server.deleteSession', ComAtprotoServerDescribeServer: 'com.atproto.server.describeServer', ComAtprotoServerGetAccountInviteCodes: 'com.atproto.server.getAccountInviteCodes', ComAtprotoServerGetServiceAuth: 'com.atproto.server.getServiceAuth', ComAtprotoServerGetSession: 'com.atproto.server.getSession', ComAtprotoServerListAppPasswords: 'com.atproto.server.listAppPasswords', ComAtprotoServerRefreshSession: 'com.atproto.server.refreshSession', ComAtprotoServerRequestAccountDelete: 'com.atproto.server.requestAccountDelete', ComAtprotoServerRequestEmailConfirmation: 'com.atproto.server.requestEmailConfirmation', ComAtprotoServerRequestEmailUpdate: 'com.atproto.server.requestEmailUpdate', ComAtprotoServerRequestPasswordReset: 'com.atproto.server.requestPasswordReset', ComAtprotoServerReserveSigningKey: 'com.atproto.server.reserveSigningKey', ComAtprotoServerResetPassword: 'com.atproto.server.resetPassword', ComAtprotoServerRevokeAppPassword: 'com.atproto.server.revokeAppPassword', ComAtprotoServerUpdateEmail: 'com.atproto.server.updateEmail', ComAtprotoSyncDefs: 'com.atproto.sync.defs', ComAtprotoSyncGetBlob: 'com.atproto.sync.getBlob', ComAtprotoSyncGetBlocks: 'com.atproto.sync.getBlocks', ComAtprotoSyncGetCheckout: 'com.atproto.sync.getCheckout', ComAtprotoSyncGetHead: 'com.atproto.sync.getHead', ComAtprotoSyncGetHostStatus: 'com.atproto.sync.getHostStatus', ComAtprotoSyncGetLatestCommit: 'com.atproto.sync.getLatestCommit', ComAtprotoSyncGetRecord: 'com.atproto.sync.getRecord', ComAtprotoSyncGetRepo: 'com.atproto.sync.getRepo', ComAtprotoSyncGetRepoStatus: 'com.atproto.sync.getRepoStatus', ComAtprotoSyncListBlobs: 'com.atproto.sync.listBlobs', ComAtprotoSyncListHosts: 'com.atproto.sync.listHosts', ComAtprotoSyncListRepos: 'com.atproto.sync.listRepos', ComAtprotoSyncListReposByCollection: 'com.atproto.sync.listReposByCollection', ComAtprotoSyncNotifyOfUpdate: 'com.atproto.sync.notifyOfUpdate', ComAtprotoSyncRequestCrawl: 'com.atproto.sync.requestCrawl', ComAtprotoSyncSubscribeRepos: 'com.atproto.sync.subscribeRepos', ComAtprotoTempAddReservedHandle: 'com.atproto.temp.addReservedHandle', ComAtprotoTempCheckHandleAvailability: 'com.atproto.temp.checkHandleAvailability', ComAtprotoTempCheckSignupQueue: 'com.atproto.temp.checkSignupQueue', ComAtprotoTempDereferenceScope: 'com.atproto.temp.dereferenceScope', ComAtprotoTempFetchLabels: 'com.atproto.temp.fetchLabels', ComAtprotoTempRequestPhoneVerification: 'com.atproto.temp.requestPhoneVerification', ComAtprotoTempRevokeAccountCredentials: 'com.atproto.temp.revokeAccountCredentials', ComGermnetworkDeclaration: 'com.germnetwork.declaration', ToolsOzoneCommunicationCreateTemplate: 'tools.ozone.communication.createTemplate', ToolsOzoneCommunicationDefs: 'tools.ozone.communication.defs', ToolsOzoneCommunicationDeleteTemplate: 'tools.ozone.communication.deleteTemplate', ToolsOzoneCommunicationListTemplates: 'tools.ozone.communication.listTemplates', ToolsOzoneCommunicationUpdateTemplate: 'tools.ozone.communication.updateTemplate', ToolsOzoneHostingGetAccountHistory: 'tools.ozone.hosting.getAccountHistory', ToolsOzoneModerationCancelScheduledActions: 'tools.ozone.moderation.cancelScheduledActions', ToolsOzoneModerationDefs: 'tools.ozone.moderation.defs', ToolsOzoneModerationEmitEvent: 'tools.ozone.moderation.emitEvent', ToolsOzoneModerationGetAccountTimeline: 'tools.ozone.moderation.getAccountTimeline', ToolsOzoneModerationGetEvent: 'tools.ozone.moderation.getEvent', ToolsOzoneModerationGetRecord: 'tools.ozone.moderation.getRecord', ToolsOzoneModerationGetRecords: 'tools.ozone.moderation.getRecords', ToolsOzoneModerationGetRepo: 'tools.ozone.moderation.getRepo', ToolsOzoneModerationGetReporterStats: 'tools.ozone.moderation.getReporterStats', ToolsOzoneModerationGetRepos: 'tools.ozone.moderation.getRepos', ToolsOzoneModerationGetSubjects: 'tools.ozone.moderation.getSubjects', ToolsOzoneModerationListScheduledActions: 'tools.ozone.moderation.listScheduledActions', ToolsOzoneModerationQueryEvents: 'tools.ozone.moderation.queryEvents', ToolsOzoneModerationQueryStatuses: 'tools.ozone.moderation.queryStatuses', ToolsOzoneModerationScheduleAction: 'tools.ozone.moderation.scheduleAction', ToolsOzoneModerationSearchRepos: 'tools.ozone.moderation.searchRepos', ToolsOzoneReportDefs: 'tools.ozone.report.defs', ToolsOzoneSafelinkAddRule: 'tools.ozone.safelink.addRule', ToolsOzoneSafelinkDefs: 'tools.ozone.safelink.defs', ToolsOzoneSafelinkQueryEvents: 'tools.ozone.safelink.queryEvents', ToolsOzoneSafelinkQueryRules: 'tools.ozone.safelink.queryRules', ToolsOzoneSafelinkRemoveRule: 'tools.ozone.safelink.removeRule', ToolsOzoneSafelinkUpdateRule: 'tools.ozone.safelink.updateRule', ToolsOzoneServerGetConfig: 'tools.ozone.server.getConfig', ToolsOzoneSetAddValues: 'tools.ozone.set.addValues', ToolsOzoneSetDefs: 'tools.ozone.set.defs', ToolsOzoneSetDeleteSet: 'tools.ozone.set.deleteSet', ToolsOzoneSetDeleteValues: 'tools.ozone.set.deleteValues', ToolsOzoneSetGetValues: 'tools.ozone.set.getValues', ToolsOzoneSetQuerySets: 'tools.ozone.set.querySets', ToolsOzoneSetUpsertSet: 'tools.ozone.set.upsertSet', ToolsOzoneSettingDefs: 'tools.ozone.setting.defs', ToolsOzoneSettingListOptions: 'tools.ozone.setting.listOptions', ToolsOzoneSettingRemoveOptions: 'tools.ozone.setting.removeOptions', ToolsOzoneSettingUpsertOption: 'tools.ozone.setting.upsertOption', ToolsOzoneSignatureDefs: 'tools.ozone.signature.defs', ToolsOzoneSignatureFindCorrelation: 'tools.ozone.signature.findCorrelation', ToolsOzoneSignatureFindRelatedAccounts: 'tools.ozone.signature.findRelatedAccounts', ToolsOzoneSignatureSearchAccounts: 'tools.ozone.signature.searchAccounts', ToolsOzoneTeamAddMember: 'tools.ozone.team.addMember', ToolsOzoneTeamDefs: 'tools.ozone.team.defs', ToolsOzoneTeamDeleteMember: 'tools.ozone.team.deleteMember', ToolsOzoneTeamListMembers: 'tools.ozone.team.listMembers', ToolsOzoneTeamUpdateMember: 'tools.ozone.team.updateMember', ToolsOzoneVerificationDefs: 'tools.ozone.verification.defs', ToolsOzoneVerificationGrantVerifications: 'tools.ozone.verification.grantVerifications', ToolsOzoneVerificationListVerifications: 'tools.ozone.verification.listVerifications', ToolsOzoneVerificationRevokeVerifications: 'tools.ozone.verification.revokeVerifications', } as const ================================================ FILE: packages/api/src/client/types/app/bsky/actor/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as AppBskyGraphDefs from '../graph/defs.js' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' import type * as AppBskyNotificationDefs from '../notification/defs.js' import type * as AppBskyFeedThreadgate from '../feed/threadgate.js' import type * as AppBskyFeedPostgate from '../feed/postgate.js' import type * as AppBskyEmbedExternal from '../embed/external.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.defs' export interface ProfileViewBasic { $type?: 'app.bsky.actor.defs#profileViewBasic' did: string handle: string displayName?: string pronouns?: string avatar?: string associated?: ProfileAssociated viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] createdAt?: string verification?: VerificationState status?: StatusView /** Debug information for internal development */ debug?: { [_ in string]: unknown } } const hashProfileViewBasic = 'profileViewBasic' export function isProfileViewBasic(v: V) { return is$typed(v, id, hashProfileViewBasic) } export function validateProfileViewBasic(v: V) { return validate(v, id, hashProfileViewBasic) } export interface ProfileView { $type?: 'app.bsky.actor.defs#profileView' did: string handle: string displayName?: string pronouns?: string description?: string avatar?: string associated?: ProfileAssociated indexedAt?: string createdAt?: string viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] verification?: VerificationState status?: StatusView /** Debug information for internal development */ debug?: { [_ in string]: unknown } } const hashProfileView = 'profileView' export function isProfileView(v: V) { return is$typed(v, id, hashProfileView) } export function validateProfileView(v: V) { return validate(v, id, hashProfileView) } export interface ProfileViewDetailed { $type?: 'app.bsky.actor.defs#profileViewDetailed' did: string handle: string displayName?: string description?: string pronouns?: string website?: string avatar?: string banner?: string followersCount?: number followsCount?: number postsCount?: number associated?: ProfileAssociated joinedViaStarterPack?: AppBskyGraphDefs.StarterPackViewBasic indexedAt?: string createdAt?: string viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] pinnedPost?: ComAtprotoRepoStrongRef.Main verification?: VerificationState status?: StatusView /** Debug information for internal development */ debug?: { [_ in string]: unknown } } const hashProfileViewDetailed = 'profileViewDetailed' export function isProfileViewDetailed(v: V) { return is$typed(v, id, hashProfileViewDetailed) } export function validateProfileViewDetailed(v: V) { return validate(v, id, hashProfileViewDetailed) } export interface ProfileAssociated { $type?: 'app.bsky.actor.defs#profileAssociated' lists?: number feedgens?: number starterPacks?: number labeler?: boolean chat?: ProfileAssociatedChat activitySubscription?: ProfileAssociatedActivitySubscription germ?: ProfileAssociatedGerm } const hashProfileAssociated = 'profileAssociated' export function isProfileAssociated(v: V) { return is$typed(v, id, hashProfileAssociated) } export function validateProfileAssociated(v: V) { return validate(v, id, hashProfileAssociated) } export interface ProfileAssociatedChat { $type?: 'app.bsky.actor.defs#profileAssociatedChat' allowIncoming: 'all' | 'none' | 'following' | (string & {}) } const hashProfileAssociatedChat = 'profileAssociatedChat' export function isProfileAssociatedChat(v: V) { return is$typed(v, id, hashProfileAssociatedChat) } export function validateProfileAssociatedChat(v: V) { return validate(v, id, hashProfileAssociatedChat) } export interface ProfileAssociatedGerm { $type?: 'app.bsky.actor.defs#profileAssociatedGerm' messageMeUrl: string showButtonTo: 'usersIFollow' | 'everyone' | (string & {}) } const hashProfileAssociatedGerm = 'profileAssociatedGerm' export function isProfileAssociatedGerm(v: V) { return is$typed(v, id, hashProfileAssociatedGerm) } export function validateProfileAssociatedGerm(v: V) { return validate(v, id, hashProfileAssociatedGerm) } export interface ProfileAssociatedActivitySubscription { $type?: 'app.bsky.actor.defs#profileAssociatedActivitySubscription' allowSubscriptions: 'followers' | 'mutuals' | 'none' | (string & {}) } const hashProfileAssociatedActivitySubscription = 'profileAssociatedActivitySubscription' export function isProfileAssociatedActivitySubscription(v: V) { return is$typed(v, id, hashProfileAssociatedActivitySubscription) } export function validateProfileAssociatedActivitySubscription(v: V) { return validate( v, id, hashProfileAssociatedActivitySubscription, ) } /** Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests. */ export interface ViewerState { $type?: 'app.bsky.actor.defs#viewerState' muted?: boolean mutedByList?: AppBskyGraphDefs.ListViewBasic blockedBy?: boolean blocking?: string blockingByList?: AppBskyGraphDefs.ListViewBasic following?: string followedBy?: string knownFollowers?: KnownFollowers activitySubscription?: AppBskyNotificationDefs.ActivitySubscription } const hashViewerState = 'viewerState' export function isViewerState(v: V) { return is$typed(v, id, hashViewerState) } export function validateViewerState(v: V) { return validate(v, id, hashViewerState) } /** The subject's followers whom you also follow */ export interface KnownFollowers { $type?: 'app.bsky.actor.defs#knownFollowers' count: number followers: ProfileViewBasic[] } const hashKnownFollowers = 'knownFollowers' export function isKnownFollowers(v: V) { return is$typed(v, id, hashKnownFollowers) } export function validateKnownFollowers(v: V) { return validate(v, id, hashKnownFollowers) } /** Represents the verification information about the user this object is attached to. */ export interface VerificationState { $type?: 'app.bsky.actor.defs#verificationState' /** All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included. */ verifications: VerificationView[] /** The user's status as a verified account. */ verifiedStatus: 'valid' | 'invalid' | 'none' | (string & {}) /** The user's status as a trusted verifier. */ trustedVerifierStatus: 'valid' | 'invalid' | 'none' | (string & {}) } const hashVerificationState = 'verificationState' export function isVerificationState(v: V) { return is$typed(v, id, hashVerificationState) } export function validateVerificationState(v: V) { return validate(v, id, hashVerificationState) } /** An individual verification for an associated subject. */ export interface VerificationView { $type?: 'app.bsky.actor.defs#verificationView' /** The user who issued this verification. */ issuer: string /** The AT-URI of the verification record. */ uri: string /** True if the verification passes validation, otherwise false. */ isValid: boolean /** Timestamp when the verification was created. */ createdAt: string } const hashVerificationView = 'verificationView' export function isVerificationView(v: V) { return is$typed(v, id, hashVerificationView) } export function validateVerificationView(v: V) { return validate(v, id, hashVerificationView) } export type Preferences = ( | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | { $type: string } )[] export interface AdultContentPref { $type?: 'app.bsky.actor.defs#adultContentPref' enabled: boolean } const hashAdultContentPref = 'adultContentPref' export function isAdultContentPref(v: V) { return is$typed(v, id, hashAdultContentPref) } export function validateAdultContentPref(v: V) { return validate(v, id, hashAdultContentPref) } export interface ContentLabelPref { $type?: 'app.bsky.actor.defs#contentLabelPref' /** Which labeler does this preference apply to? If undefined, applies globally. */ labelerDid?: string label: string visibility: 'ignore' | 'show' | 'warn' | 'hide' | (string & {}) } const hashContentLabelPref = 'contentLabelPref' export function isContentLabelPref(v: V) { return is$typed(v, id, hashContentLabelPref) } export function validateContentLabelPref(v: V) { return validate(v, id, hashContentLabelPref) } export interface SavedFeed { $type?: 'app.bsky.actor.defs#savedFeed' id: string type: 'feed' | 'list' | 'timeline' | (string & {}) value: string pinned: boolean } const hashSavedFeed = 'savedFeed' export function isSavedFeed(v: V) { return is$typed(v, id, hashSavedFeed) } export function validateSavedFeed(v: V) { return validate(v, id, hashSavedFeed) } export interface SavedFeedsPrefV2 { $type?: 'app.bsky.actor.defs#savedFeedsPrefV2' items: SavedFeed[] } const hashSavedFeedsPrefV2 = 'savedFeedsPrefV2' export function isSavedFeedsPrefV2(v: V) { return is$typed(v, id, hashSavedFeedsPrefV2) } export function validateSavedFeedsPrefV2(v: V) { return validate(v, id, hashSavedFeedsPrefV2) } export interface SavedFeedsPref { $type?: 'app.bsky.actor.defs#savedFeedsPref' pinned: string[] saved: string[] timelineIndex?: number } const hashSavedFeedsPref = 'savedFeedsPref' export function isSavedFeedsPref(v: V) { return is$typed(v, id, hashSavedFeedsPref) } export function validateSavedFeedsPref(v: V) { return validate(v, id, hashSavedFeedsPref) } export interface PersonalDetailsPref { $type?: 'app.bsky.actor.defs#personalDetailsPref' /** The birth date of account owner. */ birthDate?: string } const hashPersonalDetailsPref = 'personalDetailsPref' export function isPersonalDetailsPref(v: V) { return is$typed(v, id, hashPersonalDetailsPref) } export function validatePersonalDetailsPref(v: V) { return validate(v, id, hashPersonalDetailsPref) } /** Read-only preference containing value(s) inferred from the user's declared birthdate. Absence of this preference object in the response indicates that the user has not made a declaration. */ export interface DeclaredAgePref { $type?: 'app.bsky.actor.defs#declaredAgePref' /** Indicates if the user has declared that they are over 13 years of age. */ isOverAge13?: boolean /** Indicates if the user has declared that they are over 16 years of age. */ isOverAge16?: boolean /** Indicates if the user has declared that they are over 18 years of age. */ isOverAge18?: boolean } const hashDeclaredAgePref = 'declaredAgePref' export function isDeclaredAgePref(v: V) { return is$typed(v, id, hashDeclaredAgePref) } export function validateDeclaredAgePref(v: V) { return validate(v, id, hashDeclaredAgePref) } export interface FeedViewPref { $type?: 'app.bsky.actor.defs#feedViewPref' /** The URI of the feed, or an identifier which describes the feed. */ feed: string /** Hide replies in the feed. */ hideReplies?: boolean /** Hide replies in the feed if they are not by followed users. */ hideRepliesByUnfollowed: boolean /** Hide replies in the feed if they do not have this number of likes. */ hideRepliesByLikeCount?: number /** Hide reposts in the feed. */ hideReposts?: boolean /** Hide quote posts in the feed. */ hideQuotePosts?: boolean } const hashFeedViewPref = 'feedViewPref' export function isFeedViewPref(v: V) { return is$typed(v, id, hashFeedViewPref) } export function validateFeedViewPref(v: V) { return validate(v, id, hashFeedViewPref) } export interface ThreadViewPref { $type?: 'app.bsky.actor.defs#threadViewPref' /** Sorting mode for threads. */ sort?: | 'oldest' | 'newest' | 'most-likes' | 'random' | 'hotness' | (string & {}) } const hashThreadViewPref = 'threadViewPref' export function isThreadViewPref(v: V) { return is$typed(v, id, hashThreadViewPref) } export function validateThreadViewPref(v: V) { return validate(v, id, hashThreadViewPref) } export interface InterestsPref { $type?: 'app.bsky.actor.defs#interestsPref' /** A list of tags which describe the account owner's interests gathered during onboarding. */ tags: string[] } const hashInterestsPref = 'interestsPref' export function isInterestsPref(v: V) { return is$typed(v, id, hashInterestsPref) } export function validateInterestsPref(v: V) { return validate(v, id, hashInterestsPref) } export type MutedWordTarget = 'content' | 'tag' | (string & {}) /** A word that the account owner has muted. */ export interface MutedWord { $type?: 'app.bsky.actor.defs#mutedWord' id?: string /** The muted word itself. */ value: string /** The intended targets of the muted word. */ targets: MutedWordTarget[] /** Groups of users to apply the muted word to. If undefined, applies to all users. */ actorTarget: 'all' | 'exclude-following' | (string & {}) /** The date and time at which the muted word will expire and no longer be applied. */ expiresAt?: string } const hashMutedWord = 'mutedWord' export function isMutedWord(v: V) { return is$typed(v, id, hashMutedWord) } export function validateMutedWord(v: V) { return validate(v, id, hashMutedWord) } export interface MutedWordsPref { $type?: 'app.bsky.actor.defs#mutedWordsPref' /** A list of words the account owner has muted. */ items: MutedWord[] } const hashMutedWordsPref = 'mutedWordsPref' export function isMutedWordsPref(v: V) { return is$typed(v, id, hashMutedWordsPref) } export function validateMutedWordsPref(v: V) { return validate(v, id, hashMutedWordsPref) } export interface HiddenPostsPref { $type?: 'app.bsky.actor.defs#hiddenPostsPref' /** A list of URIs of posts the account owner has hidden. */ items: string[] } const hashHiddenPostsPref = 'hiddenPostsPref' export function isHiddenPostsPref(v: V) { return is$typed(v, id, hashHiddenPostsPref) } export function validateHiddenPostsPref(v: V) { return validate(v, id, hashHiddenPostsPref) } export interface LabelersPref { $type?: 'app.bsky.actor.defs#labelersPref' labelers: LabelerPrefItem[] } const hashLabelersPref = 'labelersPref' export function isLabelersPref(v: V) { return is$typed(v, id, hashLabelersPref) } export function validateLabelersPref(v: V) { return validate(v, id, hashLabelersPref) } export interface LabelerPrefItem { $type?: 'app.bsky.actor.defs#labelerPrefItem' did: string } const hashLabelerPrefItem = 'labelerPrefItem' export function isLabelerPrefItem(v: V) { return is$typed(v, id, hashLabelerPrefItem) } export function validateLabelerPrefItem(v: V) { return validate(v, id, hashLabelerPrefItem) } /** A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this. */ export interface BskyAppStatePref { $type?: 'app.bsky.actor.defs#bskyAppStatePref' activeProgressGuide?: BskyAppProgressGuide /** An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user. */ queuedNudges?: string[] /** Storage for NUXs the user has encountered. */ nuxs?: Nux[] } const hashBskyAppStatePref = 'bskyAppStatePref' export function isBskyAppStatePref(v: V) { return is$typed(v, id, hashBskyAppStatePref) } export function validateBskyAppStatePref(v: V) { return validate(v, id, hashBskyAppStatePref) } /** If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress. */ export interface BskyAppProgressGuide { $type?: 'app.bsky.actor.defs#bskyAppProgressGuide' guide: string } const hashBskyAppProgressGuide = 'bskyAppProgressGuide' export function isBskyAppProgressGuide(v: V) { return is$typed(v, id, hashBskyAppProgressGuide) } export function validateBskyAppProgressGuide(v: V) { return validate(v, id, hashBskyAppProgressGuide) } /** A new user experiences (NUX) storage object */ export interface Nux { $type?: 'app.bsky.actor.defs#nux' id: string completed: boolean /** Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters. */ data?: string /** The date and time at which the NUX will expire and should be considered completed. */ expiresAt?: string } const hashNux = 'nux' export function isNux(v: V) { return is$typed(v, id, hashNux) } export function validateNux(v: V) { return validate(v, id, hashNux) } /** Preferences for how verified accounts appear in the app. */ export interface VerificationPrefs { $type?: 'app.bsky.actor.defs#verificationPrefs' /** Hide the blue check badges for verified accounts and trusted verifiers. */ hideBadges: boolean } const hashVerificationPrefs = 'verificationPrefs' export function isVerificationPrefs(v: V) { return is$typed(v, id, hashVerificationPrefs) } export function validateVerificationPrefs(v: V) { return validate(v, id, hashVerificationPrefs) } /** Preferences for live events. */ export interface LiveEventPreferences { $type?: 'app.bsky.actor.defs#liveEventPreferences' /** A list of feed IDs that the user has hidden from live events. */ hiddenFeedIds?: string[] /** Whether to hide all feeds from live events. */ hideAllFeeds: boolean } const hashLiveEventPreferences = 'liveEventPreferences' export function isLiveEventPreferences(v: V) { return is$typed(v, id, hashLiveEventPreferences) } export function validateLiveEventPreferences(v: V) { return validate(v, id, hashLiveEventPreferences) } /** Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly. */ export interface PostInteractionSettingsPref { $type?: 'app.bsky.actor.defs#postInteractionSettingsPref' /** Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */ threadgateAllowRules?: ( | $Typed | $Typed | $Typed | $Typed | { $type: string } )[] /** Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */ postgateEmbeddingRules?: ( | $Typed | { $type: string } )[] } const hashPostInteractionSettingsPref = 'postInteractionSettingsPref' export function isPostInteractionSettingsPref(v: V) { return is$typed(v, id, hashPostInteractionSettingsPref) } export function validatePostInteractionSettingsPref(v: V) { return validate( v, id, hashPostInteractionSettingsPref, ) } export interface StatusView { $type?: 'app.bsky.actor.defs#statusView' uri?: string cid?: string /** The status for the account. */ status: 'app.bsky.actor.status#live' | (string & {}) record: { [_ in string]: unknown } embed?: $Typed | { $type: string } /** The date when this status will expire. The application might choose to no longer return the status after expiration. */ expiresAt?: string /** True if the status is not expired, false if it is expired. Only present if expiration was set. */ isActive?: boolean /** True if the user's go-live access has been disabled by a moderator, false otherwise. */ isDisabled?: boolean } const hashStatusView = 'statusView' export function isStatusView(v: V) { return is$typed(v, id, hashStatusView) } export function validateStatusView(v: V) { return validate(v, id, hashStatusView) } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/getPreferences.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.getPreferences' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { preferences: AppBskyActorDefs.Preferences } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/getProfile.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.getProfile' export type QueryParams = { /** Handle or DID of account to fetch profile of. */ actor: string } export type InputSchema = undefined export type OutputSchema = AppBskyActorDefs.ProfileViewDetailed export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/getProfiles.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.getProfiles' export type QueryParams = { actors: string[] } export type InputSchema = undefined export interface OutputSchema { profiles: AppBskyActorDefs.ProfileViewDetailed[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/getSuggestions.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.getSuggestions' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string actors: AppBskyActorDefs.ProfileView[] /** DEPRECATED: use recIdStr instead. */ recId?: number /** Snowflake for this recommendation, use when submitting recommendation events. */ recIdStr?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/profile.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.profile' export interface Main { $type: 'app.bsky.actor.profile' displayName?: string /** Free-form profile description text. */ description?: string /** Free-form pronouns text. */ pronouns?: string website?: string /** Small image to be displayed next to posts from account. AKA, 'profile picture' */ avatar?: BlobRef /** Larger horizontal image to display behind profile view. */ banner?: BlobRef labels?: $Typed | { $type: string } joinedViaStarterPack?: ComAtprotoRepoStrongRef.Main pinnedPost?: ComAtprotoRepoStrongRef.Main createdAt?: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/putPreferences.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.putPreferences' export type QueryParams = {} export interface InputSchema { preferences: AppBskyActorDefs.Preferences } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/searchActors.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.searchActors' export type QueryParams = { /** DEPRECATED: use 'q' instead. */ term?: string /** Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. */ q?: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string actors: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/searchActorsTypeahead.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.searchActorsTypeahead' export type QueryParams = { /** DEPRECATED: use 'q' instead. */ term?: string /** Search query prefix; not a full query string. */ q?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { actors: AppBskyActorDefs.ProfileViewBasic[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/actor/status.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyEmbedExternal from '../embed/external.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.actor.status' export interface Main { $type: 'app.bsky.actor.status' /** The status for the account. */ status: 'app.bsky.actor.status#live' | (string & {}) embed?: $Typed | { $type: string } /** The duration of the status in minutes. Applications can choose to impose minimum and maximum limits. */ durationMinutes?: number createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } /** Advertises an account as currently offering live content. */ export const LIVE = `${id}#live` ================================================ FILE: packages/api/src/client/types/app/bsky/ageassurance/begin.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyAgeassuranceDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.ageassurance.begin' export type QueryParams = {} export interface InputSchema { /** The user's email address to receive Age Assurance instructions. */ email: string /** The user's preferred language for communication during the Age Assurance process. */ language: string /** An ISO 3166-1 alpha-2 code of the user's location. */ countryCode: string /** An optional ISO 3166-2 code of the user's region or state within the country. */ regionCode?: string } export type OutputSchema = AppBskyAgeassuranceDefs.State export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class InvalidEmailError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class DidTooLongError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidInitiationError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class RegionNotSupportedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'InvalidEmail') return new InvalidEmailError(e) if (e.error === 'DidTooLong') return new DidTooLongError(e) if (e.error === 'InvalidInitiation') return new InvalidInitiationError(e) if (e.error === 'RegionNotSupported') return new RegionNotSupportedError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/ageassurance/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.ageassurance.defs' /** The access level granted based on Age Assurance data we've processed. */ export type Access = 'unknown' | 'none' | 'safe' | 'full' | (string & {}) /** The status of the Age Assurance process. */ export type Status = | 'unknown' | 'pending' | 'assured' | 'blocked' | (string & {}) /** The user's computed Age Assurance state. */ export interface State { $type?: 'app.bsky.ageassurance.defs#state' /** The timestamp when this state was last updated. */ lastInitiatedAt?: string status: Status access: Access } const hashState = 'state' export function isState(v: V) { return is$typed(v, id, hashState) } export function validateState(v: V) { return validate(v, id, hashState) } /** Additional metadata needed to compute Age Assurance state client-side. */ export interface StateMetadata { $type?: 'app.bsky.ageassurance.defs#stateMetadata' /** The account creation timestamp. */ accountCreatedAt?: string } const hashStateMetadata = 'stateMetadata' export function isStateMetadata(v: V) { return is$typed(v, id, hashStateMetadata) } export function validateStateMetadata(v: V) { return validate(v, id, hashStateMetadata) } export interface Config { $type?: 'app.bsky.ageassurance.defs#config' /** The per-region Age Assurance configuration. */ regions: ConfigRegion[] } const hashConfig = 'config' export function isConfig(v: V) { return is$typed(v, id, hashConfig) } export function validateConfig(v: V) { return validate(v, id, hashConfig) } /** The Age Assurance configuration for a specific region. */ export interface ConfigRegion { $type?: 'app.bsky.ageassurance.defs#configRegion' /** The ISO 3166-1 alpha-2 country code this configuration applies to. */ countryCode: string /** The ISO 3166-2 region code this configuration applies to. If omitted, the configuration applies to the entire country. */ regionCode?: string /** The minimum age (as a whole integer) required to use Bluesky in this region. */ minAccessAge: number /** The ordered list of Age Assurance rules that apply to this region. Rules should be applied in order, and the first matching rule determines the access level granted. The rules array should always include a default rule as the last item. */ rules: ( | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | { $type: string } )[] } const hashConfigRegion = 'configRegion' export function isConfigRegion(v: V) { return is$typed(v, id, hashConfigRegion) } export function validateConfigRegion(v: V) { return validate(v, id, hashConfigRegion) } /** Age Assurance rule that applies by default. */ export interface ConfigRegionRuleDefault { $type?: 'app.bsky.ageassurance.defs#configRegionRuleDefault' access: Access } const hashConfigRegionRuleDefault = 'configRegionRuleDefault' export function isConfigRegionRuleDefault(v: V) { return is$typed(v, id, hashConfigRegionRuleDefault) } export function validateConfigRegionRuleDefault(v: V) { return validate( v, id, hashConfigRegionRuleDefault, ) } /** Age Assurance rule that applies if the user has declared themselves equal-to or over a certain age. */ export interface ConfigRegionRuleIfDeclaredOverAge { $type?: 'app.bsky.ageassurance.defs#configRegionRuleIfDeclaredOverAge' /** The age threshold as a whole integer. */ age: number access: Access } const hashConfigRegionRuleIfDeclaredOverAge = 'configRegionRuleIfDeclaredOverAge' export function isConfigRegionRuleIfDeclaredOverAge(v: V) { return is$typed(v, id, hashConfigRegionRuleIfDeclaredOverAge) } export function validateConfigRegionRuleIfDeclaredOverAge(v: V) { return validate( v, id, hashConfigRegionRuleIfDeclaredOverAge, ) } /** Age Assurance rule that applies if the user has declared themselves under a certain age. */ export interface ConfigRegionRuleIfDeclaredUnderAge { $type?: 'app.bsky.ageassurance.defs#configRegionRuleIfDeclaredUnderAge' /** The age threshold as a whole integer. */ age: number access: Access } const hashConfigRegionRuleIfDeclaredUnderAge = 'configRegionRuleIfDeclaredUnderAge' export function isConfigRegionRuleIfDeclaredUnderAge(v: V) { return is$typed(v, id, hashConfigRegionRuleIfDeclaredUnderAge) } export function validateConfigRegionRuleIfDeclaredUnderAge(v: V) { return validate( v, id, hashConfigRegionRuleIfDeclaredUnderAge, ) } /** Age Assurance rule that applies if the user has been assured to be equal-to or over a certain age. */ export interface ConfigRegionRuleIfAssuredOverAge { $type?: 'app.bsky.ageassurance.defs#configRegionRuleIfAssuredOverAge' /** The age threshold as a whole integer. */ age: number access: Access } const hashConfigRegionRuleIfAssuredOverAge = 'configRegionRuleIfAssuredOverAge' export function isConfigRegionRuleIfAssuredOverAge(v: V) { return is$typed(v, id, hashConfigRegionRuleIfAssuredOverAge) } export function validateConfigRegionRuleIfAssuredOverAge(v: V) { return validate( v, id, hashConfigRegionRuleIfAssuredOverAge, ) } /** Age Assurance rule that applies if the user has been assured to be under a certain age. */ export interface ConfigRegionRuleIfAssuredUnderAge { $type?: 'app.bsky.ageassurance.defs#configRegionRuleIfAssuredUnderAge' /** The age threshold as a whole integer. */ age: number access: Access } const hashConfigRegionRuleIfAssuredUnderAge = 'configRegionRuleIfAssuredUnderAge' export function isConfigRegionRuleIfAssuredUnderAge(v: V) { return is$typed(v, id, hashConfigRegionRuleIfAssuredUnderAge) } export function validateConfigRegionRuleIfAssuredUnderAge(v: V) { return validate( v, id, hashConfigRegionRuleIfAssuredUnderAge, ) } /** Age Assurance rule that applies if the account is equal-to or newer than a certain date. */ export interface ConfigRegionRuleIfAccountNewerThan { $type?: 'app.bsky.ageassurance.defs#configRegionRuleIfAccountNewerThan' /** The date threshold as a datetime string. */ date: string access: Access } const hashConfigRegionRuleIfAccountNewerThan = 'configRegionRuleIfAccountNewerThan' export function isConfigRegionRuleIfAccountNewerThan(v: V) { return is$typed(v, id, hashConfigRegionRuleIfAccountNewerThan) } export function validateConfigRegionRuleIfAccountNewerThan(v: V) { return validate( v, id, hashConfigRegionRuleIfAccountNewerThan, ) } /** Age Assurance rule that applies if the account is older than a certain date. */ export interface ConfigRegionRuleIfAccountOlderThan { $type?: 'app.bsky.ageassurance.defs#configRegionRuleIfAccountOlderThan' /** The date threshold as a datetime string. */ date: string access: Access } const hashConfigRegionRuleIfAccountOlderThan = 'configRegionRuleIfAccountOlderThan' export function isConfigRegionRuleIfAccountOlderThan(v: V) { return is$typed(v, id, hashConfigRegionRuleIfAccountOlderThan) } export function validateConfigRegionRuleIfAccountOlderThan(v: V) { return validate( v, id, hashConfigRegionRuleIfAccountOlderThan, ) } /** Object used to store Age Assurance data in stash. */ export interface Event { $type?: 'app.bsky.ageassurance.defs#event' /** The date and time of this write operation. */ createdAt: string /** The unique identifier for this instance of the Age Assurance flow, in UUID format. */ attemptId: string /** The status of the Age Assurance process. */ status: 'unknown' | 'pending' | 'assured' | 'blocked' | (string & {}) /** The access level granted based on Age Assurance data we've processed. */ access: 'unknown' | 'none' | 'safe' | 'full' | (string & {}) /** The ISO 3166-1 alpha-2 country code provided when beginning the Age Assurance flow. */ countryCode: string /** The ISO 3166-2 region code provided when beginning the Age Assurance flow. */ regionCode?: string /** The email used for Age Assurance. */ email?: string /** The IP address used when initiating the Age Assurance flow. */ initIp?: string /** The user agent used when initiating the Age Assurance flow. */ initUa?: string /** The IP address used when completing the Age Assurance flow. */ completeIp?: string /** The user agent used when completing the Age Assurance flow. */ completeUa?: string } const hashEvent = 'event' export function isEvent(v: V) { return is$typed(v, id, hashEvent) } export function validateEvent(v: V) { return validate(v, id, hashEvent) } ================================================ FILE: packages/api/src/client/types/app/bsky/ageassurance/getConfig.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyAgeassuranceDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.ageassurance.getConfig' export type QueryParams = {} export type InputSchema = undefined export type OutputSchema = AppBskyAgeassuranceDefs.Config export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/ageassurance/getState.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyAgeassuranceDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.ageassurance.getState' export type QueryParams = { countryCode: string regionCode?: string } export type InputSchema = undefined export interface OutputSchema { state: AppBskyAgeassuranceDefs.State metadata: AppBskyAgeassuranceDefs.StateMetadata } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/bookmark/createBookmark.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.bookmark.createBookmark' export type QueryParams = {} export interface InputSchema { uri: string cid: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export class UnsupportedCollectionError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'UnsupportedCollection') return new UnsupportedCollectionError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/bookmark/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' import type * as AppBskyFeedDefs from '../feed/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.bookmark.defs' /** Object used to store bookmark data in stash. */ export interface Bookmark { $type?: 'app.bsky.bookmark.defs#bookmark' subject: ComAtprotoRepoStrongRef.Main } const hashBookmark = 'bookmark' export function isBookmark(v: V) { return is$typed(v, id, hashBookmark) } export function validateBookmark(v: V) { return validate(v, id, hashBookmark) } export interface BookmarkView { $type?: 'app.bsky.bookmark.defs#bookmarkView' subject: ComAtprotoRepoStrongRef.Main createdAt?: string item: | $Typed | $Typed | $Typed | { $type: string } } const hashBookmarkView = 'bookmarkView' export function isBookmarkView(v: V) { return is$typed(v, id, hashBookmarkView) } export function validateBookmarkView(v: V) { return validate(v, id, hashBookmarkView) } ================================================ FILE: packages/api/src/client/types/app/bsky/bookmark/deleteBookmark.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.bookmark.deleteBookmark' export type QueryParams = {} export interface InputSchema { uri: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export class UnsupportedCollectionError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'UnsupportedCollection') return new UnsupportedCollectionError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/bookmark/getBookmarks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyBookmarkDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.bookmark.getBookmarks' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string bookmarks: AppBskyBookmarkDefs.BookmarkView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.defs' /** Associates a profile with the positional index of the contact import input in the call to `app.bsky.contact.importContacts`, so clients can know which phone caused a particular match. */ export interface MatchAndContactIndex { $type?: 'app.bsky.contact.defs#matchAndContactIndex' match: AppBskyActorDefs.ProfileView /** The index of this match in the import contact input. */ contactIndex: number } const hashMatchAndContactIndex = 'matchAndContactIndex' export function isMatchAndContactIndex(v: V) { return is$typed(v, id, hashMatchAndContactIndex) } export function validateMatchAndContactIndex(v: V) { return validate(v, id, hashMatchAndContactIndex) } export interface SyncStatus { $type?: 'app.bsky.contact.defs#syncStatus' /** Last date when contacts where imported. */ syncedAt: string /** Number of existing contact matches resulting of the user imports and of their imported contacts having imported the user. Matches stop being counted when the user either follows the matched contact or dismisses the match. */ matchesCount: number } const hashSyncStatus = 'syncStatus' export function isSyncStatus(v: V) { return is$typed(v, id, hashSyncStatus) } export function validateSyncStatus(v: V) { return validate(v, id, hashSyncStatus) } /** A stash object to be sent via bsync representing a notification to be created. */ export interface Notification { $type?: 'app.bsky.contact.defs#notification' /** The DID of who this notification comes from. */ from: string /** The DID of who this notification should go to. */ to: string } const hashNotification = 'notification' export function isNotification(v: V) { return is$typed(v, id, hashNotification) } export function validateNotification(v: V) { return validate(v, id, hashNotification) } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/dismissMatch.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.dismissMatch' export type QueryParams = {} export interface InputSchema { /** The subject's DID to dismiss the match with. */ subject: string } export interface OutputSchema {} export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class InvalidDidError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InternalError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'InvalidDid') return new InvalidDidError(e) if (e.error === 'InternalError') return new InternalError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/getMatches.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.getMatches' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string matches: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class InvalidDidError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidLimitError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidCursorError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InternalError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'InvalidDid') return new InvalidDidError(e) if (e.error === 'InvalidLimit') return new InvalidLimitError(e) if (e.error === 'InvalidCursor') return new InvalidCursorError(e) if (e.error === 'InternalError') return new InternalError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/getSyncStatus.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyContactDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.getSyncStatus' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { syncStatus?: AppBskyContactDefs.SyncStatus } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class InvalidDidError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InternalError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'InvalidDid') return new InvalidDidError(e) if (e.error === 'InternalError') return new InternalError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/importContacts.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyContactDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.importContacts' export type QueryParams = {} export interface InputSchema { /** JWT to authenticate the call. Use the JWT received as a response to the call to `app.bsky.contact.verifyPhone`. */ token: string /** List of phone numbers in global E.164 format (e.g., '+12125550123'). Phone numbers that cannot be normalized into a valid phone number will be discarded. Should not repeat the 'phone' input used in `app.bsky.contact.verifyPhone`. */ contacts: string[] } export interface OutputSchema { /** The users that matched during import and their indexes on the input contacts, so the client can correlate with its local list. */ matchesAndContactIndexes: AppBskyContactDefs.MatchAndContactIndex[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class InvalidDidError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidContactsError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class TooManyContactsError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidTokenError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InternalError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'InvalidDid') return new InvalidDidError(e) if (e.error === 'InvalidContacts') return new InvalidContactsError(e) if (e.error === 'TooManyContacts') return new TooManyContactsError(e) if (e.error === 'InvalidToken') return new InvalidTokenError(e) if (e.error === 'InternalError') return new InternalError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/removeData.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.removeData' export type QueryParams = {} export interface InputSchema {} export interface OutputSchema {} export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class InvalidDidError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InternalError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'InvalidDid') return new InvalidDidError(e) if (e.error === 'InternalError') return new InternalError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/sendNotification.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.sendNotification' export type QueryParams = {} export interface InputSchema { /** The DID of who this notification comes from. */ from: string /** The DID of who this notification should go to. */ to: string } export interface OutputSchema {} export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/startPhoneVerification.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.startPhoneVerification' export type QueryParams = {} export interface InputSchema { /** The phone number to receive the code via SMS. */ phone: string } export interface OutputSchema {} export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class RateLimitExceededError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidDidError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidPhoneError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InternalError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'RateLimitExceeded') return new RateLimitExceededError(e) if (e.error === 'InvalidDid') return new InvalidDidError(e) if (e.error === 'InvalidPhone') return new InvalidPhoneError(e) if (e.error === 'InternalError') return new InternalError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/contact/verifyPhone.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.contact.verifyPhone' export type QueryParams = {} export interface InputSchema { /** The phone number to verify. Should be the same as the one passed to `app.bsky.contact.startPhoneVerification`. */ phone: string /** The code received via SMS as a result of the call to `app.bsky.contact.startPhoneVerification`. */ code: string } export interface OutputSchema { /** JWT to be used in a call to `app.bsky.contact.importContacts`. It is only valid for a single call. */ token: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class RateLimitExceededError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidDidError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidPhoneError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidCodeError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InternalError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'RateLimitExceeded') return new RateLimitExceededError(e) if (e.error === 'InvalidDid') return new InvalidDidError(e) if (e.error === 'InvalidPhone') return new InvalidPhoneError(e) if (e.error === 'InvalidCode') return new InvalidCodeError(e) if (e.error === 'InternalError') return new InternalError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/draft/createDraft.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyDraftDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.draft.createDraft' export type QueryParams = {} export interface InputSchema { draft: AppBskyDraftDefs.Draft } export interface OutputSchema { /** The ID of the created draft. */ id: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class DraftLimitReachedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'DraftLimitReached') return new DraftLimitReachedError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/draft/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedPostgate from '../feed/postgate.js' import type * as AppBskyFeedThreadgate from '../feed/threadgate.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.draft.defs' /** A draft with an identifier, used to store drafts in private storage (stash). */ export interface DraftWithId { $type?: 'app.bsky.draft.defs#draftWithId' /** A TID to be used as a draft identifier. */ id: string draft: Draft } const hashDraftWithId = 'draftWithId' export function isDraftWithId(v: V) { return is$typed(v, id, hashDraftWithId) } export function validateDraftWithId(v: V) { return validate(v, id, hashDraftWithId) } /** A draft containing an array of draft posts. */ export interface Draft { $type?: 'app.bsky.draft.defs#draft' /** UUIDv4 identifier of the device that created this draft. */ deviceId?: string /** The device and/or platform on which the draft was created. */ deviceName?: string /** Array of draft posts that compose this draft. */ posts: DraftPost[] /** Indicates human language of posts primary text content. */ langs?: string[] /** Embedding rules for the postgates to be created when this draft is published. */ postgateEmbeddingRules?: ( | $Typed | { $type: string } )[] /** Allow-rules for the threadgate to be created when this draft is published. */ threadgateAllow?: ( | $Typed | $Typed | $Typed | $Typed | { $type: string } )[] } const hashDraft = 'draft' export function isDraft(v: V) { return is$typed(v, id, hashDraft) } export function validateDraft(v: V) { return validate(v, id, hashDraft) } /** One of the posts that compose a draft. */ export interface DraftPost { $type?: 'app.bsky.draft.defs#draftPost' /** The primary post content. It has a higher limit than post contents to allow storing a larger text that can later be refined into smaller posts. */ text: string labels?: $Typed | { $type: string } embedImages?: DraftEmbedImage[] embedVideos?: DraftEmbedVideo[] embedExternals?: DraftEmbedExternal[] embedRecords?: DraftEmbedRecord[] } const hashDraftPost = 'draftPost' export function isDraftPost(v: V) { return is$typed(v, id, hashDraftPost) } export function validateDraftPost(v: V) { return validate(v, id, hashDraftPost) } /** View to present drafts data to users. */ export interface DraftView { $type?: 'app.bsky.draft.defs#draftView' /** A TID to be used as a draft identifier. */ id: string draft: Draft /** The time the draft was created. */ createdAt: string /** The time the draft was last updated. */ updatedAt: string } const hashDraftView = 'draftView' export function isDraftView(v: V) { return is$typed(v, id, hashDraftView) } export function validateDraftView(v: V) { return validate(v, id, hashDraftView) } export interface DraftEmbedLocalRef { $type?: 'app.bsky.draft.defs#draftEmbedLocalRef' /** Local, on-device ref to file to be embedded. Embeds are currently device-bound for drafts. */ path: string } const hashDraftEmbedLocalRef = 'draftEmbedLocalRef' export function isDraftEmbedLocalRef(v: V) { return is$typed(v, id, hashDraftEmbedLocalRef) } export function validateDraftEmbedLocalRef(v: V) { return validate(v, id, hashDraftEmbedLocalRef) } export interface DraftEmbedCaption { $type?: 'app.bsky.draft.defs#draftEmbedCaption' lang: string content: string } const hashDraftEmbedCaption = 'draftEmbedCaption' export function isDraftEmbedCaption(v: V) { return is$typed(v, id, hashDraftEmbedCaption) } export function validateDraftEmbedCaption(v: V) { return validate(v, id, hashDraftEmbedCaption) } export interface DraftEmbedImage { $type?: 'app.bsky.draft.defs#draftEmbedImage' localRef: DraftEmbedLocalRef alt?: string } const hashDraftEmbedImage = 'draftEmbedImage' export function isDraftEmbedImage(v: V) { return is$typed(v, id, hashDraftEmbedImage) } export function validateDraftEmbedImage(v: V) { return validate(v, id, hashDraftEmbedImage) } export interface DraftEmbedVideo { $type?: 'app.bsky.draft.defs#draftEmbedVideo' localRef: DraftEmbedLocalRef alt?: string captions?: DraftEmbedCaption[] } const hashDraftEmbedVideo = 'draftEmbedVideo' export function isDraftEmbedVideo(v: V) { return is$typed(v, id, hashDraftEmbedVideo) } export function validateDraftEmbedVideo(v: V) { return validate(v, id, hashDraftEmbedVideo) } export interface DraftEmbedExternal { $type?: 'app.bsky.draft.defs#draftEmbedExternal' uri: string } const hashDraftEmbedExternal = 'draftEmbedExternal' export function isDraftEmbedExternal(v: V) { return is$typed(v, id, hashDraftEmbedExternal) } export function validateDraftEmbedExternal(v: V) { return validate(v, id, hashDraftEmbedExternal) } export interface DraftEmbedRecord { $type?: 'app.bsky.draft.defs#draftEmbedRecord' record: ComAtprotoRepoStrongRef.Main } const hashDraftEmbedRecord = 'draftEmbedRecord' export function isDraftEmbedRecord(v: V) { return is$typed(v, id, hashDraftEmbedRecord) } export function validateDraftEmbedRecord(v: V) { return validate(v, id, hashDraftEmbedRecord) } ================================================ FILE: packages/api/src/client/types/app/bsky/draft/deleteDraft.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.draft.deleteDraft' export type QueryParams = {} export interface InputSchema { id: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/draft/getDrafts.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyDraftDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.draft.getDrafts' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string drafts: AppBskyDraftDefs.DraftView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/draft/updateDraft.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyDraftDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.draft.updateDraft' export type QueryParams = {} export interface InputSchema { draft: AppBskyDraftDefs.DraftWithId } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/embed/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.embed.defs' /** width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit. */ export interface AspectRatio { $type?: 'app.bsky.embed.defs#aspectRatio' width: number height: number } const hashAspectRatio = 'aspectRatio' export function isAspectRatio(v: V) { return is$typed(v, id, hashAspectRatio) } export function validateAspectRatio(v: V) { return validate(v, id, hashAspectRatio) } ================================================ FILE: packages/api/src/client/types/app/bsky/embed/external.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.embed.external' /** A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post). */ export interface Main { $type?: 'app.bsky.embed.external' external: External } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain) } export interface External { $type?: 'app.bsky.embed.external#external' uri: string title: string description: string thumb?: BlobRef } const hashExternal = 'external' export function isExternal(v: V) { return is$typed(v, id, hashExternal) } export function validateExternal(v: V) { return validate(v, id, hashExternal) } export interface View { $type?: 'app.bsky.embed.external#view' external: ViewExternal } const hashView = 'view' export function isView(v: V) { return is$typed(v, id, hashView) } export function validateView(v: V) { return validate(v, id, hashView) } export interface ViewExternal { $type?: 'app.bsky.embed.external#viewExternal' uri: string title: string description: string thumb?: string } const hashViewExternal = 'viewExternal' export function isViewExternal(v: V) { return is$typed(v, id, hashViewExternal) } export function validateViewExternal(v: V) { return validate(v, id, hashViewExternal) } ================================================ FILE: packages/api/src/client/types/app/bsky/embed/images.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyEmbedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.embed.images' export interface Main { $type?: 'app.bsky.embed.images' images: Image[] } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain) } export interface Image { $type?: 'app.bsky.embed.images#image' image: BlobRef /** Alt text description of the image, for accessibility. */ alt: string aspectRatio?: AppBskyEmbedDefs.AspectRatio } const hashImage = 'image' export function isImage(v: V) { return is$typed(v, id, hashImage) } export function validateImage(v: V) { return validate(v, id, hashImage) } export interface View { $type?: 'app.bsky.embed.images#view' images: ViewImage[] } const hashView = 'view' export function isView(v: V) { return is$typed(v, id, hashView) } export function validateView(v: V) { return validate(v, id, hashView) } export interface ViewImage { $type?: 'app.bsky.embed.images#viewImage' /** Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View. */ thumb: string /** Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View. */ fullsize: string /** Alt text description of the image, for accessibility. */ alt: string aspectRatio?: AppBskyEmbedDefs.AspectRatio } const hashViewImage = 'viewImage' export function isViewImage(v: V) { return is$typed(v, id, hashViewImage) } export function validateViewImage(v: V) { return validate(v, id, hashViewImage) } ================================================ FILE: packages/api/src/client/types/app/bsky/embed/record.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' import type * as AppBskyFeedDefs from '../feed/defs.js' import type * as AppBskyGraphDefs from '../graph/defs.js' import type * as AppBskyLabelerDefs from '../labeler/defs.js' import type * as AppBskyActorDefs from '../actor/defs.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as AppBskyEmbedImages from './images.js' import type * as AppBskyEmbedVideo from './video.js' import type * as AppBskyEmbedExternal from './external.js' import type * as AppBskyEmbedRecordWithMedia from './recordWithMedia.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.embed.record' export interface Main { $type?: 'app.bsky.embed.record' record: ComAtprotoRepoStrongRef.Main } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain) } export interface View { $type?: 'app.bsky.embed.record#view' record: | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | { $type: string } } const hashView = 'view' export function isView(v: V) { return is$typed(v, id, hashView) } export function validateView(v: V) { return validate(v, id, hashView) } export interface ViewRecord { $type?: 'app.bsky.embed.record#viewRecord' uri: string cid: string author: AppBskyActorDefs.ProfileViewBasic /** The record data itself. */ value: { [_ in string]: unknown } labels?: ComAtprotoLabelDefs.Label[] replyCount?: number repostCount?: number likeCount?: number quoteCount?: number embeds?: ( | $Typed | $Typed | $Typed | $Typed | $Typed | { $type: string } )[] indexedAt: string } const hashViewRecord = 'viewRecord' export function isViewRecord(v: V) { return is$typed(v, id, hashViewRecord) } export function validateViewRecord(v: V) { return validate(v, id, hashViewRecord) } export interface ViewNotFound { $type?: 'app.bsky.embed.record#viewNotFound' uri: string notFound: true } const hashViewNotFound = 'viewNotFound' export function isViewNotFound(v: V) { return is$typed(v, id, hashViewNotFound) } export function validateViewNotFound(v: V) { return validate(v, id, hashViewNotFound) } export interface ViewBlocked { $type?: 'app.bsky.embed.record#viewBlocked' uri: string blocked: true author: AppBskyFeedDefs.BlockedAuthor } const hashViewBlocked = 'viewBlocked' export function isViewBlocked(v: V) { return is$typed(v, id, hashViewBlocked) } export function validateViewBlocked(v: V) { return validate(v, id, hashViewBlocked) } export interface ViewDetached { $type?: 'app.bsky.embed.record#viewDetached' uri: string detached: true } const hashViewDetached = 'viewDetached' export function isViewDetached(v: V) { return is$typed(v, id, hashViewDetached) } export function validateViewDetached(v: V) { return validate(v, id, hashViewDetached) } ================================================ FILE: packages/api/src/client/types/app/bsky/embed/recordWithMedia.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyEmbedRecord from './record.js' import type * as AppBskyEmbedImages from './images.js' import type * as AppBskyEmbedVideo from './video.js' import type * as AppBskyEmbedExternal from './external.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.embed.recordWithMedia' export interface Main { $type?: 'app.bsky.embed.recordWithMedia' record: AppBskyEmbedRecord.Main media: | $Typed | $Typed | $Typed | { $type: string } } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain) } export interface View { $type?: 'app.bsky.embed.recordWithMedia#view' record: AppBskyEmbedRecord.View media: | $Typed | $Typed | $Typed | { $type: string } } const hashView = 'view' export function isView(v: V) { return is$typed(v, id, hashView) } export function validateView(v: V) { return validate(v, id, hashView) } ================================================ FILE: packages/api/src/client/types/app/bsky/embed/video.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyEmbedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.embed.video' export interface Main { $type?: 'app.bsky.embed.video' /** The mp4 video file. May be up to 100mb, formerly limited to 50mb. */ video: BlobRef captions?: Caption[] /** Alt text description of the video, for accessibility. */ alt?: string aspectRatio?: AppBskyEmbedDefs.AspectRatio /** A hint to the client about how to present the video. */ presentation?: 'default' | 'gif' | (string & {}) } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain) } export interface Caption { $type?: 'app.bsky.embed.video#caption' lang: string file: BlobRef } const hashCaption = 'caption' export function isCaption(v: V) { return is$typed(v, id, hashCaption) } export function validateCaption(v: V) { return validate(v, id, hashCaption) } export interface View { $type?: 'app.bsky.embed.video#view' cid: string playlist: string thumbnail?: string alt?: string aspectRatio?: AppBskyEmbedDefs.AspectRatio /** A hint to the client about how to present the video. */ presentation?: 'default' | 'gif' | (string & {}) } const hashView = 'view' export function isView(v: V) { return is$typed(v, id, hashView) } export function validateView(v: V) { return validate(v, id, hashView) } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' import type * as AppBskyEmbedImages from '../embed/images.js' import type * as AppBskyEmbedVideo from '../embed/video.js' import type * as AppBskyEmbedExternal from '../embed/external.js' import type * as AppBskyEmbedRecord from '../embed/record.js' import type * as AppBskyEmbedRecordWithMedia from '../embed/recordWithMedia.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as AppBskyRichtextFacet from '../richtext/facet.js' import type * as AppBskyGraphDefs from '../graph/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.defs' export interface PostView { $type?: 'app.bsky.feed.defs#postView' uri: string cid: string author: AppBskyActorDefs.ProfileViewBasic record: { [_ in string]: unknown } embed?: | $Typed | $Typed | $Typed | $Typed | $Typed | { $type: string } bookmarkCount?: number replyCount?: number repostCount?: number likeCount?: number quoteCount?: number indexedAt: string viewer?: ViewerState labels?: ComAtprotoLabelDefs.Label[] threadgate?: ThreadgateView /** Debug information for internal development */ debug?: { [_ in string]: unknown } } const hashPostView = 'postView' export function isPostView(v: V) { return is$typed(v, id, hashPostView) } export function validatePostView(v: V) { return validate(v, id, hashPostView) } /** Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests. */ export interface ViewerState { $type?: 'app.bsky.feed.defs#viewerState' repost?: string like?: string bookmarked?: boolean threadMuted?: boolean replyDisabled?: boolean embeddingDisabled?: boolean pinned?: boolean } const hashViewerState = 'viewerState' export function isViewerState(v: V) { return is$typed(v, id, hashViewerState) } export function validateViewerState(v: V) { return validate(v, id, hashViewerState) } /** Metadata about this post within the context of the thread it is in. */ export interface ThreadContext { $type?: 'app.bsky.feed.defs#threadContext' rootAuthorLike?: string } const hashThreadContext = 'threadContext' export function isThreadContext(v: V) { return is$typed(v, id, hashThreadContext) } export function validateThreadContext(v: V) { return validate(v, id, hashThreadContext) } export interface FeedViewPost { $type?: 'app.bsky.feed.defs#feedViewPost' post: PostView reply?: ReplyRef reason?: $Typed | $Typed | { $type: string } /** Context provided by feed generator that may be passed back alongside interactions. */ feedContext?: string /** Unique identifier per request that may be passed back alongside interactions. */ reqId?: string } const hashFeedViewPost = 'feedViewPost' export function isFeedViewPost(v: V) { return is$typed(v, id, hashFeedViewPost) } export function validateFeedViewPost(v: V) { return validate(v, id, hashFeedViewPost) } export interface ReplyRef { $type?: 'app.bsky.feed.defs#replyRef' root: | $Typed | $Typed | $Typed | { $type: string } parent: | $Typed | $Typed | $Typed | { $type: string } grandparentAuthor?: AppBskyActorDefs.ProfileViewBasic } const hashReplyRef = 'replyRef' export function isReplyRef(v: V) { return is$typed(v, id, hashReplyRef) } export function validateReplyRef(v: V) { return validate(v, id, hashReplyRef) } export interface ReasonRepost { $type?: 'app.bsky.feed.defs#reasonRepost' by: AppBskyActorDefs.ProfileViewBasic uri?: string cid?: string indexedAt: string } const hashReasonRepost = 'reasonRepost' export function isReasonRepost(v: V) { return is$typed(v, id, hashReasonRepost) } export function validateReasonRepost(v: V) { return validate(v, id, hashReasonRepost) } export interface ReasonPin { $type?: 'app.bsky.feed.defs#reasonPin' } const hashReasonPin = 'reasonPin' export function isReasonPin(v: V) { return is$typed(v, id, hashReasonPin) } export function validateReasonPin(v: V) { return validate(v, id, hashReasonPin) } export interface ThreadViewPost { $type?: 'app.bsky.feed.defs#threadViewPost' post: PostView parent?: | $Typed | $Typed | $Typed | { $type: string } replies?: ( | $Typed | $Typed | $Typed | { $type: string } )[] threadContext?: ThreadContext } const hashThreadViewPost = 'threadViewPost' export function isThreadViewPost(v: V) { return is$typed(v, id, hashThreadViewPost) } export function validateThreadViewPost(v: V) { return validate(v, id, hashThreadViewPost) } export interface NotFoundPost { $type?: 'app.bsky.feed.defs#notFoundPost' uri: string notFound: true } const hashNotFoundPost = 'notFoundPost' export function isNotFoundPost(v: V) { return is$typed(v, id, hashNotFoundPost) } export function validateNotFoundPost(v: V) { return validate(v, id, hashNotFoundPost) } export interface BlockedPost { $type?: 'app.bsky.feed.defs#blockedPost' uri: string blocked: true author: BlockedAuthor } const hashBlockedPost = 'blockedPost' export function isBlockedPost(v: V) { return is$typed(v, id, hashBlockedPost) } export function validateBlockedPost(v: V) { return validate(v, id, hashBlockedPost) } export interface BlockedAuthor { $type?: 'app.bsky.feed.defs#blockedAuthor' did: string viewer?: AppBskyActorDefs.ViewerState } const hashBlockedAuthor = 'blockedAuthor' export function isBlockedAuthor(v: V) { return is$typed(v, id, hashBlockedAuthor) } export function validateBlockedAuthor(v: V) { return validate(v, id, hashBlockedAuthor) } export interface GeneratorView { $type?: 'app.bsky.feed.defs#generatorView' uri: string cid: string did: string creator: AppBskyActorDefs.ProfileView displayName: string description?: string descriptionFacets?: AppBskyRichtextFacet.Main[] avatar?: string likeCount?: number acceptsInteractions?: boolean labels?: ComAtprotoLabelDefs.Label[] viewer?: GeneratorViewerState contentMode?: | 'app.bsky.feed.defs#contentModeUnspecified' | 'app.bsky.feed.defs#contentModeVideo' | (string & {}) indexedAt: string } const hashGeneratorView = 'generatorView' export function isGeneratorView(v: V) { return is$typed(v, id, hashGeneratorView) } export function validateGeneratorView(v: V) { return validate(v, id, hashGeneratorView) } export interface GeneratorViewerState { $type?: 'app.bsky.feed.defs#generatorViewerState' like?: string } const hashGeneratorViewerState = 'generatorViewerState' export function isGeneratorViewerState(v: V) { return is$typed(v, id, hashGeneratorViewerState) } export function validateGeneratorViewerState(v: V) { return validate(v, id, hashGeneratorViewerState) } export interface SkeletonFeedPost { $type?: 'app.bsky.feed.defs#skeletonFeedPost' post: string reason?: | $Typed | $Typed | { $type: string } /** Context that will be passed through to client and may be passed to feed generator back alongside interactions. */ feedContext?: string } const hashSkeletonFeedPost = 'skeletonFeedPost' export function isSkeletonFeedPost(v: V) { return is$typed(v, id, hashSkeletonFeedPost) } export function validateSkeletonFeedPost(v: V) { return validate(v, id, hashSkeletonFeedPost) } export interface SkeletonReasonRepost { $type?: 'app.bsky.feed.defs#skeletonReasonRepost' repost: string } const hashSkeletonReasonRepost = 'skeletonReasonRepost' export function isSkeletonReasonRepost(v: V) { return is$typed(v, id, hashSkeletonReasonRepost) } export function validateSkeletonReasonRepost(v: V) { return validate(v, id, hashSkeletonReasonRepost) } export interface SkeletonReasonPin { $type?: 'app.bsky.feed.defs#skeletonReasonPin' } const hashSkeletonReasonPin = 'skeletonReasonPin' export function isSkeletonReasonPin(v: V) { return is$typed(v, id, hashSkeletonReasonPin) } export function validateSkeletonReasonPin(v: V) { return validate(v, id, hashSkeletonReasonPin) } export interface ThreadgateView { $type?: 'app.bsky.feed.defs#threadgateView' uri?: string cid?: string record?: { [_ in string]: unknown } lists?: AppBskyGraphDefs.ListViewBasic[] } const hashThreadgateView = 'threadgateView' export function isThreadgateView(v: V) { return is$typed(v, id, hashThreadgateView) } export function validateThreadgateView(v: V) { return validate(v, id, hashThreadgateView) } export interface Interaction { $type?: 'app.bsky.feed.defs#interaction' item?: string event?: | 'app.bsky.feed.defs#requestLess' | 'app.bsky.feed.defs#requestMore' | 'app.bsky.feed.defs#clickthroughItem' | 'app.bsky.feed.defs#clickthroughAuthor' | 'app.bsky.feed.defs#clickthroughReposter' | 'app.bsky.feed.defs#clickthroughEmbed' | 'app.bsky.feed.defs#interactionSeen' | 'app.bsky.feed.defs#interactionLike' | 'app.bsky.feed.defs#interactionRepost' | 'app.bsky.feed.defs#interactionReply' | 'app.bsky.feed.defs#interactionQuote' | 'app.bsky.feed.defs#interactionShare' | (string & {}) /** Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton. */ feedContext?: string /** Unique identifier per request that may be passed back alongside interactions. */ reqId?: string } const hashInteraction = 'interaction' export function isInteraction(v: V) { return is$typed(v, id, hashInteraction) } export function validateInteraction(v: V) { return validate(v, id, hashInteraction) } /** Request that less content like the given feed item be shown in the feed */ export const REQUESTLESS = `${id}#requestLess` /** Request that more content like the given feed item be shown in the feed */ export const REQUESTMORE = `${id}#requestMore` /** User clicked through to the feed item */ export const CLICKTHROUGHITEM = `${id}#clickthroughItem` /** User clicked through to the author of the feed item */ export const CLICKTHROUGHAUTHOR = `${id}#clickthroughAuthor` /** User clicked through to the reposter of the feed item */ export const CLICKTHROUGHREPOSTER = `${id}#clickthroughReposter` /** User clicked through to the embedded content of the feed item */ export const CLICKTHROUGHEMBED = `${id}#clickthroughEmbed` /** Declares the feed generator returns any types of posts. */ export const CONTENTMODEUNSPECIFIED = `${id}#contentModeUnspecified` /** Declares the feed generator returns posts containing app.bsky.embed.video embeds. */ export const CONTENTMODEVIDEO = `${id}#contentModeVideo` /** Feed item was seen by user */ export const INTERACTIONSEEN = `${id}#interactionSeen` /** User liked the feed item */ export const INTERACTIONLIKE = `${id}#interactionLike` /** User reposted the feed item */ export const INTERACTIONREPOST = `${id}#interactionRepost` /** User replied to the feed item */ export const INTERACTIONREPLY = `${id}#interactionReply` /** User quoted the feed item */ export const INTERACTIONQUOTE = `${id}#interactionQuote` /** User shared the feed item */ export const INTERACTIONSHARE = `${id}#interactionShare` ================================================ FILE: packages/api/src/client/types/app/bsky/feed/describeFeedGenerator.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.describeFeedGenerator' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { did: string feeds: Feed[] links?: Links } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface Feed { $type?: 'app.bsky.feed.describeFeedGenerator#feed' uri: string } const hashFeed = 'feed' export function isFeed(v: V) { return is$typed(v, id, hashFeed) } export function validateFeed(v: V) { return validate(v, id, hashFeed) } export interface Links { $type?: 'app.bsky.feed.describeFeedGenerator#links' privacyPolicy?: string termsOfService?: string } const hashLinks = 'links' export function isLinks(v: V) { return is$typed(v, id, hashLinks) } export function validateLinks(v: V) { return validate(v, id, hashLinks) } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/generator.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyRichtextFacet from '../richtext/facet.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.generator' export interface Main { $type: 'app.bsky.feed.generator' did: string displayName: string description?: string descriptionFacets?: AppBskyRichtextFacet.Main[] avatar?: BlobRef /** Declaration that a feed accepts feedback interactions from a client through app.bsky.feed.sendInteractions */ acceptsInteractions?: boolean labels?: $Typed | { $type: string } contentMode?: | 'app.bsky.feed.defs#contentModeUnspecified' | 'app.bsky.feed.defs#contentModeVideo' | (string & {}) createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getActorFeeds.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getActorFeeds' export type QueryParams = { actor: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feeds: AppBskyFeedDefs.GeneratorView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getActorLikes.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getActorLikes' export type QueryParams = { actor: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feed: AppBskyFeedDefs.FeedViewPost[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class BlockedActorError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class BlockedByActorError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'BlockedActor') return new BlockedActorError(e) if (e.error === 'BlockedByActor') return new BlockedByActorError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getAuthorFeed.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getAuthorFeed' export type QueryParams = { actor: string limit?: number cursor?: string /** Combinations of post/repost types to include in response. */ filter?: | 'posts_with_replies' | 'posts_no_replies' | 'posts_with_media' | 'posts_and_author_threads' | 'posts_with_video' | (string & {}) includePins?: boolean } export type InputSchema = undefined export interface OutputSchema { cursor?: string feed: AppBskyFeedDefs.FeedViewPost[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class BlockedActorError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class BlockedByActorError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'BlockedActor') return new BlockedActorError(e) if (e.error === 'BlockedByActor') return new BlockedByActorError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getFeed.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getFeed' export type QueryParams = { feed: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feed: AppBskyFeedDefs.FeedViewPost[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class UnknownFeedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'UnknownFeed') return new UnknownFeedError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getFeedGenerator.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getFeedGenerator' export type QueryParams = { /** AT-URI of the feed generator record. */ feed: string } export type InputSchema = undefined export interface OutputSchema { view: AppBskyFeedDefs.GeneratorView /** Indicates whether the feed generator service has been online recently, or else seems to be inactive. */ isOnline: boolean /** Indicates whether the feed generator service is compatible with the record declaration. */ isValid: boolean } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getFeedGenerators.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getFeedGenerators' export type QueryParams = { feeds: string[] } export type InputSchema = undefined export interface OutputSchema { feeds: AppBskyFeedDefs.GeneratorView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getFeedSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getFeedSkeleton' export type QueryParams = { /** Reference to feed generator record describing the specific feed being requested. */ feed: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feed: AppBskyFeedDefs.SkeletonFeedPost[] /** Unique identifier per request that may be passed back alongside interactions. */ reqId?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class UnknownFeedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'UnknownFeed') return new UnknownFeedError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getLikes.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getLikes' export type QueryParams = { /** AT-URI of the subject (eg, a post record). */ uri: string /** CID of the subject record (aka, specific version of record), to filter likes. */ cid?: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { uri: string cid?: string cursor?: string likes: Like[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface Like { $type?: 'app.bsky.feed.getLikes#like' indexedAt: string createdAt: string actor: AppBskyActorDefs.ProfileView } const hashLike = 'like' export function isLike(v: V) { return is$typed(v, id, hashLike) } export function validateLike(v: V) { return validate(v, id, hashLike) } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getListFeed.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getListFeed' export type QueryParams = { /** Reference (AT-URI) to the list record. */ list: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feed: AppBskyFeedDefs.FeedViewPost[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class UnknownListError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'UnknownList') return new UnknownListError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getPostThread.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getPostThread' export type QueryParams = { /** Reference (AT-URI) to post record. */ uri: string /** How many levels of reply depth should be included in response. */ depth?: number /** How many levels of parent (and grandparent, etc) post to include. */ parentHeight?: number } export type InputSchema = undefined export interface OutputSchema { thread: | $Typed | $Typed | $Typed | { $type: string } threadgate?: AppBskyFeedDefs.ThreadgateView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class NotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'NotFound') return new NotFoundError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getPosts.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getPosts' export type QueryParams = { /** List of post AT-URIs to return hydrated views for. */ uris: string[] } export type InputSchema = undefined export interface OutputSchema { posts: AppBskyFeedDefs.PostView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getQuotes.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getQuotes' export type QueryParams = { /** Reference (AT-URI) of post record */ uri: string /** If supplied, filters to quotes of specific version (by CID) of the post record. */ cid?: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { uri: string cid?: string cursor?: string posts: AppBskyFeedDefs.PostView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getRepostedBy.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getRepostedBy' export type QueryParams = { /** Reference (AT-URI) of post record */ uri: string /** If supplied, filters to reposts of specific version (by CID) of the post record. */ cid?: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { uri: string cid?: string cursor?: string repostedBy: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getSuggestedFeeds.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getSuggestedFeeds' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feeds: AppBskyFeedDefs.GeneratorView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/getTimeline.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.getTimeline' export type QueryParams = { /** Variant 'algorithm' for timeline. Implementation-specific. NOTE: most feed flexibility has been moved to feed generator mechanism. */ algorithm?: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feed: AppBskyFeedDefs.FeedViewPost[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/like.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.like' export interface Main { $type: 'app.bsky.feed.like' subject: ComAtprotoRepoStrongRef.Main createdAt: string via?: ComAtprotoRepoStrongRef.Main [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/post.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyRichtextFacet from '../richtext/facet.js' import type * as AppBskyEmbedImages from '../embed/images.js' import type * as AppBskyEmbedVideo from '../embed/video.js' import type * as AppBskyEmbedExternal from '../embed/external.js' import type * as AppBskyEmbedRecord from '../embed/record.js' import type * as AppBskyEmbedRecordWithMedia from '../embed/recordWithMedia.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.post' export interface Main { $type: 'app.bsky.feed.post' /** The primary post content. May be an empty string, if there are embeds. */ text: string /** DEPRECATED: replaced by app.bsky.richtext.facet. */ entities?: Entity[] /** Annotations of text (mentions, URLs, hashtags, etc) */ facets?: AppBskyRichtextFacet.Main[] reply?: ReplyRef embed?: | $Typed | $Typed | $Typed | $Typed | $Typed | { $type: string } /** Indicates human language of post primary text content. */ langs?: string[] labels?: $Typed | { $type: string } /** Additional hashtags, in addition to any included in post text and facets. */ tags?: string[] /** Client-declared timestamp when this post was originally created. */ createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } export interface ReplyRef { $type?: 'app.bsky.feed.post#replyRef' root: ComAtprotoRepoStrongRef.Main parent: ComAtprotoRepoStrongRef.Main } const hashReplyRef = 'replyRef' export function isReplyRef(v: V) { return is$typed(v, id, hashReplyRef) } export function validateReplyRef(v: V) { return validate(v, id, hashReplyRef) } /** Deprecated: use facets instead. */ export interface Entity { $type?: 'app.bsky.feed.post#entity' index: TextSlice /** Expected values are 'mention' and 'link'. */ type: string value: string } const hashEntity = 'entity' export function isEntity(v: V) { return is$typed(v, id, hashEntity) } export function validateEntity(v: V) { return validate(v, id, hashEntity) } /** Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings. */ export interface TextSlice { $type?: 'app.bsky.feed.post#textSlice' start: number end: number } const hashTextSlice = 'textSlice' export function isTextSlice(v: V) { return is$typed(v, id, hashTextSlice) } export function validateTextSlice(v: V) { return validate(v, id, hashTextSlice) } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/postgate.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.postgate' export interface Main { $type: 'app.bsky.feed.postgate' createdAt: string /** Reference (AT-URI) to the post record. */ post: string /** List of AT-URIs embedding this post that the author has detached from. */ detachedEmbeddingUris?: string[] /** List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed. */ embeddingRules?: ($Typed | { $type: string })[] [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } /** Disables embedding of this post. */ export interface DisableRule { $type?: 'app.bsky.feed.postgate#disableRule' } const hashDisableRule = 'disableRule' export function isDisableRule(v: V) { return is$typed(v, id, hashDisableRule) } export function validateDisableRule(v: V) { return validate(v, id, hashDisableRule) } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/repost.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.repost' export interface Main { $type: 'app.bsky.feed.repost' subject: ComAtprotoRepoStrongRef.Main createdAt: string via?: ComAtprotoRepoStrongRef.Main [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/searchPosts.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.searchPosts' export type QueryParams = { /** Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. */ q: string /** Specifies the ranking order of results. */ sort?: 'top' | 'latest' | (string & {}) /** Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD). */ since?: string /** Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD). */ until?: string /** Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions. */ mentions?: string /** Filter to posts by the given account. Handles are resolved to DID before query-time. */ author?: string /** Filter to posts in the given language. Expected to be based on post language field, though server may override language detection. */ lang?: string /** Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization. */ domain?: string /** Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching. */ url?: string /** Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching. */ tag?: string[] limit?: number /** Optional pagination mechanism; may not necessarily allow scrolling through entire result set. */ cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string /** Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits. */ hitsTotal?: number posts: AppBskyFeedDefs.PostView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class BadQueryStringError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'BadQueryString') return new BadQueryStringError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/sendInteractions.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.sendInteractions' export type QueryParams = {} export interface InputSchema { feed?: string interactions: AppBskyFeedDefs.Interaction[] } export interface OutputSchema {} export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/feed/threadgate.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.feed.threadgate' export interface Main { $type: 'app.bsky.feed.threadgate' /** Reference (AT-URI) to the post record. */ post: string /** List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply. */ allow?: ( | $Typed | $Typed | $Typed | $Typed | { $type: string } )[] createdAt: string /** List of hidden reply URIs. */ hiddenReplies?: string[] [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } /** Allow replies from actors mentioned in your post. */ export interface MentionRule { $type?: 'app.bsky.feed.threadgate#mentionRule' } const hashMentionRule = 'mentionRule' export function isMentionRule(v: V) { return is$typed(v, id, hashMentionRule) } export function validateMentionRule(v: V) { return validate(v, id, hashMentionRule) } /** Allow replies from actors who follow you. */ export interface FollowerRule { $type?: 'app.bsky.feed.threadgate#followerRule' } const hashFollowerRule = 'followerRule' export function isFollowerRule(v: V) { return is$typed(v, id, hashFollowerRule) } export function validateFollowerRule(v: V) { return validate(v, id, hashFollowerRule) } /** Allow replies from actors you follow. */ export interface FollowingRule { $type?: 'app.bsky.feed.threadgate#followingRule' } const hashFollowingRule = 'followingRule' export function isFollowingRule(v: V) { return is$typed(v, id, hashFollowingRule) } export function validateFollowingRule(v: V) { return validate(v, id, hashFollowingRule) } /** Allow replies from actors on a list. */ export interface ListRule { $type?: 'app.bsky.feed.threadgate#listRule' list: string } const hashListRule = 'listRule' export function isListRule(v: V) { return is$typed(v, id, hashListRule) } export function validateListRule(v: V) { return validate(v, id, hashListRule) } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/block.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.block' export interface Main { $type: 'app.bsky.graph.block' /** DID of the account to be blocked. */ subject: string createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as AppBskyActorDefs from '../actor/defs.js' import type * as AppBskyRichtextFacet from '../richtext/facet.js' import type * as AppBskyFeedDefs from '../feed/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.defs' export interface ListViewBasic { $type?: 'app.bsky.graph.defs#listViewBasic' uri: string cid: string name: string purpose: ListPurpose avatar?: string listItemCount?: number labels?: ComAtprotoLabelDefs.Label[] viewer?: ListViewerState indexedAt?: string } const hashListViewBasic = 'listViewBasic' export function isListViewBasic(v: V) { return is$typed(v, id, hashListViewBasic) } export function validateListViewBasic(v: V) { return validate(v, id, hashListViewBasic) } export interface ListView { $type?: 'app.bsky.graph.defs#listView' uri: string cid: string creator: AppBskyActorDefs.ProfileView name: string purpose: ListPurpose description?: string descriptionFacets?: AppBskyRichtextFacet.Main[] avatar?: string listItemCount?: number labels?: ComAtprotoLabelDefs.Label[] viewer?: ListViewerState indexedAt: string } const hashListView = 'listView' export function isListView(v: V) { return is$typed(v, id, hashListView) } export function validateListView(v: V) { return validate(v, id, hashListView) } export interface ListItemView { $type?: 'app.bsky.graph.defs#listItemView' uri: string subject: AppBskyActorDefs.ProfileView } const hashListItemView = 'listItemView' export function isListItemView(v: V) { return is$typed(v, id, hashListItemView) } export function validateListItemView(v: V) { return validate(v, id, hashListItemView) } export interface StarterPackView { $type?: 'app.bsky.graph.defs#starterPackView' uri: string cid: string record: { [_ in string]: unknown } creator: AppBskyActorDefs.ProfileViewBasic list?: ListViewBasic listItemsSample?: ListItemView[] feeds?: AppBskyFeedDefs.GeneratorView[] joinedWeekCount?: number joinedAllTimeCount?: number labels?: ComAtprotoLabelDefs.Label[] indexedAt: string } const hashStarterPackView = 'starterPackView' export function isStarterPackView(v: V) { return is$typed(v, id, hashStarterPackView) } export function validateStarterPackView(v: V) { return validate(v, id, hashStarterPackView) } export interface StarterPackViewBasic { $type?: 'app.bsky.graph.defs#starterPackViewBasic' uri: string cid: string record: { [_ in string]: unknown } creator: AppBskyActorDefs.ProfileViewBasic listItemCount?: number joinedWeekCount?: number joinedAllTimeCount?: number labels?: ComAtprotoLabelDefs.Label[] indexedAt: string } const hashStarterPackViewBasic = 'starterPackViewBasic' export function isStarterPackViewBasic(v: V) { return is$typed(v, id, hashStarterPackViewBasic) } export function validateStarterPackViewBasic(v: V) { return validate(v, id, hashStarterPackViewBasic) } export type ListPurpose = | 'app.bsky.graph.defs#modlist' | 'app.bsky.graph.defs#curatelist' | 'app.bsky.graph.defs#referencelist' | (string & {}) /** A list of actors to apply an aggregate moderation action (mute/block) on. */ export const MODLIST = `${id}#modlist` /** A list of actors used for curation purposes such as list feeds or interaction gating. */ export const CURATELIST = `${id}#curatelist` /** A list of actors used for only for reference purposes such as within a starter pack. */ export const REFERENCELIST = `${id}#referencelist` export interface ListViewerState { $type?: 'app.bsky.graph.defs#listViewerState' muted?: boolean blocked?: string } const hashListViewerState = 'listViewerState' export function isListViewerState(v: V) { return is$typed(v, id, hashListViewerState) } export function validateListViewerState(v: V) { return validate(v, id, hashListViewerState) } /** indicates that a handle or DID could not be resolved */ export interface NotFoundActor { $type?: 'app.bsky.graph.defs#notFoundActor' actor: string notFound: true } const hashNotFoundActor = 'notFoundActor' export function isNotFoundActor(v: V) { return is$typed(v, id, hashNotFoundActor) } export function validateNotFoundActor(v: V) { return validate(v, id, hashNotFoundActor) } /** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ export interface Relationship { $type?: 'app.bsky.graph.defs#relationship' did: string /** if the actor follows this DID, this is the AT-URI of the follow record */ following?: string /** if the actor is followed by this DID, contains the AT-URI of the follow record */ followedBy?: string /** if the actor blocks this DID, this is the AT-URI of the block record */ blocking?: string /** if the actor is blocked by this DID, contains the AT-URI of the block record */ blockedBy?: string /** if the actor blocks this DID via a block list, this is the AT-URI of the listblock record */ blockingByList?: string /** if the actor is blocked by this DID via a block list, contains the AT-URI of the listblock record */ blockedByList?: string } const hashRelationship = 'relationship' export function isRelationship(v: V) { return is$typed(v, id, hashRelationship) } export function validateRelationship(v: V) { return validate(v, id, hashRelationship) } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/follow.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.follow' export interface Main { $type: 'app.bsky.graph.follow' subject: string createdAt: string via?: ComAtprotoRepoStrongRef.Main [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getActorStarterPacks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getActorStarterPacks' export type QueryParams = { actor: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string starterPacks: AppBskyGraphDefs.StarterPackViewBasic[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getBlocks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getBlocks' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string blocks: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getFollowers.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getFollowers' export type QueryParams = { actor: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { subject: AppBskyActorDefs.ProfileView cursor?: string followers: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getFollows.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getFollows' export type QueryParams = { actor: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { subject: AppBskyActorDefs.ProfileView cursor?: string follows: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getKnownFollowers.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getKnownFollowers' export type QueryParams = { actor: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { subject: AppBskyActorDefs.ProfileView cursor?: string followers: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getList.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getList' export type QueryParams = { /** Reference (AT-URI) of the list record to hydrate. */ list: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string list: AppBskyGraphDefs.ListView items: AppBskyGraphDefs.ListItemView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getListBlocks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getListBlocks' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string lists: AppBskyGraphDefs.ListView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getListMutes.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getListMutes' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string lists: AppBskyGraphDefs.ListView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getLists.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getLists' export type QueryParams = { /** The account (actor) to enumerate lists from. */ actor: string limit?: number cursor?: string /** Optional filter by list purpose. If not specified, all supported types are returned. */ purposes?: 'modlist' | 'curatelist' | (string & {})[] } export type InputSchema = undefined export interface OutputSchema { cursor?: string lists: AppBskyGraphDefs.ListView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getListsWithMembership.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getListsWithMembership' export type QueryParams = { /** The account (actor) to check for membership. */ actor: string limit?: number cursor?: string /** Optional filter by list purpose. If not specified, all supported types are returned. */ purposes?: 'modlist' | 'curatelist' | (string & {})[] } export type InputSchema = undefined export interface OutputSchema { cursor?: string listsWithMembership: ListWithMembership[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } /** A list and an optional list item indicating membership of a target user to that list. */ export interface ListWithMembership { $type?: 'app.bsky.graph.getListsWithMembership#listWithMembership' list: AppBskyGraphDefs.ListView listItem?: AppBskyGraphDefs.ListItemView } const hashListWithMembership = 'listWithMembership' export function isListWithMembership(v: V) { return is$typed(v, id, hashListWithMembership) } export function validateListWithMembership(v: V) { return validate(v, id, hashListWithMembership) } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getMutes.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getMutes' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string mutes: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getRelationships.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getRelationships' export type QueryParams = { /** Primary account requesting relationships for. */ actor: string /** List of 'other' accounts to be related back to the primary. */ others?: string[] } export type InputSchema = undefined export interface OutputSchema { actor?: string relationships: ( | $Typed | $Typed | { $type: string } )[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class ActorNotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'ActorNotFound') return new ActorNotFoundError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getStarterPack.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getStarterPack' export type QueryParams = { /** Reference (AT-URI) of the starter pack record. */ starterPack: string } export type InputSchema = undefined export interface OutputSchema { starterPack: AppBskyGraphDefs.StarterPackView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getStarterPacks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getStarterPacks' export type QueryParams = { uris: string[] } export type InputSchema = undefined export interface OutputSchema { starterPacks: AppBskyGraphDefs.StarterPackViewBasic[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getStarterPacksWithMembership.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getStarterPacksWithMembership' export type QueryParams = { /** The account (actor) to check for membership. */ actor: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string starterPacksWithMembership: StarterPackWithMembership[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } /** A starter pack and an optional list item indicating membership of a target user to that starter pack. */ export interface StarterPackWithMembership { $type?: 'app.bsky.graph.getStarterPacksWithMembership#starterPackWithMembership' starterPack: AppBskyGraphDefs.StarterPackView listItem?: AppBskyGraphDefs.ListItemView } const hashStarterPackWithMembership = 'starterPackWithMembership' export function isStarterPackWithMembership(v: V) { return is$typed(v, id, hashStarterPackWithMembership) } export function validateStarterPackWithMembership(v: V) { return validate( v, id, hashStarterPackWithMembership, ) } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/getSuggestedFollowsByActor.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.getSuggestedFollowsByActor' export type QueryParams = { actor: string } export type InputSchema = undefined export interface OutputSchema { suggestions: AppBskyActorDefs.ProfileView[] /** Snowflake for this recommendation, use when submitting recommendation events. */ recIdStr?: string /** DEPRECATED, unused. Previously: if true, response has fallen-back to generic results, and is not scoped using relativeToDid */ isFallback: boolean /** DEPRECATED: use recIdStr instead. */ recId?: number } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/list.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' import type * as AppBskyRichtextFacet from '../richtext/facet.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.list' export interface Main { $type: 'app.bsky.graph.list' purpose: AppBskyGraphDefs.ListPurpose /** Display name for list; can not be empty. */ name: string description?: string descriptionFacets?: AppBskyRichtextFacet.Main[] avatar?: BlobRef labels?: $Typed | { $type: string } createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/listblock.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.listblock' export interface Main { $type: 'app.bsky.graph.listblock' /** Reference (AT-URI) to the mod list record. */ subject: string createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/listitem.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.listitem' export interface Main { $type: 'app.bsky.graph.listitem' /** The account which is included on the list. */ subject: string /** Reference (AT-URI) to the list record (app.bsky.graph.list). */ list: string createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/muteActor.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.muteActor' export type QueryParams = {} export interface InputSchema { actor: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/muteActorList.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.muteActorList' export type QueryParams = {} export interface InputSchema { list: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/muteThread.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.muteThread' export type QueryParams = {} export interface InputSchema { root: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/searchStarterPacks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.searchStarterPacks' export type QueryParams = { /** Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. */ q: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string starterPacks: AppBskyGraphDefs.StarterPackViewBasic[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/starterpack.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyRichtextFacet from '../richtext/facet.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.starterpack' export interface Main { $type: 'app.bsky.graph.starterpack' /** Display name for starter pack; can not be empty. */ name: string description?: string descriptionFacets?: AppBskyRichtextFacet.Main[] /** Reference (AT-URI) to the list record. */ list: string feeds?: FeedItem[] createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } export interface FeedItem { $type?: 'app.bsky.graph.starterpack#feedItem' uri: string } const hashFeedItem = 'feedItem' export function isFeedItem(v: V) { return is$typed(v, id, hashFeedItem) } export function validateFeedItem(v: V) { return validate(v, id, hashFeedItem) } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/unmuteActor.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.unmuteActor' export type QueryParams = {} export interface InputSchema { actor: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/unmuteActorList.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.unmuteActorList' export type QueryParams = {} export interface InputSchema { list: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/unmuteThread.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.unmuteThread' export type QueryParams = {} export interface InputSchema { root: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/graph/verification.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.graph.verification' export interface Main { $type: 'app.bsky.graph.verification' /** DID of the subject the verification applies to. */ subject: string /** Handle of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current handle matches the one at the time of verifying. */ handle: string /** Display name of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current displayName matches the one at the time of verifying. */ displayName: string /** Date of when the verification was created. */ createdAt: string [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/labeler/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as ComAtprotoModerationDefs from '../../../com/atproto/moderation/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.labeler.defs' export interface LabelerView { $type?: 'app.bsky.labeler.defs#labelerView' uri: string cid: string creator: AppBskyActorDefs.ProfileView likeCount?: number viewer?: LabelerViewerState indexedAt: string labels?: ComAtprotoLabelDefs.Label[] } const hashLabelerView = 'labelerView' export function isLabelerView(v: V) { return is$typed(v, id, hashLabelerView) } export function validateLabelerView(v: V) { return validate(v, id, hashLabelerView) } export interface LabelerViewDetailed { $type?: 'app.bsky.labeler.defs#labelerViewDetailed' uri: string cid: string creator: AppBskyActorDefs.ProfileView policies: LabelerPolicies likeCount?: number viewer?: LabelerViewerState indexedAt: string labels?: ComAtprotoLabelDefs.Label[] /** The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed. */ reasonTypes?: ComAtprotoModerationDefs.ReasonType[] /** The set of subject types (account, record, etc) this service accepts reports on. */ subjectTypes?: ComAtprotoModerationDefs.SubjectType[] /** Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type. */ subjectCollections?: string[] } const hashLabelerViewDetailed = 'labelerViewDetailed' export function isLabelerViewDetailed(v: V) { return is$typed(v, id, hashLabelerViewDetailed) } export function validateLabelerViewDetailed(v: V) { return validate(v, id, hashLabelerViewDetailed) } export interface LabelerViewerState { $type?: 'app.bsky.labeler.defs#labelerViewerState' like?: string } const hashLabelerViewerState = 'labelerViewerState' export function isLabelerViewerState(v: V) { return is$typed(v, id, hashLabelerViewerState) } export function validateLabelerViewerState(v: V) { return validate(v, id, hashLabelerViewerState) } export interface LabelerPolicies { $type?: 'app.bsky.labeler.defs#labelerPolicies' /** The label values which this labeler publishes. May include global or custom labels. */ labelValues: ComAtprotoLabelDefs.LabelValue[] /** Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler. */ labelValueDefinitions?: ComAtprotoLabelDefs.LabelValueDefinition[] } const hashLabelerPolicies = 'labelerPolicies' export function isLabelerPolicies(v: V) { return is$typed(v, id, hashLabelerPolicies) } export function validateLabelerPolicies(v: V) { return validate(v, id, hashLabelerPolicies) } ================================================ FILE: packages/api/src/client/types/app/bsky/labeler/getServices.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyLabelerDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.labeler.getServices' export type QueryParams = { dids: string[] detailed?: boolean } export type InputSchema = undefined export interface OutputSchema { views: ( | $Typed | $Typed | { $type: string } )[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/labeler/service.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyLabelerDefs from './defs.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' import type * as ComAtprotoModerationDefs from '../../../com/atproto/moderation/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.labeler.service' export interface Main { $type: 'app.bsky.labeler.service' policies: AppBskyLabelerDefs.LabelerPolicies labels?: $Typed | { $type: string } createdAt: string /** The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed. */ reasonTypes?: ComAtprotoModerationDefs.ReasonType[] /** The set of subject types (account, record, etc) this service accepts reports on. */ subjectTypes?: ComAtprotoModerationDefs.SubjectType[] /** Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type. */ subjectCollections?: string[] [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/declaration.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.declaration' export interface Main { $type: 'app.bsky.notification.declaration' /** A declaration of the user's preference for allowing activity subscriptions from other users. Absence of a record implies 'followers'. */ allowSubscriptions: 'followers' | 'mutuals' | 'none' | (string & {}) [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.defs' export interface RecordDeleted { $type?: 'app.bsky.notification.defs#recordDeleted' } const hashRecordDeleted = 'recordDeleted' export function isRecordDeleted(v: V) { return is$typed(v, id, hashRecordDeleted) } export function validateRecordDeleted(v: V) { return validate(v, id, hashRecordDeleted) } export interface ChatPreference { $type?: 'app.bsky.notification.defs#chatPreference' include: 'all' | 'accepted' | (string & {}) push: boolean } const hashChatPreference = 'chatPreference' export function isChatPreference(v: V) { return is$typed(v, id, hashChatPreference) } export function validateChatPreference(v: V) { return validate(v, id, hashChatPreference) } export interface FilterablePreference { $type?: 'app.bsky.notification.defs#filterablePreference' include: 'all' | 'follows' | (string & {}) list: boolean push: boolean } const hashFilterablePreference = 'filterablePreference' export function isFilterablePreference(v: V) { return is$typed(v, id, hashFilterablePreference) } export function validateFilterablePreference(v: V) { return validate(v, id, hashFilterablePreference) } export interface Preference { $type?: 'app.bsky.notification.defs#preference' list: boolean push: boolean } const hashPreference = 'preference' export function isPreference(v: V) { return is$typed(v, id, hashPreference) } export function validatePreference(v: V) { return validate(v, id, hashPreference) } export interface Preferences { $type?: 'app.bsky.notification.defs#preferences' chat: ChatPreference follow: FilterablePreference like: FilterablePreference likeViaRepost: FilterablePreference mention: FilterablePreference quote: FilterablePreference reply: FilterablePreference repost: FilterablePreference repostViaRepost: FilterablePreference starterpackJoined: Preference subscribedPost: Preference unverified: Preference verified: Preference } const hashPreferences = 'preferences' export function isPreferences(v: V) { return is$typed(v, id, hashPreferences) } export function validatePreferences(v: V) { return validate(v, id, hashPreferences) } export interface ActivitySubscription { $type?: 'app.bsky.notification.defs#activitySubscription' post: boolean reply: boolean } const hashActivitySubscription = 'activitySubscription' export function isActivitySubscription(v: V) { return is$typed(v, id, hashActivitySubscription) } export function validateActivitySubscription(v: V) { return validate(v, id, hashActivitySubscription) } /** Object used to store activity subscription data in stash. */ export interface SubjectActivitySubscription { $type?: 'app.bsky.notification.defs#subjectActivitySubscription' subject: string activitySubscription: ActivitySubscription } const hashSubjectActivitySubscription = 'subjectActivitySubscription' export function isSubjectActivitySubscription(v: V) { return is$typed(v, id, hashSubjectActivitySubscription) } export function validateSubjectActivitySubscription(v: V) { return validate( v, id, hashSubjectActivitySubscription, ) } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/getPreferences.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyNotificationDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.getPreferences' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { preferences: AppBskyNotificationDefs.Preferences } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/getUnreadCount.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.getUnreadCount' export type QueryParams = { priority?: boolean seenAt?: string } export type InputSchema = undefined export interface OutputSchema { count: number } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/listActivitySubscriptions.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.listActivitySubscriptions' export type QueryParams = { limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string subscriptions: AppBskyActorDefs.ProfileView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/listNotifications.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.listNotifications' export type QueryParams = { /** Notification reasons to include in response. */ reasons?: string[] limit?: number priority?: boolean cursor?: string seenAt?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string notifications: Notification[] priority?: boolean seenAt?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface Notification { $type?: 'app.bsky.notification.listNotifications#notification' uri: string cid: string author: AppBskyActorDefs.ProfileView /** The reason why this notification was delivered - e.g. your post was liked, or you received a new follower. */ reason: | 'like' | 'repost' | 'follow' | 'mention' | 'reply' | 'quote' | 'starterpack-joined' | 'verified' | 'unverified' | 'like-via-repost' | 'repost-via-repost' | 'subscribed-post' | 'contact-match' | (string & {}) reasonSubject?: string record: { [_ in string]: unknown } isRead: boolean indexedAt: string labels?: ComAtprotoLabelDefs.Label[] } const hashNotification = 'notification' export function isNotification(v: V) { return is$typed(v, id, hashNotification) } export function validateNotification(v: V) { return validate(v, id, hashNotification) } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/putActivitySubscription.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyNotificationDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.putActivitySubscription' export type QueryParams = {} export interface InputSchema { subject: string activitySubscription: AppBskyNotificationDefs.ActivitySubscription } export interface OutputSchema { subject: string activitySubscription?: AppBskyNotificationDefs.ActivitySubscription } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/putPreferences.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.putPreferences' export type QueryParams = {} export interface InputSchema { priority: boolean } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/putPreferencesV2.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyNotificationDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.putPreferencesV2' export type QueryParams = {} export interface InputSchema { chat?: AppBskyNotificationDefs.ChatPreference follow?: AppBskyNotificationDefs.FilterablePreference like?: AppBskyNotificationDefs.FilterablePreference likeViaRepost?: AppBskyNotificationDefs.FilterablePreference mention?: AppBskyNotificationDefs.FilterablePreference quote?: AppBskyNotificationDefs.FilterablePreference reply?: AppBskyNotificationDefs.FilterablePreference repost?: AppBskyNotificationDefs.FilterablePreference repostViaRepost?: AppBskyNotificationDefs.FilterablePreference starterpackJoined?: AppBskyNotificationDefs.Preference subscribedPost?: AppBskyNotificationDefs.Preference unverified?: AppBskyNotificationDefs.Preference verified?: AppBskyNotificationDefs.Preference } export interface OutputSchema { preferences: AppBskyNotificationDefs.Preferences } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/registerPush.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.registerPush' export type QueryParams = {} export interface InputSchema { serviceDid: string token: string platform: 'ios' | 'android' | 'web' | (string & {}) appId: string /** Set to true when the actor is age restricted */ ageRestricted?: boolean } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/unregisterPush.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.unregisterPush' export type QueryParams = {} export interface InputSchema { serviceDid: string token: string platform: 'ios' | 'android' | 'web' | (string & {}) appId: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/notification/updateSeen.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.notification.updateSeen' export type QueryParams = {} export interface InputSchema { seenAt: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/richtext/facet.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.richtext.facet' /** Annotation of a sub-string within rich text. */ export interface Main { $type?: 'app.bsky.richtext.facet' index: ByteSlice features: ($Typed | $Typed | $Typed | { $type: string })[] } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain) } /** Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID. */ export interface Mention { $type?: 'app.bsky.richtext.facet#mention' did: string } const hashMention = 'mention' export function isMention(v: V) { return is$typed(v, id, hashMention) } export function validateMention(v: V) { return validate(v, id, hashMention) } /** Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. */ export interface Link { $type?: 'app.bsky.richtext.facet#link' uri: string } const hashLink = 'link' export function isLink(v: V) { return is$typed(v, id, hashLink) } export function validateLink(v: V) { return validate(v, id, hashLink) } /** Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags'). */ export interface Tag { $type?: 'app.bsky.richtext.facet#tag' tag: string } const hashTag = 'tag' export function isTag(v: V) { return is$typed(v, id, hashTag) } export function validateTag(v: V) { return validate(v, id, hashTag) } /** Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets. */ export interface ByteSlice { $type?: 'app.bsky.richtext.facet#byteSlice' byteStart: number byteEnd: number } const hashByteSlice = 'byteSlice' export function isByteSlice(v: V) { return is$typed(v, id, hashByteSlice) } export function validateByteSlice(v: V) { return validate(v, id, hashByteSlice) } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' import type * as AppBskyFeedDefs from '../feed/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.defs' export interface SkeletonSearchPost { $type?: 'app.bsky.unspecced.defs#skeletonSearchPost' uri: string } const hashSkeletonSearchPost = 'skeletonSearchPost' export function isSkeletonSearchPost(v: V) { return is$typed(v, id, hashSkeletonSearchPost) } export function validateSkeletonSearchPost(v: V) { return validate(v, id, hashSkeletonSearchPost) } export interface SkeletonSearchActor { $type?: 'app.bsky.unspecced.defs#skeletonSearchActor' did: string } const hashSkeletonSearchActor = 'skeletonSearchActor' export function isSkeletonSearchActor(v: V) { return is$typed(v, id, hashSkeletonSearchActor) } export function validateSkeletonSearchActor(v: V) { return validate(v, id, hashSkeletonSearchActor) } export interface SkeletonSearchStarterPack { $type?: 'app.bsky.unspecced.defs#skeletonSearchStarterPack' uri: string } const hashSkeletonSearchStarterPack = 'skeletonSearchStarterPack' export function isSkeletonSearchStarterPack(v: V) { return is$typed(v, id, hashSkeletonSearchStarterPack) } export function validateSkeletonSearchStarterPack(v: V) { return validate( v, id, hashSkeletonSearchStarterPack, ) } export interface TrendingTopic { $type?: 'app.bsky.unspecced.defs#trendingTopic' topic: string displayName?: string description?: string link: string } const hashTrendingTopic = 'trendingTopic' export function isTrendingTopic(v: V) { return is$typed(v, id, hashTrendingTopic) } export function validateTrendingTopic(v: V) { return validate(v, id, hashTrendingTopic) } export interface SkeletonTrend { $type?: 'app.bsky.unspecced.defs#skeletonTrend' topic: string displayName: string link: string startedAt: string postCount: number status?: 'hot' | (string & {}) category?: string dids: string[] } const hashSkeletonTrend = 'skeletonTrend' export function isSkeletonTrend(v: V) { return is$typed(v, id, hashSkeletonTrend) } export function validateSkeletonTrend(v: V) { return validate(v, id, hashSkeletonTrend) } export interface TrendView { $type?: 'app.bsky.unspecced.defs#trendView' topic: string displayName: string link: string startedAt: string postCount: number status?: 'hot' | (string & {}) category?: string actors: AppBskyActorDefs.ProfileViewBasic[] } const hashTrendView = 'trendView' export function isTrendView(v: V) { return is$typed(v, id, hashTrendView) } export function validateTrendView(v: V) { return validate(v, id, hashTrendView) } export interface ThreadItemPost { $type?: 'app.bsky.unspecced.defs#threadItemPost' post: AppBskyFeedDefs.PostView /** This post has more parents that were not present in the response. This is just a boolean, without the number of parents. */ moreParents: boolean /** This post has more replies that were not present in the response. This is a numeric value, which is best-effort and might not be accurate. */ moreReplies: number /** This post is part of a contiguous thread by the OP from the thread root. Many different OP threads can happen in the same thread. */ opThread: boolean /** The threadgate created by the author indicates this post as a reply to be hidden for everyone consuming the thread. */ hiddenByThreadgate: boolean /** This is by an account muted by the viewer requesting it. */ mutedByViewer: boolean } const hashThreadItemPost = 'threadItemPost' export function isThreadItemPost(v: V) { return is$typed(v, id, hashThreadItemPost) } export function validateThreadItemPost(v: V) { return validate(v, id, hashThreadItemPost) } export interface ThreadItemNoUnauthenticated { $type?: 'app.bsky.unspecced.defs#threadItemNoUnauthenticated' } const hashThreadItemNoUnauthenticated = 'threadItemNoUnauthenticated' export function isThreadItemNoUnauthenticated(v: V) { return is$typed(v, id, hashThreadItemNoUnauthenticated) } export function validateThreadItemNoUnauthenticated(v: V) { return validate( v, id, hashThreadItemNoUnauthenticated, ) } export interface ThreadItemNotFound { $type?: 'app.bsky.unspecced.defs#threadItemNotFound' } const hashThreadItemNotFound = 'threadItemNotFound' export function isThreadItemNotFound(v: V) { return is$typed(v, id, hashThreadItemNotFound) } export function validateThreadItemNotFound(v: V) { return validate(v, id, hashThreadItemNotFound) } export interface ThreadItemBlocked { $type?: 'app.bsky.unspecced.defs#threadItemBlocked' author: AppBskyFeedDefs.BlockedAuthor } const hashThreadItemBlocked = 'threadItemBlocked' export function isThreadItemBlocked(v: V) { return is$typed(v, id, hashThreadItemBlocked) } export function validateThreadItemBlocked(v: V) { return validate(v, id, hashThreadItemBlocked) } /** The computed state of the age assurance process, returned to the user in question on certain authenticated requests. */ export interface AgeAssuranceState { $type?: 'app.bsky.unspecced.defs#ageAssuranceState' /** The timestamp when this state was last updated. */ lastInitiatedAt?: string /** The status of the age assurance process. */ status: 'unknown' | 'pending' | 'assured' | 'blocked' | (string & {}) } const hashAgeAssuranceState = 'ageAssuranceState' export function isAgeAssuranceState(v: V) { return is$typed(v, id, hashAgeAssuranceState) } export function validateAgeAssuranceState(v: V) { return validate(v, id, hashAgeAssuranceState) } /** Object used to store age assurance data in stash. */ export interface AgeAssuranceEvent { $type?: 'app.bsky.unspecced.defs#ageAssuranceEvent' /** The date and time of this write operation. */ createdAt: string /** The status of the age assurance process. */ status: 'unknown' | 'pending' | 'assured' | (string & {}) /** The unique identifier for this instance of the age assurance flow, in UUID format. */ attemptId: string /** The email used for AA. */ email?: string /** The IP address used when initiating the AA flow. */ initIp?: string /** The user agent used when initiating the AA flow. */ initUa?: string /** The IP address used when completing the AA flow. */ completeIp?: string /** The user agent used when completing the AA flow. */ completeUa?: string } const hashAgeAssuranceEvent = 'ageAssuranceEvent' export function isAgeAssuranceEvent(v: V) { return is$typed(v, id, hashAgeAssuranceEvent) } export function validateAgeAssuranceEvent(v: V) { return validate(v, id, hashAgeAssuranceEvent) } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getAgeAssuranceState.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getAgeAssuranceState' export type QueryParams = {} export type InputSchema = undefined export type OutputSchema = AppBskyUnspeccedDefs.AgeAssuranceState export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getConfig.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getConfig' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { checkEmailConfirmed?: boolean liveNow?: LiveNowConfig[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface LiveNowConfig { $type?: 'app.bsky.unspecced.getConfig#liveNowConfig' did: string domains: string[] } const hashLiveNowConfig = 'liveNowConfig' export function isLiveNowConfig(v: V) { return is$typed(v, id, hashLiveNowConfig) } export function validateLiveNowConfig(v: V) { return validate(v, id, hashLiveNowConfig) } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from '../graph/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks' export type QueryParams = { limit?: number } export type InputSchema = undefined export interface OutputSchema { starterPacks: AppBskyGraphDefs.StarterPackView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). */ viewer?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { starterPacks: string[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). */ viewer?: string /** Category of users to get suggestions for. */ category?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { dids: string[] /** DEPRECATED: use recIdStr instead. */ recId?: string /** Snowflake for this recommendation, use when submitting recommendation events. */ recIdStr?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getPopularFeedGenerators.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from '../feed/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getPopularFeedGenerators' export type QueryParams = { limit?: number cursor?: string query?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string feeds: AppBskyFeedDefs.GeneratorView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getPostThreadOtherV2.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getPostThreadOtherV2' export type QueryParams = { /** Reference (AT-URI) to post record. This is the anchor post. */ anchor: string } export type InputSchema = undefined export interface OutputSchema { /** A flat list of other thread items. The depth of each item is indicated by the depth property inside the item. */ thread: ThreadItem[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface ThreadItem { $type?: 'app.bsky.unspecced.getPostThreadOtherV2#threadItem' uri: string /** The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths. */ depth: number value: $Typed | { $type: string } } const hashThreadItem = 'threadItem' export function isThreadItem(v: V) { return is$typed(v, id, hashThreadItem) } export function validateThreadItem(v: V) { return validate(v, id, hashThreadItem) } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getPostThreadV2.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from '../feed/defs.js' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getPostThreadV2' export type QueryParams = { /** Reference (AT-URI) to post record. This is the anchor post, and the thread will be built around it. It can be any post in the tree, not necessarily a root post. */ anchor: string /** Whether to include parents above the anchor. */ above?: boolean /** How many levels of replies to include below the anchor. */ below?: number /** Maximum of replies to include at each level of the thread, except for the direct replies to the anchor, which are (NOTE: currently, during unspecced phase) all returned (NOTE: later they might be paginated). */ branchingFactor?: number /** Sorting for the thread replies. */ sort?: 'newest' | 'oldest' | 'top' | (string & {}) } export type InputSchema = undefined export interface OutputSchema { /** A flat list of thread items. The depth of each item is indicated by the depth property inside the item. */ thread: ThreadItem[] threadgate?: AppBskyFeedDefs.ThreadgateView /** Whether this thread has additional replies. If true, a call can be made to the `getPostThreadOtherV2` endpoint to retrieve them. */ hasOtherReplies: boolean } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface ThreadItem { $type?: 'app.bsky.unspecced.getPostThreadV2#threadItem' uri: string /** The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths. */ depth: number value: | $Typed | $Typed | $Typed | $Typed | { $type: string } } const hashThreadItem = 'threadItem' export function isThreadItem(v: V) { return is$typed(v, id, hashThreadItem) } export function validateThreadItem(v: V) { return validate(v, id, hashThreadItem) } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestedFeeds.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyFeedDefs from '../feed/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestedFeeds' export type QueryParams = { limit?: number } export type InputSchema = undefined export interface OutputSchema { feeds: AppBskyFeedDefs.GeneratorView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestedFeedsSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestedFeedsSkeleton' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). */ viewer?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { feeds: string[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestedOnboardingUsers.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestedOnboardingUsers' export type QueryParams = { /** Category of users to get suggestions for. */ category?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { actors: AppBskyActorDefs.ProfileView[] /** DEPRECATED: use recIdStr instead. */ recId?: string /** Snowflake for this recommendation, use when submitting recommendation events. */ recIdStr?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestedStarterPacks.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyGraphDefs from '../graph/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestedStarterPacks' export type QueryParams = { limit?: number } export type InputSchema = undefined export interface OutputSchema { starterPacks: AppBskyGraphDefs.StarterPackView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). */ viewer?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { starterPacks: string[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestedUsers.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestedUsers' export type QueryParams = { /** Category of users to get suggestions for. */ category?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { actors: AppBskyActorDefs.ProfileView[] /** DEPRECATED: use recIdStr instead. */ recId?: string /** Snowflake for this recommendation, use when submitting recommendation events. */ recIdStr?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestedUsersSkeleton' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). */ viewer?: string /** Category of users to get suggestions for. */ category?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { dids: string[] /** DEPRECATED: use recIdStr instead. */ recId?: string /** Snowflake for this recommendation, use when submitting recommendation events. */ recIdStr?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getSuggestionsSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getSuggestionsSkeleton' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. */ viewer?: string limit?: number cursor?: string /** DID of the account to get suggestions relative to. If not provided, suggestions will be based on the viewer. */ relativeToDid?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string actors: AppBskyUnspeccedDefs.SkeletonSearchActor[] /** DID of the account these suggestions are relative to. If this is returned undefined, suggestions are based on the viewer. */ relativeToDid?: string /** DEPRECATED: use recIdStr instead. */ recId?: number /** Snowflake for this recommendation, use when submitting recommendation events. */ recIdStr?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getTaggedSuggestions.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getTaggedSuggestions' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { suggestions: Suggestion[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface Suggestion { $type?: 'app.bsky.unspecced.getTaggedSuggestions#suggestion' tag: string subjectType: 'actor' | 'feed' | (string & {}) subject: string } const hashSuggestion = 'suggestion' export function isSuggestion(v: V) { return is$typed(v, id, hashSuggestion) } export function validateSuggestion(v: V) { return validate(v, id, hashSuggestion) } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getTrendingTopics.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getTrendingTopics' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. */ viewer?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { topics: AppBskyUnspeccedDefs.TrendingTopic[] suggested: AppBskyUnspeccedDefs.TrendingTopic[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getTrends.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getTrends' export type QueryParams = { limit?: number } export type InputSchema = undefined export interface OutputSchema { trends: AppBskyUnspeccedDefs.TrendView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/getTrendsSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.getTrendsSkeleton' export type QueryParams = { /** DID of the account making the request (not included for public/unauthenticated queries). */ viewer?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { trends: AppBskyUnspeccedDefs.SkeletonTrend[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/initAgeAssurance.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.initAgeAssurance' export type QueryParams = {} export interface InputSchema { /** The user's email address to receive assurance instructions. */ email: string /** The user's preferred language for communication during the assurance process. */ language: string /** An ISO 3166-1 alpha-2 code of the user's location. */ countryCode: string } export type OutputSchema = AppBskyUnspeccedDefs.AgeAssuranceState export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class InvalidEmailError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class DidTooLongError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class InvalidInitiationError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'InvalidEmail') return new InvalidEmailError(e) if (e.error === 'DidTooLong') return new DidTooLongError(e) if (e.error === 'InvalidInitiation') return new InvalidInitiationError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/searchActorsSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.searchActorsSkeleton' export type QueryParams = { /** Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. For typeahead search, only simple term match is supported, not full syntax. */ q: string /** DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. */ viewer?: string /** If true, acts as fast/simple 'typeahead' query. */ typeahead?: boolean limit?: number /** Optional pagination mechanism; may not necessarily allow scrolling through entire result set. */ cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string /** Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits. */ hitsTotal?: number actors: AppBskyUnspeccedDefs.SkeletonSearchActor[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class BadQueryStringError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'BadQueryString') return new BadQueryStringError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/searchPostsSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.searchPostsSkeleton' export type QueryParams = { /** Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. */ q: string /** Specifies the ranking order of results. */ sort?: 'top' | 'latest' | (string & {}) /** Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD). */ since?: string /** Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD). */ until?: string /** Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions. */ mentions?: string /** Filter to posts by the given account. Handles are resolved to DID before query-time. */ author?: string /** Filter to posts in the given language. Expected to be based on post language field, though server may override language detection. */ lang?: string /** Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization. */ domain?: string /** Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching. */ url?: string /** Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching. */ tag?: string[] /** DID of the account making the request (not included for public/unauthenticated queries). Used for 'from:me' queries. */ viewer?: string limit?: number /** Optional pagination mechanism; may not necessarily allow scrolling through entire result set. */ cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string /** Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits. */ hitsTotal?: number posts: AppBskyUnspeccedDefs.SkeletonSearchPost[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class BadQueryStringError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'BadQueryString') return new BadQueryStringError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/unspecced/searchStarterPacksSkeleton.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyUnspeccedDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.unspecced.searchStarterPacksSkeleton' export type QueryParams = { /** Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. */ q: string /** DID of the account making the request (not included for public/unauthenticated queries). */ viewer?: string limit?: number /** Optional pagination mechanism; may not necessarily allow scrolling through entire result set. */ cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string /** Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits. */ hitsTotal?: number starterPacks: AppBskyUnspeccedDefs.SkeletonSearchStarterPack[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class BadQueryStringError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'BadQueryString') return new BadQueryStringError(e) } return e } ================================================ FILE: packages/api/src/client/types/app/bsky/video/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.video.defs' export interface JobStatus { $type?: 'app.bsky.video.defs#jobStatus' jobId: string did: string /** The state of the video processing job. All values not listed as a known value indicate that the job is in process. */ state: 'JOB_STATE_COMPLETED' | 'JOB_STATE_FAILED' | (string & {}) /** Progress within the current processing state. */ progress?: number blob?: BlobRef error?: string message?: string } const hashJobStatus = 'jobStatus' export function isJobStatus(v: V) { return is$typed(v, id, hashJobStatus) } export function validateJobStatus(v: V) { return validate(v, id, hashJobStatus) } ================================================ FILE: packages/api/src/client/types/app/bsky/video/getJobStatus.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyVideoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.video.getJobStatus' export type QueryParams = { jobId: string } export type InputSchema = undefined export interface OutputSchema { jobStatus: AppBskyVideoDefs.JobStatus } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/video/getUploadLimits.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.video.getUploadLimits' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { canUpload: boolean remainingDailyVideos?: number remainingDailyBytes?: number message?: string error?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/app/bsky/video/uploadVideo.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyVideoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'app.bsky.video.uploadVideo' export type QueryParams = {} export type InputSchema = string | Uint8Array | Blob export interface OutputSchema { jobStatus: AppBskyVideoDefs.JobStatus } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'video/mp4' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/actor/declaration.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.actor.declaration' export interface Main { $type: 'chat.bsky.actor.declaration' allowIncoming: 'all' | 'none' | 'following' | (string & {}) [k: string]: unknown } const hashMain = 'main' export function isMain(v: V) { return is$typed(v, id, hashMain) } export function validateMain(v: V) { return validate
(v, id, hashMain, true) } export { type Main as Record, isMain as isRecord, validateMain as validateRecord, } ================================================ FILE: packages/api/src/client/types/chat/bsky/actor/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyActorDefs from '../../../app/bsky/actor/defs.js' import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.actor.defs' export interface ProfileViewBasic { $type?: 'chat.bsky.actor.defs#profileViewBasic' did: string handle: string displayName?: string avatar?: string associated?: AppBskyActorDefs.ProfileAssociated viewer?: AppBskyActorDefs.ViewerState labels?: ComAtprotoLabelDefs.Label[] /** Set to true when the actor cannot actively participate in conversations */ chatDisabled?: boolean verification?: AppBskyActorDefs.VerificationState } const hashProfileViewBasic = 'profileViewBasic' export function isProfileViewBasic(v: V) { return is$typed(v, id, hashProfileViewBasic) } export function validateProfileViewBasic(v: V) { return validate(v, id, hashProfileViewBasic) } ================================================ FILE: packages/api/src/client/types/chat/bsky/actor/deleteAccount.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.actor.deleteAccount' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema {} export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/actor/exportAccountData.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.actor.exportAccountData' export type QueryParams = {} export type InputSchema = undefined export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: Uint8Array } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/acceptConvo.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.acceptConvo' export type QueryParams = {} export interface InputSchema { convoId: string } export interface OutputSchema { /** Rev when the convo was accepted. If not present, the convo was already accepted. */ rev?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/addReaction.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.addReaction' export type QueryParams = {} export interface InputSchema { convoId: string messageId: string value: string } export interface OutputSchema { message: ChatBskyConvoDefs.MessageView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class ReactionMessageDeletedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class ReactionLimitReachedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class ReactionInvalidValueError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'ReactionMessageDeleted') return new ReactionMessageDeletedError(e) if (e.error === 'ReactionLimitReached') return new ReactionLimitReachedError(e) if (e.error === 'ReactionInvalidValue') return new ReactionInvalidValueError(e) } return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as AppBskyRichtextFacet from '../../../app/bsky/richtext/facet.js' import type * as AppBskyEmbedRecord from '../../../app/bsky/embed/record.js' import type * as ChatBskyActorDefs from '../actor/defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.defs' export interface MessageRef { $type?: 'chat.bsky.convo.defs#messageRef' did: string convoId: string messageId: string } const hashMessageRef = 'messageRef' export function isMessageRef(v: V) { return is$typed(v, id, hashMessageRef) } export function validateMessageRef(v: V) { return validate(v, id, hashMessageRef) } export interface MessageInput { $type?: 'chat.bsky.convo.defs#messageInput' text: string /** Annotations of text (mentions, URLs, hashtags, etc) */ facets?: AppBskyRichtextFacet.Main[] embed?: $Typed | { $type: string } } const hashMessageInput = 'messageInput' export function isMessageInput(v: V) { return is$typed(v, id, hashMessageInput) } export function validateMessageInput(v: V) { return validate(v, id, hashMessageInput) } export interface MessageView { $type?: 'chat.bsky.convo.defs#messageView' id: string rev: string text: string /** Annotations of text (mentions, URLs, hashtags, etc) */ facets?: AppBskyRichtextFacet.Main[] embed?: $Typed | { $type: string } /** Reactions to this message, in ascending order of creation time. */ reactions?: ReactionView[] sender: MessageViewSender sentAt: string } const hashMessageView = 'messageView' export function isMessageView(v: V) { return is$typed(v, id, hashMessageView) } export function validateMessageView(v: V) { return validate(v, id, hashMessageView) } export interface DeletedMessageView { $type?: 'chat.bsky.convo.defs#deletedMessageView' id: string rev: string sender: MessageViewSender sentAt: string } const hashDeletedMessageView = 'deletedMessageView' export function isDeletedMessageView(v: V) { return is$typed(v, id, hashDeletedMessageView) } export function validateDeletedMessageView(v: V) { return validate(v, id, hashDeletedMessageView) } export interface MessageViewSender { $type?: 'chat.bsky.convo.defs#messageViewSender' did: string } const hashMessageViewSender = 'messageViewSender' export function isMessageViewSender(v: V) { return is$typed(v, id, hashMessageViewSender) } export function validateMessageViewSender(v: V) { return validate(v, id, hashMessageViewSender) } export interface ReactionView { $type?: 'chat.bsky.convo.defs#reactionView' value: string sender: ReactionViewSender createdAt: string } const hashReactionView = 'reactionView' export function isReactionView(v: V) { return is$typed(v, id, hashReactionView) } export function validateReactionView(v: V) { return validate(v, id, hashReactionView) } export interface ReactionViewSender { $type?: 'chat.bsky.convo.defs#reactionViewSender' did: string } const hashReactionViewSender = 'reactionViewSender' export function isReactionViewSender(v: V) { return is$typed(v, id, hashReactionViewSender) } export function validateReactionViewSender(v: V) { return validate(v, id, hashReactionViewSender) } export interface MessageAndReactionView { $type?: 'chat.bsky.convo.defs#messageAndReactionView' message: MessageView reaction: ReactionView } const hashMessageAndReactionView = 'messageAndReactionView' export function isMessageAndReactionView(v: V) { return is$typed(v, id, hashMessageAndReactionView) } export function validateMessageAndReactionView(v: V) { return validate(v, id, hashMessageAndReactionView) } export interface ConvoView { $type?: 'chat.bsky.convo.defs#convoView' id: string rev: string members: ChatBskyActorDefs.ProfileViewBasic[] lastMessage?: | $Typed | $Typed | { $type: string } lastReaction?: $Typed | { $type: string } muted: boolean status?: 'request' | 'accepted' | (string & {}) unreadCount: number } const hashConvoView = 'convoView' export function isConvoView(v: V) { return is$typed(v, id, hashConvoView) } export function validateConvoView(v: V) { return validate(v, id, hashConvoView) } export interface LogBeginConvo { $type?: 'chat.bsky.convo.defs#logBeginConvo' rev: string convoId: string } const hashLogBeginConvo = 'logBeginConvo' export function isLogBeginConvo(v: V) { return is$typed(v, id, hashLogBeginConvo) } export function validateLogBeginConvo(v: V) { return validate(v, id, hashLogBeginConvo) } export interface LogAcceptConvo { $type?: 'chat.bsky.convo.defs#logAcceptConvo' rev: string convoId: string } const hashLogAcceptConvo = 'logAcceptConvo' export function isLogAcceptConvo(v: V) { return is$typed(v, id, hashLogAcceptConvo) } export function validateLogAcceptConvo(v: V) { return validate(v, id, hashLogAcceptConvo) } export interface LogLeaveConvo { $type?: 'chat.bsky.convo.defs#logLeaveConvo' rev: string convoId: string } const hashLogLeaveConvo = 'logLeaveConvo' export function isLogLeaveConvo(v: V) { return is$typed(v, id, hashLogLeaveConvo) } export function validateLogLeaveConvo(v: V) { return validate(v, id, hashLogLeaveConvo) } export interface LogMuteConvo { $type?: 'chat.bsky.convo.defs#logMuteConvo' rev: string convoId: string } const hashLogMuteConvo = 'logMuteConvo' export function isLogMuteConvo(v: V) { return is$typed(v, id, hashLogMuteConvo) } export function validateLogMuteConvo(v: V) { return validate(v, id, hashLogMuteConvo) } export interface LogUnmuteConvo { $type?: 'chat.bsky.convo.defs#logUnmuteConvo' rev: string convoId: string } const hashLogUnmuteConvo = 'logUnmuteConvo' export function isLogUnmuteConvo(v: V) { return is$typed(v, id, hashLogUnmuteConvo) } export function validateLogUnmuteConvo(v: V) { return validate(v, id, hashLogUnmuteConvo) } export interface LogCreateMessage { $type?: 'chat.bsky.convo.defs#logCreateMessage' rev: string convoId: string message: $Typed | $Typed | { $type: string } } const hashLogCreateMessage = 'logCreateMessage' export function isLogCreateMessage(v: V) { return is$typed(v, id, hashLogCreateMessage) } export function validateLogCreateMessage(v: V) { return validate(v, id, hashLogCreateMessage) } export interface LogDeleteMessage { $type?: 'chat.bsky.convo.defs#logDeleteMessage' rev: string convoId: string message: $Typed | $Typed | { $type: string } } const hashLogDeleteMessage = 'logDeleteMessage' export function isLogDeleteMessage(v: V) { return is$typed(v, id, hashLogDeleteMessage) } export function validateLogDeleteMessage(v: V) { return validate(v, id, hashLogDeleteMessage) } export interface LogReadMessage { $type?: 'chat.bsky.convo.defs#logReadMessage' rev: string convoId: string message: $Typed | $Typed | { $type: string } } const hashLogReadMessage = 'logReadMessage' export function isLogReadMessage(v: V) { return is$typed(v, id, hashLogReadMessage) } export function validateLogReadMessage(v: V) { return validate(v, id, hashLogReadMessage) } export interface LogAddReaction { $type?: 'chat.bsky.convo.defs#logAddReaction' rev: string convoId: string message: $Typed | $Typed | { $type: string } reaction: ReactionView } const hashLogAddReaction = 'logAddReaction' export function isLogAddReaction(v: V) { return is$typed(v, id, hashLogAddReaction) } export function validateLogAddReaction(v: V) { return validate(v, id, hashLogAddReaction) } export interface LogRemoveReaction { $type?: 'chat.bsky.convo.defs#logRemoveReaction' rev: string convoId: string message: $Typed | $Typed | { $type: string } reaction: ReactionView } const hashLogRemoveReaction = 'logRemoveReaction' export function isLogRemoveReaction(v: V) { return is$typed(v, id, hashLogRemoveReaction) } export function validateLogRemoveReaction(v: V) { return validate(v, id, hashLogRemoveReaction) } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/deleteMessageForSelf.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.deleteMessageForSelf' export type QueryParams = {} export interface InputSchema { convoId: string messageId: string } export type OutputSchema = ChatBskyConvoDefs.DeletedMessageView export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/getConvo.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.getConvo' export type QueryParams = { convoId: string } export type InputSchema = undefined export interface OutputSchema { convo: ChatBskyConvoDefs.ConvoView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/getConvoAvailability.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.getConvoAvailability' export type QueryParams = { members: string[] } export type InputSchema = undefined export interface OutputSchema { canChat: boolean convo?: ChatBskyConvoDefs.ConvoView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/getConvoForMembers.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.getConvoForMembers' export type QueryParams = { members: string[] } export type InputSchema = undefined export interface OutputSchema { convo: ChatBskyConvoDefs.ConvoView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/getLog.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.getLog' export type QueryParams = { cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string logs: ( | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | $Typed | { $type: string } )[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/getMessages.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.getMessages' export type QueryParams = { convoId: string limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string messages: ( | $Typed | $Typed | { $type: string } )[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/leaveConvo.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.leaveConvo' export type QueryParams = {} export interface InputSchema { convoId: string } export interface OutputSchema { convoId: string rev: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/listConvos.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.listConvos' export type QueryParams = { limit?: number cursor?: string readState?: 'unread' | (string & {}) status?: 'request' | 'accepted' | (string & {}) } export type InputSchema = undefined export interface OutputSchema { cursor?: string convos: ChatBskyConvoDefs.ConvoView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/muteConvo.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.muteConvo' export type QueryParams = {} export interface InputSchema { convoId: string } export interface OutputSchema { convo: ChatBskyConvoDefs.ConvoView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/removeReaction.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.removeReaction' export type QueryParams = {} export interface InputSchema { convoId: string messageId: string value: string } export interface OutputSchema { message: ChatBskyConvoDefs.MessageView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class ReactionMessageDeletedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class ReactionInvalidValueError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'ReactionMessageDeleted') return new ReactionMessageDeletedError(e) if (e.error === 'ReactionInvalidValue') return new ReactionInvalidValueError(e) } return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/sendMessage.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.sendMessage' export type QueryParams = {} export interface InputSchema { convoId: string message: ChatBskyConvoDefs.MessageInput } export type OutputSchema = ChatBskyConvoDefs.MessageView export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/sendMessageBatch.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.sendMessageBatch' export type QueryParams = {} export interface InputSchema { items: BatchItem[] } export interface OutputSchema { items: ChatBskyConvoDefs.MessageView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface BatchItem { $type?: 'chat.bsky.convo.sendMessageBatch#batchItem' convoId: string message: ChatBskyConvoDefs.MessageInput } const hashBatchItem = 'batchItem' export function isBatchItem(v: V) { return is$typed(v, id, hashBatchItem) } export function validateBatchItem(v: V) { return validate(v, id, hashBatchItem) } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/unmuteConvo.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.unmuteConvo' export type QueryParams = {} export interface InputSchema { convoId: string } export interface OutputSchema { convo: ChatBskyConvoDefs.ConvoView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/updateAllRead.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.updateAllRead' export type QueryParams = {} export interface InputSchema { status?: 'request' | 'accepted' | (string & {}) } export interface OutputSchema { /** The count of updated convos. */ updatedCount: number } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/convo/updateRead.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.convo.updateRead' export type QueryParams = {} export interface InputSchema { convoId: string messageId?: string } export interface OutputSchema { convo: ChatBskyConvoDefs.ConvoView } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/moderation/getActorMetadata.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.moderation.getActorMetadata' export type QueryParams = { actor: string } export type InputSchema = undefined export interface OutputSchema { day: Metadata month: Metadata all: Metadata } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } export interface Metadata { $type?: 'chat.bsky.moderation.getActorMetadata#metadata' messagesSent: number messagesReceived: number convos: number convosStarted: number } const hashMetadata = 'metadata' export function isMetadata(v: V) { return is$typed(v, id, hashMetadata) } export function validateMetadata(v: V) { return validate(v, id, hashMetadata) } ================================================ FILE: packages/api/src/client/types/chat/bsky/moderation/getMessageContext.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ChatBskyConvoDefs from '../convo/defs.js' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.moderation.getMessageContext' export type QueryParams = { /** Conversation that the message is from. NOTE: this field will eventually be required. */ convoId?: string messageId: string before?: number after?: number } export type InputSchema = undefined export interface OutputSchema { messages: ( | $Typed | $Typed | { $type: string } )[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/chat/bsky/moderation/updateActorAccess.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'chat.bsky.moderation.updateActorAccess' export type QueryParams = {} export interface InputSchema { actor: string allowAccess: boolean ref?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoServerDefs from '../server/defs.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.defs' export interface StatusAttr { $type?: 'com.atproto.admin.defs#statusAttr' applied: boolean ref?: string } const hashStatusAttr = 'statusAttr' export function isStatusAttr(v: V) { return is$typed(v, id, hashStatusAttr) } export function validateStatusAttr(v: V) { return validate(v, id, hashStatusAttr) } export interface AccountView { $type?: 'com.atproto.admin.defs#accountView' did: string handle: string email?: string relatedRecords?: { [_ in string]: unknown }[] indexedAt: string invitedBy?: ComAtprotoServerDefs.InviteCode invites?: ComAtprotoServerDefs.InviteCode[] invitesDisabled?: boolean emailConfirmedAt?: string inviteNote?: string deactivatedAt?: string threatSignatures?: ThreatSignature[] } const hashAccountView = 'accountView' export function isAccountView(v: V) { return is$typed(v, id, hashAccountView) } export function validateAccountView(v: V) { return validate(v, id, hashAccountView) } export interface RepoRef { $type?: 'com.atproto.admin.defs#repoRef' did: string } const hashRepoRef = 'repoRef' export function isRepoRef(v: V) { return is$typed(v, id, hashRepoRef) } export function validateRepoRef(v: V) { return validate(v, id, hashRepoRef) } export interface RepoBlobRef { $type?: 'com.atproto.admin.defs#repoBlobRef' did: string cid: string recordUri?: string } const hashRepoBlobRef = 'repoBlobRef' export function isRepoBlobRef(v: V) { return is$typed(v, id, hashRepoBlobRef) } export function validateRepoBlobRef(v: V) { return validate(v, id, hashRepoBlobRef) } export interface ThreatSignature { $type?: 'com.atproto.admin.defs#threatSignature' property: string value: string } const hashThreatSignature = 'threatSignature' export function isThreatSignature(v: V) { return is$typed(v, id, hashThreatSignature) } export function validateThreatSignature(v: V) { return validate(v, id, hashThreatSignature) } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/deleteAccount.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.deleteAccount' export type QueryParams = {} export interface InputSchema { did: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/disableAccountInvites.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.disableAccountInvites' export type QueryParams = {} export interface InputSchema { account: string /** Optional reason for disabled invites. */ note?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/disableInviteCodes.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.disableInviteCodes' export type QueryParams = {} export interface InputSchema { codes?: string[] accounts?: string[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/enableAccountInvites.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.enableAccountInvites' export type QueryParams = {} export interface InputSchema { account: string /** Optional reason for enabled invites. */ note?: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/getAccountInfo.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoAdminDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.getAccountInfo' export type QueryParams = { did: string } export type InputSchema = undefined export type OutputSchema = ComAtprotoAdminDefs.AccountView export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/getAccountInfos.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoAdminDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.getAccountInfos' export type QueryParams = { dids: string[] } export type InputSchema = undefined export interface OutputSchema { infos: ComAtprotoAdminDefs.AccountView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/getInviteCodes.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoServerDefs from '../server/defs.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.getInviteCodes' export type QueryParams = { sort?: 'recent' | 'usage' | (string & {}) limit?: number cursor?: string } export type InputSchema = undefined export interface OutputSchema { cursor?: string codes: ComAtprotoServerDefs.InviteCode[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/getSubjectStatus.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoAdminDefs from './defs.js' import type * as ComAtprotoRepoStrongRef from '../repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.getSubjectStatus' export type QueryParams = { did?: string uri?: string blob?: string } export type InputSchema = undefined export interface OutputSchema { subject: | $Typed | $Typed | $Typed | { $type: string } takedown?: ComAtprotoAdminDefs.StatusAttr deactivated?: ComAtprotoAdminDefs.StatusAttr } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/searchAccounts.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoAdminDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.searchAccounts' export type QueryParams = { email?: string cursor?: string limit?: number } export type InputSchema = undefined export interface OutputSchema { cursor?: string accounts: ComAtprotoAdminDefs.AccountView[] } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/sendEmail.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.sendEmail' export type QueryParams = {} export interface InputSchema { recipientDid: string content: string subject?: string senderDid: string /** Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers */ comment?: string } export interface OutputSchema { sent: boolean } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/updateAccountEmail.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.updateAccountEmail' export type QueryParams = {} export interface InputSchema { /** The handle or DID of the repo. */ account: string email: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/updateAccountHandle.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.updateAccountHandle' export type QueryParams = {} export interface InputSchema { did: string handle: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/updateAccountPassword.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.updateAccountPassword' export type QueryParams = {} export interface InputSchema { did: string password: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/updateAccountSigningKey.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.updateAccountSigningKey' export type QueryParams = {} export interface InputSchema { did: string /** Did-key formatted public key */ signingKey: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/admin/updateSubjectStatus.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoAdminDefs from './defs.js' import type * as ComAtprotoRepoStrongRef from '../repo/strongRef.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.admin.updateSubjectStatus' export type QueryParams = {} export interface InputSchema { subject: | $Typed | $Typed | $Typed | { $type: string } takedown?: ComAtprotoAdminDefs.StatusAttr deactivated?: ComAtprotoAdminDefs.StatusAttr } export interface OutputSchema { subject: | $Typed | $Typed | $Typed | { $type: string } takedown?: ComAtprotoAdminDefs.StatusAttr } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.defs' export interface IdentityInfo { $type?: 'com.atproto.identity.defs#identityInfo' did: string /** The validated handle of the account; or 'handle.invalid' if the handle did not bi-directionally match the DID document. */ handle: string /** The complete DID document for the identity. */ didDoc: { [_ in string]: unknown } } const hashIdentityInfo = 'identityInfo' export function isIdentityInfo(v: V) { return is$typed(v, id, hashIdentityInfo) } export function validateIdentityInfo(v: V) { return validate(v, id, hashIdentityInfo) } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/getRecommendedDidCredentials.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.getRecommendedDidCredentials' export type QueryParams = {} export type InputSchema = undefined export interface OutputSchema { /** Recommended rotation keys for PLC dids. Should be undefined (or ignored) for did:webs. */ rotationKeys?: string[] alsoKnownAs?: string[] verificationMethods?: { [_ in string]: unknown } services?: { [_ in string]: unknown } } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/refreshIdentity.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoIdentityDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.refreshIdentity' export type QueryParams = {} export interface InputSchema { identifier: string } export type OutputSchema = ComAtprotoIdentityDefs.IdentityInfo export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class HandleNotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class DidNotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class DidDeactivatedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'HandleNotFound') return new HandleNotFoundError(e) if (e.error === 'DidNotFound') return new DidNotFoundError(e) if (e.error === 'DidDeactivated') return new DidDeactivatedError(e) } return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/requestPlcOperationSignature.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.requestPlcOperationSignature' export type QueryParams = {} export type InputSchema = undefined export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/resolveDid.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.resolveDid' export type QueryParams = { /** DID to resolve. */ did: string } export type InputSchema = undefined export interface OutputSchema { /** The complete DID document for the identity. */ didDoc: { [_ in string]: unknown } } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class DidNotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class DidDeactivatedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'DidNotFound') return new DidNotFoundError(e) if (e.error === 'DidDeactivated') return new DidDeactivatedError(e) } return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/resolveHandle.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.resolveHandle' export type QueryParams = { /** The handle to resolve. */ handle: string } export type InputSchema = undefined export interface OutputSchema { did: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class HandleNotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'HandleNotFound') return new HandleNotFoundError(e) } return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/resolveIdentity.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' import type * as ComAtprotoIdentityDefs from './defs.js' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.resolveIdentity' export type QueryParams = { /** Handle or DID to resolve. */ identifier: string } export type InputSchema = undefined export type OutputSchema = ComAtprotoIdentityDefs.IdentityInfo export interface CallOptions { signal?: AbortSignal headers?: HeadersMap } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export class HandleNotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class DidNotFoundError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export class DidDeactivatedError extends XRPCError { constructor(src: XRPCError) { super(src.status, src.error, src.message, src.headers, { cause: src }) } } export function toKnownErr(e: any) { if (e instanceof XRPCError) { if (e.error === 'HandleNotFound') return new HandleNotFoundError(e) if (e.error === 'DidNotFound') return new DidNotFoundError(e) if (e.error === 'DidDeactivated') return new DidDeactivatedError(e) } return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/signPlcOperation.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.signPlcOperation' export type QueryParams = {} export interface InputSchema { /** A token received through com.atproto.identity.requestPlcOperationSignature */ token?: string rotationKeys?: string[] alsoKnownAs?: string[] verificationMethods?: { [_ in string]: unknown } services?: { [_ in string]: unknown } } export interface OutputSchema { /** A signed DID PLC operation. */ operation: { [_ in string]: unknown } } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap data: OutputSchema } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/submitPlcOperation.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.submitPlcOperation' export type QueryParams = {} export interface InputSchema { operation: { [_ in string]: unknown } } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/identity/updateHandle.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { HeadersMap, XRPCError } from '@atproto/xrpc' import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.identity.updateHandle' export type QueryParams = {} export interface InputSchema { /** The new handle. */ handle: string } export interface CallOptions { signal?: AbortSignal headers?: HeadersMap qp?: QueryParams encoding?: 'application/json' } export interface Response { success: boolean headers: HeadersMap } export function toKnownErr(e: any) { return e } ================================================ FILE: packages/api/src/client/types/com/atproto/label/defs.ts ================================================ /** * GENERATED CODE - DO NOT MODIFY */ import { type ValidationResult, BlobRef } from '@atproto/lexicon' import { CID } from 'multiformats/cid' import { validate as _validate } from '../../../../lexicons' import { type $Typed, is$typed as _is$typed, type OmitKey, } from '../../../../util' const is$typed = _is$typed, validate = _validate const id = 'com.atproto.label.defs' /** Metadata tag on an atproto resource (eg, repo or record). */ export interface Label { $type?: 'com.atproto.label.defs#label' /** The AT Protocol version of the label object. */ ver?: number /** DID of the actor who created this label. */ src: string /** AT URI of the record, repository (account), or other resource that this label applies to. */ uri: string /** Optionally, CID specifying the specific version of 'uri' resource this label applies to. */ cid?: string /** The short string name of the value or type of this label. */ val: string /** If true, this is a negation label, overwriting a previous label. */ neg?: boolean /** Timestamp when this label was created. */ cts: string /** Timestamp at which this label expires (no longer applies). */ exp?: string /** Signature of dag-cbor encoded label. */ sig?: Uint8Array } const hashLabel = 'label' export function isLabel(v: V) { return is$typed(v, id, hashLabel) } export function validateLabel(v: V) { return validate