# social.craftsky.feed.post

> Published by [craftsky.social](https://lexicon.garden/identity/did:plc:lmmx63zcns6gewgxqfdt4kof)

✓ This is the authoritative definition for this NSID.

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:lmmx63zcns6gewgxqfdt4kof/social.craftsky.feed.post)
- [Documentation](https://lexicon.garden/lexicon/did:plc:lmmx63zcns6gewgxqfdt4kof/social.craftsky.feed.post/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:lmmx63zcns6gewgxqfdt4kof/social.craftsky.feed.post/examples)

## Definitions

### `social.craftsky.feed.post#aspectRatio`

**Type**: `object`

Image aspect ratio metadata used for layout/render hints.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `height` | `integer` | Yes |  |
| `width` | `integer` | Yes |  |

### `social.craftsky.feed.post#externalImport`

**Type**: `object`

Minimal self-asserted external-import provenance. It is display and distribution metadata only and does not verify ownership of an external account.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `source` | `string` | Yes | Self-asserted source service token. The value does not verify account ownership; clients should apply source-specific behavior only to values they recognize. |

### `social.craftsky.feed.post#image`

**Type**: `object`

An image blob with optional alt text.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `alt` | `string` | No | Optional alt text describing the image for accessibility. |
| `aspectRatio` | `ref` → `#aspectRatio` | No | Optional aspect ratio metadata for rendering. |
| `image` | `blob` | Yes |  |

### `social.craftsky.feed.post`

**Type**: `record`

A post on Craftsky. May be a general post or a craft project post; when the optional 'project' field is present the post is a project post. The optional open embed union supports quoted records, standard external cards, and standard video.

**Key**: `tid`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `createdAt` | `string` (datetime) | Yes | Client-declared creation timestamp. |
| `embed` | `union` | No | Optional embedded content. Open union supporting local quote embeds, standard external cards, and standard video. |
| `externalImport` | `ref` → `#externalImport` | No | Optional self-asserted provenance for content created by an external-history importer. This metadata does not verify ownership of an external account or grant trust. |
| `facets` | `array` | No | Byte-range annotations over 'text' for mentions, links, and inline hashtags. Reuses app.bsky.richtext.facet so existing renderers Just Work. Inline hashtag facets are composer-merged into project.common.tags on project posts; see the post lexicon fields spec. |
| `images` | `array` | No | Images attached to the post. Top-level (not inside 'embed') — a post may carry images alongside a quote embed without needing a wrapper variant. |
| `langs` | `array` | No | Indicates human language of post primary text content. |
| `project` | `ref` → `social.craftsky.project.defs#project` | No | If present, this post is a craft project post. Absence means it's a general social post. |
| `reply` | `ref` → `#replyRef` | No | If present, this post is a reply to another post. |
| `sponsored` | `boolean` | Yes | Whether the author declares that this post was created with sponsorship or other commercial consideration. Disclosure metadata only; it does not affect distribution. |
| `text` | `string` | Yes | The primary text content of the post. Plain text; rich-text annotations live in 'facets'. Craftsky allows longer posts than Bluesky (2000 graphemes vs 300) because crafters write fuller project write-ups. |

### `social.craftsky.feed.post#quoteEmbed`

**Type**: `object`

Embed wrapping another record (typically a social.craftsky.feed.post) for a quote post.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `record` | `ref` → `com.atproto.repo.strongRef` | Yes | Strong reference to the quoted record. |

### `social.craftsky.feed.post#replyRef`

**Type**: `object`

Reference to the parent and root posts of a thread.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `parent` | `ref` → `com.atproto.repo.strongRef` | Yes | The immediate parent post being replied to. |
| `root` | `ref` → `com.atproto.repo.strongRef` | Yes | The root post of the thread. |

## Raw Schema

```json
{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "aspectRatio": {
      "description": "Image aspect ratio metadata used for layout/render hints.",
      "properties": {
        "height": {
          "minimum": 1,
          "type": "integer"
        },
        "width": {
          "minimum": 1,
          "type": "integer"
        }
      },
      "required": [
        "width",
        "height"
      ],
      "type": "object"
    },
    "externalImport": {
      "description": "Minimal self-asserted external-import provenance. It is display and distribution metadata only and does not verify ownership of an external account.",
      "properties": {
        "source": {
          "description": "Self-asserted source service token. The value does not verify account ownership; clients should apply source-specific behavior only to values they recognize.",
          "knownValues": [
            "instagram"
          ],
          "maxLength": 64,
          "type": "string"
        }
      },
      "required": [
        "source"
      ],
      "type": "object"
    },
    "image": {
      "description": "An image blob with optional alt text.",
      "properties": {
        "alt": {
          "description": "Optional alt text describing the image for accessibility.",
          "maxGraphemes": 1000,
          "maxLength": 1000,
          "type": "string"
        },
        "aspectRatio": {
          "description": "Optional aspect ratio metadata for rendering.",
          "ref": "#aspectRatio",
          "type": "ref"
        },
        "image": {
          "accept": [
            "image/jpeg",
            "image/png",
            "image/webp"
          ],
          "maxSize": 2000000,
          "type": "blob"
        }
      },
      "required": [
        "image"
      ],
      "type": "object"
    },
    "main": {
      "description": "A post on Craftsky. May be a general post or a craft project post; when the optional 'project' field is present the post is a project post. The optional open embed union supports quoted records, standard external cards, and standard video.",
      "key": "tid",
      "record": {
        "properties": {
          "createdAt": {
            "description": "Client-declared creation timestamp.",
            "format": "datetime",
            "type": "string"
          },
          "embed": {
            "description": "Optional embedded content. Open union supporting local quote embeds, standard external cards, and standard video.",
            "refs": [
              "#quoteEmbed",
              "app.bsky.embed.external",
              "app.bsky.embed.video"
            ],
            "type": "union"
          },
          "externalImport": {
            "description": "Optional self-asserted provenance for content created by an external-history importer. This metadata does not verify ownership of an external account or grant trust.",
            "ref": "#externalImport",
            "type": "ref"
          },
          "facets": {
            "description": "Byte-range annotations over 'text' for mentions, links, and inline hashtags. Reuses app.bsky.richtext.facet so existing renderers Just Work. Inline hashtag facets are composer-merged into project.common.tags on project posts; see the post lexicon fields spec.",
            "items": {
              "ref": "app.bsky.richtext.facet",
              "type": "ref"
            },
            "type": "array"
          },
          "images": {
            "description": "Images attached to the post. Top-level (not inside 'embed') — a post may carry images alongside a quote embed without needing a wrapper variant.",
            "items": {
              "ref": "#image",
              "type": "ref"
            },
            "maxLength": 4,
            "type": "array"
          },
          "langs": {
            "description": "Indicates human language of post primary text content.",
            "items": {
              "format": "language",
              "type": "string"
            },
            "maxLength": 3,
            "type": "array"
          },
          "project": {
            "description": "If present, this post is a craft project post. Absence means it's a general social post.",
            "ref": "social.craftsky.project.defs#project",
            "type": "ref"
          },
          "reply": {
            "description": "If present, this post is a reply to another post.",
            "ref": "#replyRef",
            "type": "ref"
          },
          "sponsored": {
            "description": "Whether the author declares that this post was created with sponsorship or other commercial consideration. Disclosure metadata only; it does not affect distribution.",
            "type": "boolean"
          },
          "text": {
            "description": "The primary text content of the post. Plain text; rich-text annotations live in 'facets'. Craftsky allows longer posts than Bluesky (2000 graphemes vs 300) because crafters write fuller project write-ups.",
            "maxGraphemes": 2000,
            "maxLength": 20000,
            "type": "string"
          }
        },
        "required": [
          "text",
          "sponsored",
          "createdAt"
        ],
        "type": "object"
      },
      "type": "record"
    },
    "quoteEmbed": {
      "description": "Embed wrapping another record (typically a social.craftsky.feed.post) for a quote post.",
      "properties": {
        "record": {
          "description": "Strong reference to the quoted record.",
          "ref": "com.atproto.repo.strongRef",
          "type": "ref"
        }
      },
      "required": [
        "record"
      ],
      "type": "object"
    },
    "replyRef": {
      "description": "Reference to the parent and root posts of a thread.",
      "properties": {
        "parent": {
          "description": "The immediate parent post being replied to.",
          "ref": "com.atproto.repo.strongRef",
          "type": "ref"
        },
        "root": {
          "description": "The root post of the thread.",
          "ref": "com.atproto.repo.strongRef",
          "type": "ref"
        }
      },
      "required": [
        "root",
        "parent"
      ],
      "type": "object"
    }
  },
  "id": "social.craftsky.feed.post",
  "lexicon": 1
}
```
