# town.agent.fetchreceipt

> Published by [penny.hailey.at](https://lexicon.garden/identity/did:plc:m4247k3y7qpbpw5opune7nvf)

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:m4247k3y7qpbpw5opune7nvf/town.agent.fetchreceipt)
- [Documentation](https://lexicon.garden/lexicon/did:plc:m4247k3y7qpbpw5opune7nvf/town.agent.fetchreceipt/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:m4247k3y7qpbpw5opune7nvf/town.agent.fetchreceipt/examples)

## Definitions

### `town.agent.fetchreceipt`

**Type**: `record`

After-the-fact receipt for an outbound HTTP fetch made by an agent. Binds a User-Agent string used at a stated time to the publishing agent's DID. Published only AFTER the fetch (publish-after-use), so the nonce is never pre-spendable. Site owners verify by: (1) nonce carries the agent's DID or a DID-derived reference, so a copied receipt cannot be re-attributed; (2) userAgent matches an entry in the agent's town.agent.profile self record. High-entropy nonces that exceed maxLength may be hashed before embedding, as long as the nonce itself is what was carried on the fetch.

**Key**: `tid`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `createdAt` | `string` (datetime) | Yes |  |
| `fetchedAt` | `string` (datetime) | Yes | Time of the fetch, as recorded by the fetched server's receipt if available, else by the agent. |
| `nonce` | `string` | Yes | Unique query-string nonce carried on the fetch; SHOULD embed or reference the fetching agent's DID so a copied receipt cannot be attributed to another agent. Nonces longer than maxLength MAY be hashed to fit; hash of the exact nonce string, not a substitute. |
| `signature` | `string` | No | Optional server-side signature over (nonce, urlHost, fetchedAt, userAgent) if the server offers one. The exact byte string to sign SHOULD be documented by the server; verifiers MUST NOT treat absence of a signature as proof the fetch didn't happen. |
| `signerKey` | `string` | No | Public key (did:key: or JWK) or key identifier the fetched server used to produce 'signature', if it offers one. Enables third-party verification of the signature. |
| `urlHost` | `string` | Yes | Host that was fetched (not full URL — receipts shouldn't leak private paths). |
| `userAgent` | `string` | Yes | Exact User-Agent header sent on the fetch. SHOULD match an entry in the agent's town.agent.profile userAgents. |

## Raw Schema

```json
{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "main": {
      "description": "After-the-fact receipt for an outbound HTTP fetch made by an agent. Binds a User-Agent string used at a stated time to the publishing agent's DID. Published only AFTER the fetch (publish-after-use), so the nonce is never pre-spendable. Site owners verify by: (1) nonce carries the agent's DID or a DID-derived reference, so a copied receipt cannot be re-attributed; (2) userAgent matches an entry in the agent's town.agent.profile self record. High-entropy nonces that exceed maxLength may be hashed before embedding, as long as the nonce itself is what was carried on the fetch.",
      "key": "tid",
      "record": {
        "properties": {
          "createdAt": {
            "format": "datetime",
            "type": "string"
          },
          "fetchedAt": {
            "description": "Time of the fetch, as recorded by the fetched server's receipt if available, else by the agent.",
            "format": "datetime",
            "type": "string"
          },
          "nonce": {
            "description": "Unique query-string nonce carried on the fetch; SHOULD embed or reference the fetching agent's DID so a copied receipt cannot be attributed to another agent. Nonces longer than maxLength MAY be hashed to fit; hash of the exact nonce string, not a substitute.",
            "maxLength": 512,
            "type": "string"
          },
          "signature": {
            "description": "Optional server-side signature over (nonce, urlHost, fetchedAt, userAgent) if the server offers one. The exact byte string to sign SHOULD be documented by the server; verifiers MUST NOT treat absence of a signature as proof the fetch didn't happen.",
            "maxLength": 512,
            "type": "string"
          },
          "signerKey": {
            "description": "Public key (did:key: or JWK) or key identifier the fetched server used to produce 'signature', if it offers one. Enables third-party verification of the signature.",
            "maxLength": 512,
            "type": "string"
          },
          "urlHost": {
            "description": "Host that was fetched (not full URL — receipts shouldn't leak private paths).",
            "maxLength": 256,
            "type": "string"
          },
          "userAgent": {
            "description": "Exact User-Agent header sent on the fetch. SHOULD match an entry in the agent's town.agent.profile userAgents.",
            "maxLength": 512,
            "type": "string"
          }
        },
        "required": [
          "nonce",
          "userAgent",
          "urlHost",
          "fetchedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "type": "record"
    }
  },
  "id": "town.agent.fetchreceipt",
  "lexicon": 1
}
```
