fund.at.*
at.fund is a funding signal layer for the AT Protocol. It publishes metadata — it does not intermediate or handle payments. Records are DID-signed and live in each steward's own repository, not on a platform. What distinguishes it from prior funding standards: social context. When people in your network endorse a project, that signal is cryptographically verifiable and independently auditable.
v0.1.0 (draft) — April 2026
at.fund does not exist in isolation. It inherits from a decades-long lineage of web-native funding signals, each building on the last.
| Year | Standard | What it introduced |
|---|---|---|
| 2002 | rel="payment" | The foundational link relation: "here is where you can pay the author." |
| 2019 | GitHub FUNDING.yml | Platform-specific structured funding for repositories. |
| 2019 | npm funding | Package-level funding metadata. First to connect funding to the dependency graph. |
| 2020 | podcast:funding | RSS namespace extension. Brought url + label semantics to syndicated media. |
| 2024 | funding.json | Comprehensive machine-readable standard. Entity metadata, typed channels, tiered plans. |
| 2025 | at.fund | ATProto-native. Combines structured metadata with cryptographic identity and social graph. |
at.fund operates as a three-layer system. Each layer is independent and optional; higher layers provide progressive enhancement.
Any combination is valid: just a contribute link, channels without plans, social graph without funding data, or the full stack.
The simplest possible funding signal — a single URL pointing to where contributions can be made. The ATProto equivalent of <link rel="payment">. Singleton per account (key: literal:self).
| Field | Type | Required |
|---|---|---|
| url | uri | Yes |
| label | string (≤128) | No |
| createdAt | datetime | No |
Structured payment metadata. Each channel and plan is its own record, individually addressable by AT URI. This enables fine-grained updates, cross-account references (a plan in one account can point to a channel in another), and natural protocol-level operations.
Channel
| Field | Type | Required |
|---|---|---|
| channelType | string (≤32) | Yes |
| uri | uri | No |
| description | string (≤500) | No |
| createdAt | datetime | No |
Plan
| Field | Type | Required |
|---|---|---|
| status | string (≤16) | No |
| name | string (≤128) | Yes |
| description | string (≤500) | No |
| amount | integer (smallest unit) | No |
| currency | string (≤3) | No |
| frequency | string (≤16) | No |
| channels | at-uri[] | No |
| createdAt | datetime | No |
Amounts are stored in the smallest currency unit (cents for USD, pence for GBP) to avoid floating-point ambiguity.
These records have no equivalent in prior art. They create a social funding graph on top of the ATProto social graph: endorsements("I vouch for this entity's work") and dependencies("my work depends on this entity"). Endorsement counts are verifiable because they live on each endorser's PDS, not the endorsed project's.
A participation signal — its existence indicates that this account publishes fund.at records. All fields are optional enrichment. Singleton per account (key: literal:self).
| Field | Type | Required |
|---|---|---|
| entityType | string (≤32) | No |
| role | string (≤32) | No |
| createdAt | datetime | No |
Six AT Protocol record types organized into three namespaces — fund.at.actor (identity), fund.at.funding (payment), and fund.at.graph(relationships). Any client can read them directly from a user's repo.
Signals participation in the fund.at ecosystem. Create to join, delete to leave. A backfill service can enumerate all participants by scanning for this record. Optional fields describe the entity type and role.
Your funding page — GitHub Sponsors, Open Collective, Patreon, or any URL where people can support you. One record per account.
A payment channel — a specific place where contributions can be received. Each channel is its own record keyed by a slug ID (e.g. 'github-sponsors'). Individually addressable by AT URI, enabling cross-account references.
A funding plan or tier with a suggested amount. References channels by AT URI, which may be in this account or any other account. This enables teams to share a common payment channel while each maintainer publishes their own plans.
One record per upstream project you depend on. The subject field is a DID or hostname. Surfaces the full dependency tree so the infrastructure underneath you gets credit too.
A public endorsement of any entity you use or value. The record key is the endorsed subject (a DID or hostname), so each entity can only be endorsed once per account. Unlike contribute and dependency (published by builders), endorse is published by users — a protocol-native signal of support. Counts are verifiable because endorsements are stored on each endorser's PDS, not the endorsed project's.
at.fund aims for round-trip fidelity with funding.json v1.x. A steward's funding.json can be converted to at.fund records and back without information loss.
| funding.json field | at.fund record | Notes |
|---|---|---|
| entity.type | fund.at.actor.declaration.entityType | Direct mapping |
| entity.role | fund.at.actor.declaration.role | Direct mapping |
| funding.channels[] | fund.at.funding.channel records | One record per channel; guid → rkey, type → channelType, address → uri |
| funding.plans[] | fund.at.funding.plan records | One record per plan; guid → rkey, amount × 100, channels as AT URIs |
| funding.json field | Why omitted |
|---|---|
| entity.name | Available from the ATProto profile |
| entity.email | Privacy concern; not appropriate for a public record |
| entity.phone | Privacy concern |
| entity.description | Available from the ATProto profile |
| entity.webpageUrl | Derivable from the DID document |
| projects[] | Out of scope — at.fund is per-account, not per-project |
All string fields with constrained vocabularies use ATProto's knownValues pattern rather than closed enums. New values can be added without breaking existing clients.
This specification builds on the work of:
rel="payment" (2002), the foundational web funding signalpodcast:funding (2020), syndicated funding signalsThis specification is a work in progress. It always reflects the current definitions in github.com/andyschwab/at.fund.
Integration guides and code examples are coming to a dedicated page.