Skip to main content

Overview

User management covers the current user’s profile, admin-facing user CRUD, and the role/group system used to control access throughout the API. Every authenticated user has a UserProfile linked one-to-one to their Django User record. The profile holds extended fields (phone, address, bio, province, etc.) and is created automatically if it does not yet exist when first accessed.

UserProfile model

FieldTypeDescription
userOneToOne → UserThe linked Django user
phonestring (max 20)Contact phone number
addressstring (max 255)Street address
birth_datedateDate of birth
profile_pictureimageUploaded to profile_pics/
biotextShort biography
rolesManyToMany → GroupProfile-level role assignments
provinceForeignKey → ProvincesAssociated province (nullable)
created_atdatetimeAuto-set on creation
updated_atdatetimeAuto-updated on save

GET /api/auth/profile/

Returns the profile of the currently authenticated user. Creates the profile record automatically if it does not exist.
Requires authentication. Include your access token in the Authorization: Bearer <token> header.

Response

username
string
The user’s username (read-only, sourced from the linked User).
email
string
The user’s email address (read-only, sourced from the linked User).
phone
string
Contact phone number.
address
string
Street address.
birth_date
string
Date of birth in YYYY-MM-DD format.
profile_picture
string
URL to the uploaded profile image.
bio
string
Short biography.
roles
object[]
Profile-level role objects.
user_roles
object[]
Roles assigned directly on the User object (Django groups).
province
integer
ID of the associated province.
created_at
string
ISO 8601 datetime when the profile was created.
updated_at
string
ISO 8601 datetime of the last profile update.
curl --request GET \
  --url https://your-api.example.com/api/auth/profile/ \
  --header 'Authorization: Bearer <your_access_token>'
200 response
{
  "username": "juanperez",
  "email": "[email protected]",
  "phone": "+506 8888-1234",
  "address": "San José, Costa Rica",
  "birth_date": "1990-05-15",
  "profile_picture": "https://storage.example.com/profile_pics/juan.jpg",
  "bio": "Marine conservation enthusiast.",
  "roles": [{"id": 2, "name": "client"}],
  "user_roles": [{"id": 2, "name": "client"}],
  "province": 1,
  "created_at": "2024-01-10T08:30:00Z",
  "updated_at": "2024-03-20T14:15:00Z"
}

PUT /api/auth/profile/

Updates the current user’s profile. Accepts multipart/form-data to support profile picture uploads. All fields are optional (partial update).
Requires authentication.

Request body

phone
string
Contact phone number (max 20 characters).
address
string
Street address (max 255 characters).
birth_date
string
Date of birth in YYYY-MM-DD format.
profile_picture
file
New profile image. Replaces any existing image. Stored under profile_pics/.
bio
string
Short biography.
province
integer | string
Province ID, or the province name as a string. If passed as a string, the API resolves it to the matching province record.

Response

Returns the full updated profile object. Same structure as GET /api/auth/profile/.
curl --request PUT \
  --url https://your-api.example.com/api/auth/profile/ \
  --header 'Authorization: Bearer <your_access_token>' \
  --form 'phone=+506 8888-5678' \
  --form 'bio=Updated bio text.' \
  --form 'province=2' \
  --form 'profile_picture=@/path/to/new_photo.jpg'

GET /api/auth/user_profile/

Returns a list of all user profiles.
Requires authentication and the IsAuthenticatedAndRole permission. Access is restricted to authenticated users; set required_role on the view to limit by group.

Response

Returns an array of profile objects with the same structure as GET /api/auth/profile/.
curl --request GET \
  --url https://your-api.example.com/api/auth/user_profile/ \
  --header 'Authorization: Bearer <your_access_token>'

GET /api/auth/user_profile/{id}/

Returns the profile for a specific user by their user ID (not profile ID).
Requires authentication.

Path parameters

id
integer
required
The Django User primary key.

Response

Returns a single profile object. Same structure as GET /api/auth/profile/.
curl --request GET \
  --url https://your-api.example.com/api/auth/user_profile/42/ \
  --header 'Authorization: Bearer <your_access_token>'
404 response — user not found
{
  "error": "User not found"
}

PUT /api/auth/user_profile/{id}/update/

Updates the profile for a specific user by their user ID. Accepts partial data (all fields optional).
Requires authentication and appropriate role access.

Path parameters

id
integer
required
The Django User primary key.

Request body

Same fields as PUT /api/auth/profile/ — all optional.

GET /api/auth/users/

Returns a paginated list of all Django users. This is an admin-facing endpoint.
Requires authentication via IsAuthenticatedAndRole. Only accessible to users with the appropriate role (configured via required_role on the view).

Response

Returns an array of user objects serialized by RegisterSerializer.
username
string
email
string
first_name
string
last_name
string
roles
integer[]
List of group IDs.
profile
object
Nested profile data if present.
curl --request GET \
  --url https://your-api.example.com/api/auth/users/ \
  --header 'Authorization: Bearer <your_access_token>'

PUT /api/auth/users/{id}/update/

Updates a specific user by their user ID. Admin-facing.
Requires authentication and appropriate role access.

Path parameters

id
integer
required
The user’s primary key.

Request body

username
string
Username.
email
string
Email address.
first_name
string
Given name.
last_name
string
Family name.
roles
integer[]
List of group IDs to assign.

DELETE /api/auth/users/{id}/delete/

Permanently deletes a user account.
This action is irreversible. Deleting a user removes their account and all associated profile data via cascading database deletion.
Requires authentication and appropriate role access.

Path parameters

id
integer
required
The user’s primary key.
curl --request DELETE \
  --url https://your-api.example.com/api/auth/users/42/delete/ \
  --header 'Authorization: Bearer <your_access_token>'

Roles and permissions

The platform uses Django’s built-in Group model for role management. Every user can belong to one or more groups, which control access to role-restricted endpoints.

GET /api/auth/roles/

Lists all available roles (Django groups).
id
integer
Group ID.
name
string
Group name.
permissions
integer[]
List of permission IDs assigned to the group.
curl --request GET \
  --url https://your-api.example.com/api/auth/roles/ \
  --header 'Authorization: Bearer <your_access_token>'
200 response
[
  {"id": 1, "name": "admin", "permissions": [1, 2, 3]},
  {"id": 2, "name": "client", "permissions": []},
  {"id": 3, "name": "researcher", "permissions": [4, 5]}
]

POST /api/auth/roles/create/

Creates a new role.
Requires authentication.
name
string
required
The name for the new role.

PUT /api/auth/permissions/{id}/update/

Replaces the permission set for a role by group ID.
Requires authentication and IsAuthenticatedAndRole.
id
integer
required
The group ID whose permissions you are updating.
permissions
integer[]
required
Full list of Django permission IDs to assign to this group. Replaces the existing set.
curl --request PUT \
  --url https://your-api.example.com/api/auth/permissions/1/update/ \
  --header 'Authorization: Bearer <your_access_token>' \
  --header 'Content-Type: application/json' \
  --data '{"permissions": [1, 2, 3, 7]}'

Password reset flow

The full password reset sequence involves two endpoints:
1

Request a reset token

Call POST /api/auth/forgot-password/ with the user’s email address. The response contains a uid and token.See forgot password for full details.
2

Submit the new password

Call POST /api/auth/reset-password-confirm/ with the uid, token, and the new_password.The token is single-use. On success the user’s password is updated and the token is invalidated.See reset password confirm for full details.

Build docs developers (and LLMs) love