{"openapi":"3.1.0","info":{"title":"Scheduleit API","version":"0.1.0","description":"Cron for the web and agent era."},"paths":{"/api/projects":{"get":{"summary":"List projects in the caller’s org","tags":["projects"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}}},"post":{"summary":"Create a project","tags":["projects"],"responses":{"201":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200}},"required":["name"],"additionalProperties":false}}}}}},"/api/projects/{id}/rotate-webhook-secret":{"post":{"summary":"Generate a new HMAC signing secret for the project's webhooks","tags":["projects"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]}},"/api/events":{"get":{"summary":"List scheduled events in a project","tags":["events"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"state","in":"query","required":false,"schema":{"type":"string","enum":["scheduled","claimed","delivered","cancelled","dead_letter"]}},{"name":"channel","in":"query","required":false,"schema":{"type":"string","enum":["webhook","email"]}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200}}]},"post":{"summary":"Schedule a new event","tags":["events"],"responses":{"201":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schedule":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"oneshot"},"fireAt":{"$ref":"#/$defs/__schema0"}},"required":["kind","fireAt"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"interval"},"everySeconds":{"type":"number","exclusiveMinimum":0,"maximum":31622400},"startAt":{"$ref":"#/$defs/__schema0"}},"required":["kind","everySeconds"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"cron"},"expression":{"type":"string","minLength":1},"timezone":{"type":"string"}},"required":["kind","expression"],"additionalProperties":false}]},"target":{"oneOf":[{"type":"object","properties":{"channel":{"type":"string","const":"webhook"},"url":{"type":"string","format":"uri"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["channel","url"],"additionalProperties":false},{"type":"object","properties":{"channel":{"type":"string","const":"email"},"address":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"subject":{"type":"string","minLength":1,"maxLength":200}},"required":["channel","address"],"additionalProperties":false}]},"payloadBase64":{"type":"string"},"idempotencyKey":{"type":"string","minLength":1,"maxLength":200}},"required":["schedule","target"],"additionalProperties":false}}}}}},"/api/events/{id}":{"get":{"summary":"Fetch a single scheduled event","tags":["events"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]},"patch":{"summary":"Edit a scheduled or dead-lettered event","tags":["events"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"schedule":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"oneshot"},"fireAt":{"$ref":"#/$defs/__schema0"}},"required":["kind","fireAt"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"interval"},"everySeconds":{"type":"number","exclusiveMinimum":0,"maximum":31622400},"startAt":{"$ref":"#/$defs/__schema0"}},"required":["kind","everySeconds"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"cron"},"expression":{"type":"string","minLength":1},"timezone":{"type":"string"}},"required":["kind","expression"],"additionalProperties":false}]},"target":{"oneOf":[{"type":"object","properties":{"channel":{"type":"string","const":"webhook"},"url":{"type":"string","format":"uri"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["channel","url"],"additionalProperties":false},{"type":"object","properties":{"channel":{"type":"string","const":"email"},"address":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"subject":{"type":"string","minLength":1,"maxLength":200}},"required":["channel","address"],"additionalProperties":false}]},"payloadBase64":{"type":"string"}},"additionalProperties":false}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]},"delete":{"summary":"Cancel a scheduled event","tags":["events"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]}},"/api/events/{id}/deliveries":{"get":{"summary":"List delivery attempts for an event","tags":["deliveries"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]}},"/api/dead-letter":{"get":{"summary":"List dead-lettered events","tags":["dead-letter"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200}}]}},"/api/dead-letter/{id}/replay":{"post":{"summary":"Move a dead-lettered event back to scheduled (fires immediately)","tags":["dead-letter"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]}},"/api/api-keys":{"get":{"summary":"List API keys visible to the principal","tags":["api-keys"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"projectId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]},"post":{"summary":"Issue a new API key (plaintext returned once)","tags":["api-keys"],"responses":{"201":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"anyOf":[{"$ref":"#/$defs/__schema0"},{"type":"null"}]},"scheduleId":{"anyOf":[{"$ref":"#/$defs/__schema0"},{"type":"null"}]}},"additionalProperties":false}}}}}},"/api/api-keys/{id}":{"delete":{"summary":"Revoke an API key","tags":["api-keys"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]}},"/api/emails":{"get":{"summary":"List verified email addresses for the org","tags":["emails"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}}},"post":{"summary":"Request verification of an email address","tags":["emails"],"responses":{"202":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["email"],"additionalProperties":false}}}}}},"/api/emails/{id}":{"delete":{"summary":"Revoke a verified email entry","tags":["emails"],"responses":{"200":{"description":"Success"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"description":"Conflict"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}]}}}}