Skip to main content
This guide covers all CRUD operations for managing your portfolio content including profile, experience, education, projects, and skills.
All endpoints in this guide require authentication. See the Authentication Guide for details on obtaining and using JWT tokens.

Profile Management

Your profile is the core of your portfolio, containing personal information and contact details.

Get My Profile

Retrieve your current profile information:
GET /api/me/profile
Authorization: Bearer {token}
Response:
{
  "success": true,
  "message": "Perfil obtenido exitosamente",
  "data": {
    "id": 1,
    "fullName": "John Doe",
    "headline": "Full Stack Developer",
    "bio": "Passionate developer with 5+ years of experience...",
    "contactEmail": "[email protected]",
    "location": "San Francisco, CA",
    "avatarUrl": "https://drive.google.com/uc?export=view&id=...",
    "resumeUrl": "https://drive.google.com/uc?export=view&id=...",
    "slug": "john-doe"
  }
}

Update Profile

Update your profile information using the endpoint from MeController.java:40-51:
PUT /api/me/profile
Authorization: Bearer {token}
Content-Type: application/json
Request Body (ProfileUpdateRequest.java):
{
  "fullName": "John Doe",
  "headline": "Senior Full Stack Developer",
  "bio": "Passionate developer specializing in Spring Boot and React...",
  "contactEmail": "[email protected]",
  "location": "San Francisco, CA"
}
Validation Rules:
  • fullName: Required, max 120 characters
  • headline: Required, max 160 characters
  • bio: Required, max 5000 characters
  • contactEmail: Required, valid email format, max 160 characters
  • location: Optional, max 100 characters

Update Contact Email

Update only the contact email separately:
PUT /api/me/settings/contact-email
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
{
  "email": "[email protected]"
}

Experience Management

Manage your work experience with full CRUD operations. See ExperienceController.java for implementation.

List All Experiences

GET /api/me/experience
Authorization: Bearer {token}
Response:
{
  "success": true,
  "message": "Experiencias obtenidas exitosamente",
  "data": [
    {
      "id": 1,
      "company": "Tech Corp",
      "role": "Senior Developer",
      "location": "Remote",
      "startDate": "2020-01-15",
      "endDate": null,
      "current": true,
      "description": "Leading development of microservices architecture..."
    }
  ]
}

Get Single Experience

GET /api/me/experience/{id}
Authorization: Bearer {token}

Create Experience

Add a new work experience entry:
POST /api/me/experience
Authorization: Bearer {token}
Content-Type: application/json
Request Body (ExperienceCreateRequest.java):
{
  "company": "Tech Corp",
  "role": "Senior Full Stack Developer",
  "location": "San Francisco, CA",
  "startDate": "2020-01-15",
  "endDate": null,
  "current": true,
  "description": "Leading development of microservices architecture using Spring Boot and React. Mentoring junior developers and implementing CI/CD pipelines."
}
Validation Rules:
  • company: Required, max 150 characters
  • role: Required, max 150 characters
  • location: Optional, max 100 characters
  • startDate: Required, ISO date format
  • endDate: Optional, ISO date format
  • current: Required boolean
  • description: Optional, max 65535 characters

Update Experience

PUT /api/me/experience/{id}
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
{
  "company": "Tech Corp",
  "role": "Staff Engineer",
  "location": "Remote",
  "startDate": "2020-01-15",
  "endDate": null,
  "current": true,
  "description": "Updated description..."
}

Delete Experience

DELETE /api/me/experience/{id}
Authorization: Bearer {token}
Response:
{
  "success": true,
  "message": "Experiencia eliminada exitosamente"
}

Education Management

Manage your educational background. Implementation in EducationController.java.

List All Education

GET /api/me/education
Authorization: Bearer {token}

Create Education

POST /api/me/education
Authorization: Bearer {token}
Content-Type: application/json
Request Body (EducationCreateRequest.java):
{
  "institution": "Stanford University",
  "degree": "Bachelor of Science",
  "field": "Computer Science",
  "startDate": "2015-09-01",
  "endDate": "2019-06-15",
  "description": "Focused on distributed systems and machine learning. GPA: 3.8/4.0"
}
Validation Rules:
  • institution: Required, max 150 characters
  • degree: Required, max 150 characters
  • field: Optional, max 150 characters
  • startDate: Required, ISO date format
  • endDate: Optional, ISO date format
  • description: Optional, max 65535 characters

