{"openapi":"3.1.0","info":{"title":"ChabadHub Agent API","version":"1.0.0","description":"Authenticated REST access to the ChabadHub capability registry."},"servers":[{"url":"https://app.chabadhub.app"}],"tags":[{"name":"Read","description":"Capabilities that do not change CRM data."},{"name":"Write","description":"Capabilities that can change CRM data."}],"paths":{"/api/agent/v1/kesher_log_touchpoint":{"post":{"operationId":"kesher_log_touchpoint","summary":"Log a touchpoint","description":"Log an interaction (call, visit, message, event …) on a person's timeline, directly — it is saved immediately, exactly as if the user had logged it in the app. The note is never private. A follow-up needs follow_up_on (follow_up_action alone is refused). Every change is receipted and can be undone for seven days with kesher_undo.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"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)$","description":"The person's id, as returned by kesher_search_people or kesher_get_person_brief."},"kind":{"type":"string","enum":["call","visit","meeting","slack","whatsapp","email","event","ask","mitzvah","honor_gesture","simcha","condolence","yahrzeit_call","other"],"description":"What kind of interaction it was."},"occurred_at":{"description":"When it happened, ISO 8601 with offset. Defaults to now.","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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"summary":{"type":"string","minLength":1,"maxLength":2000,"description":"What happened, in a sentence or two. Saved as a normal (non-private) note on the timeline."},"follow_up_on":{"description":"Optional YYYY-MM-DD date to follow up by. Creates an open follow-up on this touchpoint.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"follow_up_action":{"description":"Optional: what the follow-up is (e.g. 'Send the shiur schedule'). Needs follow_up_on. Defaults to 'Follow up' when only follow_up_on is given.","type":"string","minLength":1,"maxLength":500},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["person_id","kind","summary"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"touchpoint_id":{"type":"string","description":"The touchpoint now on the person's timeline."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["touchpoint_id","receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_add_note":{"post":{"operationId":"kesher_add_note","summary":"Add a note","description":"Add a plain (non-private) note to a person's timeline, directly — for a fact worth remembering that was not an interaction. To record a call, visit or message, use kesher_log_touchpoint. Receipted; kesher_undo removes it within seven days.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"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)$","description":"The person's id, as returned by kesher_search_people or kesher_get_person_brief."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The note to add to the person's timeline. Never private."},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["person_id","text"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"touchpoint_id":{"type":"string","description":"The note's timeline entry."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["touchpoint_id","receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_update_person":{"post":{"operationId":"kesher_update_person","summary":"Update a person","description":"Change a person's names, phones, emails, mailing address or tier, directly. Overwrites the current value; the receipt keeps the old one, and kesher_undo restores it within seven days. Allowed fields: first_name, last_name, hebrew_name, email, other_email, mobile_phone, home_phone, work_phone, mailing_street, mailing_city, mailing_state, mailing_postal_code, mailing_country, donor_tier. Status, notes, dates and home membership cannot be changed here.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"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)$","description":"The person's id, as returned by kesher_search_people or kesher_get_person_brief."},"patch":{"type":"object","properties":{"first_name":{"description":"First name. Cannot be cleared.","type":"string","minLength":1,"maxLength":200},"last_name":{"description":"Last name. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"hebrew_name":{"description":"Hebrew name. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"email":{"description":"Primary email. null clears it.","anyOf":[{"type":"string","maxLength":320,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"other_email":{"description":"Second email. null clears it.","anyOf":[{"type":"string","maxLength":320,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"mobile_phone":{"description":"Mobile phone. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":50},{"type":"null"}]},"home_phone":{"description":"Home phone. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":50},{"type":"null"}]},"work_phone":{"description":"Work phone. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":50},{"type":"null"}]},"mailing_street":{"description":"Street address. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":300},{"type":"null"}]},"mailing_city":{"description":"City. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"mailing_state":{"description":"State / province. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"mailing_postal_code":{"description":"Postal code. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"mailing_country":{"description":"Country. null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"donor_tier":{"description":"The person's tier (the People board's Tier column).","type":"string","enum":["T1","T2","T3","T4","T5","none"]}},"additionalProperties":{},"description":"Only the fields to change. Allowed: first_name, last_name, hebrew_name, email, other_email, mobile_phone, home_phone, work_phone, mailing_street, mailing_city, mailing_state, mailing_postal_code, mailing_country, donor_tier. Any other field refuses the whole call."},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["person_id","patch"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"warmth":{"type":["number","null"]},"status":{"type":["string","null"]},"status_meaning":{"type":["string","null"]},"contact_status":{"type":["string","null"]},"contact_status_meaning":{"type":["string","null"]},"household_id":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"mobile_phone":{"type":["string","null"]},"city":{"type":["string","null"]},"birthdate":{"type":["string","null"]},"address":{"type":"object","properties":{"street":{"type":["string","null"]},"city":{"type":["string","null"]},"postal_code":{"type":["string","null"]},"country":{"type":["string","null"]}},"required":["street","city","postal_code","country"],"additionalProperties":false}},"required":["id","name","warmth","status","status_meaning","contact_status","contact_status_meaning","household_id","email","phone","mobile_phone","city","birthdate"],"additionalProperties":false,"description":"The person after the change."},"changed":{"type":"array","items":{"type":"string"},"description":"The patch fields whose value actually changed (empty when everything already matched — then nothing was written)."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["person","changed","receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_create_person":{"post":{"operationId":"kesher_create_person","summary":"Add a person","description":"Add a new person to the CRM, directly. Needs either their date_of_birth or adult:true (the user has confirmed this person is an adult); a minor (under 18 by date_of_birth) is added only into an existing home and without email or phone. Never blocks on a possible duplicate: it creates the person and NAMES any likely duplicates in possible_duplicates so you can tell the user (also on a retried request). Receipted; kesher_undo removes the new person within seven days.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"first_name":{"type":"string","minLength":1,"maxLength":200,"description":"First name (required)."},"last_name":{"description":"Last name.","type":"string","minLength":1,"maxLength":200},"hebrew_name":{"description":"Hebrew name.","type":"string","minLength":1,"maxLength":200},"phone":{"description":"Mobile phone number.","type":"string","minLength":1,"maxLength":50},"email":{"description":"Email address.","type":"string","maxLength":320,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"city":{"description":"City (mailing address).","type":"string","minLength":1,"maxLength":200},"household_id":{"description":"Optional: an existing home to add the person to, from kesher_search_households.","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)$"},"date_of_birth":{"description":"Date of birth, YYYY-MM-DD. Give this OR adult:true. Under 18 makes the person a minor: a minor needs household_id and must have no email or phone.","type":"string"},"adult":{"description":"true = the user has confirmed this person is an adult. Give this OR date_of_birth; never set it without asking the user.","type":"boolean","const":true},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["first_name"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"type":"string","description":"The new person's id."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"possible_duplicates":{"type":"array","items":{"type":"object","properties":{"person":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"warmth":{"type":["number","null"]},"status":{"type":["string","null"]},"status_meaning":{"type":["string","null"]},"contact_status":{"type":["string","null"]},"contact_status_meaning":{"type":["string","null"]},"household_id":{"type":["string","null"]}},"required":["id","name","warmth","status","status_meaning","contact_status","contact_status_meaning","household_id"],"additionalProperties":false},"match_kind":{"type":"string"},"confidence":{"type":"string"}},"required":["person","match_kind","confidence"],"additionalProperties":false},"description":"Existing people who may be the same person (shared email/phone, or same name and city). The person WAS still created — tell the user so they can merge in the app if it is a duplicate."},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["person_id","receipt_id","possible_duplicates"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_complete_queue_item":{"post":{"operationId":"kesher_complete_queue_item","summary":"Mark a Today item done or snoozed","description":"Record the user's reaction to a nudge on their Today queue — done ('acted') or snoozed — exactly like tapping it in the app. Done also nudges the person's warmth up, as in the app. The reaction is receipted, but it cannot be undone with kesher_undo.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"queue_id":{"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)$","description":"The `id` of a nudge returned by kesher_today_queue."},"reaction":{"type":"string","enum":["acted","snooze"],"description":"'acted' = done (the user reached out); 'snooze' = hide it until tomorrow."},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["queue_id","reaction"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"outcome":{"description":"recorded | recorded_personal (someone else already handled the card; yours is added) | same_actor_replay (you already reacted).","type":"string"},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_receipts":{"get":{"summary":"Recent agent changes","description":"List the changes agents have made in this CRM, newest first: what changed, when, by which connected app, and whether it can still be undone. Use it to answer 'what did you change?' and to find the receipt to pass to kesher_undo.","tags":["Read"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"since","in":"query","required":false,"schema":{"description":"Only changes made at or after this ISO 8601 time.","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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"description":"Only changes made at or after this ISO 8601 time."},{"name":"limit","in":"query","required":false,"schema":{"default":20,"description":"How many receipts, newest first (1–100, default 20).","type":"integer","minimum":1,"maximum":100},"description":"How many receipts, newest first (1–100, default 20)."}],"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"receipts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Pass to kesher_undo to reverse this change."},"capability":{"type":"string","description":"Which agent action made the change."},"op":{"type":"string","description":"insert | update | delete."},"target_table":{"type":"string"},"target_id":{"type":"string"},"changed_fields":{"type":"array","items":{"type":"string"},"description":"Which fields the change touched. Values are not repeated here."},"agent_client_id":{"description":"The connected app that made the change.","type":["string","null"]},"created_at":{"type":"string"},"undo_until":{"type":"string","description":"After this time the change can no longer be undone."},"undone_at":{"description":"Set when the change was already undone.","type":["string","null"]},"undoable":{"type":"boolean","description":"True when kesher_undo can still reverse it."}},"required":["id","capability","op","target_table","target_id","changed_fields","agent_client_id","created_at","undo_until","undone_at","undoable"],"additionalProperties":false},"description":"Newest first."}},"required":["receipts"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}},"post":{"operationId":"kesher_receipts","summary":"Recent agent changes","description":"List the changes agents have made in this CRM, newest first: what changed, when, by which connected app, and whether it can still be undone. Use it to answer 'what did you change?' and to find the receipt to pass to kesher_undo.","tags":["Read"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"since":{"description":"Only changes made at or after this ISO 8601 time.","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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"limit":{"default":20,"description":"How many receipts, newest first (1–100, default 20).","type":"integer","minimum":1,"maximum":100}}}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"receipts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Pass to kesher_undo to reverse this change."},"capability":{"type":"string","description":"Which agent action made the change."},"op":{"type":"string","description":"insert | update | delete."},"target_table":{"type":"string"},"target_id":{"type":"string"},"changed_fields":{"type":"array","items":{"type":"string"},"description":"Which fields the change touched. Values are not repeated here."},"agent_client_id":{"description":"The connected app that made the change.","type":["string","null"]},"created_at":{"type":"string"},"undo_until":{"type":"string","description":"After this time the change can no longer be undone."},"undone_at":{"description":"Set when the change was already undone.","type":["string","null"]},"undoable":{"type":"boolean","description":"True when kesher_undo can still reverse it."}},"required":["id","capability","op","target_table","target_id","changed_fields","agent_client_id","created_at","undo_until","undone_at","undoable"],"additionalProperties":false},"description":"Newest first."}},"required":["receipts"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_undo":{"post":{"operationId":"kesher_undo","summary":"Undo an agent change","description":"Reverse one change an agent made, within seven days, using its receipt. When one call changed several records (e.g. a donation that also moved an ask), any of its receipts reverses all of them together, or none. Refuses (ok:false with a reason) when a record was edited since, the window has passed, or it was already undone — it never overwrites newer work. Changes to giving records (gifts, asks, recurring giving) can be undone only by the organization's shliach.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"receipt_id":{"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)$","description":"The receipt to reverse, from a write's receipt_id or kesher_receipts."}},"required":["receipt_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"type":"boolean","description":"True when the change was reversed."},"reason":{"description":"Why it was not reversed: row_changed (edited since, or other records now depend on it — undo would overwrite newer work), expired (older than seven days), already_undone, not_allowed. Tell the user.","type":"string"},"detail":{"description":"For row_changed: moved (the record was edited since) or referenced (other records now point at it).","type":"string"},"undo_receipt_id":{"description":"The receipt of the reversal itself.","type":"string"}},"required":["ok"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_record_donation":{"post":{"operationId":"kesher_record_donation","summary":"Record a donation","description":"Record a gift someone gave, directly: amount in the organisation's own currency, the date (default today), how it was paid and an optional note. If the person has an open ask for that year, its received amount moves in the same step. The same person, date and amount twice is refused as a duplicate. Records money; never moves it. Receipted; kesher_undo reverses the gift and the ask change together, within seven days and by the organization's shliach.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"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)$","description":"The person's id, as returned by kesher_search_people or kesher_get_person_brief."},"amount":{"type":"number","exclusiveMinimum":0,"exclusiveMaximum":10000000000000,"description":"An amount in the organisation's own currency, e.g. 180 or 180.50 (no currency code)."},"donated_on":{"description":"YYYY-MM-DD the gift was given. Defaults to today; a future date is refused.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"method":{"description":"How it was paid, e.g. eft, cash, card, cheque. Saved as the gift's payment type.","type":"string","minLength":1,"maxLength":100},"note":{"description":"Optional short note saved on the gift (its memo).","type":"string","minLength":1,"maxLength":500},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["person_id","amount"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"donation_id":{"type":"string","description":"The gift now on file."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"pipeline_status":{"description":"What happened to this year's ask: updated (its received amount moved), no_open_ask, duplicate_open_asks (two open asks — none was moved; tell the user), unchanged.","type":"string","enum":["updated","no_open_ask","duplicate_open_asks","unchanged"]},"ask_id":{"description":"The ask whose received amount moved, when pipeline_status is updated.","type":"string"},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["donation_id","receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_set_pledge":{"post":{"operationId":"kesher_set_pledge","summary":"Set a pledge or ask","description":"Set what a person pledged or is being asked for in one campaign year, directly: pledged amount, ask amount, stage, and when to get back to them. Changes the person's ask for that year, or creates it when there is none. Money received is not set here — record the gift with kesher_record_donation. Receipted; kesher_undo restores the previous values within seven days, by the organization's shliach.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"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)$","description":"The person's id, as returned by kesher_search_people or kesher_get_person_brief."},"campaign_year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The campaign year of the ask, e.g. 2026. One ask per person per year."},"pledged_amount":{"description":"The amount the person pledged.","type":"number","exclusiveMinimum":0,"exclusiveMaximum":10000000000000},"ask_amount":{"description":"The amount being asked for.","type":"number","exclusiveMinimum":0,"exclusiveMaximum":10000000000000},"state":{"description":"The ask's stage. Use committed when recording a pledge. A new ask without a state starts at to_ask.","type":"string","enum":["to_ask","asked","considering","deferred","redirected","declined_this_year","partial","committed","received","thanked"]},"recontact_on":{"description":"YYYY-MM-DD to get back to them. null clears it.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["person_id","campaign_year"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ask_id":{"type":"string","description":"The person's ask for that campaign year."},"created":{"type":"boolean","description":"True when no ask existed for the year and one was created."},"changed":{"type":"array","items":{"type":"string"},"description":"The fields whose value actually changed (empty when everything already matched — then nothing was written)."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["ask_id","created","changed","receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_set_recurring":{"post":{"operationId":"kesher_set_recurring","summary":"Set recurring giving","description":"Set up, change or end a person's recurring giving, directly: the amount per charge, the cadence (weekly, monthly, quarterly, annually), the next charge date, or active:false to end it. Changes the person's running commitment, or creates one (amount and cadence required) when there is none. Records the arrangement only; it never charges anyone. Receipted; kesher_undo restores the previous values within seven days, by the organization's shliach.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"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)$","description":"The person's id, as returned by kesher_search_people or kesher_get_person_brief."},"recurring_id":{"description":"Which commitment, when the person has more than one running (see kesher_giving_summary).","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)$"},"amount":{"description":"The amount of each charge.","type":"number","exclusiveMinimum":0,"exclusiveMaximum":10000000000000},"cadence":{"description":"How often it is given. Required when creating one.","type":"string","enum":["weekly","monthly","quarterly","annually"]},"start_on":{"description":"YYYY-MM-DD of the next charge.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"active":{"description":"false ends the commitment (it is kept as cancelled, never deleted).","type":"boolean"},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["person_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"recurring_id":{"type":"string","description":"The commitment that was changed or created."},"created":{"type":"boolean","description":"True when the person had no running commitment and one was created."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["recurring_id","created","receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_mark_thanked":{"post":{"operationId":"kesher_mark_thanked","summary":"Mark a gift thanked","description":"Mark one gift as thanked, directly (stamps the time). A gift already thanked is left as it is. This does not log a conversation: if the user spoke to the donor, also call kesher_log_touchpoint. Receipted; the mark can be undone with kesher_undo within seven days, by the organization's shliach.","tags":["Write"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"donation_id":{"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)$","description":"The gift, from kesher_record_donation's donation_id."},"idempotency_key":{"description":"Optional. Pass the same key when retrying the same request: the change is made once and a retry returns the original result. Reusing a key with different arguments is refused.","type":"string","pattern":"^[A-Za-z0-9._:-]{1,128}$"}},"required":["donation_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"donation_id":{"type":"string"},"thanked_at":{"type":"string","description":"When the gift was marked thanked (the original time when it already was)."},"already_thanked":{"type":"boolean","description":"True when the gift was already marked thanked; nothing was written."},"receipt_id":{"description":"The receipt for this change (undo it with kesher_undo within seven days). Null only if the receipt layer did not record the change — tell the user.","type":["string","null"]},"replayed":{"description":"True when this was a retry with an idempotency_key already used; nothing new was changed.","type":"boolean"}},"required":["donation_id","thanked_at","already_thanked","receipt_id"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}},"/api/agent/v1/kesher_giving_summary":{"get":{"summary":"Giving summary","description":"Summarise a home's giving (pass a person to get their home — the home is the donor unit): this and last fiscal year's totals in the organisation's own fiscal years, lifetime total, the last gift, whether they gave last year but not this year, open pledges and recurring giving. Read-only. Amounts are in the organisation's own currency. Gift notes and dedications are never included.","tags":["Read"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"person_id","in":"query","required":false,"schema":{"description":"A person: the summary covers their home (the donor unit).","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)$"},"description":"A person: the summary covers their home (the donor unit)."},{"name":"household_id","in":"query","required":false,"schema":{"description":"A home, from kesher_search_households.","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)$"},"description":"A home, from kesher_search_households."}],"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"scope":{"type":"string","enum":["household","person"],"description":"household normally; person only when the person belongs to no household."},"household_id":{"type":["string","null"]},"this_fiscal_year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The organisation's current fiscal year, named by the calendar year it starts in."},"fiscal_year_basis":{"type":"string","description":"Which years these are, e.g. 'fiscal years starting March'."},"this_year_total":{"type":"number"},"last_year_total":{"type":"number"},"lifetime_total":{"type":"number"},"withheld_count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Number of gifts excluded by the connector's subject wall; no withheld amounts are included."},"last_gift":{"anyOf":[{"type":"object","properties":{"donated_on":{"type":"string"},"amount":{"type":"number"}},"required":["donated_on","amount"],"additionalProperties":false},{"type":"null"}]},"gave_last_year_not_this_year":{"type":"boolean"},"open_pledges":{"type":"array","items":{"type":"object","properties":{"ask_id":{"type":"string"},"campaign_year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"state":{"type":"string"},"pledged_amount":{"type":["number","null"]},"received_amount":{"type":["number","null"]}},"required":["ask_id","campaign_year","state","pledged_amount","received_amount"],"additionalProperties":false}},"recurring":{"type":"array","items":{"type":"object","properties":{"recurring_id":{"type":"string"},"state":{"type":"string"},"amount_per_charge":{"type":["number","null"]},"schedule":{"description":"As stored (imported values pass through unchanged).","type":["string","null"]},"next_charge_date":{"type":["string","null"]},"last_payment_date":{"type":["string","null"]}},"required":["recurring_id","state","amount_per_charge","schedule","next_charge_date","last_payment_date"],"additionalProperties":false}}},"required":["scope","household_id","this_fiscal_year","fiscal_year_basis","this_year_total","last_year_total","lifetime_total","withheld_count","last_gift","gave_last_year_not_this_year","open_pledges","recurring"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}},"post":{"operationId":"kesher_giving_summary","summary":"Giving summary","description":"Summarise a home's giving (pass a person to get their home — the home is the donor unit): this and last fiscal year's totals in the organisation's own fiscal years, lifetime total, the last gift, whether they gave last year but not this year, open pledges and recurring giving. Read-only. Amounts are in the organisation's own currency. Gift notes and dedications are never included.","tags":["Read"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"person_id":{"description":"A person: the summary covers their home (the donor unit).","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)$"},"household_id":{"description":"A home, from kesher_search_households.","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)$"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Capability completed successfully.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"scope":{"type":"string","enum":["household","person"],"description":"household normally; person only when the person belongs to no household."},"household_id":{"type":["string","null"]},"this_fiscal_year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The organisation's current fiscal year, named by the calendar year it starts in."},"fiscal_year_basis":{"type":"string","description":"Which years these are, e.g. 'fiscal years starting March'."},"this_year_total":{"type":"number"},"last_year_total":{"type":"number"},"lifetime_total":{"type":"number"},"withheld_count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Number of gifts excluded by the connector's subject wall; no withheld amounts are included."},"last_gift":{"anyOf":[{"type":"object","properties":{"donated_on":{"type":"string"},"amount":{"type":"number"}},"required":["donated_on","amount"],"additionalProperties":false},{"type":"null"}]},"gave_last_year_not_this_year":{"type":"boolean"},"open_pledges":{"type":"array","items":{"type":"object","properties":{"ask_id":{"type":"string"},"campaign_year":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"state":{"type":"string"},"pledged_amount":{"type":["number","null"]},"received_amount":{"type":["number","null"]}},"required":["ask_id","campaign_year","state","pledged_amount","received_amount"],"additionalProperties":false}},"recurring":{"type":"array","items":{"type":"object","properties":{"recurring_id":{"type":"string"},"state":{"type":"string"},"amount_per_charge":{"type":["number","null"]},"schedule":{"description":"As stored (imported values pass through unchanged).","type":["string","null"]},"next_charge_date":{"type":["string","null"]},"last_payment_date":{"type":["string","null"]}},"required":["recurring_id","state","amount_per_charge","schedule","next_charge_date","last_payment_date"],"additionalProperties":false}}},"required":["scope","household_id","this_fiscal_year","fiscal_year_basis","this_year_total","last_year_total","lifetime_total","withheld_count","last_gift","gave_last_year_not_this_year","open_pledges","recurring"],"additionalProperties":false}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Bearer token missing or invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"403":{"description":"The token lacks the required scope.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Capability or record not found.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"The request conflicts with current state.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"Request rate limit exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}},"503":{"description":"Capability temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}}