At

 view release on metacpan or  search on metacpan

Changes.md  view on Meta::CPAN

- Firehose requires Archive::CAR

### Fixed
- While processing lexicons, validation errors fall back to the raw string instead of throwing a fatal exception.

## [1.4] - 2026-03-09

### Added
- Added high-level helpers for...
  - Rrepository management: `create_record`, `delete_record`, `put_record`, and `apply_writes`
  - Direct PDS binary uploads: `upload_blob`
  - Identity resolution: `resolve_did_to_handle`

## [1.3] - 2026-03-08
... [rest of file] ...

[Unreleased]: https://github.com/sanko/At.pm/compare/1.6...HEAD
[1.6]: https://github.com/sanko/At.pm/compare/1.5...1.6
[1.5]: https://github.com/sanko/At.pm/compare/1.4...1.5
[1.4]: https://github.com/sanko/At.pm/compare/1.3...1.4
[1.3]: https://github.com/sanko/At.pm/releases/tag/1.3

MANIFEST  view on Meta::CPAN

share/lexicons/app/bsky/unspecced/getTrendingTopics.json
share/lexicons/app/bsky/unspecced/getTrends.json
share/lexicons/app/bsky/unspecced/getTrendsSkeleton.json
share/lexicons/app/bsky/unspecced/initAgeAssurance.json
share/lexicons/app/bsky/unspecced/searchActorsSkeleton.json
share/lexicons/app/bsky/unspecced/searchPostsSkeleton.json
share/lexicons/app/bsky/unspecced/searchStarterPacksSkeleton.json
share/lexicons/app/bsky/video/defs.json
share/lexicons/app/bsky/video/getJobStatus.json
share/lexicons/app/bsky/video/getUploadLimits.json
share/lexicons/app/bsky/video/uploadVideo.json
share/lexicons/chat/bsky/actor/declaration.json
share/lexicons/chat/bsky/actor/defs.json
share/lexicons/chat/bsky/actor/deleteAccount.json
share/lexicons/chat/bsky/actor/exportAccountData.json
share/lexicons/chat/bsky/authFullChatClient.json
share/lexicons/chat/bsky/convo/acceptConvo.json
share/lexicons/chat/bsky/convo/addReaction.json
share/lexicons/chat/bsky/convo/defs.json
share/lexicons/chat/bsky/convo/deleteMessageForSelf.json
share/lexicons/chat/bsky/convo/getConvo.json

MANIFEST  view on Meta::CPAN

share/lexicons/com/atproto/repo/createRecord.json
share/lexicons/com/atproto/repo/defs.json
share/lexicons/com/atproto/repo/deleteRecord.json
share/lexicons/com/atproto/repo/describeRepo.json
share/lexicons/com/atproto/repo/getRecord.json
share/lexicons/com/atproto/repo/importRepo.json
share/lexicons/com/atproto/repo/listMissingBlobs.json
share/lexicons/com/atproto/repo/listRecords.json
share/lexicons/com/atproto/repo/putRecord.json
share/lexicons/com/atproto/repo/strongRef.json
share/lexicons/com/atproto/repo/uploadBlob.json
share/lexicons/com/atproto/server/activateAccount.json
share/lexicons/com/atproto/server/checkAccountStatus.json
share/lexicons/com/atproto/server/confirmEmail.json
share/lexicons/com/atproto/server/createAccount.json
share/lexicons/com/atproto/server/createAppPassword.json
share/lexicons/com/atproto/server/createInviteCode.json
share/lexicons/com/atproto/server/createInviteCodes.json
share/lexicons/com/atproto/server/createSession.json
share/lexicons/com/atproto/server/deactivateAccount.json
share/lexicons/com/atproto/server/defs.json

README.md  view on Meta::CPAN


Gets or sets the `atproto-proxy` header value on the underlying user agent. When set, requests will be sent to the
primary `host` but include this header, signaling the PDS to proxy the request to the specified service.

Example for Bluesky Chat:

```
$at->http->at_protocol_proxy("did:web:api.bsky.chat#bsky_chat");
```

## `upload_blob( $data, $mime_type )`

Uploads a raw binary blob to the PDS. Returns the blob's metadata (CID, etc).

## `create_record( $collection, $record, [ $rkey ] )`

Helper to create a new record in a specific collection. Automatically uses the authenticated user's DID.

## `delete_record( $collection, $rkey )`

Helper to delete a record from a specific collection.

lib/At.pm  view on Meta::CPAN

    # Identity & Helpers
    method did()                   { $session ? $session->did . '' : undef; }
    method resolve_handle($handle) { $self->get( 'com.atproto.identity.resolveHandle' => { handle => $handle } ); }

    method resolve_did_to_handle ($did) {
        my $doc = $self->resolve_did($did);
        return $doc->{alsoKnownAs}[0] =~ s/^at:\/\///r if $doc && $doc->{alsoKnownAs};
        return;
    }

    method upload_blob ( $data, $mime_type ) {
        $self->post( 'com.atproto.repo.uploadBlob' => { content => $data, headers => { 'Content-Type' => $mime_type } } );
    }

    method create_record ( $collection, $record, $rkey = undef ) {
        $self->post( 'com.atproto.repo.createRecord' =>
                { repo => $self->did, collection => $collection, record => $record, defined $rkey ? ( rkey => $rkey ) : () } );
    }

    method delete_record ( $collection, $rkey ) {
        $self->post( 'com.atproto.repo.deleteRecord' => { repo => $self->did, collection => $collection, rkey => $rkey } );
    }

lib/At.pm  view on Meta::CPAN


=head2 C<atproto_proxy( [ $service_did ] )>

Gets or sets the C<atproto-proxy> header value on the underlying user agent. When set, requests will be sent to the
primary C<host> but include this header, signaling the PDS to proxy the request to the specified service.

Example for Bluesky Chat:

    $at->http->at_protocol_proxy("did:web:api.bsky.chat#bsky_chat");

=head2 C<upload_blob( $data, $mime_type )>

Uploads a raw binary blob to the PDS. Returns the blob's metadata (CID, etc).

=head2 C<create_record( $collection, $record, [ $rkey ] )>

Helper to create a new record in a specific collection. Automatically uses the authenticated user's DID.

=head2 C<delete_record( $collection, $rkey )>

Helper to delete a record from a specific collection.

share/lexicons/app/bsky/authCreatePosts.json  view on Meta::CPAN

      "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",

share/lexicons/app/bsky/authFullApp.json  view on Meta::CPAN

            "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",

share/lexicons/app/bsky/video/getUploadLimits.json  view on Meta::CPAN

{
  "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" },

share/lexicons/app/bsky/video/uploadVideo.json  view on Meta::CPAN

{
  "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": {

share/lexicons/com/atproto/repo/uploadBlob.json  view on Meta::CPAN

{
  "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 create...
      "input": {
        "encoding": "*/*"
      },
      "output": {
        "encoding": "application/json",
        "schema": {

share/lexicons/com/atproto/sync/getBlob.json  view on Meta::CPAN

{
  "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": {



( run in 3.826 seconds using v1.01-cache-2.11-cpan-b16cb0d3907 )