{"openapi":"3.0.3","info":{"title":"External API","version":"1.0.0","description":"## Introduction\nThis API exposes partner-facing endpoints under `/api/`.\n\n## Authentication and Security\nAll protected endpoints require:\n- `Authorization: Bearer <token>`\n- `x-client-id` (must exist in DB and be active)\n- token `client_id` must match `x-client-id`\n\n## Authentication API\n- `POST /api/auth/token`: accepts `client_id` and `client_secret`, returns\n  `access_token` (30 minutes) and `refresh_token` (30 days). Prior tokens for that client are invalidated.\n- `POST /api/auth/refresh`: accepts `refresh_token`, returns new `access_token` and a new `refresh_token`; the submitted refresh token is revoked (single-use rotation).\n- In the left menu, open `Auth` to view:\n  - `Get Token`\n  - `Get Refresher Token`\n\n## Response Format\nAll API responses use a standard envelope:\n`{ status, code, message, data }`"},"servers":[{"url":"/","description":"Current server"}],"tags":[{"name":"Auth","description":"Authentication APIs: Get Token and Get Refresher Token"},{"name":"Users","description":"Users APIs"},{"name":"Share","description":"Shared reference + verification APIs"}],"x-tagGroups":[{"name":"Auth","tags":["Auth"]},{"name":"Profile","tags":["Users"]},{"name":"Share","tags":["Share"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"clientIdHeader":{"type":"apiKey","in":"header","name":"x-client-id"}},"schemas":{"SuccessEnvelopeBase":{"type":"object","properties":{"status":{"type":"string","example":"success"},"code":{"type":"integer","example":200},"message":{"type":"string","example":"Request successful"}},"required":["status","code","message"]},"ErrorResponse":{"type":"object","properties":{"status":{"type":"string","example":"error"},"code":{"type":"integer","example":401},"message":{"type":"string","example":"Unauthorized"},"trace_id":{"type":"string","nullable":true},"retryable":{"type":"boolean","example":false}},"required":["status","code","message"]},"TokenRequest":{"type":"object","required":["client_id","client_secret"],"properties":{"client_id":{"type":"string","example":"my-client-id"},"client_secret":{"type":"string","example":"my-client-secret"}}},"RefreshTokenRequest":{"type":"object","required":["refresh_token"],"properties":{"refresh_token":{"type":"string"}}},"TokenPayload":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","example":"Bearer"},"expires_in":{"type":"integer","example":1800},"refresh_token":{"type":"string"},"refresh_expires_in":{"type":"integer","example":2592000}},"required":["access_token","token_type","expires_in"]},"TokenIssueResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TokenPayload"}},"required":["data"]}]},"TokenRefreshPayload":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","example":"Bearer"},"expires_in":{"type":"integer","example":1800},"refresh_token":{"type":"string"},"refresh_expires_in":{"type":"integer","example":2592000}},"required":["access_token","token_type","expires_in","refresh_token","refresh_expires_in"]},"TokenRefreshResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TokenRefreshPayload"}},"required":["data"]}]},"UserProfile":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"email":{"type":"string","nullable":true},"professional_email":{"type":"string","nullable":true},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"phone_number":{"type":"string","nullable":true},"national_id":{"type":"string","nullable":true},"profile_image":{"type":"string","nullable":true}}},"UserEducationItem":{"type":"object","additionalProperties":true,"description":"An education row. GET /user/educations returns an array of these.","properties":{"id":{"type":"string","example":"2207169020-00001","description":"Composite id: {userId}-{qualificationId}"},"qualification_id":{"type":"string","nullable":true,"example":"00001","description":"Catalog qualification id — use GET /api/share/qualifications/{degreeId}"},"qualification_name":{"type":"string","nullable":true,"example":"Bachelor's Degree in Computer Science"},"graduation_year":{"type":"integer","nullable":true,"example":2020},"school_id":{"type":"integer","nullable":true,"example":101,"description":"School id — use GET /api/share/schools-by-country/{countryId}"},"school_name":{"type":"string","nullable":true,"example":"University of Rwanda"},"doc_reference_id":{"type":"string","nullable":true,"example":"54321","description":"Document reference id from the file service"},"document_url":{"type":"string","nullable":true,"example":"https://documents.ippis.rw/preview/54321"},"school_country_name":{"type":"string","nullable":true,"example":"Rwanda"},"school_country_id":{"type":"string","nullable":true,"example":"RW"},"degree_name":{"type":"string","nullable":true,"example":"Bachelor"},"degree_id":{"type":"string","nullable":true,"example":"3"}},"example":{"id":"2207169020-00001","qualification_id":"00001","qualification_name":"Bachelor's Degree in Computer Science","graduation_year":2020,"school_id":101,"school_name":"University of Rwanda","doc_reference_id":"54321","document_url":"https://documents.ippis.rw/preview/54321","school_country_name":"Rwanda","school_country_id":"RW","degree_name":"Bachelor","degree_id":"3"}},"UserEducationDetail":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"user_id":{"type":"string","nullable":true},"qualification_id":{"type":"integer","nullable":true},"graduation_year":{"type":"integer","nullable":true},"school_id":{"type":"integer","nullable":true},"doc_reference_id":{"type":"string","nullable":true},"document_url":{"type":"string","nullable":true},"created_on":{"type":"string","nullable":true},"created_by":{"type":"string","nullable":true},"qualification":{"type":"object","additionalProperties":true},"school":{"type":"object","additionalProperties":true}}},"UserLanguageItem":{"type":"object","additionalProperties":true,"description":"A language proficiency row. GET /user/languages returns an array; POST /user/languages returns a single one.","properties":{"id":{"type":"integer","example":12345,"description":"Row id"},"language_id":{"type":"integer","nullable":true,"example":3,"description":"Catalog language id — use GET /api/share/languages to fetch valid ids"},"language_name":{"type":"string","nullable":true,"example":"French","description":"Language display name from catalog"},"reading":{"type":"string","nullable":true,"example":"Excellent","description":"Reading proficiency level (e.g. Basic, Good, Very Good, Excellent)"},"writing":{"type":"string","nullable":true,"example":"Good","description":"Writing proficiency level"},"speaking":{"type":"string","nullable":true,"example":"Excellent","description":"Speaking proficiency level"}},"example":{"id":12345,"language_id":3,"language_name":"French","reading":"Excellent","writing":"Good","speaking":"Excellent"}},"UserRefereeItem":{"type":"object","additionalProperties":true,"description":"A referee row. GET /user/referees returns an array; POST /user/referees returns a single item.","properties":{"id":{"type":"integer","example":456,"description":"Row id"},"referee_first_name":{"type":"string","nullable":true,"example":"John"},"referee_last_name":{"type":"string","nullable":true,"example":"Doe"},"referee_phone_number":{"type":"string","nullable":true,"example":"+250788000000","description":"Must be unique per user (duplicate check on insert)"},"referee_email":{"type":"string","nullable":true,"example":"john.doe@example.com","description":"Must be unique per user (duplicate check on insert)"},"referee_position_name":{"type":"string","nullable":true,"example":"Senior Manager","description":"Referee's job title or position"},"referee_institution_name":{"type":"string","nullable":true,"example":"MINICT","description":"Institution or company where the referee works"}},"example":{"id":456,"referee_first_name":"John","referee_last_name":"Doe","referee_phone_number":"+250788000000","referee_email":"john.doe@example.com","referee_position_name":"Senior Manager","referee_institution_name":"MINICT"}},"UserCertificateItem":{"type":"object","additionalProperties":true,"description":"A certificate row. GET /user/certificates returns an array of these.","properties":{"id":{"type":"string","example":"2207169020-00012","description":"Composite id: {userId}-{certificateId padded to 5 digits}"},"certificate_id":{"type":"string","nullable":true,"example":"12","description":"Catalog certificate id — use GET /api/share/certificates to fetch valid ids"},"certificate_name":{"type":"string","nullable":true,"example":"Driving License"},"year_issued":{"type":"integer","nullable":true,"example":2022},"institution_name":{"type":"string","nullable":true,"example":"Rwanda National Police"},"doc_reference_id":{"type":"string","nullable":true,"example":"78901","description":"Document reference id from the file service"},"document_url":{"type":"string","nullable":true,"example":"https://documents.ippis.rw/preview/78901","description":"Preview URL constructed from doc_reference_id"}},"example":{"id":"2207169020-00012","certificate_id":"12","certificate_name":"Driving License","year_issued":2022,"institution_name":"Rwanda National Police","doc_reference_id":"78901","document_url":"https://documents.ippis.rw/preview/78901"}},"UserCertificateFieldNested":{"type":"object","additionalProperties":true,"nullable":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true}}},"UserCertificateCatalogNested":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"certificate_field":{"$ref":"#/components/schemas/UserCertificateFieldNested","nullable":true}}},"UserCertificateDetail":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"user_id":{"type":"string","nullable":true},"certificate_id":{"type":"integer","nullable":true},"year_issued":{"type":"integer","nullable":true},"institution_name":{"type":"string","nullable":true},"doc_reference_id":{"type":"string","nullable":true},"document_url":{"type":"string","nullable":true},"created_on":{"type":"string","nullable":true},"created_by":{"type":"string","nullable":true},"updated_on":{"type":"string","nullable":true},"certificate":{"$ref":"#/components/schemas/UserCertificateCatalogNested"}}},"UserDisabilityItem":{"type":"object","additionalProperties":true,"description":"A disability row. GET /user/disabilities returns an array; POST /user/disabilities returns a single item.","properties":{"id":{"type":"integer","example":454600,"description":"Row id"},"disability_id":{"type":"integer","nullable":true,"example":1,"description":"Catalog disability id — use GET /api/share/disabilities to fetch valid ids"},"disability_name":{"type":"string","nullable":true,"example":"None"},"disability_level_name":{"type":"string","nullable":true,"example":null,"description":"Disability level name from catalog — null when no level specified. Use GET /api/share/disability-levels."},"doc_reference_id":{"type":"string","nullable":true,"example":null,"description":"Document reference id from the file service (when a PDF was uploaded)"},"document_url":{"type":"string","nullable":true,"example":"https://documents.ippis.rw/preview/","description":"Preview URL; suffix is empty when doc_reference_id is null"}},"example":{"id":454600,"disability_id":1,"disability_name":"None","disability_level_name":null,"doc_reference_id":null,"document_url":"https://documents.ippis.rw/preview/"}},"UserPublicationItem":{"type":"object","additionalProperties":true,"description":"A publication row. GET /user/publications returns an array; POST /user/publications returns a single item.","properties":{"id":{"type":"integer","example":789,"description":"Row id"},"publication_type_id":{"type":"integer","nullable":true,"example":8,"description":"Catalog publication type id — use GET /api/share/publication-types to fetch valid ids"},"publication_type_name":{"type":"string","nullable":true,"example":"Journal Article"},"title":{"type":"string","nullable":true,"example":"Impact of AI on Healthcare"},"publication_year":{"type":"integer","nullable":true,"example":2024},"document_url":{"type":"string","nullable":true,"example":"https://ippis.rw/user/profile","description":"The publication URL stored in the `url` column"}},"example":{"id":789,"publication_type_id":8,"publication_type_name":"Journal Article","title":"Impact of AI on Healthcare","publication_year":2024,"document_url":"https://ippis.rw/user/profile"}},"UserExperienceItem":{"type":"object","additionalProperties":true,"description":"A work experience row. GET /user/experiences returns an array of these.","properties":{"id":{"type":"string","example":"987654321","description":"Row id (numeric string or composite string for public-sector records)"},"user_id":{"type":"string","nullable":true,"example":"2207169020"},"responsibilities":{"type":"string","nullable":true,"example":"Led cross-functional teams and managed delivery timelines."},"institution_name":{"type":"string","nullable":true,"example":"Rwanda Development Board","description":"Employer / institution name (maps to `employerName` in the request body)"},"institution_email":{"type":"string","nullable":true,"example":"hr@rdb.rw"},"institution_phone":{"type":"string","nullable":true,"example":"+250788000000"},"position_name":{"type":"string","nullable":true,"example":"Senior Project Manager","description":"Job title (maps to `jobTitle` in the request body)"},"from_date":{"type":"string","nullable":true,"example":"2020-01-01"},"to_date":{"type":"string","nullable":true,"example":"2023-12-31","description":"null when is_currently_active is 1"},"doc_reference_id":{"type":"string","nullable":true,"example":"123456","description":"Document reference id from the file service"},"url":{"type":"string","nullable":true,"example":null,"description":"Legacy local file path (if any)"},"is_currently_active":{"type":"integer","example":0,"description":"1 = currently employed; 0 = past employment"},"verified":{"type":"integer","example":0},"employee_position_id":{"type":"string","nullable":true,"example":null},"job_field":{"type":"object","nullable":true,"additionalProperties":true,"properties":{"id":{"type":"string","nullable":true,"example":"101"},"name":{"type":"string","nullable":true,"example":"Management"}}},"document_url":{"type":"string","nullable":true,"example":"https://documents.ippis.rw/preview/123456"},"created_on":{"type":"string","nullable":true,"example":"2024-01-15T10:00:00.000Z"},"created_by":{"type":"string","nullable":true,"example":"2207169020"},"updated_on":{"type":"string","nullable":true,"example":null}},"example":{"id":"987654321","user_id":"2207169020","responsibilities":"Led cross-functional teams and managed delivery timelines.","institution_name":"Rwanda Development Board","institution_email":"hr@rdb.rw","institution_phone":"+250788000000","position_name":"Senior Project Manager","from_date":"2020-01-01","to_date":"2023-12-31","doc_reference_id":"123456","url":null,"is_currently_active":0,"verified":0,"employee_position_id":null,"job_field":{"id":"101","name":"Management"},"document_url":"https://documents.ippis.rw/preview/123456","created_on":"2024-01-15T10:00:00.000Z","created_by":"2207169020","updated_on":null}},"UserExperienceDetail":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"user_id":{"type":"string","nullable":true},"responsibilities":{"type":"string","nullable":true},"institution_name":{"type":"string","nullable":true},"institution_email":{"type":"string","nullable":true},"institution_phone":{"type":"string","nullable":true},"position_name":{"type":"string","nullable":true},"from_date":{"type":"string","nullable":true},"to_date":{"type":"string","nullable":true},"doc_reference_id":{"type":"string","nullable":true},"url":{"type":"string","nullable":true},"is_currently_active":{"type":"integer","nullable":true},"verified":{"type":"integer","nullable":true},"employee_position_id":{"type":"string","nullable":true},"job_field":{"type":"object","additionalProperties":true,"nullable":true},"document_url":{"type":"string","nullable":true},"created_on":{"type":"string","nullable":true},"created_by":{"type":"string","nullable":true},"updated_on":{"type":"string","nullable":true}}},"UserProfileResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserProfile"}},"required":["data"]}]},"UserCvReferenceResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"description":"IPPIS CV document id or empty string when none","oneOf":[{"type":"string"},{"type":"integer"}]}},"required":["data"]}]},"UserCvUploadResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"description":"New document id after upload","oneOf":[{"type":"string"},{"type":"integer"}]}},"required":["data"]}]},"UserEducationResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserEducationItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User education fetched successfully","data":[{"id":"2207169020-00001","qualification_id":"00001","qualification_name":"Bachelor's Degree in Computer Science","graduation_year":2020,"school_id":101,"school_name":"University of Rwanda","doc_reference_id":"54321","document_url":"https://documents.ippis.rw/preview/54321","school_country_name":"Rwanda","school_country_id":"RW","degree_name":"Bachelor","degree_id":"3"}]}},"UserEducationUpsertResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserEducationItem","description":"Same shape as each element of GET /user/educations"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User education saved successfully","data":{"id":"2207169020-00001","qualification_id":"00001","qualification_name":"Bachelor's Degree in Computer Science","graduation_year":2020,"school_id":101,"school_name":"University of Rwanda","doc_reference_id":"54321","document_url":"https://documents.ippis.rw/preview/54321","school_country_name":"Rwanda","school_country_id":"RW","degree_name":"Bachelor","degree_id":"3"}}},"UserEducationDeleteResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean","example":true},"already_deleted":{"type":"boolean","example":false,"description":"true when the record was already absent (idempotent)"}},"required":["deleted","already_deleted"]}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Education deleted successfully","data":{"deleted":true,"already_deleted":false}}},"UserLanguageResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserLanguageItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User language fetched successfully","data":[{"id":12345,"language_id":3,"language_name":"French","reading":"Excellent","writing":"Good","speaking":"Excellent"},{"id":12346,"language_id":2,"language_name":"English","reading":"Excellent","writing":"Excellent","speaking":"Excellent"}]}},"UserLanguageSingleResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserLanguageItem"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User languages saved successfully","data":{"id":12345,"language_id":3,"language_name":"French","reading":"Excellent","writing":"Good","speaking":"Excellent"}}},"UserRefereesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserRefereeItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User referees fetched successfully","data":[{"id":456,"referee_first_name":"John","referee_last_name":"Doe","referee_phone_number":"+250788000000","referee_email":"john.doe@example.com","referee_position_name":"Senior Manager","referee_institution_name":"MINICT"}]}},"UserRefereeSingleResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserRefereeItem"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User referees saved successfully","data":{"id":456,"referee_first_name":"John","referee_last_name":"Doe","referee_phone_number":"+250788000000","referee_email":"john.doe@example.com","referee_position_name":"Senior Manager","referee_institution_name":"MINICT"}}},"KoraInternalUserInfoNested":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","nullable":true},"given_name":{"type":"string","nullable":true},"family_name":{"type":"string","nullable":true},"picture":{"type":"string","nullable":true},"date_of_birth":{"type":"string","nullable":true,"description":"DD-MM-YYYY"},"sex":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"province":{"type":"string","nullable":true},"district":{"type":"string","nullable":true},"sector":{"type":"string","nullable":true},"cell":{"type":"string","nullable":true},"village":{"type":"string","nullable":true},"phone_number":{"type":"string","nullable":true},"document_type":{"type":"string","nullable":true,"enum":["NID","PASSPORT"]},"id_number":{"type":"string","nullable":true},"passport_number":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"email_verified":{"type":"boolean"}}},"KoraInternalUserPayload":{"type":"object","additionalProperties":true,"properties":{"sub":{"type":"string"},"institution_acronym":{"type":"string","nullable":true},"institution_name":{"type":"string","nullable":true},"institution_phone":{"type":"string","nullable":true},"institution_tin":{"type":"string","nullable":true},"employee_position_name":{"type":"string","nullable":true},"employee_unit_name":{"type":"string","nullable":true},"user_info":{"$ref":"#/components/schemas/KoraInternalUserInfoNested"}}},"KoraInternalUsersListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/KoraInternalUserPayload"}}},"required":["data"]}]},"UserCertificatesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserCertificateItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User certificates fetched successfully","data":[{"id":"2207169020-00012","certificate_id":"12","certificate_name":"Driving License","year_issued":2022,"institution_name":"Rwanda National Police","doc_reference_id":"78901","document_url":"https://documents.ippis.rw/preview/78901"}]}},"UserCertificateUpsertResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserCertificateDetail"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User certificate saved successfully","data":{"id":"2207169020-00012","user_id":"2207169020","certificate_id":12,"year_issued":2022,"institution_name":"Rwanda National Police","doc_reference_id":"78901","document_url":"https://documents.ippis.rw/preview/78901","created_on":"2024-01-10T08:00:00.000Z","created_by":"2207169020","updated_on":null,"certificate":{"id":12,"name":"Driving License","certificate_field":{"id":"3","name":"Transport"}}}}},"UserCertificateDeleteResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean"},"already_deleted":{"type":"boolean"}},"required":["deleted","already_deleted"]}},"required":["data"]}]},"ProfileResourceDeleteResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean","example":true},"already_deleted":{"type":"boolean","example":false,"description":"true when the record was already absent (idempotent)"}},"required":["deleted","already_deleted"]}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Record removed successfully","data":{"deleted":true,"already_deleted":false}}},"ProfileDisabilityDeleteResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"]}},"required":["data"]}]},"UserDisabilitiesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserDisabilityItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User disabilities fetched successfully","data":[{"id":454600,"disability_id":1,"disability_name":"None","disability_level_name":null,"doc_reference_id":null,"document_url":"https://documents.ippis.rw/preview/"}]}},"UserDisabilitySingleResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserDisabilityItem"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User disabilities saved successfully","data":{"id":454600,"disability_id":1,"disability_name":"None","disability_level_name":null,"doc_reference_id":null,"document_url":"https://documents.ippis.rw/preview/"}}},"UserPublicationsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserPublicationItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User publications fetched successfully","data":[{"id":789,"publication_type_id":8,"publication_type_name":"Journal Article","title":"Impact of AI on Healthcare","publication_year":2024,"document_url":"https://ippis.rw/user/profile"}]}},"UserPublicationSingleResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserPublicationItem"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User publications saved successfully","data":{"id":789,"publication_type_id":8,"publication_type_name":"Journal Article","title":"Impact of AI on Healthcare","publication_year":2024,"document_url":"https://ippis.rw/user/profile"}}},"UserExperiencesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserExperienceItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User experiences fetched successfully","data":[{"id":"987654321","user_id":"2207169020","responsibilities":"Led cross-functional teams and managed delivery timelines.","institution_name":"Rwanda Development Board","institution_email":"hr@rdb.rw","institution_phone":"+250788000000","position_name":"Senior Project Manager","from_date":"2020-01-01","to_date":"2023-12-31","doc_reference_id":"123456","url":null,"is_currently_active":0,"verified":0,"employee_position_id":null,"job_field":{"id":"101","name":"Management"},"document_url":"https://documents.ippis.rw/preview/123456","created_on":"2024-01-15T10:00:00.000Z","created_by":"2207169020","updated_on":null}]}},"UserExperienceUpsertResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserExperienceDetail"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User experience saved successfully","data":{"id":"987654321","user_id":"2207169020","responsibilities":"Led cross-functional teams and managed delivery timelines.","institution_name":"Rwanda Development Board","institution_email":"hr@rdb.rw","institution_phone":"+250788000000","position_name":"Senior Project Manager","from_date":"2020-01-01","to_date":"2023-12-31","doc_reference_id":"123456","url":null,"is_currently_active":0,"verified":0,"employee_position_id":null,"job_field":{"id":"101","name":"Management"},"document_url":"https://documents.ippis.rw/preview/123456","created_on":"2024-01-15T10:00:00.000Z","created_by":"2207169020","updated_on":null}}},"UserExperienceDeleteResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean"},"already_deleted":{"type":"boolean"}},"required":["deleted","already_deleted"]}},"required":["data"]}]},"VerifiedIdentityUser":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"phone_number":{"type":"string","nullable":true},"nid_verified":{"type":"boolean","nullable":true},"national_id":{"type":"string","nullable":true}}},"TinVerificationData":{"type":"object","additionalProperties":true,"description":"RRA business-details payload when found; `details` is null when not found (e.g. 404).","properties":{"valid":{"type":"boolean"},"details":{"type":"object","nullable":true,"additionalProperties":true}},"required":["valid","details"]},"TinVerificationResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TinVerificationData"}},"required":["data"]}]},"NationalIdVerifyRequest":{"oneOf":[{"type":"object","required":["national_id"],"properties":{"national_id":{"type":"string","minLength":1,"maxLength":16}}},{"type":"object","required":["nationalId"],"properties":{"nationalId":{"type":"string","minLength":1,"maxLength":16}}},{"type":"object","required":["document_number"],"properties":{"document_number":{"type":"string","minLength":1,"maxLength":16}}},{"type":"object","required":["documentNumber"],"properties":{"documentNumber":{"type":"string","minLength":1,"maxLength":16}}},{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["national_id"],"properties":{"national_id":{"type":"string","minLength":1,"maxLength":16}}}}},{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["nationalId"],"properties":{"nationalId":{"type":"string","minLength":1,"maxLength":16}}}}},{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["document_number"],"properties":{"document_number":{"type":"string","minLength":1,"maxLength":16}}}}},{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["documentNumber"],"properties":{"documentNumber":{"type":"string","minLength":1,"maxLength":16}}}}}]},"NationalIdResidenceDistrict":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"province":{"type":"object","additionalProperties":true,"nullable":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true}}}}},"NationalIdResidenceSector":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"district":{"$ref":"#/components/schemas/NationalIdResidenceDistrict","nullable":true}}},"NationalIdResidenceCell":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"sector":{"$ref":"#/components/schemas/NationalIdResidenceSector","nullable":true}}},"NationalIdResidenceVillage":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"cell":{"$ref":"#/components/schemas/NationalIdResidenceCell","nullable":true}}},"NationalIdVerificationData":{"type":"object","additionalProperties":true,"description":"Payload from national ID API plus local residence hierarchy. Keys are snake_case in JSON responses.","properties":{"last_name":{"type":"string","nullable":true},"first_name":{"type":"string","nullable":true},"father_names":{"type":"string","nullable":true},"mother_names":{"type":"string","nullable":true},"place_of_birth":{"type":"string","nullable":true},"gender_id":{"type":"string","nullable":true},"date_of_birth":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"email":{"type":"string","nullable":true,"description":"From usr_users when NID matches; else NID API if present"},"phone_number":{"type":"string","nullable":true,"description":"From usr_users when NID matches; else NID API if present"},"verified":{"type":"boolean"},"residence":{"$ref":"#/components/schemas/NationalIdResidenceVillage","nullable":true},"profile_image":{"type":"string","nullable":true}},"required":["verified"]},"NationalIdVerificationResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/NationalIdVerificationData"}},"required":["data"]}]},"UserResidenceResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","additionalProperties":true,"description":"Village with nested cell → sector → district → province, or `{}` when not set","properties":{"id":{"type":"string","nullable":true,"example":"500101"},"name":{"type":"string","nullable":true,"example":"Amajyaruguru"},"cell":{"type":"object","nullable":true,"additionalProperties":true,"properties":{"id":{"type":"string","nullable":true,"example":"50010"},"name":{"type":"string","nullable":true,"example":"Bumbogo"},"sector":{"type":"object","nullable":true,"additionalProperties":true,"properties":{"id":{"type":"string","nullable":true,"example":"5001"},"name":{"type":"string","nullable":true,"example":"Bumbogo"},"district":{"type":"object","nullable":true,"additionalProperties":true,"properties":{"id":{"type":"string","nullable":true,"example":"5"},"name":{"type":"string","nullable":true,"example":"Gasabo"},"province":{"type":"object","nullable":true,"additionalProperties":true,"properties":{"id":{"type":"string","nullable":true,"example":"1"},"name":{"type":"string","nullable":true,"example":"Kigali City"}}}}}}}}}}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User residence fetched successfully","data":{"id":"500101","name":"Amajyaruguru","cell":{"id":"50010","name":"Bumbogo","sector":{"id":"5001","name":"Bumbogo","district":{"id":"5","name":"Gasabo","province":{"id":"1","name":"Kigali City"}}}}}}},"UpdateUserResidenceRequest":{"oneOf":[{"type":"object","required":["residence_village_id"],"properties":{"residence_village_id":{"type":"string","pattern":"^[0-9]+$","description":"Village id from `COM_Villages`"}}},{"type":"object","required":["residenceVillageId"],"properties":{"residenceVillageId":{"type":"string","pattern":"^[0-9]+$"}}},{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["residence_village_id"],"properties":{"residence_village_id":{"type":"string","pattern":"^[0-9]+$"}}}}},{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["residenceVillageId"],"properties":{"residenceVillageId":{"type":"string","pattern":"^[0-9]+$"}}}}}]},"UserProfileStatusPayload":{"type":"object","additionalProperties":true,"description":"Profile completion flags and loan summary. Each boolean is true when the section has at least one record (referees requires ≥ 3).","properties":{"verified":{"type":"boolean","example":false},"cv":{"type":"boolean","example":true,"description":"true when cvDocReferenceId is set"},"education":{"type":"boolean","example":true,"description":"true when at least 1 education record exists"},"experience":{"type":"boolean","example":true},"language":{"type":"boolean","example":true},"disability":{"type":"boolean","example":true},"certificate":{"type":"boolean","example":false},"publication":{"type":"boolean","example":false},"referees":{"type":"boolean","example":false,"description":"true when referee count ≥ 3"},"total_loan_amount":{"type":"number","example":0},"total_paid_amount":{"type":"number","example":0},"remaining_loan_amount":{"type":"number","example":0},"has_visual_impairment":{"type":"boolean","nullable":true,"example":null}},"example":{"verified":false,"cv":true,"education":true,"experience":true,"language":true,"disability":true,"certificate":false,"publication":false,"referees":false,"total_loan_amount":0,"total_paid_amount":0,"remaining_loan_amount":0,"has_visual_impairment":null}},"UserProfileStatusResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserProfileStatusPayload"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User profile status fetched successfully","data":{"verified":false,"cv":true,"education":true,"experience":true,"language":true,"disability":true,"certificate":false,"publication":false,"referees":false,"total_loan_amount":0,"total_paid_amount":0,"remaining_loan_amount":0,"has_visual_impairment":null}}},"DegreeItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"QualificationsItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"QualificationGradeItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"qualification_id":{"type":"string","nullable":true},"grade_name":{"type":"string","nullable":true}}},"CountryItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"ProvinceItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"DistrictItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"SectorItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"CellItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"VillageItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"DegreesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DegreeItem"}}},"required":["data"]}]},"ShareCertificateFieldItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true}}},"ShareCertificateItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"certificate_field_id":{"type":"string","nullable":true},"certificate_field":{"$ref":"#/components/schemas/ShareCertificateFieldItem","nullable":true}}},"ShareCertificatesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShareCertificateItem"}}},"required":["data"]}]},"ShareDisabilityCatalogItem":{"type":"object","additionalProperties":true,"description":"Row from `USR_Disabilities` (columns vary by schema; `is_active` after snake_case when present).","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true}}},"ShareDisabilitiesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShareDisabilityCatalogItem"}}},"required":["data"]}]},"QualificationsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/QualificationsItem"}}},"required":["data"]}]},"QualificationGradesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/QualificationGradeItem"}}},"required":["data"]}]},"CountriesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CountryItem"}}},"required":["data"]}]},"ProvincesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProvinceItem"}}},"required":["data"]}]},"DistrictsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DistrictItem"}}},"required":["data"]}]},"SectorsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SectorItem"}}},"required":["data"]}]},"CellsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CellItem"}}},"required":["data"]}]},"VillagesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VillageItem"}}},"required":["data"]}]},"SchoolRecordItem":{"type":"object","additionalProperties":true,"description":"Row from COM_Schools (column names depend on database schema)","properties":{"id":{"type":"string","example":"101"},"name":{"type":"string","nullable":true,"example":"University of Rwanda"}}},"SchoolsByCountryResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SchoolRecordItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Request successful","data":[{"id":"101","name":"University of Rwanda"},{"id":"102","name":"Kigali Independent University"}]}},"ShareLanguageItem":{"type":"object","additionalProperties":true,"description":"A language entry from COM_Languages. Use `id` as `languageId` in POST /api/profile/user/languages.","properties":{"id":{"type":"integer","example":3},"name":{"type":"string","nullable":true,"example":"French"}},"example":{"id":3,"name":"French"}},"ShareLanguagesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShareLanguageItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Request successful","data":[{"id":1,"name":"Kinyarwanda"},{"id":2,"name":"English"},{"id":3,"name":"French"}]}},"ShareDisabilityLevelItem":{"type":"object","additionalProperties":true,"description":"A disability level entry from USR_DisabilityLevels. Use `id` as `disabilityLevelId` in POST /api/profile/user/disabilities.","properties":{"id":{"type":"integer","example":1},"name":{"type":"string","nullable":true,"example":"Mild"}},"example":{"id":1,"name":"Mild"}},"ShareDisabilityLevelsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShareDisabilityLevelItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Request successful","data":[{"id":1,"name":"Mild"},{"id":2,"name":"Moderate"},{"id":3,"name":"Severe"}]}},"SharePublicationTypeItem":{"type":"object","additionalProperties":true,"description":"A publication type entry from COM_PublicationTypes. Use `id` as `publicationTypeId` in POST /api/profile/user/publications.","properties":{"id":{"type":"integer","example":8},"name":{"type":"string","nullable":true,"example":"Journal Article"}},"example":{"id":8,"name":"Journal Article"}},"SharePublicationTypesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SharePublicationTypeItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Request successful","data":[{"id":1,"name":"Book"},{"id":2,"name":"Book Chapter"},{"id":8,"name":"Journal Article"}]}},"ShareJobFieldItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","example":"101"},"name":{"type":"string","nullable":true,"example":"Information Technology"}},"example":{"id":"101","name":"Information Technology"}},"ShareJobFieldsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShareJobFieldItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Request successful","data":[{"id":"101","name":"Information Technology"},{"id":"102","name":"Health"}]}},"ShareSchoolCategoryItem":{"type":"object","additionalProperties":true,"properties":{"id":{"type":"string","example":"1"},"name":{"type":"string","nullable":true,"example":"University"}},"example":{"id":"1","name":"University"}},"ShareSchoolCategoriesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShareSchoolCategoryItem"}}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Request successful","data":[{"id":"1","name":"University"},{"id":"2","name":"College"},{"id":"3","name":"Technical School"}]}},"RebDistrictNested":{"type":"object","nullable":true,"properties":{"id":{"oneOf":[{"type":"integer"},{"type":"string"}],"nullable":true,"example":1},"name":{"type":"string","nullable":true,"example":"Gasabo"}}},"RebApplicantPreferencesPayload":{"type":"object","properties":{"examDistrict":{"$ref":"#/components/schemas/RebDistrictNested","nullable":true,"description":"Preferred exam district; null if not set"},"workDistricts":{"type":"array","items":{"$ref":"#/components/schemas/RebDistrictNested"},"description":"Up to 3 preferred work districts (nulls for unset slots)","example":[{"id":2,"name":"Kicukiro"},{"id":3,"name":"Nyarugenge"},null]},"didEducation":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"nullable":true,"description":"Whether the applicant completed education in Rwanda; empty string when not set","example":true}},"example":{"examDistrict":{"id":1,"name":"Gasabo"},"workDistricts":[{"id":2,"name":"Kicukiro"},{"id":3,"name":"Nyarugenge"},null],"didEducation":true}},"RebApplicantPreferencesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RebApplicantPreferencesPayload"}},"required":["data"]}],"example":{"status":"success","code":200,"message":"REB applicant preferences fetched successfully","data":{"examDistrict":{"id":1,"name":"Gasabo"},"workDistricts":[{"id":2,"name":"Kicukiro"},{"id":3,"name":"Nyarugenge"},null],"didEducation":true}}},"WorkCertificateResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","properties":{"docId":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"New document reference id for the generated work certificate","example":"98765"}},"required":["docId"]}},"required":["data"]}],"example":{"status":"success","code":200,"message":"Work certificate requested successfully","data":{"docId":"98765"}}},"UpdateUserFileFromLegacyResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelopeBase"},{"type":"object","properties":{"data":{"type":"object","properties":{"docReferenceId":{"type":"string","description":"New document reference id saved for the resource","example":"22222"}},"required":["docReferenceId"]}},"required":["data"]}],"example":{"status":"success","code":200,"message":"User file reference updated successfully","data":{"docReferenceId":"22222"}}}}},"paths":{"/api/auth/token":{"post":{"tags":["Auth"],"summary":"Get Token","description":"Use this endpoint to authenticate a client and receive access and refresh tokens.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"},"examples":{"snake_case":{"value":{"client_id":"my-client-id","client_secret":"my-client-secret"}},"camel_case":{"value":{"clientId":"my-client-id","clientSecret":"my-client-secret"}},"wrapped_data":{"value":{"data":{"client_id":"my-client-id","client_secret":"my-client-secret"}}}}}}},"responses":{"200":{"description":"Token issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenIssueResponse"},"examples":{"success":{"value":{"status":"success","code":200,"message":"Token issued successfully","data":{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","token_type":"Bearer","expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","refresh_expires_in":2592000}}}}}}},"400":{"description":"Invalid request payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing_fields":{"value":{"status":"error","code":400,"message":"client_id and client_secret are required","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"401":{"description":"Invalid client credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_credentials":{"value":{"status":"error","code":401,"message":"Invalid client credentials","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}}}}},"/api/auth/refresh":{"post":{"tags":["Auth"],"summary":"Get Refresher Token","description":"Exchanges a valid refresh token for a new access token and a new refresh token (rotation). The previous refresh token is revoked and cannot be reused.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequest"},"examples":{"snake_case":{"value":{"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}},"camel_case":{"value":{"refreshToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}},"wrapped_data":{"value":{"data":{"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}}}}}}},"responses":{"200":{"description":"Access token refreshed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRefreshResponse"},"examples":{"success":{"value":{"status":"success","code":200,"message":"Access token refreshed successfully","data":{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","token_type":"Bearer","expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","refresh_expires_in":2592000}}}}}}},"400":{"description":"Invalid request payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing_refresh_token":{"value":{"status":"error","code":400,"message":"refresh_token is required","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"401":{"description":"Invalid refresh token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_refresh_token":{"value":{"status":"error","code":401,"message":"Invalid or expired refresh token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"revoked_refresh_token":{"value":{"status":"error","code":401,"message":"Refresh token has been revoked","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}}}}},"/api/profile/user/identity":{"get":{"tags":["Users"],"summary":"Identity","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User profile fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/cv":{"get":{"tags":["Users"],"summary":"CV document reference","description":"Returns `usr_users.cvDocReferenceId` in `data`, or an empty string when unset. Standard success envelope; `data` is a scalar (string or numeric id).","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"CV reference","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCvReferenceResponse"}}}},"400":{"description":"Invalid request headers or missing user id on token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Upload or replace CV (PDF)","description":"Multipart form with PDF `file` (max 5 MB). Document type 34, RECRUITMENT module. Deletes the previous file in the file service when a CV reference already exists.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"PDF only"}}}}}},"responses":{"200":{"description":"New CV document id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCvUploadResponse"}}}},"400":{"description":"No file attached or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/educations":{"get":{"tags":["Users"],"summary":"List user education","description":"Returns all qualification rows for the token user with nested school, degree, and `document_url` when `doc_reference_id` is set. Requires `profile:user` scope.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User education fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserEducationResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Create or update education","description":"Multipart form (`multipart/form-data`). PDF `file` is required when creating a new record; optional when updating. Omit `id` to create (row id becomes `{userId}-{qualificationId}`). Use `id` to update an existing row.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["schoolId","graduationYear","qualificationId"],"properties":{"id":{"type":"string","description":"Existing education row id (update only)"},"schoolId":{"type":"string","description":"School id"},"graduationYear":{"type":"string","example":"2020"},"qualificationId":{"type":"string","description":"Qualification id"},"file":{"type":"string","format":"binary","description":"PDF document (required on create; optional on update)"}}}}}},"responses":{"200":{"description":"Education saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserEducationUpsertResponse"}}}},"400":{"description":"Validation, duplicate record, or upload error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Not allowed to modify this record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/educations/{id}":{"delete":{"tags":["Users"],"summary":"Delete education (idempotent)","description":"Removes the education row and its stored document when present. Repeating delete for the same id succeeds with `already_deleted: true`.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Deleted or already absent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserEducationDeleteResponse"}}}},"400":{"description":"Invalid path parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Not allowed to delete this record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/languages":{"get":{"tags":["Users"],"summary":"List user languages","description":"Returns all language rows for the token user with nested `language`. Requires `profile:user` scope.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User language fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLanguageResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Create or update user language","description":"Omit `id` to insert a new record. Include `id` to update an existing one. Duplicate `languageId` per user is rejected. Returns the saved language row.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["languageId"],"properties":{"id":{"type":"string","nullable":true,"description":"Row id — omit or leave empty to insert, provide to update","example":null},"languageId":{"type":"integer","description":"Language catalog id","example":3},"reading":{"type":"string","nullable":true,"description":"Reading proficiency level","example":"Excellent"},"writing":{"type":"string","nullable":true,"description":"Writing proficiency level","example":"Good"},"speaking":{"type":"string","nullable":true,"description":"Speaking proficiency level","example":"Excellent"}}},"example":{"id":null,"languageId":3,"reading":"Excellent","writing":"Good","speaking":"Excellent"}}}},"responses":{"200":{"description":"Language saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLanguageSingleResponse"}}}},"400":{"description":"Validation or duplicate language","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/languages/{id}":{"delete":{"tags":["Users"],"summary":"Delete user language row","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResourceDeleteResponse"}}}},"400":{"description":"Invalid id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/certificates":{"get":{"tags":["Users"],"summary":"Certificates","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User certificates fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCertificatesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Create or update user certificate","description":"Multipart form. PDF `file` required on create. New row id is `{userId}-{certificateId padded to 5 digits}` (e.g. `2207169020-00012`). Document type 26, recruitment module. Omit `id` to create.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["certificateId","yearIssued","institutionName"],"properties":{"id":{"type":"string","description":"Existing row id when updating"},"certificateId":{"type":"string","description":"Catalog certificate id"},"yearIssued":{"type":"string","example":"2022"},"institutionName":{"type":"string"},"file":{"type":"string","format":"binary","description":"PDF (required on create)"}}}}}},"responses":{"200":{"description":"Certificate saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCertificateUpsertResponse"}}}},"400":{"description":"Validation, duplicate record, or upload error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Not allowed to modify this record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/certificates/{id}":{"delete":{"tags":["Users"],"summary":"Delete user certificate (idempotent)","description":"Deletes the stored document when present, then the row. Repeating delete succeeds with `already_deleted: true`.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Deleted or already absent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCertificateDeleteResponse"}}}},"400":{"description":"Invalid path parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Not allowed to delete this record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/disabilities":{"get":{"tags":["Users"],"summary":"Disabilities","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User disabilities fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDisabilitiesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Create or update user disability","description":"Multipart form (`multipart/form-data`). Optional PDF `file` (document type 33, RECRUITMENT module). Omit `id` to insert a new disability record; supply `id` to update. Disability id `1` (None) cannot coexist with other disability ids. Returns the saved disability row as a single object.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["disabilityId"],"properties":{"id":{"type":"string","nullable":true,"description":"Row id — omit or leave empty to insert, provide to update","example":null},"disabilityId":{"type":"string","description":"Catalog disability id from GET /api/share/disabilities","example":"1"},"disabilityLevelId":{"type":"string","nullable":true,"description":"Optional disability level id from GET /api/share/disability-levels","example":null},"file":{"type":"string","format":"binary","description":"PDF supporting document (optional)"}}}}}},"responses":{"200":{"description":"Disability saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDisabilitySingleResponse"}}}},"400":{"description":"Validation, duplicate record, or business rule violation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden — record belongs to another user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/disability-document":{"post":{"tags":["Users"],"summary":"Upload user-level disability document","description":"Multipart PDF required. Sets `usr_users.disabilityDocReferenceId` (document type 33).","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Document id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCvUploadResponse"}}}},"400":{"description":"Missing file or validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/disabilities/{id}":{"delete":{"tags":["Users"],"summary":"Delete user disability row","description":"Path `id` is the `USR_UserDisabilities` row id (not catalog disability id).","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileDisabilityDeleteResponse"}}}},"400":{"description":"Record not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/publications":{"get":{"tags":["Users"],"summary":"Publications","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User publications fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPublicationsResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Create or update user publication","description":"JSON body. Omit `id` (or pass `null`) to insert a new record. Provide `id` to update an existing one. Returns the saved publication as a single object.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["publicationTypeId","publicationYear"],"properties":{"id":{"oneOf":[{"type":"integer"},{"type":"null"}],"description":"Row id — omit or null to insert, provide integer to update","example":null},"publicationTypeId":{"type":"integer","description":"Catalog publication type id from GET /api/share/publication-types","example":8},"publicationYear":{"type":"integer","description":"4-digit publication year","example":2024},"title":{"type":"string","nullable":true,"description":"Publication title","example":"Impact of AI on Healthcare"},"url":{"type":"string","nullable":true,"description":"External URL for the publication","example":"https://ippis.rw/user/profile"}}},"example":{"id":null,"publicationTypeId":8,"publicationYear":2024,"title":"Impact of AI on Healthcare","url":"https://ippis.rw/user/profile"}}}},"responses":{"200":{"description":"Publication saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPublicationSingleResponse"}}}},"400":{"description":"Validation error or record not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden — record belongs to another user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/publications/{id}":{"delete":{"tags":["Users"],"summary":"Delete user publication row","description":"Path `id` is the `USR_UserPublications` row id (not the catalog publication type id). Idempotent: if the row is already gone, `already_deleted` is true. Requires `profile:user` scope.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Deleted or already absent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResourceDeleteResponse"}}}},"400":{"description":"Invalid path parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Not allowed to delete this record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/experiences":{"get":{"tags":["Users"],"summary":"Experiences","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User experiences fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserExperiencesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Create or update work experience","description":"Multipart form. PDF `file` is required for create; optional on update. Omit `id` to insert. When `is_currently_active` is true, `to_date` is stored as null. Uploads use recruitment document type 25.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["employerName","jobTitle","fromDate"],"properties":{"id":{"type":"string","description":"Existing row id (update only)"},"description":{"type":"string","description":"Responsibilities / description"},"employerName":{"type":"string","description":"Institution / employer name"},"institutionEmail":{"type":"string"},"institutionPhoneNumber":{"type":"string"},"jobTitle":{"type":"string","maxLength":128,"description":"Maps to position_name"},"fromDate":{"type":"string"},"toDate":{"type":"string","description":"Ignored when currently active"},"isCurrentlyActive":{"oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}],"description":"Truthy when employment is ongoing"},"file":{"type":"string","format":"binary","description":"PDF (required on create)"}}}}}},"responses":{"200":{"description":"Experience saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserExperienceUpsertResponse"}}}},"400":{"description":"Validation, missing file on create, or upload error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Not allowed to modify this record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/experiences/{id}":{"delete":{"tags":["Users"],"summary":"Delete work experience (idempotent)","description":"Deletes the document in the file service when present, removes a legacy local file when `url` contains `uploads/`, then deletes the row. Repeating delete succeeds with `already_deleted: true`.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Deleted or already absent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserExperienceDeleteResponse"}}}},"400":{"description":"Invalid path parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Not allowed to delete this record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/referees":{"get":{"tags":["Users"],"summary":"Referees","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User referees fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRefereesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Create or update referee","description":"Omit `id` to insert a new referee. Provide `id` to update an existing one. Duplicate email or phone per user is rejected on insert.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Row id — omit or null to insert, provide to update","example":null},"refereeFirstName":{"type":"string","nullable":true,"description":"Referee first name","example":"John"},"refereeLastName":{"type":"string","nullable":true,"description":"Referee last name","example":"Doe"},"refereePhoneNumber":{"type":"string","nullable":true,"description":"Referee phone number","example":"+250788000000"},"refereeEmail":{"type":"string","nullable":true,"description":"Referee email address","example":"john.doe@example.com"},"refereePositionName":{"type":"string","nullable":true,"description":"Referee job position / title","example":"Senior Manager"},"refereeInstitutionName":{"type":"string","nullable":true,"description":"Institution or company where the referee works","example":"MINICT"}}},"example":{"id":null,"refereeFirstName":"John","refereeLastName":"Doe","refereePhoneNumber":"+250788000000","refereeEmail":"john.doe@example.com","refereePositionName":"Senior Manager","refereeInstitutionName":"MINICT"}}}},"responses":{"200":{"description":"Referee saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRefereeSingleResponse"}}}},"400":{"description":"Duplicate referee (same email or phone) or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden — record belongs to another user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/referees/{id}":{"delete":{"tags":["Users"],"summary":"Delete referee","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Deleted or already absent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResourceDeleteResponse"}}}},"400":{"description":"Invalid id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/residence":{"get":{"tags":["Users"],"summary":"User residence","description":"Residence village with nested cell, sector, and district (from `usr_users.residenceVillageId`). Requires `profile:user` scope. `data` is `{}` when unset. Response keys are snake_case.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User residence fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResidenceResponse"}}}},"400":{"description":"Invalid request headers or missing user id on token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"tags":["Users"],"summary":"Update user residence","description":"Sets `residence_village_id` on the authenticated user after verifying the village exists in `COM_Villages`. Returns the same `data` shape as `GET /api/profile/user/residence`. Requires `profile:user` scope.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserResidenceRequest"},"examples":{"snake_case":{"value":{"residence_village_id":"12345"}},"camel_case":{"value":{"residenceVillageId":"12345"}},"wrapped_data":{"value":{"data":{"residence_village_id":"12345"}}}}}}},"responses":{"200":{"description":"User residence updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResidenceResponse"}}}},"400":{"description":"Invalid body, invalid village id, or village does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/status":{"get":{"tags":["Users"],"summary":"User profile status","description":"Completion flags and loan totals from `USR_GetUserProfileStatus`. Requires `profile:user` scope. Response keys are snake_case.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"User profile status fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileStatusResponse"}}}},"400":{"description":"Invalid request headers or missing user id on token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/update-status":{"get":{"tags":["Users"],"summary":"Update profile status via BRD","description":"Posts the user's NID (first 13 chars, spaces stripped) to BRD `brd-beneficiaries`, then returns the same profile status payload as `/user/status`. Requires `profile:user` scope and `BRD_SERVICE_API` / `BRD_ACCESS_TOKEN`. Response keys are snake_case.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Profile status refreshed after BRD sync","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileStatusResponse"}}}},"400":{"description":"Missing NID, invalid token user id, or BRD request failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"BRD integration not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/verify-tin/{tinNumber}":{"get":{"tags":["Share"],"summary":"Verify TIN number","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"tinNumber","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9]+$","minLength":1,"maxLength":10,"example":"1234567890"}}],"responses":{"200":{"description":"TIN validated via RRA","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TinVerificationResponse"}}}},"400":{"description":"Invalid request parameters or RRA rejected the request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"RRA integration not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/verify-national-id":{"post":{"tags":["Share"],"summary":"Verify national ID","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NationalIdVerifyRequest"},"examples":{"snake_case":{"value":{"national_id":"107300123"}},"camel_case":{"value":{"nationalId":"107300123"}},"wrapped_data":{"value":{"data":{"national_id":"107300123"}}}}}}},"responses":{"200":{"description":"National ID verified via NID service","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NationalIdVerificationResponse"}}}},"400":{"description":"Invalid request payload or NID service rejected verification","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"NID integration not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/degrees":{"get":{"tags":["Share"],"summary":"Get degrees","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Degrees fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DegreesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/qualifications/{degreeId}":{"get":{"tags":["Share"],"summary":"Get qualifications by degree","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"degreeId","in":"path","required":true,"schema":{"type":"string","example":"1"}}],"responses":{"200":{"description":"Qualifications fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualificationsResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/provinces":{"get":{"tags":["Share"],"summary":"Get provinces","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Provinces fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvincesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/districts/{provinceId}":{"get":{"tags":["Share"],"summary":"Get districts by province","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"provinceId","in":"path","required":true,"schema":{"type":"string","example":"1"}}],"responses":{"200":{"description":"Districts fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DistrictsResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/qualification-grades":{"get":{"tags":["Share"],"summary":"Get qualification grades","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Qualification grades fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualificationGradesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/countries":{"get":{"tags":["Share"],"summary":"Get countries","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Countries fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountriesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/sectors/{districtId}":{"get":{"tags":["Share"],"summary":"Get sectors by district","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"districtId","in":"path","required":true,"schema":{"type":"string","example":"1"}}],"responses":{"200":{"description":"Sectors fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SectorsResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/cells/{sectorUd}":{"get":{"tags":["Share"],"summary":"Get cells by sector","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"sectorUd","in":"path","required":true,"schema":{"type":"string","example":"1"}}],"responses":{"200":{"description":"Cells fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CellsResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/villages/{cellId}":{"get":{"tags":["Share"],"summary":"Get villages by cell","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"cellId","in":"path","required":true,"schema":{"type":"string","example":"1"}}],"responses":{"200":{"description":"Villages fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VillagesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/languages":{"get":{"tags":["Share"],"summary":"Get languages catalog","description":"Returns all active languages from `COM_Languages`. Use the returned `id` as `languageId` when creating/updating `POST /api/profile/user/languages`.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Languages fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLanguagesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/disability-levels":{"get":{"tags":["Share"],"summary":"Get disability levels catalog","description":"Returns all disability levels from `USR_DisabilityLevels`. Use the returned `id` as `disabilityLevelId` when creating/updating `POST /api/profile/user/disabilities`.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Disability levels fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareDisabilityLevelsResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/disabilities":{"get":{"tags":["Share"],"summary":"Get active disabilities (catalog)","description":"Returns rows from `USR_Disabilities` where `isActive` is true (same catalog used for profile `disabilityId`). Full row shape depends on the table; response keys are snake_case.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Disabilities fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareDisabilitiesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/publication-types":{"get":{"tags":["Share"],"summary":"Get publication types catalog","description":"Returns all publication types from `COM_PublicationTypes`. Use the returned `id` as `publicationTypeId` when creating/updating `POST /api/profile/user/publications`.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Publication types fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharePublicationTypesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/certificates":{"get":{"tags":["Share"],"summary":"Get certificates","description":"Returns certificates from `COM_Certificates` with nested certificate-field information from `COM_CertificateFields`.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Certificates fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareCertificatesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/job-field":{"get":{"tags":["Share"],"summary":"Get job fields catalog","description":"Returns job field / sector categories from the catalog.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"Job fields fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareJobFieldsResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/school-categories":{"get":{"tags":["Share"],"summary":"Get school categories catalog","description":"Returns school type categories from the catalog.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"School categories fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareSchoolCategoriesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/schools-by-country/{countryId}":{"get":{"tags":["Share"],"summary":"Get schools by country","security":[{"bearerAuth":[],"clientIdHeader":[]}],"parameters":[{"name":"countryId","in":"path","required":true,"description":"Country identifier as stored in COM_Schools (e.g. numeric id or code such as RW).","schema":{"type":"string","example":"RW","maxLength":5,"pattern":"^[A-Za-z0-9_-]{1,5}$"}}],"responses":{"200":{"description":"Schools fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchoolsByCountryResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/update-user-file":{"post":{"tags":["Users"],"summary":"Migrate legacy file reference","description":"Updates a document reference id for an existing education, certificate, or experience record when the file was stored via a legacy path. The old document is deleted from the file service; the new reference is saved to the relevant row. `actionType` determines which resource type is updated.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["oldDocReferenceId","id","actionType","userId"],"properties":{"oldDocReferenceId":{"type":"string","description":"Existing document reference id to replace","example":"11111"},"id":{"type":"string","description":"Row id of the education, certificate, or experience record","example":"2207169020-00001"},"actionType":{"type":"string","enum":["CHANGE_EDUCATION_FILE","CHANGE_CERTIFICATE_FILE","CHANGE_EXPERIENCE_FILE"],"description":"Determines which resource type to update","example":"CHANGE_EDUCATION_FILE"},"userId":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"User id — must match the authenticated partner user","example":"2207169020"},"docName":{"type":"string","nullable":true,"description":"Optional document name for the file service","example":"Education Certificate"}}},"example":{"oldDocReferenceId":"11111","id":"2207169020-00001","actionType":"CHANGE_EDUCATION_FILE","userId":"2207169020","docName":"Education Certificate"}}}},"responses":{"200":{"description":"File reference updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserFileFromLegacyResponse"},"example":{"status":"success","code":200,"message":"User file reference updated successfully","data":{"docReferenceId":"22222"}}}}},"400":{"description":"Validation error or record not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden — userId does not match authenticated user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/reb-applicant-preferences":{"get":{"tags":["Users"],"summary":"Get REB applicant preferences","description":"Fetches the authenticated user's REB (Rwanda Education Board) exam district and work district preferences, plus whether they did their education in Rwanda.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"REB preferences fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebApplicantPreferencesResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Users"],"summary":"Save REB applicant preferences","description":"Upserts the authenticated user's REB exam and work district preferences. All fields are optional — omit to leave unchanged. `didEducation` indicates whether the applicant received education in Rwanda.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"examDistrictId":{"oneOf":[{"type":"integer"},{"type":"string"},{"type":"null"}],"description":"Preferred district id for the exam — use GET /api/share/districts/{provinceId}","example":1},"workDistrictId1":{"oneOf":[{"type":"integer"},{"type":"string"},{"type":"null"}],"description":"First preferred work district id","example":2},"workDistrictId2":{"oneOf":[{"type":"integer"},{"type":"string"},{"type":"null"}],"description":"Second preferred work district id","example":3},"workDistrictId3":{"oneOf":[{"type":"integer"},{"type":"string"},{"type":"null"}],"description":"Third preferred work district id","example":null},"didEducation":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}],"description":"Whether the applicant completed education in Rwanda","example":true}}},"example":{"examDistrictId":1,"workDistrictId1":2,"workDistrictId2":3,"workDistrictId3":null,"didEducation":true}}}},"responses":{"200":{"description":"REB preferences saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebApplicantPreferencesResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/profile/user/request-work-certificate":{"post":{"tags":["Users"],"summary":"Request work certificate","description":"Generates a work certificate PDF via the file service for the authenticated user's employee position. The `employeeId` must match the authenticated user. If `docReferenceId` is provided, the old document is deleted before generating a new one. Returns the new document id.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["employeePositionId","employeeId"],"properties":{"employeePositionId":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"The employee position id for which to generate the certificate","example":"EP-12345"},"employeeId":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"Must match the authenticated user id from the bearer token","example":"2207169020"},"docReferenceId":{"oneOf":[{"type":"integer"},{"type":"string"},{"type":"null"}],"description":"Existing document reference id to replace (optional — pass to delete previous certificate before generating new one)","example":null}}},"example":{"employeePositionId":"EP-12345","employeeId":"2207169020","docReferenceId":null}}}},"responses":{"200":{"description":"Work certificate generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkCertificateResponse"},"example":{"status":"success","code":200,"message":"Work certificate requested successfully","data":{"docId":"98765"}}}}},"400":{"description":"Validation error, employee position not found, or missing letter configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"403":{"description":"Forbidden — employeeId does not match authenticated user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"File service not configured or unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/share/internal-kora-users":{"get":{"tags":["Share"],"summary":"List internal KORA users (OAuth-style userinfo)","description":"Returns every user with role `KORA_INTERNAL` (one entry per user). Each item includes institution / employee fields and nested `user_info`. Empty array if none. Response keys are snake_case.","security":[{"bearerAuth":[],"clientIdHeader":[]}],"responses":{"200":{"description":"KORA internal users fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KoraInternalUsersListResponse"}}}},"400":{"description":"Invalid request headers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_or_expired_token":{"value":{"status":"error","code":401,"message":"Invalid or expired bearer token","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}},"client_id_mismatch":{"value":{"status":"error","code":401,"message":"Bearer token client_id does not match x-client-id header","trace_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","retryable":false}}}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}