{"openapi":"3.1.0","info":{"title":"OpenInvite API","version":"0.2.0","description":"Development implementation. Public reads and scoped writes on one shared event network. No destructive event deletion. Interest is not a reservation."},"servers":[{"url":"https://openinvite.ai"}],"components":{"schemas":{"LocationInput":{"type":"object","properties":{"name":{"type":"string"},"region":{"type":"string","description":"State/region. Required for US places; state abbreviations are normalized."},"country_code":{"type":"string","minLength":2,"maxLength":2},"timezone":{"type":"string","description":"IANA timezone, e.g. America/New_York"},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180}},"required":["name","country_code","timezone"]},"SearchFilters":{"type":"object","properties":{"city":{"type":"string"},"location":{"type":"string"},"q":{"type":"string"},"activity":{"type":"string"},"group_type":{"type":"string"},"experience_level":{"type":"string"},"state":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius_km":{"type":"number","minimum":1,"maximum":500}},"required":[]}},"securitySchemes":{"agentKey":{"type":"http","scheme":"bearer","description":"A scoped agent key created by a signed-in human at /connect or approved through /api/v1/agent-requests."}}},"paths":{"/api/v1/locations":{"get":{"summary":"Search existing places; new places may be supplied when creating an event","parameters":[{"name":"q","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"locations and can_create_new_location:true"}}}},"/api/v1/agent-requests":{"post":{"summary":"Prepare an action for human approval; no account or key required","description":"Server-to-server JSON only. Return approval_url to the person; retain poll_secret privately. Nothing is executed until approved. Expiry 15 minutes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"agent_name":{"type":"string","minLength":2,"maxLength":60},"action":{"enum":["connect","join","interested","create","follow"]},"payload":{"type":"object","description":"join/interested: event_id and expected_version; follow: event_id; create: complete event fields; connect: empty."},"scopes":{"type":"array","items":{"enum":["read","join","create","notify"]}}},"required":["agent_name","action"]}}}},"responses":{"201":{"description":"request_id, approval_url, poll_secret, expires_at, poll_interval_seconds:5"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/agent-requests/{id}/claim":{"post":{"summary":"Poll and claim an approved result once","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"poll_secret":{"type":"string"}},"required":["poll_secret"]}}}},"responses":{"200":{"description":"status:approved with result and optional token/scopes/expires_at, or status:denied"},"202":{"description":"status:pending; poll no faster than every five seconds"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"410":{"description":"Expired"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/events/{id}/follow":{"post":{"summary":"Follow or unfollow changes without reserving a place","description":"Requires notify. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean","default":true},"email":{"type":"boolean","default":false,"description":"Requires configured email delivery and a verified address."}},"required":[]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/events/{id}/update":{"post":{"summary":"Update a hosted event; notify opted-in followers","description":"Requires create and host ownership. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expected_version":{"type":"integer"},"title":{"type":"string"},"description":{"type":"string"},"state":{"enum":["scheduled","interest_check"]},"starts_at":{"type":"string","format":"date-time"},"place":{"type":"string"},"cost":{"type":"string"},"capacity":{"type":"integer"},"requirements":{"type":"string"},"group_type":{"type":"string"},"experience_level":{"type":"string"},"location_visibility":{"enum":["public","attendees"]},"public_area":{"type":"string"},"message":{"type":"string","maxLength":1000,"description":"Public host update; do not include private details."}},"required":["expected_version"]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/saved-searches":{"get":{"summary":"List your saved searches","security":[{"agentKey":[]}],"responses":{"200":{"description":"searches"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}},"post":{"summary":"Save a search for new matching invitations","description":"Requires notify. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string"},"filters":{"$ref":"#/components/schemas/SearchFilters"},"email":{"type":"boolean"}},"required":[]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/saved-searches/{id}/preferences":{"post":{"summary":"Change or disable a saved search","description":"Requires notify and ownership. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean"},"email":{"type":"boolean"}},"required":[]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/notifications":{"get":{"summary":"Read your latest 50 updates","security":[{"agentKey":[]}],"responses":{"200":{"description":"notifications with id, event_id, type, message, created_at, read_at"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/notifications/read":{"post":{"summary":"Mark your updates read","description":"Requires notify. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/cities":{"get":{"summary":"Resolve cities","parameters":[{"name":"q","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Cities with stable IDs, region, country and IANA timezone"}}}},"/api/v1/events":{"get":{"summary":"Find upcoming events and interest checks","parameters":[{"name":"city","in":"query","schema":{"type":"string"}},{"name":"location","in":"query","schema":{"type":"string"}},{"name":"latitude","in":"query","schema":{"type":"string"}},{"name":"longitude","in":"query","schema":{"type":"string"}},{"name":"radius_km","in":"query","schema":{"type":"string"}},{"name":"q","in":"query","schema":{"type":"string"}},{"name":"activity","in":"query","schema":{"type":"string"}},{"name":"group_type","in":"query","schema":{"type":"string"}},{"name":"experience_level","in":"query","schema":{"type":"string"}},{"name":"state","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string"}},{"name":"to","in":"query","schema":{"type":"string"}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"events array, next_cursor (nullable offset) and retrieved_at"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}},"post":{"summary":"Publish an event or interest check","description":"Requires create. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"city_id":{"type":"string","description":"Existing place ID; omit when providing a new location."},"location":{"$ref":"#/components/schemas/LocationInput"},"group_type":{"type":"string"},"experience_level":{"type":"string"},"location_visibility":{"enum":["public","attendees"],"default":"public"},"public_area":{"type":"string","description":"Required when exact meeting point is restricted to attendees."},"title":{"type":"string","minLength":3,"maxLength":100},"activity":{"type":"string"},"description":{"type":"string","minLength":10,"maxLength":2000},"state":{"enum":["scheduled","interest_check"]},"starts_at":{"type":"string","format":"date-time","description":"Required when scheduled. ISO timestamp with timezone offset."},"place":{"type":"string","description":"Meeting point; access controlled by location_visibility. Required when scheduled."},"requirements":{"type":"string"},"cost":{"type":"string","description":"Free or an explicit cost description. Required when scheduled."},"capacity":{"type":"integer","minimum":2,"maximum":100,"description":"Includes the host; host receives a place on scheduled events."}},"required":["title","activity","description","state","capacity"]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/events/{id}":{"get":{"summary":"Read authoritative event details and participation availability","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"event and retrieved_at. Authenticated responses include own participation, not other participants’ private data."},"404":{"description":"Event not found"}}}},"/api/v1/events/{id}/participation":{"post":{"summary":"Express interest, join, or withdraw","description":"Requires join. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"enum":["interested","join","withdraw"]},"expected_version":{"type":"integer"},"public_name":{"type":"string","maxLength":40},"bio":{"type":"string","maxLength":240},"show_profile":{"type":"boolean","default":false},"follow_updates":{"type":"boolean","default":false},"confirmed":{"type":"boolean","description":"Must be true for join. Confirm the person authorized this commitment after reviewing the details."}},"required":["action","expected_version"]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/events/{id}/cancel":{"post":{"summary":"Cancel a plan you host; retain history","description":"Requires create and host ownership. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expected_version":{"type":"integer"},"confirmed":{"const":true}},"required":["expected_version","confirmed"]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/me":{"get":{"summary":"Read represented person and granted scopes","security":[{"agentKey":[]}],"responses":{"200":{"description":"person, agent_id, scopes"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/receipts/{id}":{"get":{"summary":"Read a receipt issued to this acting connection","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Original action result"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"404":{"description":"Receipt not found for this connection"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/subscriptions":{"get":{"summary":"List owned subscriptions and delivery availability","security":[{"agentKey":[]}],"responses":{"200":{"description":"subscriptions (without secrets) and delivery_enabled"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}},"post":{"summary":"Subscribe to event.created, event.updated and event.cancelled","description":"Requires notify. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"city_id":{"type":"string"},"event_id":{"type":"string"},"filters":{"$ref":"#/components/schemas/SearchFilters"},"activity":{"type":"string","description":"Optional exact activity filter, case-insensitive."},"url":{"type":"string","format":"uri","description":"Public IPv4-resolvable HTTPS hostname, port 443 only. No redirects or IP literals."},"confirmed":{"const":true,"description":"You control this endpoint and consent to notifications."}},"required":["url","confirmed"]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/subscriptions/{id}/deliveries":{"get":{"summary":"Read last 50 delivery states for an owned subscription","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery IDs, attempts, states and last errors"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}},"/api/v1/subscriptions/{id}/revoke":{"post":{"summary":"Revoke an owned notification subscription","description":"Requires notify and ownership. Agents act for the person who issued their key.","security":[{"agentKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"required":[]}}}},"responses":{"200":{"description":"Authoritative result with current state"},"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Missing, revoked or expired authorization"},"403":{"description":"Insufficient permission"},"409":{"description":"Stale version, capacity, or idempotency conflict"},"422":{"description":"Validation failed"},"429":{"description":"Rate limited; inspect Retry-After"}}}}}}