# com.emdashcms.experimental.publisher.profile

> Published by [emdashcms.com](https://lexicon.garden/identity/did:plc:ilznslhspsvk6naatedr66pi)

✓ This is the authoritative definition for this NSID.

## Description

Identity-level metadata for a plugin publisher. One record per publisher DID, located at rkey `self`. Optional: a DID may publish packages without ever publishing a publisher.profile, in which case clients fall back to the publisher's handle and per-package metadata for display. EXPERIMENTAL: this NSID is part of the experimental phase of the EmDash plugin registry. The stable namespace target is com.emdashcms.publisher.profile.

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:ilznslhspsvk6naatedr66pi/com.emdashcms.experimental.publisher.profile)
- [Documentation](https://lexicon.garden/lexicon/did:plc:ilznslhspsvk6naatedr66pi/com.emdashcms.experimental.publisher.profile/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:ilznslhspsvk6naatedr66pi/com.emdashcms.experimental.publisher.profile/examples)

## Definitions

### `com.emdashcms.experimental.publisher.profile#contact`

**Type**: `object`

Identity-level publisher contact. At least one of url or email MUST be present; Lexicon cannot express required-one-of, so aggregators MUST validate this and reject records carrying a contact with neither field. Same shape as `com.emdashcms.experimental.package.profile#contact`.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `email` | `string` | No |  |
| `kind` | `string` | No | Channel role. 'general' for ordinary contact, 'security' for vulnerability reporting. |
| `url` | `string` (uri) | No |  |

### `com.emdashcms.experimental.publisher.profile`

**Type**: `record`

A publisher's identity-level profile. Distinct from `com.emdashcms.experimental.package.profile`, which carries per-package metadata. The publisher profile is the canonical landing page for the entity behind a DID: 'who is publishing these packages?'. The record key is the literal string `self`. Per-package fields like `authors[]` and `security[]` on package profile records remain authoritative for their respective packages and MAY differ from the values here; clients render package-level fields when present, falling back to publisher profile values otherwise. The publisher profile's `displayName` is the value that `com.emdashcms.experimental.publisher.verification` records bind against — see that lexicon's docs for the validity rules.

**Key**: `literal:self`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `contact` | `array` | No | Identity-level contact channels for the publisher (general / security). Per-package security contacts on package profile records remain authoritative for their respective packages; this list is for the publisher entity itself. |
| `description` | `string` | No | Short description / bio of the publisher. SHOULD NOT exceed 280 characters per UI convention. Plain text; no Markdown. |
| `displayName` | `string` | Yes | Human-readable name for the publisher (e.g. 'Acme Plugin Co.'). Displayed alongside packages and verification badges. Verification records bind against this value: a change to displayName invalidates any unexpired verification claims targeting this DID until the issuer re-attests. |
| `updatedAt` | `string` (datetime) | No | When this profile was last updated. |
| `url` | `string` (uri) | No | Publisher's primary homepage. Distinct from per-package repo or homepage URLs. |

## Raw Schema

```json
{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "contact": {
      "description": "Identity-level publisher contact. At least one of url or email MUST be present; Lexicon cannot express required-one-of, so aggregators MUST validate this and reject records carrying a contact with neither field. Same shape as `com.emdashcms.experimental.package.profile#contact`.",
      "properties": {
        "email": {
          "maxLength": 256,
          "type": "string"
        },
        "kind": {
          "description": "Channel role. 'general' for ordinary contact, 'security' for vulnerability reporting.",
          "knownValues": [
            "general",
            "security"
          ],
          "maxLength": 32,
          "type": "string"
        },
        "url": {
          "format": "uri",
          "maxLength": 1024,
          "type": "string"
        }
      },
      "type": "object"
    },
    "main": {
      "description": "A publisher's identity-level profile. Distinct from `com.emdashcms.experimental.package.profile`, which carries per-package metadata. The publisher profile is the canonical landing page for the entity behind a DID: 'who is publishing these packages?'. The record key is the literal string `self`. Per-package fields like `authors[]` and `security[]` on package profile records remain authoritative for their respective packages and MAY differ from the values here; clients render package-level fields when present, falling back to publisher profile values otherwise. The publisher profile's `displayName` is the value that `com.emdashcms.experimental.publisher.verification` records bind against — see that lexicon's docs for the validity rules.",
      "key": "literal:self",
      "record": {
        "properties": {
          "contact": {
            "description": "Identity-level contact channels for the publisher (general / security). Per-package security contacts on package profile records remain authoritative for their respective packages; this list is for the publisher entity itself.",
            "items": {
              "ref": "#contact",
              "type": "ref"
            },
            "maxLength": 8,
            "type": "array"
          },
          "description": {
            "description": "Short description / bio of the publisher. SHOULD NOT exceed 280 characters per UI convention. Plain text; no Markdown.",
            "maxGraphemes": 280,
            "maxLength": 2048,
            "type": "string"
          },
          "displayName": {
            "description": "Human-readable name for the publisher (e.g. 'Acme Plugin Co.'). Displayed alongside packages and verification badges. Verification records bind against this value: a change to displayName invalidates any unexpired verification claims targeting this DID until the issuer re-attests.",
            "maxGraphemes": 100,
            "maxLength": 1024,
            "type": "string"
          },
          "updatedAt": {
            "description": "When this profile was last updated.",
            "format": "datetime",
            "type": "string"
          },
          "url": {
            "description": "Publisher's primary homepage. Distinct from per-package repo or homepage URLs.",
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          }
        },
        "required": [
          "displayName"
        ],
        "type": "object"
      },
      "type": "record"
    }
  },
  "description": "Identity-level metadata for a plugin publisher. One record per publisher DID, located at rkey `self`. Optional: a DID may publish packages without ever publishing a publisher.profile, in which case clients fall back to the publisher's handle and per-package metadata for display. EXPERIMENTAL: this NSID is part of the experimental phase of the EmDash plugin registry. The stable namespace target is com.emdashcms.publisher.profile.",
  "id": "com.emdashcms.experimental.publisher.profile",
  "lexicon": 1
}
```
