Create or update a profile
Write a practitioner's or clinic's public profile, with an optional image, as multipart form data.
POST /v1/public-profiles/add-updateOne route for both create and update — it is keyed by profileId and
profileType, so writing the same pair twice edits rather than duplicates.
It takes multipart/form-data, not JSON, because the profile image is
uploaded in the same request.
Body (form fields)
| Field | Type | Required | Description |
|---|---|---|---|
profileId | number | Yes | The doctor's user id, or the workspace id. |
profileType | string | Yes | USER or WORKSPACE. |
workspaceId | number | Yes | Your workspace. |
isDraft | boolean | No | true keeps it unpublished. A draft is invisible to the patient-facing bundle. |
name | string | No | Display name, including any prefix the clinic uses. |
specialization | string | No | |
qualification | string | No | |
experience | number | No | Years. |
designation | string | No | |
registrationNumber, registrationAuthority | string | No | Council registration. |
gender | string | No | MALE, FEMALE, OTHER. |
profileSummary | string | No | Short blurb. |
professionalSummary, description | string | No | Longer body copy. Rich-text HTML is accepted and returned as stored. |
services, expertise, languages, mode, awards, customServices, serviceOfferingIds | string | No | Repeat the field once per value — this is form data, not JSON, so lists are repeated parts. |
education | string | No | |
videoUrl, treatmentPhilosophy, whatToExpect | string | No | |
slug | string | No | The URL segment for a public page. |
faqs, socialLinks, workHistory, seo | string | No | JSON encoded as a string inside the form field. |
googleRating, googleReviewUrl | string | No | |
clearFields | string | No | Names of fields to blank out. Repeat per field. |
file | file | No | The profile image. |
Only clinical staff get a profile
A profileType: USER write is rejected unless that user is a practitioner in
the workspace — a doctor or allied professional. Receptionists and
administrators cannot have one, so no unused profile rows are ever created.
Try it
/v1/public-profiles/add-updateBody
POST /v1/public-profiles/add-update{
"profileType": "USER"
}https://api.medos.oneUse a dedicated test key, and put your browser's address on its allowlist
A Developer API key authenticates on its own, so it only works from the addresses registered against it — and this page calls from your browser, not your servers. Unless your own public address is on the list you get a 403 naming it, which is the allowlist doing its job. Your browser may also reach us over IPv6 even when your server does not, so the address in the error is often not the one you expected. The key here is kept in memory only and never written to storage, but create a test key for it and deactivate that key when you are done.
Request
curl -sX POST "https://api.medos.one/v1/public-profiles/add-update" \
-H "x-api-key: $MEDOS_API_KEY" \
-F "profileId=4" \
-F "profileType=USER" \
-F "workspaceId=1" \
-F "name=Dr. Meera Rao" \
-F "specialization=Physiotherapy" \
-F "experience=11" \
-F "services=Manual therapy" \
-F "services=Dry needling" \
-F "faqs=[{\"question\":\"Do I need a referral?\",\"answer\":\"No.\"}]" \
-F "isDraft=false" \
-F "file=@meera.jpg"Note services appearing twice — that is how a list is sent. A JSON array in a
single field is stored as one literal string.
Response
201, with the saved profile in the same enriched shape
the read route returns.
Common failures
| Status | Cause |
|---|---|
400 | profileType: USER for a user who is not a practitioner in the workspace. |
400 | A JSON-encoded field (faqs, seo, socialLinks, workHistory) that is not valid JSON. |
403 | The profile belongs to another workspace. |
413 | The image exceeds the upload limit. |
Omitted is not cleared
A field you leave out keeps its stored value. To blank one, name it in
clearFields — sending an empty string is not the same thing.