{"openapi":"3.1.0","info":{"title":"Almendra API","version":"v1","description":"REST API for Almendra (https://almendra.io), the practice-management platform for nutritionists, dietitians, coaches and personal trainers. Read and manage the patients, scheduled appointments and health plans of one professional account. Every request needs an API key sent as `Authorization: Bearer <key>`; each key is bound to a single professional account, so no account id is ever passed in the URL. Keys are issued by Almendra support (hola@almendra.io). List endpoints are paginated with a fixed page size of 50.","contact":{"name":"Almendra support","email":"hola@almendra.io"}},"externalDocs":{"description":"Interactive API reference","url":"https://api.almendra.io/docs"},"security":[{"bearerAuth":[]}],"servers":[{"url":"https://api.almendra.io/openapi","description":"Production server"}],"tags":[{"name":"Patients","description":"Patient management endpoints"},{"name":"Appointments","description":"Scheduled appointment management endpoints"},{"name":"Health Plans","description":"Health plan and purchased health plan management endpoints"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Almendra API key, bound to one professional account. Send it as `Authorization: Bearer YOUR_API_KEY`."}},"schemas":{"PatientListResponse":{"type":"object","properties":{"patients":{"type":"array","items":{"$ref":"#/components/schemas/PatientResponse"}},"page":{"type":"integer","minimum":0,"exclusiveMinimum":true,"example":1},"pageSize":{"type":"integer","minimum":0,"exclusiveMinimum":true,"example":50},"totalCount":{"type":"integer","example":150},"totalPages":{"type":"integer","example":3}},"required":["patients","page","pageSize","totalCount","totalPages"]},"PatientResponse":{"type":"object","properties":{"_id":{"type":"string","example":"507f1f77bcf86cd799439011"},"firstName":{"type":"string","example":"John"},"lastName":{"type":"string","example":"Doe"},"email":{"type":"string","format":"email","example":"john.doe@example.com"},"phone":{"type":"string","example":"+1234567890"},"nationality":{"type":"string","example":"American"},"address":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}},"required":["value","timestamp"]},"example":[{"value":"123 Main St, City, State 12345","timestamp":"2024-01-15T00:00:00.000Z"}]},"birthdate":{"type":"string","format":"date-time","example":"1990-01-15T00:00:00.000Z"},"idNumber":{"type":"string","example":"123456789"},"occupation":{"type":"string","example":"Software Engineer"},"sex":{"type":"string","enum":["male","female","other"],"example":"male"},"expert":{"type":"string","example":"507f1f77bcf86cd799439012"},"createdAt":{"type":"string","format":"date-time","example":"2024-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2024-01-15T00:00:00.000Z"}},"required":["_id","firstName","lastName","sex","expert","createdAt","updatedAt"]},"PatientBasicInfo":{"type":"object","properties":{"firstName":{"type":"string","minLength":1,"example":"John","description":"Patient first name"},"lastName":{"type":"string","minLength":1,"example":"Doe","description":"Patient last name"},"email":{"type":"string","format":"email","example":"john.doe@example.com","description":"Patient email"},"phone":{"type":"string","example":"+1234567890","description":"Patient phone number"},"nationality":{"type":"string","example":"American","description":"Patient nationality"},"address":{"type":"string","example":"123 Main St, City, State 12345","description":"Patient address"},"birthdate":{"type":"string","format":"date-time","example":"1990-01-15T00:00:00.000Z","description":"Patient birthdate in ISO 8601 format"},"idNumber":{"type":"string","example":"123456789","description":"Patient ID number (e.g., SSN, passport)"},"occupation":{"type":"string","example":"Software Engineer","description":"Patient occupation"},"sex":{"type":"string","enum":["M","F"],"example":"M","description":"Patient sex"}},"required":["firstName","lastName","sex"]},"ScheduledAppointmentListResponse":{"type":"object","properties":{"appointments":{"type":"array","items":{"$ref":"#/components/schemas/ScheduledAppointmentResponse"}},"page":{"type":"integer","minimum":0,"exclusiveMinimum":true,"example":1},"pageSize":{"type":"integer","minimum":0,"exclusiveMinimum":true,"example":50},"totalCount":{"type":"integer","example":150},"totalPages":{"type":"integer","example":3}},"required":["appointments","page","pageSize","totalCount","totalPages"]},"ScheduledAppointmentResponse":{"type":"object","properties":{"_id":{"type":"string","example":"507f1f77bcf86cd799439016","description":"Appointment ID"},"patient":{"type":"string","example":"507f1f77bcf86cd799439011","description":"Patient ID"},"expert":{"type":"string","example":"507f1f77bcf86cd799439012","description":"Expert ID"},"appointmentStatus":{"type":"integer","example":0,"description":"Appointment status code"},"scheduledInfo":{"type":"object","properties":{"wasScheduled":{"type":"boolean"},"scheduledTimeStart":{"type":"string","format":"date-time"},"scheduledTimeEnd":{"type":"string","format":"date-time"},"scheduledDuration":{"type":"integer"}},"required":["wasScheduled"],"example":{"wasScheduled":true,"scheduledTimeStart":"2024-02-01T10:00:00.000Z","scheduledTimeEnd":"2024-02-01T11:00:00.000Z","scheduledDuration":60}},"location":{"type":"string"},"conferenceType":{"type":"string"},"conferenceRoomUrl":{"type":"string"},"conferenceRoomId":{"type":"string"},"price":{"type":"number"},"purchasedHealthPlan":{"type":"string"},"createdAt":{"type":"string","format":"date-time","example":"2024-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2024-01-15T00:00:00.000Z"}},"required":["_id","patient","expert","appointmentStatus","scheduledInfo","createdAt","updatedAt"]},"ScheduledAppointmentCreate":{"type":"object","properties":{"patient_id":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439011","description":"Patient ID"},"scheduledTimeStart":{"type":"string","format":"date-time","example":"2024-02-01T10:00:00.000Z","description":"Appointment start time in ISO 8601 format"},"scheduledTimeEnd":{"type":"string","format":"date-time","example":"2024-02-01T11:00:00.000Z","description":"Appointment end time in ISO 8601 format"},"scheduledTimeDuration":{"type":"integer","minimum":0,"exclusiveMinimum":true,"example":60,"description":"Appointment duration in minutes"},"location":{"type":"string","example":"Clinic Room 101","description":"Physical location of the appointment"},"conferenceType":{"type":"string","enum":["zoom","meet","other","none"],"example":"zoom","description":"Type of video conference"},"conferenceRoomUrl":{"type":"string","format":"uri","example":"https://zoom.us/j/1234567890","description":"Video conference URL"},"modality":{"type":"string","enum":["Virtual","Presencial","Consulta a Domicilio"],"example":"Virtual","description":"Appointment modality"},"address":{"type":"string","example":"123 Main St, City, State 12345","description":"Address for home visit appointments"},"healthPlan_id":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439013","description":"Health Plan ID"},"purchasedHealthPlan_id":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439014","description":"Purchased Health Plan ID (if using existing plan)"},"price":{"type":"number","minimum":0,"example":100,"description":"Appointment price"}},"required":["patient_id","scheduledTimeStart","scheduledTimeEnd","scheduledTimeDuration","modality","healthPlan_id","price"]},"ScheduledAppointmentUpdate":{"type":"object","properties":{"conferenceRoomUrl":{"type":"string","format":"uri","example":"https://zoom.us/j/1234567890","description":"Updated video conference URL"}}},"HealthPlanListResponse":{"type":"object","properties":{"healthPlans":{"type":"array","items":{"$ref":"#/components/schemas/HealthPlanResponse"}},"page":{"type":"integer","minimum":0,"exclusiveMinimum":true,"example":1},"pageSize":{"type":"integer","minimum":0,"exclusiveMinimum":true,"example":50},"totalCount":{"type":"integer","example":10},"totalPages":{"type":"integer","example":1}},"required":["healthPlans","page","pageSize","totalCount","totalPages"]},"HealthPlanResponse":{"type":"object","properties":{"_id":{"type":"string","example":"507f1f77bcf86cd799439013","description":"Health Plan ID"},"planName":{"type":"string","example":"Basic Consultation","description":"Health plan name"},"planDescription":{"type":"string","example":"Standard consultation package","description":"Health plan description"},"publicHealthPlan":{"type":"boolean","example":true,"description":"Whether this is a public health plan"},"isSingleAppointment":{"type":"boolean","example":true,"description":"Whether this is a single appointment plan"},"totalAppointments":{"type":"integer","example":1,"description":"Total number of appointments in the plan"},"includedAppointments":{"type":"array","items":{"type":"integer"},"example":[1],"description":"Array of included appointment counts"},"price":{"type":"number","example":100,"description":"Price of the health plan"},"currency":{"type":"string","example":"USD","description":"Currency code"},"createdAt":{"type":"string","format":"date-time","example":"2024-01-15T00:00:00.000Z","description":"Creation date"}},"required":["_id","isSingleAppointment"]},"PurchasedHealthPlanResponse":{"type":"object","properties":{"_id":{"type":"string","example":"507f1f77bcf86cd799439014","description":"Purchased Health Plan ID"},"planName":{"type":"string","example":"Basic Consultation","description":"Health plan name"},"planDescription":{"type":"string","example":"Standard consultation package","description":"Health plan description"},"isSingleAppointment":{"type":"boolean","example":true,"description":"Whether this is a single appointment plan"},"totalAppointments":{"type":"integer","example":1,"description":"Total number of appointments in the plan"},"price":{"type":"number","example":100,"description":"Price paid for the health plan"},"currency":{"type":"string","example":"USD","description":"Currency code"},"expert":{"type":"string","example":"507f1f77bcf86cd799439012","description":"Expert ID"},"patient":{"type":"string","example":"507f1f77bcf86cd799439011","description":"Patient ID"},"healthPlan":{"type":"string","example":"507f1f77bcf86cd799439013","description":"Original Health Plan ID"},"appointments":{"type":"array","items":{"type":"string"},"example":["507f1f77bcf86cd799439016"],"description":"Array of appointment IDs"},"remainingAppointments":{"type":"integer","example":0,"description":"Number of remaining appointments"},"pendingAmount":{"type":"number","example":0,"description":"Pending amount to pay"}},"required":["_id","isSingleAppointment","totalAppointments","price","expert","patient","healthPlan","appointments","remainingAppointments","pendingAmount"]}},"parameters":{}},"paths":{"/patients":{"get":{"operationId":"listPatients","tags":["Patients"],"summary":"List all patients for an expert","description":"Returns a paginated list of patients. Page size is fixed at 50 patients.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":0,"exclusiveMinimum":true,"default":1,"example":"1","description":"Page number (starts at 1)"},"required":false,"description":"Page number (starts at 1)","name":"page","in":"query"}],"responses":{"200":{"description":"List of patients","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientListResponse"}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Expert not found"}}},"post":{"operationId":"createPatient","tags":["Patients"],"summary":"Create a new patient","description":"Creates a new patient with basic information.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientBasicInfo"}}}},"responses":{"201":{"description":"Patient created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientResponse"}}}},"400":{"description":"Bad request - Invalid input"},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Expert not found"},"415":{"description":"Unsupported Media Type - send the body as JSON with Content-Type: application/json"}}}},"/patients/{patient_id}":{"get":{"operationId":"getPatient","tags":["Patients"],"summary":"Get a specific patient","description":"Returns detailed information about a specific patient.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439011","description":"Patient ID"},"required":true,"description":"Patient ID","name":"patient_id","in":"path"}],"responses":{"200":{"description":"Patient details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientResponse"}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Patient not found"}}},"put":{"operationId":"updatePatient","tags":["Patients"],"summary":"Update a patient","description":"Updates basic information of an existing patient.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439011","description":"Patient ID"},"required":true,"description":"Patient ID","name":"patient_id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string","minLength":1,"example":"John","description":"Patient first name"},"lastName":{"type":"string","minLength":1,"example":"Doe","description":"Patient last name"},"email":{"type":"string","format":"email","example":"john.doe@example.com","description":"Patient email"},"phone":{"type":"string","example":"+1234567890","description":"Patient phone number"},"nationality":{"type":"string","example":"American","description":"Patient nationality"},"address":{"type":"string","example":"123 Main St, City, State 12345","description":"Patient address"},"birthdate":{"type":"string","format":"date-time","example":"1990-01-15T00:00:00.000Z","description":"Patient birthdate in ISO 8601 format"},"idNumber":{"type":"string","example":"123456789","description":"Patient ID number (e.g., SSN, passport)"},"occupation":{"type":"string","example":"Software Engineer","description":"Patient occupation"},"sex":{"type":"string","enum":["M","F"],"example":"M","description":"Patient sex"}}}}}},"responses":{"200":{"description":"Patient updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientResponse"}}}},"400":{"description":"Bad request - Invalid input"},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Patient not found"},"415":{"description":"Unsupported Media Type - send the body as JSON with Content-Type: application/json"}}}},"/appointments":{"get":{"operationId":"listAppointments","tags":["Appointments"],"summary":"List scheduled appointments","description":"Returns a paginated list of scheduled appointments. Page size is fixed at 50.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":0,"exclusiveMinimum":true,"default":1,"example":"1","description":"Page number (starts at 1)"},"required":false,"description":"Page number (starts at 1)","name":"page","in":"query"}],"responses":{"200":{"description":"List of scheduled appointments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledAppointmentListResponse"}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Expert not found"}}},"post":{"operationId":"createAppointment","tags":["Appointments"],"summary":"Create a scheduled appointment","description":"Creates a new scheduled appointment. Automatically handles health plan management.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledAppointmentCreate"}}}},"responses":{"201":{"description":"Appointment created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledAppointmentResponse"}}}},"400":{"description":"Bad request - Invalid input"},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Expert or patient not found"},"415":{"description":"Unsupported Media Type - send the body as JSON with Content-Type: application/json"}}}},"/appointments/{appointment_id}":{"get":{"operationId":"getAppointment","tags":["Appointments"],"summary":"Get a specific scheduled appointment","description":"Returns detailed information about a specific appointment.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439016","description":"Appointment ID"},"required":true,"description":"Appointment ID","name":"appointment_id","in":"path"}],"responses":{"200":{"description":"Appointment details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledAppointmentResponse"}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Appointment not found"}}},"put":{"operationId":"updateAppointment","tags":["Appointments"],"summary":"Update a scheduled appointment","description":"Updates an existing scheduled appointment. Currently supports updating conference room URL.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439016","description":"Appointment ID"},"required":true,"description":"Appointment ID","name":"appointment_id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledAppointmentUpdate"}}}},"responses":{"200":{"description":"Appointment updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduledAppointmentResponse"}}}},"400":{"description":"Bad request - Invalid input"},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Appointment not found"},"415":{"description":"Unsupported Media Type - send the body as JSON with Content-Type: application/json"}}},"delete":{"operationId":"deleteAppointment","tags":["Appointments"],"summary":"Delete a scheduled appointment","description":"Deletes an existing scheduled appointment.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439016","description":"Appointment ID"},"required":true,"description":"Appointment ID","name":"appointment_id","in":"path"}],"responses":{"200":{"description":"Appointment deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"deletedId":{"type":"string"}},"required":["message","deletedId"]}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Appointment not found"}}}},"/health-plans":{"get":{"operationId":"listHealthPlans","tags":["Health Plans"],"summary":"List health plans","description":"Returns a paginated list of health plans for the expert. Page size is fixed at 50.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":0,"exclusiveMinimum":true,"default":1,"example":"1","description":"Page number (starts at 1)"},"required":false,"description":"Page number (starts at 1)","name":"page","in":"query"}],"responses":{"200":{"description":"List of health plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthPlanListResponse"}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Expert not found"}}}},"/patients/{patient_id}/purchased-health-plans/active":{"get":{"operationId":"getActivePurchasedHealthPlans","tags":["Health Plans"],"summary":"Get active purchased health plan for a patient","description":"Returns the list of active purchased health plans for a specific patient.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{24}$","example":"507f1f77bcf86cd799439011","description":"Patient ID"},"required":true,"description":"Patient ID","name":"patient_id","in":"path"}],"responses":{"200":{"description":"List of active purchased health plans","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PurchasedHealthPlanResponse"},{"nullable":true}]}}}},"401":{"description":"Unauthorized - Invalid API key"},"404":{"description":"Patient not found"}}}}}}