{"openapi":"3.1.0","info":{"title":"CHT API","version":"5.1.0","description":"API for interacting with the Community Health Toolkit","contact":{"name":"Medic","email":"hello@medic.org","url":"https://forum.communityhealthtoolkit.org/"},"license":{"name":"AGPL-3.0","url":"https://www.gnu.org/licenses/agpl-3.0.html"}},"servers":[{"url":"/"}],"components":{"schemas":{"PageCursor":{"type":["string","null"],"description":"Token for retrieving the next page. A `null` value indicates there are no more pages."},"OkResponse":{"type":"object","properties":{"ok":{"const":true}}},"ExportOptions":{"type":"object","properties":{"humanReadable":{"type":"boolean","description":"Set to true to format dates as ISO 8601 instead of epoch timestamps."}},"additionalProperties":true},"UserDevice":{"type":"object","properties":{"user":{"type":"string","description":"The user's name."},"deviceId":{"type":"string","description":"The unique key for the user's device."},"date":{"type":"string","description":"The date the telemetry entry was taken (YYYY-MM-DD), see [relevant docs](/technical-overview/data/performance/telemetry/).\n"},"browser":{"type":"object","properties":{"name":{"type":"string","description":"The name of the browser used."},"version":{"type":"string","description":"The version of the browser used."}}},"apk":{"type":"string","description":"The [version code](https://developer.android.com/reference/android/R.styleable#AndroidManifest_versionCode) of the Android app.\n"},"android":{"type":"string","description":"The version of Android OS."},"cht":{"type":"string","description":"The version of CHT at time of telemetry."},"settings":{"type":"string","description":"The revision of the App Settings document."},"storageFree":{"type":"number","description":"Free storage space on the device in bytes. Added in CHT 5.0.0."},"storageTotal":{"type":"number","description":"Total storage capacity of the device in bytes. Added in CHT 5.0.0."}}},"HydrationResult":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"The document uuid."},"doc":{"type":"object","additionalProperties":true,"description":"The fully hydrated document. Present when the document is found."},"error":{"type":"string","description":"\"not_found\" when the document is not found."}}},"MonitoringVersion":{"type":"object","properties":{"app":{"type":"string","description":"The version of the webapp."},"node":{"type":"string","description":"The version of NodeJS."},"couchdb":{"type":"string","description":"The version of CouchDB."}}},"MonitoringCouchDb":{"type":"object","description":"CouchDB metrics keyed by database name (e.g. \"medic\", \"medic-sentinel\", \"medic-users-meta\", \"_users\").\n","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"The name of the db."},"update_sequence":{"type":"number","description":"The number of changes in the db."},"doc_count":{"type":"number","description":"The number of docs in the db."},"doc_del_count":{"type":"number","description":"The number of deleted docs in the db."},"fragmentation":{"type":"number","description":"The fragmentation of the entire db (including view indexes) as stored on disk. A lower value is better. `1` is no fragmentation.\n"},"sizes":{"type":"object","description":"Database size information. Requires CHT Core `4.11.0` or later.","properties":{"active":{"type":"number","description":"The size in bytes of live data inside the database. Includes documents, metadata, and attachments, but not view indexes.\n"},"file":{"type":"number","description":"The size in bytes of the database file on disk. Includes documents, metadata, and attachments, but not view indexes.\n"}}},"view_indexes":{"type":"array","description":"View index information. Requires CHT Core `4.11.0` or later.","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the view index (the design)."},"sizes":{"type":"object","properties":{"active":{"type":"number","description":"The size in bytes of live data inside the view."},"file":{"type":"number","description":"The size in bytes of the view as stored on disk."}}}}}}}}},"MonitoringDate":{"type":"object","properties":{"current":{"type":"number","description":"The current server date in millis since the epoch, useful for ensuring the server time is correct.\n"},"uptime":{"type":"number","description":"How long API has been running in seconds."}}},"MonitoringSentinel":{"type":"object","properties":{"backlog":{"type":"number","description":"Number of changes yet to be processed by Sentinel."}}},"MonitoringOutboundPush":{"type":"object","properties":{"backlog":{"type":"number","description":"Number of changes yet to be processed by Outbound Push."}}},"MonitoringFeedback":{"type":"object","properties":{"count":{"type":"number","description":"Number of feedback docs created, usually indicative of client side errors.\n"}}},"MonitoringConflict":{"type":"object","properties":{"count":{"type":"number","description":"Number of doc conflicts which need to be resolved manually."}}},"MonitoringReplicationLimit":{"type":"object","properties":{"count":{"type":"number","description":"Number of users that exceeded the replication limit of documents."}}},"MonitoringConnectedUsers":{"type":"object","properties":{"count":{"type":"number","description":"Number of users that have connected to the api in a given number of days. The period defaults to 7 days but can be changed via the `connected_user_interval` query parameter.\n"}}},"RecordSuccess":{"type":"object","properties":{"success":{"type":"boolean"},"id":{"type":"string","description":"The id of the created record."}},"required":["success","id"]},"UpgradeRequestBody":{"type":"object","required":["build"],"properties":{"build":{"type":"object","required":["namespace","application","version"],"properties":{"namespace":{"type":"string","description":"Must be \"medic\"."},"application":{"type":"string","description":"Must be \"medic\"."},"version":{"type":"string","description":"The version to upgrade to. Should correspond to a release, pre-release, or branch that has been pushed to the builds server (`https://staging.dev.medicmobile.org/builds`).\n"}}}}},"UserInput":{"type":"object","required":["username","roles"],"properties":{"username":{"type":"string","description":"Identifier used for authentication."},"roles":{"type":"array","items":{"type":"string"}},"place":{"description":"Place identifier or object representing the place the user resides in. Required if roles contain an offline role.\n","oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]},"contact":{"description":"Person identifier or object representing the person contact for the user. Required if roles contain an offline role.\n","oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]},"password":{"type":"string","description":"Password for authentication. Must be at least 8 characters long and difficult to guess. Required if `token_login` or `oidc_username` is not set.\n"},"phone":{"type":"string","description":"Valid phone number. Required if `token_login` is set."},"token_login":{"type":"boolean","description":"Sets [login by SMS](/building/reference/app-settings/token_login) for this user. Added in `3.10.0`.\n"},"fullname":{"type":"string"},"email":{"type":"string"},"known":{"type":"boolean","description":"Indicates if the user has logged in before."},"password_change_required":{"type":"boolean","description":"Set `false` to skip [password reset prompt](/building/login/#password-reset-on-first-login) on next login. Added in `4.17.0`.\n"},"oidc_username":{"type":"string","description":"Unique username for [authenticating via OIDC](/building/reference/api/#login-by-oidc). This value must match the `email` claim returned for the user by the OIDC provider. Added in `4.20.0`.\n"}}},"UserCreateResult":{"type":"object","properties":{"contact":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}},"user-settings":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}},"user":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}}}},"InvalidUserInputError":{"type":"object","additionalProperties":true,"properties":{"error":{"oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]}},"examples":[{"error":{"message":"Username \"mary\" already taken.","translationKey":"username.taken","translationParams":{"username":"mary"}}},{"error":"Missing required fields: username, password, type or roles","details":{"failingIndexes":[{"fields":["username","password","type or roles"],"index":0},{"fields":["password","type or roles"],"index":1}]}}]},"v1.Contact":{"type":"object","properties":{"_id":{"type":"string"},"parent":{"$ref":"#/components/schemas/NormalizedParent"},"_rev":{"type":"string"},"contact_type":{"type":"string"},"name":{"type":"string"},"reported_date":{"type":"number"},"type":{"type":"string"}},"required":["_id","_rev","type"],"additionalProperties":true,"description":"Immutable data about a Contact."},"NormalizedParent":{"type":"object","properties":{"_id":{"type":"string"},"parent":{"$ref":"#/components/schemas/NormalizedParent"}},"additionalProperties":true,"required":["_id"],"description":"Parent lineage data for an entity."},"DataObject":{"type":"object","additionalProperties":true,"properties":{},"description":"A data object."},"v1.ContactWithLineage":{"type":"object","properties":{"_id":{"type":"string"},"parent":{"anyOf":[{"$ref":"#/components/schemas/v1.ContactWithLineage"},{"$ref":"#/components/schemas/NormalizedParent"}]},"_rev":{"type":"string"},"contact_type":{"type":"string"},"name":{"type":"string"},"reported_date":{"type":"number"},"type":{"type":"string"}},"additionalProperties":true,"required":["_id","_rev","type"],"description":"Immutable data about a contact, including the full records of the parent's lineage."},"v1.Person":{"type":"object","properties":{"_id":{"type":"string"},"parent":{"$ref":"#/components/schemas/NormalizedParent"},"_rev":{"type":"string"},"contact_type":{"type":"string"},"name":{"type":"string"},"reported_date":{"type":"number"},"type":{"type":"string"},"date_of_birth":{"$ref":"#/components/schemas/DateTimeString"},"phone":{"type":"string"},"patient_id":{"type":"string"},"sex":{"type":"string"}},"additionalProperties":true,"required":["_id","_rev","type"],"description":"Immutable data about a person contact."},"DateTimeString":{"type":"string","description":"A string representation of a date value (optionally including the time). Valid values are supported parameters for the `Date.parse()` function and the `Date()` constructor."},"v1.PersonWithLineage":{"type":"object","properties":{"_id":{"type":"string"},"parent":{"anyOf":[{"$ref":"#/components/schemas/v1.PlaceWithLineage"},{"$ref":"#/components/schemas/NormalizedParent"}]},"_rev":{"type":"string"},"contact_type":{"type":"string"},"name":{"type":"string"},"reported_date":{"type":"number"},"type":{"type":"string"},"date_of_birth":{"$ref":"#/components/schemas/DateTimeString"},"phone":{"type":"string"},"patient_id":{"type":"string"},"sex":{"type":"string"}},"additionalProperties":true,"required":["_id","_rev","type"],"description":"Immutable data about a person contact, including the full records of the parent place lineage."},"v1.PlaceWithLineage":{"type":"object","properties":{"_id":{"type":"string"},"parent":{"anyOf":[{"$ref":"#/components/schemas/v1.PlaceWithLineage"},{"$ref":"#/components/schemas/NormalizedParent"}]},"_rev":{"type":"string"},"contact_type":{"type":"string"},"name":{"type":"string"},"reported_date":{"type":"number"},"type":{"type":"string"},"contact":{"anyOf":[{"$ref":"#/components/schemas/v1.PersonWithLineage"},{"$ref":"#/components/schemas/NormalizedParent"}]},"place_id":{"type":"string"}},"additionalProperties":true,"required":["_id","_rev","type"],"description":"Immutable data about a place contact, including the full records of the parent place lineage and the primary contact for the place."},"v1.Place":{"type":"object","properties":{"_id":{"type":"string"},"parent":{"$ref":"#/components/schemas/NormalizedParent"},"_rev":{"type":"string"},"contact_type":{"type":"string"},"name":{"type":"string"},"reported_date":{"type":"number"},"type":{"type":"string"},"contact":{"$ref":"#/components/schemas/NormalizedParent"},"place_id":{"type":"string"}},"additionalProperties":true,"required":["_id","_rev","type"],"description":"Immutable data about a place contact."},"v1.Report":{"type":"object","properties":{"_id":{"type":"string"},"_rev":{"type":"string"},"form":{"type":"string"},"reported_date":{"type":"number"},"fields":{"$ref":"#/components/schemas/DataObject"},"contact":{"$ref":"#/components/schemas/NormalizedParent"}},"required":["_id","_rev","form"],"additionalProperties":true,"description":"A report document."},"v1.ReportWithLineage":{"type":"object","properties":{"_id":{"type":"string"},"_rev":{"type":"string"},"form":{"type":"string"},"reported_date":{"type":"number"},"fields":{"$ref":"#/components/schemas/DataObject"},"contact":{"anyOf":[{"$ref":"#/components/schemas/v1.ContactWithLineage"},{"$ref":"#/components/schemas/NormalizedParent"}]},"patient":{"anyOf":[{"$ref":"#/components/schemas/v1.ContactWithLineage"},{"$ref":"#/components/schemas/NormalizedParent"}]},"place":{"anyOf":[{"$ref":"#/components/schemas/v1.ContactWithLineage"},{"$ref":"#/components/schemas/NormalizedParent"}]}},"additionalProperties":true,"required":["_id","_rev","form"],"description":"A report document with lineage information."},"v1.TargetValue":{"type":"object","properties":{"id":{"type":"string"},"value":{"type":"object","properties":{"pass":{"type":"number"},"total":{"type":"number"},"percent":{"type":"number"}},"required":["pass","total"],"additionalProperties":false}},"required":["id","value"],"additionalProperties":true,"description":"Data about a particular target for a user."},"v1.Target":{"type":"object","properties":{"_id":{"type":"string"},"_rev":{"type":"string"},"user":{"type":"string"},"owner":{"type":"string"},"reporting_period":{"type":"string"},"updated_date":{"type":"number"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/v1.TargetValue"}}},"required":["_id","_rev","owner","reporting_period","targets","updated_date","user"],"additionalProperties":true,"description":"Data about a user's targets from a particular interval."},"v1.ReportInput":{"type":"object","properties":{"form":{"type":"string"},"reported_date":{"anyOf":[{"$ref":"#/components/schemas/DateTimeString"},{"type":"number"}]},"contact":{"type":"string"}},"required":["form","contact"],"additionalProperties":true,"description":"Input data for a report."},"v1.PersonInput":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"reported_date":{"anyOf":[{"$ref":"#/components/schemas/DateTimeString"},{"type":"number"}]},"parent":{"type":"string"},"date_of_birth":{"anyOf":[{"$ref":"#/components/schemas/DateTimeString"},{"type":"string","format":"date-time"}]},"phone":{"type":"string"},"patient_id":{"type":"string"},"sex":{"type":"string"}},"required":["name","parent","type"],"additionalProperties":true,"description":"Input data for a person."},"v1.UpdatePersonInput":{"anyOf":[{"$ref":"#/components/schemas/v1.Person"},{"$ref":"#/components/schemas/v1.PersonWithLineage"}],"description":"Input data for updating a person. The following properties are read-only and cannot be changed: `reported_date`, `parent`, `type`, `contact_type`."},"v1.PlaceInput":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"reported_date":{"anyOf":[{"$ref":"#/components/schemas/DateTimeString"},{"type":"number"}]},"parent":{"type":"string"},"contact":{"type":"string"},"place_id":{"type":"string"}},"additionalProperties":true,"required":["name","type"],"description":"Input data for a place."}},"parameters":{"cursor":{"in":"query","name":"cursor","schema":{"type":"string"},"description":"Token identifying which page to retrieve. Omit for the first page. Subsequent pages can be retrieved by providing the cursor returned with the previous page."},"limitEntity":{"in":"query","name":"limit","schema":{"type":"number","default":100,"minimum":1},"description":"The maximum number of entities to return."},"limitId":{"in":"query","name":"limit","schema":{"type":"number","default":10000,"minimum":1},"description":"The maximum number of identifiers to return."},"withLineage":{"in":"query","name":"with_lineage","schema":{"enum":["true","false"],"default":"false"},"description":"Include the full parent lineage."},"exportOptionsQuery":{"in":"query","name":"options","description":"Export options.","style":"deepObject","explode":true,"schema":{"type":"object","properties":{"humanReadable":{"enum":["true","false"],"default":"false","description":"Set to \"true\" to format dates as ISO 8601 instead of epoch timestamps."}}}}},"responses":{"NotFound":{"description":"Entity not found"},"BadRequest":{"description":"Invalid input (missing required fields, invalid types, etc.)"},"Unauthorized":{"description":"Not authenticated"},"Forbidden":{"description":"Insufficient permissions"},"CsvExport":{"description":"The exported data as a CSV file download","content":{"text/csv":{"schema":{"type":"string","format":"binary"}}}},"UserDeviceExport":{"description":"User device information","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserDevice"}}}}}},"requestBodies":{"RecordInput":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Message string in a supported format (e.g. Muvuku or Textforms)."},"from":{"type":"string","description":"Reporting phone number."},"sent_timestamp":{"type":"number","description":"Timestamp in ms since Unix Epoch of when the message was received on the gateway. Defaults to now.\n"}},"required":["message","from"]}},"application/json":{"schema":{"type":"object","description":"Form field values as properties. Special values reside in `_meta`. Only strings and numbers are supported as field values. All property names will be lowercased.\n","properties":{"_meta":{"type":"object","properties":{"form":{"type":"string","description":"The form code."},"from":{"type":"string","description":"Reporting phone number. Optional."},"reported_date":{"type":"number","description":"Timestamp in ms since Unix Epoch of when the message was received on the gateway. Defaults to now.\n"},"locale":{"type":"string","description":"Optional locale string (e.g. 'fr')."}},"required":["form"]}},"additionalProperties":true}}}}}},"paths":{"/api/v1/express-metrics":{"get":{"summary":"Get metrics for Express API endpoints","operationId":"v1ExpressMetricsGet","description":"Used to retrieve a range of metrics for monitoring the API’s performance and internals.\n\nThe response is formatted for the [Prometheus Data Model](https://prometheus.io/docs/concepts/data_model/).\nThe metrics exposed are defined by the [prometheus-api-metrics package](https://www.npmjs.com/package/prometheus-api-metrics)\nand include optional default metrics and garbage collection metrics.\n","tags":["Monitoring"],"responses":{"200":{"description":"Prometheus metrics","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/api/info":{"get":{"summary":"Get the version of the CHT server","operationId":"apiInfoGet","description":"Returns the version of the CHT server.","tags":["Monitoring"],"responses":{"200":{"description":"The API info data","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string"}},"required":["version"]}}}}}}},"/api/deploy-info":{"get":{"summary":"Get deploy information","operationId":"apiDeployInfoGet","description":"Returns build and deploy information for the running CHT instance.","tags":["Monitoring"],"responses":{"200":{"description":"The deploy info data","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string","description":"The version of the deployed CHT instance"}},"required":["version"],"additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/places":{"post":{"summary":"Create a place","operationId":"v1PlacesPost","deprecated":true,"description":"Use [POST /api/v1/place](#/Place/v1PlacePost) instead. Create a new place and optionally a contact. The parent can be referenced by UUID or created inline. A contact can also be created inline or referenced by UUID.\n","tags":["Place"],"x-permissions":{"hasAll":["can_edit","can_create_places"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the place."},"type":{"type":"string","description":"The place type (e.g. `clinic`, `health_center`, `district_hospital`)."},"parent":{"description":"Parent place UUID or inline object. Required unless creating a top-level place.","oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]},"contact":{"description":"Contact person UUID or inline object.","oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]}},"required":["name","type"],"additionalProperties":true}}}},"responses":{"200":{"description":"Place created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/places/{id}":{"post":{"summary":"Update a place","operationId":"v1PlacesIdPost","deprecated":true,"description":"Use [PUT /api/v1/place/{id}](#/Place/v1PlaceIdPut) instead. Update a place and optionally its contact.\n","tags":["Place"],"x-permissions":{"hasAll":["can_edit","can_update_places"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the place to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Place properties to update."}}}},"responses":{"200":{"description":"Place updated","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/people":{"post":{"summary":"Create a person","operationId":"v1PeoplePost","deprecated":true,"description":"Use [POST /api/v1/person](#/Person/v1PersonPost) instead. Create a new person contact. A place can be created inline or referenced by UUID.\n","tags":["Person"],"x-permissions":{"hasAll":["can_edit","can_create_people"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The person's name."},"type":{"type":"string","default":"person","description":"ID of the contact_type for the new person. Defaults to `person` for backwards compatibility.\n"},"place":{"description":"Place UUID or inline object.","oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]},"reported_date":{"type":"number","description":"Timestamp of when the record was reported or created. Defaults to now."}},"required":["name"],"additionalProperties":true}}}},"responses":{"200":{"description":"Person created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/sms/africastalking/incoming-messages":{"post":{"summary":"Receive incoming SMS from Africa's Talking","operationId":"v1SmsAfricasTalkingIncomingMessagesPost","description":"Webhook endpoint for receiving incoming SMS messages from the Africa's Talking gateway. Requires a valid incoming key passed as a query parameter. See the [documentation](/building/messaging/gateways/africas-talking/) for more details.\n","tags":["SMS"],"parameters":[{"in":"query","name":"key","required":true,"schema":{"type":"string"},"description":"The configured incoming key for authentication."}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The Africa's Talking message id."},"from":{"type":"string","description":"The sender's phone number."},"text":{"type":"string","description":"The message content."}},"required":["id","from","text"]}}}},"responses":{"200":{"description":"Message processing results","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/sms/africastalking/delivery-reports":{"post":{"summary":"Receive delivery reports from Africa's Talking","operationId":"v1SmsAfricasTalkingDeliveryReportsPost","description":"Webhook endpoint for receiving SMS delivery status reports from the Africa's Talking gateway. Requires a valid incoming key passed as a query parameter. See the [documentation](/building/messaging/gateways/africas-talking/) for more details.\n","tags":["SMS"],"parameters":[{"in":"query","name":"key","required":true,"schema":{"type":"string"},"description":"The configured incoming key for authentication."}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The gateway message reference."},"status":{"enum":["Sent","Submitted","Buffered","Rejected","Success","Failed"],"description":"The delivery status from Africa's Talking."},"failureReason":{"type":"string","description":"The reason for failure, if applicable."}},"required":["id","status"]}}}},"responses":{"200":{"description":"Delivery report processing results","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/bulk-delete":{"post":{"summary":"Bulk delete documents","operationId":"v1BulkDeletePost","description":"Bulk delete endpoint for deleting large numbers of documents. Docs are batched into groups\nof 100 and sent sequentially to CouchDB. The response is chunked JSON (one batch at a\ntime), so to get an indication of progress incomplete JSON must be parsed with a library such as\n[`partial-json-parser`](https://github.com/indgov/partial-json-parser).\n\n### Errors\n\nIf an error is encountered part-way through the response (eg on the third batch), it’s impossible to send\nnew headers to indicate a 5xx error, so the connection will simply be terminated (as recommended here\nhttps://github.com/expressjs/express/issues/2700).\n","tags":["Bulk"],"x-permissions":{"hasAll":["can_edit"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["docs"],"properties":{"docs":{"type":"array","description":"Array of objects each with an `_id` property.","items":{"type":"object","additionalProperties":true,"required":["_id"],"properties":{"_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Chunked JSON response. Each chunk is an array of results for a batch of deletions.\n","content":{"application/json":{"schema":{"type":"array","items":{"type":"array","items":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":"string"},"rev":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/contact/{id}":{"get":{"summary":"Get a contact by id","operationId":"v1ContactIdGet","description":"Returns a contact record (person or place). Optionally includes the full parent place lineage.\n","tags":["Contact"],"x-since":"4.18.0","x-permissions":{"hasAll":["can_view_contacts"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the contact to retrieve"},{"$ref":"#/components/parameters/withLineage"}],"responses":{"200":{"description":"The contact record","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Contact"},{"$ref":"#/components/schemas/v1.ContactWithLineage"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/contact/uuid":{"get":{"summary":"Get contact UUIDs","operationId":"v1ContactUuidGet","description":"Returns a paginated array of contact identifier strings matching the given filter criteria. At least one of `type` or `freetext` must be provided.\n","tags":["Contact"],"x-since":"4.18.0","x-permissions":{"hasAll":["can_view_contacts"]},"parameters":[{"in":"query","name":"type","schema":{"type":"string"},"description":"The contact_type id for the type of contacts to fetch. Required if `freetext` is not provided and may be combined with `freetext`.\n"},{"in":"query","name":"freetext","schema":{"type":"string","minLength":3},"description":"A search term for filtering contacts. Must be at least 3 characters and not contain whitespace. Required if `type` is not provided and may be combined with `type`.\n"},{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/limitId"}],"responses":{"200":{"description":"A page of contact UUIDs","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","description":"The results for this page","items":{"type":"string"}},"cursor":{"$ref":"#/components/schemas/PageCursor"}},"required":["data","cursor"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/contacts-by-phone":{"get":{"summary":"Find contacts by phone number","operationId":"v1ContactsByPhoneGet","description":"Accepts a phone number and returns fully hydrated contacts that match. If multiple contacts are found, all are returned. Returns 404 when no matches are found.\n","tags":["Contact"],"x-since":"3.10.0","parameters":[{"in":"query","name":"phone","required":true,"schema":{"type":"string"},"description":"A URL-encoded string representing a phone number."}],"responses":{"200":{"description":"Matching contacts found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"docs":{"type":"array","description":"Fully hydrated matching contacts.","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Find contacts by phone number (POST)","operationId":"v1ContactsByPhonePost","description":"Accepts a phone number and returns fully hydrated contacts that match. If multiple contacts are found, all are returned. Returns 404 when no matches are found.\n","tags":["Contact"],"x-since":"3.10.0","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phone"],"properties":{"phone":{"type":"string","description":"A string representing a phone number."}}}}}},"responses":{"200":{"description":"Matching contacts found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"docs":{"type":"array","description":"Fully hydrated matching contacts.","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/credentials/{key}":{"put":{"summary":"Set a credential","operationId":"v1CredentialsKeyPut","description":"Securely store a credential for authentication with third-party systems such as SMS aggregators and HMIS.\nThe credential key is provided as a path parameter and the password as plain text in the request body.\nOnly database admins can access this endpoint.\n\nExample:\nTo set a credential with key “mykey” and password “my pass” use the following command:\n\n```shell\ncurl -X PUT -H \"Content-Type: text/plain\" https://<user>:<pass>@<domain>/api/v1/credentials/mykey -d 'my pass'\n```\n","tags":["Config"],"x-since":"4.0.0","parameters":[{"in":"path","name":"key","required":true,"schema":{"type":"string"},"description":"The credential key identifier."}],"requestBody":{"required":true,"content":{"text/plain":{"schema":{"type":"string","description":"The credential password/secret value."}}}},"responses":{"200":{"description":"Credential stored successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/export/dhis":{"get":{"summary":"Export DHIS2 target data","operationId":"v2ExportDhisGet","description":"Exports target data formatted as a DHIS2 dataValueSet. The data can be filtered to a specific section of the contact hierarchy or for a given time interval.\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_dhis"]},"parameters":[{"in":"query","name":"filters","schema":{"type":"object","properties":{"dataSet":{"type":"string","description":"A DHIS2 dataSet ID. Targets associated with this dataSet will have their data aggregated.\n"},"date":{"type":"object","required":["from"],"properties":{"from":{"type":"number","description":"Filter the target data to be within the month of this timestamp."}}},"orgUnit":{"type":"string","description":"Filter the target data to only that associated with contacts with attribute `{ dhis: { orgUnit } }`.\n"}},"required":["dataSet","date"]},"style":"deepObject","explode":true,"description":"Filters for the DHIS2 export."},{"$ref":"#/components/parameters/exportOptionsQuery"}],"responses":{"200":{"description":"DHIS2 dataValueSet","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Export DHIS2 target data","operationId":"v2ExportDhisPost","deprecated":true,"description":"Use [GET /api/v2/export/dhis](#/Export/v2ExportDhisGet) instead. Exports target data formatted as a DHIS2 dataValueSet. Accepts filters in the request body.\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_dhis"]},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"filters":{"type":"object","properties":{"dataSet":{"type":"string","description":"A DHIS2 dataSet ID."},"date":{"type":"object","required":["from"],"properties":{"from":{"type":"number","description":"Filter target data to be within the month of this timestamp."}}},"orgUnit":{"type":"string","description":"Filter by contacts with this DHIS2 orgUnit attribute."}},"required":["dataSet","date"]},"options":{"$ref":"#/components/schemas/ExportOptions"}}}}}},"responses":{"200":{"description":"DHIS2 dataValueSet","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/export/reports":{"get":{"summary":"Export reports","operationId":"v2ExportReportsGet","description":"Exports reports as CSV. Uses the [search library](https://github.com/medic/cht-core/tree/master/shared-libs/search) to ensure identical results to the front-end. Filters can be passed as query parameters using form-style encoding (e.g. `filters[forms][selected][0][code]=immunization_visit`).\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_messages"]},"parameters":[{"in":"query","name":"filters","schema":{"type":"object","properties":{"search":{"type":"string","description":"A freetext search term."},"forms":{"type":"object","description":"Filter by form codes.","properties":{"selected":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"}}}}}},"date":{"type":"object","properties":{"from":{"type":"number","description":"Start of date range (epoch timestamp)."},"to":{"type":"number","description":"End of date range (epoch timestamp)."}}},"verified":{"type":"string","description":"Filter by verification status (\"true\", \"false\")."},"valid":{"type":"string","description":"Filter by validity (\"true\")."}},"additionalProperties":true},"style":"deepObject","explode":true,"description":"Filters for the reports export."},{"$ref":"#/components/parameters/exportOptionsQuery"}],"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Export reports","operationId":"v2ExportReportsPost","deprecated":true,"description":"Use [GET /api/v2/export/reports](#/Export/v2ExportReportsGet) instead. Exports reports as CSV. Accepts filters in the request body.\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_messages"]},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"filters":{"type":"object","properties":{"search":{"type":"string","description":"A freetext search term."},"forms":{"type":"object","description":"Filter by form codes.","properties":{"selected":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"}}}}}},"date":{"type":"object","properties":{"from":{"type":"number","description":"Start of date range (epoch timestamp)."},"to":{"type":"number","description":"End of date range (epoch timestamp)."}}},"verified":{"description":"Filter by verification status.","oneOf":[{"type":"boolean"},{"type":"array","items":{"type":"boolean"}}]},"valid":{"type":"boolean","description":"Filter by validity."}},"additionalProperties":true},"options":{"$ref":"#/components/schemas/ExportOptions"}}}}}},"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/export/messages":{"get":{"summary":"Export messages","operationId":"v2ExportMessagesGet","description":"Exports messages as CSV.\n\n### Response Columns\n\n| Column             | Description                                                                          |\n| ------------------ | ------------------------------------------------------------------------------------ |\n| Record UUID        | The unique ID for the message in the database.                                       |\n| Patient ID         | The generated short patient ID for use in SMS.                                       |\n| Reported Date      | The date the message was received or generated.                                      |\n| From               | This phone number the message is or will be sent from.                               |\n| Contact Name       | The name of the user this message is assigned to.                                    |\n| Message Type       | The type of the message                                                              |\n| Message State      | The state of the message at the time this export was generated                       |\n| Received Timestamp | The datetime the message was received. Only applies to incoming messages.            |\n| Other Timestamps   | The datetime the message transitioned to each state.                                 |\n| Sent By            | The phone number the message was sent from. Only applies to incoming messages.       |\n| To Phone           | The phone number the message is or will be sent to. Only applies to outgoing.        |\n| Message Body       | The content of the message.                                                          |\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_messages"]},"parameters":[{"in":"query","name":"filters","schema":{"type":"object","properties":{"date":{"type":"object","properties":{"from":{"type":"number","description":"Start of date range (epoch timestamp)."},"to":{"type":"number","description":"End of date range (epoch timestamp)."}}}},"additionalProperties":true},"style":"deepObject","explode":true,"description":"Filters for the messages export."},{"$ref":"#/components/parameters/exportOptionsQuery"}],"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Export messages","operationId":"v2ExportMessagesPost","deprecated":true,"description":"Use [GET /api/v2/export/messages](#/Export/v2ExportMessagesGet) instead. Exports messages as CSV. Accepts filters in the request body. See [GET](#/Export/v2ExportMessagesGet) for output column details.\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_messages"]},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"filters":{"type":"object","properties":{"date":{"type":"object","properties":{"from":{"type":"number","description":"Start of date range (epoch timestamp)."},"to":{"type":"number","description":"End of date range (epoch timestamp)."}}}},"additionalProperties":true},"options":{"$ref":"#/components/schemas/ExportOptions"}}}}}},"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/export/contacts":{"get":{"summary":"Export contacts","operationId":"v2ExportContactsGet","description":"Exports contacts as a CSV. Filters use the same query format as the\n[search library](https://github.com/medic/cht-core/tree/master/shared-libs/search).\n\n### Response Columns\n\n| Column       | Description                                                                    |\n| -------------| -------------------------------------------------------------------------------|\n| id           | The unique ID for the contact in the database.                                 |\n| rev          | The current CouchDb revision of contact in the database.                       |\n| name         | The name of the user this message is assigned to.                              |\n| patient_id   | The generated short patient ID for use in SMS.                                 |\n| type         | The contact type. For configurable hierarchies, this will always be `contact`. |\n| contact_type | The configurable contact type. Will be empty if using the default hierarchy.   |\n| place_id     | The generated short place ID for use in SMS.                                   |\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_contacts"]},"parameters":[{"in":"query","name":"filters","schema":{"type":"object","properties":{"search":{"type":"string","description":"A freetext search term. (e.g. `GET /api/v2/export/contacts?filters[search]=jim`)"}},"additionalProperties":true},"style":"deepObject","explode":true,"description":"Filters for the contacts export."}],"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Export contacts","operationId":"v2ExportContactsPost","deprecated":true,"description":"Use [GET /api/v2/export/contacts](#/Export/v2ExportContactsGet) instead. Exports contacts as a CSV. Accepts filters in the request body. See [GET](#/Export/v2ExportContactsGet) for output column details.\n","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_contacts"]},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"filters":{"type":"object","properties":{"search":{"type":"string","description":"A freetext search term."}},"additionalProperties":true}}}}}},"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/export/feedback":{"get":{"summary":"Export feedback","operationId":"v2ExportFeedbackGet","description":"Exports user feedback data as CSV.","tags":["Export"],"x-permissions":{"hasAny":["can_export_all","can_export_feedback"]},"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Export feedback","operationId":"v2ExportFeedbackPost","deprecated":true,"description":"Use [GET /api/v2/export/feedback](#/Export/v2ExportFeedbackGet) instead. Exports user feedback data as CSV.\n","tags":["Export"],"x-permissions":{"isOnline":true,"hasAny":["can_export_all","can_export_feedback"]},"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"$ref":"#/components/responses/CsvExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/export/user-devices":{"get":{"summary":"Export user device information","operationId":"v2ExportUserDevicesGet","description":"This endpoint is deprecated as it can negatively impact server performance. Deployments should avoid using\nthis endpoint or use it only when end users will not be impacted. An improved endpoint is\n[being planned](https://github.com/medic/cht-core/issues/10298) for a later date.\n\nReturns a JSON array of CHT-related software versions and device information for each user device.\nThis information is derived from the latest telemetry entry for each user device.\n\nIf a particular user has used multiple devices, an entry will be included for each device. Reference the\ndate value to determine which devices have been recently used. If multiple users used the same physical\ndevice (e.g. they were logged into the same phone at different times), an entry will be included for each\nuser.\n","tags":["Export"],"deprecated":true,"x-since":"4.7.0","x-permissions":{"hasAny":["can_export_all","can_export_devices_details"]},"responses":{"200":{"$ref":"#/components/responses/UserDeviceExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Export user device information","operationId":"v2ExportUserDevicesPost","deprecated":true,"description":"Use [GET /api/v2/export/user-devices](#/Export/v2ExportUserDevicesGet) instead. Returns a JSON array of CHT-related software versions and device information for each user device. This endpoint may negatively impact server performance.\n","tags":["Export"],"x-since":"4.7.0","x-permissions":{"hasAny":["can_export_all","can_export_devices_details"]},"responses":{"200":{"$ref":"#/components/responses/UserDeviceExport"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/forms":{"get":{"summary":"List installed forms","operationId":"v1FormsGet","description":"Returns a list of currently installed forms. By default returns a JSON array of form filenames. If the `X-OpenRosa-Version` header is set to `1.0`, returns an OpenRosa `xformsList` compatible XML response instead.\n","tags":["Config"],"parameters":[{"in":"header","name":"X-OpenRosa-Version","schema":{"enum":["1.0"]},"description":"If set to \"1.0\", returns XML formatted forms list compatible with the [OpenRosa FormListAPI](https://bitbucket.org/javarosa/javarosa/wiki/FormListAPI).\n"}],"responses":{"200":{"description":"List of installed forms","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"example":["anc_visit.xml","anc_registration.xml"]}},"text/xml":{"schema":{"type":"object","xml":{"name":"xforms","namespace":"http://openrosa.org/xforms/xformsList"},"description":"OpenRosa xformsList compatible XML.","properties":{"xform":{"type":"array","xml":{"wrapped":false},"items":{"type":"object","xml":{"name":"xform"},"properties":{"name":{"type":"string","example":"Visit"},"formID":{"type":"string","example":"ANCVisit"},"hash":{"type":"string","example":"md5:1f0f096602ed794a264ab67224608cf4"},"downloadUrl":{"type":"string","example":"http://medic.local/api/v1/forms/anc_visit.xml"}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/forms/{form}":{"get":{"summary":"Get a form definition","operationId":"v1FormsFormGet","description":"Returns the form definition for a given form ID and format. The form parameter should include the format extension (e.g. `pregnancyregistration.xml`). Currently only `xml` format is supported.\n","tags":["Config"],"parameters":[{"in":"path","name":"form","required":true,"schema":{"type":"string"},"description":"Form identifier with format extension (e.g. `pregnancyregistration.xml`)."}],"responses":{"200":{"description":"The form definition","content":{"text/xml":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/forms/validate":{"post":{"summary":"Validate an XForm","operationId":"v1FormsValidatePost","description":"Validates the XForm XML passed in the request body.\n","tags":["Config"],"x-since":"3.12.0","x-permissions":{"hasAll":["can_configure"]},"requestBody":{"required":true,"content":{"application/xml":{"schema":{"type":"string","description":"The XForm XML to validate."}}}},"responses":{"200":{"description":"Form validation passed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"description":"Form validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Description of the validation error."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/hydrate":{"get":{"summary":"Hydrate documents by id (GET)","operationId":"v1HydrateGet","description":"Accepts a JSON array of document uuids and returns fully hydrated documents, in the same order in which they were requested. When documents are not found, an entry with the missing uuid and an error is added instead.\n","tags":["Bulk"],"parameters":[{"in":"query","name":"doc_ids","required":true,"description":"A JSON-encoded array of document uuids.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}},"example":["id1","id2","id3"]}}}],"responses":{"200":{"description":"Hydrated documents","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HydrationResult"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Hydrate documents by id (POST)","operationId":"v1HydratePost","description":"Accepts a JSON array of document uuids and returns fully hydrated documents, in the same order in which they were requested. When documents are not found, an entry with the missing uuid and an error is added instead.\n","tags":["Bulk"],"x-permissions":{"isOnline":true},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["doc_ids"],"properties":{"doc_ids":{"type":"array","description":"A JSON array of document uuids.","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Hydrated documents","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HydrationResult"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/impact":{"get":{"summary":"Get impact metrics","operationId":"v1ImpactGet","description":"Returns aggregated impact metrics including user, contact, and report counts.","tags":["Monitoring"],"x-since":"5.0.0","responses":{"200":{"description":"The impact metrics","content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"object","properties":{"count":{"type":"number","description":"Total number of users."}}},"contacts":{"type":"object","properties":{"count":{"type":"number","description":"Total number of contacts."},"by_type":{"type":"array","description":"Contact counts broken down by contact type.","items":{"type":"object","properties":{"type":{"type":"string","description":"Name of the contact type."},"count":{"type":"number","description":"Total number of contacts with the type."}}}}}},"reports":{"type":"object","properties":{"count":{"type":"number","description":"Total number of reports."},"by_form":{"type":"array","description":"Report counts broken down by form.","items":{"type":"object","properties":{"form":{"type":"string","description":"Name of the form."},"count":{"type":"number","description":"Total number of reports with the form."}}}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/monitoring":{"get":{"summary":"Get monitoring metrics","operationId":"v1MonitoringGet","deprecated":true,"description":"Use [GET /api/v2/monitoring](#/Monitoring/v2MonitoringGet) instead.\nReturns a range of metrics about the instance for automated monitoring, allowing tracking of trends over\ntime and alerting about potential issues. No authentication is required.\n\nErrors:\n\n- A metric of `\"\"` (for string values) or `-1` (for numeric values) indicates an error occurred while\n  querying the metric - check the API logs for details.\n- If no response or an error response is received the instance is unreachable. Thus, this API can be used\n  as an uptime monitoring endpoint.\n","tags":["Monitoring"],"parameters":[{"in":"query","name":"connected_user_interval","schema":{"type":"number","default":7},"description":"The number of days to use when counting connected users"}],"responses":{"200":{"description":"Monitoring metrics","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/MonitoringVersion"},"couchdb":{"$ref":"#/components/schemas/MonitoringCouchDb"},"date":{"$ref":"#/components/schemas/MonitoringDate"},"sentinel":{"$ref":"#/components/schemas/MonitoringSentinel"},"messaging":{"type":"object","properties":{"outgoing":{"type":"object","properties":{"state":{"type":"object","properties":{"due":{"type":"number","description":"The number of messages due to be sent."},"scheduled":{"type":"number","description":"The number of messages scheduled to be sent in the future."},"muted":{"type":"number","description":"The number of messages that are muted and therefore will not be sent.\n"},"delivered":{"type":"number","description":"The number of messages that have been delivered or sent. As of 3.12.x.\n"},"failed":{"type":"number","description":"The number of messages that have failed to be delivered. As of 3.12.x."}}}}}}},"outbound_push":{"$ref":"#/components/schemas/MonitoringOutboundPush"},"feedback":{"$ref":"#/components/schemas/MonitoringFeedback"},"conflict":{"$ref":"#/components/schemas/MonitoringConflict"},"replication_limit":{"$ref":"#/components/schemas/MonitoringReplicationLimit"},"connected_users":{"$ref":"#/components/schemas/MonitoringConnectedUsers"}}}}}}}}},"/api/v2/monitoring":{"get":{"summary":"Get monitoring metrics","operationId":"v2MonitoringGet","description":"Returns a range of metrics about the instance for automated monitoring, allowing tracking of trends over\ntime and alerting about potential issues. No authentication is required.\n\nErrors:\n\n- A metric of `\"\"` (for string values) or `-1` (for numeric values) indicates an error occurred while\n  querying the metric - check the API logs for details.\n- If no response or an error response is received the instance is unreachable. Thus, this API can be used\n  as an uptime monitoring endpoint.\n","tags":["Monitoring"],"x-since":"3.12.0","parameters":[{"in":"query","name":"connected_user_interval","schema":{"type":"number","default":7},"description":"The number of days to use when counting connected users"}],"responses":{"200":{"description":"Monitoring metrics","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/MonitoringVersion"},"couchdb":{"$ref":"#/components/schemas/MonitoringCouchDb"},"date":{"$ref":"#/components/schemas/MonitoringDate"},"sentinel":{"$ref":"#/components/schemas/MonitoringSentinel"},"messaging":{"type":"object","properties":{"outgoing":{"type":"object","properties":{"total":{"type":"object","properties":{"due":{"type":"number","description":"The number of messages due to be sent."},"scheduled":{"type":"number","description":"The number of messages scheduled to be sent in the future."},"muted":{"type":"number","description":"The number of messages that are muted and therefore will not be sent.\n"},"delivered":{"type":"number","description":"The number of messages that have been delivered or sent."},"failed":{"type":"number","description":"The number of messages that have failed to be delivered."}}},"seven_days":{"type":"object","properties":{"due":{"type":"number","description":"The number of messages due to be sent in the last seven days."},"scheduled":{"type":"number","description":"The number of messages that were scheduled to be sent in the last seven days.\n"},"muted":{"type":"number","description":"The number of messages that were due in the last seven days and are muted.\n"},"delivered":{"type":"number","description":"The number of messages that were due in the last seven days and have been delivered or sent.\n"},"failed":{"type":"number","description":"The number of messages that were due in the last seven days and have failed to be delivered.\n"}}},"last_hundred":{"type":"object","properties":{"pending":{"type":"object","description":"Counts within last 100 messages that have received status updates, and are one of the \"pending\" group statuses.\n","properties":{"pending":{"type":"number","description":"Number of messages that are pending."},"forwarded-to-gateway":{"type":"number","description":"Number of messages that are forwarded-to-gateway."},"received-by-gateway":{"type":"number","description":"Number of messages that are received-by-gateway."},"forwarded-by-gateway":{"type":"number","description":"Number of messages that are forwarded-by-gateway."}}},"final":{"type":"object","description":"Counts within last 100 messages that have received status updates, and are in one of the \"final\" group statuses.\n","properties":{"sent":{"type":"number","description":"Number of messages that are sent."},"delivered":{"type":"number","description":"Number of messages that are delivered."},"failed":{"type":"number","description":"Number of messages that are failed."},"denied":{"type":"number","description":"Number of messages that are denied."},"cleared":{"type":"number","description":"Number of messages that are cleared."},"muted":{"type":"number","description":"Number of messages that are muted."},"duplicate":{"type":"number","description":"Number of messages that are duplicate."}}},"muted":{"type":"object","description":"Counts within last 100 messages that have received status updates, and are in one of the \"muted\" group statuses.\n","additionalProperties":{"type":"number"}}}}}}}},"outbound_push":{"$ref":"#/components/schemas/MonitoringOutboundPush"},"feedback":{"$ref":"#/components/schemas/MonitoringFeedback"},"conflict":{"$ref":"#/components/schemas/MonitoringConflict"},"replication_limit":{"$ref":"#/components/schemas/MonitoringReplicationLimit"},"connected_users":{"$ref":"#/components/schemas/MonitoringConnectedUsers"}}}}}}}}},"/api/v1/person/{id}":{"get":{"summary":"Get a person by id","operationId":"v1PersonIdGet","description":"Returns a person contact record. Optionally includes the full parent place lineage.","tags":["Person"],"x-since":"4.9.0","x-permissions":{"hasAll":["can_view_contacts"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the person to retrieve"},{"$ref":"#/components/parameters/withLineage"}],"responses":{"200":{"description":"The person record","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Person"},{"$ref":"#/components/schemas/v1.PersonWithLineage"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"summary":"Update a person","operationId":"v1PersonIdPut","description":"Updates an existing person contact record. Fields omitted on the request will be removed from the record. Any included lineage data will be minified on the stored record.\n","tags":["Person"],"x-since":"5.2.0","x-permissions":{"hasAny":["can_update_people","can_edit"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the person to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.UpdatePersonInput"}}}},"responses":{"200":{"description":"The updated person record","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Person"},{"$ref":"#/components/schemas/v1.PersonWithLineage"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/person":{"get":{"summary":"Get persons","operationId":"v1PersonGet","description":"Returns a paginated array of persons for the given contact type. Use the `cursor` returned in each response to retrieve subsequent pages. See also [Get Person by id](#/Person/v1PersonIdGet) for retrieving a single person.\n","tags":["Person"],"x-since":"4.11.0","x-permissions":{"hasAll":["can_view_contacts"]},"parameters":[{"in":"query","name":"type","required":true,"schema":{"type":"string"},"description":"The contact_type id for the type of persons to fetch"},{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/limitEntity"}],"responses":{"200":{"description":"A page of person records","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","description":"The results for this page","items":{"$ref":"#/components/schemas/v1.Person"}},"cursor":{"$ref":"#/components/schemas/PageCursor"}},"required":["data","cursor"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Create a new person","operationId":"v1PersonPost","description":"Creates a new person record.","tags":["Person"],"x-since":"5.2.0","x-permissions":{"hasAny":["can_create_people","can_edit"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.PersonInput"}}}},"responses":{"200":{"description":"The created person record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.Person"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/place/{id}":{"get":{"summary":"Get a place by id","operationId":"v1PlaceIdGet","description":"Returns a place contact record. Optionally includes the full parent place lineage.","tags":["Place"],"x-since":"4.10.0","x-permissions":{"hasAll":["can_view_contacts"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the place to retrieve"},{"$ref":"#/components/parameters/withLineage"}],"responses":{"200":{"description":"The place record","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Place"},{"$ref":"#/components/schemas/v1.PlaceWithLineage"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"summary":"Update a place","operationId":"v1PlaceIdPut","description":"Updates an existing place contact record.  Fields omitted on the request will be removed from the record. Any included lineage data will be minified on the stored record.\n","tags":["Place"],"x-since":"5.2.0","x-permissions":{"hasAny":["can_update_places","can_edit"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the place to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Place"},{"$ref":"#/components/schemas/v1.PlaceWithLineage"}],"properties":{"contact":{"oneOf":[{"type":"string","description":"UUID of the contact"},{"$ref":"#/components/schemas/NormalizedParent"}]}}}}}},"responses":{"200":{"description":"The updated place record","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Place"},{"$ref":"#/components/schemas/v1.PlaceWithLineage"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/place":{"get":{"summary":"Get places","operationId":"v1PlaceGet","description":"Returns a paginated array of places for the given contact type. Use the `cursor` returned in each response to retrieve subsequent pages. See also [Get Place by id](#/Place/v1PlaceIdGet) for retrieving a single place.\n","tags":["Place"],"x-since":"4.12.0","x-permissions":{"hasAll":["can_view_contacts"]},"parameters":[{"in":"query","name":"type","required":true,"schema":{"type":"string"},"description":"The contact_type id for the type of places to fetch"},{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/limitEntity"}],"responses":{"200":{"description":"A page of place records","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","description":"The results for this page","items":{"$ref":"#/components/schemas/v1.Place"}},"cursor":{"$ref":"#/components/schemas/PageCursor"}},"required":["data","cursor"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Create a new place","operationId":"v1PlacePost","description":"Creates a new place record.","tags":["Place"],"x-since":"5.2.0","x-permissions":{"hasAny":["can_create_places","can_edit"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.PlaceInput"}}}},"responses":{"200":{"description":"The created place record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.Place"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/sms/radpidpro/incoming-messages":{"post":{"summary":"Receive incoming SMS from RapidPro","operationId":"v1SmsRadpidproIncomingMessagesPost","deprecated":true,"description":"Use [POST /api/v2/sms/rapidpro/incoming-messages](#/SMS/v2SmsRapidProIncomingMessagesPost) instead. Webhook endpoint for receiving incoming SMS messages from the RapidPro gateway. Authenticated via an `Authorization: Token <key>` header. See the [documentation](/building/messaging/gateways/rapidpro/) for more details.\n","tags":["SMS"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The RapidPro message id."},"from":{"type":"string","description":"The sender's phone number."},"content":{"type":"string","description":"The message content."}},"required":["id","from","content"]}}}},"responses":{"200":{"description":"Message processing results","content":{"application/json":{"schema":{"type":"object","properties":{"saved":{"type":"number","description":"The number of messages saved."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/sms/rapidpro/incoming-messages":{"post":{"summary":"Receive incoming SMS from RapidPro","operationId":"v2SmsRapidProIncomingMessagesPost","description":"Webhook endpoint for receiving incoming SMS messages from the RapidPro gateway. Authenticated via an `Authorization: Token <key>` header. See the [documentation](/building/messaging/gateways/rapidpro/) for more details.\n","tags":["SMS"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The RapidPro message id."},"from":{"type":"string","description":"The sender's phone number."},"content":{"type":"string","description":"The message content."}},"required":["id","from","content"]}}}},"responses":{"200":{"description":"Message processing results","content":{"application/json":{"schema":{"type":"object","properties":{"saved":{"type":"number","description":"The number of messages saved."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/records":{"post":{"summary":"Create a record","operationId":"v1RecordsPost","deprecated":true,"description":"Use [POST /api/v2/records](#/SMS/v2RecordsPost) instead. Creates a new record based on a configured form. Accepts form-encoded or JSON data.\n","tags":["SMS"],"x-permissions":{"hasAll":["can_create_records"]},"parameters":[{"in":"query","name":"locale","schema":{"type":"string"},"description":"Optional locale string (e.g. `fr`)."}],"requestBody":{"$ref":"#/components/requestBodies/RecordInput"},"responses":{"200":{"description":"Record created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSuccess"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/records":{"post":{"summary":"Create a record","operationId":"v2RecordsPost","description":"Creates a new record based on a configured [JSON form](/building/reference/app-settings/forms/). Accepts either form-encoded or JSON data.\n","tags":["SMS"],"x-permissions":{"hasAll":["can_create_records"]},"requestBody":{"$ref":"#/components/requestBodies/RecordInput"},"responses":{"200":{"description":"Record created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordSuccess"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/users-doc-count":{"get":{"summary":"Get user document replication counts","operationId":"v1UsersDocCountGet","description":"Returns the quantity of documents replicated by each user. Optionally filter by username. Only allowed for database admins.\n","tags":["User"],"x-since":"3.11.0","parameters":[{"in":"query","name":"user","schema":{"type":"string"},"description":"Filter by username. If not provided, returns all users."}],"responses":{"200":{"description":"User replication document counts","content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"number","description":"The configured replication limit."},"users":{"description":"A single user replication log object (when filtered) or an object keyed by username.\n","type":"object","properties":{"_id":{"type":"string"},"_rev":{"type":"string"},"user":{"type":"string","description":"The username."},"date":{"type":"number","description":"Timestamp of the replication count entry."},"count":{"type":"number","description":"Number of documents replicated by the user."}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/report/{id}":{"get":{"summary":"Get a report by id","operationId":"v1ReportIdGet","description":"Returns a report record. Optionally includes the full contact, patient, and/or place lineage.\n","tags":["Report"],"x-since":"4.18.0","x-permissions":{"hasAll":["can_view_reports"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the report to retrieve"},{"$ref":"#/components/parameters/withLineage"}],"responses":{"200":{"description":"The report record","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Report"},{"$ref":"#/components/schemas/v1.ReportWithLineage"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"summary":"Update a report","operationId":"v1ReportIdPut","description":"Updates an existing report.  Fields omitted on the request will be removed from the record. Any included lineage data will be minified on the stored record.\n","tags":["Report"],"x-since":"5.2.0","x-permissions":{"hasAny":["can_update_reports","can_edit"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the report to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Report"},{"$ref":"#/components/schemas/v1.ReportWithLineage"}],"properties":{"contact":{"oneOf":[{"type":"string","description":"UUID of the contact"},{"$ref":"#/components/schemas/NormalizedParent"}]}}}}}},"responses":{"200":{"description":"The updated report record","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/v1.Report"},{"$ref":"#/components/schemas/v1.ReportWithLineage"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/report/uuid":{"get":{"summary":"Get report UUIDs","operationId":"v1ReportUuidGet","description":"Returns a paginated array of report identifiers matching the given freetext search term.\n","tags":["Report"],"x-since":"4.18.0","x-permissions":{"hasAll":["can_view_reports"]},"parameters":[{"in":"query","name":"freetext","required":true,"schema":{"type":"string","minLength":3},"description":"A search term for filtering reports. Must be at least 3 characters and not contain whitespace.\n"},{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/limitId"}],"responses":{"200":{"description":"A page of report UUIDs","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","description":"The results for this page","items":{"type":"string"}},"cursor":{"$ref":"#/components/schemas/PageCursor"}},"required":["data","cursor"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/report":{"post":{"summary":"Create a new report","operationId":"v1ReportPost","description":"Creates a new report.","tags":["Report"],"x-since":"5.2.0","x-permissions":{"hasAny":["can_create_records","can_edit"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.ReportInput"}}}},"responses":{"200":{"description":"The created report record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.Report"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/settings":{"get":{"summary":"Get app settings","operationId":"v1SettingsGet","description":"Returns the app settings in JSON format.","tags":["Config"],"responses":{"200":{"description":"The app settings","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"put":{"summary":"Update app settings","operationId":"v1SettingsPut","description":"Update the app settings. By default, the provided properties are merged with existing settings. Use query parameters to control replacement behavior.\n","tags":["Config"],"x-permissions":{"hasAll":["can_edit","can_configure"]},"parameters":[{"in":"query","name":"replace","schema":{"enum":["true","false"],"default":"false"},"description":"Whether to replace existing settings for the given properties or to merge."},{"in":"query","name":"overwrite","schema":{"enum":["true","false"],"default":"false"},"description":"Whether to replace the entire settings document with the input document. If both `replace` and `overwrite` are set, `overwrite` takes precedence.\n"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"The settings properties to update."}}}},"responses":{"200":{"description":"Settings update result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"updated":{"type":"boolean","description":"Whether the settings document was updated."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/settings/deprecated-transitions":{"get":{"summary":"Get deprecated transitions","operationId":"v1SettingsDeprecatedTransitionsGet","description":"Returns a list of deprecated transitions configured in the app settings.","tags":["Config"],"responses":{"200":{"description":"Deprecated transitions","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/sms":{"get":{"summary":"Check SMS gateway connectivity","operationId":"smsGet","description":"Returns a simple response to verify that the cht-gateway SMS endpoint is available. See the [cht-gateway documentation](https://github.com/medic/cht-gateway) for more details.\n","tags":["SMS"],"x-permissions":{"hasAll":["can_access_gateway_api"]},"responses":{"200":{"description":"Gateway endpoint is available","content":{"application/json":{"schema":{"type":"object","properties":{"medic-gateway":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Exchange SMS messages with cht-gateway","operationId":"smsPost","description":"Processes incoming messages and delivery status updates from cht-gateway, and returns outgoing messages that are ready to be sent. See the [cht-gateway documentation](https://github.com/medic/cht-gateway) for more details.\n","tags":["SMS"],"x-permissions":{"hasAll":["can_access_gateway_api"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","description":"Incoming messages to process.","items":{"type":"object","properties":{"id":{"type":"string","description":"The message id."},"from":{"type":"string","description":"The sender's phone number."},"content":{"type":"string","description":"The message content."}},"required":["id","from","content"]}},"updates":{"type":"array","description":"Delivery status updates for previously sent messages.","items":{"type":"object","properties":{"id":{"type":"string","description":"The message id."},"status":{"enum":["UNSENT","PENDING","SENT","DELIVERED","FAILED"],"description":"The delivery status from the gateway."},"reason":{"type":"string","description":"The reason for failure, if applicable."}},"required":["id","status"]}}},"required":["messages"]}}}},"responses":{"200":{"description":"Outgoing messages ready to be sent","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","description":"Outgoing messages for the gateway to send.","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/target/{id}":{"get":{"summary":"Get a target by id","operationId":"v1TargetIdGet","description":"Returns a target record.","tags":["Target"],"x-since":"5.1.0","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"},"description":"The id of the target to retrieve"}],"responses":{"200":{"description":"The target record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/v1.Target"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/target":{"get":{"summary":"Get targets","operationId":"v1TargetGet","description":"Returns a paginated array of targets for the given contact and reporting period. Use the `cursor` returned in each response to retrieve subsequent pages. See also [Get Target by id](#/Target/v1TargetIdGet) for retrieving a single target.\n","tags":["Target"],"x-since":"5.1.0","parameters":[{"in":"query","name":"contact_id","schema":{"type":"string"},"description":"A single contact id to filter targets by. Either `contact_id` or `contact_ids` must be provided.\n"},{"in":"query","name":"contact_ids","schema":{"type":"string"},"description":"Comma-separated contact ids to filter targets by. Either `contact_id` or `contact_ids` must be provided.\n"},{"in":"query","name":"reporting_period","required":true,"schema":{"type":"string"},"description":"The reporting period to filter targets by (e.g. '2025-09')"},{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/limitEntity"}],"responses":{"200":{"description":"A page of target records","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","description":"The results for this page","items":{"$ref":"#/components/schemas/v1.Target"}},"cursor":{"$ref":"#/components/schemas/PageCursor"}},"required":["data","cursor"]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/upgrade/can-upgrade":{"get":{"summary":"Check if an upgrade can be performed","operationId":"v2UpgradeCanUpgradeGet","description":"Returns whether the instance is in a state where an upgrade can be performed.","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"responses":{"200":{"description":"Whether an upgrade can be performed","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","description":"Whether an upgrade can be performed."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/upgrade":{"post":{"summary":"Upgrade to a version","operationId":"v1UpgradePost","deprecated":true,"description":"Use [POST /api/v2/upgrade](#/Upgrade/v2UpgradePost) instead. Performs a complete upgrade to the provided version. This is equivalent to calling `/api/v1/upgrade/stage` and then `/api/v1/upgrade/complete` once staging has finished. This is asynchronous. Progress can be followed by watching the `horti-upgrade` document. Calling this endpoint will eventually cause api and sentinel to restart.\n","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequestBody"}}}},"responses":{"200":{"description":"Upgrade initiated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/upgrade":{"post":{"summary":"Upgrade to a version","operationId":"v2UpgradePost","description":"Performs a complete upgrade to the provided version. This is equivalent to calling\n`/api/v2/upgrade/stage` and then `/api/v2/upgrade/complete` once staging has finished.\nThis is asynchronous. Progress can be followed via [GET /api/v2/upgrade](#/Upgrade/v2UpgradeGet).\n\nCalling this endpoint will eventually cause api and sentinel to restart.\n\nIt is expected that the caller ensures forwards or backwards compatibility is maintained between deployed\nversions. This endpoint does not stop you from “upgrading” to an earlier version, or a branch that is\nincompatible with your current state.\n","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequestBody"}}}},"responses":{"200":{"description":"Upgrade initiated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"get":{"summary":"Get upgrade status","operationId":"v2UpgradeGet","description":"Returns the current upgrade status, indexer progress, and builds server URL.","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"responses":{"200":{"description":"The current upgrade status","content":{"application/json":{"schema":{"type":"object","properties":{"upgradeDoc":{"description":"The current upgrade document, or null if no upgrade is in progress."},"indexers":{"description":"Current indexer progress information."},"buildsUrl":{"type":"string","description":"The URL of the builds server."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"delete":{"summary":"Abort an upgrade","operationId":"v2UpgradeDelete","description":"Aborts an in-progress upgrade.","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"responses":{"200":{"description":"Upgrade aborted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/upgrade/stage":{"post":{"summary":"Stage an upgrade","operationId":"v1UpgradeStagePost","deprecated":true,"description":"Use [POST /api/v2/upgrade/stage](#/Upgrade/v2UpgradeStagePost) instead. Stages an upgrade to the provided version. Does as much of the upgrade as possible without actually swapping versions over and restarting. An upgrade has been staged when the `horti-upgrade` document has `\"action\": \"stage\"` and `\"staging_complete\": true`.\n","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequestBody"}}}},"responses":{"200":{"description":"Staging initiated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/upgrade/stage":{"post":{"summary":"Stage an upgrade","operationId":"v2UpgradeStagePost","description":"Stages an upgrade to the provided version. Does as much of the upgrade as possible without actually swapping versions over and restarting.\n","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequestBody"}}}},"responses":{"200":{"description":"Staging initiated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/upgrade/complete":{"post":{"summary":"Complete a staged upgrade","operationId":"v1UpgradeCompletePost","deprecated":true,"description":"Use [POST /api/v2/upgrade/complete](#/Upgrade/v2UpgradeCompletePost) instead. Completes a staged upgrade. Returns a 404 if there is no upgrade in the staged position.\n","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"responses":{"200":{"description":"Upgrade completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v2/upgrade/complete":{"post":{"summary":"Complete a staged upgrade","operationId":"v2UpgradeCompletePost","description":"Completes a staged upgrade. Returns a 404 if there is no upgrade in the staged position.\n","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"responses":{"200":{"description":"Upgrade completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v2/upgrade/service-worker":{"post":{"summary":"Update the service worker","operationId":"v2UpgradeServiceWorkerPost","description":"Triggers an update of the service worker cache.","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"responses":{"200":{"description":"Service worker updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/upgrade/compare":{"post":{"summary":"Compare build versions","operationId":"v2UpgradeComparePost","description":"Compares the provided build version against the currently deployed version, returning differences in design documents.\n","tags":["Upgrade"],"x-permissions":{"hasAll":["can_upgrade"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequestBody"}}}},"responses":{"200":{"description":"Comparison results","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/users":{"get":{"summary":"List users","operationId":"v1UsersGet","deprecated":true,"description":"Use [GET /api/v2/users](#/User/v2UsersGet) instead. Returns a list of users and their profile data.\n","tags":["User"],"x-permissions":{"hasAll":["can_view_users"]},"responses":{"200":{"description":"A list of users","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Create users","operationId":"v1UsersPost","deprecated":true,"description":"Use [POST /api/v3/users](#/User/v3UsersPost) to create a single user or\n[POST /api/v2/users](#/User/v2UsersPost) to create multiple users.\nCreate new users with a place and a contact. Accepts a single user object or an array of user objects\n(since CHT `3.15.0`). Users are created in parallel and the creation is not aborted even if one of the\nusers fails to be created.\n\nPassing a single user in the request’s body will return a single object whereas passing an array of users\nwill return an array of objects.\n","tags":["User"],"x-permissions":{"hasAll":["can_edit","can_create_users"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/UserInput"},{"type":"array","items":{"$ref":"#/components/schemas/UserInput"}}]}}}},"responses":{"200":{"description":"User creation results","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/UserCreateResult"},{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/UserCreateResult"},{"$ref":"#/components/schemas/InvalidUserInputError"}]}}]}}}},"400":{"description":"Invalid user data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidUserInputError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/users/{username}":{"post":{"summary":"Update a user","operationId":"v1UsersUsernamePost","deprecated":true,"description":"Use [POST /api/v3/users/{username}](#/User/v3UsersUsernamePost) instead. Update property values on a user account. Users with `can_edit` and `can_update_users` permissions can update any user. Users can update themselves without these permissions, but cannot modify `type`, `roles`, `contact`, or `place`. Password changes require Basic Auth (either the header or in the URL). This is to ensure the password is known at time of request, and no one is hijacking a cookie.\n","tags":["User"],"x-permissions":{"hasAll":["can_edit","can_update_users"]},"parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"},"description":"The username of the user to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"User properties to update."}}}},"responses":{"200":{"description":"User updated","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}},"user-settings":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}}}}}}},"400":{"description":"Invalid user data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidUserInputError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"delete":{"summary":"Delete a user","operationId":"v1UsersUsernameDelete","description":"Delete a user. Does not affect the person or place associated with the user.","tags":["User"],"x-permissions":{"hasAll":["can_edit","can_delete_users"]},"parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"},"description":"The username of the user to delete."}],"responses":{"200":{"description":"User deleted","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/users-info":{"get":{"summary":"Get user replication info","operationId":"v1UsersInfoGet","description":"Returns the total number of documents an offline user would replicate (`total_docs`), the number of\ndocs excluding tasks the user would replicate (`warn_docs`), and a warning flag (`warn`) if the count\nexceeds the recommended limit (`10,000`).\n\nOffline users can get their own doc count. Online users with `can_update_users` permission\ncan query for any user by providing `role` and `facility_id` query parameters. (When requested as an\nonline user, the number of tasks are never counted and never returned, so `warn_docs` is always equal to\n`total_docs`.)\n","tags":["User"],"parameters":[{"in":"query","name":"facility_id","schema":{"type":"string"},"description":"Identifier of the user's facility. Required for online users."},{"in":"query","name":"role","schema":{"type":"string"},"description":"User role (must be an offline role). Accepts a string or JSON array. Required for online users.\n"},{"in":"query","name":"contact_id","schema":{"type":"string"},"description":"Identifier of the user's associated contact. Optional for online users."}],"responses":{"200":{"description":"User replication info","content":{"application/json":{"schema":{"type":"object","properties":{"total_docs":{"type":"number","description":"Total number of documents the user would replicate."},"warn_docs":{"type":"number","description":"Number of docs excluding tasks the user would replicate."},"warn":{"type":"boolean","description":"Whether the doc count exceeds the recommended limit."},"limit":{"type":"number","description":"The recommended document limit."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v2/users/{username}":{"get":{"summary":"Get a user by username.","operationId":"v2UsersUsernameGet","description":"Returns a user's profile data. Users with `can_view_users` permission can view any user. Users can also view their own profile.\n","tags":["User"],"x-since":"4.7.0","x-permissions":{"hasAll":["can_view_users"]},"parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"},"description":"The username to retrieve."}],"responses":{"200":{"description":"The user profile","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"id":"org.couchdb.user:demo","rev":"14-8758c8493edcc6dac50366173fc3e24a","type":"district-manager","fullname":"Example User","username":"demo","oidc_username":"demo@email.com","place":{"_id":"eeb17d6d-5dde-c2c0-62c4a1a0ca17d38b","type":"district_hospital","name":"Sample District","contact":{"_id":"eeb17d6d-5dde-c2c0-62c4a1a0ca17fd17","type":"person","name":"Paul","phone":"+2868917046"}},"contact":{"_id":"eeb17d6d-5dde-c2c0-62c4a1a0ca17fd17","type":"person","name":"Paul","phone":"+2868917046"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v2/users":{"get":{"summary":"List users","operationId":"v2UsersGet","description":"Returns a list of users and their profile data including roles.","tags":["User"],"x-since":"4.1.0","x-permissions":{"hasAll":["can_view_users"]},"parameters":[{"in":"query","name":"facility_id","schema":{"type":"string"},"description":"Filter by facility identifier. Added in `4.7.0`."},{"in":"query","name":"contact_id","schema":{"type":"string"},"description":"Filter by associated contact identifier. Added in `4.7.0`."}],"responses":{"200":{"description":"A list of users","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Create users - bulk import (JSON or CSV)","operationId":"v2UsersPost","description":"Create new users with a place and a contact. Accepts either a JSON array of user objects or a CSV file\nwhere each row represents a user. Columns with an `:excluded` suffix will be ignored. A log entry is\ncreated for each bulk import in the `medic-logs` database.\n\n### Example\n\nA spreadsheet compatible with the default configuration of the CHT is available.\n[Click here](https://docs.google.com/spreadsheets/d/1yUenFP-5deQ0I9c-OYDTpbKYrkl3juv9djXoLLPoQ7Y/copy) to\nmake a copy of the spreadsheet in Google Sheets. [A guide](/building/training/users-bulk-load) on how to\nimport users with this spreadsheet from within the Admin Console (without manually calling this endpoint)\nis available.\n\n### Logging\n\nA log entry is created with each bulk import that contains the import status for each user and the import\nprogress status that gets updated throughout the import and finalized upon completion. These entries are\nsaved in the [`medic-logs`](/technical-overview/data#medic-logs) database and you can access them by\nquerying documents with a key that starts with `bulk-user-upload-`.\n","tags":["User"],"x-since":"3.16.0","x-permissions":{"hasAll":["can_edit","can_create_users"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/UserInput"},{"type":"array","items":{"$ref":"#/components/schemas/UserInput"}}]}},"text/csv":{"schema":{"type":"string","description":"CSV with headers matching user properties. Columns with `:excluded` suffix are ignored.\n"}}}},"responses":{"200":{"description":"User creation results","content":{"application/json":{"schema":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/UserCreateResult"},{"$ref":"#/components/schemas/InvalidUserInputError"}]}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v3/users":{"post":{"summary":"Create a user","operationId":"v3UsersPost","description":"Creates a user that can be associated with multiple facilities.","tags":["User"],"x-permissions":{"hasAll":["can_edit","can_create_users"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/UserInput"},{"type":"object","properties":{"place":{"description":"Place identifier(s). Required if roles contain an offline role. Can be a single place id or an array of place ids for multi-facility users. Setting multiple places requires the `can_have_multiple_places` permission.\n","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}}]}}}},"responses":{"200":{"description":"User creation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateResult"}}}},"400":{"description":"Invalid user data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidUserInputError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v3/users/{username}":{"post":{"summary":"Update a user","operationId":"v3UsersUsernamePost","description":"Update property values on a user account. Users with `can_edit` and `can_update_users` permissions can update any user. Users can update themselves without these permissions, but cannot modify `type`, `roles`, `contact`, or `place`. Password changes require Basic Auth (either the header or in the URL). This is to ensure the password is known at time of request, and no one is hijacking a cookie.\n","tags":["User"],"x-permissions":{"hasAll":["can_edit","can_update_users"]},"parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"},"description":"The username of the user to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"User properties to update."}}}},"responses":{"200":{"description":"User updated","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}},"user-settings":{"type":"object","properties":{"id":{"type":"string"},"rev":{"type":"string"}}}}}}}},"400":{"description":"Invalid user data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidUserInputError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}}},"tags":[{"name":"Bulk","description":"Bulk document operations"},{"name":"Config","description":"Operations for app configuration"},{"name":"Contact","description":"Operations for contacts (persons and places)"},{"name":"Export","description":"Export data in various formats"},{"name":"Monitoring","description":"Operations for monitoring the CHT instance"},{"name":"Person","description":"Operations for person contacts"},{"name":"Place","description":"Operations for place contacts"},{"name":"Report","description":"Operations for reports"},{"name":"SMS","description":"Operations for SMS messaging integrations"},{"name":"Target","description":"Operations for targets"},{"name":"Upgrade","description":"Operations for upgrading the CHT instance"},{"name":"User","description":"Operations for user management"}]}