Update Education

PUT /api/me/education/{id}
Authorization: Bearer {token}
Content-Type: application/json

Delete Education

DELETE /api/me/education/{id}
Authorization: Bearer {token}

Project Management

Showcase your projects with detailed information. See ProjectMeController.java for implementation.

List All Projects

GET /api/me/projects
Authorization: Bearer {token}
Response:
{
  "success": true,
  "message": "Proyectos obtenidos exitosamente",
  "data": [
    {
      "id": 1,
      "title": "E-Commerce Platform",
      "slug": "e-commerce-platform",
      "summary": "Full-stack e-commerce solution with Spring Boot and React",
      "description": "Built a scalable e-commerce platform...",
      "repoUrl": "https://github.com/johndoe/ecommerce",
      "liveUrl": "https://ecommerce-demo.example.com",
      "coverImage": "https://drive.google.com/uc?export=view&id=...",
      "startDate": "2023-01-01",
      "endDate": "2023-06-30",
      "featured": true,
      "sortOrder": 1,
      "skills": [
        {
          "id": 1,
          "name": "Spring Boot",
          "level": 90,
          "icon": "https://..."
        },
        {
          "id": 2,
          "name": "React",
          "level": 85,
          "icon": "https://..."
        }
      ]
    }
  ]
}

Get Single Project

GET /api/me/projects/{id}
Authorization: Bearer {token}

Create Project

POST /api/me/projects
Authorization: Bearer {token}
Content-Type: application/json
Request Body (ProjectCreateRequest.java):
{
  "title": "Portfolio Hub API",
  "summary": "RESTful API for managing professional portfolios",
  "description": "A comprehensive Spring Boot API with JWT authentication, Google Drive integration, and email notifications. Features include user management, portfolio CRUD operations, and public API access.",
  "repoUrl": "https://github.com/johndoe/portfolio-api",
  "liveUrl": "https://api.portfolio.example.com",
  "coverImage": null,
  "startDate": "2024-01-01",
  "endDate": null,
  "featured": true,
  "sortOrder": 1
}
Validation Rules:
  • title: Required, max 140 characters
  • summary: Required, max 280 characters
  • description: Optional, max 65535 characters
  • repoUrl: Optional, max 512 characters
  • liveUrl: Optional, max 512 characters
  • coverImage: Optional, max 512 characters
  • startDate: Optional, ISO date format
  • endDate: Optional, ISO date format
  • featured: Required boolean
  • sortOrder: Required integer

Update Project

PUT /api/me/projects/{id}
Authorization: Bearer {token}
Content-Type: application/json

Delete Project

DELETE /api/me/projects/{id}
Authorization: Bearer {token}

Associate Skills to Project

Link existing skills to a project from ProjectMeController.java:83-90:
POST /api/me/projects/{projectId}/skills
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
{
  "skillIds": [1, 2, 5, 8]
}
Response:
{
  "success": true,
  "message": "Skills asociados al proyecto exitosamente",
  "data": {
    "id": 1,
    "title": "Portfolio Hub API",
    "skills": [
      { "id": 1, "name": "Spring Boot", "level": 90 },
      { "id": 2, "name": "React", "level": 85 },
      { "id": 5, "name": "PostgreSQL", "level": 80 },
      { "id": 8, "name": "Docker", "level": 75 }
    ]
  }
}

Skills Management

Skills are organized into categories. Each category can contain multiple skills. See SkillMeController.java for full implementation.

List All Skill Categories

GET /api/me/skill-categories
Authorization: Bearer {token}
Response:
{
  "success": true,
  "message": "Categorías de skills obtenidas",
  "data": [
    {
      "id": 1,
      "name": "Backend Development",
      "sortOrder": 1,
      "skills": [
        {
          "id": 1,
          "name": "Spring Boot",
          "level": 90,
          "icon": "https://drive.google.com/uc?export=view&id=...",
          "sortOrder": 1
        },
        {
          "id": 2,
          "name": "Node.js",
          "level": 75,
          "icon": "https://drive.google.com/uc?export=view&id=...",
          "sortOrder": 2
        }
      ]
    },
    {
      "id": 2,
      "name": "Frontend Development",
      "sortOrder": 2,
      "skills": [
        {
          "id": 3,
          "name": "React",
          "level": 85,
          "icon": "https://drive.google.com/uc?export=view&id=...",
          "sortOrder": 1
        }
      ]
    }
  ]
}

