Usage Guide
Introduction
This API offers CRUD operations over members, projects and participations in the context of HackerSchool.
Notes: In the requests examples we will be using null values for optional fields, but keep in mind that a null value will attempt to set the entity value to null, if you wish to skip those optional fields don’t include them in the JSON body.
Members
POST /members
- Description
Create a member
Request format
A member object, as follows
{ "username": "user123", // required, string, 3-32 chars, alphanumeric only "name": "Alice Johnson", // required, string, 1-512 chars "email": "alice@example.com", // required, string, 1-512 chars "ist_id": "ist1123456", // optional, string, pattern: ^ist1[0-9]{5,7}$ "password": "secret123", // optional, string, 6-256 chars "member_number": 42, // optional, int > 0 "course": "LEIC", // optional, string, 1-8 chars "roles": ["member", "rh"], // optional, list of strings "join_date": "2023-01-15", // optional, string, ISO 8601 date (YYYY-MM-DD) "exit_date": null, // optional, string, ISO 8601 date (YYYY-MM-DD) "description": "A long description here...", // optional, string, max 2048 chars "extra": null // optional, string, max 2048 chars }
- Response format
The created member object without the password key
GET /members
- Description
Retrieve a list of all registered members.
- Request format
No request body required.
- Response format
List of member objects without the password key.
GET /members/<username>
- Description
Retrieve member by username.
- Request format
No request body required.
- Response format
Member object without the password key.
PUT /members/<username>
- Description
Update an existing member’s information by their username.
Request format
Update member object, as follows
{ "username": "user123", /* optional, string, 3-32 chars, alphanumeric only */ "name": "Alice Johnson", /* optional, string, 1-512 chars */ "email": "alice@example.com", /* optional, string, 1-512 chars */ "password": "secret123", /* optional, string, 6-256 chars */ "member_number": 42, /* optional, int > 0 */ "course": "LEIC", /* optional, string, 1-8 chars */ "roles": ["member", "rh"], /* optional, list of strings */ "join_date": "2023-01-15", /* optional, string, ISO 8601 date (YYYY-MM-DD) */ "exit_date": null, /* optional, string, ISO 8601 date (YYYY-MM-DD) */ "description": "A long description here...", /* optional, string,max 2048 chars */ "extra": null /* optional, string, max 2048 chars */ }
- Response format
Updated member object without the password key
DELETE /members/<username>
- Description
Delete member by username.
- Request format
No request body required.
Response format
{ "description": "Member deleted successfully", "username": "username", }
GET /members/<username>/image
- Description
Retrieve the profile image of a member by their username.
- Request format
No request body required.
- Response format
Binary image data with content type
image/jpeg
orimage/png
depending on the stored image format.
POST /members/<username>/image
- Description
Update the profile image of a member by their username.
- Request format
multipart/form-data
containing the image file with a.png
,.jpg
, or.jpeg
extension.The image is included in the multipart body as a part named
file
, with the appropriate content type (image/png
orimage/jpeg
).Response format
{ "description": "Member image uploaded successfully", "username": "username", }
GET /members/<username>/participations/
- Description
Get list of member’s participations by username.
- Request format
No request body required.
- Response format
{ "join_date": "2025-08-12", // string, ISO 8601 date "project_name": "Platform Revamp", // string, 2–255 chars "roles": ["coordinator", "participant"] // array of strings }
Projects
POST /projects
- Description
Create a new project.
Request format
{ "name": "HS API", // required, string, 2–255 chars "state": "active", // required, string, (enum: e.g., "active", "archived", "planned") "start_date": "2024-11-18", // required, string, ISO 8601 date (YYYY-MM-D "end_date": null, // optional, string, ISO 8601 date (YYYY-MM-DD) "description": "CRUD HS API", // optional, string, max 2048 chars }Response format
A project object, adds the slug key to the previous submitted object, as follows
{ "name": "HS API", // string, 2–255 chars "state": "active", // string (enum: e.g., "active", "archived", "planned") "start_date": "2025-08-12", // string, required, ISO 8601 date (YYYY-MM-DD) "slug": "hs-api", // string, URL-safe identifier "end_date": null, // string or null, ISO 8601 date "description": "CRUD API for HackerSchool" // string or null, project description }
GET /projects
- Description
Retrieve a list of all projects.
- Request format
No request body required.
- Response format
List of projects objects.
GET /projects/<slug>
- Description
Get a project by slug.
- Request format
No request body required.
- Response format
Project object.
PUT /projects/<slug>
- Description
Update a project by slug.
- Request format
Update project object, as follows
{ "name": "HackerSchool API", // optional, string, 2–255 chars "state": null, // optional, string (enum: e.g., "active", "archived", "planned") "start_date": null, // optional, string, ISO 8601 date (YYYY-MM-DD) "end_date": null, // optional, string, ISO 8601 date (YYYY-MM-DD) "description": null // optional, string, project description }- Response format
The updated project object.
DELETE /projects/<slug>
- Description
Delete a project by slug.
- Request format
No request body required.
Response format
{ "description": "Project deleted successfully", "name": "project name", }
GET /projects/<slug>/image
- Description
Retrieve the profile image of a member by their username.
- Request format
No request body required.
- Response format
Binary image data with content type
image/jpeg
orimage/png
depending on the stored image format.
POST /projects/<slug>/image
- Description
Update the image of a project by slug.
- Request format
multipart/form-data
containing the image file with a.png
,.jpg
, or.jpeg
extension.The image is included in the multipart body as a part named
file
, with the appropriate content type (image/png
orimage/jpeg
).Response format
{ "description": "Project image uploaded successfully", "name": "project name", }
POST /projects/<slug>/participations
- Description
Create a new participation entry for project by slug.
Request format
{ "username": "johndoe", // required, string, 3–32 chars, alphanumeric only "join_date": "2025-08-12", // required, string, ISO 8601 date (YYYY-MM-DD) "roles": ["coordinator"] // optional, array of strings }
- Response format
A participation object, as follows
{ "username": "johndoe", // string, required, 3–32 chars, alphanumeric only "join_date": "2025-08-12", // string or null, optional, ISO 8601 date (YYYY-MM-DD) "project_name": "HS API", // string or null, optional, 2–255 chars "roles": ["coordinator"] // array of strings or null, optional }
GET /projects/<slug>/participations
- Description
Retrieve a list of all participations in a specific project by slug.
- Request format
No request body required.
- Response format
A participation object without the project_name field.
GET /projects/<slug>/participations/<username>
- Description
Retrieve details about a specific member’s participation in a project, identified by project slug and member username.
- Request format
No request body required.
- Response format
A participation object.
Authentication
Authentication is session based using cookies. The client authenticates with the API, at which point a session is created server side and a cookie is sent back with the session ID to identify the client in future requests.
You can initiate a session with a traditional login password or through Fenix.
POST /login`
- Description
Login with username and password
- Request format
{ "username": "username", "password": "password", }- Response format
{ "member": {} // logged in member object "description": "Logged in successfully!" }
GET /fenix-login`
The Fenix authentication is made using OAuth 2.0 and the /fenix-login
endpoint starts the OAuth Flow.
Once the flow is complete and if the user’s IST ID is also present in the database, then the authentication is complete and the
the same response as POST /login
is sent.
Errors
All application errors are returned as follows:
{ "code": "404", "name": "Not Found", "description": "Member with username 'username' not found", "details": {} // optional, set by 422 errors to inform the invalid fields of the request }
- Custom application errors:
401 Unauthorized: User doesn’t have a session or invalid credentials provided.
403 Forbidden: User has no permission to perform the action.
404 Not Found: Request entities that do not exist.
413 Request Entity Too Large: Upload of the image is too big.
422 Unprocessable Content: Invalid JSON schema in request.