Human‑Centric Availability Resolution
Calendario is a federated, identity‑first protocol for resolving a person’s availability. It enables apps, assistants, agents, and software to determine when, how, and under what conditions a human is available — by resolving a structured JSON profile located at:
/.well‑known/calendario/{username}
The protocol only standardizes how a person or organization declares their:
Calendario is designed to be:
GET https://yourdomain.com/.well-known/calendario/jane
      Accept: application/json
Schema Compliance
The JSON profile must conform to calendario-schema-v0.1.json and can be validated using validator.py.
{
  "version": "0.1",
  "username": "jane",
  "display_name": "Jane Doe",
  "self": "did:key:xyz...",
  "self_proof": {
    "type": "DIDSignature2021",
    "created": "2025-05-03T17:00:00Z",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "did:key:xyz...",
    "jws": "eyJhbGciOiJFUz..."
  },
  "organization": "https://acme.example.com",
  "organization_proof": {
    "type": "DIDSignature2021",
    "created": "2025-05-03T18:00:00Z",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "did:key:abc123...",
    "jws": "eyJhbGciOiJFUz..."
  },
  "representing": "ceo@acme.example.com",
  "representing_proof": {
    "type": "DIDSignature2021",
    "created": "2025-05-03T17:30:00Z",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "did:key:xyz123...",
    "jws": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "timezone": "America/New_York",
  "visibility": "public",
  "allow_anonymous_booking": false,
  "min_notice_hours": 72,
  "max_bookings_per_day": 3,
  "blackouts": [
    "2025-12-01",
    { "start": "2025-12-24", "end": "2025-12-31" }
  ],
  "scheduling": [
    {
      "type": "weekly",
      "days": ["monday", "wednesday", "friday"],
      "hours": ["09:00-11:00", "16:00-18:00"],
      "expires": "2025-06-30"
    },
    {
      "type": "date",
      "dates": ["2025-06-07", "2025-06-10"],
      "hours": ["09:00-11:00"]
    },
    {
      "type": "range",
      "start": "2025-06-01",
      "end": "2025-06-14",
      "days": ["monday", "tuesday", "thursday"],
      "hours": ["17:00-20:00"]
    }
  ],
  "pricing": {
    "hour": 75,
    "half_hour": 45,
    "currency": "USD"
  },
  "payment_required": true,
  "payment_url": "https://yourdomain.com/pay/jane",
  "no_show_policy_url": "https://yourdomain.com/no-show",
  "terms_url": "https://yourdomain.com/terms",
  "privacy_url": "https://yourdomain.com/privacy",
  "response_channel": {
    "human_ack_required": true,
    "notify": [
      { "type": "email", "value": "jane@example.com" },
      { "type": "sms", "value": "+14155551234" },
      { "type": "push", "value": "https://push.jane.dev/inbox" },
      { "type": "webhook", "value": "https://jane.dev/notify" },
      { "type": "matrix_dm", "value": "@jane:matrix.org" }
    ],
    "confirm": {
      "meeting_response_url": "https://yourdomain.com/api/bookings/jane",
      "static_meeting_url": "https://meet.google.com/abc-defg-hij",
      "free_busy_url": "https://yourdomain.com/api/freebusy/jane"
    },
    "booking_confirmation_message": "Thank you for booking with Jane. Please bring your brief and join the call 5 mins early.",
    "booking_error_message": "Sorry, I'm no longer available at this time. Please propose another slot."
  }
}
| Field | Type | Required | Description | Example / Context | 
|---|---|---|---|---|
| version | string | ✅ | Protocol version used | "0.1" — allows future breaking changes | 
| username | string | ✅ | Username component of URL | "jane" | 
| display_name | string | ✅ | Human‑readable name | "Jane Doe" | 
| self | string | ✅ | DID or unique self‑identifier | "did:key:xyz..." | 
| self_proof | object | ✅ | Signature proving identity ownership | JSON‑LD proof with JWS | 
| organization | string | — | URL of affiliated organization | "https://acme.example.com" | 
| organization_proof | object | — | Proof signed by org key | Org DID signature | 
| representing | string | — | Email/DID you act on behalf of | "ceo@acme.example.com" | 
| representing_proof | object | — | Signature authorizing representation | JWS | 
| timezone | string | ✅ | IANA time zone | "America/New_York" | 
| visibility | string | ✅ | "public" or "private" profile | "public" | 
| allow_anonymous_booking | boolean | ✅ | Permit unauthenticated bookings | false | 
| min_notice_hours | integer | — | Required notice period | 72 | 
| max_bookings_per_day | integer | — | Daily booking limit | 3 | 
| blackouts | array | — | Specific unavailable dates/ranges | ["2025‑12‑01", {start,end}] | 
| scheduling | array | ✅ | Availability blocks | See Scheduling Blocks | 
| pricing | object | — | Rates & currency | {"hour":75} | 
| payment_required | boolean | — | Is pre‑payment mandatory? | true | 
| payment_url | string | — | URL to pay | Stripe link | 
| no_show_policy_url | string | — | Cancellation / no‑show policy | Policy page | 
| terms_url | string | — | Engagement terms | Terms page | 
| privacy_url | string | — | Privacy policy | Privacy page | 
| response_channel | object | ✅ | Notification & confirmation config | See Response Channel | 
| meta | object | — | Arbitrary tags / hints | {"x-tags":["founder"]} | 
Each item in scheduling defines availability logic.
{
  "type": "weekly",
  "days": ["monday", "wednesday"],
  "hours": ["09:00-12:00"],
  "expires": "2025-06-30"
}Types supported:
"response_channel": {
  "human_ack_required": true,
  "notify": [ ... ],
  "confirm": { ... },
  "booking_confirmation_message": "...",
  "booking_error_message": "..."
}notify — multiple channels (email, sms, push, webhook, matrix_dm)confirm.meeting_response_url — POST here to bookconfirm.static_meeting_url — fallback meeting linkconfirm.free_busy_url — GET here to check live conflictsPOST to meeting_response_url:
{
  "status": "confirmed",
  "meeting_url": "https://meet.google.com/xyz-1234",
  "start_time": "2025-06-03T14:00:00Z",
  "duration_minutes": 30,
  "confirmation_message": "Looking forward to speaking with you!"
}If time is unavailable:
{
  "status": "conflict",
  "reason": "Requested time already booked",
  "suggested_times": ["2025-06-03T15:00:00Z"],
  "fallback_meeting_url": "https://meet.google.com/xyz-9999"
}{
  "busy": [
    { "start": "2025-06-03T14:00:00Z", "end": "2025-06-03T14:30:00Z" }
  ],
  "generated_at": "2025-05-03T16:00:00Z",
  "ttl_seconds": 300
}Clients should call this before POSTing to avoid conflicts.
self_proof and organization_proof with verifiable signatures..well-known/calendario endpoints.free_busy_url to check conflicts before booking.min_notice_hours and max_bookings_per_day.meeting_response_url with atomic checks.visibility, payment_required, and blackouts.Clients MUST ignore unknown top‑level fields. Arbitrary additions belong in meta or should start with x‑.
Add this TXT record to DNS:
calendario=/.well-known/calendarioCalendario Protocol is open‑source under the MIT License. Anyone can adopt, implement, or extend it.