Calendario Protocol v0.1

Human‑Centric Availability Resolution

🌐 Overview

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:

🧩 Sample Endpoint & JSON (v0.1)

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.

Canonical Example

{
  "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 Reference (v0.1)

Field Type Required Description Example / Context
versionstringProtocol version used"0.1" — allows future breaking changes
usernamestringUsername component of URL"jane"
display_namestringHuman‑readable name"Jane Doe"
selfstringDID or unique self‑identifier"did:key:xyz..."
self_proofobjectSignature proving identity ownershipJSON‑LD proof with JWS
organizationstringURL of affiliated organization"https://acme.example.com"
organization_proofobjectProof signed by org keyOrg DID signature
representingstringEmail/DID you act on behalf of"ceo@acme.example.com"
representing_proofobjectSignature authorizing representationJWS
timezonestringIANA time zone"America/New_York"
visibilitystring"public" or "private" profile"public"
allow_anonymous_bookingbooleanPermit unauthenticated bookingsfalse
min_notice_hoursintegerRequired notice period72
max_bookings_per_dayintegerDaily booking limit3
blackoutsarraySpecific unavailable dates/ranges["2025‑12‑01", {start,end}]
schedulingarrayAvailability blocksSee Scheduling Blocks
pricingobjectRates & currency{"hour":75}
payment_requiredbooleanIs pre‑payment mandatory?true
payment_urlstringURL to payStripe link
no_show_policy_urlstringCancellation / no‑show policyPolicy page
terms_urlstringEngagement termsTerms page
privacy_urlstringPrivacy policyPrivacy page
response_channelobjectNotification & confirmation configSee Response Channel
metaobjectArbitrary tags / hints{"x-tags":["founder"]}

📆 Scheduling Blocks

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

"response_channel": {
  "human_ack_required": true,
  "notify": [ ... ],
  "confirm": { ... },
  "booking_confirmation_message": "...",
  "booking_error_message": "..."
}

✅ Booking Confirmation Format

POST 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"
}

🧠 Free/Busy Format

{
  "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.

🔐 Security Guidelines

🧠 Concurrency & Conflict Prevention

❌ Error Handling Guidelines

🔧 Extensibility

Clients MUST ignore unknown top‑level fields. Arbitrary additions belong in meta or should start with x‑.

🔁 Discovery

Add this TXT record to DNS:

calendario=/.well-known/calendario

📜 License

Calendario Protocol is open‑source under the MIT License. Anyone can adopt, implement, or extend it.

📎 Resources