Get Single Category

GET /api/me/skill-categories/{categoryId}
Authorization: Bearer {token}

Batch Create Skill Categories

Create multiple categories at once:
POST /api/me/skill-categories/batch
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
[
  {
    "name": "Backend Development",
    "sortOrder": 1
  },
  {
    "name": "Frontend Development",
    "sortOrder": 2
  },
  {
    "name": "DevOps",
    "sortOrder": 3
  }
]

Batch Update Skill Categories

PUT /api/me/skill-categories/batch
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
[
  {
    "id": 1,
    "name": "Backend & APIs",
    "sortOrder": 1
  },
  {
    "id": 2,
    "name": "Frontend & UI",
    "sortOrder": 2
  }
]

Batch Delete Skill Categories

DELETE /api/me/skill-categories/batch
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
{
  "ids": [1, 2, 3]
}

Get Skills for Category

GET /api/me/skill-categories/{categoryId}/skills
Authorization: Bearer {token}

Batch Create Skills

Add multiple skills to a category:
POST /api/me/skill-categories/{categoryId}/skills/batch
Authorization: Bearer {token}
Content-Type: application/json
Request Body (SkillCreateRequest.java):
[
  {
    "name": "Spring Boot",
    "level": 90,
    "icon": null,
    "sortOrder": 1
  },
  {
    "name": "PostgreSQL",
    "level": 80,
    "icon": null,
    "sortOrder": 2
  },
  {
    "name": "MongoDB",
    "level": 75,
    "icon": null,
    "sortOrder": 3
  }
]
Validation Rules per Skill:
  • name: Required, max 80 characters
  • level: Required, integer between 0-100
  • icon: Optional, max 255 characters
  • sortOrder: Required integer

Batch Update Skills

PUT /api/me/skill-categories/{categoryId}/skills/batch
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
[
  {
    "id": 1,
    "name": "Spring Boot",
    "level": 95,
    "icon": "https://drive.google.com/uc?export=view&id=...",
    "sortOrder": 1
  }
]

Batch Delete Skills

DELETE /api/me/skill-categories/{categoryId}/skills/batch
Authorization: Bearer {token}
Content-Type: application/json
Request Body:
{
  "ids": [1, 2, 3]
}

Search Global Skills

Search for pre-defined skills in the global database:
GET /api/me/skill-categories/search?query=java
Authorization: Bearer {token}
Response:
{
  "success": true,
  "message": "Resultados de búsqueda",
  "data": [
    {
      "id": 1,
      "name": "Java",
      "icon": "https://cdn.example.com/java.svg"
    },
    {
      "id": 2,
      "name": "JavaScript",
      "icon": "https://cdn.example.com/javascript.svg"
    }
  ]
}

Common Response Format

All API responses follow a consistent structure:
public class ApiResponse<T> {
    private boolean success;
    private String message;
    private T data;
}
Success Response:
{
  "success": true,
  "message": "Operation completed successfully",
  "data": { /* response data */ }
}
Error Response:
{
  "success": false,
  "message": "Error message describing what went wrong",
  "data": null
}

Best Practices

Important Tips:
  1. Use batch operations when creating/updating multiple items to reduce API calls
  2. Set appropriate sort orders to control the display order on your portfolio
  3. Keep descriptions concise but informative for better user experience
  4. Mark current positions with current: true for experience entries
  5. Associate skills with projects to showcase your technical expertise
Performance Considerations:
  • All operations are scoped to the authenticated user automatically
  • Batch operations are transactional - they either all succeed or all fail
  • Skills can be reused across multiple projects
  • Use the search endpoint to find existing global skills before creating new ones

Next Steps

File Uploads

Upload avatars, resumes, project covers, and skill icons

Public API

Learn how others can view your portfolio without authentication

Build docs developers (and LLMs) love