Mentor Verification Document API
Endpoints for a mentor to upload, list, update, download, and delete their KYC verification documents (ID / passport / driving licence). Files are stored on a private disk and are never served from a public URL — they are streamed to the owner via the download endpoint.
Admin review of these documents is documented separately in Admin Verification Document API.
- Base URL:
/api/v1 - Auth: all endpoints require a Sanctum bearer token —
Authorization: Bearer {token} - Owner scoped: every endpoint operates only on the authenticated mentor's own documents
Lifecycle rules
- Uploads always start as
pending. - An admin review sets the status to
approvedorrejected. A rejection always carries an admin comment (admin_notes), and the mentor is notified (database + mail) of every outcome. - A
pendingorrejecteddocument can be updated (file replaced) or deleted; updating resets it topendingand wipes the previous review. - Once a document type is approved, it is locked — the mentor can no longer update it, upload a new file of the same type, or delete it.
Response envelope
Success
{ "status": "success", "message": "…", "data": { } }
Error
{ "status": "error", "message": "…", "data": { } }
Status codes
| Code | Meaning |
|---|---|
| 200 | OK (list, update, delete, download stream) |
| 201 | Document uploaded |
| 401 | Missing/invalid token |
| 404 | No mentor profile, or document not found / not owned by the caller |
| 422 | Validation error (bad type, wrong file, too large), or business rule violation (updating/replacing/deleting an approved document) |
| 500 | Server error |
Enums
Document type
| Value | Label |
|---|---|
id_card |
National ID Card |
passport |
Passport |
driving_license |
Driving License |
Status (set by admin review; uploads start as pending)
| Value | Label |
|---|---|
pending |
Pending Review |
approved |
Approved |
rejected |
Rejected |
Document object
{
"id": "9b6f…",
"documentType": "passport",
"documentTypeLabel": "Passport",
"originalName": "passport.pdf",
"mimeType": "application/pdf",
"fileSize": 204800,
"status": "pending",
"statusLabel": "Pending Review",
"adminNotes": null,
"downloadUrl": "https://api.example.com/api/v1/mentor/verification-documents/9b6f…/download",
"createdAt": "2026-07-01T09:00:00+00:00",
"updatedAt": "2026-07-01T09:00:00+00:00"
}
fileSizeis in bytes.adminNotesis populated by an admin during review (nullable).- The raw storage path is never exposed — use
downloadUrl.
1. List my verification documents
GET /api/v1/mentor/verification-documents
Returns the authenticated mentor's documents, newest first.
200 Response
{
"status": "success",
"message": "Verification documents retrieved successfully.",
"data": {
"verification_documents": [ { "…document object…" } ]
}
}
Errors: 401 unauthenticated · 404 no mentor profile
2. Upload verification documents
POST /api/v1/mentor/verification-documents
Uploads one or more files (max 5 per request) for a single document type — e.g. the
front and back of an ID card in one go. Each file becomes its own document record with
status pending.
Content type: multipart/form-data (this endpoint accepts files, not JSON).
Form fields
| Field | Type | Required | Notes |
|---|---|---|---|
document_type |
string | yes | One of the document-type values (id_card, passport, driving_license) |
documents[] |
file[] | yes | 1–5 files; each pdf, jpg, jpeg, or png; max 5 MB (5120 KB) each |
Example (cURL)
curl -X POST https://api.example.com/api/v1/mentor/verification-documents \
-H "Authorization: Bearer {token}" \
-F "document_type=id_card" \
-F "documents[]=@/path/to/id-front.jpg" \
-F "documents[]=@/path/to/id-back.jpg"
201 Response
{
"status": "success",
"message": "Verification documents uploaded successfully.",
"data": { "verification_documents": [ { "…document object…" }, { "…document object…" } ] }
}
Errors
| Code | When |
|---|---|
| 422 | document_type missing/invalid; documents missing/empty (At least one document file is required.) or more than 5 files (You may upload at most 5 files per request.) |
| 422 | A file has the wrong type (Each document must be a PDF, JPG, or PNG file.) or is over 5 MB (Each document may not be larger than 5 MB.) — errors are keyed per file, e.g. documents.0 |
| 422 | A document of this type is already approved — Your {type} has already been approved and cannot be replaced. Re-uploading is only allowed while the existing documents are pending or rejected. |
| 404 | No mentor profile |
| 401 | Unauthenticated |
3. Update (replace) a verification document
POST /api/v1/mentor/verification-documents/{id}
Replaces the file of a not-yet-approved document (and optionally changes its type).
The document is reset to pending and the previous review (adminNotes, reviewer, review
time) is wiped, so an admin reviews the new file from scratch. The old file is removed from
storage.
Uses
POST(notPUT/PATCH) because PHP cannot parsemultipart/form-databodies onPUTrequests.
Content type: multipart/form-data
Form fields
| Field | Type | Required | Notes |
|---|---|---|---|
document |
file | yes | The replacement file — pdf, jpg, jpeg, or png; max 5 MB (5120 KB) |
document_type |
string | no | Optionally move the document to another type (id_card, passport, driving_license) |
Example (cURL)
curl -X POST https://api.example.com/api/v1/mentor/verification-documents/{id} \
-H "Authorization: Bearer {token}" \
-F "document=@/path/to/passport-v2.pdf"
200 Response
{
"status": "success",
"message": "Verification document updated successfully.",
"data": { "verification_document": { "…document object, status back to pending…" } }
}
Errors
| Code | When |
|---|---|
| 422 | document missing (A replacement document file is required.), wrong type, or over 5 MB |
| 422 | The document is already approved — An approved verification document cannot be updated. |
| 422 | document_type targets a type that already has an approved document — Your {type} has already been approved and cannot be replaced. |
| 404 | Document not found / not owned by the caller, or no mentor profile |
| 401 | Unauthenticated |
4. Download a verification document
GET /api/v1/mentor/verification-documents/{id}/download
Streams the stored file as an attachment (Content-Disposition: attachment; filename=…).
Because files live on a private disk, this is the only way to retrieve the binary, and only
the owning mentor may do so.
200 Response: binary file stream (not JSON).
Errors: 401 unauthenticated · 404 document not found / not owned by the caller
5. Delete a verification document
DELETE /api/v1/mentor/verification-documents/{id}
Removes the record and deletes the underlying file from storage. Approved documents
cannot be deleted — only pending and rejected ones.
200 Response
{
"status": "success",
"message": "Verification document deleted successfully.",
"data": { }
}
Errors: 401 unauthenticated · 404 document not found / not owned by the caller ·
422 document is approved (An approved verification document cannot be deleted.)
Admin review
Documents are reviewed by admins — see the separate Admin Verification Document API for the review queue, admin download, and the approve/reject endpoint. From the mentor's perspective:
statusmoves frompendingtoapprovedorrejected; a rejection includes the admin's comment inadminNotes.- The mentor receives a notification (database + mail) on every review outcome.
- After approval the document is locked (no update, no replacement upload, no deletion).