User update post
POST
https://app.sulus.ai/api/user
Update profile fields (multipart; used by the Profile UI)
Authentication
Send a bearer token created on your dashboard's Developer page:
Authorization: Bearer <YOUR_API_KEY>
Request body
name
string
Required
Display name.
Validation:
required|string|max:255Stored in
users.namephone
string
Optional
Nullable
Phone number.
Validation:
nullable|string|max:20Stored in
users.phonecompany
string
Optional
Nullable
Company name.
Validation:
nullable|string|max:255Stored in
users.companybio
string
Optional
Nullable
Short bio.
Validation:
nullable|string|max:1000Stored in
users.bioprofile_picture
file
Optional
Nullable
Image file; stored on the public disk; response returns a public URL.
Validation:
nullable|image|mimes:jpeg,png,jpg,gif|max:2048Stored in
users.profile_pictureErrors
| Status | Meaning | Body |
|---|---|---|
401 |
Missing or invalid bearer token | |
422 |
Validation failed | {"message":"The given data was invalid.","errors":{"name":["The name field is required."]}} |
400 |
Uploaded file failed isValid() | {"success":false,"message":"Invalid file upload"} |
500 |
Unexpected save/storage failure | {"success":false,"message":"Failed to update profile: …"} |
Notes
- Same handler as PUT /user. The SPA uses POST with FormData so profile_picture can be a file part.
- Content-Type multipart/form-data. Omit profile_picture to leave the existing picture unchanged.
- Validation and error bodies match PUT /user.
curl --request POST \
--url https://app.sulus.ai/api/user \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--form 'profile_picture=@/path/to/file'
import requests
url = "https://app.sulus.ai/api/user"
headers = {"Authorization": "Bearer <YOUR_API_KEY>"}
files = {"profile_picture": open("/path/to/file", "rb")}
response = requests.post(url, files=files, headers=headers)
print(response.json())
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
url := "https://app.sulus.ai/api/user"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <YOUR_API_KEY>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
Response
200
{
"success": true,
"data": {
"id": 42,
"reseller_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"reseller_current_ui_version": "v2",
"reseller_ui_intro_seen_at": "2026-06-01T12:00:00.000000Z",
"name": "Jordan Lee",
"email": "[email protected]",
"supabase_id": null,
"google_id": null,
"role": "user",
"phone": "+14155550123",
"company": "Acme Dental",
"bio": "Practice manager",
"profile_picture": "https://app.sulus.ai/storage/profile-pictures/abc123.jpg",
"status": "active",
"email_verified_at": "2026-05-01T10:00:00.000000Z",
"created_at": "2026-05-01T09:00:00.000000Z",
"updated_at": "2026-07-30T16:00:00.000000Z",
"deleted_at": null,
"is_reseller_admin": false,
"is_reseller": true
},
"message": "Profile updated successfully"
}
Response — POST
/user
200
{
"success": true,
"data": {
"id": 42,
"reseller_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"reseller_current_ui_version": "v2",
"reseller_ui_intro_seen_at": "2026-06-01T12:00:00.000000Z",
"name": "Jordan Lee",
"email": "[email protected]",
"supabase_id": null,
"google_id": null,
"role": "user",
"phone": "+14155550123",
"company": "Acme Dental",
"bio": "Practice manager",
"profile_picture": "https://app.sulus.ai/storage/profile-pictures/abc123.jpg",
"status": "active",
"email_verified_at": "2026-05-01T10:00:00.000000Z",
"created_at": "2026-05-01T09:00:00.000000Z",
"updated_at": "2026-07-30T16:00:00.000000Z",
"deleted_at": null,
"is_reseller_admin": false,
"is_reseller": true
},
"message": "Profile updated successfully"
}